summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorXavier Santolaria <xsa@cvs.openbsd.org>2006-11-08 20:20:43 +0000
committerXavier Santolaria <xsa@cvs.openbsd.org>2006-11-08 20:20:43 +0000
commit4244df7681fc7a2f85ba800a95ab96a98ca65423 (patch)
tree48380c437c262d87e19f60d33e1ea25837161da8 /usr.bin
parent253b093a1f7f5a2d2e8f5a6121627a669731d5c3 (diff)
bring back support for CVS_CLIENT_LOG that was removed with
the proto.c removal a while ago.... OK ray@ joris@.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/cvs/client.c194
1 files changed, 189 insertions, 5 deletions
diff --git a/usr.bin/cvs/client.c b/usr.bin/cvs/client.c
index d28a6b9b5ca..64746cd6ed7 100644
--- a/usr.bin/cvs/client.c
+++ b/usr.bin/cvs/client.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: client.c,v 1.15 2006/10/31 15:23:40 xsa Exp $ */
+/* $OpenBSD: client.c,v 1.16 2006/11/08 20:20:42 xsa Exp $ */
/*
* Copyright (c) 2006 Joris Vink <joris@openbsd.org>
*
@@ -90,10 +90,21 @@ struct cvs_req cvs_requests[] = {
{ "", -1, NULL, 0 }
};
-static void client_check_directory(char *);
-static char *client_get_supported_responses(void);
-static char *lastdir = NULL;
-static int end_of_response = 0;
+static void client_check_directory(char *);
+static char *client_get_supported_responses(void);
+static char *lastdir = NULL;
+static int end_of_response = 0;
+
+static void cvs_client_initlog(void);
+
+/*
+ * File descriptors for protocol logging when the CVS_CLIENT_LOG environment
+ * variable is set.
+ */
+static int cvs_client_logon = 0;
+static int cvs_client_inlog_fd = -1;
+static int cvs_client_outlog_fd = -1;
+
static char *
client_get_supported_responses(void)
@@ -223,6 +234,8 @@ cvs_client_connect_to_server(void)
setvbuf(current_cvsroot->cr_srvin, NULL,_IOLBF, 0);
setvbuf(current_cvsroot->cr_srvout, NULL, _IOLBF, 0);
+ cvs_client_initlog();
+
cvs_client_send_request("Root %s", current_cvsroot->cr_dir);
resp = client_get_supported_responses();
@@ -266,6 +279,23 @@ cvs_client_send_request(char *fmt, ...)
*s = ' ';
cvs_log(LP_TRACE, "%s", data);
+
+ if (cvs_client_inlog_fd != -1) {
+ BUF *bp;
+
+ bp = cvs_buf_alloc(strlen(data), BUF_AUTOEXT);
+
+ if (cvs_buf_append(bp, data, strlen(data)) < 0)
+ fatal("cvs_client_send_request: cvs_buf_append");
+
+ cvs_buf_putc(bp, '\n');
+
+ if (cvs_buf_write_fd(bp, cvs_client_inlog_fd) < 0)
+ fatal("cvs_client_send_request: cvs_buf_write_fd");
+
+ cvs_buf_free(bp);
+ }
+
cvs_remote_output(data);
xfree(data);
}
@@ -287,7 +317,36 @@ cvs_client_read_response(void)
if (resp->hdlr == NULL)
fatal("opencvs client does not support '%s'", cmd);
+ if (cvs_client_outlog_fd != -1) {
+ BUF *bp;
+
+ bp = cvs_buf_alloc(strlen(cmd), BUF_AUTOEXT);
+
+ if (cvs_buf_append(bp, cmd, strlen(cmd)) < 0)
+ fatal("cvs_client_read_response: cvs_buf_append");
+
+ if (cvs_buf_append(bp,
+ (data == NULL) ? "" : " ",
+ (data == NULL) ? 0 : 1) < 0) {
+ fatal("cvs_client_read_response: cvs_buf_append");
+ }
+
+ if (cvs_buf_append(bp,
+ (data == NULL) ? "" : data,
+ (data == NULL) ? 0 : strlen(data)) < 0) {
+ fatal("cvs_client_read_response: cvs_buf_append");
+ }
+
+ cvs_buf_putc(bp, '\n');
+
+ if (cvs_buf_write_fd(bp, cvs_client_outlog_fd) < 0)
+ fatal("cvs_client_read_response: cvs_buf_write_fd");
+
+ cvs_buf_free(bp);
+ }
+
(*resp->hdlr)(data);
+
xfree(cmd);
}
@@ -612,3 +671,128 @@ cvs_client_remove_entry(char *data)
dir = cvs_remote_input();
xfree(dir);
}
+/*
+ * cvs_client_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
+ * appropriate suffix is added (".in" for client input and ".out" for server
+ * output).
+ */
+static void
+cvs_client_initlog(void)
+{
+ int l;
+ u_int i;
+ char *env, *envdup, buf[MAXPATHLEN], fpath[MAXPATHLEN];
+ char rpath[MAXPATHLEN], *s;
+ struct stat st;
+ time_t now;
+ struct passwd *pwd;
+
+ /* avoid doing it more than once */
+ if (cvs_client_logon)
+ return;
+
+ if ((env = getenv("CVS_CLIENT_LOG")) == NULL)
+ return;
+
+ envdup = xstrdup(env);
+ if ((s = strchr(envdup, '%')) != NULL)
+ *s = '\0';
+
+ if (strlcpy(buf, env, sizeof(buf)) >= sizeof(buf))
+ fatal("cvs_client_initlog: truncation");
+
+ if (strlcpy(rpath, envdup, sizeof(rpath)) >= sizeof(rpath))
+ fatal("cvs_client_initlog: truncation");
+
+ xfree(envdup);
+
+ s = buf;
+ while ((s = strchr(s, '%')) != NULL) {
+ s++;
+ switch (*s) {
+ case 'c':
+ if (strlcpy(fpath, cvs_command, sizeof(fpath)) >=
+ sizeof(fpath))
+ fatal("cvs_client_initlog: truncation");
+ break;
+ case 'd':
+ time(&now);
+ if (strlcpy(fpath, ctime(&now), sizeof(fpath)) >=
+ sizeof(fpath))
+ fatal("cvs_client_initlog: truncation");
+ break;
+ case 'p':
+ snprintf(fpath, sizeof(fpath), "%d", getpid());
+ break;
+ case 'u':
+ if ((pwd = getpwuid(getuid())) != NULL) {
+ if (strlcpy(fpath, pwd->pw_name,
+ sizeof(fpath)) >= sizeof(fpath))
+ fatal("cvs_client_initlog: truncation");
+ } else {
+ fpath[0] = '\0';
+ }
+ endpwent();
+ break;
+ default:
+ fpath[0] = '\0';
+ break;
+ }
+
+ if (fpath[0] != '\0') {
+ if (strlcat(rpath, "-", sizeof(rpath)) >= sizeof(rpath))
+ fatal("cvs_client_initlog: truncation");
+
+ if (strlcat(rpath, fpath, sizeof(rpath))
+ >= sizeof(rpath))
+ fatal("cvs_client_initlog: truncation");
+ }
+ }
+
+ for (i = 0; i < UINT_MAX; i++) {
+ l = snprintf(fpath, sizeof(fpath), "%s-%d.in", rpath, i);
+ if (l == -1 || l >= (int)sizeof(fpath))
+ fatal("cvs_client_initlog: overflow");
+
+ if (stat(fpath, &st) != -1)
+ continue;
+
+ if (errno != ENOENT)
+ fatal("cvs_client_initlog() stat failed '%s'",
+ strerror(errno));
+
+ break;
+ }
+
+ if ((cvs_client_inlog_fd = open(fpath,
+ O_RDWR | O_CREAT | O_TRUNC, 0644)) == NULL) {
+ fatal("cvs_client_initlog: open `%s': %s",
+ fpath, strerror(errno));
+ }
+
+ for (i = 0; i < UINT_MAX; i++) {
+ l = snprintf(fpath, sizeof(fpath), "%s-%d.out", rpath, i);
+ if (l == -1 || l >= (int)sizeof(fpath))
+ fatal("cvs_client_initlog: overflow");
+
+ if (stat(fpath, &st) != -1)
+ continue;
+
+ if (errno != ENOENT)
+ fatal("cvs_client_initlog() stat failed '%s'",
+ strerror(errno));
+
+ break;
+ }
+
+ if ((cvs_client_outlog_fd = open(fpath,
+ O_RDWR | O_CREAT | O_TRUNC, 0644)) == NULL) {
+ fatal("cvs_client_initlog: open `%s': %s",
+ fpath, strerror(errno));
+ }
+
+ cvs_client_logon = 1;
+}