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

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

version 1.9, 2002/05/29 18:33:39 version 1.10, 2002/06/17 07:06:39
Line 42 
Line 42 
   If your master sources are located in /usr/local/src/X and you would like    If your master sources are located in /usr/local/src/X and you would like
   your link tree to be in /usr/local/src/new-X, do the following:    your link tree to be in /usr/local/src/new-X, do the following:
   
         %  mkdir /usr/local/src/new-X          %  mkdir /usr/local/src/new-X
         %  cd /usr/local/src/new-X          %  cd /usr/local/src/new-X
         %  lndir ../X          %  lndir ../X
 */  */
   
 #include <stdio.h>  #include <stdio.h>
Line 80 
Line 80 
 struct except *exceptions = (struct except *)NULL;  struct except *exceptions = (struct except *)NULL;
   
 int  int
 main (argc, argv)  main(int argc, char *argv[])
         int     argc;  
         char    **argv;  
 {  {
         char *fn, *tn;  
         struct stat fs, ts;          struct stat fs, ts;
           char *fn, *tn;
   
         while (++argv, --argc) {          while (++argv, --argc) {
                 if ((strcmp(*argv, "-silent") == 0)                  if ((strcmp(*argv, "-silent") == 0) ||
                     || (strcmp(*argv, "-s") == 0))                      (strcmp(*argv, "-s") == 0))
                         silent = 1;                          silent = 1;
                 else if ((strcmp(*argv, "-ignorelinks") == 0)                  else if ((strcmp(*argv, "-ignorelinks") == 0) ||
                         || (strcmp(*argv, "-i") == 0))                      (strcmp(*argv, "-i") == 0))
                         ignore_links = 1;                          ignore_links = 1;
                 else if (strcmp(*argv, "-e") == 0) {                  else if (strcmp(*argv, "-e") == 0) {
                         ++argv, --argc;                          ++argv, --argc;
   
                         if (argc < 2)                          if (argc < 2)
                                 usage();                                  usage();
                         addexcept(*argv);                          addexcept(*argv);
                 } else if (strcmp(*argv, "--") == 0) {                  } else if (strcmp(*argv, "--") == 0) {
                         ++argv, --argc;                          ++argv, --argc;
                         break;                          break;
                 } else                  } else
                         break;                          break;
         }          }
   
           if (argc < 1 || argc > 2)
     if (argc < 1 || argc > 2)                  usage();
         usage();  
   
     fn = argv[0];          fn = argv[0];
     if (argc == 2)          if (argc == 2)
         tn = argv[1];                  tn = argv[1];
     else          else
         tn = ".";                  tn = ".";
   
     /* to directory */          /* to directory */
     if (stat(tn, &ts) < 0)          if (stat(tn, &ts) < 0)
         err(1, "%s", tn);                  err(1, "%s", tn);
     if (!(S_ISDIR(ts.st_mode)))          if (!(S_ISDIR(ts.st_mode)))
         errx(2, "%s: %s", tn, strerror(ENOTDIR));                  errx(2, "%s: %s", tn, strerror(ENOTDIR));
     if (chdir(tn) < 0)          if (chdir(tn) < 0)
         err(1, "%s", tn);                  err(1, "%s", tn);
   
     /* from directory */          /* from directory */
     if (stat(fn, &fs) < 0)          if (stat(fn, &fs) < 0)
         err(1, "%s", fn);                  err(1, "%s", fn);
     if (!(S_ISDIR(fs.st_mode)))          if (!(S_ISDIR(fs.st_mode)))
         err(2, "%s: %s", fn, strerror(ENOTDIR));                  err(2, "%s: %s", fn, strerror(ENOTDIR));
   
     exit(dodir (fn, &fs, &ts, 0));          exit(dodir(fn, &fs, &ts, 0));
 }  }
   
 int  int
 equivalent(lname, rname)  equivalent(char *lname, char *rname)
     char *lname;  
     char *rname;  
 {  {
     char *s;          char *s;
   
     if (!strcmp(lname, rname))          if (!strcmp(lname, rname))
         return(1);                  return(1);
     for (s = lname; *s && (s = strchr(s, '/')); s++) {          for (s = lname; *s && (s = strchr(s, '/')); s++) {
         while (s[1] == '/')                  while (s[1] == '/')
             strcpy(s+1, s+2);                          strcpy(s+1, s+2);
     }          }
     return(!strcmp(lname, rname));          return(!strcmp(lname, rname));
 }  }
   
 void  void
 addexcept(name)  addexcept(char *name)
     char *name;  
 {  {
     struct except *new;          struct except *new;
   
     new = (struct except *)malloc(sizeof(struct except));          new = (struct except *)malloc(sizeof(struct except));
     if (new == (struct except *)NULL)          if (new == (struct except *)NULL)
         err(1, "addexcept");                  err(1, "addexcept");
     new->name = strdup(name);          new->name = strdup(name);
     if (new->name == (char *)NULL)          if (new->name == (char *)NULL)
         err(1, "addexcept");                  err(1, "addexcept");
   
     new->next = exceptions;          new->next = exceptions;
     exceptions = new;          exceptions = new;
 }  }
   
   
Line 172 
Line 166 
  * Recursively create symbolic links from the current directory to the "from"   * Recursively create symbolic links from the current directory to the "from"
  * directory.  Assumes that files described by fs and ts are directories.   * directory.  Assumes that files described by fs and ts are directories.
  */   */
 int  #if 0
 dodir(fn, fs, ts, rel)  
         char *fn;               /* name of "from" directory, either absolute or          char *fn;               /* name of "from" directory, either absolute or
                                    relative to cwd */                                     relative to cwd */
         struct stat *fs, *ts;   /* stats for the "from" directory and cwd */          struct stat *fs, *ts;   /* stats for the "from" directory and cwd */
         int rel;                /* if true, prepend "../" to fn before using */          int rel;                /* if true, prepend "../" to fn before using */
   #endif
   int
   dodir(char *fn, struct stat *fs, struct stat *ts, int rel)
 {  {
     DIR *df;          char buf[MAXPATHLEN + 1], symbuf[MAXPATHLEN + 1], basesym[MAXPATHLEN + 1];
     struct dirent *dp;          int n_dirs, symlen, basesymlen = -1;
     char buf[MAXPATHLEN + 1], *p;          struct stat sb, sc;
     char symbuf[MAXPATHLEN + 1];          struct except *cur;
     char basesym[MAXPATHLEN + 1];          struct dirent *dp;
     struct stat sb, sc;          char *ocurdir, *p;
     int n_dirs;          DIR *df;
     int symlen;  
     int basesymlen = -1;  
     char *ocurdir;  
     struct except *cur;  
   
     if ((fs->st_dev == ts->st_dev) && (fs->st_ino == ts->st_ino)) {          if (fs->st_dev == ts->st_dev && fs->st_ino == ts->st_ino) {
         warn("%s: From and to directories are identical!", fn);                  warn("%s: From and to directories are identical!", fn);
         return(1);                  return(1);
     }          }
   
     if (rel)          if (rel)
         strcpy(buf, "../");                  strlcpy(buf, "../", sizeof buf);
     else          else
         buf[0] = '\0';                  buf[0] = '\0';
     strlcat(buf, fn, sizeof buf);          strlcat(buf, fn, sizeof buf);
   
     if (!(df = opendir(buf))) {          if (!(df = opendir(buf))) {
         warn("%s: Cannot opendir", buf);                  warn("%s: Cannot opendir", buf);
         return(1);                  return(1);
     }  
   
     p = buf + strlen(buf);  
     *p++ = '/';  
     n_dirs = fs->st_nlink;  
     while ((dp = readdir(df))) {  
         if (dp->d_name[strlen(dp->d_name) - 1] == '~')  
             continue;  
         for (cur = exceptions; cur != (struct except *)NULL;  
              cur = cur->next) {  
             if (!strcmp (dp->d_name, cur->name))  
                 goto next;      /* can't continue */  
         }          }
         strcpy(p, dp->d_name);  
   
         if (n_dirs > 0) {          p = buf + strlen(buf);
             if (stat(buf, &sb) < 0) {          *p++ = '/';
                 warn("%s", buf);          n_dirs = fs->st_nlink;
                 continue;          while ((dp = readdir(df))) {
             }                  if (dp->d_name[strlen(dp->d_name) - 1] == '~')
   
             if (S_ISDIR(sb.st_mode)) {  
                 /* directory */  
                 n_dirs--;  
                 if (dp->d_name[0] == '.' &&  
                     (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&  
                                                dp->d_name[2] == '\0')))  
                     continue;  
                 if (!strcmp(dp->d_name, "RCS"))  
                     continue;  
                 if (!strcmp(dp->d_name, "SCCS"))  
                     continue;  
                 if (!strcmp(dp->d_name, "CVS"))  
                     continue;  
                 if (!strcmp(dp->d_name, "CVS.adm"))  
                     continue;  
                 ocurdir = rcurdir;  
                 rcurdir = buf;  
                 curdir = silent ? buf : NULL;  
                 if (!silent)  
                     printf("%s:\n", buf);  
                 if ((stat(dp->d_name, &sc) < 0) && (errno == ENOENT)) {  
                     if (mkdir(dp->d_name, 0777) < 0 ||  
                         stat(dp->d_name, &sc) < 0) {  
                         warn("%s", dp->d_name);  
                         curdir = rcurdir = ocurdir;  
                         continue;                          continue;
                     }                  for (cur = exceptions; cur != (struct except *)NULL;
                       cur = cur->next) {
                           if (!strcmp (dp->d_name, cur->name))
                                   goto next;      /* can't continue */
                 }                  }
                 if (readlink(dp->d_name, symbuf, sizeof(symbuf) - 1) >= 0) {                  strcpy(p, dp->d_name);
                     (void)fprintf(stderr, "%s: is a link instead of a directory\n",  
                                 dp->d_name);                  if (n_dirs > 0) {
                     curdir = rcurdir = ocurdir;                          if (stat(buf, &sb) < 0) {
                     continue;                                  warn("%s", buf);
                                   continue;
                           }
   
                           if (S_ISDIR(sb.st_mode)) {
                                   /* directory */
                                   n_dirs--;
                                   if (dp->d_name[0] == '.' &&
                                       (dp->d_name[1] == '\0' || (dp->d_name[1] == '.' &&
                                       dp->d_name[2] == '\0')))
                                           continue;
                                   if (!strcmp(dp->d_name, "RCS"))
                                           continue;
                                   if (!strcmp(dp->d_name, "SCCS"))
                                           continue;
                                   if (!strcmp(dp->d_name, "CVS"))
                                           continue;
                                   if (!strcmp(dp->d_name, "CVS.adm"))
                                           continue;
                                   ocurdir = rcurdir;
                                   rcurdir = buf;
                                   curdir = silent ? buf : NULL;
                                   if (!silent)
                                           printf("%s:\n", buf);
                                   if (stat(dp->d_name, &sc) < 0 && errno == ENOENT) {
                                           if (mkdir(dp->d_name, 0777) < 0 ||
                                               stat(dp->d_name, &sc) < 0) {
                                                   warn("%s", dp->d_name);
                                                   curdir = rcurdir = ocurdir;
                                                   continue;
                                           }
                                   }
                                   if (readlink(dp->d_name, symbuf,
                                       sizeof(symbuf) - 1) >= 0) {
                                           fprintf(stderr,
                                               "%s: is a link instead of a directory\n",
                                               dp->d_name);
                                           curdir = rcurdir = ocurdir;
                                           continue;
                                   }
                                   if (chdir(dp->d_name) < 0) {
                                           warn("%s", dp->d_name);
                                           curdir = rcurdir = ocurdir;
                                           continue;
                                   }
                                   dodir(buf, &sb, &sc, (buf[0] != '/'));
                                   if (chdir("..") < 0)
                                           err(1, "..");
                                   curdir = rcurdir = ocurdir;
                                   continue;
                           }
                 }                  }
                 if (chdir(dp->d_name) < 0) {  
                     warn("%s", dp->d_name);  
                     curdir = rcurdir = ocurdir;  
                     continue;  
                 }  
                 dodir(buf, &sb, &sc, (buf[0] != '/'));  
                 if (chdir ("..") < 0)  
                     err (1, "..");  
                 curdir = rcurdir = ocurdir;  
                 continue;  
             }  
         }  
   
         /* non-directory */                  /* non-directory */
         symlen = readlink(dp->d_name, symbuf, sizeof(symbuf) - 1);                  symlen = readlink(dp->d_name, symbuf, sizeof(symbuf) - 1);
         if (symlen >= 0)                  if (symlen >= 0)
             symbuf[symlen] = '\0';                          symbuf[symlen] = '\0';
   
         /*                  /*
          * The option to ignore links exists mostly because                   * The option to ignore links exists mostly because
          * checking for them slows us down by 10-20%.                   * checking for them slows us down by 10-20%.
          * But it is off by default because this really is a useful check.                   * But it is off by default because this really is a useful check.
          */                   */
         if (!ignore_links) {                  if (!ignore_links) {
             /* see if the file in the base tree was a symlink */                          /* see if the file in the base tree was a symlink */
             basesymlen = readlink(buf, basesym, sizeof(basesym) - 1);                          basesymlen = readlink(buf, basesym, sizeof(basesym) - 1);
             if (basesymlen >= 0)                          if (basesymlen >= 0)
                 basesym[basesymlen] = '\0';                                  basesym[basesymlen] = '\0';
         }                  }
   
         if (symlen >= 0) {                  if (symlen >= 0) {
             /* Link exists in new tree.  Print message if it doesn't match. */                          /*
             if (!equivalent(basesymlen>=0 ? basesym : buf, symbuf))                           * Link exists in new tree.  Print message if
                 (void)fprintf(stderr,"%s: %s\n", dp->d_name, symbuf);                           * it doesn't match.
         } else {                           */
             if (symlink(basesymlen>=0 ? basesym : buf, dp->d_name) < 0)                          if (!equivalent(basesymlen>=0 ? basesym : buf, symbuf))
                 warn("%s", dp->d_name);                                  fprintf(stderr,"%s: %s\n", dp->d_name, symbuf);
         }                  } else {
                           if (symlink(basesymlen>=0 ? basesym : buf, dp->d_name) < 0)
                                   warn("%s", dp->d_name);
                   }
 next:  next:
     }          }
   
     closedir(df);          closedir(df);
     return(0);          return(0);
 }  }
   
 void  void
 usage()  usage(void)
 {  {
         (void)fprintf(stderr, "usage: %s [-e except] [-si] fromdir todir\n",          (void)fprintf(stderr, "usage: %s [-e except] [-si] fromdir todir\n",
                 __progname);              __progname);
         exit(1);          exit(1);
 }  }

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