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

Diff for /src/usr.bin/cvs/file.c between version 1.33 and 1.34

version 1.33, 2004/08/31 11:17:02 version 1.34, 2004/11/26 16:23:50
Line 86 
Line 86 
   
   
 /*  /*
    * Filename hash table used to avoid duplication of name strings when working
    * on large source trees with common parts.
    */
   
   SLIST_HEAD(cvs_fhb, cvs_fname);
   
   static struct cvs_fhb cvs_fnht[CVS_FILE_NBUCKETS];
   
   
   
   /*
  * Entries in the CVS/Entries file with a revision of '0' have only been   * Entries in the CVS/Entries file with a revision of '0' have only been
  * added.  Compare against this revision to see if this is the case   * added.  Compare against this revision to see if this is the case
  */   */
Line 95 
Line 106 
 TAILQ_HEAD(, cvs_ignpat)  cvs_ign_pats;  TAILQ_HEAD(, cvs_ignpat)  cvs_ign_pats;
   
   
 static int        cvs_file_getdir  (CVSFILE *, int);  static int               cvs_file_getdir   (CVSFILE *, int);
 static void       cvs_file_freedir (struct cvs_dir *);  static void              cvs_file_freedir  (struct cvs_dir *);
 static int        cvs_file_sort    (struct cvs_flist *, u_int);  static int               cvs_file_sort     (struct cvs_flist *, u_int);
 static int        cvs_file_cmp     (const void *, const void *);  static int               cvs_file_cmp      (const void *, const void *);
 static int        cvs_file_cmpname (const char *, const char *);  static int               cvs_file_cmpname  (const char *, const char *);
 static CVSFILE*   cvs_file_alloc   (const char *, u_int);  static u_int8_t          cvs_file_hashname (const char *);
 static CVSFILE*   cvs_file_lget    (const char *, int, CVSFILE *);  static struct cvs_fname* cvs_file_getname  (const char *);
   static CVSFILE*          cvs_file_alloc    (const char *, u_int);
   static CVSFILE*          cvs_file_lget     (const char *, int, CVSFILE *);
   
   
   
Line 119 
Line 132 
         FILE *ifp;          FILE *ifp;
         struct passwd *pwd;          struct passwd *pwd;
   
           /* initialize the filename hash table */
           for (i = 0; i < CVS_FILE_NBUCKETS; i++)
                   SLIST_INIT(&(cvs_fnht[i]));
   
         TAILQ_INIT(&cvs_ign_pats);          TAILQ_INIT(&cvs_ign_pats);
   
         cvs_addedrev = rcsnum_alloc();          cvs_addedrev = rcsnum_alloc();
Line 135 
Line 152 
                 ifp = fopen(path, "r");                  ifp = fopen(path, "r");
                 if (ifp == NULL) {                  if (ifp == NULL) {
                         if (errno != ENOENT)                          if (errno != ENOENT)
                                 cvs_log(LP_ERRNO, "failed to open `%s'", path);                                  cvs_log(LP_ERRNO,
                                       "failed to open user's cvsignore", path);
                 }                  }
                 else {                  else {
                         while (fgets(buf, sizeof(buf), ifp) != NULL) {                          while (fgets(buf, sizeof(buf), ifp) != NULL) {
Line 233 
Line 251 
  */   */
   
 CVSFILE*  CVSFILE*
 cvs_file_create(const char *path, u_int type, mode_t mode)  cvs_file_create(CVSFILE *parent, const char *path, u_int type, mode_t mode)
 {  {
         int fd;          int fd;
           char fp[MAXPATHLEN];
         CVSFILE *cfp;          CVSFILE *cfp;
   
           printf("cvs_file_create(%s)\n", path);
         cfp = cvs_file_alloc(path, type);          cfp = cvs_file_alloc(path, type);
         if (cfp == NULL)          if (cfp == NULL)
                 return (NULL);                  return (NULL);
   
         cfp->cf_type = type;          cfp->cf_type = type;
         cfp->cf_mode = mode;          cfp->cf_mode = mode;
         cfp->cf_ddat->cd_root = cvsroot_get(path);          cfp->cf_parent = parent;
         cfp->cf_ddat->cd_repo = strdup(cfp->cf_path);  
   
         if (cfp->cf_ddat->cd_repo == NULL) {  
                 cvs_file_free(cfp);  
                 return (NULL);  
         }  
   
         if (type == DT_DIR) {          if (type == DT_DIR) {
                   cfp->cf_ddat->cd_root = cvsroot_get(path);
                   cfp->cf_ddat->cd_repo = strdup(cvs_file_getpath(cfp,
                       fp, sizeof(fp)));
                   if (cfp->cf_ddat->cd_repo == NULL) {
                           cvs_file_free(cfp);
                           return (NULL);
                   }
   
                 if ((mkdir(path, mode) == -1) || (cvs_mkadmin(cfp, mode) < 0)) {                  if ((mkdir(path, mode) == -1) || (cvs_mkadmin(cfp, mode) < 0)) {
                         cvs_file_free(cfp);                          cvs_file_free(cfp);
                         return (NULL);                          return (NULL);
Line 389 
Line 411 
                 }                  }
   
                 TAILQ_FOREACH(sf, &(cf->cf_ddat->cd_files), cf_list)                  TAILQ_FOREACH(sf, &(cf->cf_ddat->cd_files), cf_list)
                         if (cvs_file_cmpname(pp, sf->cf_name) == 0)                          if (cvs_file_cmpname(pp, CVS_FILE_NAME(sf)) == 0)
                                 break;                                  break;
                 if (sf == NULL)                  if (sf == NULL)
                         return (NULL);                          return (NULL);
Line 403 
Line 425 
   
   
 /*  /*
    * cvs_file_getpath()
    *
    * Get the full path of the file <file> and store it in <buf>, which is of
    * size <len>.  For portability, it is recommended that <buf> always be
    * at least MAXPATHLEN bytes long.
    * Returns a pointer to the start of the path on success, or NULL on failure.
    */
   
   char*
   cvs_file_getpath(CVSFILE *file, char *buf, size_t len)
   {
           u_int i;
           char *fp, *namevec[CVS_FILE_MAXDEPTH];
           CVSFILE *top;
   
           buf[0] = '\0';
           i = CVS_FILE_MAXDEPTH;
           memset(namevec, 0, sizeof(namevec));
   
           /* find the top node */
           for (top = file; (top != NULL) && (i > 0); top = top->cf_parent) {
                   fp = CVS_FILE_NAME(top);
   
                   /* skip self-references */
                   if ((fp[0] == '.') && (fp[1] == '\0'))
                           continue;
                   namevec[--i] = fp;
           }
   
           if (i == 0)
                   return (NULL);
           else if (i == CVS_FILE_MAXDEPTH) {
                   strlcpy(buf, ".", len);
                   return (buf);
           }
   
           while (i < CVS_FILE_MAXDEPTH - 1) {
                   strlcat(buf, namevec[i++], len);
                   strlcat(buf, "/", len);
           }
           strlcat(buf, namevec[i], len);
   
           return (buf);
   }
   
   
   /*
  * cvs_file_attach()   * cvs_file_attach()
  *   *
  * Attach the file <file> as one of the children of parent <parent>, which   * Attach the file <file> as one of the children of parent <parent>, which
Line 443 
Line 512 
         u_int ndirs;          u_int ndirs;
         long base;          long base;
         void *dp, *ep;          void *dp, *ep;
         char fbuf[2048], pbuf[MAXPATHLEN];          char fbuf[2048], pbuf[MAXPATHLEN], fpath[MAXPATHLEN];
         struct dirent *ent;          struct dirent *ent;
         CVSFILE *cfp;          CVSFILE *cfp;
         struct stat st;          struct stat st;
Line 454 
Line 523 
         TAILQ_INIT(&dirs);          TAILQ_INIT(&dirs);
         cdp = cf->cf_ddat;          cdp = cf->cf_ddat;
   
           cvs_file_getpath(cf, fpath, sizeof(fpath));
   
         if (cf->cf_cvstat != CVS_FST_UNKNOWN) {          if (cf->cf_cvstat != CVS_FST_UNKNOWN) {
                 cdp->cd_root = cvsroot_get(cf->cf_path);                  cdp->cd_root = cvsroot_get(fpath);
                 if (cdp->cd_root == NULL)                  if (cdp->cd_root == NULL)
                         return (-1);                          return (-1);
   
Line 463 
Line 534 
                         cvs_mkadmin(cf, 0755);                          cvs_mkadmin(cf, 0755);
   
                 /* if the CVS administrative directory exists, load the info */                  /* if the CVS administrative directory exists, load the info */
                 snprintf(pbuf, sizeof(pbuf), "%s/" CVS_PATH_CVSDIR,                  snprintf(pbuf, sizeof(pbuf), "%s/" CVS_PATH_CVSDIR, fpath);
                     cf->cf_path);  
                 if ((stat(pbuf, &st) == 0) && S_ISDIR(st.st_mode)) {                  if ((stat(pbuf, &st) == 0) && S_ISDIR(st.st_mode)) {
                         if (cvs_readrepo(cf->cf_path, pbuf,                          if (cvs_readrepo(fpath, pbuf, sizeof(pbuf)) == 0) {
                             sizeof(pbuf)) == 0) {  
                                 cdp->cd_repo = strdup(pbuf);                                  cdp->cd_repo = strdup(pbuf);
                                 if (cdp->cd_repo == NULL) {                                  if (cdp->cd_repo == NULL) {
                                         cvs_log(LP_ERRNO,                                          cvs_log(LP_ERRNO,
Line 476 
Line 545 
                                 }                                  }
                         }                          }
   
                         cdp->cd_ent = cvs_ent_open(cf->cf_path, O_RDWR);                          cdp->cd_ent = cvs_ent_open(fpath, O_RDWR);
                 }                  }
         }          }
   
         if (!(flags & CF_RECURSE) || (cf->cf_cvstat == CVS_FST_UNKNOWN))          if (!(flags & CF_RECURSE) || (cf->cf_cvstat == CVS_FST_UNKNOWN))
                 return (0);                  return (0);
   
         fd = open(cf->cf_path, O_RDONLY);          fd = open(fpath, O_RDONLY);
         if (fd == -1) {          if (fd == -1) {
                 cvs_log(LP_ERRNO, "failed to open `%s'", cf->cf_path);                  cvs_log(LP_ERRNO, "failed to open `%s'", fpath);
                 return (-1);                  return (-1);
         }          }
   
Line 511 
Line 580 
                         if ((flags & CF_NOSYMS) && (ent->d_type == DT_LNK))                          if ((flags & CF_NOSYMS) && (ent->d_type == DT_LNK))
                                 continue;                                  continue;
   
                         snprintf(pbuf, sizeof(pbuf), "%s/%s",                          snprintf(pbuf, sizeof(pbuf), "%s/%s", fpath,
                             cf->cf_path, ent->d_name);                              ent->d_name);
                         cfp = cvs_file_lget(pbuf, flags, cf);                          cfp = cvs_file_lget(pbuf, flags, cf);
                         if (cfp != NULL) {                          if (cfp != NULL) {
                                 if (cfp->cf_type == DT_DIR) {                                  if (cfp->cf_type == DT_DIR) {
Line 528 
Line 597 
                 }                  }
         } while (ret > 0);          } while (ret > 0);
   
   #if 1
           cvs_ent_close(cdp->cd_ent);
           cdp->cd_ent = NULL;
   #endif
   
         if (flags & CF_SORT) {          if (flags & CF_SORT) {
                 cvs_file_sort(&(cdp->cd_files), cdp->cd_nfiles);                  cvs_file_sort(&(cdp->cd_files), cdp->cd_nfiles);
                 cvs_file_sort(&dirs, ndirs);                  cvs_file_sort(&dirs, ndirs);
Line 555 
Line 629 
 void  void
 cvs_file_free(CVSFILE *cf)  cvs_file_free(CVSFILE *cf)
 {  {
         if (cf->cf_path != NULL)  
                 free(cf->cf_path);  
         if (cf->cf_ddat != NULL)          if (cf->cf_ddat != NULL)
                 cvs_file_freedir(cf->cf_ddat);                  cvs_file_freedir(cf->cf_ddat);
         free(cf);          free(cf);
Line 680 
Line 752 
         CVSFILE *cf1, *cf2;          CVSFILE *cf1, *cf2;
         cf1 = *(CVSFILE **)f1;          cf1 = *(CVSFILE **)f1;
         cf2 = *(CVSFILE **)f2;          cf2 = *(CVSFILE **)f2;
         return cvs_file_cmpname(cf1->cf_name, cf2->cf_name);          return cvs_file_cmpname(CVS_FILE_NAME(cf1), CVS_FILE_NAME(cf2));
 }  }
   
   
   /*
    * cvs_file_alloc()
    *
    * Allocate a CVSFILE structure and initialize its internals.
    */
   
 CVSFILE*  CVSFILE*
 cvs_file_alloc(const char *path, u_int type)  cvs_file_alloc(const char *path, u_int type)
 {  {
         size_t len;          size_t len;
         char pbuf[MAXPATHLEN];          char pbuf[MAXPATHLEN];
           const char *fnp;
         CVSFILE *cfp;          CVSFILE *cfp;
         struct cvs_dir *ddat;          struct cvs_dir *ddat;
   
Line 705 
Line 784 
         while (pbuf[len - 1] == '/')          while (pbuf[len - 1] == '/')
                 pbuf[--len] = '\0';                  pbuf[--len] = '\0';
   
         cfp->cf_path = strdup(pbuf);          fnp = strrchr(path, '/');
         if (cfp->cf_path == NULL) {          if (fnp == NULL)
                 free(cfp);                  fnp = path;
                 return (NULL);  
         }  
   
         cfp->cf_name = strrchr(cfp->cf_path, '/');  
         if (cfp->cf_name == NULL)  
                 cfp->cf_name = cfp->cf_path;  
         else          else
                 cfp->cf_name++;                  fnp++;
   
           cfp->cf_name = cvs_file_getname(fnp);
           if (cfp->cf_name == NULL) {
                   cvs_log(LP_ERR, "WTF!?");
                   return (NULL);
           }
         cfp->cf_type = type;          cfp->cf_type = type;
         cfp->cf_cvstat = CVS_FST_UNKNOWN;          cfp->cf_cvstat = CVS_FST_UNKNOWN;
   
Line 748 
Line 826 
         int cwd;          int cwd;
         struct stat st;          struct stat st;
         CVSFILE *cfp;          CVSFILE *cfp;
         struct cvs_ent *ent;          struct cvs_ent *ent = NULL;
   
         ent = NULL;  
   
         if (strcmp(path, ".") == 0)          if (strcmp(path, ".") == 0)
                 cwd = 1;                  cwd = 1;
         else          else
Line 772 
Line 848 
         cfp->cf_mtime = st.st_mtime;          cfp->cf_mtime = st.st_mtime;
   
         if ((parent != NULL) && (CVS_DIR_ENTRIES(parent) != NULL)) {          if ((parent != NULL) && (CVS_DIR_ENTRIES(parent) != NULL)) {
                 ent = cvs_ent_get(CVS_DIR_ENTRIES(parent), cfp->cf_name);                  ent = cvs_ent_get(CVS_DIR_ENTRIES(parent), CVS_FILE_NAME(cfp));
         }          }
   
         if (ent == NULL) {          if (ent == NULL) {
Line 808 
Line 884 
 {  {
         return (cvs_nocase == 0) ? (strcmp(name1, name2)) :          return (cvs_nocase == 0) ? (strcmp(name1, name2)) :
             (strcasecmp(name1, name2));              (strcasecmp(name1, name2));
   }
   
   
   /*
    * cvs_file_hashname()
    *
    * Generate an 8 bit hash value from the name of a file.
    * XXX Improve my distribution!
    */
   
   static u_int8_t
   cvs_file_hashname(const char *name)
   {
           const char *np;
           u_int8_t h;
   
           h = 0xb5;
           for (np = name; *np != '\0'; np++)
                   h ^= (*np << 3 ^ *np >> 1);
   
           return (h);
   }
   
   
   /*
    * cvs_file_getname()
    *
    * Look for the file name <name> in the filename hash table.
    * If no entry is found for that name, a new one is created and inserted into
    * the table.  The name's reference count is increased.
    */
   
   static struct cvs_fname*
   cvs_file_getname(const char *name)
   {
           u_int8_t h;
           struct cvs_fname *fnp;
   
           h = cvs_file_hashname(name);
   
           SLIST_FOREACH(fnp, &(cvs_fnht[h]), cf_list)
                   if (strcmp(name, fnp->cf_name) == 0) {
                           fnp->cf_ref++;
                           break;
                   }
   
           if (fnp == NULL) {
                   fnp = (struct cvs_fname *)malloc(sizeof(*fnp));
                   if (fnp == NULL) {
                           cvs_log(LP_ERRNO,
                               "failed to allocate new file name entry");
                           return (NULL);
                   }
   
                   fnp->cf_name = strdup(name);
                   fnp->cf_ref = 1;
                   SLIST_INSERT_HEAD(&(cvs_fnht[h]), fnp, cf_list);
           }
   
           return (fnp);
 }  }

Legend:
Removed from v.1.33  
changed lines
  Added in v.1.34