Annotation of src/usr.bin/cvs/remove.c, Revision 1.19
1.19 ! xsa 1: /* $OpenBSD: remove.c,v 1.18 2005/07/08 16:03:38 joris Exp $ */
1.1 xsa 2: /*
3: * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
4: * Copyright (c) 2004 Xavier Santolaria <xsa@openbsd.org>
5: * All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: *
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. The name of the author may not be used to endorse or promote products
14: * derived from this software without specific prior written permission.
15: *
16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
17: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
18: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
19: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26: */
27:
28: #include <sys/types.h>
29:
30: #include <errno.h>
1.2 jfb 31: #include <fcntl.h>
1.1 xsa 32: #include <stdio.h>
33: #include <stdlib.h>
34: #include <string.h>
35: #include <unistd.h>
36:
37: #include "cvs.h"
38: #include "log.h"
39: #include "proto.h"
40:
41:
42: extern char *__progname;
43:
44:
1.16 jfb 45: static int cvs_remove_init (struct cvs_cmd *, int, char **, int *);
1.18 joris 46: static int cvs_remove_remote (CVSFILE *, void *);
47: static int cvs_remove_local (CVSFILE *, void *);
1.1 xsa 48:
1.4 joris 49: static int force_remove = 0; /* -f option */
50:
1.16 jfb 51: struct cvs_cmd cvs_cmd_remove = {
52: CVS_OP_REMOVE, CVS_REQ_REMOVE, "remove",
53: { "rm", "delete" },
54: "Remove an entry from the repository",
55: "[-flR] [file ...]",
56: "flR",
1.4 joris 57: NULL,
1.16 jfb 58: CF_IGNORE | CF_RECURSE,
59: cvs_remove_init,
60: NULL,
1.18 joris 61: cvs_remove_remote,
62: cvs_remove_local,
1.16 jfb 63: NULL,
64: NULL,
1.4 joris 65: CVS_CMD_SENDDIR | CVS_CMD_SENDARGS2 | CVS_CMD_ALLOWSPEC
66: };
1.1 xsa 67:
1.13 xsa 68: static int
1.16 jfb 69: cvs_remove_init(struct cvs_cmd *cmd, int argc, char **argv, int *arg)
1.1 xsa 70: {
1.4 joris 71: int ch;
1.1 xsa 72:
1.16 jfb 73: while ((ch = getopt(argc, argv, cmd->cmd_opts)) != -1) {
1.1 xsa 74: switch (ch) {
75: case 'f':
1.3 xsa 76: force_remove = 1;
1.1 xsa 77: break;
78: case 'l':
1.16 jfb 79: cmd->file_flags &= ~CF_RECURSE;
1.1 xsa 80: break;
81: case 'R':
1.16 jfb 82: cmd->file_flags |= CF_RECURSE;
1.1 xsa 83: break;
84: default:
1.7 joris 85: return (CVS_EX_USAGE);
1.1 xsa 86: }
87: }
88:
89: argc -= optind;
90: argv += optind;
91:
1.4 joris 92: *arg = optind;
1.1 xsa 93: return (0);
94: }
95:
96:
1.13 xsa 97: static int
1.18 joris 98: cvs_remove_remote(CVSFILE *cf, void *arg)
1.1 xsa 99: {
100: int ret;
1.2 jfb 101: char fpath[MAXPATHLEN];
1.1 xsa 102: struct cvsroot *root;
103:
104: ret = 0;
105: root = CVS_DIR_ROOT(cf);
106:
107: if (cf->cf_type == DT_DIR) {
1.18 joris 108: if (cf->cf_cvstat == CVS_FST_UNKNOWN)
109: ret = cvs_sendreq(root, CVS_REQ_QUESTIONABLE,
110: CVS_FILE_NAME(cf));
111: else
112: ret = cvs_senddir(root, cf);
1.1 xsa 113:
1.18 joris 114: if (ret == -1)
115: ret = CVS_EX_PROTO;
1.1 xsa 116: return (ret);
117: }
118:
1.2 jfb 119: cvs_file_getpath(cf, fpath, sizeof(fpath));
120:
1.18 joris 121: /* if -f option is used, physically remove the file */
122: if ((force_remove == 1) && !cvs_noexec) {
123: if((unlink(fpath) == -1) && (errno != ENOENT)) {
124: cvs_log(LP_ERRNO,
125: "failed to unlink `%s'", fpath);
126: return (CVS_EX_FILE);
1.3 xsa 127: }
1.18 joris 128: }
129:
130: if (cvs_sendentry(root, cf) < 0)
131: return (CVS_EX_PROTO);
1.3 xsa 132:
1.18 joris 133: if (cf->cf_cvstat != CVS_FST_LOST && force_remove != 1) {
134: if (cvs_sendreq(root, CVS_REQ_MODIFIED,
135: CVS_FILE_NAME(cf)) < 0) {
1.10 xsa 136: return (CVS_EX_PROTO);
1.18 joris 137: }
1.17 joris 138:
1.18 joris 139: if (cvs_sendfile(root, fpath) < 0)
140: return (CVS_EX_PROTO);
141: }
1.11 xsa 142:
1.18 joris 143: return (0);
144: }
145:
146: static int
147: cvs_remove_local(CVSFILE *cf, void *arg)
148: {
1.19 ! xsa 149: if (cf->cf_type == DT_DIR) {
! 150: if (verbosity > 1)
! 151: cvs_log(LP_INFO, "Removing %s", cf->cf_name);
! 152: return (0);
! 153: }
! 154:
1.18 joris 155: cvs_log(LP_INFO, "scheduling file `%s' for removal", cf->cf_name);
156: cvs_log(LP_INFO, "use `%s commit' to remove this file permanently",
157: __progname);
1.1 xsa 158:
1.18 joris 159: return (0);
1.1 xsa 160: }