summaryrefslogtreecommitdiff
path: root/usr.bin
diff options
context:
space:
mode:
authorJoris Vink <joris@cvs.openbsd.org>2005-05-18 20:24:20 +0000
committerJoris Vink <joris@cvs.openbsd.org>2005-05-18 20:24:20 +0000
commit6726ad6012217b4c1deb337f7a3bdcb6adda8f0b (patch)
treeef2d40d434004c9180c789489ac249c12d709ce6 /usr.bin
parent2331260019b16e69e20fccf7b0f0d10b3db3e87c (diff)
build a local copy of the client's source tree when acting as a server.
more server stuff coming soon! ok jfb@, xsa@
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/cvs/cvs.h3
-rw-r--r--usr.bin/cvs/req.c58
-rw-r--r--usr.bin/cvs/server.c32
-rw-r--r--usr.bin/cvs/util.c52
4 files changed, 140 insertions, 5 deletions
diff --git a/usr.bin/cvs/cvs.h b/usr.bin/cvs/cvs.h
index 46928520c31..12b6c140969 100644
--- a/usr.bin/cvs/cvs.h
+++ b/usr.bin/cvs/cvs.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: cvs.h,v 1.54 2005/05/02 15:00:18 xsa Exp $ */
+/* $OpenBSD: cvs.h,v 1.55 2005/05/18 20:24:19 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -406,6 +406,7 @@ int cvs_mkadmin (CVSFILE *, mode_t);
int cvs_cksum (const char *, char *, size_t);
int cvs_exec (int, char **, int []);
int cvs_getargv (const char *, char **, int);
+int cvs_remove_dir (const char *);
char** cvs_makeargv (const char *, int *);
void cvs_freeargv (char **, int);
diff --git a/usr.bin/cvs/req.c b/usr.bin/cvs/req.c
index b281b6d9112..367382a9440 100644
--- a/usr.bin/cvs/req.c
+++ b/usr.bin/cvs/req.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: req.c,v 1.13 2005/04/18 21:33:34 jfb Exp $ */
+/* $OpenBSD: req.c,v 1.14 2005/05/18 20:24:19 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -150,7 +150,11 @@ struct cvs_reqhdlr {
*/
static char *cvs_req_rootpath;
+static char *cvs_req_currentdir;
+static char *cvs_req_repopath;
+static char cvs_req_tmppath[MAXPATHLEN];
+extern char cvs_server_tmpdir[MAXPATHLEN];
static char *cvs_req_args[CVS_PROTO_MAXARG];
static int cvs_req_nargs = 0;
@@ -261,11 +265,42 @@ cvs_req_validresp(int reqid, char *line)
static int
cvs_req_directory(int reqid, char *line)
{
+ int l;
char rdir[MAXPATHLEN];
if (cvs_getln(NULL, rdir, sizeof(rdir)) < 0)
return (-1);
+ if (cvs_req_currentdir != NULL)
+ free(cvs_req_currentdir);
+
+ cvs_req_currentdir = strdup(rdir);
+ if (cvs_req_currentdir == NULL) {
+ cvs_log(LP_ERROR, "failed to duplicate directory");
+ return (-1);
+ }
+
+ /* now obtain the path relative to the Root directory */
+ cvs_req_repopath = cvs_req_currentdir + strlen(cvs_req_rootpath) + 1;
+
+ /* create tmp path */
+ l = snprintf(cvs_req_tmppath, sizeof(cvs_req_tmppath), "%s/%s",
+ cvs_server_tmpdir, cvs_req_repopath);
+ if (l == -1 || l >= (int)sizeof(cvs_req_tmppath)) {
+ errno = ENAMETOOLONG;
+ cvs_log(LP_ERRNO, "%s", cvs_req_tmppath);
+ return (-1);
+ }
+
+ if ((mkdir(cvs_req_tmppath, 0755) == -1) && (errno != EEXIST)) {
+ cvs_log(LP_ERRNO, "failed to create temporary directory '%s'",
+ cvs_req_tmppath);
+ return (-1);
+ }
+
+ /* create the CVS/ administrative files */
+ /* XXX - TODO */
+
return (0);
}
@@ -290,13 +325,34 @@ cvs_req_entry(int reqid, char *line)
static int
cvs_req_filestate(int reqid, char *line)
{
+ int l;
mode_t fmode;
BUF *fdata;
+ char fpath[MAXPATHLEN];
if (reqid == CVS_REQ_MODIFIED) {
fdata = cvs_recvfile(NULL, &fmode);
if (fdata == NULL)
return (-1);
+
+ /* create full temporary path */
+ l = snprintf(fpath, sizeof(fpath), "%s/%s", cvs_req_tmppath,
+ line);
+ if (l == -1 || l >= (int)sizeof(fpath)) {
+ errno = ENAMETOOLONG;
+ cvs_log(LP_ERRNO, "%s", fpath);
+ cvs_buf_free(fdata);
+ return (-1);
+ }
+
+ /* write the file */
+ if (cvs_buf_write(fdata, fpath, fmode) < 0) {
+ cvs_log(LP_ERROR, "failed to create file %s", fpath);
+ cvs_buf_free(fdata);
+ return (-1);
+ }
+
+ cvs_buf_free(fdata);
}
return (0);
diff --git a/usr.bin/cvs/server.c b/usr.bin/cvs/server.c
index 9f0442b428a..34443c4e221 100644
--- a/usr.bin/cvs/server.c
+++ b/usr.bin/cvs/server.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.13 2005/04/12 14:58:40 joris Exp $ */
+/* $OpenBSD: server.c,v 1.14 2005/05/18 20:24:19 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -25,6 +25,7 @@
*/
#include <sys/types.h>
+#include <sys/stat.h>
#include <stdlib.h>
#include <stdio.h>
@@ -47,6 +48,8 @@ u_int cvs_case = 0;
struct cvs_cmd_info cmd_server = {
NULL, NULL, NULL, NULL, NULL, 0, 0, 0 };
+char cvs_server_tmpdir[MAXPATHLEN];
+
/*
* cvs_server()
*
@@ -61,6 +64,7 @@ struct cvs_cmd_info cmd_server = {
int
cvs_server(int argc, char **argv)
{
+ int l, ret;
size_t len;
char reqbuf[512];
@@ -72,6 +76,27 @@ cvs_server(int argc, char **argv)
(void)setvbuf(stdin, NULL, _IOLBF, 0);
(void)setvbuf(stdout, NULL, _IOLBF, 0);
+ /* create the temporary directory */
+ l = snprintf(cvs_server_tmpdir, sizeof(cvs_server_tmpdir),
+ "%scvs-serv%d", _PATH_TMP, getpid());
+ if (l == -1 || l >= (int)sizeof(cvs_server_tmpdir)) {
+ errno = ENAMETOOLONG;
+ cvs_log(LP_ERRNO, "%s", cvs_server_tmpdir);
+ return (CVS_EX_DATA);
+ }
+
+ if (mkdir(cvs_server_tmpdir, 0700) == -1) {
+ cvs_log(LP_ERRNO, "failed to create temporary directory '%s'",
+ cvs_server_tmpdir);
+ return (CVS_EX_DATA);
+ }
+
+ if (chdir(cvs_server_tmpdir) == -1) {
+ cvs_log(LP_ERRNO, "failed to change to temporary directory '%s'"
+ , cvs_server_tmpdir);
+ return (CVS_EX_DATA);
+ }
+
for (;;) {
if (fgets(reqbuf, sizeof(reqbuf), stdin) == NULL) {
if (feof(stdin))
@@ -94,5 +119,8 @@ cvs_server(int argc, char **argv)
}
- return (0);
+ /* cleanup the temporary tree */
+ ret = cvs_remove_dir(cvs_server_tmpdir);
+
+ return (ret);
}
diff --git a/usr.bin/cvs/util.c b/usr.bin/cvs/util.c
index 60416880f96..4e6d9f6b821 100644
--- a/usr.bin/cvs/util.c
+++ b/usr.bin/cvs/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.23 2005/04/18 21:02:50 jfb Exp $ */
+/* $OpenBSD: util.c,v 1.24 2005/05/18 20:24:19 joris Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -604,3 +604,53 @@ cvs_exec(int argc, char **argv, int fds[3])
return (ret);
}
+
+/*
+ * remove a directory tree from disk.
+ */
+int
+cvs_remove_dir(const char *path)
+{
+ int l, ret;
+ DIR *dirp;
+ struct dirent *ent;
+ char fpath[MAXPATHLEN];
+
+ if ((dirp = opendir(path)) == NULL) {
+ cvs_log(LP_ERRNO, "failed to open '%s'", path);
+ return (CVS_EX_FILE);
+ }
+
+ while ((ent = readdir(dirp)) != NULL) {
+ if (!strcmp(ent->d_name, ".") ||
+ !strcmp(ent->d_name, ".."))
+ continue;
+
+ l = snprintf(fpath, sizeof(fpath), "%s/%s", path, ent->d_name);
+ if (l == -1 || l >= (int)sizeof(fpath)) {
+ errno = ENAMETOOLONG;
+ cvs_log(LP_ERRNO, "%s", fpath);
+ closedir(dirp);
+ return (CVS_EX_FILE);
+ }
+
+ if (ent->d_type == DT_DIR) {
+ if ((ret = cvs_remove_dir(fpath)) != CVS_EX_OK) {
+ closedir(dirp);
+ return (ret);
+ }
+ } else {
+ if ((unlink(fpath) == -1) && (errno != ENOENT))
+ cvs_log(LP_ERRNO, "failed to remove '%s'",
+ fpath);
+ }
+ }
+
+ closedir(dirp);
+
+ if ((rmdir(path) == -1) && (errno != ENOENT))
+ cvs_log(LP_ERRNO, "failed to remove '%s'", path);
+
+ return (CVS_EX_OK);
+}
+