/* $VER: DiaGFList V2.2 (28 Jun 1995) */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <dialog/dlg_pragmas.h>
#include <dialog/misc.h>
#include <dialog/file.h>
#include <dialog/msg.h>
#define __USE_SYSBASE

#include <proto/exec.h>
#include <proto/dos.h>

#define MINOSVER 37

#define VERSION_NAG \
        "\nYou have neglected your responsibility to upgrade\n"\
        "your system software to version 2.04 or greater!\n\n"

#define DLGERROR \
        "\nDiaMail error: Can't open dlg.library!\n\n"

#define SORTERROR \
        "\nDiaMail error: Check sort value again!\n\n"

#define MEMORYERROR \
        "\nDiaMail error: No enough free memory. Check buffer value!\n\n"

#define HEADER \
        "\x1b[1m[1;35mDiaGFList V2.2\x1b[0m -- Build AmigaGuide Filelist\n"\
        "Written by Janne Saarme 1994/1995\n\n" \
        "Usage: DiaGFList [-a] [-b] [-c] [-f] [-l] [-n] [-r]areas [-s] filename\n\n" \
        "Switches:\n\n" \
        "-a          Build AmigaGuide list\n" \
        "-b          Buffer size = max files in one area (default 1500)\n" \
        "-c<length>  Length of description\n" \
        "-f          Do not list areas where freq is not allowed\n" \
        "-l          Add linefeed (for MS-DOS systems)\n" \
        "-n<days>    List x days old file(s)\n" \
        "-r<areas>   No not list areas. Syntax:1,2-10,15\n" \
        "-s<x>       Sort: 1-Date(N)/2-Date(O)/3-Size(B)/4-Size(S)/5-Name(Z-A)\n\n"

void 	sulkemiset(void);
void    arvot(long arvo);

int QuickFileHighLow(struct QuickFile *a, struct QuickFile *b);
int QuickFileLowHigh(struct QuickFile *a, struct QuickFile *b);
int QuickFileSizeHigh(struct QuickFile *a, struct QuickFile *b);
int QuickFileSizeLow(struct QuickFile *a, struct QuickFile *b);

int QuickFileNameLow(struct QuickFile *a, struct QuickFile *b);

APTR DLGBase; 
BPTR f1, f2;

char amigaguide = 0;
long laske=0, *taulukko, laskuri;

void main(int ac, char **arg)
{
struct ATime pvm;

static struct QuickFile *buf;
static struct Msg_Area area[150];

char dlenght = 40, sort=0, new=0, nofreq=0, *b, notallowed=0, eiole=0, arvo=0,
     fname[50], cdate[40], *filename=0, *LINEFEED[1]={""},
     *month[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};

short nold=12345, buffer=1500, alueita=0, tutki, tutki2;  

long n=1, f=0, indeksi=-1, datainbuf, total=0, counter=0, NewSec;

if(((struct Library *)SysBase)->lib_Version<MINOSVER ||
   DOSBase->dl_lib.lib_Version<MINOSVER) {
     Write(Output(), VERSION_NAG, sizeof(VERSION_NAG));
     exit(0);
     }

if(!(DLGBase = OpenLibrary("dlg.library", 0))) {
  Write(Output(), DLGERROR, sizeof(DLGERROR));
  sulkemiset();
  }

while((arg++, --ac) && **arg=='-')
  switch(arg[0][1])
    {
    case 'a':
    amigaguide = 1;
    break;

    case 'b':
    buffer = atoi(arg[0]+2);
    break;
    
    case 'l':
    LINEFEED[0] = "\r";
    break;

    case 'c':
    dlenght = atoi(arg[0]+2);
    break;

    case 'n':
    nold = atoi(arg[0]+2);
    new = 1;
    break;

    case 'f':
    nofreq = 1;
    break;

    case 'r':
    if(!(taulukko=malloc(10000*sizeof(long)))) { Write(Output(), MEMORYERROR, sizeof(MEMORYERROR)); sulkemiset(); }   
    b = arg[0]+2;
    break;
     
    case 's':
    sort = atoi(arg[0]+2);
    if(sort<1||sort>5) { Write(Output(), SORTERROR, sizeof(SORTERROR)); sulkemiset(); }
    break;
 
   default:
   new = 0; amigaguide = 0, dlenght = 40, nofreq = 0;
   break;
}

if(!ac||nold==0||arg[0][0]=='?') { Write(Output(), HEADER, sizeof(HEADER)); sulkemiset(); }
else               
  filename=arg[0];

while(*b)
  {
  f=atoi(b);
  while(isdigit(*b)) b++;
    if(*b=='-')
      {
      n=atoi(++b);
      while(isdigit(*b)) b++;
      }
    else
      n=f;

    if(*b) b++;

    while(f<=n) arvot(f++);
}

if(!(f1 = Open(filename, MODE_NEWFILE))) sulkemiset();
if(!(f2 = Open("ram:Area.bbs", MODE_READWRITE))) sulkemiset();

if (amigaguide==1) {
   FPrintf(f1, "@Database \"DiaGFList.Guide\"\n");
   FPrintf(f1, "@Node Main \"DiaGFlist V2.1\"\n");
   }

MDate(cdate);

FPrintf(f1, "%s\n%s\n                      DiaGFlist V2.1 by Janne Saarme 1994", LINEFEED[0], LINEFEED[0]);
FPrintf(f1, "%s\n                        List updated: %s%s\n", LINEFEED[0], cdate, LINEFEED[0]);

if(new == 1) FPrintf(f1, "%s\n                           List of files %ld day(s) old\%s\n\%s\n", LINEFEED[0], nold, LINEFEED[0], LINEFEED[0]);
else FPrintf(f1, "%s\n                                 List off allfiles%s\n%s\n", LINEFEED[0], LINEFEED[0], LINEFEED[0]);

do {
  for(datainbuf=0, f=1; f && datainbuf<sizeof area; datainbuf+=f)
    if((f=Read(f2, (char *)area+datainbuf, sizeof area-datainbuf))<0) sulkemiset();
      if(amigaguide == 1) {
        for(n=0; n<datainbuf/sizeof *area; n=n+3) {
          FPrintf(f1, "@{\" %-20.20s \" Link \"%ld\" } @{\" %-20.20s \" Link \"%ld\" } @{\" %-20.20s \" Link \"%ld\" }\n",
          area[n].Name, area[n].Number, area[n+1].Name, area[n+1].Number, area[n+2].Name, area[n+2].Number);
          }
        } 

if(CheckSignal(SIGBREAKF_CTRL_C)) sulkemiset();
} while(datainbuf==sizeof area);


while(laskuri!=10000) {
if(area[alueita].Number == 0) laskuri = 10000;
alueita++;
}

if(!(buf=malloc(buffer*sizeof(*buf)))) { Write(Output(), MEMORYERROR, sizeof(MEMORYERROR)); sulkemiset(); }

while (alueita!=indeksi)
{
if (f2) Close(f2); f2=0;
arvo = 0;indeksi++;

for(laskuri=0; laskuri<=laske; laskuri++)
   {
   tutki  = taulukko[laskuri];
   tutki2 = area[indeksi].Number;
   if(tutki==tutki2) arvo=1;
   }  

if(nofreq==1) if(area[indeksi].Flag & FREQ_AREA) notallowed=0;
  else notallowed=1;
      
if(arvo!=1&&notallowed==0) 
  {   
  if(CheckSignal(SIGBREAKF_CTRL_C)) sulkemiset();
  sprintf(fname, "File:%d/File.dat", area[indeksi].Number);
  if(!(f2 = Open(fname, MODE_READWRITE))) sulkemiset();
  eiole=0, f=0;
  if (amigaguide==1) FPrintf(f1, "\n@EndNode\n@Node \"%ld\" \"%s\"\n", area[indeksi].Number, area[indeksi].Name);  

  do  
    { 
     for(datainbuf=0, f=1; f && datainbuf<sizeof *buf; datainbuf+=f)
       if((f=Read(f2, (char *)buf+datainbuf, (buffer*(sizeof *buf))-datainbuf))<0) sulkemiset(); /* I/O virhe */

     if(sort==1) qsort(buf, datainbuf/sizeof *buf, sizeof *buf, QuickFileHighLow);
     if(sort==2) qsort(buf, datainbuf/sizeof *buf, sizeof *buf, QuickFileLowHigh);
     if(sort==3) qsort(buf, datainbuf/sizeof *buf, sizeof *buf, QuickFileSizeHigh);
     if(sort==4) qsort(buf, datainbuf/sizeof *buf, sizeof *buf, QuickFileSizeLow);
     if(sort==5) qsort(buf, datainbuf/sizeof *buf, sizeof *buf, QuickFileNameLow);

    for(n=0; n<datainbuf/sizeof *buf; n++)
       {
       char *p;
  
       UnpackTime(buf[n].date, &pvm);
    
       for(p=buf[n].desc; *p; p++) if(*p=='\r' || *p=='\n') *p=' ';

       if(p>buf[n].desc+dlenght) strcpy(buf[n].desc+(dlenght-3), "...");

       NewSec = AmigaTime()-(nold * 86400);

       if(eiole==0&&buf[n].date > NewSec) {
           FPrintf(f1, "%s\n=-= File area is %ld (%s) =-=%s\n%s\n", LINEFEED[0], area[indeksi].Number, area[indeksi].Name, LINEFEED[0], LINEFEED[0]);
	   FPrintf(f1, "=-= Name =-=     = Date =   =Size= =-= Description =-=%s\n", LINEFEED[0]);
           eiole=1;
           }
       
       if(new==1&&buf[n].date > NewSec) 
         FPrintf(f1, "%-14.14s  %02ld-%3s-%4ld %4ldKB %s%s\n", buf[n].filename,
	         pvm.mday, month[pvm.mon], pvm.year, (buf[n].size)/1000, buf[n].desc, LINEFEED[0]);

       if(new==0) FPrintf(f1, "%-14.14s  %02ld-%3s-%4ld %4ldKB %s%s\n", buf[n].filename,
	                       pvm.mday, month[pvm.mon], pvm.year, (buf[n].size)/1000, buf[n].desc, LINEFEED[0]);

       total = total + buf[n].size; counter++;
       }

   if(CheckSignal(SIGBREAKF_CTRL_C)) sulkemiset();

} while(datainbuf==sizeof *buf);

   if(new == 0&&counter!=0) FPrintf(f1,"%s\nTotal files in this area %ld (%ldKB)%s\n%s\n", LINEFEED[0], counter, total/1000, LINEFEED[0], LINEFEED[0]);

   counter = 0; total=0;
   }
}
sulkemiset();
}

int QuickFileHighLow(struct QuickFile *a, struct QuickFile *b)
   {
   return b->number-a->number;
   } 

int QuickFileLowHigh(struct QuickFile *a, struct QuickFile *b)
   {
   return a->number-b->number;
   } 

int QuickFileSizeHigh(struct QuickFile *a, struct QuickFile *b)
   {
   return b->size-a->size;
   } 

int QuickFileSizeLow(struct QuickFile *a, struct QuickFile *b)
   {
   return a->size-b->size;
   } 

int QuickFileNameLow(struct QuickFile *a, struct QuickFile *b) 
   {                                                           
   return strcmp(b->filename, a->filename);                    
   }

void arvot(long arvo)
{
taulukko[laske] = arvo; laske++;
}

void sulkemiset(void) 
{
if (amigaguide==1) FPrintf(f1, "\n@EndNode\n");
if (f1) Close(f1); f1=0;
if (f2) Close(f2); f2=0;
if (DLGBase) CloseLibrary(DLGBase);
exit(0);
}
