Annotation of src/usr.bin/cvs/req.c, Revision 1.5
1.1 jfb 1: /* $OpenBSD$ */
2: /*
3: * Copyright (c) 2004 Jean-Francois Brousseau <jfb@openbsd.org>
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: *
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. The name of the author may not be used to endorse or promote products
13: * derived from this software without specific prior written permission.
14: *
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27:
28: #include <sys/types.h>
29: #include <sys/stat.h>
30:
31: #include <fcntl.h>
32: #include <stdio.h>
33: #include <errno.h>
34: #include <stdlib.h>
35: #include <unistd.h>
36: #include <signal.h>
37: #include <string.h>
38: #include <sysexits.h>
39: #ifdef CVS_ZLIB
40: #include <zlib.h>
41: #endif
42:
43: #include "buf.h"
44: #include "cvs.h"
45: #include "log.h"
46: #include "file.h"
47: #include "proto.h"
48:
49:
50: extern int verbosity;
51: extern int cvs_compress;
52: extern char *cvs_rsh;
53: extern int cvs_trace;
54: extern int cvs_nolog;
55: extern int cvs_readonly;
56:
57:
58: static int cvs_req_root (int, char *);
1.4 jfb 59: static int cvs_req_validreq (int, char *);
60: static int cvs_req_validresp (int, char *);
1.1 jfb 61: static int cvs_req_directory (int, char *);
1.5 ! jfb 62: static int cvs_req_case (int, char *);
1.2 jfb 63: static int cvs_req_argument (int, char *);
1.3 jfb 64: static int cvs_req_globalopt (int, char *);
1.1 jfb 65: static int cvs_req_version (int, char *);
66:
67:
68: struct cvs_reqhdlr {
69: int (*hdlr)(int, char *);
70: } cvs_req_swtab[CVS_REQ_MAX + 1] = {
71: { NULL },
72: { cvs_req_root },
1.4 jfb 73: { cvs_req_validreq },
74: { cvs_req_validresp },
1.1 jfb 75: { cvs_req_directory },
76: { NULL },
77: { NULL },
78: { NULL },
79: { NULL },
80: { NULL },
81: { NULL }, /* 10 */
82: { NULL },
83: { NULL },
84: { NULL },
85: { NULL },
86: { NULL },
87: { NULL },
88: { NULL },
1.5 ! jfb 89: { cvs_req_case },
1.1 jfb 90: { NULL },
1.2 jfb 91: { cvs_req_argument }, /* 20 */
92: { cvs_req_argument },
1.3 jfb 93: { cvs_req_globalopt },
1.1 jfb 94: { NULL },
95: { NULL },
96: { NULL },
97: { NULL },
98: { NULL },
99: { NULL },
100: { NULL },
101: { NULL }, /* 30 */
102: { NULL },
103: { NULL },
104: { NULL },
105: { NULL },
106: { NULL },
107: { NULL },
108: { NULL },
109: { NULL },
110: { NULL },
111: { NULL }, /* 40 */
112: { NULL },
113: { NULL },
114: { NULL },
115: { NULL },
116: { NULL },
117: { NULL },
118: { NULL },
119: { NULL },
120: { NULL },
121: { NULL }, /* 50 */
122: { NULL },
123: { NULL },
124: { NULL },
125: { NULL },
126: { NULL },
127: { NULL },
128: { NULL },
129: { NULL },
130: { NULL },
131: { NULL }, /* 60 */
132: { NULL },
133: { NULL },
134: { NULL },
135: { NULL },
136: { NULL },
137: { NULL },
138: { NULL },
139: { NULL },
140: { cvs_req_version },
141: };
142:
143:
144:
145: /*
1.2 jfb 146: * Argument array built by `Argument' and `Argumentx' requests.
147: */
148:
149: static char *cvs_req_args[CVS_PROTO_MAXARG];
150: static int cvs_req_nargs = 0;
151:
152:
153:
154:
155:
156: /*
1.1 jfb 157: * cvs_req_handle()
158: *
159: * Generic request handler dispatcher. The handler expects the first line
160: * of the command as single argument.
161: * Returns the return value of the command on success, or -1 on failure.
162: */
163:
164: int
165: cvs_req_handle(char *line)
166: {
167: char *cp, *cmd;
168: struct cvs_req *req;
169:
170: cmd = line;
171:
172: cp = strchr(cmd, ' ');
173: if (cp != NULL)
174: *(cp++) = '\0';
175:
176: req = cvs_req_getbyname(cmd);
177: if (req == NULL)
178: return (-1);
179: else if (cvs_req_swtab[req->req_id].hdlr == NULL) {
180: cvs_log(LP_ERRNO, "handler for `%s' not implemented", cmd);
181: return (-1);
182: }
183:
184: return (*cvs_req_swtab[req->req_id].hdlr)(req->req_id, cp);
185: }
186:
187:
188:
189: static int
190: cvs_req_root(int reqid, char *line)
191: {
192:
1.4 jfb 193: return (0);
194: }
195:
196:
197: static int
198: cvs_req_validreq(int reqid, char *line)
199: {
200: char *vreq;
201:
202: vreq = cvs_req_getvalid();
203: if (vreq == NULL)
204: return (-1);
205:
206: cvs_sendresp(CVS_RESP_VALIDREQ, vreq);
207:
208: return (0);
209: }
210:
211: static int
212: cvs_req_validresp(int reqid, char *line)
213: {
214: char *sp, *ep;
215: struct cvs_resp *resp;
1.1 jfb 216:
1.4 jfb 217: sp = line;
218: do {
219: ep = strchr(sp, ' ');
220: if (ep != NULL)
221: *(ep++) = '\0';
222:
223: resp = cvs_resp_getbyname(sp);
224: if (resp != NULL)
225: ;
226:
227: if (ep != NULL)
228: sp = ep + 1;
229: } while (ep != NULL);
1.1 jfb 230:
231: return (0);
232: }
233:
234: static int
235: cvs_req_directory(int reqid, char *line)
236: {
237:
238:
1.2 jfb 239:
1.5 ! jfb 240: return (0);
! 241: }
! 242:
! 243: /*
! 244: * cvs_req_case()
! 245: *
! 246: * Handler for the `Case' requests, which toggles case sensitivity ON or OFF
! 247: */
! 248:
! 249: static int
! 250: cvs_req_case(int reqid, char *line)
! 251: {
! 252: cvs_nocase = 1;
1.2 jfb 253: return (0);
254: }
255:
256:
257: static int
258: cvs_req_argument(int reqid, char *line)
259: {
260: char *nap;
261:
262: if (cvs_req_nargs == CVS_PROTO_MAXARG) {
263: cvs_log(LP_ERR, "too many arguments");
264: return (-1);
265: }
266:
267: if (reqid == CVS_REQ_ARGUMENT) {
268: cvs_req_args[cvs_req_nargs] = strdup(line);
269: if (cvs_req_args[cvs_req_nargs] == NULL) {
270: cvs_log(LP_ERRNO, "failed to copy argument");
271: return (-1);
272: }
273: cvs_req_nargs++;
274: }
275: else if (reqid == CVS_REQ_ARGUMENTX) {
276: if (cvs_req_nargs == 0)
277: cvs_log(LP_WARN, "no argument to append to");
278: else {
279: asprintf(&nap, "%s%s", cvs_req_args[cvs_req_nargs - 1],
280: line);
281: if (nap == NULL) {
282: cvs_log(LP_ERRNO,
283: "failed to append to argument");
284: return (-1);
285: }
286: free(cvs_req_args[cvs_req_nargs - 1]);
287: cvs_req_args[cvs_req_nargs - 1] = nap;
288: }
1.3 jfb 289: }
290:
291: return (0);
292: }
293:
294:
295: static int
296: cvs_req_globalopt(int reqid, char *line)
297: {
298: if ((*line != '-') || (*(line + 2) != '\0')) {
299: cvs_log(LP_ERR,
300: "invalid `Global_option' request format");
301: return (-1);
302: }
303:
304: switch (*(line + 1)) {
305: case 'l':
306: cvs_nolog = 1;
307: break;
308: case 'n':
309: break;
310: case 'Q':
311: verbosity = 0;
312: break;
313: case 'q':
314: if (verbosity > 1)
315: verbosity = 1;
316: break;
317: case 'r':
318: cvs_readonly = 1;
319: break;
320: case 't':
321: cvs_trace = 1;
322: break;
323: default:
324: cvs_log(LP_ERR, "unknown global option `%s'", line);
325: return (-1);
1.2 jfb 326: }
1.1 jfb 327:
328: return (0);
329: }
330:
331:
332: static int
333: cvs_req_version(int reqid, char *line)
334: {
335: cvs_printf("%s\n", CVS_VERSION);
336: return (0);
337: }