Annotation of src/usr.bin/cvs/req.c, Revision 1.2
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 *);
59: static int cvs_req_directory (int, char *);
1.2 ! jfb 60: static int cvs_req_argument (int, char *);
1.1 jfb 61: static int cvs_req_version (int, char *);
62:
63:
64: struct cvs_reqhdlr {
65: int (*hdlr)(int, char *);
66: } cvs_req_swtab[CVS_REQ_MAX + 1] = {
67: { NULL },
68: { cvs_req_root },
69: { NULL },
70: { NULL },
71: { cvs_req_directory },
72: { NULL },
73: { NULL },
74: { NULL },
75: { NULL },
76: { NULL },
77: { NULL }, /* 10 */
78: { NULL },
79: { NULL },
80: { NULL },
81: { NULL },
82: { NULL },
83: { NULL },
84: { NULL },
85: { NULL },
86: { NULL },
1.2 ! jfb 87: { cvs_req_argument }, /* 20 */
! 88: { cvs_req_argument },
1.1 jfb 89: { NULL },
90: { NULL },
91: { NULL },
92: { NULL },
93: { NULL },
94: { NULL },
95: { NULL },
96: { NULL },
97: { NULL }, /* 30 */
98: { NULL },
99: { NULL },
100: { NULL },
101: { NULL },
102: { NULL },
103: { NULL },
104: { NULL },
105: { NULL },
106: { NULL },
107: { NULL }, /* 40 */
108: { NULL },
109: { NULL },
110: { NULL },
111: { NULL },
112: { NULL },
113: { NULL },
114: { NULL },
115: { NULL },
116: { NULL },
117: { NULL }, /* 50 */
118: { NULL },
119: { NULL },
120: { NULL },
121: { NULL },
122: { NULL },
123: { NULL },
124: { NULL },
125: { NULL },
126: { NULL },
127: { NULL }, /* 60 */
128: { NULL },
129: { NULL },
130: { NULL },
131: { NULL },
132: { NULL },
133: { NULL },
134: { NULL },
135: { NULL },
136: { cvs_req_version },
137: };
138:
139:
140:
141: /*
1.2 ! jfb 142: * Argument array built by `Argument' and `Argumentx' requests.
! 143: */
! 144:
! 145: static char *cvs_req_args[CVS_PROTO_MAXARG];
! 146: static int cvs_req_nargs = 0;
! 147:
! 148:
! 149:
! 150:
! 151:
! 152: /*
1.1 jfb 153: * cvs_req_handle()
154: *
155: * Generic request handler dispatcher. The handler expects the first line
156: * of the command as single argument.
157: * Returns the return value of the command on success, or -1 on failure.
158: */
159:
160: int
161: cvs_req_handle(char *line)
162: {
163: char *cp, *cmd;
164: struct cvs_req *req;
165:
166: cmd = line;
167:
168: cp = strchr(cmd, ' ');
169: if (cp != NULL)
170: *(cp++) = '\0';
171:
172: req = cvs_req_getbyname(cmd);
173: if (req == NULL)
174: return (-1);
175: else if (cvs_req_swtab[req->req_id].hdlr == NULL) {
176: cvs_log(LP_ERRNO, "handler for `%s' not implemented", cmd);
177: return (-1);
178: }
179:
180: return (*cvs_req_swtab[req->req_id].hdlr)(req->req_id, cp);
181: }
182:
183:
184:
185: static int
186: cvs_req_root(int reqid, char *line)
187: {
188:
189:
190:
191: return (0);
192: }
193:
194: static int
195: cvs_req_directory(int reqid, char *line)
196: {
197:
198:
1.2 ! jfb 199:
! 200: return (0);
! 201: }
! 202:
! 203:
! 204: static int
! 205: cvs_req_argument(int reqid, char *line)
! 206: {
! 207: char *nap;
! 208:
! 209: if (cvs_req_nargs == CVS_PROTO_MAXARG) {
! 210: cvs_log(LP_ERR, "too many arguments");
! 211: return (-1);
! 212: }
! 213:
! 214: if (reqid == CVS_REQ_ARGUMENT) {
! 215: cvs_req_args[cvs_req_nargs] = strdup(line);
! 216: if (cvs_req_args[cvs_req_nargs] == NULL) {
! 217: cvs_log(LP_ERRNO, "failed to copy argument");
! 218: return (-1);
! 219: }
! 220: cvs_req_nargs++;
! 221: }
! 222: else if (reqid == CVS_REQ_ARGUMENTX) {
! 223: if (cvs_req_nargs == 0)
! 224: cvs_log(LP_WARN, "no argument to append to");
! 225: else {
! 226: asprintf(&nap, "%s%s", cvs_req_args[cvs_req_nargs - 1],
! 227: line);
! 228: if (nap == NULL) {
! 229: cvs_log(LP_ERRNO,
! 230: "failed to append to argument");
! 231: return (-1);
! 232: }
! 233: free(cvs_req_args[cvs_req_nargs - 1]);
! 234: cvs_req_args[cvs_req_nargs - 1] = nap;
! 235: }
! 236: }
1.1 jfb 237:
238: return (0);
239: }
240:
241:
242: static int
243: cvs_req_version(int reqid, char *line)
244: {
245: cvs_printf("%s\n", CVS_VERSION);
246: return (0);
247: }