summaryrefslogtreecommitdiff
path: root/usr.bin/cvs
diff options
context:
space:
mode:
authorJean-Francois Brousseau <jfb@cvs.openbsd.org>2004-11-26 16:23:51 +0000
committerJean-Francois Brousseau <jfb@cvs.openbsd.org>2004-11-26 16:23:51 +0000
commitdb3cb2196dc4401149258da8e6829cd3dad178e7 (patch)
treeb9a9aaf07fb5d5f42c77215bccac5baa122704a8 /usr.bin/cvs
parent03ab04eece2d53fa3853fa9383b5278032ffa1ce (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.c257
-rw-r--r--usr.bin/cvs/conf.y9
-rw-r--r--usr.bin/cvs/cvs/Makefile4
-rw-r--r--usr.bin/cvs/diff.c28
-rw-r--r--usr.bin/cvs/file.c228
-rw-r--r--usr.bin/cvs/file.h40
-rw-r--r--usr.bin/cvs/getlog.c29
-rw-r--r--usr.bin/cvs/logmsg.c26
-rw-r--r--usr.bin/cvs/proto.c23
-rw-r--r--usr.bin/cvs/resp.c7
-rw-r--r--usr.bin/cvs/status.c29
-rw-r--r--usr.bin/cvs/update.c25
-rw-r--r--usr.bin/cvs/util.c22
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);
}