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