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

Diff for /src/usr.bin/readlink/readlink.c between version 1.9 and 1.10

version 1.9, 1997/08/18 20:27:53 version 1.10, 1997/09/23 20:13:21
Line 28 
Line 28 
  */   */
   
 #include <limits.h>  #include <limits.h>
   #include <errno.h>
 #include <stdio.h>  #include <stdio.h>
   #include <string.h>
 #include <unistd.h>  #include <unistd.h>
   
   void canonicalize __P((const char *, char *));
   
 int  int
 main(argc, argv)  main(argc, argv)
 int argc;          int argc;
 char **argv;          char **argv;
 {  {
         char buf[PATH_MAX];          char buf[PATH_MAX];
         int n, ch, nflag = 0;          int n, ch, nflag = 0, fflag = 0;
         extern int optind;          extern int optind;
   
         while ((ch = getopt(argc, argv, "n")) != -1)          while ((ch = getopt(argc, argv, "fn")) != -1)
                 switch (ch) {                  switch (ch) {
                   case 'f':
                           fflag = 1;
                           break;
                 case 'n':                  case 'n':
                         nflag = 1;                          nflag = 1;
                         break;                          break;
                 default:                  default:
                         (void)fprintf(stderr,                          (void)fprintf(stderr,
                             "usage: readlink [-n] symlink\n");                              "usage: readlink [-n] [-f] symlink\n");
                         exit(1);                          exit(1);
                 }                  }
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
   
         if (argc != 1) {          if (argc != 1) {
                 fprintf(stderr, "usage: readlink [-n] symlink\n");                  fprintf(stderr, "usage: readlink [-n] [-f] symlink\n");
                 exit(1);                  exit(1);
         }          }
   
         if ((n = readlink(argv[0], buf, PATH_MAX)) < 0)          n = strlen(argv[0]);
           if (n > PATH_MAX - 1)
                   errx(1, "filename longer than PATH_MAX-1 (%d)\n",
                       PATH_MAX - 1);
   
           if (fflag)
                   canonicalize(argv[0], buf);
           else if ((n = readlink(argv[0], buf, PATH_MAX)) < 0)
                 exit(1);                  exit(1);
   
         buf[n] = '\0';  
         printf("%s", buf);          printf("%s", buf);
         if (!nflag)          if (!nflag)
                 putchar('\n');                  putchar('\n');
         exit(0);          exit(0);
   }
   
   void
   canonicalize(path, newpath)
           const char *path;
           char *newpath;
   {
           int n;
           char *p, *np, *lp, c  ;
           char target[PATH_MAX];
   
           strcpy(newpath, path);
           for (;;) {
                   p = np = newpath;
   
                   /*
                    * If absolute path, skip the root slash now so we won't
                    * think of this as a NULL component.
                    */
                   if (*p == '/')
                           p++;
   
                   /*
                    * loop through all components of the path until a link is
                    * found then expand it, if no link is found we are ready.
                    */
                   for (; *p; lp = ++p) {
                           while (*p && *p != '/')
                                   p++;
                           c = *p;
                           *p = '\0';
                           n = readlink(newpath, target, PATH_MAX);
                           *p = c;
                           if (n > 0 || errno != EINVAL)
                                   break;
                   }
                   if (!*p && n < 0 && errno == EINVAL)
                           break;
                   if (n < 0)
                           err(1, "%s", newpath);
                   target[n] = '\0';
   #ifdef DEBUG
                   fprintf(stderr, "%.*s -> %s : ", p - newpath, newpath, target);
   #endif
                   if (*target == '/') {
                           bcopy(p, newpath + n, strlen(p) + 1);
                           bcopy(target, newpath, n);
                   } else {
                           bcopy(p, lp + n, strlen(p) + 1);
                           bcopy(target, lp, n);
                   }
   #ifdef DEBUG
                   fprintf(stderr, "%s\n", newpath);
   #endif
                   strcpy(target, newpath);
                   path = target;
           }
 }  }

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.10