Annotation of src/usr.bin/cvs/release.c, Revision 1.37
1.37 ! tobias 1: /* $OpenBSD: release.c,v 1.36 2007/09/25 10:56:04 chl 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.34 xsa 34: CVS_OP_RELEASE, 0, "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.4 xsa 99: char *wdir, cwd[MAXPATHLEN];
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)) {
126: cvs_log(LP_ERR, "no repository directory: %s",
127: cf->file_path);
128: return;
1.1 xsa 129: }
1.22 xsa 130: }
131:
1.34 xsa 132: saved_noexec = cvs_noexec;
133: cvs_noexec = 1;
1.22 xsa 134:
1.34 xsa 135: cr.enterdir = NULL;
136: cr.leavedir = NULL;
137: cr.fileproc = cvs_update_local;
138: cr.flags = CR_REPO | CR_RECURSE_DIRS;
139:
140: cvs_file_run(1, &arg, &cr);
141:
142: cvs_noexec = saved_noexec;
143:
144: cr.enterdir = NULL;
145: cr.leavedir = NULL;
146: cr.fileproc = release_check_files;
147: cr.flags = CR_RECURSE_DIRS;
1.22 xsa 148:
1.34 xsa 149: cvs_file_run(1, &arg, &cr);
1.22 xsa 150:
1.34 xsa 151: (void)printf("You have [%d] altered files in this repository.\n",
152: files_altered);
153: (void)printf("Are you sure you want to release %sdirectory `%s': ",
154: (dflag == 1) ? "(and delete) " : "", cf->file_path);
1.22 xsa 155:
1.34 xsa 156: if (cvs_yesno() == -1) {
157: (void)fprintf(stderr,
1.37 ! tobias 158: "** `%s' aborted by user choice.\n", cmdp->cmd_name);
1.22 xsa 159:
160: /* change back to original working dir */
1.25 xsa 161: cvs_chdir(wdir, 0);
1.22 xsa 162:
1.34 xsa 163: return;
1.22 xsa 164: }
165:
166: /* change back to original working dir */
1.25 xsa 167: cvs_chdir(wdir, 0);
1.22 xsa 168:
169: if (dflag == 1) {
1.34 xsa 170: if (cvs_rmdir(cf->file_path) != 0)
171: fatal("cvs_release_local: cvs_rmdir failed");
1.1 xsa 172: }
1.34 xsa 173: }
1.1 xsa 174:
1.34 xsa 175: static void
176: release_check_files(struct cvs_file *cf)
177: {
178: cvs_log(LP_TRACE, "release_check_files(%s)", cf->file_path);
179:
1.35 joris 180: cvs_file_classify(cf, cvs_directory_tag);
1.34 xsa 181:
182: if (cf->file_status == FILE_MERGE ||
183: cf->file_status == FILE_ADDED ||
184: cf->file_status == FILE_PATCH ||
185: cf->file_status == FILE_CONFLICT)
186: files_altered++;
187: return;
1.1 xsa 188: }