diff options
author | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-11-26 16:23:51 +0000 |
---|---|---|
committer | Jean-Francois Brousseau <jfb@cvs.openbsd.org> | 2004-11-26 16:23:51 +0000 |
commit | db3cb2196dc4401149258da8e6829cd3dad178e7 (patch) | |
tree | b9a9aaf07fb5d5f42c77215bccac5baa122704a8 /usr.bin/cvs | |
parent | 03ab04eece2d53fa3853fa9383b5278032ffa1ce (diff) |
Rewrite the internals of the file management code so that we do not keep
a full path to each file we load, and cache file names so we can have
multiple references to a single name. This saves a lot of memory on large
trees such as /usr/src, especially on 'Makefile', 'README' and such.
Diffstat (limited to 'usr.bin/cvs')
-rw-r--r-- | usr.bin/cvs/commit.c | 257 | ||||
-rw-r--r-- | usr.bin/cvs/conf.y | 9 | ||||
-rw-r--r-- | usr.bin/cvs/cvs/Makefile | 4 | ||||
-rw-r--r-- | usr.bin/cvs/diff.c | 28 | ||||
-rw-r--r-- | usr.bin/cvs/file.c | 228 | ||||
-rw-r--r-- | usr.bin/cvs/file.h | 40 | ||||
-rw-r--r-- | usr.bin/cvs/getlog.c | 29 | ||||
-rw-r--r-- | usr.bin/cvs/logmsg.c | 26 | ||||
-rw-r--r-- | usr.bin/cvs/proto.c | 23 | ||||
-rw-r--r-- | usr.bin/cvs/resp.c | 7 | ||||
-rw-r--r-- | usr.bin/cvs/status.c | 29 | ||||
-rw-r--r-- | usr.bin/cvs/update.c | 25 | ||||
-rw-r--r-- | usr.bin/cvs/util.c | 22 |
13 files changed, 403 insertions, 324 deletions
diff --git a/usr.bin/cvs/commit.c b/usr.bin/cvs/commit.c index 6906f136c9f..d6bd3034434 100644 --- a/usr.bin/cvs/commit.c +++ b/usr.bin/cvs/commit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: commit.c,v 1.5 2004/11/09 22:22:47 krapht Exp $ */ +/* $OpenBSD: commit.c,v 1.6 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -25,6 +25,7 @@ */ #include <sys/types.h> +#include <sys/queue.h> #include <sys/stat.h> #include <errno.h> @@ -41,16 +42,17 @@ #include "proto.h" -#define CVS_COMMIT_BIGMSG 32000 -#define CVS_COMMIT_FTMPL "/tmp/cvsXXXXXXXXXX" -#define CVS_COMMIT_LOGPREFIX "CVS:" -#define CVS_COMMIT_LOGLINE \ -"----------------------------------------------------------------------" +LIST_HEAD(ci_list, ci_file); +struct ci_file { + char *ci_path; + RCSNUM *ci_rev; + LIST_ENTRY(ci_file) ci_link; +}; -static char* cvs_commit_openmsg (const char *); -static char* cvs_commit_getmsg (const char *); + +int cvs_commit_file (CVSFILE *, void *); /* @@ -62,14 +64,15 @@ static char* cvs_commit_getmsg (const char *); int cvs_commit(int argc, char **argv) { - int ch, recurse; + int ch, recurse, flags; char *msg, *mfile; + struct ci_list cl; + flags = 0; recurse = 1; mfile = NULL; msg = NULL; - - cvs_commit_getmsg("."); + LIST_INIT(&cl); while ((ch = getopt(argc, argv, "F:flm:R")) != -1) { switch (ch) { @@ -98,210 +101,90 @@ cvs_commit(int argc, char **argv) return (EX_USAGE); } - if ((mfile != NULL) && (msg = cvs_commit_openmsg(mfile)) == NULL) + if ((mfile != NULL) && (msg = cvs_logmsg_open(mfile)) == NULL) return (EX_DATAERR); argc -= optind; argv += optind; - return (0); -} - - -/* - * cvs_commit_openmsg() - * - * Open the file specified by <path> and allocate a buffer large enough to - * hold all of the file's contents. The returned value must later be freed - * using the free() function. - * Returns a pointer to the allocated buffer on success, or NULL on failure. - */ - -static char* -cvs_commit_openmsg(const char *path) -{ - int ch; - size_t len; - char lbuf[256], *msg; - struct stat st; - FILE *fp; - BUF *bp; - - if (stat(path, &st) == -1) { - cvs_log(LP_ERRNO, "failed to stat `%s'", path); - return (NULL); - } - - if (!S_ISREG(st.st_mode)) { - cvs_log(LP_ERR, "message file must be a regular file"); - return (NULL); - } - - if (st.st_size > CVS_COMMIT_BIGMSG) { - do { - fprintf(stderr, - "The specified message file seems big. " - "Proceed anyways? (y/n) "); - if (fgets(lbuf, sizeof(lbuf), stdin) == NULL) { - cvs_log(LP_ERRNO, - "failed to read from standard input"); - return (NULL); - } - - len = strlen(lbuf); - if ((len == 0) || (len > 2) || - ((lbuf[0] != 'y') && (lbuf[0] != 'n'))) { - fprintf(stderr, "invalid input\n"); - continue; - } - else if (lbuf[0] == 'y') - break; - else if (lbuf[0] == 'n') { - cvs_log(LP_ERR, "aborted by user"); - return (NULL); - } - - } while (1); - } - - if ((fp = fopen(path, "r")) == NULL) { - cvs_log(LP_ERRNO, "failed to open message file `%s'", path); - return (NULL); - } - - bp = cvs_buf_alloc(128, BUF_AUTOEXT); - if (bp == NULL) { - return (NULL); + if (argc == 0) + cvs_files = cvs_file_get(".", flags); + else { + cvs_files = cvs_file_getspec(argv, argc, flags); } + if (cvs_files == NULL) + return (EX_DATAERR); - while (fgets(lbuf, sizeof(lbuf), fp) != NULL) { - len = strlen(lbuf); - if (len == 0) - continue; - - /* skip lines starting with the prefix */ - if (strncmp(lbuf, CVS_COMMIT_LOGPREFIX, - strlen(CVS_COMMIT_LOGPREFIX)) == 0) - continue; - - cvs_buf_append(bp, lbuf, strlen(lbuf)); - } - cvs_buf_putc(bp, '\0'); + cvs_file_examine(cvs_files, cvs_commit_file, &cl); - msg = (char *)cvs_buf_release(bp); + cvs_senddir(cvs_files->cf_ddat->cd_root, cvs_files); + cvs_sendreq(cvs_files->cf_ddat->cd_root, CVS_REQ_CI, NULL); - return (msg); + return (0); } /* - * cvs_commit_getmsg() + * cvs_commit_file() * - * Get a commit log message by forking the user's editor. - * Returns the message in a dynamically allocated string on success, NULL on - * failure. + * Commit a single file. */ -static char* -cvs_commit_getmsg(const char *dir) +int +cvs_commit_file(CVSFILE *cf, void *arg) { - int ret, fd, argc, fds[3]; - size_t len; - char *argv[4], buf[16], path[MAXPATHLEN], *msg; - FILE *fp; - struct stat st1, st2; + char *repo, rcspath[MAXPATHLEN], fpath[MAXPATHLEN]; + RCSFILE *rf; + struct cvsroot *root; + struct cvs_ent *entp; + struct ci_list *cl; + + cl = (struct ci_list *)arg; + + if (cf->cf_type == DT_DIR) { + if (cf->cf_cvstat != CVS_FST_UNKNOWN) { + root = cf->cf_ddat->cd_root; + if ((cf->cf_parent == NULL) || + (root != cf->cf_parent->cf_ddat->cd_root)) { + cvs_connect(root); + } - msg = NULL; - fds[0] = -1; - fds[1] = -1; - fds[2] = -1; - strlcpy(path, CVS_COMMIT_FTMPL, sizeof(path)); - argc = 0; - argv[argc++] = cvs_editor; - argv[argc++] = path; - argv[argc] = NULL; - - if ((fd = mkstemp(path)) == -1) { - cvs_log(LP_ERRNO, "failed to create temporary file"); - return (NULL); - } + cvs_senddir(root, cf); + } - fp = fdopen(fd, "w"); - if (fp == NULL) { - cvs_log(LP_ERRNO, "failed to fdopen"); - } else { - fprintf(fp, - "\n%s %s\n%s Enter Log. Lines beginning with `%s' are " - "removed automatically\n%s\n%s Commiting in %s\n" - "%s\n%s Modified Files:\n", - CVS_COMMIT_LOGPREFIX, CVS_COMMIT_LOGLINE, - CVS_COMMIT_LOGPREFIX, CVS_COMMIT_LOGPREFIX, - CVS_COMMIT_LOGPREFIX, CVS_COMMIT_LOGPREFIX, - dir, CVS_COMMIT_LOGPREFIX, CVS_COMMIT_LOGPREFIX); - - /* XXX list files here */ - - fprintf(fp, "%s %s\n", CVS_COMMIT_LOGPREFIX, - CVS_COMMIT_LOGLINE); + return (0); } - (void)fflush(fp); - - if (fstat(fd, &st1) == -1) { - cvs_log(LP_ERRNO, "failed to stat log message file"); + else + root = cf->cf_parent->cf_ddat->cd_root; - (void)fclose(fp); - if (unlink(path) == -1) - cvs_log(LP_ERRNO, "failed to unlink log file %s", path); - return (NULL); + rf = NULL; + if (cf->cf_parent != NULL) { + repo = cf->cf_parent->cf_ddat->cd_repo; + } + else { + repo = NULL; } - for (;;) { - ret = cvs_exec(argc, argv, fds); - if (ret == -1) - break; - if (fstat(fd, &st2) == -1) { - cvs_log(LP_ERRNO, "failed to stat log message file"); - break; - } - - if (st2.st_mtime != st1.st_mtime) - break; - - /* nothing was entered */ - fprintf(stderr, - "Log message unchanged or not specified\na)bort, " - "c)ontinue, e)dit, !)reuse this message unchanged " - "for remaining dirs\nAction: (continue) "); + entp = cvs_ent_getent(fpath); + if (entp == NULL) + return (-1); - if (fgets(buf, sizeof(buf), stdin) == NULL) { - cvs_log(LP_ERRNO, "failed to read from standard input"); - break; + if ((cf->cf_cvstat == CVS_FST_ADDED) || + (cf->cf_cvstat == CVS_FST_MODIFIED)) { + if ((root->cr_method != CVS_METHOD_LOCAL) && + (cvs_sendentry(root, entp) < 0)) { + cvs_ent_free(entp); + return (-1); } - len = strlen(buf); - if ((len == 0) || (len > 2)) { - fprintf(stderr, "invalid input\n"); - continue; - } - else if (buf[0] == 'a') { - cvs_log(LP_ERR, "aborted by user"); - break; - } else if ((buf[0] == '\n') || (buf[0] == 'c')) { - /* empty message */ - msg = strdup(""); - break; - } else if (ret == 'e') - continue; - else if (ret == '!') { - /* XXX do something */ - } + cvs_sendreq(root, CVS_REQ_MODIFIED, CVS_FILE_NAME(cf)); + cvs_sendfile(root, fpath); } - (void)fclose(fp); - (void)close(fd); + snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s", + root->cr_dir, repo, fpath, RCS_FILE_EXT); - if (unlink(path) == -1) - cvs_log(LP_ERRNO, "failed to unlink log file %s", path); + cvs_ent_free(entp); - return (msg); + return (0); } diff --git a/usr.bin/cvs/conf.y b/usr.bin/cvs/conf.y index 1b350e9fdb3..57cb242cf2f 100644 --- a/usr.bin/cvs/conf.y +++ b/usr.bin/cvs/conf.y @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.y,v 1.3 2004/09/27 12:39:29 jfb Exp $ */ +/* $OpenBSD: conf.y,v 1.4 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -640,6 +640,7 @@ u_int cvs_acl_eval(struct cvs_op *op) { u_int res; + char fpath[MAXPATHLEN]; CVSFILE *cf; struct acl_rule *rule; @@ -653,9 +654,11 @@ cvs_acl_eval(struct cvs_op *op) continue; /* see if one of the files has a matching path */ - TAILQ_FOREACH(cf, &(op->co_files), cf_list) - if (!cvs_acl_matchpath(cf->cf_path, rule->ar_path)) + TAILQ_FOREACH(cf, &(op->co_files), cf_list) { + /* XXX borked */ + if (!cvs_acl_matchpath(fpath, rule->ar_path)) continue; + } res = rule->ar_act; diff --git a/usr.bin/cvs/cvs/Makefile b/usr.bin/cvs/cvs/Makefile index c4460612a94..c8289dbda13 100644 --- a/usr.bin/cvs/cvs/Makefile +++ b/usr.bin/cvs/cvs/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.9 2004/11/18 15:48:53 jfb Exp $ +# $Id: Makefile,v 1.10 2004/11/26 16:23:50 jfb Exp $ .PATH: ${.CURDIR}/.. @@ -14,11 +14,13 @@ BINOWN=root BINGRP=_cvsd BINMODE=555 +CFLAGS= -g -ggdb CFLAGS+= -Wall CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes CFLAGS+= -Wsign-compare CFLAGS+= -DCVS +INSTALL_STRIP= .include <bsd.prog.mk> diff --git a/usr.bin/cvs/diff.c b/usr.bin/cvs/diff.c index be3a2918eff..36f2f5aaa79 100644 --- a/usr.bin/cvs/diff.c +++ b/usr.bin/cvs/diff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff.c,v 1.7 2004/08/12 18:37:27 jfb Exp $ */ +/* $OpenBSD: diff.c,v 1.8 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. * All rights reserved. @@ -244,7 +244,7 @@ static char *preadline(int, size_t, off_t); extern int cvs_client; -static int aflag, bflag, dflag, iflag, tflag, Tflag, wflag; +static int aflag, bflag, dflag, iflag, Nflag, tflag, Tflag, wflag; static int context, status; static int format = D_NORMAL; static struct stat stb1, stb2; @@ -361,7 +361,7 @@ cvs_diff(int argc, char **argv) memset(&darg, 0, sizeof(darg)); strlcpy(diffargs, argv[0], sizeof(diffargs)); - while ((ch = getopt(argc, argv, "cD:lir:u")) != -1) { + while ((ch = getopt(argc, argv, "cD:liN:r:u")) != -1) { switch (ch) { case 'c': strlcat(diffargs, " -c", sizeof(diffargs)); @@ -387,6 +387,10 @@ cvs_diff(int argc, char **argv) strlcat(diffargs, " -i", sizeof(diffargs)); iflag = 1; break; + case 'N': + strlcat(diffargs, " -N", sizeof(diffargs)); + Nflag = 1; + break; case 'r': if ((darg.rev1 == NULL) && (darg.date1 == NULL)) darg.rev1 = optarg; @@ -475,7 +479,8 @@ cvs_diff_sendflags(struct cvsroot *root, struct diff_arg *dap) int cvs_diff_file(struct cvs_file *cfp, void *arg) { - char *dir, *repo, rcspath[MAXPATHLEN], buf[64]; + char *dir, *repo, buf[64]; + char fpath[MAXPATHLEN], dfpath[MAXPATHLEN], rcspath[MAXPATHLEN]; BUF *b1, *b2; RCSNUM *r1, *r2; RCSFILE *rf; @@ -488,7 +493,8 @@ cvs_diff_file(struct cvs_file *cfp, void *arg) if (cfp->cf_type == DT_DIR) { if (cfp->cf_cvstat == CVS_FST_UNKNOWN) { root = cfp->cf_parent->cf_ddat->cd_root; - cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cfp->cf_name); + cvs_sendreq(root, CVS_REQ_QUESTIONABLE, + CVS_FILE_NAME(cfp)); } else { root = cfp->cf_ddat->cd_root; @@ -505,10 +511,10 @@ cvs_diff_file(struct cvs_file *cfp, void *arg) } rf = NULL; - diff_file = cfp->cf_path; + diff_file = cvs_file_getpath(cfp, fpath, sizeof(fpath)); if (cfp->cf_parent != NULL) { - dir = cfp->cf_parent->cf_path; + dir = cvs_file_getpath(cfp->cf_parent, dfpath, sizeof(dfpath)); root = cfp->cf_parent->cf_ddat->cd_root; repo = cfp->cf_parent->cf_ddat->cd_repo; } @@ -522,7 +528,8 @@ cvs_diff_file(struct cvs_file *cfp, void *arg) if (root->cr_method == CVS_METHOD_LOCAL) cvs_log(LP_WARN, "I know nothing about %s", diff_file); else - cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cfp->cf_name); + cvs_sendreq(root, CVS_REQ_QUESTIONABLE, + CVS_FILE_NAME(cfp)); return (0); } @@ -539,14 +546,15 @@ cvs_diff_file(struct cvs_file *cfp, void *arg) if (cfp->cf_cvstat == CVS_FST_UPTODATE) { if (root->cr_method != CVS_METHOD_LOCAL) - cvs_sendreq(root, CVS_REQ_UNCHANGED, cfp->cf_name); + cvs_sendreq(root, CVS_REQ_UNCHANGED, + CVS_FILE_NAME(cfp)); cvs_ent_free(entp); return (0); } /* at this point, the file is modified */ if (root->cr_method != CVS_METHOD_LOCAL) { - cvs_sendreq(root, CVS_REQ_MODIFIED, cfp->cf_name); + cvs_sendreq(root, CVS_REQ_MODIFIED, CVS_FILE_NAME(cfp)); cvs_sendfile(root, diff_file); } else { diff --git a/usr.bin/cvs/file.c b/usr.bin/cvs/file.c index dce9e4b2811..07171696afd 100644 --- a/usr.bin/cvs/file.c +++ b/usr.bin/cvs/file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: file.c,v 1.33 2004/08/31 11:17:02 joris Exp $ */ +/* $OpenBSD: file.c,v 1.34 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -86,6 +86,17 @@ static const char *cvs_ign_std[] = { /* + * 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 * added. Compare against this revision to see if this is the case */ @@ -95,13 +106,15 @@ 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 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 u_int8_t cvs_file_hashname (const char *); +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 *); @@ -119,6 +132,10 @@ cvs_file_init(void) FILE *ifp; 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); cvs_addedrev = rcsnum_alloc(); @@ -135,7 +152,8 @@ cvs_file_init(void) ifp = fopen(path, "r"); if (ifp == NULL) { if (errno != ENOENT) - cvs_log(LP_ERRNO, "failed to open `%s'", path); + cvs_log(LP_ERRNO, + "failed to open user's cvsignore", path); } else { while (fgets(buf, sizeof(buf), ifp) != NULL) { @@ -233,26 +251,30 @@ cvs_file_chkign(const char *file) */ 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; + char fp[MAXPATHLEN]; CVSFILE *cfp; + printf("cvs_file_create(%s)\n", path); cfp = cvs_file_alloc(path, type); if (cfp == NULL) return (NULL); cfp->cf_type = type; cfp->cf_mode = mode; - cfp->cf_ddat->cd_root = cvsroot_get(path); - cfp->cf_ddat->cd_repo = strdup(cfp->cf_path); - - if (cfp->cf_ddat->cd_repo == NULL) { - cvs_file_free(cfp); - return (NULL); - } + 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); + } + if ((mkdir(path, mode) == -1) || (cvs_mkadmin(cfp, mode) < 0)) { cvs_file_free(cfp); return (NULL); @@ -389,7 +411,7 @@ cvs_file_find(CVSFILE *hier, const char *path) } 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; if (sf == NULL) return (NULL); @@ -403,6 +425,53 @@ cvs_file_find(CVSFILE *hier, const char *path) /* + * 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() * * Attach the file <file> as one of the children of parent <parent>, which @@ -443,7 +512,7 @@ cvs_file_getdir(CVSFILE *cf, int flags) u_int ndirs; long base; void *dp, *ep; - char fbuf[2048], pbuf[MAXPATHLEN]; + char fbuf[2048], pbuf[MAXPATHLEN], fpath[MAXPATHLEN]; struct dirent *ent; CVSFILE *cfp; struct stat st; @@ -454,8 +523,10 @@ cvs_file_getdir(CVSFILE *cf, int flags) TAILQ_INIT(&dirs); cdp = cf->cf_ddat; + cvs_file_getpath(cf, fpath, sizeof(fpath)); + 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) return (-1); @@ -463,11 +534,9 @@ cvs_file_getdir(CVSFILE *cf, int flags) cvs_mkadmin(cf, 0755); /* if the CVS administrative directory exists, load the info */ - snprintf(pbuf, sizeof(pbuf), "%s/" CVS_PATH_CVSDIR, - cf->cf_path); + snprintf(pbuf, sizeof(pbuf), "%s/" CVS_PATH_CVSDIR, fpath); if ((stat(pbuf, &st) == 0) && S_ISDIR(st.st_mode)) { - if (cvs_readrepo(cf->cf_path, pbuf, - sizeof(pbuf)) == 0) { + if (cvs_readrepo(fpath, pbuf, sizeof(pbuf)) == 0) { cdp->cd_repo = strdup(pbuf); if (cdp->cd_repo == NULL) { cvs_log(LP_ERRNO, @@ -476,16 +545,16 @@ cvs_file_getdir(CVSFILE *cf, int flags) } } - 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)) return (0); - fd = open(cf->cf_path, O_RDONLY); + fd = open(fpath, O_RDONLY); 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); } @@ -511,8 +580,8 @@ cvs_file_getdir(CVSFILE *cf, int flags) if ((flags & CF_NOSYMS) && (ent->d_type == DT_LNK)) continue; - snprintf(pbuf, sizeof(pbuf), "%s/%s", - cf->cf_path, ent->d_name); + snprintf(pbuf, sizeof(pbuf), "%s/%s", fpath, + ent->d_name); cfp = cvs_file_lget(pbuf, flags, cf); if (cfp != NULL) { if (cfp->cf_type == DT_DIR) { @@ -528,6 +597,11 @@ cvs_file_getdir(CVSFILE *cf, int flags) } } while (ret > 0); +#if 1 + cvs_ent_close(cdp->cd_ent); + cdp->cd_ent = NULL; +#endif + if (flags & CF_SORT) { cvs_file_sort(&(cdp->cd_files), cdp->cd_nfiles); cvs_file_sort(&dirs, ndirs); @@ -555,8 +629,6 @@ cvs_file_getdir(CVSFILE *cf, int flags) void cvs_file_free(CVSFILE *cf) { - if (cf->cf_path != NULL) - free(cf->cf_path); if (cf->cf_ddat != NULL) cvs_file_freedir(cf->cf_ddat); free(cf); @@ -680,15 +752,22 @@ cvs_file_cmp(const void *f1, const void *f2) CVSFILE *cf1, *cf2; cf1 = *(CVSFILE **)f1; 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* cvs_file_alloc(const char *path, u_int type) { size_t len; char pbuf[MAXPATHLEN]; + const char *fnp; CVSFILE *cfp; struct cvs_dir *ddat; @@ -705,18 +784,17 @@ cvs_file_alloc(const char *path, u_int type) while (pbuf[len - 1] == '/') pbuf[--len] = '\0'; - cfp->cf_path = strdup(pbuf); - 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; + fnp = strrchr(path, '/'); + if (fnp == NULL) + fnp = path; 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_cvstat = CVS_FST_UNKNOWN; @@ -748,9 +826,7 @@ cvs_file_lget(const char *path, int flags, CVSFILE *parent) int cwd; struct stat st; CVSFILE *cfp; - struct cvs_ent *ent; - - ent = NULL; + struct cvs_ent *ent = NULL; if (strcmp(path, ".") == 0) cwd = 1; @@ -772,7 +848,7 @@ cvs_file_lget(const char *path, int flags, CVSFILE *parent) cfp->cf_mtime = st.st_mtime; 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) { @@ -809,3 +885,63 @@ cvs_file_cmpname(const char *name1, const char *name2) return (cvs_nocase == 0) ? (strcmp(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); +} diff --git a/usr.bin/cvs/file.h b/usr.bin/cvs/file.h index 99d29b6e9ca..2609dd56f20 100644 --- a/usr.bin/cvs/file.h +++ b/usr.bin/cvs/file.h @@ -1,4 +1,4 @@ -/* $OpenBSD: file.h,v 1.8 2004/08/06 20:12:15 jfb Exp $ */ +/* $OpenBSD: file.h,v 1.9 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -30,12 +30,18 @@ #include <sys/param.h> #include <dirent.h> +#include <search.h> struct cvs_file; struct cvs_dir; struct cvs_entries; +#define CVS_FILE_MAXDEPTH 32 +#define CVS_FILE_NBUCKETS 256 + + + #define CF_STAT 0x01 /* obsolete */ #define CF_IGNORE 0x02 /* apply regular ignore rules */ #define CF_RECURSE 0x04 /* recurse on directory operations */ @@ -68,23 +74,30 @@ struct cvs_entries; #define CVS_FST_CONFLICT 5 #define CVS_FST_PATCHED 6 + +struct cvs_fname { + char *cf_name; + u_int cf_ref; + SLIST_ENTRY(cvs_fname) cf_list; +}; + TAILQ_HEAD(cvs_flist, cvs_file); typedef struct cvs_file { - char *cf_path; - struct cvs_file *cf_parent; /* parent directory (NULL if none) */ - char *cf_name; - mode_t cf_mode; - time_t cf_mtime; - u_int16_t cf_cvstat; /* cvs status of the file */ - u_int16_t cf_type; /* uses values from dirent.h */ - struct cvs_dir *cf_ddat; /* only for directories */ + struct cvs_file *cf_parent; /* parent directory (NULL if none) */ + struct cvs_fname *cf_name; + mode_t cf_mode; + time_t cf_mtime; + u_int16_t cf_cvstat; /* cvs status of the file */ + u_int16_t cf_type; /* uses values from dirent.h */ + struct cvs_dir *cf_ddat; /* only for directories */ TAILQ_ENTRY(cvs_file) cf_list; } CVSFILE; +#define CVS_FILE_NAME(cf) (cf->cf_name->cf_name) #define CVS_DIRF_STATIC 0x01 @@ -92,12 +105,12 @@ typedef struct cvs_file { struct cvs_dir { - u_int cd_flags; struct cvsroot *cd_root; char *cd_repo; struct cvs_entries *cd_ent; struct cvs_flist cd_files; - u_int cd_nfiles; + u_int16_t cd_nfiles; + u_int16_t cd_flags; }; @@ -116,13 +129,14 @@ struct cvs_dir { int cvs_file_init (void); int cvs_file_ignore (const char *); int cvs_file_chkign (const char *); -CVSFILE* cvs_file_create (const char *, u_int, mode_t); CVSFILE* cvs_file_get (const char *, int); CVSFILE* cvs_file_getspec (char **, int, int); +CVSFILE* cvs_file_create (CVSFILE *, const char *, u_int, mode_t); CVSFILE* cvs_file_find (CVSFILE *, const char *); int cvs_file_attach (CVSFILE *, CVSFILE *); +char* cvs_file_getpath (CVSFILE *, char *, size_t); int cvs_file_examine (CVSFILE *, int (*)(CVSFILE *, void *), void *); -void cvs_file_free (struct cvs_file *); +void cvs_file_free (CVSFILE *); #endif /* FILE_H */ diff --git a/usr.bin/cvs/getlog.c b/usr.bin/cvs/getlog.c index 7afe0e6160a..662755e5472 100644 --- a/usr.bin/cvs/getlog.c +++ b/usr.bin/cvs/getlog.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getlog.c,v 1.6 2004/11/18 15:54:17 jfb Exp $ */ +/* $OpenBSD: getlog.c,v 1.7 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -126,15 +126,18 @@ cvs_getlog(int argc, char **argv) static int cvs_getlog_file(CVSFILE *cf, void *arg) { - char *dir, *repo, rcspath[MAXPATHLEN]; + char *repo, fpath[MAXPATHLEN]; RCSFILE *rf; struct cvsroot *root; struct cvs_ent *entp; + cvs_file_getpath(cf, fpath, sizeof(fpath)); + if (cf->cf_type == DT_DIR) { if (cf->cf_cvstat == CVS_FST_UNKNOWN) { root = cf->cf_parent->cf_ddat->cd_root; - cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name); + cvs_sendreq(root, CVS_REQ_QUESTIONABLE, + CVS_FILE_NAME(cf)); } else { root = cf->cf_ddat->cd_root; @@ -153,23 +156,22 @@ cvs_getlog_file(CVSFILE *cf, void *arg) rf = NULL; if (cf->cf_parent != NULL) { - dir = cf->cf_parent->cf_path; repo = cf->cf_parent->cf_ddat->cd_repo; } else { - dir = "."; repo = NULL; } if (cf->cf_cvstat == CVS_FST_UNKNOWN) { if (root->cr_method == CVS_METHOD_LOCAL) - cvs_printf("? %s\n", cf->cf_path); + cvs_printf("? %s\n", fpath); else - cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name); + cvs_sendreq(root, CVS_REQ_QUESTIONABLE, + CVS_FILE_NAME(cf)); return (0); } - entp = cvs_ent_getent(cf->cf_path); + entp = cvs_ent_getent(fpath); if (entp == NULL) return (-1); @@ -182,11 +184,12 @@ cvs_getlog_file(CVSFILE *cf, void *arg) if (root->cr_method != CVS_METHOD_LOCAL) { switch (cf->cf_cvstat) { case CVS_FST_UPTODATE: - cvs_sendreq(root, CVS_REQ_UNCHANGED, cf->cf_name); + cvs_sendreq(root, CVS_REQ_UNCHANGED, CVS_FILE_NAME(cf)); break; case CVS_FST_ADDED: case CVS_FST_MODIFIED: - cvs_sendreq(root, CVS_REQ_ISMODIFIED, cf->cf_name); + cvs_sendreq(root, CVS_REQ_ISMODIFIED, + CVS_FILE_NAME(cf)); break; default: return (-1); @@ -196,10 +199,10 @@ cvs_getlog_file(CVSFILE *cf, void *arg) return (0); } - snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s", - root->cr_dir, repo, cf->cf_path, RCS_FILE_EXT); + snprintf(fpath, sizeof(fpath), "%s/%s/%s%s", + root->cr_dir, repo, fpath, RCS_FILE_EXT); - rf = rcs_open(rcspath, RCS_MODE_READ); + rf = rcs_open(fpath, RCS_MODE_READ); if (rf == NULL) { cvs_ent_free(entp); return (-1); diff --git a/usr.bin/cvs/logmsg.c b/usr.bin/cvs/logmsg.c index 952485fa4ec..5ac6c3ee50d 100644 --- a/usr.bin/cvs/logmsg.c +++ b/usr.bin/cvs/logmsg.c @@ -1,4 +1,4 @@ -/* $OpenBSD: logmsg.c,v 1.1 2004/11/12 17:49:11 jfb Exp $ */ +/* $OpenBSD: logmsg.c,v 1.2 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -36,8 +36,10 @@ #include "cvs.h" #include "log.h" #include "buf.h" +#include "proto.h" +#define CVS_LOGMSG_TERMWIDTH 80 #define CVS_LOGMSG_BIGMSG 32000 #define CVS_LOGMSG_FTMPL "/tmp/cvsXXXXXXXXXX" #define CVS_LOGMSG_LOGPREFIX "CVS:" @@ -252,3 +254,25 @@ cvs_logmsg_get(const char *dir) return (msg); } + + +/* + * cvs_logmsg_send() + * + */ + +int +cvs_logmsg_send(struct cvsroot *root, const char *msg) +{ + const char *mp, *np; + + for (np = msg;; np = strchr(np, '\n')) { + if (np == NULL) + break; + + if (cvs_sendarg(root, np, (np == msg) ? 0 : 1) < 0) + return (-1); + } + + return (0); +} diff --git a/usr.bin/cvs/proto.c b/usr.bin/cvs/proto.c index 3ebbde34314..e402ab581c4 100644 --- a/usr.bin/cvs/proto.c +++ b/usr.bin/cvs/proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: proto.c,v 1.27 2004/11/16 21:03:43 jfb Exp $ */ +/* $OpenBSD: proto.c,v 1.28 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -177,6 +177,8 @@ static int cvs_server_logon = 0; static FILE *cvs_server_inlog = NULL; static FILE *cvs_server_outlog = NULL; +static pid_t cvs_subproc_pid; + /* * cvs_connect() @@ -194,7 +196,6 @@ int cvs_connect(struct cvsroot *root) { int argc, infd[2], outfd[2], errfd[2]; - pid_t pid; char *argv[16], *cvs_server_cmd, *vresp; if (pipe(infd) == -1) { @@ -221,12 +222,12 @@ cvs_connect(struct cvsroot *root) return (-1); } - pid = fork(); - if (pid == -1) { + cvs_subproc_pid = fork(); + if (cvs_subproc_pid == -1) { cvs_log(LP_ERRNO, "failed to fork for cvs server connection"); return (-1); } - if (pid == 0) { + else if (cvs_subproc_pid == 0) { if ((dup2(infd[0], STDIN_FILENO) == -1) || (dup2(outfd[1], STDOUT_FILENO) == -1)) { cvs_log(LP_ERRNO, @@ -960,16 +961,18 @@ cvs_recvraw(struct cvsroot *root, void *dst, size_t len) int cvs_senddir(struct cvsroot *root, CVSFILE *dir) { - char buf[MAXPATHLEN]; + char lbuf[MAXPATHLEN], rbuf[MAXPATHLEN]; if (dir->cf_ddat->cd_repo == NULL) - strlcpy(buf, root->cr_dir, sizeof(buf)); + strlcpy(rbuf, root->cr_dir, sizeof(rbuf)); else - snprintf(buf, sizeof(buf), "%s/%s", root->cr_dir, + snprintf(rbuf, sizeof(rbuf), "%s/%s", root->cr_dir, dir->cf_ddat->cd_repo); - if ((cvs_sendreq(root, CVS_REQ_DIRECTORY, dir->cf_path) < 0) || - (cvs_sendln(root, buf) < 0)) + cvs_file_getpath(dir, lbuf, sizeof(lbuf)); + + if ((cvs_sendreq(root, CVS_REQ_DIRECTORY, lbuf) < 0) || + (cvs_sendln(root, rbuf) < 0)) return (-1); return (0); diff --git a/usr.bin/cvs/resp.c b/usr.bin/cvs/resp.c index 04afbf4bd4f..3b2662ccdcf 100644 --- a/usr.bin/cvs/resp.c +++ b/usr.bin/cvs/resp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: resp.c,v 1.7 2004/09/23 15:35:10 jfb Exp $ */ +/* $OpenBSD: resp.c,v 1.8 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -384,7 +384,7 @@ cvs_resp_sticky(struct cvsroot *root, int type, char *line) cf = cvs_file_find(sdir, file); if (cf == NULL) { /* attempt to create it */ - cf = cvs_file_create(line, DT_DIR, 0755); + cf = cvs_file_create(sdir, line, DT_DIR, 0755); if (cf == NULL) return (-1); cf->cf_ddat->cd_repo = strdup(line); @@ -395,7 +395,8 @@ cvs_resp_sticky(struct cvsroot *root, int type, char *line) /* add a directory entry to the parent */ if (CVS_DIR_ENTRIES(sdir) != NULL) { - snprintf(buf, sizeof(buf), "D/%s////", cf->cf_name); + snprintf(buf, sizeof(buf), "D/%s////", + CVS_FILE_NAME(cf)); ent = cvs_ent_parse(buf); if (ent == NULL) cvs_log(LP_ERR, diff --git a/usr.bin/cvs/status.c b/usr.bin/cvs/status.c index d302fa1e4d5..d7ab962bcdf 100644 --- a/usr.bin/cvs/status.c +++ b/usr.bin/cvs/status.c @@ -1,4 +1,4 @@ -/* $OpenBSD: status.c,v 1.1 2004/07/30 17:44:48 jfb Exp $ */ +/* $OpenBSD: status.c,v 1.2 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -85,7 +85,6 @@ cvs_status(int argc, char **argv) if (argc == 0) { cf = cvs_file_get(".", flags); if (cf == NULL) { - printf("FUCK!\n"); return (EX_DATAERR); } @@ -108,14 +107,15 @@ cvs_status(int argc, char **argv) */ int -cvs_status_file(struct cvs_file *cfp, void *arg) +cvs_status_file(CVSFILE *cfp, void *arg) { - char *dir, *repo, rcspath[MAXPATHLEN]; + char *repo, fpath[MAXPATHLEN], rcspath[MAXPATHLEN]; RCSFILE *rf; struct cvs_ent *entp; struct cvsroot *root; - cvs_log(LP_DEBUG, "%s: getting status for %s", __func__, cfp->cf_path); + cvs_file_getpath(cfp, fpath, sizeof(fpath)); + cvs_log(LP_DEBUG, "%s: getting status for %s", __func__, fpath); if (cfp->cf_type == DT_DIR) { root = cfp->cf_ddat->cd_root; @@ -132,24 +132,22 @@ cvs_status_file(struct cvs_file *cfp, void *arg) rf = NULL; if (cfp->cf_parent != NULL) { - dir = cfp->cf_parent->cf_path; repo = cfp->cf_parent->cf_ddat->cd_repo; } else { - dir = "."; repo = NULL; } if (cfp->cf_cvstat == CVS_FST_UNKNOWN) { if (root->cr_method == CVS_METHOD_LOCAL) - cvs_log(LP_WARN, "I know nothing about %s", - cfp->cf_path); + cvs_log(LP_WARN, "I know nothing about %s", fpath); else - cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cfp->cf_name); + cvs_sendreq(root, CVS_REQ_QUESTIONABLE, + CVS_FILE_NAME(cfp)); return (0); } - entp = cvs_ent_getent(cfp->cf_path); + entp = cvs_ent_getent(fpath); if (entp == NULL) return (-1); @@ -162,19 +160,20 @@ cvs_status_file(struct cvs_file *cfp, void *arg) if (cfp->cf_cvstat == CVS_FST_UPTODATE) { if (root->cr_method != CVS_METHOD_LOCAL) - cvs_sendreq(root, CVS_REQ_UNCHANGED, cfp->cf_name); + cvs_sendreq(root, CVS_REQ_UNCHANGED, + CVS_FILE_NAME(cfp)); cvs_ent_free(entp); return (0); } /* at this point, the file is modified */ if (root->cr_method != CVS_METHOD_LOCAL) { - cvs_sendreq(root, CVS_REQ_MODIFIED, cfp->cf_name); - cvs_sendfile(root, cfp->cf_path); + cvs_sendreq(root, CVS_REQ_MODIFIED, CVS_FILE_NAME(cfp)); + cvs_sendfile(root, fpath); } else { snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s", - root->cr_dir, repo, cfp->cf_name, RCS_FILE_EXT); + root->cr_dir, repo, CVS_FILE_NAME(cfp), RCS_FILE_EXT); rf = rcs_open(rcspath, RCS_MODE_READ); if (rf == NULL) { diff --git a/usr.bin/cvs/update.c b/usr.bin/cvs/update.c index 4c39961b91b..398cb6bd0a4 100644 --- a/usr.bin/cvs/update.c +++ b/usr.bin/cvs/update.c @@ -1,4 +1,4 @@ -/* $OpenBSD: update.c,v 1.8 2004/08/27 15:55:31 jfb Exp $ */ +/* $OpenBSD: update.c,v 1.9 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -119,15 +119,18 @@ cvs_update(int argc, char **argv) int cvs_update_file(CVSFILE *cf, void *arg) { - char *dir, *repo, rcspath[MAXPATHLEN]; + char *repo, fpath[MAXPATHLEN], rcspath[MAXPATHLEN]; RCSFILE *rf; struct cvsroot *root; struct cvs_ent *entp; + cvs_file_getpath(cf, fpath, sizeof(fpath)); + if (cf->cf_type == DT_DIR) { if (cf->cf_cvstat == CVS_FST_UNKNOWN) { root = cf->cf_parent->cf_ddat->cd_root; - cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name); + cvs_sendreq(root, CVS_REQ_QUESTIONABLE, + CVS_FILE_NAME(cf)); } else { root = cf->cf_ddat->cd_root; @@ -146,23 +149,21 @@ cvs_update_file(CVSFILE *cf, void *arg) rf = NULL; if (cf->cf_parent != NULL) { - dir = cf->cf_parent->cf_path; repo = cf->cf_parent->cf_ddat->cd_repo; } else { - dir = "."; repo = NULL; } if (cf->cf_cvstat == CVS_FST_UNKNOWN) { if (root->cr_method == CVS_METHOD_LOCAL) - cvs_printf("? %s\n", cf->cf_path); + cvs_printf("? %s\n", fpath); else - cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name); + cvs_sendreq(root, CVS_REQ_QUESTIONABLE, CVS_FILE_NAME(cf)); return (0); } - entp = cvs_ent_getent(cf->cf_path); + entp = cvs_ent_getent(fpath); if (entp == NULL) return (-1); @@ -175,12 +176,12 @@ cvs_update_file(CVSFILE *cf, void *arg) if (root->cr_method != CVS_METHOD_LOCAL) { switch (cf->cf_cvstat) { case CVS_FST_UPTODATE: - cvs_sendreq(root, CVS_REQ_UNCHANGED, cf->cf_name); + cvs_sendreq(root, CVS_REQ_UNCHANGED, CVS_FILE_NAME(cf)); break; case CVS_FST_ADDED: case CVS_FST_MODIFIED: - cvs_sendreq(root, CVS_REQ_MODIFIED, cf->cf_name); - cvs_sendfile(root, cf->cf_path); + cvs_sendreq(root, CVS_REQ_MODIFIED, CVS_FILE_NAME(cf)); + cvs_sendfile(root, fpath); break; default: return (-1); @@ -191,7 +192,7 @@ cvs_update_file(CVSFILE *cf, void *arg) } snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s", - root->cr_dir, repo, cf->cf_path, RCS_FILE_EXT); + root->cr_dir, repo, fpath, RCS_FILE_EXT); rf = rcs_open(rcspath, RCS_MODE_READ); if (rf == NULL) { diff --git a/usr.bin/cvs/util.c b/usr.bin/cvs/util.c index 929a311e4eb..e9b7b975559 100644 --- a/usr.bin/cvs/util.c +++ b/usr.bin/cvs/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.12 2004/11/10 22:27:31 krapht Exp $ */ +/* $OpenBSD: util.c,v 1.13 2004/11/26 16:23:50 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org> * All rights reserved. @@ -29,7 +29,6 @@ #include <sys/wait.h> #include <md5.h> -#include <err.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -468,26 +467,28 @@ cvs_freeargv(char **argv, int argc) */ int -cvs_mkadmin(struct cvs_file *cdir, mode_t mode) +cvs_mkadmin(CVSFILE *cdir, mode_t mode) { - char path[MAXPATHLEN]; + char dpath[MAXPATHLEN], path[MAXPATHLEN]; FILE *fp; CVSENTRIES *ef; struct stat st; struct cvsroot *root; - snprintf(path, sizeof(path), "%s/" CVS_PATH_CVSDIR, cdir->cf_path); + cvs_file_getpath(cdir, dpath, sizeof(dpath)); + + snprintf(path, sizeof(path), "%s/" CVS_PATH_CVSDIR, dpath); if ((mkdir(path, mode) == -1) && (errno != EEXIST)) { cvs_log(LP_ERRNO, "failed to create directory %s", path); return (-1); } /* just create an empty Entries file */ - ef = cvs_ent_open(cdir->cf_path, O_WRONLY); + ef = cvs_ent_open(dpath, O_WRONLY); (void)cvs_ent_close(ef); root = cdir->cf_ddat->cd_root; - snprintf(path, sizeof(path), "%s/" CVS_PATH_ROOTSPEC, cdir->cf_path); + snprintf(path, sizeof(path), "%s/" CVS_PATH_ROOTSPEC, dpath); if ((root != NULL) && (stat(path, &st) != 0) && (errno == ENOENT)) { fp = fopen(path, "w"); if (fp == NULL) { @@ -513,7 +514,7 @@ cvs_mkadmin(struct cvs_file *cdir, mode_t mode) (void)fclose(fp); } - snprintf(path, sizeof(path), "%s/" CVS_PATH_REPOSITORY, cdir->cf_path); + snprintf(path, sizeof(path), "%s/" CVS_PATH_REPOSITORY, dpath); if ((stat(path, &st) != 0) && (errno == ENOENT) && (cdir->cf_ddat->cd_repo != NULL)) { fp = fopen(path, "w"); @@ -544,11 +545,12 @@ cvs_exec(int argc, char **argv, int fds[3]) return (-1); } else if (pid == 0) { execvp(argv[0], argv); - err(1, "failed to exec %s", argv[0]); + cvs_log(LP_ERRNO, "failed to exec %s", argv[0]); + exit(1); } if (waitpid(pid, &ret, 0) == -1) - warn("failed to waitpid"); + cvs_log(LP_ERRNO, "failed to waitpid"); return (ret); } |