summaryrefslogtreecommitdiff
path: root/usr.bin/cvs
diff options
context:
space:
mode:
authorJean-Francois Brousseau <jfb@cvs.openbsd.org>2004-07-30 01:49:27 +0000
committerJean-Francois Brousseau <jfb@cvs.openbsd.org>2004-07-30 01:49:27 +0000
commitb59c4319a2b0bee7cbb7f9ef3342f372940000e1 (patch)
treea92383f8032facbf9c49611d38ee8dd3cfeaa963 /usr.bin/cvs
parentf1a256bf9c1770f12d8fbfedbab0ecc0c472d43d (diff)
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.
Diffstat (limited to 'usr.bin/cvs')
-rw-r--r--usr.bin/cvs/add.c21
-rw-r--r--usr.bin/cvs/checkout.c22
-rw-r--r--usr.bin/cvs/client.c123
-rw-r--r--usr.bin/cvs/commit.c3
-rw-r--r--usr.bin/cvs/cvs.c62
-rw-r--r--usr.bin/cvs/cvs.h150
-rw-r--r--usr.bin/cvs/cvs/Makefile6
-rw-r--r--usr.bin/cvs/diff.c396
-rw-r--r--usr.bin/cvs/file.h206
-rw-r--r--usr.bin/cvs/getlog.c3
-rw-r--r--usr.bin/cvs/history.c22
-rw-r--r--usr.bin/cvs/proto.c714
-rw-r--r--usr.bin/cvs/proto.h173
-rw-r--r--usr.bin/cvs/root.c3
-rw-r--r--usr.bin/cvs/update.c24
-rw-r--r--usr.bin/cvs/util.c4
-rw-r--r--usr.bin/cvs/version.c23
17 files changed, 960 insertions, 995 deletions
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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* All rights reserved.
@@ -41,6 +41,7 @@
#include "cvs.h"
#include "log.h"
+#include "proto.h"
@@ -200,80 +201,6 @@ cvs_client_disconnect(struct cvsroot *root)
/*
- * cvs_client_sendreq()
- *
- * Send a request to the server of type <rid>, with optional arguments
- * contained in <arg>, which should not be terminated by a newline.
- * The <resp> 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()
*
* Send a single line <line> string to the server. The line is sent as is,
@@ -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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
+ * 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 <sys/param.h>
+#include <stdio.h>
+#include <dirent.h>
+
+#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 <cf_path> field is a path relative to the
+ * directory in which the cvs command was executed. The <cf_parent> 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 <cf_cvstat> 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 <cf_ddat> 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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* 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 <root> 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);
@@ -1081,6 +1255,39 @@ cvs_getresp(struct cvs_root *root)
/*
+ * cvs_getln()
+ *
+ * Get a line from the server's output and store it in <lbuf>. 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()
*
* Send a response to the client of type <rid>, with optional arguments
@@ -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 <root> 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 <len> bytes from the buffer <src> 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 <len> bytes from the buffer <src> 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 <lbuf>. 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 <arg> to the server. The argument <append> 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 <ent> (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 <jfb@openbsd.org>
+ * 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 <sys/param.h>
+#include <stdio.h>
+#include <dirent.h>
+
+#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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* 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 <jfb@openbsd.org>
* All rights reserved.
@@ -34,32 +34,33 @@
#include <sysexits.h>
#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);
}