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