#include <exec/types.h>
#include <stdio.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>

struct FileInfoBlock block;
struct DosLibrary *DosBase;
extern LONG *OpenLibrary();

char *monat[]=
 {
  "Januar",
  "Februar",
  "März",
  "April",
  "Mai",
  "Juni",
  "Juli",
  "August",
  "September",
  "Oktober",
  "November",
  "Dezember"
 };

int laenge[12]=
 {
  31,
  28,
  31,
  30,
  31,
  30,
  31,
  31,
  30,
  31,
  30,
  31
 };

char *text[]=
{
 " Listing von ",
 " Länge der Datei: ",
 "Bytes",
 "            belegte Blöcke: ",
 " Protection-Flags: ",
 " Erstellungsdatum der Datei:    ",
 "um",
 " Erstellungsdatum des Listings: ",
 " Dieses Listing wurde mit ",
 " V1.0 von Jörg Hüddersen erstellt."
};


char *fehler[]=
{
 "Fehler beim Öffnen der dos.library !",
 "Fehler beim Öffnen der Datei !",
 "Die Datei ist ein Directory !",
 "Die Datei ist lesegeschützt !",
 "Fehler beim Öffnen des Druckerkanals !"
};


int amerikanisch, deutsch, protectionflags[8];
long datum[12],aktdat[3];
char *proflags="hsparwed";
FILE *eingabe, *ausgabe, *fopen();


Flag(flags)
register long flags;
{
 register int wert=128,zaehler=7;

 while (flags>0L)
  {
   if(flags-wert>=0L)
    {
     flags-=wert;
     protectionflags[zaehler]=1;
     zaehler--;
     wert/=2;
    }
   else
    {
     protectionflags[zaehler]=0;
     zaehler--;
     wert/=2;
    }
   }

 while(zaehler>=0)
  {
   protectionflags[zaehler]=0;
   zaehler--;
  }
}


Datum(days,minute,tick,nummer)
register long days,minute,tick;
register int nummer;
{
 register int t=0,i=2;
 datum[1+nummer]=1;
 datum[2+nummer]=1978;
 datum[3+nummer]=0;

 while(days>=365)
  {
   if (i<=3)
    {
     days-=365;
     datum[2+nummer]++;
     i++;
    }
   else
    {
     days-=366;
     datum[2+nummer]++;
     i=1;
    }
  }

 if (days<0)
  {
   datum[2+nummer]--;
   days+=366;
  }

 while (days>=laenge[t])
  {
   days-=laenge[t];
   if ((i==4) && (t==1))
    days--;
   datum[1+nummer]++;
   if (t<=10)
    t++;
  }

 datum[0+nummer]=days+1;

 while(minute>=60)
  {
   minute-=60;
   datum[3+nummer]++;
  }

 datum[4+nummer]=minute;

 while (tick>=50)
  {
   tick-=50;
   datum[5+nummer]++;
  }
 if (tick>=25)
  datum[5+nummer]++;
}

Amerikanisch()
{
 fputc(27,ausgabe);
 fputc('R',ausgabe);
 fputc(0,ausgabe);
 amerikanisch=1;
 deutsch=0;
}


Deutsch()
{
 fputc(27,ausgabe);
 fputc('R',ausgabe);
 fputc(2,ausgabe);
 amerikanisch=0;
 deutsch=1;
}


LineFeed()
{
 fputc(10,ausgabe);
}


CarriageReturn()
{
 fputc(13,ausgabe);
}


Space()
{
 fputc(32,ausgabe);
}


HorizontalTab()
{
 fputc(9,ausgabe);
}


TabAt(position)
register int position;
{
 fputc(27,ausgabe);
 fputc('D',ausgabe);
 fputc(position,ausgabe);
 fputc(0,ausgabe);
}

Big()
{
 fputc(28,ausgabe);
 fputc('E',ausgabe);
 fputc('1',ausgabe);
 fputc(28,ausgabe);
 fputc('V',ausgabe);
 fputc(1,ausgabe);
}

Small()
{
 fputc(28,ausgabe);
 fputc('E',ausgabe);
 fputc(0,ausgabe);
 fputc(28,ausgabe);
 fputc('V',ausgabe);
 fputc(0,ausgabe);
}

send (Buchstabe)
register char Buchstabe;
{
 switch (Buchstabe)
  {
   case '{':
    if (deutsch)
     Amerikanisch();
    fputc('{',ausgabe);
    break;
   case '}':
    if (deutsch)
     Amerikanisch();
    fputc('}',ausgabe);
    break;
   case '[':
    if (deutsch)
     Amerikanisch();
    fputc('[',ausgabe);
    break;
   case ']':
    if (deutsch)
     Amerikanisch();
    fputc(']',ausgabe);
    break;
   case 92:
    if (deutsch)
     Amerikanisch();
    fputc(92,ausgabe);
    break;
   case '|':
    if (deutsch)
     Amerikanisch();
    fputc('|',ausgabe);
    break;
   case 228:
    if (amerikanisch)
     Deutsch();
    fputc(123,ausgabe);
    break;
   case 246:
    if (amerikanisch)
     Deutsch();
    fputc(124,ausgabe);
    break;
   case 252:
    if (amerikanisch)
     Deutsch();
    fputc(125,ausgabe);
    break;
   case 196:
    if (amerikanisch)
     Deutsch();
    fputc(91,ausgabe);
    break;
   case 214:
    if (amerikanisch)
     Deutsch();
    fputc(92,ausgabe);
    break;
   case 220:
    if (amerikanisch)
     Deutsch();
    fputc(93,ausgabe);
    break;
   case 223:
    if (amerikanisch)
     Deutsch();
    fputc(126,ausgabe);
    break;
   case 'ä':
    if (amerikanisch)
     Deutsch();
    fputc(123,ausgabe);
    break;
   case 'ö':
    if (amerikanisch)
     Deutsch();
    fputc(124,ausgabe);
    break;
   case 'ü':
    if (amerikanisch)
     Deutsch();
    fputc(125,ausgabe);
    break;
   case 'Ä':
    if (amerikanisch)
     Deutsch();
    fputc(91,ausgabe);
    break;
   case 'Ö':
    if (amerikanisch)
     Deutsch();
    fputc(92,ausgabe);
    break;
   case 'Ü':
    if (amerikanisch)
     Deutsch();
    fputc(93,ausgabe);
    break;
   case 'ß':
    if (amerikanisch)
     Deutsch();
    fputc(126,ausgabe);
    break;
   default:
    fputc(Buchstabe,ausgabe);
  }
}


solange (text)
char text[];
{
 register int i=0;

 while (text[i])
  {
   send(text[i]);
   i++;
  }
}

main (argc,argv)
int argc;
char *argv[];

{
 register int Zeichen,altZeichen,i=0,Nummer=1,t;
 register long lo;

 while(argv[0][i])
  {
   if (argv[0][i]>=97 && argv[0][i]<=122)
    argv[0][i]-=32;
   i++;
  }
 i=0;
 printf("%s V1.0\n",argv[0]);
 printf("Copyright by Jörg Hüddersen 1988/89\n");

 if (!(DosBase=(struct DosLibrary *)
     OpenLibrary("dos.library",0)))
  {
   printf("%s\n",fehler[0]);
   exit (FALSE);
  }

 if (argc==2)
  {
   lo=Lock(argv[1], ACCESS_READ);
   if (lo)
    {
     if(!Examine(lo, &block))
      {
       printf("%s\n",fehler[1]);
       exit(FALSE);
      }
    }
   else
    {
     printf("%s\n",fehler[1]);
     exit(FALSE);
    }
   if (block.fib_DirEntryType>0)
    {
     printf("%s\n",fehler[2]);
     exit(FALSE);
    }

   Flag(block.fib_Protection);
   if (protectionflags[3]==1)
    {
     printf("%s\n",fehler[3]);
     exit(FALSE);
    }
   UnLock (lo);

   if (!(eingabe=fopen(argv[1],"r")))
    {
     printf("%s\n",fehler[1]);
     exit (10L);
    }

   if (!(ausgabe=fopen("PAR:Listing","w")))
    {
     printf("%s\n",fehler[4]);
     fclose (eingabe);
     exit (10L);
    }

   DateStamp(&aktdat[0]);

   Deutsch();
   TabAt(6);

   Datum(block.fib_Date.ds_Days,block.fib_Date.ds_Minute,
         block.fib_Date.ds_Tick,0);
   Datum(aktdat[0],aktdat[1],aktdat[2],6);

   solange(text[0]);
   Big();
   solange(argv[1]);
   Small();
   LineFeed();
   Space();
   solange(block.fib_Comment);
   LineFeed();
   solange(text[1]);
   fprintf(ausgabe,"%ld ",block.fib_Size);
   for (t=2; t<=3; t++)
    solange(text[t]);
   fprintf(ausgabe,"%ld",block.fib_NumBlocks);
   LineFeed();
   solange(text[4]);
   for (t=7; t>=0; t--)
    {
     if (!protectionflags[t])
      send(proflags[7-t]);
     else
      send('-');
    }

   LineFeed();
   solange(text[5]);
   if (datum[0]<10)
    send('0');
   fprintf(ausgabe,"%ld.",datum[0]);
   solange(monat[datum[1]-1]);
   fprintf(ausgabe," %ld ",datum[2]);

   solange(text[6]);
   if (datum[3]<10)
     send('0');
   fprintf(ausgabe," %ld.",datum[3]);
   if (datum[4]<10)
    send('0');
   fprintf(ausgabe,"%ld.",datum[4]);
   if (datum[5]<10)
    send('0');
   fprintf(ausgabe,"%ld Uhr",datum[5]);

   LineFeed();
   solange(text[7]);
   if (datum[6]<10)
    send('0');
   fprintf(ausgabe,"%ld.",datum[6]);
   solange(monat[datum[7]-1]);
   fprintf(ausgabe," %ld ",datum[8]);
   solange(text[6]);
   if (datum[9]<10)
     send('0');
   fprintf(ausgabe," %ld.",datum[9]);
   if (datum[10]<10)
    send('0', ausgabe);
   fprintf(ausgabe,"%ld.",datum[10]);
   if (datum[11]<10)
    send('0', ausgabe);
   fprintf(ausgabe,"%ld Uhr",datum[11]);


   LineFeed();
   LineFeed();

   altZeichen=10;
   while((Zeichen=fgetc(eingabe))!=EOF)
    {
     if (altZeichen==10)
      {
       LineFeed();
       fprintf(ausgabe,"%6d",Nummer);
       Nummer++;
       HorizontalTab();
       fputc(':',ausgabe);
       Space();
       Space();
      }
     else
      send(altZeichen);
     altZeichen=Zeichen;
    }

   LineFeed();
   LineFeed();
   solange(text[8]);
   solange(argv[0]);
   solange(text[9]);

   LineFeed();
   CarriageReturn();
   if (eingabe) fclose(eingabe);
   if (ausgabe) fclose(ausgabe);
  }
 else
  printf("USAGE %s [Datei]\n",argv[0]);

 exit(TRUE);
}

