1 /* $OpenBSD: watch.c,v 1.23 2017/06/01 08:08:24 joris Exp $ */
2 /*
3 * Copyright (c) 2005-2007 Xavier Santolaria <xsa@openbsd.org>
4 *
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.
8 *
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.
16 */
17
18 #include <string.h>
19 #include <unistd.h>
20
21 #include "cvs.h"
22 #include "remote.h"
23
24 #define W_COMMIT 0x01
25 #define W_EDIT 0x02
26 #define W_UNEDIT 0x04
27 #define W_ADD 0x08
28 #define W_REMOVE 0x10
29 #define W_ON 0x20
30 #define W_OFF 0x40
31 #define W_ALL (W_EDIT|W_COMMIT|W_UNEDIT)
32
33 static void cvs_watch_local(struct cvs_file *);
34 static void cvs_watchers_local(struct cvs_file *);
35
36 struct cvs_cmd cvs_cmd_watch = {
37 CVS_OP_WATCH, CVS_USE_WDIR, "watch",
38 { { 0 }, { 0 } },
39 "Set watches",
40 "on | off | add | remove [-lR] [-a action] [file ...]",
41 "a:lR",
42 NULL,
43 cvs_watch
44 };
45
46 struct cvs_cmd cvs_cmd_watchers = {
47 CVS_OP_WATCHERS, CVS_USE_WDIR, "watchers",
48 { { 0 }, { 0 } },
49 "See who is watching a file",
50 "[-lR] [file ...]",
51 "lR",
52 NULL,
53 cvs_watchers
54 };
55
56 int
cvs_watch(int argc,char ** argv)57 cvs_watch(int argc, char **argv)
58 {
59 int ch, flags;
60 struct cvs_recursion cr;
61 int watch_req = 0;
62 int watch_aflags = 0;
63
64 if (argc < 2)
65 fatal("%s", cvs_cmd_watch.cmd_synopsis);
66
67 if (strcmp(argv[1], "on") == 0)
68 watch_req |= W_ON;
69 else if (strcmp(argv[1], "off") == 0)
70 watch_req |= W_OFF;
71 else if (strcmp(argv[1], "add") == 0)
72 watch_req |= W_ADD;
73 else if (strcmp(argv[1], "remove") == 0)
74 watch_req |= W_REMOVE;
75 else
76 fatal("%s", cvs_cmd_watch.cmd_synopsis);
77
78 --argc;
79 ++argv;
80
81 flags = CR_RECURSE_DIRS;
82
83 while ((ch = getopt(argc, argv, cvs_cmd_watch.cmd_opts)) != -1) {
84 switch (ch) {
85 case 'a':
86 if (!(watch_req & (W_ADD|W_REMOVE)))
87 fatal("%s", cvs_cmd_watch.cmd_synopsis);
88
89 if (strcmp(optarg, "edit") == 0)
90 watch_aflags |= W_EDIT;
91 else if (strcmp(optarg, "unedit") == 0)
92 watch_aflags |= W_UNEDIT;
93 else if (strcmp(optarg, "commit") == 0)
94 watch_aflags |= W_COMMIT;
95 else if (strcmp(optarg, "all") == 0)
96 watch_aflags |= W_ALL;
97 else if (strcmp(optarg, "none") == 0)
98 watch_aflags &= ~W_ALL;
99 else
100 fatal("%s", cvs_cmd_watch.cmd_synopsis);
101 break;
102 case 'l':
103 flags &= ~CR_RECURSE_DIRS;
104 break;
105 case 'R':
106 flags |= CR_RECURSE_DIRS;
107 break;
108 default:
109 fatal("%s", cvs_cmd_watch.cmd_synopsis);
110 }
111 }
112
113 argc -= optind;
114 argv += optind;
115
116 if (watch_aflags == 0)
117 watch_aflags |= W_ALL;
118
119 cr.enterdir = NULL;
120 cr.leavedir = NULL;
121
122 if (cvsroot_is_remote()) {
123 cvs_client_connect_to_server();
124 cr.fileproc = cvs_client_sendfile;
125
126 if (watch_req & (W_ADD|W_REMOVE)) {
127 if (watch_aflags & W_EDIT)
128 cvs_client_send_request("Argument -a edit");
129
130 if (watch_aflags & W_UNEDIT)
131 cvs_client_send_request("Argument -a unedit");
132
133 if (watch_aflags & W_COMMIT)
134 cvs_client_send_request("Argument -a commit");
135
136 if (!(watch_aflags & W_ALL))
137 cvs_client_send_request("Argument -a none");
138 }
139
140 if (!(flags & CR_RECURSE_DIRS))
141 cvs_client_send_request("Argument -l");
142 } else {
143 cr.fileproc = cvs_watch_local;
144 }
145
146 cr.flags = flags;
147
148 cvs_file_run(argc, argv, &cr);
149
150 if (cvsroot_is_remote()) {
151 cvs_client_send_files(argv, argc);
152 cvs_client_senddir(".");
153
154 if (watch_req & (W_ADD|W_REMOVE))
155 cvs_client_send_request("watch-%s",
156 (watch_req & W_ADD) ? "add" : "remove");
157 else
158 cvs_client_send_request("watch-%s",
159 (watch_req & W_ON) ? "on" : "off");
160
161 cvs_client_get_responses();
162 }
163
164 return (0);
165 }
166
167 int
cvs_watchers(int argc,char ** argv)168 cvs_watchers(int argc, char **argv)
169 {
170 int ch;
171 int flags;
172 struct cvs_recursion cr;
173
174 flags = CR_RECURSE_DIRS;
175
176 while ((ch = getopt(argc, argv, cvs_cmd_watchers.cmd_opts)) != -1) {
177 switch (ch) {
178 case 'l':
179 flags &= ~CR_RECURSE_DIRS;
180 break;
181 case 'R':
182 flags |= CR_RECURSE_DIRS;
183 break;
184 default:
185 fatal("%s", cvs_cmd_watchers.cmd_synopsis);
186 }
187 }
188
189 argc -= optind;
190 argv += optind;
191
192 if (argc == 0)
193 fatal("%s", cvs_cmd_watchers.cmd_synopsis);
194
195 cr.enterdir = NULL;
196 cr.leavedir = NULL;
197
198 if (cvsroot_is_remote()) {
199 cvs_client_connect_to_server();
200 cr.fileproc = cvs_client_sendfile;
201
202 if (!(flags & CR_RECURSE_DIRS))
203 cvs_client_send_request("Argument -l");
204 } else {
205 cr.fileproc = cvs_watchers_local;
206 }
207
208 cr.flags = flags;
209
210 cvs_file_run(argc, argv, &cr);
211
212 if (cvsroot_is_remote()) {
213 cvs_client_send_files(argv, argc);
214 cvs_client_senddir(".");
215 cvs_client_send_request("watchers");
216 cvs_client_get_responses();
217 }
218
219 return (0);
220 }
221
222 static void
cvs_watch_local(struct cvs_file * cf)223 cvs_watch_local(struct cvs_file *cf)
224 {
225 }
226
227 static void
cvs_watchers_local(struct cvs_file * cf)228 cvs_watchers_local(struct cvs_file *cf)
229 {
230 }
231