Annotation of src/usr.bin/cvs/release.c, Revision 1.42
1.42 ! deraadt 1: /* $OpenBSD: release.c,v 1.41 2009/03/21 11:18:45 joris Exp $ */
1.34 xsa 2: /*-
3: * Copyright (c) 2005-2007 Xavier Santolaria <xsa@openbsd.org>
1.1 xsa 4: *
1.34 xsa 5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 xsa 8: *
1.34 xsa 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 xsa 16: */
17:
1.34 xsa 18: #include <sys/stat.h>
19:
20: #include <string.h>
21: #include <unistd.h>
1.1 xsa 22:
23: #include "cvs.h"
1.34 xsa 24: #include "remote.h"
1.3 xsa 25:
1.34 xsa 26: void cvs_release_local(struct cvs_file *);
27:
28: static void release_check_files(struct cvs_file *);
1.1 xsa 29:
1.34 xsa 30: static int dflag = 0;
31: static int files_altered = 0;
1.7 jfb 32:
33: struct cvs_cmd cvs_cmd_release = {
1.38 tobias 34: CVS_OP_RELEASE, CVS_USE_WDIR, "release",
1.20 xsa 35: { "re", "rel" },
1.34 xsa 36: "Indicate that a Module is no longer in use",
37: "[-d] dir...",
1.7 jfb 38: "d",
39: NULL,
1.34 xsa 40: cvs_release
1.1 xsa 41: };
42:
1.34 xsa 43: int
44: cvs_release(int argc, char **argv)
1.1 xsa 45: {
46: int ch;
1.34 xsa 47: int flags;
48: struct cvs_recursion cr;
49:
50: flags = CR_REPO;
1.1 xsa 51:
1.34 xsa 52: while ((ch = getopt(argc, argv, cvs_cmd_release.cmd_opts)) != -1) {
1.1 xsa 53: switch (ch) {
54: case 'd':
55: dflag = 1;
56: break;
57: default:
1.34 xsa 58: fatal("%s", cvs_cmd_release.cmd_synopsis);
1.1 xsa 59: }
60: }
61:
62: argc -= optind;
63: argv += optind;
64:
65: if (argc == 0)
1.34 xsa 66: fatal("%s", cvs_cmd_release.cmd_synopsis);
1.1 xsa 67:
1.34 xsa 68: cr.enterdir = NULL;
69: cr.leavedir = NULL;
70:
71: if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
72: cvs_client_connect_to_server();
73: cr.fileproc = cvs_client_sendfile;
1.1 xsa 74:
1.27 xsa 75: if (dflag == 1)
1.34 xsa 76: cvs_client_send_request("Argument -d");
77: } else
78: cr.fileproc = cvs_release_local;
79:
80: cr.flags = flags;
81:
82: cvs_file_run(argc, argv, &cr);
83:
84: if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
85: cvs_client_send_files(argv, argc);
86: cvs_client_senddir(".");
87: cvs_client_send_request("release");
88: cvs_client_get_responses();
1.11 joris 89: }
1.34 xsa 90:
1.1 xsa 91: return (0);
92: }
93:
1.34 xsa 94: void
95: cvs_release_local(struct cvs_file *cf)
1.1 xsa 96: {
1.34 xsa 97: struct stat st;
98: struct cvs_recursion cr;
1.42 ! deraadt 99: char *wdir, cwd[PATH_MAX];
1.34 xsa 100: char *arg = ".";
101: int saved_noexec;
102:
103: if (cf->file_type == CVS_FILE)
104: return;
1.1 xsa 105:
1.34 xsa 106: cvs_log(LP_TRACE, "cvs_release_local(%s)", cf->file_path);
1.1 xsa 107:
1.35 joris 108: cvs_file_classify(cf, cvs_directory_tag);
1.34 xsa 109:
110: if (cvs_server_active == 1) {
111: cvs_history_add(CVS_HISTORY_RELEASE, cf, NULL);
112: return;
113: }
1.1 xsa 114:
1.29 xsa 115: if ((wdir = getcwd(cwd, sizeof(cwd))) == NULL)
116: fatal("getcwd failed");
1.22 xsa 117:
1.34 xsa 118: if (cf->file_type == CVS_DIR) {
119: if (!strcmp(cf->file_name, "."))
120: return;
121:
122: /* chdir before updating the directory. */
123: cvs_chdir(cf->file_path, 0);
124:
125: if (stat(CVS_PATH_CVSDIR, &st) == -1 || !S_ISDIR(st.st_mode)) {
1.40 xsa 126: if (verbosity > 0)
127: cvs_log(LP_ERR, "no repository directory: %s",
128: cf->file_path);
1.34 xsa 129: return;
1.1 xsa 130: }
1.22 xsa 131: }
132:
1.39 xsa 133: /* Skip the interactive part if -Q is specified. */
134: if (verbosity == 0)
135: goto delete;
136:
1.34 xsa 137: saved_noexec = cvs_noexec;
138: cvs_noexec = 1;
1.22 xsa 139:
1.34 xsa 140: cr.enterdir = NULL;
141: cr.leavedir = NULL;
142: cr.fileproc = cvs_update_local;
143: cr.flags = CR_REPO | CR_RECURSE_DIRS;
144:
145: cvs_file_run(1, &arg, &cr);
146:
147: cvs_noexec = saved_noexec;
148:
149: cr.enterdir = NULL;
150: cr.leavedir = NULL;
151: cr.fileproc = release_check_files;
152: cr.flags = CR_RECURSE_DIRS;
1.22 xsa 153:
1.34 xsa 154: cvs_file_run(1, &arg, &cr);
1.22 xsa 155:
1.34 xsa 156: (void)printf("You have [%d] altered files in this repository.\n",
157: files_altered);
158: (void)printf("Are you sure you want to release %sdirectory `%s': ",
159: (dflag == 1) ? "(and delete) " : "", cf->file_path);
1.22 xsa 160:
1.34 xsa 161: if (cvs_yesno() == -1) {
162: (void)fprintf(stderr,
1.37 tobias 163: "** `%s' aborted by user choice.\n", cmdp->cmd_name);
1.22 xsa 164:
165: /* change back to original working dir */
1.25 xsa 166: cvs_chdir(wdir, 0);
1.22 xsa 167:
1.34 xsa 168: return;
1.22 xsa 169: }
170:
171: /* change back to original working dir */
1.25 xsa 172: cvs_chdir(wdir, 0);
1.22 xsa 173:
1.39 xsa 174: delete:
1.22 xsa 175: if (dflag == 1) {
1.34 xsa 176: if (cvs_rmdir(cf->file_path) != 0)
177: fatal("cvs_release_local: cvs_rmdir failed");
1.1 xsa 178: }
1.34 xsa 179: }
1.1 xsa 180:
1.34 xsa 181: static void
182: release_check_files(struct cvs_file *cf)
183: {
184: cvs_log(LP_TRACE, "release_check_files(%s)", cf->file_path);
185:
1.35 joris 186: cvs_file_classify(cf, cvs_directory_tag);
1.34 xsa 187:
188: if (cf->file_status == FILE_MERGE ||
189: cf->file_status == FILE_ADDED ||
190: cf->file_status == FILE_PATCH ||
191: cf->file_status == FILE_CONFLICT)
192: files_altered++;
1.1 xsa 193: }