summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Santolaria <xsa@cvs.openbsd.org>2005-05-11 15:31:55 +0000
committerXavier Santolaria <xsa@cvs.openbsd.org>2005-05-11 15:31:55 +0000
commitd7ca6c5ca122b38a9d5d58382a7238c4257a49e6 (patch)
tree7a69803a30081a81603ee2eb1c09f79c7415bdb7
parent3c9e07e88ef1a524a9f4bf0ff2ab59ceb2174103 (diff)
start for the `release' command, need more work; joris ok
-rw-r--r--usr.bin/cvs/release.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/usr.bin/cvs/release.c b/usr.bin/cvs/release.c
new file mode 100644
index 00000000000..065bbc8bd8b
--- /dev/null
+++ b/usr.bin/cvs/release.c
@@ -0,0 +1,188 @@
+/* $OpenBSD: release.c,v 1.1 2005/05/11 15:31:54 xsa Exp $ */
+/*
+ * Copyright (c) 2005 Xavier Santolaria <xsa@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.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "cvs.h"
+#include "log.h"
+#include "proto.h"
+
+
+static int cvs_release_options(char *, int, char **, int *);
+static int cvs_release_sendflags(struct cvsroot *);
+static int cvs_release_yesno(void);
+static int cvs_release_dir(CVSFILE *, void *);
+
+struct cvs_cmd_info cvs_release = {
+ cvs_release_options,
+ cvs_release_sendflags,
+ cvs_release_dir,
+ NULL, NULL, NULL,
+ CVS_REQ_RELEASE,
+ CVS_CMD_SENDDIR | CVS_CMD_SENDARGS2 | CVS_CMD_ALLOWSPEC
+};
+
+static int dflag; /* -d option */
+
+static int
+cvs_release_options(char *opt, int argc, char **argv, int *arg)
+{
+ int ch;
+
+ while ((ch = getopt(argc, argv, opt)) != -1) {
+ switch (ch) {
+ case 'd':
+ dflag = 1;
+ break;
+ default:
+ return (CVS_EX_USAGE);
+ }
+ }
+
+ argc -= optind;
+ argv += optind;
+ *arg = optind;
+
+ if (argc == 0)
+ return (CVS_EX_USAGE);
+
+ return (0);
+}
+
+static int
+cvs_release_sendflags(struct cvsroot *root)
+{
+ if (dflag && cvs_sendarg(root, "-d", 0) < 0)
+ return (CVS_EX_PROTO);
+
+ return (0);
+}
+
+/*
+ * cvs_release_yesno()
+ *
+ * Read from standart input for `y' or `Y' character.
+ * Returns 0 on success, or -1 on failure.
+ */
+static int
+cvs_release_yesno(void)
+{
+ int c, ret;
+
+ ret = 0;
+
+ fflush (stderr);
+ fflush (stdout);
+
+ if ((c = getchar()) != 'y' && c != 'Y')
+ ret = -1;
+ else
+ while (c != EOF && c != '\n')
+ c = getchar();
+
+ return (ret);
+}
+
+/*
+ * cvs_release_dir()
+ *
+ * Release specified directorie(s).
+ * Returns 0 on success, or -1 on failure.
+ */
+static int
+cvs_release_dir(CVSFILE *cdir, void *arg)
+{
+ int j, l;
+ char cdpath[MAXPATHLEN], dpath[MAXPATHLEN];
+ struct stat st;
+ struct cvsroot *root;
+
+ j = 0; /* number of altered files in the working copy */
+
+ root = CVS_DIR_ROOT(cdir);
+
+ cvs_file_getpath(cdir, dpath, sizeof(dpath));
+
+ l = snprintf(cdpath, sizeof(cdpath), "%s/" CVS_PATH_CVSDIR, dpath);
+ if (l == -1 || l >= (int)sizeof(cdpath)) {
+ errno = ENAMETOOLONG;
+ cvs_log(LP_ERRNO, "%s", cdpath);
+ return (-1);
+ }
+
+ if (cdir->cf_type == DT_DIR) {
+ if (!strcmp(CVS_FILE_NAME(cdir), "."))
+ return (0);
+ else {
+ /* test if dir has CVS/ directory */
+ if (stat(cdpath, &st) == -1) {
+ cvs_log(LP_ERR,
+ "no repository directory: %s", dpath);
+ return (0);
+ }
+ }
+
+ if (root->cr_method != CVS_METHOD_LOCAL) {
+
+ /* XXX run cvs_update() w/out updating files */
+
+ printf("You have [%d] altered files in "
+ "this repository.\n", j);
+ printf("Are you sure you want to release "
+ "%sdirectory `%s': ",
+ dflag ? "(and delete) " : "", dpath);
+
+ if (cvs_release_yesno() == -1) { /* No */
+ (void)fprintf(stderr,
+ "** `%s' aborted by user choice.\n",
+ cvs_command);
+ return (-1);
+ }
+
+ if (dflag == 1) {
+ if (unlink(dpath) == -1) {
+ cvs_log(LP_ERRNO,
+ "deletion of directory %s failed",
+ dpath);
+ return (-1);
+ }
+ }
+ }
+ } else {
+ cvs_log(LP_ERR, "no such directory: %s", dpath);
+ return (-1);
+ }
+
+ return (0);
+}