#include STDIO.H
#include TERMCAP.H
long length=0;
long seekpos[1000];
long start,end;
int linesmax=1;
int line=1;
int lastkey=0;
int keyflag;
int flag=1;
char buf[256];
char filename[14];
FILE *fp;

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

   if (argc != 2) {
      puts("usage: more filename");
      exit(1);
   }

   strcpy(filename,argv[1]);

   if (!(fp=fopen(filename,"r"))) {
      printf("more: can't open %s\r\n",filename);
      exit(1);
   }

   seekpos[linesmax] = 0;
   while ((c=getc(fp)) != EOF) {
      length++;
      if (c == '\n')
         seekpos[++linesmax] = length;
   }
   output(MAXLINES);

   for (;;) {
      while(!(c=tolower(bdos(NULL,3)))) ;
      switch(c) {
         case  '\r' : line -= MAXLINES;
                      output(MAXLINES);
                      break;
         case  '3'  :
         case  ' '  : output(MAXLINES);
                      break;
         case  '9'  : output(-MAXLINES);
                      break;
         case  '2'  : output(MAXLINES/2);
                      break;
         case  '8'  : output(-MAXLINES/2);
                      break;
         case  '5'  : line = 1;
                      output(MAXLINES);
                      break;
         case  '1'  : output(1);
                      break;
         case  '7'  : output(-1);
                      break;
         case  '\n' : menue();
                      break;
         case  '/'  : patfind();
                      break;
         case  'l'  : linefind();
                      break;
         case  'q'  : CRLF;
                      PUL("");
                      CURON;
                      exit(0);
         default    : BEEP;
                      continue;
      }
      lastkey = c;
      keyflag = (c == '/' || c == 'l' || c == '\n');
   }
}

output(n)
int n;
{

   if (n<0) {
      line = line - MAXLINES + n;
      n = MAXLINES;
      CLEAR;
   }
   if (line<1) line = 1;
   pageout(n);
   CUROFF;
   HALFON;
   sprintf(buf,"more    %s  %ld  %% %c",filename,end*100/length,'\0');
   sprintf(buf,"%s     line %d   length %ld bytes%c",buf,line-1,length,'\0');
   PUL(buf);
   HALFOFF;
}

pageout(n)
int n;
{
   int  c;
   long i;

   if (keyflag) {
      line -= MAXLINES;
      keyflag = 0;
      pageout(MAXLINES);
   }

   start = line;
   if ((line+n) > linesmax && !flag)
      return;
   line += n;
   if ((flag=(line < linesmax)))
      end = seekpos[line] - 2;
   else
      end = length-1;
   fseek(fp,seekpos[start],0);
   CRLF;
   for (i=seekpos[start];i < end;i++)
      if ((c=getc(fp)) == 26)
         break;
      else
         putc(c,STDOUT);
   if (!flag) {
      HALF("\r\nEND OF FILE");
      line = linesmax;
   }
}

menue()
{
   CLEAR;
   PUL("");
   puts("\r\n\r\n------    help menue    ------\r\n");
   puts("  'CR'    :  Bildschirm auffrischen");
   puts("   '3'    :");
   puts("   ' '    :  volle Seite vor");
   puts("   '2'    :  halbe Seite vor");
   puts("   '1'    :  eine  Zeile vor");
   puts("   '9'    :  volle Seite zurueck");
   puts("   '8'    :  halbe Seite zurueck");
   puts("   '7'    :  eine  Zeile zurueck");
   puts("   '5'    :  neu vom Anfang beginnen");
   puts("   'q'    :  more beenden");
   puts("   '/'    :  nach einem Muster suchen");
   puts("   'l'    :  Sprung nach Zeilennummer");
   puts("  'HELP'  :  help menue ausgeben");
}

patfind()
{
   int p,pos;
   register int c;
   static int l;
   static char pattern[256];

   p = 0;
   HALFON;
   pr_line();
   printf("Suchmuster: ");
   if (pattern[0] != '\0' && lastkey == '/') {
      printf(pattern);
      LF;
   }
   else {
      CURON;
      gets(pattern);
      CUROFF;
      if (!(l=strlen(pattern))) {
         puts("das ist doch kein Muster!");
         HALFOFF;
         return;
      }
   }
   pos = line;
   fseek(fp,seekpos[line],0);
   while (p < l) {
      if ((c = getc(fp)) == EOF) {
         printf("Muster nicht gefunden\r\n",pattern);
         HALFOFF;
         pattern[0] = '\0';
         return;
      }
      if (pattern[p++] != c)  p = 0;
      pos += (c == '\n');
   }
   line = pos - MAXLINES/2;
   HALFOFF;
   output(MAXLINES);
}

linefind()
{
   int i,no;

   CURON;
   HALFON;
   pr_line();
   printf("Zeilennummer: ");
   gets(buf);
   CUROFF;
   no = atoi(buf);
   if (no < 1 || no > linesmax) {
      printf("%s nicht gefunden\r\n",buf);
      HALFOFF;
      return;
   }
   line = no - MAXLINES;
   HALFOFF;
   output(MAXLINES);
}

pr_line()
{
   int i=0;

   puts("\r\n");
   while (i++ < MAXROWS)
      putchar('-');
   puts("\r\n");
   CURUP;
}
