summaryrefslogtreecommitdiff
path: root/usr.bin/cvs/file.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/cvs/file.c')
-rw-r--r--usr.bin/cvs/file.c212
1 files changed, 96 insertions, 116 deletions
diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c
index 56e94691b71..8d4017317a5 100644
--- a/usr.bin/cvs/file.c
+++ b/usr.bin/cvs/file.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file.c,v 1.61 2005/04/16 20:05:05 xsa Exp $ */
+/* $OpenBSD: file.c,v 1.62 2005/04/18 21:02:50 jfb Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -107,13 +107,12 @@ static RCSNUM *cvs_addedrev;
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 *);
+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,6 +250,7 @@ cvs_file_create(CVSFILE *parent, const char *path, u_int type, mode_t mode)
int fd;
char fp[MAXPATHLEN];
CVSFILE *cfp;
+ CVSENTRIES *ent;
cfp = cvs_file_alloc(path, type);
if (cfp == NULL)
@@ -260,10 +260,10 @@ cvs_file_create(CVSFILE *parent, const char *path, u_int type, mode_t mode)
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,
+ cfp->cf_root = cvsroot_get(path);
+ cfp->cf_repo = strdup(cvs_file_getpath(cfp,
fp, sizeof(fp)));
- if (cfp->cf_ddat->cd_repo == NULL) {
+ if (cfp->cf_repo == NULL) {
cvs_file_free(cfp);
return (NULL);
}
@@ -273,10 +273,9 @@ cvs_file_create(CVSFILE *parent, const char *path, u_int type, mode_t mode)
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;
+ 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,10 +315,11 @@ cvs_file_copy(CVSFILE *orig)
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) {
+ 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,7 +346,7 @@ cvs_file_copy(CVSFILE *orig)
CVSFILE*
cvs_file_get(const char *path, int flags)
{
- return cvs_file_lget(path, flags, NULL);
+ return cvs_file_lget(path, flags, NULL, NULL);
}
@@ -380,7 +380,7 @@ cvs_file_getspec(char **fspec, int fsn, int flags)
*np = '\0';
nf = cvs_file_find(cf, sp);
if (nf == NULL) {
- nf = cvs_file_lget(pcopy, 0, cf);
+ nf = cvs_file_lget(pcopy, 0, cf, NULL);
if (nf == NULL) {
cvs_file_free(base);
return (NULL);
@@ -442,7 +442,7 @@ cvs_file_find(CVSFILE *hier, const char *path)
continue;
}
- TAILQ_FOREACH(sf, &(cf->cf_ddat->cd_files), cf_list)
+ SIMPLEQ_FOREACH(sf, &(cf->cf_files), cf_list)
if (cvs_file_cmpname(pp, CVS_FILE_NAME(sf)) == 0)
break;
if (sf == NULL)
@@ -512,15 +512,10 @@ cvs_file_getpath(CVSFILE *file, char *buf, size_t len)
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++;
+ SIMPLEQ_INSERT_TAIL(&(parent->cf_files), file, cf_list);
file->cf_parent = parent;
return (0);
@@ -538,25 +533,25 @@ static int
cvs_file_getdir(CVSFILE *cf, int flags)
{
int ret, fd, l;
- u_int ndirs;
+ 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_dir *cdp;
struct cvs_ent *cvsent;
struct cvs_flist dirs;
ndirs = 0;
- TAILQ_INIT(&dirs);
- cdp = cf->cf_ddat;
+ nfiles = 0;
+ SIMPLEQ_INIT(&dirs);
cvs_file_getpath(cf, fpath, sizeof(fpath));
- cdp->cd_root = cvsroot_get(fpath);
- if (cdp->cd_root == NULL)
+ cf->cf_root = cvsroot_get(fpath);
+ if (cf->cf_root == NULL)
return (-1);
if (cf->cf_cvstat != CVS_FST_UNKNOWN) {
@@ -573,15 +568,15 @@ cvs_file_getdir(CVSFILE *cf, int flags)
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) {
+ cf->cf_repo = strdup(pbuf);
+ if (cf->cf_repo == NULL) {
cvs_log(LP_ERRNO,
"failed to dup repository string");
return (-1);
}
}
- cdp->cd_ent = cvs_ent_open(fpath, O_RDONLY);
+ entfile = cvs_ent_open(fpath, O_RDONLY);
}
}
@@ -627,8 +622,8 @@ cvs_file_getdir(CVSFILE *cf, int flags)
continue;
if (!(flags & CF_RECURSE) && (ent->d_type == DT_DIR)) {
- if (cdp->cd_ent != NULL)
- (void)cvs_ent_remove(cdp->cd_ent,
+ if (entfile != NULL)
+ (void)cvs_ent_remove(entfile,
ent->d_name);
continue;
}
@@ -643,28 +638,32 @@ cvs_file_getdir(CVSFILE *cf, int flags)
return (-1);
}
- cfp = cvs_file_lget(pbuf, flags, cf);
+ 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) {
- TAILQ_INSERT_TAIL(&dirs, cfp, cf_list);
+ SIMPLEQ_INSERT_TAIL(&dirs, cfp, cf_list);
ndirs++;
} else {
- TAILQ_INSERT_TAIL(&(cdp->cd_files), cfp,
+ SIMPLEQ_INSERT_TAIL(&(cf->cf_files), cfp,
cf_list);
- cdp->cd_nfiles++;
+ nfiles++;
}
}
} while (ret > 0);
- if (cdp->cd_ent != NULL) {
+ 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(cdp->cd_ent)) != NULL) {
+ 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,36 +674,33 @@ cvs_file_getdir(CVSFILE *cf, int flags)
return (-1);
}
- cfp = cvs_file_lget(pbuf, flags, cf);
+ cfp = cvs_file_lget(pbuf, flags, cf, cvsent);
if (cfp != NULL) {
if (cfp->cf_type == DT_DIR) {
- TAILQ_INSERT_TAIL(&dirs, cfp, cf_list);
+ SIMPLEQ_INSERT_TAIL(&dirs, cfp, cf_list);
ndirs++;
} else {
- TAILQ_INSERT_TAIL(&(cdp->cd_files), cfp,
+ SIMPLEQ_INSERT_TAIL(&(cf->cf_files), cfp,
cf_list);
- cdp->cd_nfiles++;
+ nfiles++;
}
}
}
- cvs_ent_close(cdp->cd_ent);
- cdp->cd_ent = NULL;
+ cvs_ent_close(entfile);
}
if (flags & CF_SORT) {
- cvs_file_sort(&(cdp->cd_files), cdp->cd_nfiles);
+ cvs_file_sort(&(cf->cf_files), 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);
+ while (!SIMPLEQ_EMPTY(&dirs)) {
+ cfp = SIMPLEQ_FIRST(&dirs);
+ SIMPLEQ_REMOVE_HEAD(&dirs, cf_list);
+ SIMPLEQ_INSERT_TAIL(&(cf->cf_files), cfp, cf_list);
}
- cdp->cd_nfiles += ndirs;
(void)close(fd);
-
return (0);
}
@@ -717,10 +713,22 @@ cvs_file_getdir(CVSFILE *cf, int flags)
void
cvs_file_free(CVSFILE *cf)
{
- if (cf->cf_ddat != NULL)
- cvs_file_freedir(cf->cf_ddat);
+ 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,7 +748,7 @@ cvs_file_examine(CVSFILE *cf, int (*exam)(CVSFILE *, void *), void *arg)
if (cf->cf_type == DT_DIR) {
ret = (*exam)(cf, arg);
- TAILQ_FOREACH(fp, &(cf->cf_ddat->cd_files), cf_list) {
+ SIMPLEQ_FOREACH(fp, &(cf->cf_files), cf_list) {
ret = cvs_file_examine(fp, exam, arg);
if (ret != 0)
break;
@@ -751,33 +759,6 @@ cvs_file_examine(CVSFILE *cf, int (*exam)(CVSFILE *, void *), void *arg)
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()
*
@@ -800,12 +781,12 @@ cvs_file_sort(struct cvs_flist *flp, u_int nfiles)
}
i = 0;
- TAILQ_FOREACH(cf, flp, cf_list) {
+ 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)
- TAILQ_INSERT_HEAD(flp, cfvec[i], cf_list);
+ SIMPLEQ_INSERT_HEAD(flp, cfvec[i], cf_list);
free(cfvec);
return (-1);
}
@@ -814,18 +795,18 @@ cvs_file_sort(struct cvs_flist *flp, u_int nfiles)
/* now unlink it from the list,
* we'll put it back in order later
*/
- TAILQ_REMOVE(flp, cf, cf_list);
+ SIMPLEQ_REMOVE_HEAD(flp, cf_list);
}
/* clear the list just in case */
- TAILQ_INIT(flp);
+ 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--)
- TAILQ_INSERT_HEAD(flp, cfvec[i], cf_list);
+ SIMPLEQ_INSERT_HEAD(flp, cfvec[i], cf_list);
free(cfvec);
return (0);
@@ -836,8 +817,8 @@ static int
cvs_file_cmp(const void *f1, const void *f2)
{
const CVSFILE *cf1, *cf2;
- cf1 = *(const CVSFILE **)f1;
- cf2 = *(const CVSFILE **)f2;
+ cf1 = *(CVSFILE * const *)f1;
+ cf2 = *(CVSFILE * const *)f2;
return cvs_file_cmpname(CVS_FILE_NAME(cf1), CVS_FILE_NAME(cf2));
}
@@ -851,7 +832,6 @@ CVSFILE*
cvs_file_alloc(const char *path, u_int type)
{
CVSFILE *cfp;
- struct cvs_dir *ddat;
cfp = (CVSFILE *)malloc(sizeof(*cfp));
if (cfp == NULL) {
@@ -860,26 +840,20 @@ cvs_file_alloc(const char *path, u_int type)
}
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);
}
- 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);
}
@@ -892,17 +866,18 @@ cvs_file_alloc(const char *path, u_int type)
* failure.
*/
static CVSFILE*
-cvs_file_lget(const char *path, int flags, CVSFILE *parent)
+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;
- struct cvs_ent *ent = NULL;
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,14 +887,12 @@ cvs_file_lget(const char *path, int flags, CVSFILE *parent)
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));
+ cfp->cf_flags |= CVS_DIRF_BASE;
if (ret == 0) {
cfp->cf_mode = st.st_mode & ACCESSPERMS;
- cfp->cf_mtime = st.st_mtime;
+ if (cfp->cf_type == DT_REG)
+ cfp->cf_mtime = st.st_mtime;
if (ent == NULL)
cfp->cf_cvstat = (cwd == 1) ?
@@ -948,8 +921,15 @@ cvs_file_lget(const char *path, int flags, CVSFILE *parent)
cfp->cf_cvstat = CVS_FST_LOST;
}
- if (ent != NULL)
- cvs_ent_remove(CVS_DIR_ENTRIES(parent), CVS_FILE_NAME(cfp));
+ 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);