From b59c4319a2b0bee7cbb7f9ef3342f372940000e1 Mon Sep 17 00:00:00 2001 From: Jean-Francois Brousseau Date: Fri, 30 Jul 2004 01:49:27 +0000 Subject: Move to the new API for the client-server protocol. All functions now take a cvs root structure as parameter. This will allow for much easier management of CVS trees that make use of multiple roots. --- usr.bin/cvs/add.c | 21 +- usr.bin/cvs/checkout.c | 22 +- usr.bin/cvs/client.c | 123 +------- usr.bin/cvs/commit.c | 3 +- usr.bin/cvs/cvs.c | 62 ++-- usr.bin/cvs/cvs.h | 150 +--------- usr.bin/cvs/cvs/Makefile | 6 +- usr.bin/cvs/diff.c | 396 ++++++++++---------------- usr.bin/cvs/file.h | 206 ++++++++++++++ usr.bin/cvs/getlog.c | 3 +- usr.bin/cvs/history.c | 22 +- usr.bin/cvs/proto.c | 714 ++++++++++++++++++++++------------------------- usr.bin/cvs/proto.h | 173 ++++++++++++ usr.bin/cvs/root.c | 3 +- usr.bin/cvs/update.c | 24 +- usr.bin/cvs/util.c | 4 +- usr.bin/cvs/version.c | 23 +- 17 files changed, 960 insertions(+), 995 deletions(-) create mode 100644 usr.bin/cvs/file.h create mode 100644 usr.bin/cvs/proto.h (limited to 'usr.bin/cvs') diff --git a/usr.bin/cvs/add.c b/usr.bin/cvs/add.c index fde7a4f205a..733ccdff5f3 100644 --- a/usr.bin/cvs/add.c +++ b/usr.bin/cvs/add.c @@ -1,4 +1,4 @@ -/* $OpenBSD: add.c,v 1.1 2004/07/13 22:02:40 jfb Exp $ */ +/* $OpenBSD: add.c,v 1.2 2004/07/30 01:49:21 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -35,10 +35,7 @@ #include "cvs.h" #include "log.h" - - - -extern struct cvsroot *cvs_root; +#include "proto.h" @@ -54,6 +51,7 @@ cvs_add(int argc, char **argv) { int ch, i, ret; char *kflag, *msg; + struct cvsroot *root; kflag = NULL; @@ -77,22 +75,19 @@ cvs_add(int argc, char **argv) return (EX_USAGE); } + root = NULL; + for (i = 0; i < argc; i++) { - /* - * XXX figure out if we should send `Modified' or `Is-Modified' - * The cvs documentation specifies that Modified should be used - * in this case, but GNU CVS sends the latter. - */ - ret = cvs_client_sendreq(CVS_REQ_ISMODIFIED, argv[i], 0); + ret = cvs_sendreq(root, CVS_REQ_ISMODIFIED, argv[i]); if (ret < 0) return (EX_DATAERR); } for (i = 0; i < argc; i++) { - ret = cvs_client_sendreq(CVS_REQ_ARGUMENT, argv[i], 0); + ret = cvs_sendreq(root, CVS_REQ_ARGUMENT, argv[i]); } - ret = cvs_client_sendreq(CVS_REQ_ADD, NULL, 0); + ret = cvs_sendreq(root, CVS_REQ_ADD, NULL); return (0); } diff --git a/usr.bin/cvs/checkout.c b/usr.bin/cvs/checkout.c index 4ea52dc3c2b..7e3e220eb22 100644 --- a/usr.bin/cvs/checkout.c +++ b/usr.bin/cvs/checkout.c @@ -1,4 +1,4 @@ -/* $OpenBSD: checkout.c,v 1.4 2004/07/29 18:32:45 jfb Exp $ */ +/* $OpenBSD: checkout.c,v 1.5 2004/07/30 01:49:22 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -35,6 +35,7 @@ #include "cvs.h" #include "log.h" +#include "proto.h" @@ -49,6 +50,7 @@ int cvs_checkout(int argc, char **argv) { int ch; + struct cvsroot *root; while ((ch = getopt(argc, argv, "")) != -1) { switch (ch) { @@ -66,18 +68,18 @@ cvs_checkout(int argc, char **argv) return (EX_USAGE); } - cvs_root = cvsroot_get("."); - if (cvs_root->cr_method != CVS_METHOD_LOCAL) { - cvs_client_connect(cvs_root); + root = cvsroot_get("."); + if (root->cr_method != CVS_METHOD_LOCAL) { + cvs_connect(root); } - cvs_client_sendarg(argv[0], 0); - cvs_client_senddir("."); - cvs_client_sendreq(CVS_REQ_XPANDMOD, NULL, 1); + cvs_sendarg(root, argv[0], 0); + cvs_senddir(root, "."); + cvs_sendreq(root, CVS_REQ_XPANDMOD, NULL); - cvs_client_sendarg(argv[0], 0); - cvs_client_senddir("."); - cvs_client_sendreq(CVS_REQ_CO, NULL, 1); + cvs_sendarg(root, argv[0], 0); + cvs_senddir(root, "."); + cvs_sendreq(root, CVS_REQ_CO, NULL); return (0); } diff --git a/usr.bin/cvs/client.c b/usr.bin/cvs/client.c index 892f7a87333..471fc54dced 100644 --- a/usr.bin/cvs/client.c +++ b/usr.bin/cvs/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.6 2004/07/29 18:32:03 jfb Exp $ */ +/* $OpenBSD: client.c,v 1.7 2004/07/30 01:49:22 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -41,6 +41,7 @@ #include "cvs.h" #include "log.h" +#include "proto.h" @@ -199,80 +200,6 @@ cvs_client_disconnect(struct cvsroot *root) } -/* - * cvs_client_sendreq() - * - * Send a request to the server of type , with optional arguments - * contained in , which should not be terminated by a newline. - * The argument is 0 if no response is expected, or any other value if - * a response is expected. - * Returns 0 on success, or -1 on failure. - */ - -int -cvs_client_sendreq(u_int rid, const char *arg, int resp) -{ - int ret; - size_t len; - char *rbp; - const char *reqp; - - if (cvs_server_in == NULL) { - cvs_log(LP_ERR, "cannot send request: Not connected"); - return (-1); - } - - reqp = cvs_req_getbyid(rid); - if (reqp == NULL) { - cvs_log(LP_ERR, "unsupported request type %u", rid); - return (-1); - } - - snprintf(cvs_client_buf, sizeof(cvs_client_buf), "%s%s%s\n", reqp, - (arg == NULL) ? "" : " ", (arg == NULL) ? "" : arg); - - rbp = cvs_client_buf; - - if (cvs_server_inlog != NULL) - fputs(cvs_client_buf, cvs_server_inlog); - - ret = fputs(cvs_client_buf, cvs_server_in); - if (ret == EOF) { - cvs_log(LP_ERRNO, "failed to send request to server"); - return (-1); - } - - if (resp) { - do { - /* wait for incoming data */ - if (fgets(cvs_client_buf, sizeof(cvs_client_buf), - cvs_server_out) == NULL) { - if (feof(cvs_server_out)) - return (0); - cvs_log(LP_ERRNO, - "failed to read response from server"); - return (-1); - } - - if (cvs_server_outlog != NULL) - fputs(cvs_client_buf, cvs_server_outlog); - - if ((len = strlen(cvs_client_buf)) != 0) { - if (cvs_client_buf[len - 1] != '\n') { - /* truncated line */ - } - else - cvs_client_buf[--len] = '\0'; - } - - ret = cvs_resp_handle(cvs_client_buf); - } while (ret == 0); - } - - return (ret); -} - - /* * cvs_client_sendln() * @@ -541,49 +468,3 @@ cvs_client_initlog(void) return (0); } - - -/* - * cvs_client_sendfile() - * - */ - -int -cvs_client_sendfile(const char *path) -{ - int fd; - ssize_t ret; - char buf[4096]; - struct stat st; - - if (stat(path, &st) == -1) { - cvs_log(LP_ERRNO, "failed to stat `%s'", path); - return (-1); - } - - fd = open(path, O_RDONLY, 0); - if (fd == -1) { - return (-1); - } - - if (cvs_modetostr(st.st_mode, buf, sizeof(buf)) < 0) - return (-1); - - cvs_client_sendln(buf); - snprintf(buf, sizeof(buf), "%lld\n", st.st_size); - cvs_client_sendln(buf); - - while ((ret = read(fd, buf, sizeof(buf))) != 0) { - if (ret == -1) { - cvs_log(LP_ERRNO, "failed to read file `%s'", path); - return (-1); - } - - cvs_client_sendraw(buf, (size_t)ret); - - } - - (void)close(fd); - - return (0); -} diff --git a/usr.bin/cvs/commit.c b/usr.bin/cvs/commit.c index 839bd29abb2..263da620078 100644 --- a/usr.bin/cvs/commit.c +++ b/usr.bin/cvs/commit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: commit.c,v 1.1 2004/07/13 22:02:40 jfb Exp $ */ +/* $OpenBSD: commit.c,v 1.2 2004/07/30 01:49:22 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -37,6 +37,7 @@ #include "cvs.h" #include "log.h" +#include "proto.h" diff --git a/usr.bin/cvs/cvs.c b/usr.bin/cvs/cvs.c index d109dfe27f6..2094946cf0e 100644 --- a/usr.bin/cvs/cvs.c +++ b/usr.bin/cvs/cvs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cvs.c,v 1.5 2004/07/29 17:48:19 jfb Exp $ */ +/* $OpenBSD: cvs.c,v 1.6 2004/07/30 01:49:22 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -57,6 +57,7 @@ int cvs_readonly = 0; /* name of the command we are running */ char *cvs_command; +int cvs_cmdop; char *cvs_rootstr; char *cvs_rsh = CVS_RSH_DEFAULT; char *cvs_editor = CVS_EDITOR_DEFAULT; @@ -78,6 +79,7 @@ struct cvsroot *cvs_root = NULL; */ static struct cvs_cmd { + int cmd_op; char cmd_name[CVS_CMD_MAXNAMELEN]; char cmd_alias[CVS_CMD_MAXALIAS][CVS_CMD_MAXNAMELEN]; int (*cmd_hdlr)(int, char **); @@ -85,62 +87,62 @@ static struct cvs_cmd { char cmd_descr[CVS_CMD_MAXDESCRLEN]; } cvs_cdt[] = { { - "add", { "ad", "new" }, cvs_add, + CVS_OP_ADD, "add", { "ad", "new" }, cvs_add, "[-m msg] file ...", "Add a new file/directory to the repository", }, { - "admin", { "adm", "rcs" }, NULL, + -1, "admin", { "adm", "rcs" }, NULL, "", "Administration front end for rcs", }, { - "annotate", { "ann" }, NULL, + CVS_OP_ANNOTATE, "annotate", { "ann" }, NULL, "", "Show last revision where each line was modified", }, { - "checkout", { "co", "get" }, cvs_checkout, + CVS_OP_CHECKOUT, "checkout", { "co", "get" }, cvs_checkout, "", "Checkout sources for editing", }, { - "commit", { "ci", "com" }, cvs_commit, + CVS_OP_COMMIT, "commit", { "ci", "com" }, cvs_commit, "[-flR] [-F logfile | -m msg] [-r rev] ...", "Check files into the repository", }, { - "diff", { "di", "dif" }, cvs_diff, + CVS_OP_DIFF, "diff", { "di", "dif" }, cvs_diff, "[-cilu] [-D date] [-r rev] ...", "Show differences between revisions", }, { - "edit", { }, NULL, + -1, "edit", { }, NULL, "", "Get ready to edit a watched file", }, { - "editors", { }, NULL, + -1, "editors", { }, NULL, "", "See who is editing a watched file", }, { - "export", { "ex", "exp" }, NULL, + -1, "export", { "ex", "exp" }, NULL, "", "Export sources from CVS, similar to checkout", }, { - "history", { "hi", "his" }, cvs_history, + CVS_OP_HISTORY, "history", { "hi", "his" }, cvs_history, "", "Show repository access history", }, { - "import", { "im", "imp" }, NULL, + CVS_OP_IMPORT, "import", { "im", "imp" }, NULL, "", "Import sources into CVS, using vendor branches", }, { - "init", { }, cvs_init, + CVS_OP_INIT, "init", { }, cvs_init, "", "Create a CVS repository if it doesn't exist", }, @@ -152,82 +154,82 @@ static struct cvs_cmd { }, #endif { - "log", { "lo" }, cvs_getlog, + CVS_OP_LOG, "log", { "lo" }, cvs_getlog, "", "Print out history information for files", }, { - "login", {}, NULL, + -1, "login", {}, NULL, "", "Prompt for password for authenticating server", }, { - "logout", {}, NULL, + -1, "logout", {}, NULL, "", "Removes entry in .cvspass for remote repository", }, { - "rdiff", {}, NULL, + -1, "rdiff", {}, NULL, "", "Create 'patch' format diffs between releases", }, { - "release", {}, NULL, + -1, "release", {}, NULL, "", "Indicate that a Module is no longer in use", }, { - "remove", {}, NULL, + CVS_OP_REMOVE, "remove", {}, NULL, "", "Remove an entry from the repository", }, { - "rlog", {}, NULL, + -1, "rlog", {}, NULL, "", "Print out history information for a module", }, { - "rtag", {}, NULL, + -1, "rtag", {}, NULL, "", "Add a symbolic tag to a module", }, { - "server", {}, cvs_server, + CVS_OP_SERVER, "server", {}, cvs_server, "", "Server mode", }, { - "status", {}, NULL, + CVS_OP_STATUS, "status", {}, NULL, "", "Display status information on checked out files", }, { - "tag", { "ta", }, NULL, + CVS_OP_TAG, "tag", { "ta", }, NULL, "", "Add a symbolic tag to checked out version of files", }, { - "unedit", {}, NULL, + -1, "unedit", {}, NULL, "", "Undo an edit command", }, { - "update", {}, cvs_update, + CVS_OP_UPDATE, "update", {}, cvs_update, "", "Bring work tree in sync with repository", }, { - "version", {}, cvs_version, + CVS_OP_VERSION, "version", {}, cvs_version, "", "Show current CVS version(s)", }, { - "watch", {}, NULL, + -1, "watch", {}, NULL, "", "Set watches", }, { - "watchers", {}, NULL, + -1, "watchers", {}, NULL, "", "See who is watching a file", }, @@ -394,6 +396,8 @@ main(int argc, char **argv) exit(1); } + cvs_cmdop = cmdp->cmd_op; + ret = (*cmdp->cmd_hdlr)(argc, argv); if (ret == EX_USAGE) { fprintf(stderr, "Usage: %s %s %s\n", __progname, cvs_command, diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h index 205672ddbf6..0b36051b374 100644 --- a/usr.bin/cvs/cvs.h +++ b/usr.bin/cvs/cvs.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cvs.h,v 1.15 2004/07/29 18:22:28 jfb Exp $ */ +/* $OpenBSD: cvs.h,v 1.16 2004/07/30 01:49:22 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -40,10 +40,6 @@ #define CVS_HIST_NBFLD 6 -#define CVS_REQ_TIMEOUT 300 - - - #define CVS_CKSUM_LEN 33 /* length of a CVS checksum string */ @@ -51,10 +47,19 @@ #define CVS_OP_ANY 0 /* all operations */ #define CVS_OP_ADD 1 #define CVS_OP_ANNOTATE 2 -#define CVS_OP_COMMIT 3 -#define CVS_OP_DIFF 4 -#define CVS_OP_TAG 5 -#define CVS_OP_UPDATE 6 +#define CVS_OP_CHECKOUT 3 +#define CVS_OP_COMMIT 4 +#define CVS_OP_DIFF 5 +#define CVS_OP_HISTORY 6 +#define CVS_OP_IMPORT 7 +#define CVS_OP_INIT 8 +#define CVS_OP_LOG 9 +#define CVS_OP_REMOVE 10 +#define CVS_OP_SERVER 11 +#define CVS_OP_STATUS 12 +#define CVS_OP_TAG 13 +#define CVS_OP_UPDATE 14 +#define CVS_OP_VERSION 15 @@ -69,117 +74,6 @@ #define CVS_METHOD_EXT 6 #define CVS_METHOD_FORK 7 /* local but fork */ -/* client/server protocol requests */ -#define CVS_REQ_NONE 0 -#define CVS_REQ_ROOT 1 -#define CVS_REQ_VALIDREQ 2 -#define CVS_REQ_VALIDRESP 3 -#define CVS_REQ_DIRECTORY 4 -#define CVS_REQ_MAXDOTDOT 5 -#define CVS_REQ_STATICDIR 6 -#define CVS_REQ_STICKY 7 -#define CVS_REQ_ENTRY 8 -#define CVS_REQ_ENTRYEXTRA 9 -#define CVS_REQ_CHECKINTIME 10 -#define CVS_REQ_MODIFIED 11 -#define CVS_REQ_ISMODIFIED 12 -#define CVS_REQ_UNCHANGED 13 -#define CVS_REQ_USEUNCHANGED 14 -#define CVS_REQ_NOTIFY 15 -#define CVS_REQ_NOTIFYUSER 16 -#define CVS_REQ_QUESTIONABLE 17 -#define CVS_REQ_CASE 18 -#define CVS_REQ_UTF8 19 -#define CVS_REQ_ARGUMENT 20 -#define CVS_REQ_ARGUMENTX 21 -#define CVS_REQ_GLOBALOPT 22 -#define CVS_REQ_GZIPSTREAM 23 -#define CVS_REQ_KERBENCRYPT 24 -#define CVS_REQ_GSSENCRYPT 25 -#define CVS_REQ_PROTOENCRYPT 26 -#define CVS_REQ_GSSAUTH 27 -#define CVS_REQ_PROTOAUTH 28 -#define CVS_REQ_READCVSRC2 29 -#define CVS_REQ_READWRAP 30 -#define CVS_REQ_ERRIFREADER 31 -#define CVS_REQ_VALIDRCSOPT 32 -#define CVS_REQ_READIGNORE 33 -#define CVS_REQ_SET 34 -#define CVS_REQ_XPANDMOD 35 -#define CVS_REQ_CI 36 -#define CVS_REQ_CHOWN 37 -#define CVS_REQ_SETOWN 38 -#define CVS_REQ_SETPERM 39 -#define CVS_REQ_CHACL 40 -#define CVS_REQ_LISTPERM 41 -#define CVS_REQ_LISTACL 42 -#define CVS_REQ_SETPASS 43 -#define CVS_REQ_PASSWD 44 -#define CVS_REQ_DIFF 45 -#define CVS_REQ_STATUS 46 -#define CVS_REQ_LS 47 -#define CVS_REQ_TAG 48 -#define CVS_REQ_IMPORT 49 -#define CVS_REQ_ADMIN 50 -#define CVS_REQ_HISTORY 51 -#define CVS_REQ_WATCHERS 52 -#define CVS_REQ_EDITORS 53 -#define CVS_REQ_ANNOTATE 54 -#define CVS_REQ_LOG 55 -#define CVS_REQ_CO 56 -#define CVS_REQ_EXPORT 57 -#define CVS_REQ_RANNOTATE 58 -#define CVS_REQ_INIT 59 -#define CVS_REQ_UPDATE 60 -#define CVS_REQ_ADD 62 -#define CVS_REQ_REMOVE 63 -#define CVS_REQ_NOOP 64 -#define CVS_REQ_RTAG 65 -#define CVS_REQ_RELEASE 66 -#define CVS_REQ_RLOG 67 -#define CVS_REQ_RDIFF 68 -#define CVS_REQ_VERSION 69 - -#define CVS_REQ_MAX 69 - - -/* responses */ -#define CVS_RESP_OK 1 -#define CVS_RESP_ERROR 2 -#define CVS_RESP_VALIDREQ 3 -#define CVS_RESP_CHECKEDIN 4 -#define CVS_RESP_NEWENTRY 5 -#define CVS_RESP_CKSUM 6 -#define CVS_RESP_COPYFILE 7 -#define CVS_RESP_UPDATED 8 -#define CVS_RESP_CREATED 9 -#define CVS_RESP_UPDEXIST 10 -#define CVS_RESP_MERGED 11 -#define CVS_RESP_PATCHED 12 -#define CVS_RESP_RCSDIFF 13 -#define CVS_RESP_MODE 14 -#define CVS_RESP_MODTIME 15 -#define CVS_RESP_REMOVED 16 -#define CVS_RESP_RMENTRY 17 -#define CVS_RESP_SETSTATDIR 18 -#define CVS_RESP_CLRSTATDIR 19 -#define CVS_RESP_SETSTICKY 20 -#define CVS_RESP_CLRSTICKY 21 -#define CVS_RESP_TEMPLATE 22 -#define CVS_RESP_SETCIPROG 23 -#define CVS_RESP_SETUPDPROG 24 -#define CVS_RESP_NOTIFIED 25 -#define CVS_RESP_MODXPAND 26 -#define CVS_RESP_WRAPRCSOPT 27 -#define CVS_RESP_M 28 -#define CVS_RESP_MBINARY 29 -#define CVS_RESP_E 30 -#define CVS_RESP_F 31 -#define CVS_RESP_MT 32 - - - - #define CVS_CMD_MAXNAMELEN 16 #define CVS_CMD_MAXALIAS 2 #define CVS_CMD_MAXDESCRLEN 64 @@ -384,22 +278,6 @@ int cvs_update (int, char **); int cvs_version (int, char **); -/* proto.c */ -int cvs_req_handle (char *); -const char* cvs_req_getbyid (int); -int cvs_req_getbyname (const char *); -char* cvs_req_getvalid (void); - - -int cvs_resp_handle (char *); -const char* cvs_resp_getbyid (int); -int cvs_resp_getbyname (const char *); -char* cvs_resp_getvalid (void); - -int cvs_sendfile (const char *); -int cvs_recvfile (const char *); - - /* from client.c */ int cvs_client_connect (struct cvsroot *); void cvs_client_disconnect (struct cvsroot *); diff --git a/usr.bin/cvs/cvs/Makefile b/usr.bin/cvs/cvs/Makefile index 714676bfceb..1b546691e88 100644 --- a/usr.bin/cvs/cvs/Makefile +++ b/usr.bin/cvs/cvs/Makefile @@ -1,11 +1,11 @@ -# $Id: Makefile,v 1.4 2004/07/29 15:33:02 jfb Exp $ +# $Id: Makefile,v 1.5 2004/07/30 01:49:26 jfb Exp $ .PATH: ${.CURDIR}/.. PROG=cvs MAN=cvs.1 cvsrc.5 -SRCS= cvs.c add.c buf.c client.c checkout.c commit.c diff.c entries.c file.c \ +SRCS= cvs.c add.c buf.c checkout.c commit.c diff.c entries.c file.c \ getlog.c history.c hist.c init.c lock.c log.c proto.c rcs.c rcsnum.c \ root.c server.c sock.c update.c util.c version.c @@ -14,7 +14,7 @@ BINOWN=root BINGRP=_cvsd BINMODE=2555 -CFLAGS+= -Wall +CFLAGS+= -DDEBUG -Wall CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes CFLAGS+= -Wsign-compare CFLAGS+= -DCVS diff --git a/usr.bin/cvs/diff.c b/usr.bin/cvs/diff.c index e56f0eab74d..a68c2d222be 100644 --- a/usr.bin/cvs/diff.c +++ b/usr.bin/cvs/diff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: diff.c,v 1.3 2004/07/14 04:32:42 jfb Exp $ */ +/* $OpenBSD: diff.c,v 1.4 2004/07/30 01:49:23 jfb Exp $ */ /* * Copyright (C) Caldera International Inc. 2001-2002. * All rights reserved. @@ -146,6 +146,7 @@ #include "cvs.h" #include "log.h" #include "buf.h" +#include "proto.h" #define CVS_DIFF_DEFCTX 3 /* default context length */ @@ -197,6 +198,13 @@ struct context_vec { int d; /* end line in new file */ }; +struct diff_arg { + char *rev1; + char *rev2; + char *date1; + char *date2; +}; + struct excludes { char *pattern; @@ -206,8 +214,7 @@ struct excludes { char *splice(char *, char *); int cvs_diffreg(const char *, const char *); -int cvs_diff_file (const char *, const char *, const char *); -int cvs_diff_dir (const char *, int); +int cvs_diff_file (struct cvs_file *, void *); static void output(const char *, FILE *, const char *, FILE *); static void check(FILE *, FILE *); static void range(int, int, char *); @@ -231,17 +238,11 @@ static int isqrt(int); static int stone(int *, int, int *, int *); static int readhash(FILE *); static int files_differ(FILE *, FILE *); -static __inline int min(int, int); -static __inline int max(int, int); -static char *match_function(const long *, int, FILE *); static char *preadline(int, size_t, off_t); extern int cvs_client; -extern struct cvsroot *cvs_root; - - static int aflag, bflag, dflag, iflag, tflag, Tflag, wflag; static int context, status; @@ -272,7 +273,6 @@ static struct context_vec *context_vec_end; static struct context_vec *context_vec_ptr; #define FUNCTION_CONTEXT_SIZE 41 -static char lastbuf[FUNCTION_CONTEXT_SIZE]; static int lastline; static int lastmatchline; @@ -350,17 +350,18 @@ u_char cup2low[256] = { int cvs_diff(int argc, char **argv) { - int i, ch, recurse; - size_t dalen; - char dir[MAXPATHLEN], file[MAXPATHLEN], *d1, *d2, *r1, *r2; + int ch, recurse, flags; + struct cvs_file *files; + struct diff_arg darg; + struct cvsroot *root; context = CVS_DIFF_DEFCTX; - strlcpy(diffargs, argv[0], sizeof(diffargs)); - - d1 = d2 = NULL; - r1 = r2 = NULL; + flags = CF_RECURSE|CF_IGNORE|CF_SORT|CF_KNOWN; recurse = 1; + memset(&darg, 0, sizeof(darg)); + strlcpy(diffargs, argv[0], sizeof(diffargs)); + while ((ch = getopt(argc, argv, "cD:lir:u")) != -1) { switch (ch) { case 'c': @@ -368,10 +369,10 @@ cvs_diff(int argc, char **argv) format = D_CONTEXT; break; case 'D': - if (d1 == NULL && r1 == NULL) - d1 = optarg; - else if (d2 == NULL && r2 == NULL) - d2 = optarg; + if (darg.date1 == NULL && darg.rev1 == NULL) + darg.date1 = optarg; + else if (darg.date2 == NULL && darg.rev2 == NULL) + darg.date2 = optarg; else { cvs_log(LP_ERR, "no more than two revisions/dates can " @@ -381,16 +382,17 @@ cvs_diff(int argc, char **argv) case 'l': strlcat(diffargs, " -l", sizeof(diffargs)); recurse = 0; + flags &= ~CF_RECURSE; break; case 'i': strlcat(diffargs, " -i", sizeof(diffargs)); iflag = 1; break; case 'r': - if ((r1 == NULL) && (d1 == NULL)) - r1 = optarg; - else if ((r2 == NULL) && (d2 == NULL)) - r2 = optarg; + if ((darg.rev1 == NULL) && (darg.date1 == NULL)) + darg.rev1 = optarg; + else if ((darg.rev2 == NULL) && (darg.date2 == NULL)) + darg.rev2 = optarg; else { cvs_log(LP_ERR, "no more than two revisions/dates can " @@ -411,68 +413,51 @@ cvs_diff(int argc, char **argv) argv += optind; if (argc == 0) { - /* get the CVSROOT from current dir */ - strlcpy(dir, ".", sizeof(dir)); - - cvs_root = cvsroot_get(dir); - if (cvs_root == NULL) - return (EX_USAGE); - - if (cvs_root->cr_method != CVS_METHOD_LOCAL) { - cvs_client_connect(); + files = cvs_file_get(".", flags); + } + else + files = cvs_file_getspec(argv, argc, 0); - /* send the flags */ - if (format == D_CONTEXT) - cvs_client_sendarg("-c", 0); - else if (format == D_UNIFIED) - cvs_client_sendarg("-u", 0); + cvs_file_examine(files, cvs_diff_file, &darg); - if (r1 != NULL) { - cvs_client_sendarg("-r", 0); - cvs_client_sendarg(r1, 1); - } - else if (d1 != NULL) { - cvs_client_sendarg("-D", 0); - cvs_client_sendarg(d1, 1); - } - if (r2 != NULL) { - cvs_client_sendarg("-r", 0); - cvs_client_sendarg(r2, 1); - } - else if (d2 != NULL) { - cvs_client_sendarg("-D", 0); - cvs_client_sendarg(d2, 1); - } - } + root = files->cf_ddat->cd_root; + if (root->cr_method != CVS_METHOD_LOCAL) + cvs_sendreq(root, CVS_REQ_DIFF, NULL); - cvs_diff_dir(dir, recurse); - } - else { - for (i = 0; i < argc; i++) { - cvs_splitpath(argv[i], dir, sizeof(dir), - file, sizeof(file)); - cvs_root = cvsroot_get(dir); - if (cvs_root == NULL) - return (EX_USAGE); + return (0); +} - if (cvs_root->cr_method != CVS_METHOD_LOCAL) { - cvs_client_connect(); - if (i == 0) { - /* send the flags */ - if (format == D_CONTEXT) - cvs_client_sendarg("-c", 0); - else if (format == D_UNIFIED) - cvs_client_sendarg("-u", 0); - } - } +/* + * cvs_diff_sendflags() + * + */ - cvs_diff_file(argv[i], r1, r2); - } +int +cvs_diff_sendflags(struct cvsroot *root, struct diff_arg *dap) +{ + /* send the flags */ + if (format == D_CONTEXT) + cvs_sendarg(root, "-c", 0); + else if (format == D_UNIFIED) + cvs_sendarg(root, "-u", 0); + + if (dap->rev1 != NULL) { + cvs_sendarg(root, "-r", 0); + cvs_sendarg(root, dap->rev1, 1); + } + else if (dap->date1 != NULL) { + cvs_sendarg(root, "-D", 0); + cvs_sendarg(root, dap->date1, 1); + } + if (dap->rev2 != NULL) { + cvs_sendarg(root, "-r", 0); + cvs_sendarg(root, dap->rev2, 1); + } + else if (dap->date2 != NULL) { + cvs_sendarg(root, "-D", 0); + cvs_sendarg(root, dap->date2, 1); } - - if (cvs_root->cr_method != CVS_METHOD_LOCAL) - cvs_client_sendreq(CVS_REQ_DIFF, NULL, 1); return (0); } @@ -485,186 +470,127 @@ cvs_diff(int argc, char **argv) */ int -cvs_diff_file(const char *path, const char *rev1, const char *rev2) +cvs_diff_file(struct cvs_file *cfp, void *arg) { - int modif; - char dir[MAXPATHLEN], file[MAXPATHLEN], rcspath[MAXPATHLEN]; - char repo[MAXPATHLEN], buf[64]; - time_t tsec; + char *dir, *repo, rcspath[MAXPATHLEN], buf[64]; BUF *b1, *b2; RCSNUM *r1, *r2; RCSFILE *rf; - CVSENTRIES *entf; - struct tm tmstamp; - struct stat fst; + struct diff_arg *dap; struct cvs_ent *entp; + struct cvsroot *root; - rf = NULL; - diff_file = path; + dap = (struct diff_arg *)arg; - if (stat(path, &fst) == -1) { - cvs_log(LP_ERRNO, "cannot find %s", path); - return (-1); - } + cvs_log(LP_DEBUG, "%s: diffing %s", __func__, cfp->cf_path); - cvs_splitpath(path, dir, sizeof(dir), file, sizeof(file)); - cvs_readrepo(dir, repo, sizeof(repo)); + if (cfp->cf_type == DT_DIR) { + root = cfp->cf_ddat->cd_root; + if ((cfp->cf_parent == NULL) || + (root != cfp->cf_parent->cf_ddat->cd_root)) { + cvs_connect(root); + cvs_diff_sendflags(root, dap); + } - entf = cvs_ent_open(dir, O_RDONLY); - if (entf == NULL) { - cvs_log(LP_ERR, "no CVS/Entries file in `%s'", dir); - return (-1); + cvs_senddir(root, cfp); + return (0); } + else /* take the root of parent directory */ + root = cfp->cf_parent->cf_ddat->cd_root; - entp = cvs_ent_get(entf, file); - if ((entp == NULL) && (cvs_root->cr_method == CVS_METHOD_LOCAL)) { - cvs_log(LP_WARN, "I know nothing about %s", path); - return (-1); + rf = NULL; + diff_file = cfp->cf_path; + if (cfp->cf_parent != NULL) { + dir = cfp->cf_parent->cf_path; + repo = cfp->cf_parent->cf_ddat->cd_repo; } - - if (cvs_root->cr_method != CVS_METHOD_LOCAL) { - if (cvs_client_senddir(dir) < 0) - return (-1); + else { + dir = "."; + repo = NULL; } - tsec = (time_t)fst.st_mtimespec.tv_sec; + if (cfp->cf_cvstat == CVS_FST_UNKNOWN) { + 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); + return (0); + } - if ((gmtime_r(&tsec, &tmstamp) == NULL) || - (asctime_r(&tmstamp, buf) == NULL)) { - cvs_log(LP_ERR, "failed to generate file timestamp"); + entp = cvs_ent_getent(diff_file); + if (entp == NULL) return (-1); - } - modif = (strcmp(buf, entp->ce_timestamp) == 0) ? 0 : 1; - if (cvs_root->cr_method != CVS_METHOD_LOCAL) - cvs_client_sendentry(entp); + if (root->cr_method != CVS_METHOD_LOCAL) { + if (cvs_sendentry(root, entp) < 0) { + cvs_ent_free(entp); + return (-1); + } + } - if (!modif) { - if (cvs_root->cr_method != CVS_METHOD_LOCAL) - cvs_client_sendreq(CVS_REQ_UNCHANGED, file, 0); - cvs_ent_close(entf); + if (cfp->cf_cvstat == CVS_FST_UPTODATE) { + if (root->cr_method != CVS_METHOD_LOCAL) + cvs_sendreq(root, CVS_REQ_UNCHANGED, cfp->cf_name); + cvs_ent_free(entp); return (0); } /* at this point, the file is modified */ - if (cvs_root->cr_method != CVS_METHOD_LOCAL) { - cvs_client_sendreq(CVS_REQ_MODIFIED, file, 0); - cvs_sendfile(path); + if (root->cr_method != CVS_METHOD_LOCAL) { + cvs_sendreq(root, CVS_REQ_MODIFIED, cfp->cf_name); + cvs_sendfile(root, diff_file); } else { snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s", - cvs_root->cr_dir, repo, path, RCS_FILE_EXT); + root->cr_dir, repo, diff_file, RCS_FILE_EXT); rf = rcs_open(rcspath, RCS_MODE_READ); - if (rf == NULL) + if (rf == NULL) { + cvs_ent_free(entp); return (-1); + } - printf("Index: %s\n%s\nRCS file: %s\n", path, + cvs_printf("Index: %s\n%s\nRCS file: %s\n", diff_file, RCS_DIFF_DIV, rcspath); - if (rev1 == NULL) + if (dap->rev1 == NULL) r1 = entp->ce_rev; else { r1 = rcsnum_alloc(); - rcsnum_aton(rev1, NULL, r1); + rcsnum_aton(dap->rev1, NULL, r1); } - printf("retrieving revision %s\n", + cvs_printf("retrieving revision %s\n", rcsnum_tostr(r1, buf, sizeof(buf))); b1 = rcs_getrev(rf, r1); - if (rev2 != NULL) { - printf("retrieving revision %s\n", rev2); + if (dap->rev2 != NULL) { + cvs_printf("retrieving revision %s\n", dap->rev2); r2 = rcsnum_alloc(); - rcsnum_aton(rev2, NULL, r2); + rcsnum_aton(dap->rev2, NULL, r2); b2 = rcs_getrev(rf, r2); } else { - b2 = cvs_buf_load(path, BUF_AUTOEXT); + b2 = cvs_buf_load(diff_file, BUF_AUTOEXT); } + rcs_close(rf); + printf("%s", diffargs); printf(" -r%s", buf); - if (rev2 != NULL) - printf(" -r%s", rev2); - printf(" %s\n", path); + if (dap->rev2 != NULL) + printf(" -r%s", dap->rev2); + printf(" %s\n", diff_file); cvs_buf_write(b1, "/tmp/diff1", 0600); cvs_buf_write(b2, "/tmp/diff2", 0600); cvs_diffreg("/tmp/diff1", "/tmp/diff2"); } - cvs_ent_close(entf); - + cvs_ent_free(entp); return (0); } -/* - * cvs_diff_dir() - * - */ - -int -cvs_diff_dir(const char *dir, int recurse) -{ - char path[MAXPATHLEN]; - DIR *dirp; - CVSENTRIES *entf; - struct dirent *dentp; - struct cvs_ent *entp; - - printf("cvs_diff_dir(%s)\n", dir); - - dirp = opendir(dir); - if (dirp == NULL) { - cvs_log(LP_ERRNO, "failed to open directory `%s'", dir); - return (-1); - } - - entf = cvs_ent_open(dir, O_RDONLY); - if (entf == NULL) { - cvs_log(LP_ERR, "no CVS/Entries file in `%s'", dir); - (void)closedir(dirp); - return (-1); - } - - while ((dentp = readdir(dirp)) != NULL) { - if ((strcmp(dentp->d_name, "CVS") == 0) || - (dentp->d_name[0] == '.')) - continue; - - if (strcmp(dir, ".") != 0) { - strlcpy(path, dir, sizeof(path)); - strlcat(path, "/", sizeof(path)); - } - else - path[0] = '\0'; - strlcat(path, dentp->d_name, sizeof(path)); - if (dentp->d_type == DT_DIR) { - if (!recurse) - continue; - cvs_diff_dir(path, recurse); - } - else { - entp = cvs_ent_get(entf, dentp->d_name); - if (entp == NULL) { - cvs_client_sendreq(CVS_REQ_QUESTIONABLE, path, - 0); - } - else { -#if 0 - cvs_diff_file(path); -#endif - } - } - } - - return (0); -} - - - - int cvs_diffreg(const char *file1, const char *file2) { @@ -896,7 +822,7 @@ stone(int *a, int n, int *b, int *c) int oldc, tc, oldl; u_int numtries; - const u_int bound = dflag ? UINT_MAX : max(256, isqrt(n)); + const u_int bound = dflag ? UINT_MAX : MAX(256, isqrt(n)); k = 0; c[0] = newcand(0, 0, 0); @@ -1480,46 +1406,6 @@ asciifile(FILE *f) return (1); } -static __inline int min(int a, int b) -{ - return (a < b ? a : b); -} - -static __inline int max(int a, int b) -{ - return (a > b ? a : b); -} - -static char * -match_function(const long *f, int pos, FILE *file) -{ - char buf[FUNCTION_CONTEXT_SIZE]; - size_t nc; - int last = lastline; - char *p; - - lastline = pos; - while (pos > last) { - fseek(file, f[pos - 1], SEEK_SET); - nc = f[pos] - f[pos - 1]; - if (nc >= sizeof(buf)) - nc = sizeof(buf) - 1; - nc = fread(buf, 1, nc, file); - if (nc > 0) { - buf[nc] = '\0'; - p = strchr(buf, '\n'); - if (p != NULL) - *p = '\0'; - if (isalpha(buf[0]) || buf[0] == '_' || buf[0] == '$') { - strlcpy(lastbuf, buf, sizeof lastbuf); - lastmatchline = pos; - return lastbuf; - } - } - pos--; - } - return lastmatchline > 0 ? lastbuf : NULL; -} /* dump accumulated "context" diff changes */ static void @@ -1528,16 +1414,16 @@ dump_context_vec(FILE *f1, FILE *f2) struct context_vec *cvp = context_vec_start; int lowa, upb, lowc, upd, do_output; int a, b, c, d; - char ch, *f; + char ch; if (context_vec_start > context_vec_ptr) return; b = d = 0; /* gcc */ - lowa = max(1, cvp->a - context); - upb = min(len[0], context_vec_ptr->b + context); - lowc = max(1, cvp->c - context); - upd = min(len[1], context_vec_ptr->d + context); + lowa = MAX(1, cvp->a - context); + upb = MIN(len[0], context_vec_ptr->b + context); + lowc = MAX(1, cvp->c - context); + upd = MIN(len[1], context_vec_ptr->d + context); printf("***************"); printf("\n*** "); @@ -1626,16 +1512,16 @@ dump_unified_vec(FILE *f1, FILE *f2) struct context_vec *cvp = context_vec_start; int lowa, upb, lowc, upd; int a, b, c, d; - char ch, *f; + char ch; if (context_vec_start > context_vec_ptr) return; b = d = 0; /* gcc */ - lowa = max(1, cvp->a - context); - upb = min(len[0], context_vec_ptr->b + context); - lowc = max(1, cvp->c - context); - upd = min(len[1], context_vec_ptr->d + context); + lowa = MAX(1, cvp->a - context); + upb = MIN(len[0], context_vec_ptr->b + context); + lowc = MAX(1, cvp->c - context); + upd = MIN(len[1], context_vec_ptr->d + context); fputs("@@ -", stdout); uni_range(lowa, upb); diff --git a/usr.bin/cvs/file.h b/usr.bin/cvs/file.h new file mode 100644 index 00000000000..aa587a1d06f --- /dev/null +++ b/usr.bin/cvs/file.h @@ -0,0 +1,206 @@ +/* $OpenBSD: file.h,v 1.1 2004/07/30 01:49:23 jfb Exp $ */ +/* + * Copyright (c) 2004 Jean-Francois Brousseau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FILE_H +#define FILE_H + +#include +#include +#include + +#include "rcs.h" + +#define CVS_VERSION "OpenCVS 0.1" + + +#define FILE_HIST_CACHE 128 +#define FILE_HIST_NBFLD 6 + + +#define CVS_CKSUM_LEN 33 /* length of a CVS checksum string */ + + +/* operations */ +#define CVS_OP_ANY 0 /* all operations */ +#define CVS_OP_ADD 1 +#define CVS_OP_ANNOTATE 2 +#define CVS_OP_CHECKOUT 3 +#define CVS_OP_COMMIT 4 +#define CVS_OP_DIFF 5 +#define CVS_OP_HISTORY 6 +#define CVS_OP_IMPORT 7 +#define CVS_OP_INIT 8 +#define CVS_OP_LOG 9 +#define CVS_OP_REMOVE 10 +#define CVS_OP_SERVER 11 +#define CVS_OP_STATUS 12 +#define CVS_OP_TAG 13 +#define CVS_OP_UPDATE 14 +#define CVS_OP_VERSION 15 + + + + +/* methods */ +#define CVS_METHOD_NONE 0 +#define CVS_METHOD_LOCAL 1 /* local access */ +#define CVS_METHOD_SERVER 2 /* tunnel through CVS_RSH */ +#define CVS_METHOD_PSERVER 3 /* cvs pserver */ +#define CVS_METHOD_KSERVER 4 /* kerberos */ +#define CVS_METHOD_GSERVER 5 /* gssapi server */ +#define CVS_METHOD_EXT 6 +#define CVS_METHOD_FORK 7 /* local but fork */ + +#define CVS_CMD_MAXNAMELEN 16 +#define CVS_CMD_MAXALIAS 2 +#define CVS_CMD_MAXDESCRLEN 64 + + +/* defaults */ +#define CVS_RSH_DEFAULT "ssh" +#define CVS_EDITOR_DEFAULT "vi" + + +/* server-side paths */ +#define CVS_PATH_ROOT "CVSROOT" +#define CVS_PATH_COMMITINFO CVS_PATH_ROOT "/commitinfo" +#define CVS_PATH_CONFIG CVS_PATH_ROOT "/config" +#define CVS_PATH_CVSIGNORE CVS_PATH_ROOT "/cvsignore" +#define CVS_PATH_CVSWRAPPERS CVS_PATH_ROOT "/cvswrappers" +#define CVS_PATH_EDITINFO CVS_PATH_ROOT "/editinfo" +#define CVS_PATH_HISTORY CVS_PATH_ROOT "/history" +#define CVS_PATH_LOGINFO CVS_PATH_ROOT "/loginfo" +#define CVS_PATH_MODULES CVS_PATH_ROOT "/modules" +#define CVS_PATH_NOTIFY CVS_PATH_ROOT "/notify" +#define CVS_PATH_RCSINFO CVS_PATH_ROOT "/rcsinfo" +#define CVS_PATH_TAGINFO CVS_PATH_ROOT "/taginfo" +#define CVS_PATH_VERIFYMSG CVS_PATH_ROOT "/verifymsg" + + +/* client-side paths */ +#define CVS_PATH_RC ".cvsrc" +#define CVS_PATH_CVSDIR "CVS" +#define CVS_PATH_ENTRIES CVS_PATH_CVSDIR "/Entries" +#define CVS_PATH_STATICENTRIES CVS_PATH_CVSDIR "/Entries.Static" +#define CVS_PATH_LOGENTRIES CVS_PATH_CVSDIR "/Entries.Log" +#define CVS_PATH_ROOTSPEC CVS_PATH_CVSDIR "/Root" +#define CVS_PATH_REPOSITORY CVS_PATH_CVSDIR "/Repository" + + +struct cvs_file; +struct cvs_dir; + + +struct cvs_op { + u_int co_op; + uid_t co_uid; /* user performing the operation */ + char *co_path; /* target path of the operation */ + char *co_tag; /* tag or branch, NULL if HEAD */ +}; + + + +struct cvsroot { + char *cr_str; + u_int cr_method; + char *cr_buf; + char *cr_user; + char *cr_pass; + char *cr_host; + char *cr_dir; + u_int cr_port; + u_int cr_ref; + + /* connection data */ + FILE *cr_srvin; + FILE *cr_srvout; +}; + + +#define CF_STAT 0x01 /* allocate space for file stats */ +#define CF_IGNORE 0x02 /* apply regular ignore rules */ +#define CF_RECURSE 0x04 /* recurse on directory operations */ +#define CF_SORT 0x08 /* all files are sorted alphabetically */ +#define CF_KNOWN 0x10 /* only recurse in directories known to CVS */ +#define CF_CREATE 0x20 /* create if file does not exist */ + + +/* + * The cvs_file structure is used to represent any file or directory within + * the CVS tree's hierarchy. The field is a path relative to the + * directory in which the cvs command was executed. The field + * points back to the parent node in the directory tree structure (it is + * NULL if the directory is at the wd of the command). + * + * The field gives the file's status with regards to the CVS + * repository. The file can be in any one of the CVS_FST_* states. + * If the file's type is DT_DIR, then the pointer will point to + * a cvs_dir structure containing data specific to the directory (such as + * the contents of the directory's CVS/Entries, CVS/Root, etc.). + */ + +#define CVS_FST_UNKNOWN 0 +#define CVS_FST_UPTODATE 1 +#define CVS_FST_MODIFIED 2 +#define CVS_FST_ADDED 3 +#define CVS_FST_REMOVED 4 +#define CVS_FST_CONFLICT 5 +#define CVS_FST_PATCHED 6 + + +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; + u_int16_t cf_cvstat; /* cvs status of the file */ + u_int16_t cf_type; /* uses values from dirent.h */ + struct stat *cf_stat; /* only available with CF_STAT flag */ + struct cvs_dir *cf_ddat; /* only for directories */ + + TAILQ_ENTRY(cvs_file) cf_list; +} CVSFILE; + + +struct cvs_dir { + struct cvsroot *cd_root; + char *cd_repo; + struct cvs_flist cd_files; +}; + +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); +void cvs_file_free (struct cvs_file *); +int cvs_file_examine (CVSFILE *, int (*)(CVSFILE *, void *), void *); + + +#endif /* FILE_H */ diff --git a/usr.bin/cvs/getlog.c b/usr.bin/cvs/getlog.c index bf11e55abcd..5e26d817fa1 100644 --- a/usr.bin/cvs/getlog.c +++ b/usr.bin/cvs/getlog.c @@ -1,4 +1,4 @@ -/* $OpenBSD: getlog.c,v 1.2 2004/07/29 18:23:26 jfb Exp $ */ +/* $OpenBSD: getlog.c,v 1.3 2004/07/30 01:49:23 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -38,6 +38,7 @@ #include "log.h" #include "rcs.h" #include "sock.h" +#include "proto.h" #define CVS_GLOG_RFONLY 0x01 diff --git a/usr.bin/cvs/history.c b/usr.bin/cvs/history.c index 24cf4379342..7fbb808b8f2 100644 --- a/usr.bin/cvs/history.c +++ b/usr.bin/cvs/history.c @@ -1,4 +1,4 @@ -/* $OpenBSD: history.c,v 1.2 2004/07/29 18:34:23 jfb Exp $ */ +/* $OpenBSD: history.c,v 1.3 2004/07/30 01:49:23 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -38,6 +38,7 @@ #include "cvs.h" #include "rcs.h" #include "log.h" +#include "proto.h" #define CVS_HISTORY_MAXMOD 16 @@ -162,25 +163,24 @@ cvs_history(int argc, char **argv) } else { if (flags & CVS_HF_C) - cvs_client_sendarg("-c", 0); + cvs_sendarg(root, "-c", 0); if (flags & CVS_HF_O) - cvs_client_sendarg("-o", 0); + cvs_sendarg(root, "-o", 0); if (tag != NULL) { - cvs_client_sendarg("-t", 0); - cvs_client_sendarg(tag, 0); + cvs_sendarg(root, "-t", 0); + cvs_sendarg(root, tag, 0); } if (user != NULL) { - cvs_client_sendarg("-u", 0); - cvs_client_sendarg(user, 0); + cvs_sendarg(root, "-u", 0); + cvs_sendarg(root, user, 0); } + cvs_sendarg(root, "-z", 0); + cvs_sendarg(root, zone, 0); - cvs_client_sendarg("-z", 0); - cvs_client_sendarg(zone, 0); - - cvs_client_sendreq(CVS_REQ_HISTORY, NULL, 1); + cvs_sendreq(root, CVS_REQ_HISTORY, NULL); } return (0); diff --git a/usr.bin/cvs/proto.c b/usr.bin/cvs/proto.c index dc8f3defbd5..2e306ea84eb 100644 --- a/usr.bin/cvs/proto.c +++ b/usr.bin/cvs/proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: proto.c,v 1.12 2004/07/29 19:03:33 jfb Exp $ */ +/* $OpenBSD: proto.c,v 1.13 2004/07/30 01:49:24 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -58,6 +58,7 @@ #include "buf.h" #include "cvs.h" #include "log.h" +#include "proto.h" #define CVS_MTSTK_MAXDEPTH 16 @@ -77,20 +78,21 @@ extern int cvs_readonly; -static int cvs_resp_validreq (int, char *); -static int cvs_resp_cksum (int, char *); -static int cvs_resp_modtime (int, char *); -static int cvs_resp_m (int, char *); -static int cvs_resp_ok (int, char *); -static int cvs_resp_error (int, char *); -static int cvs_resp_statdir (int, char *); -static int cvs_resp_sticky (int, char *); -static int cvs_resp_newentry (int, char *); -static int cvs_resp_updated (int, char *); -static int cvs_resp_removed (int, char *); -static int cvs_resp_mode (int, char *); -static int cvs_resp_modxpand (int, char *); +static int cvs_resp_validreq (struct cvsroot *, int, char *); +static int cvs_resp_cksum (struct cvsroot *, int, char *); +static int cvs_resp_modtime (struct cvsroot *, int, char *); +static int cvs_resp_m (struct cvsroot *, int, char *); +static int cvs_resp_ok (struct cvsroot *, int, char *); +static int cvs_resp_error (struct cvsroot *, int, char *); +static int cvs_resp_statdir (struct cvsroot *, int, char *); +static int cvs_resp_sticky (struct cvsroot *, int, char *); +static int cvs_resp_newentry (struct cvsroot *, int, char *); +static int cvs_resp_updated (struct cvsroot *, int, char *); +static int cvs_resp_removed (struct cvsroot *, int, char *); +static int cvs_resp_mode (struct cvsroot *, int, char *); +static int cvs_resp_modxpand (struct cvsroot *, int, char *); +static int cvs_initlog (void); static const char *cvs_months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", @@ -103,7 +105,7 @@ struct cvs_req { int req_id; char req_str[32]; u_int req_flags; - int (*req_hdlr)(int, char *); + int (*req_hdlr)(int, char *); } cvs_requests[] = { { CVS_REQ_DIRECTORY, "Directory", 0, NULL }, { CVS_REQ_MAXDOTDOT, "Max-dotdot", 0, NULL }, @@ -148,7 +150,7 @@ struct cvs_req { { CVS_REQ_REMOVE, "remove", CVS_REQF_RESP, NULL }, { CVS_REQ_RELEASE, "release", CVS_REQF_RESP, NULL }, { CVS_REQ_ROOT, "Root", 0, NULL }, - { CVS_REQ_VALIDRESP, "Valid-responses", CVS_REQF_RESP, NULL }, + { CVS_REQ_VALIDRESP, "Valid-responses", 0, NULL }, { CVS_REQ_VALIDREQ, "valid-requests", CVS_REQF_RESP, NULL }, { CVS_REQ_VERSION, "version", CVS_REQF_RESP, NULL }, { CVS_REQ_NOOP, "noop", CVS_REQF_RESP, NULL }, @@ -159,7 +161,7 @@ struct cvs_req { struct cvs_resp { u_int resp_id; char resp_str[32]; - int (*resp_hdlr)(int, char *); + int (*resp_hdlr)(struct cvsroot *, int, char *); } cvs_responses[] = { { CVS_RESP_OK, "ok", cvs_resp_ok }, { CVS_RESP_ERROR, "error", cvs_resp_error }, @@ -209,20 +211,192 @@ char *cvs_fcksum = NULL; mode_t cvs_lastmode = 0; +static char cvs_proto_buf[4096]; + +/* + * Output files for protocol logging when the CVS_CLIENT_LOG enviroment + * variable is set. + */ +static int cvs_server_logon = 0; +static FILE *cvs_server_inlog = NULL; +static FILE *cvs_server_outlog = NULL; + + +/* + * cvs_connect() + * + * Open a client connection to the cvs server whose address is given in + * the variable. The method used to connect depends on the + * setting of the CVS_RSH variable. + * Returns 0 on success, or -1 on failure. + */ + +int +cvs_connect(struct cvsroot *root) +{ + int argc, infd[2], outfd[2]; + pid_t pid; + char *argv[16], *cvs_server_cmd, *vresp; + + if (pipe(infd) == -1) { + cvs_log(LP_ERRNO, + "failed to create input pipe for client connection"); + return (-1); + } + + if (pipe(outfd) == -1) { + cvs_log(LP_ERRNO, + "failed to create output pipe for client connection"); + (void)close(infd[0]); + (void)close(infd[1]); + return (-1); + } + + pid = fork(); + if (pid == -1) { + cvs_log(LP_ERRNO, "failed to fork for cvs server connection"); + return (-1); + } + if (pid == 0) { + if ((dup2(infd[0], STDIN_FILENO) == -1) || + (dup2(outfd[1], STDOUT_FILENO) == -1)) { + cvs_log(LP_ERRNO, + "failed to setup standard streams for cvs server"); + return (-1); + } + (void)close(infd[1]); + (void)close(outfd[0]); + + argc = 0; + argv[argc++] = cvs_rsh; + + if (root->cr_user != NULL) { + argv[argc++] = "-l"; + argv[argc++] = root->cr_user; + } + + + cvs_server_cmd = getenv("CVS_SERVER"); + if (cvs_server_cmd == NULL) + cvs_server_cmd = "cvs"; + + argv[argc++] = root->cr_host; + argv[argc++] = cvs_server_cmd; + argv[argc++] = "server"; + argv[argc] = NULL; + + execvp(argv[0], argv); + cvs_log(LP_ERRNO, "failed to exec"); + exit(EX_OSERR); + } + + /* we are the parent */ + (void)close(infd[0]); + (void)close(outfd[1]); + + root->cr_srvin = fdopen(infd[1], "w"); + if (root->cr_srvin == NULL) { + cvs_log(LP_ERRNO, "failed to create pipe stream"); + return (-1); + } + + root->cr_srvout = fdopen(outfd[0], "r"); + if (root->cr_srvout == NULL) { + cvs_log(LP_ERRNO, "failed to create pipe stream"); + return (-1); + } + + /* make the streams line-buffered */ + (void)setvbuf(root->cr_srvin, NULL, _IOLBF, 0); + (void)setvbuf(root->cr_srvout, NULL, _IOLBF, 0); + + cvs_initlog(); + + /* + * Send the server the list of valid responses, then ask for valid + * requests. + */ + + vresp = cvs_resp_getvalid(); + if (vresp == NULL) { + cvs_log(LP_ERR, "can't generate list of valid responses"); + return (-1); + } + + if (cvs_sendreq(root, CVS_REQ_VALIDRESP, vresp) < 0) { + } + free(vresp); + + if (cvs_sendreq(root, CVS_REQ_VALIDREQ, NULL) < 0) { + cvs_log(LP_ERR, "failed to get valid requests from server"); + return (-1); + } + + /* now share our global options with the server */ + if (verbosity == 1) + cvs_sendreq(root, CVS_REQ_GLOBALOPT, "-q"); + else if (verbosity == 0) + cvs_sendreq(root, CVS_REQ_GLOBALOPT, "-Q"); + + if (cvs_nolog) + cvs_sendreq(root, CVS_REQ_GLOBALOPT, "-l"); + if (cvs_readonly) + cvs_sendreq(root, CVS_REQ_GLOBALOPT, "-r"); + if (cvs_trace) + cvs_sendreq(root, CVS_REQ_GLOBALOPT, "-t"); + + /* now send the CVSROOT to the server */ + if (cvs_sendreq(root, CVS_REQ_ROOT, root->cr_dir) < 0) + return (-1); + + /* not sure why, but we have to send this */ + if (cvs_sendreq(root, CVS_REQ_USEUNCHANGED, NULL) < 0) + return (-1); + +#ifdef CVS_ZLIB + /* if compression was requested, initialize it */ +#endif + + cvs_log(LP_DEBUG, "connected to %s", root->cr_host); + + return (0); +} + + +/* + * cvs_disconnect() + * + * Disconnect from the cvs server. + */ + +void +cvs_disconnect(struct cvsroot *root) +{ + cvs_log(LP_DEBUG, "closing connection to %s", root->cr_host); + if (root->cr_srvin != NULL) { + (void)fclose(root->cr_srvin); + root->cr_srvin = NULL; + } + if (root->cr_srvout != NULL) { + (void)fclose(root->cr_srvout); + root->cr_srvout = NULL; + } +} + /* * cvs_req_getbyid() * */ -const char* +struct cvs_req* cvs_req_getbyid(int reqid) { u_int i; for (i = 0; i < CVS_NBREQ; i++) if (cvs_requests[i].req_id == reqid) - return (cvs_requests[i].req_str); + return &(cvs_requests[i]); return (NULL); } @@ -231,16 +405,16 @@ cvs_req_getbyid(int reqid) * cvs_req_getbyname() */ -int +struct cvs_req* cvs_req_getbyname(const char *rname) { u_int i; for (i = 0; i < CVS_NBREQ; i++) if (strcmp(cvs_requests[i].req_str, rname) == 0) - return (cvs_requests[i].req_id); + return &(cvs_requests[i]); - return (-1); + return (NULL); } @@ -310,14 +484,14 @@ cvs_req_handle(char *line) * */ -const char* +struct cvs_resp* cvs_resp_getbyid(int respid) { u_int i; for (i = 0; i < CVS_NBREQ; i++) - if (cvs_responses[i].resp_id == respid) - return (cvs_responses[i].resp_str); + if (cvs_responses[i].resp_id == (u_int)respid) + return &(cvs_responses[i]); return (NULL); } @@ -326,16 +500,16 @@ cvs_resp_getbyid(int respid) * cvs_resp_getbyname() */ -int +struct cvs_resp* cvs_resp_getbyname(const char *rname) { u_int i; for (i = 0; i < CVS_NBREQ; i++) if (strcmp(cvs_responses[i].resp_str, rname) == 0) - return (cvs_responses[i].resp_id); + return &(cvs_responses[i]); - return (-1); + return (NULL); } @@ -395,10 +569,9 @@ cvs_resp_getvalid(void) */ int -cvs_resp_handle(char *line) +cvs_resp_handle(struct cvsroot *root, char *line) { u_int i; - size_t len; char *cp, *cmd; cmd = line; @@ -410,7 +583,7 @@ cvs_resp_handle(char *line) for (i = 0; i < CVS_NBRESP; i++) { if (strcmp(cvs_responses[i].resp_str, cmd) == 0) return (*cvs_responses[i].resp_hdlr) - (cvs_responses[i].resp_id, cp); + (root, cvs_responses[i].resp_id, cp); } /* unhandled */ @@ -428,10 +601,10 @@ cvs_resp_handle(char *line) */ static int -cvs_resp_validreq(int type, char *line) +cvs_resp_validreq(struct cvsroot *root, int type, char *line) { - int i; char *sp, *ep; + struct cvs_req *req; /* parse the requests */ sp = line; @@ -440,9 +613,9 @@ cvs_resp_validreq(int type, char *line) if (ep != NULL) *ep = '\0'; - i = cvs_req_getbyname(sp); - if (i != -1) - cvs_server_validreq[i] = 1; + req = cvs_req_getbyname(sp); + if (req != NULL) + cvs_server_validreq[req->req_id] = 1; if (ep != NULL) sp = ep + 1; @@ -459,7 +632,7 @@ cvs_resp_validreq(int type, char *line) */ static int -cvs_resp_m(int type, char *line) +cvs_resp_m(struct cvsroot *root, int type, char *line) { char *cp; FILE *stream; @@ -533,7 +706,7 @@ cvs_resp_m(int type, char *line) */ static int -cvs_resp_ok(int type, char *line) +cvs_resp_ok(struct cvsroot *root, int type, char *line) { return (1); } @@ -546,7 +719,7 @@ cvs_resp_ok(int type, char *line) */ static int -cvs_resp_error(int type, char *line) +cvs_resp_error(struct cvsroot *root, int type, char *line) { return (1); } @@ -560,12 +733,12 @@ cvs_resp_error(int type, char *line) */ static int -cvs_resp_statdir(int type, char *line) +cvs_resp_statdir(struct cvsroot *root, int type, char *line) { int fd; char rpath[MAXPATHLEN], statpath[MAXPATHLEN]; - cvs_client_getln(rpath, sizeof(rpath)); + cvs_getln(root, rpath, sizeof(rpath)); snprintf(statpath, sizeof(statpath), "%s/%s", line, CVS_PATH_STATICENTRIES); @@ -597,7 +770,7 @@ cvs_resp_statdir(int type, char *line) */ static int -cvs_resp_sticky(int type, char *line) +cvs_resp_sticky(struct cvsroot *root, int type, char *line) { size_t len; char rpath[MAXPATHLEN]; @@ -610,7 +783,7 @@ cvs_resp_sticky(int type, char *line) line[--len] = '\0'; /* get the remote path */ - cvs_client_getln(rpath, sizeof(rpath)); + cvs_getln(root, rpath, sizeof(rpath)); /* if the directory doesn't exist, create it */ if (stat(line, &st) == -1) { @@ -647,7 +820,7 @@ cvs_resp_sticky(int type, char *line) */ static int -cvs_resp_newentry(int type, char *line) +cvs_resp_newentry(struct cvsroot *root, int type, char *line) { char entbuf[128], path[MAXPATHLEN]; CVSENTRIES *entfile; @@ -655,10 +828,10 @@ cvs_resp_newentry(int type, char *line) snprintf(path, sizeof(path), "%s/" CVS_PATH_ENTRIES, line); /* get the remote path */ - cvs_client_getln(entbuf, sizeof(entbuf)); + cvs_getln(root, entbuf, sizeof(entbuf)); /* get the new Entries line */ - if (cvs_client_getln(entbuf, sizeof(entbuf)) < 0) + if (cvs_getln(root, entbuf, sizeof(entbuf)) < 0) return (-1); entfile = cvs_ent_open(path, O_WRONLY); @@ -683,7 +856,7 @@ cvs_resp_newentry(int type, char *line) */ static int -cvs_resp_cksum(int type, char *line) +cvs_resp_cksum(struct cvsroot *root, int type, char *line) { if (cvs_fcksum != NULL) { cvs_log(LP_WARN, "unused checksum"); @@ -709,7 +882,7 @@ cvs_resp_cksum(int type, char *line) */ static int -cvs_resp_modtime(int type, char *line) +cvs_resp_modtime(struct cvsroot *root, int type, char *line) { int i; long off; @@ -772,19 +945,21 @@ cvs_resp_modtime(int type, char *line) */ static int -cvs_resp_updated(int type, char *line) +cvs_resp_updated(struct cvsroot *root, int type, char *line) { size_t len; char tbuf[32], path[MAXPATHLEN], cksum_buf[CVS_CKSUM_LEN]; CVSENTRIES *ef; struct cvs_ent *ep; + ep = NULL; + if (type == CVS_RESP_CREATED) { /* read the remote path of the file */ - cvs_client_getln(path, sizeof(path)); + cvs_getln(root, path, sizeof(path)); /* read the new entry */ - cvs_client_getln(path, sizeof(path)); + cvs_getln(root, path, sizeof(path)); ep = cvs_ent_parse(path); if (ep == NULL) return (-1); @@ -808,7 +983,7 @@ cvs_resp_updated(int type, char *line) } snprintf(path, sizeof(path), "%s%s", line, ep->ce_name); - if (cvs_recvfile(path) < 0) { + if (cvs_recvfile(root, path) < 0) { return (-1); } @@ -837,7 +1012,7 @@ cvs_resp_updated(int type, char *line) */ static int -cvs_resp_removed(int type, char *line) +cvs_resp_removed(struct cvsroot *root, int type, char *line) { return (0); } @@ -850,7 +1025,7 @@ cvs_resp_removed(int type, char *line) */ static int -cvs_resp_mode(int type, char *line) +cvs_resp_mode(struct cvsroot *root, int type, char *line) { if (cvs_strtomode(line, &cvs_lastmode) < 0) { return (-1); @@ -866,7 +1041,7 @@ cvs_resp_mode(int type, char *line) */ static int -cvs_resp_modxpand(int type, char *line) +cvs_resp_modxpand(struct cvsroot *root, int type, char *line) { return (0); } @@ -880,7 +1055,7 @@ cvs_resp_modxpand(int type, char *line) */ int -cvs_sendfile(const char *path) +cvs_sendfile(struct cvsroot *root, const char *path) { int fd; ssize_t ret; @@ -900,9 +1075,9 @@ cvs_sendfile(const char *path) if (cvs_modetostr(st.st_mode, buf, sizeof(buf)) < 0) return (-1); - cvs_client_sendln(buf); + cvs_sendln(root, buf); snprintf(buf, sizeof(buf), "%lld\n", st.st_size); - cvs_client_sendln(buf); + cvs_sendln(root, buf); while ((ret = read(fd, buf, sizeof(buf))) != 0) { if (ret == -1) { @@ -910,7 +1085,7 @@ cvs_sendfile(const char *path) return (-1); } - cvs_client_sendraw(buf, (size_t)ret); + cvs_sendraw(root, buf, (size_t)ret); } @@ -929,7 +1104,7 @@ cvs_sendfile(const char *path) */ int -cvs_recvfile(const char *path) +cvs_recvfile(struct cvsroot *root, const char *path) { int fd; mode_t mode; @@ -938,12 +1113,12 @@ cvs_recvfile(const char *path) off_t fsz, cnt; char buf[4096], *ep; - if ((cvs_client_getln(buf, sizeof(buf)) < 0) || + if ((cvs_getln(root, buf, sizeof(buf)) < 0) || (cvs_strtomode(buf, &mode) < 0)) { return (-1); } - cvs_client_getln(buf, sizeof(buf)); + cvs_getln(root, buf, sizeof(buf)); fsz = (off_t)strtol(buf, &ep, 10); if (*ep != '\0') { @@ -962,7 +1137,7 @@ cvs_recvfile(const char *path) len = MIN(sizeof(buf), (size_t)(fsz - cnt)); if (len == 0) break; - ret = cvs_client_recvraw(buf, len); + ret = cvs_recvraw(root, buf, len); if (ret == -1) { (void)close(fd); (void)unlink(path); @@ -986,7 +1161,6 @@ cvs_recvfile(const char *path) } -#ifdef notyet /* * cvs_sendreq() * @@ -996,39 +1170,38 @@ cvs_recvfile(const char *path) */ int -cvs_sendreq(struct cvs_root *root, u_int rid, const char *arg) +cvs_sendreq(struct cvsroot *root, u_int rid, const char *arg) { int ret; - size_t len; - struct cvs_req *reqp; + struct cvs_req *req; if (root->cr_srvin == NULL) { cvs_log(LP_ERR, "cannot send request: Not connected"); return (-1); } - reqp = cvs_req_getbyid(rid); - if (reqp == NULL) { + req = cvs_req_getbyid(rid); + if (req == NULL) { cvs_log(LP_ERR, "unsupported request type %u", rid); return (-1); } - snprintf(cvs_client_buf, sizeof(cvs_client_buf), "%s %s\n", - reqp->req_str, (arg == NULL) ? "" : " ", (arg == NULL) ? "" : arg); + snprintf(cvs_proto_buf, sizeof(cvs_proto_buf), "%s%s%s\n", + req->req_str, (arg == NULL) ? "" : " ", (arg == NULL) ? "" : arg); if (cvs_server_inlog != NULL) - fputs(cvs_client_buf, cvs_server_inlog); + fputs(cvs_proto_buf, cvs_server_inlog); - ret = fputs(cvs_client_buf, root->cr_srvin); + ret = fputs(cvs_proto_buf, root->cr_srvin); if (ret == EOF) { cvs_log(LP_ERRNO, "failed to send request to server"); return (-1); } - if (reqp->req_flags & CVS_REQF_RESP) + if (req->req_flags & CVS_REQF_RESP) ret = cvs_getresp(root); - return (0); + return (ret); } @@ -1042,15 +1215,16 @@ cvs_sendreq(struct cvs_root *root, u_int rid, const char *arg) */ int -cvs_getresp(struct cvs_root *root) +cvs_getresp(struct cvsroot *root) { - int nbcmd; + int nbcmd, ret; + size_t len; nbcmd = 0; do { /* wait for incoming data */ - if (fgets(cvs_client_buf, sizeof(cvs_client_buf), + if (fgets(cvs_proto_buf, sizeof(cvs_proto_buf), root->cr_srvout) == NULL) { if (feof(root->cr_srvout)) return (0); @@ -1060,17 +1234,17 @@ cvs_getresp(struct cvs_root *root) } if (cvs_server_outlog != NULL) - fputs(cvs_client_buf, cvs_server_outlog); + fputs(cvs_proto_buf, cvs_server_outlog); - if ((len = strlen(cvs_client_buf)) != 0) { - if (cvs_client_buf[len - 1] != '\n') { + if ((len = strlen(cvs_proto_buf)) != 0) { + if (cvs_proto_buf[len - 1] != '\n') { /* truncated line */ } else - cvs_client_buf[--len] = '\0'; + cvs_proto_buf[--len] = '\0'; } - ret = cvs_resp_handle(cvs_client_buf); + ret = cvs_resp_handle(root, cvs_proto_buf); nbcmd++; } while (ret == 0); @@ -1080,6 +1254,39 @@ cvs_getresp(struct cvs_root *root) } +/* + * cvs_getln() + * + * Get a line from the server's output and store it in . The terminating + * newline character is stripped from the result. + */ + +int +cvs_getln(struct cvsroot *root, char *lbuf, size_t len) +{ + size_t rlen; + + if (fgets(lbuf, len, root->cr_srvout) == NULL) { + if (ferror(root->cr_srvout)) { + cvs_log(LP_ERRNO, "failed to read line from server"); + return (-1); + } + + if (feof(root->cr_srvout)) + *lbuf = '\0'; + } + + if (cvs_server_outlog != NULL) + fputs(lbuf, cvs_server_outlog); + + rlen = strlen(lbuf); + if ((rlen > 0) && (lbuf[rlen - 1] == '\n')) + lbuf[--rlen] = '\0'; + + return (0); +} + +#ifdef notyet /* * cvs_sendresp() * @@ -1096,12 +1303,12 @@ cvs_sendresp(u_int rid, const char *arg) const char *resp; resp = cvs_resp_getbyid(rid); - if (reqp == NULL) { + if (resp == NULL) { cvs_log(LP_ERR, "unsupported response type %u", rid); return (-1); } - snprintf(cvs_client_buf, sizeof(cvs_client_buf), "%s %s\n", resp, + snprintf(cvs_proto_buf, sizeof(cvs_proto_buf), "%s %s\n", resp, (arg == NULL) ? "" : arg); ret = fputs(resp, stdout); @@ -1132,7 +1339,7 @@ cvs_getreq(void) do { /* wait for incoming data */ - if (fgets(cvs_client_buf, sizeof(cvs_client_buf), + if (fgets(cvs_proto_buf, sizeof(cvs_proto_buf), stdin) == NULL) { if (feof(stdin)) return (0); @@ -1141,152 +1348,19 @@ cvs_getreq(void) return (-1); } - if ((len = strlen(cvs_client_buf)) != 0) { - if (cvs_client_buf[len - 1] != '\n') { + if ((len = strlen(cvs_proto_buf)) != 0) { + if (cvs_proto_buf[len - 1] != '\n') { /* truncated line */ } else - cvs_client_buf[--len] = '\0'; + cvs_proto_buf[--len] = '\0'; } - ret = cvs_resp_handle(cvs_client_buf); + ret = cvs_resp_handle(cvs_proto_buf); } while (ret == 0); } - - -/* - * cvs_connect() - * - * Open a client connection to the cvs server whose address is given in - * the variable. The method used to connect depends on the - * setting of the CVS_RSH variable. - * Returns 0 on success, or -1 on failure. - */ - -int -cvs_connect(struct cvsroot *root) -{ - int i, argc, infd[2], outfd[2]; - pid_t pid; - char *argv[16], *cvs_server_cmd; - - if (pipe(infd) == -1) { - cvs_log(LP_ERRNO, - "failed to create input pipe for client connection"); - return (-1); - } - - if (pipe(outfd) == -1) { - cvs_log(LP_ERRNO, - "failed to create output pipe for client connection"); - (void)close(infd[0]); - (void)close(infd[1]); - return (-1); - } - - pid = fork(); - if (pid == -1) { - cvs_log(LP_ERRNO, "failed to fork for cvs server connection"); - return (-1); - } - if (pid == 0) { - if ((dup2(infd[0], STDIN_FILENO) == -1) || - (dup2(outfd[1], STDOUT_FILENO) == -1)) { - cvs_log(LP_ERRNO, - "failed to setup standard streams for cvs server"); - return (-1); - } - (void)close(infd[1]); - (void)close(outfd[0]); - - argc = 0; - argv[argc++] = cvs_rsh; - - if (root->cr_user != NULL) { - argv[argc++] = "-l"; - argv[argc++] = root->cr_user; - } - - - cvs_server_cmd = getenv("CVS_SERVER"); - if (cvs_server_cmd == NULL) - cvs_server_cmd = "cvs"; - - argv[argc++] = root->cr_host; - argv[argc++] = cvs_server_cmd; - argv[argc++] = "server"; - argv[argc] = NULL; - - for (i = 0; i < argc; i++) - printf("argv[%d] = `%s'\n", i, argv[i]); - - execvp(argv[0], argv); - cvs_log(LP_ERRNO, "failed to exec"); - exit(EX_OSERR); - } - - /* we are the parent */ - cvs_server_infd = infd[1]; - cvs_server_outfd = outfd[0]; - - cvs_server_in = fdopen(cvs_server_infd, "w"); - if (cvs_server_in == NULL) { - cvs_log(LP_ERRNO, "failed to create pipe stream"); - return (-1); - } - - cvs_server_out = fdopen(cvs_server_outfd, "r"); - if (cvs_server_out == NULL) { - cvs_log(LP_ERRNO, "failed to create pipe stream"); - return (-1); - } - root->cr_srvin = cvs_server_in; - root->cr_srvout = cvs_server_out; - - /* make the streams line-buffered */ - setvbuf(cvs_server_in, NULL, _IOLBF, 0); - setvbuf(cvs_server_out, NULL, _IOLBF, 0); - - (void)close(infd[0]); - (void)close(outfd[1]); - - cvs_client_initlog(); - - cvs_client_sendinfo(); - -#ifdef CVS_ZLIB - /* if compression was requested, initialize it */ #endif - return (0); -} - - -/* - * cvs_disconnect() - * - * Disconnect from the cvs server. - */ - -void -cvs_disconnect(struct cvsroot *root) -{ - cvs_log(LP_DEBUG, "closing client connection"); - if (root->cr_srvin != NULL) { - (void)fclose(root->cr_srvin); - root->cr_srvin = NULL; - } - if (root->cr_srvout != NULL) { - (void)fclose(root->cr_srvout); - root->cr_srvout = NULL; - } - - if (cvs_server_inlog != NULL) - fclose(cvs_server_inlog); - if (cvs_server_outlog != NULL) - fclose(cvs_server_outlog); -} - /* * cvs_sendln() @@ -1322,17 +1396,17 @@ cvs_sendln(struct cvsroot *root, const char *line) /* - * cvs_client_sendraw() + * cvs_sendraw() * * Send the first bytes from the buffer to the server. */ int -cvs_client_sendraw(const void *src, size_t len) +cvs_sendraw(struct cvsroot *root, const void *src, size_t len) { if (cvs_server_inlog != NULL) fwrite(src, sizeof(char), len, cvs_server_inlog); - if (fwrite(src, sizeof(char), len, cvs_server_in) < len) { + if (fwrite(src, sizeof(char), len, root->cr_srvin) < len) { return (-1); } @@ -1341,17 +1415,17 @@ cvs_client_sendraw(const void *src, size_t len) /* - * cvs_client_recvraw() + * cvs_recvraw() * * Receive the first bytes from the buffer to the server. */ ssize_t -cvs_client_recvraw(void *dst, size_t len) +cvs_recvraw(struct cvsroot *root, void *dst, size_t len) { size_t ret; - ret = fread(dst, sizeof(char), len, cvs_server_out); + ret = fread(dst, sizeof(char), len, root->cr_srvout); if (ret == 0) return (-1); if (cvs_server_outlog != NULL) @@ -1361,117 +1435,24 @@ cvs_client_recvraw(void *dst, size_t len) /* - * cvs_client_getln() - * - * Get a line from the server's output and store it in . The terminating - * newline character is stripped from the result. - */ - -int -cvs_client_getln(char *lbuf, size_t len) -{ - size_t rlen; - - if (fgets(lbuf, len, cvs_server_out) == NULL) { - if (ferror(cvs_server_out)) { - cvs_log(LP_ERRNO, "failed to read line from server"); - return (-1); - } - - if (feof(cvs_server_out)) - *lbuf = '\0'; - } - - if (cvs_server_outlog != NULL) - fputs(lbuf, cvs_server_outlog); - - rlen = strlen(lbuf); - if ((rlen > 0) && (lbuf[rlen - 1] == '\n')) - lbuf[--rlen] = '\0'; - - return (0); -} - - -/* - * cvs_client_sendinfo() - * - * Initialize the connection status by first requesting the list of - * supported requests from the server. Then, we send the CVSROOT variable - * with the `Root' request. - * Returns 0 on success, or -1 on failure. - */ - -static int -cvs_client_sendinfo(void) -{ - char *vresp; - /* - * First, send the server the list of valid responses, then ask - * for valid requests - */ - - vresp = cvs_resp_getvalid(); - if (vresp == NULL) { - cvs_log(LP_ERR, "can't generate list of valid responses"); - return (-1); - } - - if (cvs_client_sendreq(CVS_REQ_VALIDRESP, vresp, 0) < 0) { - } - free(vresp); - - if (cvs_client_sendreq(CVS_REQ_VALIDREQ, NULL, 1) < 0) { - cvs_log(LP_ERR, "failed to get valid requests from server"); - return (-1); - } - - /* now share our global options with the server */ - if (verbosity == 1) - cvs_client_sendreq(CVS_REQ_GLOBALOPT, "-q", 0); - else if (verbosity == 0) - cvs_client_sendreq(CVS_REQ_GLOBALOPT, "-Q", 0); - - if (cvs_nolog) - cvs_client_sendreq(CVS_REQ_GLOBALOPT, "-l", 0); - if (cvs_readonly) - cvs_client_sendreq(CVS_REQ_GLOBALOPT, "-r", 0); - if (cvs_trace) - cvs_client_sendreq(CVS_REQ_GLOBALOPT, "-t", 0); - - /* now send the CVSROOT to the server */ - if (cvs_client_sendreq(CVS_REQ_ROOT, cvs_root->cr_dir, 0) < 0) - return (-1); - - /* not sure why, but we have to send this */ - if (cvs_client_sendreq(CVS_REQ_USEUNCHANGED, NULL, 0) < 0) - return (-1); - - return (0); -} - - -/* - * cvs_client_senddir() + * cvs_senddir() * * Send a `Directory' request along with the 2 paths that follow it. */ int -cvs_client_senddir(const char *dir) +cvs_senddir(struct cvsroot *root, CVSFILE *dir) { - char repo[MAXPATHLEN], buf[MAXPATHLEN]; + char buf[MAXPATHLEN]; - if (cvs_readrepo(dir, repo, sizeof(repo)) < 0) { - repo[0] = '\0'; - strlcpy(buf, cvs_root->cr_dir, sizeof(buf)); - } - else { - snprintf(buf, sizeof(buf), "%s/%s", cvs_root->cr_dir, repo); - } + if (dir->cf_ddat->cd_repo == NULL) + strlcpy(buf, root->cr_dir, sizeof(buf)); + else + snprintf(buf, sizeof(buf), "%s/%s", root->cr_dir, + dir->cf_ddat->cd_repo); - if ((cvs_client_sendreq(CVS_REQ_DIRECTORY, dir, 0) < 0) || - (cvs_client_sendln(buf) < 0)) + if ((cvs_sendreq(root, CVS_REQ_DIRECTORY, dir->cf_path) < 0) || + (cvs_sendln(root, buf) < 0)) return (-1); return (0); @@ -1479,7 +1460,7 @@ cvs_client_senddir(const char *dir) /* - * cvs_client_sendarg() + * cvs_sendarg() * * Send the argument to the server. The argument is used to * determine if the argument should be simply appended to the last argument @@ -1487,34 +1468,34 @@ cvs_client_senddir(const char *dir) */ int -cvs_client_sendarg(const char *arg, int append) +cvs_sendarg(struct cvsroot *root, const char *arg, int append) { - return cvs_client_sendreq(((append == 0) ? - CVS_REQ_ARGUMENT : CVS_REQ_ARGUMENTX), arg, 0); + return cvs_sendreq(root, ((append == 0) ? + CVS_REQ_ARGUMENT : CVS_REQ_ARGUMENTX), arg); } /* - * cvs_client_sendentry() + * cvs_sendentry() * * Send an `Entry' request to the server along with the mandatory fields from * the CVS entry (which are the name and revision). */ int -cvs_client_sendentry(const struct cvs_ent *ent) +cvs_sendentry(struct cvsroot *root, const struct cvs_ent *ent) { char ebuf[128], numbuf[64]; snprintf(ebuf, sizeof(ebuf), "/%s/%s///", ent->ce_name, rcsnum_tostr(ent->ce_rev, numbuf, sizeof(numbuf))); - return cvs_client_sendreq(CVS_REQ_ENTRY, ebuf, 0); + return cvs_sendreq(root, CVS_REQ_ENTRY, ebuf); } /* - * cvs_client_initlog() + * cvs_initlog() * * Initialize protocol logging if the CVS_CLIENT_LOG environment variable is * set. In this case, the variable's value is used as a path to which the @@ -1524,10 +1505,14 @@ cvs_client_sendentry(const struct cvs_ent *ent) */ static int -cvs_client_initlog(void) +cvs_initlog(void) { char *env, fpath[MAXPATHLEN]; + /* avoid doing it more than once */ + if (cvs_server_logon) + return (0); + env = getenv("CVS_CLIENT_LOG"); if (env == NULL) return (0); @@ -1554,52 +1539,7 @@ cvs_client_initlog(void) setvbuf(cvs_server_inlog, NULL, _IOLBF, 0); setvbuf(cvs_server_outlog, NULL, _IOLBF, 0); - return (0); -} - - -/* - * cvs_client_sendfile() - * - */ - -int -cvs_client_sendfile(const char *path) -{ - int fd; - ssize_t ret; - char buf[4096]; - struct stat st; - - if (stat(path, &st) == -1) { - cvs_log(LP_ERRNO, "failed to stat `%s'", path); - return (-1); - } - - fd = open(path, O_RDONLY, 0); - if (fd == -1) { - return (-1); - } - - if (cvs_modetostr(st.st_mode, buf, sizeof(buf)) < 0) - return (-1); - - cvs_client_sendln(buf); - snprintf(buf, sizeof(buf), "%lld\n", st.st_size); - cvs_client_sendln(buf); - - while ((ret = read(fd, buf, sizeof(buf))) != 0) { - if (ret == -1) { - cvs_log(LP_ERRNO, "failed to read file `%s'", path); - return (-1); - } - - cvs_client_sendraw(buf, (size_t)ret); - - } - - (void)close(fd); + cvs_server_logon = 1; return (0); } -#endif diff --git a/usr.bin/cvs/proto.h b/usr.bin/cvs/proto.h new file mode 100644 index 00000000000..f354db4cb1c --- /dev/null +++ b/usr.bin/cvs/proto.h @@ -0,0 +1,173 @@ +/* $OpenBSD: proto.h,v 1.1 2004/07/30 01:49:24 jfb Exp $ */ +/* + * Copyright (c) 2004 Jean-Francois Brousseau + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PROTO_H +#define PROTO_H + +#include +#include +#include + +#define CVS_REQ_TIMEOUT 300 + + +/* client/server protocol requests */ +#define CVS_REQ_NONE 0 +#define CVS_REQ_ROOT 1 +#define CVS_REQ_VALIDREQ 2 +#define CVS_REQ_VALIDRESP 3 +#define CVS_REQ_DIRECTORY 4 +#define CVS_REQ_MAXDOTDOT 5 +#define CVS_REQ_STATICDIR 6 +#define CVS_REQ_STICKY 7 +#define CVS_REQ_ENTRY 8 +#define CVS_REQ_ENTRYEXTRA 9 +#define CVS_REQ_CHECKINTIME 10 +#define CVS_REQ_MODIFIED 11 +#define CVS_REQ_ISMODIFIED 12 +#define CVS_REQ_UNCHANGED 13 +#define CVS_REQ_USEUNCHANGED 14 +#define CVS_REQ_NOTIFY 15 +#define CVS_REQ_NOTIFYUSER 16 +#define CVS_REQ_QUESTIONABLE 17 +#define CVS_REQ_CASE 18 +#define CVS_REQ_UTF8 19 +#define CVS_REQ_ARGUMENT 20 +#define CVS_REQ_ARGUMENTX 21 +#define CVS_REQ_GLOBALOPT 22 +#define CVS_REQ_GZIPSTREAM 23 +#define CVS_REQ_KERBENCRYPT 24 +#define CVS_REQ_GSSENCRYPT 25 +#define CVS_REQ_PROTOENCRYPT 26 +#define CVS_REQ_GSSAUTH 27 +#define CVS_REQ_PROTOAUTH 28 +#define CVS_REQ_READCVSRC2 29 +#define CVS_REQ_READWRAP 30 +#define CVS_REQ_ERRIFREADER 31 +#define CVS_REQ_VALIDRCSOPT 32 +#define CVS_REQ_READIGNORE 33 +#define CVS_REQ_SET 34 +#define CVS_REQ_XPANDMOD 35 +#define CVS_REQ_CI 36 +#define CVS_REQ_CHOWN 37 +#define CVS_REQ_SETOWN 38 +#define CVS_REQ_SETPERM 39 +#define CVS_REQ_CHACL 40 +#define CVS_REQ_LISTPERM 41 +#define CVS_REQ_LISTACL 42 +#define CVS_REQ_SETPASS 43 +#define CVS_REQ_PASSWD 44 +#define CVS_REQ_DIFF 45 +#define CVS_REQ_STATUS 46 +#define CVS_REQ_LS 47 +#define CVS_REQ_TAG 48 +#define CVS_REQ_IMPORT 49 +#define CVS_REQ_ADMIN 50 +#define CVS_REQ_HISTORY 51 +#define CVS_REQ_WATCHERS 52 +#define CVS_REQ_EDITORS 53 +#define CVS_REQ_ANNOTATE 54 +#define CVS_REQ_LOG 55 +#define CVS_REQ_CO 56 +#define CVS_REQ_EXPORT 57 +#define CVS_REQ_RANNOTATE 58 +#define CVS_REQ_INIT 59 +#define CVS_REQ_UPDATE 60 +#define CVS_REQ_ADD 62 +#define CVS_REQ_REMOVE 63 +#define CVS_REQ_NOOP 64 +#define CVS_REQ_RTAG 65 +#define CVS_REQ_RELEASE 66 +#define CVS_REQ_RLOG 67 +#define CVS_REQ_RDIFF 68 +#define CVS_REQ_VERSION 69 + +#define CVS_REQ_MAX 69 + + +/* responses */ +#define CVS_RESP_OK 1 +#define CVS_RESP_ERROR 2 +#define CVS_RESP_VALIDREQ 3 +#define CVS_RESP_CHECKEDIN 4 +#define CVS_RESP_NEWENTRY 5 +#define CVS_RESP_CKSUM 6 +#define CVS_RESP_COPYFILE 7 +#define CVS_RESP_UPDATED 8 +#define CVS_RESP_CREATED 9 +#define CVS_RESP_UPDEXIST 10 +#define CVS_RESP_MERGED 11 +#define CVS_RESP_PATCHED 12 +#define CVS_RESP_RCSDIFF 13 +#define CVS_RESP_MODE 14 +#define CVS_RESP_MODTIME 15 +#define CVS_RESP_REMOVED 16 +#define CVS_RESP_RMENTRY 17 +#define CVS_RESP_SETSTATDIR 18 +#define CVS_RESP_CLRSTATDIR 19 +#define CVS_RESP_SETSTICKY 20 +#define CVS_RESP_CLRSTICKY 21 +#define CVS_RESP_TEMPLATE 22 +#define CVS_RESP_SETCIPROG 23 +#define CVS_RESP_SETUPDPROG 24 +#define CVS_RESP_NOTIFIED 25 +#define CVS_RESP_MODXPAND 26 +#define CVS_RESP_WRAPRCSOPT 27 +#define CVS_RESP_M 28 +#define CVS_RESP_MBINARY 29 +#define CVS_RESP_E 30 +#define CVS_RESP_F 31 +#define CVS_RESP_MT 32 + + + +int cvs_sendfile (struct cvsroot *, const char *); +int cvs_recvfile (struct cvsroot *, const char *); +int cvs_connect (struct cvsroot *); +void cvs_disconnect (struct cvsroot *); + +int cvs_req_handle (char *); +struct cvs_req* cvs_req_getbyid (int); +struct cvs_req* cvs_req_getbyname (const char *); +char* cvs_req_getvalid (void); + +int cvs_resp_handle (struct cvsroot *, char *); +struct cvs_resp* cvs_resp_getbyid (int); +struct cvs_resp* cvs_resp_getbyname (const char *); +char* cvs_resp_getvalid (void); + +int cvs_sendreq (struct cvsroot *, u_int, const char *); +int cvs_getresp (struct cvsroot *); +int cvs_getln (struct cvsroot *, char *, size_t); +int cvs_senddir (struct cvsroot *, CVSFILE *); +int cvs_sendarg (struct cvsroot *, const char *, int); +int cvs_sendln (struct cvsroot *, const char *); +int cvs_sendentry (struct cvsroot *, const struct cvs_ent *); +int cvs_sendraw (struct cvsroot *, const void *, size_t); +ssize_t cvs_recvraw (struct cvsroot *, void *, size_t); + + +#endif /* PROTO_H */ diff --git a/usr.bin/cvs/root.c b/usr.bin/cvs/root.c index 37cd04c1857..a4e58d37d9b 100644 --- a/usr.bin/cvs/root.c +++ b/usr.bin/cvs/root.c @@ -1,4 +1,4 @@ -/* $OpenBSD: root.c,v 1.7 2004/07/28 02:15:10 jfb Exp $ */ +/* $OpenBSD: root.c,v 1.8 2004/07/30 01:49:24 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -255,7 +255,6 @@ cvsroot_get(const char *dir) size_t len; char rootpath[MAXPATHLEN], *rootstr, line[128]; FILE *fp; - struct cvsroot *rp; if (cvs_rootstr != NULL) return cvsroot_parse(cvs_rootstr); diff --git a/usr.bin/cvs/update.c b/usr.bin/cvs/update.c index 1777112d1f9..c748218eed0 100644 --- a/usr.bin/cvs/update.c +++ b/usr.bin/cvs/update.c @@ -1,4 +1,4 @@ -/* $OpenBSD: update.c,v 1.3 2004/07/29 18:32:46 jfb Exp $ */ +/* $OpenBSD: update.c,v 1.4 2004/07/30 01:49:24 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -38,6 +38,7 @@ #include "cvs.h" #include "rcs.h" #include "log.h" +#include "proto.h" int cvs_update_file (CVSFILE *, void *); @@ -105,8 +106,8 @@ cvs_update(int argc, char **argv) cvs_file_examine(cf, cvs_update_file, NULL); - cvs_client_senddir(cf->cf_path); - cvs_client_sendreq(CVS_REQ_UPDATE, NULL, 1); + cvs_senddir(cf->cf_ddat->cd_root, cf); + cvs_sendreq(cf->cf_ddat->cd_root, CVS_REQ_UPDATE, NULL); return (0); } @@ -132,12 +133,10 @@ cvs_update_file(CVSFILE *cf, void *arg) root = cf->cf_ddat->cd_root; if ((cf->cf_parent == NULL) || (root != cf->cf_parent->cf_ddat->cd_root)) { - cvs_client_connect(root); - /* XXX temporary hack */ - cvs_root = root; + cvs_connect(root); } - cvs_client_senddir(cf->cf_path); + cvs_senddir(root, cf); return (0); } else @@ -157,8 +156,7 @@ cvs_update_file(CVSFILE *cf, void *arg) if (root->cr_method == CVS_METHOD_LOCAL) cvs_printf("? %s\n", cf->cf_path); else - cvs_client_sendreq(CVS_REQ_QUESTIONABLE, - cf->cf_name, 0); + cvs_sendreq(root, CVS_REQ_QUESTIONABLE, cf->cf_name); return (0); } @@ -167,7 +165,7 @@ cvs_update_file(CVSFILE *cf, void *arg) return (-1); if ((root->cr_method != CVS_METHOD_LOCAL) && - (cvs_client_sendentry(entp) < 0)) { + (cvs_sendentry(root, entp) < 0)) { cvs_ent_free(entp); return (-1); } @@ -175,12 +173,12 @@ cvs_update_file(CVSFILE *cf, void *arg) if (root->cr_method != CVS_METHOD_LOCAL) { switch (cf->cf_cvstat) { case CVS_FST_UPTODATE: - cvs_client_sendreq(CVS_REQ_UNCHANGED, cf->cf_name, 0); + cvs_sendreq(root, CVS_REQ_UNCHANGED, cf->cf_name); break; case CVS_FST_ADDED: case CVS_FST_MODIFIED: - cvs_client_sendreq(CVS_REQ_MODIFIED, cf->cf_name, 0); - cvs_sendfile(cf->cf_path); + cvs_sendreq(root, CVS_REQ_MODIFIED, cf->cf_name); + cvs_sendfile(root, cf->cf_path); break; default: return (-1); diff --git a/usr.bin/cvs/util.c b/usr.bin/cvs/util.c index aa738d002c4..499c87ac537 100644 --- a/usr.bin/cvs/util.c +++ b/usr.bin/cvs/util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: util.c,v 1.3 2004/07/28 01:50:05 jfb Exp $ */ +/* $OpenBSD: util.c,v 1.4 2004/07/30 01:49:24 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -277,7 +277,7 @@ cvs_splitpath(const char *path, char *dir, size_t dlen, char *file, size_t flen) } } else { - rlen = MIN(dlen - 1, sp - path); + rlen = MIN(dlen - 1, (size_t)(sp - path)); if (dir != NULL) { strncpy(dir, path, rlen); dir[rlen] = '\0'; diff --git a/usr.bin/cvs/version.c b/usr.bin/cvs/version.c index 406e134876a..38b5b76aaef 100644 --- a/usr.bin/cvs/version.c +++ b/usr.bin/cvs/version.c @@ -1,4 +1,4 @@ -/* $OpenBSD: version.c,v 1.3 2004/07/29 18:23:25 jfb Exp $ */ +/* $OpenBSD: version.c,v 1.4 2004/07/30 01:49:25 jfb Exp $ */ /* * Copyright (c) 2004 Jean-Francois Brousseau * All rights reserved. @@ -34,32 +34,33 @@ #include #include "cvs.h" +#include "proto.h" int cvs_version(int argc, char **argv) { + struct cvsroot *root; + if (argc > 1) return (EX_USAGE); - cvs_root = cvsroot_get("."); - - if ((cvs_root) && (cvs_root->cr_method != CVS_METHOD_LOCAL)) + root = cvsroot_get("."); + if ((root != NULL) && (root->cr_method != CVS_METHOD_LOCAL)) printf("Client: "); - printf("%s\n", CVS_VERSION); - - if ((cvs_root) && (cvs_root->cr_method != CVS_METHOD_LOCAL)) - if (cvs_client_connect(cvs_root) < 0) + if ((root != NULL) && (root->cr_method != CVS_METHOD_LOCAL)) { + if (cvs_connect(root) < 0) return (1); - if ((cvs_root) && (cvs_root->cr_method != CVS_METHOD_LOCAL)) { printf("Server: "); - cvs_client_sendreq(CVS_REQ_VERSION, NULL, 1); - cvs_client_disconnect(cvs_root); + cvs_sendreq(root, CVS_REQ_VERSION, NULL); + cvs_disconnect(root); } + cvsroot_free(root); + return (0); } -- cgit v1.2.3