=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/cvs/file.c,v retrieving revision 1.61 retrieving revision 1.62 diff -c -r1.61 -r1.62 *** src/usr.bin/cvs/file.c 2005/04/16 20:05:05 1.61 --- src/usr.bin/cvs/file.c 2005/04/18 21:02:50 1.62 *************** *** 1,4 **** ! /* $OpenBSD: file.c,v 1.61 2005/04/16 20:05:05 xsa Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. --- 1,4 ---- ! /* $OpenBSD: file.c,v 1.62 2005/04/18 21:02:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. *************** *** 107,119 **** TAILQ_HEAD(, cvs_ignpat) cvs_ign_pats; ! static int cvs_file_getdir (CVSFILE *, int); ! static void cvs_file_freedir (struct cvs_dir *); ! static int cvs_file_sort (struct cvs_flist *, u_int); ! static int cvs_file_cmp (const void *, const void *); ! static int cvs_file_cmpname (const char *, const char *); ! static CVSFILE* cvs_file_alloc (const char *, u_int); ! static CVSFILE* cvs_file_lget (const char *, int, CVSFILE *); --- 107,118 ---- TAILQ_HEAD(, cvs_ignpat) cvs_ign_pats; ! static int cvs_file_getdir (CVSFILE *, int); ! static int cvs_file_sort (struct cvs_flist *, u_int); ! static int cvs_file_cmp (const void *, const void *); ! static int cvs_file_cmpname (const char *, const char *); ! static CVSFILE* cvs_file_alloc (const char *, u_int); ! static CVSFILE* cvs_file_lget (const char *, int, CVSFILE *, struct cvs_ent *); *************** *** 251,256 **** --- 250,256 ---- int fd; char fp[MAXPATHLEN]; CVSFILE *cfp; + CVSENTRIES *ent; cfp = cvs_file_alloc(path, type); if (cfp == NULL) *************** *** 260,269 **** cfp->cf_parent = parent; 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); } --- 260,269 ---- cfp->cf_parent = parent; if (type == DT_DIR) { ! cfp->cf_root = cvsroot_get(path); ! cfp->cf_repo = strdup(cvs_file_getpath(cfp, fp, sizeof(fp))); ! if (cfp->cf_repo == NULL) { cvs_file_free(cfp); return (NULL); } *************** *** 273,282 **** return (NULL); } ! cfp->cf_ddat->cd_ent = cvs_ent_open(path, O_RDWR); ! if (cfp->cf_ddat->cd_ent != NULL) { ! cvs_ent_close(cfp->cf_ddat->cd_ent); ! cfp->cf_ddat->cd_ent = NULL; } } else { fd = open(path, O_WRONLY|O_CREAT|O_EXCL, mode); --- 273,281 ---- return (NULL); } ! ent = cvs_ent_open(path, O_RDWR); ! if (ent != NULL) { ! cvs_ent_close(ent); } } else { fd = open(path, O_WRONLY|O_CREAT|O_EXCL, mode); *************** *** 316,325 **** cfp->cf_parent = orig->cf_parent; cfp->cf_mode = orig->cf_mode; - cfp->cf_mtime = orig->cf_mtime; cfp->cf_cvstat = orig->cf_cvstat; ! if (orig->cf_type == DT_DIR) { /* XXX copy CVS directory attributes */ } --- 315,325 ---- cfp->cf_parent = orig->cf_parent; cfp->cf_mode = orig->cf_mode; cfp->cf_cvstat = orig->cf_cvstat; ! if (orig->cf_type == DT_REG) ! cfp->cf_mtime = orig->cf_mtime; ! else if (orig->cf_type == DT_DIR) { /* XXX copy CVS directory attributes */ } *************** *** 346,352 **** CVSFILE* cvs_file_get(const char *path, int flags) { ! return cvs_file_lget(path, flags, NULL); } --- 346,352 ---- CVSFILE* cvs_file_get(const char *path, int flags) { ! return cvs_file_lget(path, flags, NULL, NULL); } *************** *** 380,386 **** *np = '\0'; nf = cvs_file_find(cf, sp); if (nf == NULL) { ! nf = cvs_file_lget(pcopy, 0, cf); if (nf == NULL) { cvs_file_free(base); return (NULL); --- 380,386 ---- *np = '\0'; nf = cvs_file_find(cf, sp); if (nf == NULL) { ! nf = cvs_file_lget(pcopy, 0, cf, NULL); if (nf == NULL) { cvs_file_free(base); return (NULL); *************** *** 442,448 **** continue; } ! TAILQ_FOREACH(sf, &(cf->cf_ddat->cd_files), cf_list) if (cvs_file_cmpname(pp, CVS_FILE_NAME(sf)) == 0) break; if (sf == NULL) --- 442,448 ---- continue; } ! SIMPLEQ_FOREACH(sf, &(cf->cf_files), cf_list) if (cvs_file_cmpname(pp, CVS_FILE_NAME(sf)) == 0) break; if (sf == NULL) *************** *** 512,526 **** int cvs_file_attach(CVSFILE *parent, CVSFILE *file) { - struct cvs_dir *dp; - if (parent->cf_type != DT_DIR) return (-1); ! dp = parent->cf_ddat; ! ! TAILQ_INSERT_TAIL(&(dp->cd_files), file, cf_list); ! dp->cd_nfiles++; file->cf_parent = parent; return (0); --- 512,521 ---- int cvs_file_attach(CVSFILE *parent, CVSFILE *file) { if (parent->cf_type != DT_DIR) return (-1); ! SIMPLEQ_INSERT_TAIL(&(parent->cf_files), file, cf_list); file->cf_parent = parent; return (0); *************** *** 538,562 **** cvs_file_getdir(CVSFILE *cf, int flags) { int ret, fd, l; ! u_int ndirs; long base; u_char *dp, *ep; char fbuf[2048], pbuf[MAXPATHLEN], fpath[MAXPATHLEN]; struct dirent *ent; CVSFILE *cfp; struct stat st; - struct cvs_dir *cdp; struct cvs_ent *cvsent; struct cvs_flist dirs; ndirs = 0; ! TAILQ_INIT(&dirs); ! cdp = cf->cf_ddat; cvs_file_getpath(cf, fpath, sizeof(fpath)); ! cdp->cd_root = cvsroot_get(fpath); ! if (cdp->cd_root == NULL) return (-1); if (cf->cf_cvstat != CVS_FST_UNKNOWN) { --- 533,557 ---- cvs_file_getdir(CVSFILE *cf, int flags) { int ret, fd, l; ! u_int ndirs, nfiles; long base; u_char *dp, *ep; char fbuf[2048], pbuf[MAXPATHLEN], fpath[MAXPATHLEN]; struct dirent *ent; CVSFILE *cfp; + CVSENTRIES *entfile; struct stat st; struct cvs_ent *cvsent; struct cvs_flist dirs; ndirs = 0; ! nfiles = 0; ! SIMPLEQ_INIT(&dirs); cvs_file_getpath(cf, fpath, sizeof(fpath)); ! cf->cf_root = cvsroot_get(fpath); ! if (cf->cf_root == NULL) return (-1); if (cf->cf_cvstat != CVS_FST_UNKNOWN) { *************** *** 573,587 **** if ((stat(pbuf, &st) == 0) && S_ISDIR(st.st_mode)) { if (cvs_readrepo(fpath, pbuf, sizeof(pbuf)) == 0) { ! cdp->cd_repo = strdup(pbuf); ! if (cdp->cd_repo == NULL) { cvs_log(LP_ERRNO, "failed to dup repository string"); return (-1); } } ! cdp->cd_ent = cvs_ent_open(fpath, O_RDONLY); } } --- 568,582 ---- if ((stat(pbuf, &st) == 0) && S_ISDIR(st.st_mode)) { if (cvs_readrepo(fpath, pbuf, sizeof(pbuf)) == 0) { ! cf->cf_repo = strdup(pbuf); ! if (cf->cf_repo == NULL) { cvs_log(LP_ERRNO, "failed to dup repository string"); return (-1); } } ! entfile = cvs_ent_open(fpath, O_RDONLY); } } *************** *** 627,634 **** continue; if (!(flags & CF_RECURSE) && (ent->d_type == DT_DIR)) { ! if (cdp->cd_ent != NULL) ! (void)cvs_ent_remove(cdp->cd_ent, ent->d_name); continue; } --- 622,629 ---- continue; if (!(flags & CF_RECURSE) && (ent->d_type == DT_DIR)) { ! if (entfile != NULL) ! (void)cvs_ent_remove(entfile, ent->d_name); continue; } *************** *** 643,670 **** return (-1); } ! cfp = cvs_file_lget(pbuf, flags, cf); if (cfp == NULL) { (void)close(fd); return (-1); } if (cfp->cf_type == DT_DIR) { ! TAILQ_INSERT_TAIL(&dirs, cfp, cf_list); ndirs++; } else { ! TAILQ_INSERT_TAIL(&(cdp->cd_files), cfp, cf_list); ! cdp->cd_nfiles++; } } } while (ret > 0); ! if (cdp->cd_ent != NULL) { /* now create file structure for files which have an * entry in the Entries file but no file on disk */ ! while ((cvsent = cvs_ent_next(cdp->cd_ent)) != NULL) { l = snprintf(pbuf, sizeof(pbuf), "%s/%s", fpath, cvsent->ce_name); if (l == -1 || l >= (int)sizeof(pbuf)) { --- 638,669 ---- return (-1); } ! if (entfile != NULL) ! cvsent = cvs_ent_get(entfile, ent->d_name); ! cfp = cvs_file_lget(pbuf, flags, cf, cvsent); if (cfp == NULL) { (void)close(fd); return (-1); } + if (entfile != NULL) + cvs_ent_remove(entfile, cfp->cf_name); if (cfp->cf_type == DT_DIR) { ! SIMPLEQ_INSERT_TAIL(&dirs, cfp, cf_list); ndirs++; } else { ! SIMPLEQ_INSERT_TAIL(&(cf->cf_files), cfp, cf_list); ! nfiles++; } } } while (ret > 0); ! if (entfile != NULL) { /* now create file structure for files which have an * entry in the Entries file but no file on disk */ ! while ((cvsent = cvs_ent_next(entfile)) != NULL) { l = snprintf(pbuf, sizeof(pbuf), "%s/%s", fpath, cvsent->ce_name); if (l == -1 || l >= (int)sizeof(pbuf)) { *************** *** 675,710 **** return (-1); } ! cfp = cvs_file_lget(pbuf, flags, cf); if (cfp != NULL) { if (cfp->cf_type == DT_DIR) { ! TAILQ_INSERT_TAIL(&dirs, cfp, cf_list); ndirs++; } else { ! TAILQ_INSERT_TAIL(&(cdp->cd_files), cfp, cf_list); ! cdp->cd_nfiles++; } } } ! cvs_ent_close(cdp->cd_ent); ! cdp->cd_ent = NULL; } if (flags & CF_SORT) { ! cvs_file_sort(&(cdp->cd_files), cdp->cd_nfiles); cvs_file_sort(&dirs, ndirs); } ! while (!TAILQ_EMPTY(&dirs)) { ! cfp = TAILQ_FIRST(&dirs); ! TAILQ_REMOVE(&dirs, cfp, cf_list); ! TAILQ_INSERT_TAIL(&(cdp->cd_files), cfp, cf_list); } - cdp->cd_nfiles += ndirs; (void)close(fd); - return (0); } --- 674,706 ---- return (-1); } ! cfp = cvs_file_lget(pbuf, flags, cf, cvsent); if (cfp != NULL) { if (cfp->cf_type == DT_DIR) { ! SIMPLEQ_INSERT_TAIL(&dirs, cfp, cf_list); ndirs++; } else { ! SIMPLEQ_INSERT_TAIL(&(cf->cf_files), cfp, cf_list); ! nfiles++; } } } ! cvs_ent_close(entfile); } if (flags & CF_SORT) { ! cvs_file_sort(&(cf->cf_files), nfiles); cvs_file_sort(&dirs, ndirs); } ! while (!SIMPLEQ_EMPTY(&dirs)) { ! cfp = SIMPLEQ_FIRST(&dirs); ! SIMPLEQ_REMOVE_HEAD(&dirs, cf_list); ! SIMPLEQ_INSERT_TAIL(&(cf->cf_files), cfp, cf_list); } (void)close(fd); return (0); } *************** *** 717,726 **** void cvs_file_free(CVSFILE *cf) { ! if (cf->cf_ddat != NULL) ! cvs_file_freedir(cf->cf_ddat); if (cf->cf_name != NULL) cvs_strfree(cf->cf_name); free(cf); } --- 713,734 ---- void cvs_file_free(CVSFILE *cf) { ! CVSFILE *child; ! if (cf->cf_name != NULL) cvs_strfree(cf->cf_name); + + if (cf->cf_type == DT_DIR) { + if (cf->cf_root != NULL) + cvsroot_free(cf->cf_root); + if (cf->cf_repo != NULL) + free(cf->cf_repo); + while (!SIMPLEQ_EMPTY(&(cf->cf_files))) { + child = SIMPLEQ_FIRST(&(cf->cf_files)); + SIMPLEQ_REMOVE_HEAD(&(cf->cf_files), cf_list); + cvs_file_free(child); + } + } free(cf); } *************** *** 740,746 **** if (cf->cf_type == DT_DIR) { ret = (*exam)(cf, arg); ! TAILQ_FOREACH(fp, &(cf->cf_ddat->cd_files), cf_list) { ret = cvs_file_examine(fp, exam, arg); if (ret != 0) break; --- 748,754 ---- if (cf->cf_type == DT_DIR) { ret = (*exam)(cf, arg); ! SIMPLEQ_FOREACH(fp, &(cf->cf_files), cf_list) { ret = cvs_file_examine(fp, exam, arg); if (ret != 0) break; *************** *** 751,784 **** return (ret); } - /* - * cvs_file_freedir() - * - * Free a cvs_dir structure and its contents. - */ - static void - cvs_file_freedir(struct cvs_dir *cd) - { - CVSFILE *cfp; - - if (cd->cd_root != NULL) - cvsroot_free(cd->cd_root); - if (cd->cd_repo != NULL) - free(cd->cd_repo); - - if (cd->cd_ent != NULL) - cvs_ent_close(cd->cd_ent); - - while (!TAILQ_EMPTY(&(cd->cd_files))) { - cfp = TAILQ_FIRST(&(cd->cd_files)); - TAILQ_REMOVE(&(cd->cd_files), cfp, cf_list); - cvs_file_free(cfp); - } - } - - - /* * cvs_file_sort() * * Sort a list of cvs file structures according to their filename. The list --- 759,765 ---- *************** *** 800,811 **** } i = 0; ! TAILQ_FOREACH(cf, flp, cf_list) { if (i == (int)nfiles) { cvs_log(LP_WARN, "too many files to sort"); /* rebuild the list and abort sorting */ while (--i >= 0) ! TAILQ_INSERT_HEAD(flp, cfvec[i], cf_list); free(cfvec); return (-1); } --- 781,792 ---- } i = 0; ! SIMPLEQ_FOREACH(cf, flp, cf_list) { if (i == (int)nfiles) { cvs_log(LP_WARN, "too many files to sort"); /* rebuild the list and abort sorting */ while (--i >= 0) ! SIMPLEQ_INSERT_HEAD(flp, cfvec[i], cf_list); free(cfvec); return (-1); } *************** *** 814,831 **** /* now unlink it from the list, * we'll put it back in order later */ ! TAILQ_REMOVE(flp, cf, cf_list); } /* clear the list just in case */ ! TAILQ_INIT(flp); nb = (size_t)i; heapsort(cfvec, nb, sizeof(cf), cvs_file_cmp); /* rebuild the list from the bottom up */ for (i = (int)nb - 1; i >= 0; i--) ! TAILQ_INSERT_HEAD(flp, cfvec[i], cf_list); free(cfvec); return (0); --- 795,812 ---- /* now unlink it from the list, * we'll put it back in order later */ ! SIMPLEQ_REMOVE_HEAD(flp, cf_list); } /* clear the list just in case */ ! SIMPLEQ_INIT(flp); nb = (size_t)i; heapsort(cfvec, nb, sizeof(cf), cvs_file_cmp); /* rebuild the list from the bottom up */ for (i = (int)nb - 1; i >= 0; i--) ! SIMPLEQ_INSERT_HEAD(flp, cfvec[i], cf_list); free(cfvec); return (0); *************** *** 836,843 **** cvs_file_cmp(const void *f1, const void *f2) { const CVSFILE *cf1, *cf2; ! cf1 = *(const CVSFILE **)f1; ! cf2 = *(const CVSFILE **)f2; return cvs_file_cmpname(CVS_FILE_NAME(cf1), CVS_FILE_NAME(cf2)); } --- 817,824 ---- cvs_file_cmp(const void *f1, const void *f2) { const CVSFILE *cf1, *cf2; ! cf1 = *(CVSFILE * const *)f1; ! cf2 = *(CVSFILE * const *)f2; return cvs_file_cmpname(CVS_FILE_NAME(cf1), CVS_FILE_NAME(cf2)); } *************** *** 851,857 **** cvs_file_alloc(const char *path, u_int type) { CVSFILE *cfp; - struct cvs_dir *ddat; cfp = (CVSFILE *)malloc(sizeof(*cfp)); if (cfp == NULL) { --- 832,837 ---- *************** *** 860,885 **** } memset(cfp, 0, sizeof(*cfp)); cfp->cf_name = cvs_strdup(basename(path)); if (cfp->cf_name == NULL) { cvs_log(LP_ERR, "failed to copy file name"); cvs_file_free(cfp); return (NULL); } - cfp->cf_type = type; - cfp->cf_cvstat = CVS_FST_UNKNOWN; - if (type == DT_DIR) { - ddat = (struct cvs_dir *)malloc(sizeof(*ddat)); - if (ddat == NULL) { - cvs_log(LP_ERRNO, "failed to allocate directory data"); - cvs_file_free(cfp); - return (NULL); - } - memset(ddat, 0, sizeof(*ddat)); - TAILQ_INIT(&(ddat->cd_files)); - cfp->cf_ddat = ddat; - } return (cfp); } --- 840,859 ---- } memset(cfp, 0, sizeof(*cfp)); + cfp->cf_type = type; + cfp->cf_cvstat = CVS_FST_UNKNOWN; + + if (type == DT_DIR) { + SIMPLEQ_INIT(&(cfp->cf_files)); + } + cfp->cf_name = cvs_strdup(basename(path)); if (cfp->cf_name == NULL) { cvs_log(LP_ERR, "failed to copy file name"); cvs_file_free(cfp); return (NULL); } return (cfp); } *************** *** 892,908 **** * failure. */ static CVSFILE* ! cvs_file_lget(const char *path, int flags, CVSFILE *parent) { int ret, cwd; u_int type; struct stat st; CVSFILE *cfp; - struct cvs_ent *ent = NULL; type = DT_UNKNOWN; cwd = (strcmp(path, ".") == 0) ? 1 : 0; ret = stat(path, &st); if (ret == 0) type = IFTODT(st.st_mode); --- 866,883 ---- * failure. */ static CVSFILE* ! cvs_file_lget(const char *path, int flags, CVSFILE *parent, struct cvs_ent *ent) { int ret, cwd; u_int type; struct stat st; CVSFILE *cfp; type = DT_UNKNOWN; cwd = (strcmp(path, ".") == 0) ? 1 : 0; + printf("lget(%s)\n", path); + ret = stat(path, &st); if (ret == 0) type = IFTODT(st.st_mode); *************** *** 912,925 **** cfp->cf_parent = parent; if ((cfp->cf_type == DT_DIR) && (cfp->cf_parent == NULL)) ! cfp->cf_ddat->cd_flags |= CVS_DIRF_BASE; - if ((parent != NULL) && (CVS_DIR_ENTRIES(parent) != NULL)) - ent = cvs_ent_get(CVS_DIR_ENTRIES(parent), CVS_FILE_NAME(cfp)); - if (ret == 0) { cfp->cf_mode = st.st_mode & ACCESSPERMS; ! cfp->cf_mtime = st.st_mtime; if (ent == NULL) cfp->cf_cvstat = (cwd == 1) ? --- 887,898 ---- cfp->cf_parent = parent; if ((cfp->cf_type == DT_DIR) && (cfp->cf_parent == NULL)) ! cfp->cf_flags |= CVS_DIRF_BASE; if (ret == 0) { cfp->cf_mode = st.st_mode & ACCESSPERMS; ! if (cfp->cf_type == DT_REG) ! cfp->cf_mtime = st.st_mtime; if (ent == NULL) cfp->cf_cvstat = (cwd == 1) ? *************** *** 948,955 **** cfp->cf_cvstat = CVS_FST_LOST; } ! if (ent != NULL) ! cvs_ent_remove(CVS_DIR_ENTRIES(parent), CVS_FILE_NAME(cfp)); if ((cfp->cf_type == DT_DIR) && (cvs_file_getdir(cfp, flags) < 0)) { cvs_file_free(cfp); --- 921,935 ---- cfp->cf_cvstat = CVS_FST_LOST; } ! if (ent != NULL) { ! /* steal the RCSNUM */ ! cfp->cf_lrev = ent->ce_rev; ! if ((cfp->cf_tag = cvs_strdup(ent->ce_tag)) == NULL) { ! cvs_file_free(cfp); ! return (NULL); ! } ! ent->ce_rev = NULL; ! } if ((cfp->cf_type == DT_DIR) && (cvs_file_getdir(cfp, flags) < 0)) { cvs_file_free(cfp);