[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Cvs-cvs] Changes to ccvs/src/remove.c [signed-commits]
From: |
Derek Robert Price |
Subject: |
[Cvs-cvs] Changes to ccvs/src/remove.c [signed-commits] |
Date: |
Tue, 11 Oct 2005 22:46:50 -0400 |
Index: ccvs/src/remove.c
diff -u /dev/null ccvs/src/remove.c:1.63.2.1
--- /dev/null Wed Oct 12 02:46:50 2005
+++ ccvs/src/remove.c Wed Oct 12 02:46:37 2005
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 1986-2005 The Free Software Foundation, Inc.
+ *
+ * Portions Copyright (C) 1998-2005 Derek Price, Ximbiot <http://ximbiot.com>,
+ * and others.
+ *
+ * Portions Copyright (C) 1992, Brian Berliner and Jeff Polk
+ * Portions Copyright (C) 1989-1992, Brian Berliner
+ *
+ * You may distribute under the terms of the GNU General Public License as
+ * specified in the README file that comes with the CVS source distribution.
+ *
+ * Remove a File
+ *
+ * Removes entries from the present version. The entries will be removed from
+ * the RCS repository upon the next "commit".
+ *
+ * "remove" accepts no options, only file names that are to be removed. The
+ * file must not exist in the current directory for "remove" to work
+ * correctly.
+ */
+
+#include "cvs.h"
+
+#ifdef CLIENT_SUPPORT
+static int remove_force_fileproc (void *callerdat,
+ struct file_info *finfo);
+#endif
+static int remove_fileproc (void *callerdat, struct file_info *finfo);
+static Dtype remove_dirproc (void *callerdat, const char *dir,
+ const char *repos, const char *update_dir,
+ List *entries);
+
+static int force;
+static int local;
+static int removed_files;
+static int existing_files;
+
+static const char *const remove_usage[] =
+{
+ "Usage: %s %s [-flR] [files...]\n",
+ "\t-f\tDelete the file before removing it.\n",
+ "\t-l\tProcess this directory only (not recursive).\n",
+ "\t-R\tProcess directories recursively.\n",
+ "(Specify the --help global option for a list of other help options)\n",
+ NULL
+};
+
+int
+cvsremove (int argc, char **argv)
+{
+ int c, err;
+
+ if (argc == -1)
+ usage (remove_usage);
+
+ optind = 0;
+ while ((c = getopt (argc, argv, "+flR")) != -1)
+ {
+ switch (c)
+ {
+ case 'f':
+ force = 1;
+ break;
+ case 'l':
+ local = 1;
+ break;
+ case 'R':
+ local = 0;
+ break;
+ case '?':
+ default:
+ usage (remove_usage);
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ wrap_setup ();
+
+#ifdef CLIENT_SUPPORT
+ if (current_parsed_root->isremote) {
+ /* Call expand_wild so that the local removal of files will
+ work. It's ok to do it always because we have to send the
+ file names expanded anyway. */
+ expand_wild (argc, argv, &argc, &argv);
+
+ if (force)
+ {
+ if (!noexec)
+ {
+ start_recursion (remove_force_fileproc, NULL, NULL, NULL,
+ NULL, argc, argv, local, W_LOCAL,
+ 0, CVS_LOCK_NONE, NULL, 0, NULL);
+ }
+ /* else FIXME should probably act as if the file doesn't exist
+ in doing the following checks. */
+ }
+
+ start_server ();
+ ign_setup ();
+ if (local)
+ send_arg("-l");
+ send_arg ("--");
+ /* FIXME: Can't we set SEND_NO_CONTENTS here? Needs investigation. */
+ send_files (argc, argv, local, 0, 0, SIGN_NEVER, NULL, NULL);
+ send_file_names (argc, argv, 0);
+ free_names (&argc, argv);
+ send_to_server ("remove\012", 0);
+ return get_responses_and_close ();
+ }
+#endif
+
+ /* start the recursion processor */
+ err = start_recursion (remove_fileproc, NULL, remove_dirproc, NULL,
+ NULL, argc, argv, local, W_LOCAL, 0,
+ CVS_LOCK_READ, NULL, 1, NULL);
+
+ if (removed_files && !really_quiet)
+ error (0, 0, "use `%s commit' to remove %s permanently", program_name,
+ (removed_files == 1) ? "this file" : "these files");
+
+ if (existing_files)
+ error (0, 0,
+ ((existing_files == 1) ?
+ "%d file exists; remove it first" :
+ "%d files exist; remove them first"),
+ existing_files);
+
+ return (err);
+}
+
+#ifdef CLIENT_SUPPORT
+
+/*
+ * This is called via start_recursion if we are running as the client
+ * and the -f option was used. We just physically remove the file.
+ */
+
+/*ARGSUSED*/
+static int
+remove_force_fileproc (void *callerdat, struct file_info *finfo)
+{
+ if (CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno))
+ error (0, errno, "unable to remove %s", finfo->fullname);
+ return 0;
+}
+
+#endif
+
+/*
+ * remove the file, only if it has already been physically removed
+ */
+/* ARGSUSED */
+static int
+remove_fileproc (void *callerdat, struct file_info *finfo)
+{
+ Vers_TS *vers;
+
+ if (force)
+ {
+ if (!noexec)
+ {
+ if ( CVS_UNLINK (finfo->file) < 0 && ! existence_error (errno))
+ {
+ error (0, errno, "unable to remove %s", finfo->fullname);
+ }
+ }
+ /* else FIXME should probably act as if the file doesn't exist
+ in doing the following checks. */
+ }
+
+ vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
+
+ if (vers->ts_user != NULL)
+ {
+ existing_files++;
+ if (!quiet)
+ error (0, 0, "file `%s' still in working directory",
+ finfo->fullname);
+ }
+ else if (vers->vn_user == NULL)
+ {
+ if (!quiet)
+ error (0, 0, "nothing known about `%s'", finfo->fullname);
+ }
+ else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
+ {
+ char *fname;
+
+ /*
+ * It's a file that has been added, but not commited yet. So,
+ * remove the ,t file for it and scratch it from the
+ * entries file. */
+ Scratch_Entry (finfo->entries, finfo->file);
+ fname = Xasprintf ("%s/%s%s", CVSADM, finfo->file, CVSEXT_LOG);
+ if (unlink_file (fname) < 0
+ && !existence_error (errno))
+ error (0, errno, "cannot remove %s", CVSEXT_LOG);
+ if (!quiet)
+ error (0, 0, "removed `%s'", finfo->fullname);
+
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ server_checked_in (finfo->file, finfo->update_dir,
finfo->repository);
+#endif
+ free (fname);
+ }
+ else if (vers->vn_user[0] == '-')
+ {
+ if (!quiet)
+ error (0, 0, "file `%s' already scheduled for removal",
+ finfo->fullname);
+ }
+ else if (vers->tag != NULL && isdigit ((unsigned char) *vers->tag))
+ {
+ /* Commit will just give an error, and so there seems to be
+ little reason to allow the remove. I mean, conflicts that
+ arise out of parallel development are one thing, but conflicts
+ that arise from sticky tags are quite another.
+
+ I would have thought that non-branch sticky tags should be the
+ same but at least now, removing a file with a non-branch sticky
+ tag means to delete the tag from the file. I'm not sure that
+ is a good behavior, but until it is changed, we need to allow
+ it. */
+ error (0, 0, "\
+cannot remove file `%s' which has a numeric sticky tag of `%s'",
+ finfo->fullname, vers->tag);
+ }
+ else if (vers->date != NULL)
+ {
+ /* Commit will just give an error, and so there seems to be
+ little reason to allow the remove. */
+ error (0, 0, "\
+cannot remove file `%s' which has a sticky date of `%s'",
+ finfo->fullname, vers->date);
+ }
+ else
+ {
+ char *fname;
+
+ /* Re-register it with a negative version number. */
+ fname = Xasprintf ("-%s", vers->vn_user);
+ Register (finfo->entries, finfo->file, fname, vers->ts_rcs,
+ vers->options, vers->tag, vers->date, vers->ts_conflict);
+ if (!quiet)
+ error (0, 0, "scheduling `%s' for removal", finfo->fullname);
+ removed_files++;
+
+#ifdef SERVER_SUPPORT
+ if (server_active)
+ server_checked_in (finfo->file, finfo->update_dir,
finfo->repository);
+#endif
+ free (fname);
+ }
+
+ freevers_ts (&vers);
+ return (0);
+}
+
+
+
+/*
+ * Print a warm fuzzy message
+ */
+/* ARGSUSED */
+static Dtype
+remove_dirproc (void *callerdat, const char *dir, const char *repos,
+ const char *update_dir, List *entries)
+{
+ if (!quiet)
+ error (0, 0, "Removing %s", update_dir);
+ return (R_PROCESS);
+}
- [Cvs-cvs] Changes to ccvs/src/remove.c [signed-commits],
Derek Robert Price <=