[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.2 and 1.3

version 1.2, 2004/07/16 03:08:26 version 1.3, 2004/07/23 05:40:32
Line 90 
Line 90 
 TAILQ_HEAD(, cvs_ignpat)  cvs_ign_pats;  TAILQ_HEAD(, cvs_ignpat)  cvs_ign_pats;
   
   
   static struct cvs_dir*  cvs_file_getdir  (struct cvs_file *, int);
   static void             cvs_file_freedir (struct cvs_dir *);
   static int              cvs_file_sort    (struct cvs_flist *);
   static int              cvs_file_cmp     (const void *, const void *);
   
   
   
 /*  /*
  * cvs_file_init()   * cvs_file_init()
  *   *
Line 212 
Line 219 
  */   */
   
 char**  char**
 cvs_file_getv(const char *dir, int *nfiles)  cvs_file_getv(const char *dir, int *nfiles, int recurse)
 {  {
         int nf, ret, fd;          int nf, ret, fd;
         long base;          long base;
Line 259 
Line 266 
         (void)close(fd);          (void)close(fd);
   
         return (fvec);          return (fvec);
   }
   
   
   /*
    * cvs_file_get()
    *
    * Load a cvs_file structure with all the information pertaining to the file
    * <path>.
    * Returns a pointer to the cvs file structure, which must later be freed
    * with cvs_file_free().
    */
   
   struct cvs_file*
   cvs_file_get(const char *path, int flags)
   {
           size_t dlen;
           struct stat st;
           struct cvs_file *cfp;
   
           printf("cvs_file_get(%s)\n", path);
   
           if (stat(path, &st) == -1) {
                   cvs_log(LP_ERRNO, "failed to stat file");
                   return (NULL);
           }
   
           cfp = (struct cvs_file *)malloc(sizeof(*cfp));
           if (cfp == NULL) {
                   cvs_log(LP_ERRNO, "failed to allocate CVS file data");
                   return (NULL);
           }
           memset(cfp, 0, sizeof(*cfp));
   
           cfp->cf_path = strdup(path);
           if (cfp->cf_path == NULL) {
                   free(cfp);
                   return (NULL);
           }
   
           cfp->cf_name = strrchr(cfp->cf_path, '/');
           if (cfp->cf_name == NULL)
                   cfp->cf_name = cfp->cf_path;
           else
                   cfp->cf_name++;
   
           /* convert from stat mode to dirent values */
           cfp->cf_type = IFTODT(st.st_mode);
           if (cfp->cf_type == DT_DIR) {
                   cfp->cf_ddat = cvs_file_getdir(cfp, flags);
                   if (cfp->cf_ddat == NULL) {
                           cvs_file_free(cfp);
                           return (NULL);
                   }
           }
   
           if (flags & CF_STAT) {
                   cfp->cf_stat = (struct stat *)malloc(sizeof(struct stat));
                   if (cfp->cf_stat == NULL) {
                           cvs_log(LP_ERRNO, "failed to allocate stat structure");
                           cvs_file_free(cfp);
                           return (NULL);
                   }
   
                   memcpy(cfp->cf_stat, &st, sizeof(struct stat));
           }
   
           return (cfp);
   }
   
   
   /*
    * cvs_file_getdir()
    *
    * Get a cvs directory structure for the directory whose path is <dir>.
    */
   
   static struct cvs_dir*
   cvs_file_getdir(struct cvs_file *cf, int flags)
   {
           int nf, ret, fd;
           long base;
           void *dp, *ep, *tmp;
           char fbuf[1024], pbuf[MAXPATHLEN];
           struct dirent *ent;
           struct cvs_file *cfp;
           struct cvs_dir *cdp;
   
           cdp = (struct cvs_dir *)malloc(sizeof(*cdp));
           if (cdp == NULL) {
                   cvs_log(LP_ERRNO, "failed to allocate dir");
                   return (NULL);
           }
           memset(cdp, 0, sizeof(*cdp));
           LIST_INIT(&(cdp->cd_files));
   
           if (cvs_readrepo(cf->cf_path, pbuf, sizeof(pbuf)) < 0) {
                   free(cdp);
                   return (NULL);
           }
   
           cdp->cd_repo = strdup(pbuf);
           if (cdp->cd_repo == NULL) {
                   free(cdp);
                   return (NULL);
           }
   
           cdp->cd_root = cvsroot_get(cf->cf_path);
           if (cdp->cd_root == NULL) {
                   cvs_file_freedir(cdp);
                   return (NULL);
           }
   
           fd = open(cf->cf_path, O_RDONLY);
           if (fd == -1) {
                   cvs_log(LP_ERRNO, "failed to open `%s'", cf->cf_path);
                   cvs_file_freedir(cdp);
                   return (NULL);
           }
           ret = getdirentries(fd, fbuf, sizeof(fbuf), &base);
           if (ret == -1) {
                   cvs_log(LP_ERRNO, "failed to get directory entries");
                   (void)close(fd);
                   cvs_file_freedir(cdp);
                   return (NULL);
           }
   
           dp = fbuf;
           ep = fbuf + (size_t)ret;
           while (dp < ep) {
                   ent = (struct dirent *)dp;
                   dp += ent->d_reclen;
   
                   if ((flags & CF_IGNORE) && cvs_file_isignored(ent->d_name))
                           continue;
   
                   snprintf(pbuf, sizeof(pbuf), "%s/%s", cf->cf_path, ent->d_name);
                   cfp = cvs_file_get(pbuf, flags);
   
                   LIST_INSERT_HEAD(&(cdp->cd_files), cfp, cf_list);
           }
   
           if (flags & CF_SORT)
                   cvs_file_sort(&(cdp->cd_files));
   
           (void)close(fd);
   
           return (cdp);
   }
   
   
   /*
    * cvs_file_free()
    *
    * Free a cvs_file structure and its contents.
    */
   
   void
   cvs_file_free(struct cvs_file *cf)
   {
           struct cvs_file *cfp;
           struct cvs_dir *cd;
   
           if (cf->cf_path != NULL)
                   free(cf->cf_path);
           if (cf->cf_stat != NULL)
                   free(cf->cf_stat);
           if (cf->cf_ddat != NULL)
                   cvs_file_freedir(cf->cf_ddat);
           free(cf);
   }
   
   
   /*
    * cvs_file_freedir()
    *
    * Free a cvs_dir structure and its contents.
    */
   
   static void
   cvs_file_freedir(struct cvs_dir *cd)
   {
           struct cvs_file *cfp;
   
           if (cd->cd_root != NULL)
                   cvsroot_free(cd->cd_root);
           if (cd->cd_repo != NULL)
                   free(cd->cd_repo);
   
           while (!LIST_EMPTY(&(cd->cd_files))) {
                   cfp = LIST_FIRST(&(cd->cd_files));
                   LIST_REMOVE(cfp, cf_list);
                   cvs_file_free(cfp);
           }
   }
   
   
   /*
    * cvs_file_sort()
    *
    * Sort a list of cvs file structures according to their filename.
    */
   
   static int
   cvs_file_sort(struct cvs_flist *flp)
   {
           int i;
           size_t nb;
           struct cvs_file *cf, *cfvec[256];
   
           i = 0;
           LIST_FOREACH(cf, flp, cf_list) {
                   printf("adding `%s'\n", cf->cf_path);
                   cfvec[i++] = cf;
                   if (i == sizeof(cfvec)/sizeof(struct cvs_file *)) {
                           cvs_log(LP_WARN, "too many files to sort");
                           return (-1);
                   }
   
                   /* now unlink it from the list,
                    * we'll put it back in order later
                    */
                   LIST_REMOVE(cf, cf_list);
           }
   
           /* clear the list just in case */
           LIST_INIT(flp);
           nb = (size_t)i;
   
           printf("Before: \n");
           for (i = 0; i < (int)nb; i++)
                   printf("[%d] = `%s'\n", i, cfvec[i]->cf_name);
           heapsort(cfvec, nb, sizeof(cf), cvs_file_cmp);
           printf("===================================\nAfter: \n");
           for (i = 0; i < (int)nb; i++)
                   printf("[%d] = `%s'\n", i, cfvec[i]->cf_name);
   
           /* rebuild the list from the bottom up */
           for (i = (int)nb - 1; i >= 0; i--)
                   LIST_INSERT_HEAD(flp, cfvec[i], cf_list);
   
           return (0);
   }
   
   
   static int
   cvs_file_cmp(const void *f1, const void *f2)
   {
           struct cvs_file *cf1, *cf2;
           cf1 = *(struct cvs_file **)f1;
           cf2 = *(struct cvs_file **)f2;
           return strcmp(cf1->cf_name, cf2->cf_name);
 }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3