summaryrefslogtreecommitdiffstats
path: root/usr.bin/cvs/commit.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/cvs/commit.c')
-rw-r--r--usr.bin/cvs/commit.c257
1 files changed, 70 insertions, 187 deletions
diff --git a/usr.bin/cvs/commit.c b/usr.bin/cvs/commit.c
index 6906f136c9f..d6bd3034434 100644
--- a/usr.bin/cvs/commit.c
+++ b/usr.bin/cvs/commit.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: commit.c,v 1.5 2004/11/09 22:22:47 krapht Exp $ */
+/* $OpenBSD: commit.c,v 1.6 2004/11/26 16:23:50 jfb Exp $ */
/*
* Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
* All rights reserved.
@@ -25,6 +25,7 @@
*/
#include <sys/types.h>
+#include <sys/queue.h>
#include <sys/stat.h>
#include <errno.h>
@@ -41,16 +42,17 @@
#include "proto.h"
-#define CVS_COMMIT_BIGMSG 32000
-#define CVS_COMMIT_FTMPL "/tmp/cvsXXXXXXXXXX"
-#define CVS_COMMIT_LOGPREFIX "CVS:"
-#define CVS_COMMIT_LOGLINE \
-"----------------------------------------------------------------------"
+LIST_HEAD(ci_list, ci_file);
+struct ci_file {
+ char *ci_path;
+ RCSNUM *ci_rev;
+ LIST_ENTRY(ci_file) ci_link;
+};
-static char* cvs_commit_openmsg (const char *);
-static char* cvs_commit_getmsg (const char *);
+
+int cvs_commit_file (CVSFILE *, void *);
/*
@@ -62,14 +64,15 @@ static char* cvs_commit_getmsg (const char *);
int
cvs_commit(int argc, char **argv)
{
- int ch, recurse;
+ int ch, recurse, flags;
char *msg, *mfile;
+ struct ci_list cl;
+ flags = 0;
recurse = 1;
mfile = NULL;
msg = NULL;
-
- cvs_commit_getmsg(".");
+ LIST_INIT(&cl);
while ((ch = getopt(argc, argv, "F:flm:R")) != -1) {
switch (ch) {
@@ -98,210 +101,90 @@ cvs_commit(int argc, char **argv)
return (EX_USAGE);
}
- if ((mfile != NULL) && (msg = cvs_commit_openmsg(mfile)) == NULL)
+ if ((mfile != NULL) && (msg = cvs_logmsg_open(mfile)) == NULL)
return (EX_DATAERR);
argc -= optind;
argv += optind;
- return (0);
-}
-
-
-/*
- * cvs_commit_openmsg()
- *
- * Open the file specified by <path> and allocate a buffer large enough to
- * hold all of the file's contents. The returned value must later be freed
- * using the free() function.
- * Returns a pointer to the allocated buffer on success, or NULL on failure.
- */
-
-static char*
-cvs_commit_openmsg(const char *path)
-{
- int ch;
- size_t len;
- char lbuf[256], *msg;
- struct stat st;
- FILE *fp;
- BUF *bp;
-
- if (stat(path, &st) == -1) {
- cvs_log(LP_ERRNO, "failed to stat `%s'", path);
- return (NULL);
- }
-
- if (!S_ISREG(st.st_mode)) {
- cvs_log(LP_ERR, "message file must be a regular file");
- return (NULL);
- }
-
- if (st.st_size > CVS_COMMIT_BIGMSG) {
- do {
- fprintf(stderr,
- "The specified message file seems big. "
- "Proceed anyways? (y/n) ");
- if (fgets(lbuf, sizeof(lbuf), stdin) == NULL) {
- cvs_log(LP_ERRNO,
- "failed to read from standard input");
- return (NULL);
- }
-
- len = strlen(lbuf);
- if ((len == 0) || (len > 2) ||
- ((lbuf[0] != 'y') && (lbuf[0] != 'n'))) {
- fprintf(stderr, "invalid input\n");
- continue;
- }
- else if (lbuf[0] == 'y')
- break;
- else if (lbuf[0] == 'n') {
- cvs_log(LP_ERR, "aborted by user");
- return (NULL);
- }
-
- } while (1);
- }
-
- if ((fp = fopen(path, "r")) == NULL) {
- cvs_log(LP_ERRNO, "failed to open message file `%s'", path);
- return (NULL);
- }
-
- bp = cvs_buf_alloc(128, BUF_AUTOEXT);
- if (bp == NULL) {
- return (NULL);
+ if (argc == 0)
+ cvs_files = cvs_file_get(".", flags);
+ else {
+ cvs_files = cvs_file_getspec(argv, argc, flags);
}
+ if (cvs_files == NULL)
+ return (EX_DATAERR);
- while (fgets(lbuf, sizeof(lbuf), fp) != NULL) {
- len = strlen(lbuf);
- if (len == 0)
- continue;
-
- /* skip lines starting with the prefix */
- if (strncmp(lbuf, CVS_COMMIT_LOGPREFIX,
- strlen(CVS_COMMIT_LOGPREFIX)) == 0)
- continue;
-
- cvs_buf_append(bp, lbuf, strlen(lbuf));
- }
- cvs_buf_putc(bp, '\0');
+ cvs_file_examine(cvs_files, cvs_commit_file, &cl);
- msg = (char *)cvs_buf_release(bp);
+ cvs_senddir(cvs_files->cf_ddat->cd_root, cvs_files);
+ cvs_sendreq(cvs_files->cf_ddat->cd_root, CVS_REQ_CI, NULL);
- return (msg);
+ return (0);
}
/*
- * cvs_commit_getmsg()
+ * cvs_commit_file()
*
- * Get a commit log message by forking the user's editor.
- * Returns the message in a dynamically allocated string on success, NULL on
- * failure.
+ * Commit a single file.
*/
-static char*
-cvs_commit_getmsg(const char *dir)
+int
+cvs_commit_file(CVSFILE *cf, void *arg)
{
- int ret, fd, argc, fds[3];
- size_t len;
- char *argv[4], buf[16], path[MAXPATHLEN], *msg;
- FILE *fp;
- struct stat st1, st2;
+ char *repo, rcspath[MAXPATHLEN], fpath[MAXPATHLEN];
+ RCSFILE *rf;
+ struct cvsroot *root;
+ struct cvs_ent *entp;
+ struct ci_list *cl;
+
+ cl = (struct ci_list *)arg;
+
+ if (cf->cf_type == DT_DIR) {
+ if (cf->cf_cvstat != CVS_FST_UNKNOWN) {
+ root = cf->cf_ddat->cd_root;
+ if ((cf->cf_parent == NULL) ||
+ (root != cf->cf_parent->cf_ddat->cd_root)) {
+ cvs_connect(root);
+ }
- msg = NULL;
- fds[0] = -1;
- fds[1] = -1;
- fds[2] = -1;
- strlcpy(path, CVS_COMMIT_FTMPL, sizeof(path));
- argc = 0;
- argv[argc++] = cvs_editor;
- argv[argc++] = path;
- argv[argc] = NULL;
-
- if ((fd = mkstemp(path)) == -1) {
- cvs_log(LP_ERRNO, "failed to create temporary file");
- return (NULL);
- }
+ cvs_senddir(root, cf);
+ }
- fp = fdopen(fd, "w");
- if (fp == NULL) {
- cvs_log(LP_ERRNO, "failed to fdopen");
- } else {
- fprintf(fp,
- "\n%s %s\n%s Enter Log. Lines beginning with `%s' are "
- "removed automatically\n%s\n%s Commiting in %s\n"
- "%s\n%s Modified Files:\n",
- CVS_COMMIT_LOGPREFIX, CVS_COMMIT_LOGLINE,
- CVS_COMMIT_LOGPREFIX, CVS_COMMIT_LOGPREFIX,
- CVS_COMMIT_LOGPREFIX, CVS_COMMIT_LOGPREFIX,
- dir, CVS_COMMIT_LOGPREFIX, CVS_COMMIT_LOGPREFIX);
-
- /* XXX list files here */
-
- fprintf(fp, "%s %s\n", CVS_COMMIT_LOGPREFIX,
- CVS_COMMIT_LOGLINE);
+ return (0);
}
- (void)fflush(fp);
-
- if (fstat(fd, &st1) == -1) {
- cvs_log(LP_ERRNO, "failed to stat log message file");
+ else
+ root = cf->cf_parent->cf_ddat->cd_root;
- (void)fclose(fp);
- if (unlink(path) == -1)
- cvs_log(LP_ERRNO, "failed to unlink log file %s", path);
- return (NULL);
+ rf = NULL;
+ if (cf->cf_parent != NULL) {
+ repo = cf->cf_parent->cf_ddat->cd_repo;
+ }
+ else {
+ repo = NULL;
}
- for (;;) {
- ret = cvs_exec(argc, argv, fds);
- if (ret == -1)
- break;
- if (fstat(fd, &st2) == -1) {
- cvs_log(LP_ERRNO, "failed to stat log message file");
- break;
- }
-
- if (st2.st_mtime != st1.st_mtime)
- break;
-
- /* nothing was entered */
- fprintf(stderr,
- "Log message unchanged or not specified\na)bort, "
- "c)ontinue, e)dit, !)reuse this message unchanged "
- "for remaining dirs\nAction: (continue) ");
+ entp = cvs_ent_getent(fpath);
+ if (entp == NULL)
+ return (-1);
- if (fgets(buf, sizeof(buf), stdin) == NULL) {
- cvs_log(LP_ERRNO, "failed to read from standard input");
- break;
+ if ((cf->cf_cvstat == CVS_FST_ADDED) ||
+ (cf->cf_cvstat == CVS_FST_MODIFIED)) {
+ if ((root->cr_method != CVS_METHOD_LOCAL) &&
+ (cvs_sendentry(root, entp) < 0)) {
+ cvs_ent_free(entp);
+ return (-1);
}
- len = strlen(buf);
- if ((len == 0) || (len > 2)) {
- fprintf(stderr, "invalid input\n");
- continue;
- }
- else if (buf[0] == 'a') {
- cvs_log(LP_ERR, "aborted by user");
- break;
- } else if ((buf[0] == '\n') || (buf[0] == 'c')) {
- /* empty message */
- msg = strdup("");
- break;
- } else if (ret == 'e')
- continue;
- else if (ret == '!') {
- /* XXX do something */
- }
+ cvs_sendreq(root, CVS_REQ_MODIFIED, CVS_FILE_NAME(cf));
+ cvs_sendfile(root, fpath);
}
- (void)fclose(fp);
- (void)close(fd);
+ snprintf(rcspath, sizeof(rcspath), "%s/%s/%s%s",
+ root->cr_dir, repo, fpath, RCS_FILE_EXT);
- if (unlink(path) == -1)
- cvs_log(LP_ERRNO, "failed to unlink log file %s", path);
+ cvs_ent_free(entp);
- return (msg);
+ return (0);
}