[BACK]Return to fileio.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Diff for /src/usr.bin/mg/fileio.c between version 1.6 and 1.7

version 1.6, 2000/02/27 06:02:35 version 1.7, 2000/04/13 06:12:14
Line 1 
Line 1 
 /*  /*
  *              POSIX fileio.c   *      POSIX fileio.c
  */   */
 #include        "def.h"  #include        "def.h"
   
 static  FILE    *ffp;  static FILE    *ffp;
 char    *adjustname();  
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <sys/stat.h>  #include <sys/stat.h>
Line 13 
Line 12 
 /*  /*
  * Open a file for reading.   * Open a file for reading.
  */   */
 ffropen(fn, bp) char *fn; BUFFER *bp; {  int
         struct stat statbuf;  ffropen(fn, bp)
           char           *fn;
         if ((ffp=fopen(fn, "r")) == NULL)          BUFFER         *bp;
   {
           struct stat     statbuf;
   
           if ((ffp = fopen(fn, "r")) == NULL)
                 return (FIOFNF);                  return (FIOFNF);
         if (bp && fstat(fileno(ffp), &statbuf) == 0) {          if (bp && fstat(fileno(ffp), &statbuf) == 0) {
 /* set highorder bit to make sure this isn't all zero */                  /* set highorder bit to make sure this isn't all zero */
                 bp->b_fi.fi_mode = statbuf.st_mode | 0x8000;                  bp->b_fi.fi_mode = statbuf.st_mode | 0x8000;
                 bp->b_fi.fi_uid = statbuf.st_uid;                  bp->b_fi.fi_uid = statbuf.st_uid;
                 bp->b_fi.fi_gid = statbuf.st_gid;                  bp->b_fi.fi_gid = statbuf.st_gid;
Line 32 
Line 35 
  * Return TRUE if all is well, and   * Return TRUE if all is well, and
  * FALSE on error (cannot create).   * FALSE on error (cannot create).
  */   */
 ffwopen(fn, bp) char *fn; BUFFER *bp; {  int
         if ((ffp=fopen(fn, "w")) == NULL) {  ffwopen(fn, bp)
           char   *fn;
           BUFFER *bp;
   {
   
           if ((ffp = fopen(fn, "w")) == NULL) {
                 ewprintf("Cannot open file for writing");                  ewprintf("Cannot open file for writing");
                 return (FIOERR);                  return (FIOERR);
         }          }
         /*  
          * If we have file information, use it.  We don't bother          /*
          * to check for errors, because there's no a lot we can do           * If we have file information, use it.  We don't bother to check for
          * about it.  Certainly trying to change ownership will fail           * errors, because there's no a lot we can do about it.  Certainly
          * if we aren' root.  That's probably OK.  If we don't have           * trying to change ownership will fail if we aren' root.  That's
          * info, no need to get it, since any future writes will do           * probably OK.  If we don't have info, no need to get it, since any
          * the same thing.           * future writes will do the same thing.
          */           */
         if (bp && bp->b_fi.fi_mode) {          if (bp && bp->b_fi.fi_mode) {
                 chmod(fn, bp->b_fi.fi_mode & 07777);                  chmod(fn, bp->b_fi.fi_mode & 07777);
Line 54 
Line 62 
   
 /*  /*
  * Close a file.   * Close a file.
  * Should look at the status.   * XXX - Should look at the status.
  */   */
 ffclose() {  /* ARGSUSED */
   int
   ffclose(bp)
           BUFFER *bp;
   {
   
         (VOID) fclose(ffp);          (VOID) fclose(ffp);
         return (FIOSUC);          return (FIOSUC);
 }  }
Line 68 
Line 81 
  * Check only at the newline and   * Check only at the newline and
  * end of buffer.   * end of buffer.
  */   */
   int
 ffputbuf(bp)  ffputbuf(bp)
 BUFFER *bp;          BUFFER *bp;
 {  {
     register char *cp;          char   *cp;
     register char *cpend;          char   *cpend;
     register LINE *lp;          LINE   *lp;
     register LINE *lpend;          LINE   *lpend;
   
     lpend = bp->b_linep;          lpend = bp->b_linep;
     lp = lforw(lpend);          lp = lforw(lpend);
     do {          do {
         cp = &ltext(lp)[0];             /* begining of line     */                  cp = &ltext(lp)[0];             /* begining of line      */
         cpend = &cp[llength(lp)];       /* end of line          */                  cpend = &cp[llength(lp)];       /* end of line           */
         while(cp != cpend) {                  while (cp != cpend) {
             putc(*cp, ffp);                          putc(*cp, ffp);
             cp++;       /* putc may evalualte arguments more than once */                          cp++;                   /* putc may evaluate arguments
                                                      more than once */
                   }
                   lp = lforw(lp);
                   if (lp == lpend)
                           break;                  /* no implied \n on last line */
                   putc('\n', ffp);
           } while (!ferror(ffp));
           if (ferror(ffp)) {
                   ewprintf("Write I/O error");
                   return FIOERR;
         }          }
         lp = lforw(lp);          return (FIOSUC);
         if(lp == lpend) break;          /* no implied newline on last line */  
         putc('\n', ffp);  
     } while(!ferror(ffp));  
     if(ferror(ffp)) {  
         ewprintf("Write I/O error");  
         return FIOERR;  
     }  
     return FIOSUC;  
 }  }
   
 /*  /*
Line 102 
Line 118 
  * line.  When FIOEOF is returned, there is a valid line   * line.  When FIOEOF is returned, there is a valid line
  * of data without the normally implied \n.   * of data without the normally implied \n.
  */   */
   int
 ffgetline(buf, nbuf, nbytes)  ffgetline(buf, nbuf, nbytes)
 register char   *buf;          char  *buf;
 register int    nbuf;          int    nbuf;
 register int    *nbytes;          int   *nbytes;
 {  {
         register int    c;          int    c;
         register int    i;          int    i;
   
         i = 0;          i = 0;
         while((c = getc(ffp))!=EOF && c!='\n') {          while ((c = getc(ffp)) != EOF && c != '\n') {
                 buf[i++] = c;                  buf[i++] = c;
                 if (i >= nbuf) return FIOLONG;                  if (i >= nbuf)
                           return FIOLONG;
         }          }
         if (c == EOF  && ferror(ffp) != FALSE) {          if (c == EOF && ferror(ffp) != FALSE) {
                 ewprintf("File read error");                  ewprintf("File read error");
                 return FIOERR;                  return FIOERR;
         }          }
         *nbytes = i;          *nbytes = i;
         return c==EOF ? FIOEOF : FIOSUC;          return c == EOF ? FIOEOF : FIOSUC;
 }  }
   
 #ifndef NO_BACKUP  #ifndef NO_BACKUP
Line 133 
Line 151 
  * right thing here; I don't care that much as   * right thing here; I don't care that much as
  * I don't enable backups myself.   * I don't enable backups myself.
  */   */
 fbackupfile(fn) char *fn; {  int
         register char   *nname;  fbackupfile(fn)
         char            *malloc(), *strrchr();          char  *fn;
         int             i;  {
         char            *lastpart;          char  *nname;
   
         if ((nname=malloc((unsigned)(strlen(fn)+1+1))) == NULL) {          if ((nname = malloc((unsigned) (strlen(fn) + 1 + 1))) == NULL) {
                 ewprintf("Can't get %d bytes", strlen(fn) + 1);                  ewprintf("Can't get %d bytes", strlen(fn) + 1);
                 return (ABORT);                  return (ABORT);
         }          }
Line 169 
Line 187 
 #endif  #endif
 #include <pwd.h>  #include <pwd.h>
 #ifndef NO_DIR  #ifndef NO_DIR
 extern char *wdir;  extern char    *wdir;
 #endif  #endif
   
 char *adjustname(fn)  char *
 register char *fn;  adjustname(fn)
           char           *fn;
 {  {
     register char *cp;          char           *cp;
     static char fnb[NFILEN];          static char     fnb[NFILEN];
     struct passwd *pwent;          struct passwd  *pwent;
 #ifdef  SYMBLINK  #ifdef  SYMBLINK
     struct stat statbuf;          struct stat     statbuf;
     int i, j;          int             i, j;
     char linkbuf[NFILEN];          char            linkbuf[NFILEN];
 #endif  #endif
   
     switch(*fn) {          switch (*fn) {
         case '/':          case '/':
             cp = fnb;  
             *cp++ = *fn++;  
             break;  
         case '~':  
             fn++;  
             if(*fn == '/' || *fn == '\0') {  
                 (VOID) strcpy(fnb, getenv("HOME"));  
                 cp = fnb + strlen(fnb);  
                 if(*fn) fn++;  
                 break;  
             } else {  
                 cp = fnb;                  cp = fnb;
                 while(*fn && *fn != '/') *cp++ = *fn++;                  *cp++ = *fn++;
                 *cp = '\0';                  break;
                 if((pwent = getpwnam(fnb)) != NULL) {          case '~':
                     (VOID) strcpy(fnb, pwent->pw_dir);                  fn++;
                     cp = fnb + strlen(fnb);                  if (*fn == '/' || *fn == '\0') {
                     break;                          (VOID) strcpy(fnb, getenv("HOME"));
                           cp = fnb + strlen(fnb);
                           if (*fn)
                                   fn++;
                           break;
                 } else {                  } else {
                     fn -= strlen(fnb) + 1;                          cp = fnb;
                     /* can't find ~user, continue to default case */                          while (*fn && *fn != '/')
                                   *cp++ = *fn++;
                           *cp = '\0';
                           if ((pwent = getpwnam(fnb)) != NULL) {
                                   (VOID) strcpy(fnb, pwent->pw_dir);
                                   cp = fnb + strlen(fnb);
                                   break;
                           } else {
                                   fn -= strlen(fnb) + 1;
                                   /* can't find ~user, continue to default case */
                           }
                 }                  }
             }  
         default:          default:
 #ifndef NODIR  #ifndef NODIR
             strcpy(fnb, wdir);                  strcpy(fnb, wdir);
             cp = fnb + strlen(fnb);                  cp = fnb + strlen(fnb);
             break;                  break;
 #else  #else
             return fn;                          /* punt */                  return fn;      /* punt */
 #endif  #endif
     }          }
     if(cp != fnb && cp[-1] != '/') *cp++ = '/';          if (cp != fnb && cp[-1] != '/')
     while(*fn) {                  *cp++ = '/';
         switch(*fn) {          while (*fn) {
             case '.':                  switch (*fn) {
                 switch(fn[1]) {                  case '.':
                     case '\0':                          switch (fn[1]) {
                         *--cp = '\0';                          case '\0':
                         return fnb;                                  *--cp = '\0';
                     case '/':                                  return fnb;
                         fn += 2;                          case '/':
                         continue;                                  fn += 2;
                     case '.':                                  continue;
                         if(fn[2]=='/' || fn[2] == '\0') {                          case '.':
                                   if (fn[2] != '/' && fn[2] != '\0')
                                           break;
 #ifdef SYMBLINK  #ifdef SYMBLINK
                             cp[-1] = '\0';                                  cp[-1] = '\0';
                             for(j = MAXLINK; j-- &&                                  for (j = MAXLINK; j-- &&
                                     lstat(fnb, &statbuf) != -1 &&                                       lstat(fnb, &statbuf) != -1 &&
                                     (statbuf.st_mode&S_IFMT) == S_IFLNK &&                                       (statbuf.st_mode & S_IFMT) == S_IFLNK &&
                                     (i = readlink(fnb, linkbuf, sizeof linkbuf))                                       (i = readlink(fnb, linkbuf, sizeof linkbuf))
                                     != -1 ;) {                                       != -1;) {
                                 if(linkbuf[0] != '/') {                                          if (linkbuf[0] != '/') {
                                     --cp;                                                  --cp;
                                     while(cp > fnb && *--cp != '/') {}                                                  while (cp > fnb && *--cp != '/') {
                                     ++cp;                                                  }
                                     (VOID) strncpy(cp, linkbuf, i);                                                  ++cp;
                                     cp += i;                                                  (VOID) strncpy(cp, linkbuf, i);
                                 } else {                                                  cp += i;
                                     (VOID) strncpy(fnb, linkbuf, i);                                          } else {
                                     cp = fnb + i;                                                  (VOID) strncpy(fnb, linkbuf, i);
                                                   cp = fnb + i;
                                           }
                                           if (cp[-1] != '/')
                                                   *cp++ = '\0';
                                           else
                                                   cp[-1] = '\0';
                                 }                                  }
                                 if(cp[-1]!='/') *cp++ = '\0';                                  cp[-1] = '/';
                                 else cp[-1] = '\0';  
                             }  
                             cp[-1] = '/';  
 #endif  #endif
                             --cp;                                  --cp;
                             while(cp > fnb && *--cp != '/') {}                                  while (cp > fnb && *--cp != '/') {
                             ++cp;                                  }
                             if(fn[2]=='\0') {                                  ++cp;
                                 *--cp = '\0';                                  if (fn[2] == '\0') {
                                 return fnb;                                          *--cp = '\0';
                             }                                          return fnb;
                             fn += 3;                                  }
                             continue;                                  fn += 3;
                         }                                  continue;
                         break;                          default:
                     default:                                  break;
                         break;                          }
                 }                          break;
                 break;                  case '/':
             case '/':                          fn++;
                 fn++;                          continue;
                 continue;                  default:
             default:                          break;
                 break;                  }
                   while (*fn && (*cp++ = *fn++) != '/') {
                   }
         }          }
         while(*fn && (*cp++ = *fn++) != '/') {}          if (cp[-1] == '/')
     }                  --cp;
     if(cp[-1]=='/') --cp;          *cp = '\0';
     *cp = '\0';          return fnb;
     return fnb;  
 }  }
   
 #ifndef NO_STARTUP  #ifndef NO_STARTUP
Line 292 
Line 319 
  */   */
 char *  char *
 startupfile(suffix)  startupfile(suffix)
 char *suffix;          char           *suffix;
 {  {
         register char   *file;          char           *file;
         static char     home[NFILEN];          static char     home[NFILEN];
   
         if ((file = getenv("HOME")) == NULL) goto notfound;          if ((file = getenv("HOME")) == NULL)
         if (strlen(file)+7 >= NFILEN - 1) goto notfound;                  goto notfound;
           if (strlen(file) + 7 >= NFILEN - 1)
                   goto notfound;
         (VOID) strcpy(home, file);          (VOID) strcpy(home, file);
         (VOID) strcat(home, "/.mg");          (VOID) strcat(home, "/.mg");
         if (suffix != NULL) {          if (suffix != NULL) {
                 (VOID) strcat(home, "-");                  (VOID) strcat(home, "-");
                 (VOID) strcat(home, suffix);                  (VOID) strcat(home, suffix);
         }          }
         if (access(home, F_OK) == 0) return home;          if (access(home, F_OK) == 0)
                   return home;
   
 notfound:  notfound:
 #ifdef  STARTUPFILE  #ifdef  STARTUPFILE
Line 316 
Line 346 
                 (VOID) strcat(home, suffix);                  (VOID) strcat(home, suffix);
                 file = home;                  file = home;
         }          }
         if (access(file, F_OK ) == 0) return file;          if (access(file, F_OK) == 0)
                   return file;
 #endif  #endif
   
         return NULL;          return NULL;
Line 327 
Line 358 
 #include <sys/wait.h>  #include <sys/wait.h>
 #include "kbd.h"  #include "kbd.h"
   
   int
 copy(frname, toname)  copy(frname, toname)
 char *frname, *toname;          char   *frname;
           char   *toname;
 {  {
     pid_t pid;          pid_t   pid;
     int status;          int     status;
   
     if(pid = vfork()) {          if ((pid = vfork())) {
         if(pid == -1)   return  -1;                  if (pid == -1)
         execl("/bin/cp", "cp", frname, toname, (char *)NULL);                          return -1;
         _exit(1);       /* shouldn't happen */                  execl("/bin/cp", "cp", frname, toname, (char *) NULL);
     }                  _exit(1);       /* shouldn't happen */
     while(wait(&status) != pid)          }
         ;          while (wait(&status) != pid);
     return status == 0;          return status == 0;
 }  }
   
 BUFFER *dired_(dirname)  BUFFER *
 char *dirname;  dired_(dirname)
           char   *dirname;
 {  {
     register BUFFER *bp;          BUFFER *bp;
     char line[256];          FILE   *dirpipe;
     BUFFER *findbuffer();          char    line[256];
     FILE *dirpipe;  
     FILE *popen();  
     char *strncpy();  
   
     if((dirname = adjustname(dirname)) == NULL) {          if ((dirname = adjustname(dirname)) == NULL) {
         ewprintf("Bad directory name");                  ewprintf("Bad directory name");
         return NULL;                  return NULL;
     }          }
     if(dirname[strlen(dirname)-1] != '/') (VOID) strcat(dirname, "/");          if (dirname[strlen(dirname) - 1] != '/')
     if((bp = findbuffer(dirname)) == NULL) {                  (VOID) strcat(dirname, "/");
         ewprintf("Could not create buffer");          if ((bp = findbuffer(dirname)) == NULL) {
         return NULL;                  ewprintf("Could not create buffer");
     }                  return NULL;
     if(bclear(bp) != TRUE) return FALSE;          }
     (VOID) strcpy(line, "ls -al ");          if (bclear(bp) != TRUE)
     (VOID) strcpy(&line[7], dirname);                  return FALSE;
     if((dirpipe = popen(line, "r")) == NULL) {          (VOID) strcpy(line, "ls -al ");
         ewprintf("Problem opening pipe to ls");          (VOID) strcpy(&line[7], dirname);
         return NULL;          if ((dirpipe = popen(line, "r")) == NULL) {
     }                  ewprintf("Problem opening pipe to ls");
     line[0] = line[1] = ' ';                  return NULL;
     while(fgets(&line[2], 254, dirpipe) != NULL) {          }
         line[strlen(line) - 1] = '\0';          /* remove ^J    */          line[0] = line[1] = ' ';
         (VOID) addline(bp, line);          while (fgets(&line[2], 254, dirpipe) != NULL) {
     }                  line[strlen(line) - 1] = '\0';  /* remove ^J     */
     if(pclose(dirpipe) == -1) {                  (VOID) addline(bp, line);
         ewprintf("Problem closing pipe to ls");          }
         return NULL;          if (pclose(dirpipe) == -1) {
     }                  ewprintf("Problem closing pipe to ls");
     bp->b_dotp = lforw(bp->b_linep);            /* go to first line */                  return NULL;
     (VOID) strncpy(bp->b_fname, dirname, NFILEN);          }
     if((bp->b_modes[0] = name_mode("dired")) == NULL) {          bp->b_dotp = lforw(bp->b_linep);        /* go to first line */
         bp->b_modes[0] = &map_table[0];          (VOID) strncpy(bp->b_fname, dirname, NFILEN);
         ewprintf("Could not find mode dired");          if ((bp->b_modes[0] = name_mode("dired")) == NULL) {
         return NULL;                  bp->b_modes[0] = &map_table[0];
     }                  ewprintf("Could not find mode dired");
     bp->b_nmodes = 0;                  return NULL;
     return bp;          }
           bp->b_nmodes = 0;
           return bp;
 }  }
   
   int
 d_makename(lp, fn)  d_makename(lp, fn)
 register LINE *lp;          LINE  *lp;
 register char *fn;          char  *fn;
 {  {
     register char *cp;          char  *cp;
   
     if(llength(lp) <= 56) return ABORT;          if (llength(lp) <= 56)
     (VOID) strcpy(fn, curbp->b_fname);                  return ABORT;
     cp = fn + strlen(fn);          (VOID) strcpy(fn, curbp->b_fname);
     bcopy(&lp->l_text[56], cp, llength(lp) - 56);          cp = fn + strlen(fn);
     cp[llength(lp) - 56] = '\0';          bcopy(&lp->l_text[56], cp, llength(lp) - 56);
     return lgetc(lp, 2) == 'd';          cp[llength(lp) - 56] = '\0';
           return lgetc(lp, 2) == 'd';
 }  }
 #endif NO_DIRED  #endif                          /* NO_DIRED */
   
 struct filelist {  struct filelist {
    LIST fl_l;          LIST            fl_l;
    char fl_name[NFILEN+2];          char            fl_name[NFILEN + 2];
 };  };
   
 /* these things had better be contiguous, because we're going  /*
  * to refer to the end of dirbuf + 1 byte */   * these things had better be contiguous, because we're going to refer to the
 struct direct dirbuf;   * end of dirbuf + 1 byte
 char dirdummy;   */
   struct dirent   dirbuf;
   char            dirdummy;
   
 /*  /*
  * return list of file names that match the name in buf.   * return list of file names that match the name in buf.
Line 422 
Line 459 
  * for executables and directories.  The list is not sorted.   * for executables and directories.  The list is not sorted.
  */   */
   
 LIST *make_file_list(buf,listing)  LIST *
   char *buf;  make_file_list(buf, listing)
   int listing;          char           *buf;
           int             listing;
 {  {
 char *dir,*file,*cp;          char           *dir, *file, *cp;
 int len,i,preflen;          int             len, i, preflen;
 int fp;          int             fp;
 LIST *last,*l1,*l2;          LIST           *last;
 struct filelist *current;          struct filelist *current;
 char prefixx[NFILEN+1];          char            prefixx[NFILEN + 1];
 extern int errno;          struct stat     statbuf;
 struct stat statbuf;          char            statname[NFILEN + 2];
 char statname[NFILEN+2];  
   
 /* We need three different strings:          /*
  *   dir - the name of the directory containing what the user typed.           * We need three different strings: dir - the name of the directory
  *         Must be a real unix file name, e.g. no ~user, etc..  Must           * containing what the user typed. Must be a real unix file name,
  *         not end in /.           * e.g. no ~user, etc..  Must not end in /. prefix - the portion of
  *   prefix - the portion of what the user typed that is before           * what the user typed that is before the names we are going to find
  *         the names we are going to find in the directory.  Must have           * in the directory.  Must have a trailing / if the user typed it.
  *         a trailing / if the user typed it.           * names from the directory. we open dir, and return prefix
  *   names from the directory.           * concatenated with names.
  *   we open dir, and return prefix concatenated with names.           */
  */  
   
 /* first we get a directory name we can look up */          /* first we get a directory name we can look up */
 /* names ending in . are potentially odd, because adjustname          /*
  * will treat foo/.. as a reference to another directory,           * Names ending in . are potentially odd, because adjustname will
  * whereas we are interested in names starting with ..           * treat foo/.. as a reference to another directory, whereas we are
  */           * interested in names starting with ..
 len = strlen(buf);           */
 if (buf[len-1] == '.') {          len = strlen(buf);
         buf[len-1] = 'x';          if (buf[len - 1] == '.') {
         dir = adjustname(buf);                  buf[len - 1] = 'x';
         buf[len-1] = '.';                  dir = adjustname(buf);
 }                  buf[len - 1] = '.';
 else          } else
         dir = adjustname(buf);                  dir = adjustname(buf);
 /*          /*
  * if the user typed a trailing / or the empty string           * If the user typed a trailing / or the empty string
  * he wants us to use his file spec as a directory name           * he wants us to use his file spec as a directory name.
  */           */
 if (buf[0] && buf[strlen(buf)-1] != '/') {          if (buf[0] && buf[strlen(buf) - 1] != '/') {
         file = strrchr(dir, '/');                  file = strrchr(dir, '/');
         if (file) {                  if (file) {
                 *file = 0;                          *file = 0;
                 if (*dir == 0)                          if (*dir == 0)
                         dir = "/";                                  dir = "/";
                   } else {
                           return (NULL);
                   }
         }          }
         else {          /* Now we get the prefix of the name the user typed. */
                 return(NULL);          strcpy(prefixx, buf);
         }          cp = strrchr(prefixx, '/');
 }          if (cp == NULL)
                   prefixx[0] = 0;
           else
                   cp[1] = 0;
   
 /* now we get the prefix of the name the user typed */          preflen = strlen(prefixx);
 strcpy(prefixx,buf);          /* cp is the tail of buf that really needs to be compared */
 cp = strrchr(prefixx, '/');          cp = buf + preflen;
 if (cp == NULL)          len = strlen(cp);
         prefixx[0] = 0;  
 else  
         cp[1] = 0;  
   
 preflen = strlen(prefixx);          /*
 /* cp is the tail of buf that really needs to be compared */           * Now make sure that file names will fit in the buffers allocated.
 cp = buf + preflen;           * SV files are fairly short.  For BSD, something more general would
 len = strlen(cp);           * be required.
            */
           if ((preflen + MAXNAMLEN) > NFILEN)
                   return (NULL);
           if ((strlen(dir) + MAXNAMLEN) > NFILEN)
                   listing = 0;
   
 /*          /* loop over the specified directory, making up the list of files */
  * Now make sure that file names will fit in the buffers allocated.  
  * SV files are fairly short.  For BSD, something more general  
  * would be required.  
  */  
 if ((preflen + MAXNAMLEN) > NFILEN)  
         return(NULL);  
 if ((strlen(dir) + MAXNAMLEN) > NFILEN)  
         listing = 0;  
   
 /* loop over the specified directory, making up the list of files */          /*
            * Note that it is worth our time to filter out names that don't
            * match, even though our caller is going to do so again, and to
            * avoid doing the stat if completion is being done, because stat'ing
            * every file in the directory is relatively expensive.
            */
   
 /*          fp = open(dir, 0);
  * Note that it is worth our time to filter out names that don't          if (fp < 0) {
  * match, even though our caller is going to do so again, and to                  return (NULL);
  * avoid doing the stat if completion is being done, because stat'ing  
  * every file in the directory is relatively expensive.  
  */  
   
 fp = open(dir,0);  
 if (fp < 0) {  
         return(NULL);  
 }  
   
 last = NULL;  
 /* clear entry after last so we can treat d_name as ASCIZ */  
 dirbuf.d_name[MAXNAMLEN] = 0;  
 while (1) {  
         if (read(fp, &dirbuf, sizeof(struct direct)) <= 0) {  
                 break;  
         }          }
         if (dirbuf.d_ino == 0)  /* entry not allocated */          last = NULL;
                 continue;          /* clear entry after last so we can treat d_name as ASCIZ */
         for (i=0; i<len; ++i) {          dirbuf.d_name[MAXNAMLEN] = 0;
                 if (cp[i] != dirbuf.d_name[i])          while (1) {
                   if (read(fp, &dirbuf, sizeof(struct dirent)) <= 0) {
                         break;                          break;
                   }
                   if (dirbuf.d_ino == 0)  /* entry not allocated */
                           continue;
                   for (i = 0; i < len; ++i) {
                           if (cp[i] != dirbuf.d_name[i])
                                   break;
                   }
                   if (i < len)
                           continue;
                   current = (struct filelist *) malloc(sizeof(struct filelist));
                   current->fl_l.l_next = last;
                   current->fl_l.l_name = current->fl_name;
                   last = (LIST *) current;
                   strcpy(current->fl_name, prefixx);
                   strcat(current->fl_name, dirbuf.d_name);
                   if (listing) {
                           statbuf.st_mode = 0;
                           strcpy(statname, dir);
                           strcat(statname, "/");
                           strcat(statname, dirbuf.d_name);
                           stat(statname, &statbuf);
                           if (statbuf.st_mode & 040000)
                                   strcat(current->fl_name, "/");
                           else if (statbuf.st_mode & 0100)
                                   strcat(current->fl_name, "*");
                   }
         }          }
         if (i < len)          close(fp);
                 continue;  
         current = (struct filelist *)malloc(sizeof(struct filelist));  
         current->fl_l.l_next = last;  
         current->fl_l.l_name = current->fl_name;  
         last = (LIST *)current;  
         strcpy(current->fl_name,prefixx);  
         strcat(current->fl_name,dirbuf.d_name);  
         if (listing) {  
                 statbuf.st_mode = 0;  
                 strcpy(statname,dir);  
                 strcat(statname,"/");  
                 strcat(statname,dirbuf.d_name);  
                 stat(statname,&statbuf);  
                 if (statbuf.st_mode & 040000)  
                         strcat(current->fl_name,"/");  
                 else if (statbuf.st_mode & 0100)  
                         strcat(current->fl_name,"*");  
         }  
   
 }          return (last);
 close(fp);  
   
 return (last);  
   
 }  }

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7