[BACK]Return to req.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cvs

Annotation of src/usr.bin/cvs/req.c, Revision 1.9

1.9     ! jfb         1: /*     $OpenBSD: req.c,v 1.8 2004/12/19 17:32:55 jfb Exp $     */
1.1       jfb         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:
1.9     ! jfb        58: static int  cvs_req_set        (int, char *);
1.1       jfb        59: static int  cvs_req_root       (int, char *);
1.4       jfb        60: static int  cvs_req_validreq   (int, char *);
                     61: static int  cvs_req_validresp  (int, char *);
1.1       jfb        62: static int  cvs_req_directory  (int, char *);
1.5       jfb        63: static int  cvs_req_case       (int, char *);
1.2       jfb        64: static int  cvs_req_argument   (int, char *);
1.3       jfb        65: static int  cvs_req_globalopt  (int, char *);
1.8       jfb        66: static int  cvs_req_gzipstream (int, char *);
1.1       jfb        67: static int  cvs_req_version    (int, char *);
                     68:
                     69:
                     70: struct cvs_reqhdlr {
                     71:        int (*hdlr)(int, char *);
                     72: } cvs_req_swtab[CVS_REQ_MAX + 1] = {
                     73:        { NULL               },
                     74:        { cvs_req_root       },
1.4       jfb        75:        { cvs_req_validreq   },
                     76:        { cvs_req_validresp  },
1.1       jfb        77:        { cvs_req_directory  },
                     78:        { NULL               },
                     79:        { NULL               },
                     80:        { NULL               },
                     81:        { NULL               },
                     82:        { NULL               },
                     83:        { NULL               }, /* 10 */
                     84:        { NULL               },
                     85:        { NULL               },
                     86:        { NULL               },
                     87:        { NULL               },
                     88:        { NULL               },
                     89:        { NULL               },
                     90:        { NULL               },
1.5       jfb        91:        { cvs_req_case       },
1.1       jfb        92:        { NULL               },
1.2       jfb        93:        { cvs_req_argument   }, /* 20 */
                     94:        { cvs_req_argument   },
1.3       jfb        95:        { cvs_req_globalopt  },
1.8       jfb        96:        { cvs_req_gzipstream },
1.1       jfb        97:        { NULL               },
                     98:        { NULL               },
                     99:        { NULL               },
                    100:        { NULL               },
                    101:        { NULL               },
                    102:        { NULL               },
                    103:        { NULL               }, /* 30 */
                    104:        { NULL               },
                    105:        { NULL               },
                    106:        { NULL               },
1.9     ! jfb       107:        { cvs_req_set        },
1.1       jfb       108:        { NULL               },
                    109:        { NULL               },
                    110:        { NULL               },
                    111:        { NULL               },
                    112:        { NULL               },
                    113:        { NULL               }, /* 40 */
                    114:        { NULL               },
                    115:        { NULL               },
                    116:        { NULL               },
                    117:        { NULL               },
                    118:        { NULL               },
                    119:        { NULL               },
                    120:        { NULL               },
                    121:        { NULL               },
                    122:        { NULL               },
                    123:        { NULL               }, /* 50 */
                    124:        { NULL               },
                    125:        { NULL               },
                    126:        { NULL               },
                    127:        { NULL               },
                    128:        { NULL               },
                    129:        { NULL               },
                    130:        { NULL               },
                    131:        { NULL               },
                    132:        { NULL               },
                    133:        { NULL               }, /* 60 */
                    134:        { NULL               },
                    135:        { NULL               },
                    136:        { NULL               },
                    137:        { NULL               },
                    138:        { NULL               },
                    139:        { NULL               },
                    140:        { NULL               },
                    141:        { NULL               },
                    142:        { cvs_req_version    },
                    143: };
                    144:
                    145:
                    146:
                    147: /*
1.2       jfb       148:  * Argument array built by `Argument' and `Argumentx' requests.
                    149:  */
                    150:
                    151: static char *cvs_req_args[CVS_PROTO_MAXARG];
                    152: static int   cvs_req_nargs = 0;
                    153:
                    154:
                    155: /*
1.1       jfb       156:  * cvs_req_handle()
                    157:  *
                    158:  * Generic request handler dispatcher.  The handler expects the first line
                    159:  * of the command as single argument.
                    160:  * Returns the return value of the command on success, or -1 on failure.
                    161:  */
                    162: int
                    163: cvs_req_handle(char *line)
                    164: {
                    165:        char *cp, *cmd;
                    166:        struct cvs_req *req;
                    167:
                    168:        cmd = line;
                    169:
                    170:        cp = strchr(cmd, ' ');
                    171:        if (cp != NULL)
                    172:                *(cp++) = '\0';
                    173:
                    174:        req = cvs_req_getbyname(cmd);
                    175:        if (req == NULL)
                    176:                return (-1);
                    177:        else if (cvs_req_swtab[req->req_id].hdlr == NULL) {
                    178:                cvs_log(LP_ERRNO, "handler for `%s' not implemented", cmd);
                    179:                return (-1);
                    180:        }
                    181:
                    182:        return (*cvs_req_swtab[req->req_id].hdlr)(req->req_id, cp);
                    183: }
                    184:
                    185:
                    186: static int
                    187: cvs_req_root(int reqid, char *line)
                    188: {
                    189:
1.9     ! jfb       190:        return (0);
        !           191: }
        !           192:
        !           193:
        !           194: static int
        !           195: cvs_req_set(int reqid, char *line)
        !           196: {
        !           197:        char *cp;
        !           198:
        !           199:        cp = strchr(line, '=');
        !           200:        if (cp == NULL) {
        !           201:                cvs_log(LP_ERR, "error in Set request "
        !           202:                    "(no = in variable assignment)");
        !           203:                return (-1);
        !           204:        }
        !           205:
        !           206:        if (cvs_var_set(line, cp) < 0)
        !           207:                return (-1);
1.4       jfb       208:        return (0);
                    209: }
                    210:
                    211:
                    212: static int
                    213: cvs_req_validreq(int reqid, char *line)
                    214: {
                    215:        char *vreq;
                    216:
                    217:        vreq = cvs_req_getvalid();
                    218:        if (vreq == NULL)
                    219:                return (-1);
                    220:
                    221:        cvs_sendresp(CVS_RESP_VALIDREQ, vreq);
                    222:
                    223:        return (0);
                    224: }
                    225:
                    226: static int
                    227: cvs_req_validresp(int reqid, char *line)
                    228: {
                    229:        char *sp, *ep;
                    230:        struct cvs_resp *resp;
1.1       jfb       231:
1.4       jfb       232:        sp = line;
                    233:        do {
                    234:                ep = strchr(sp, ' ');
                    235:                if (ep != NULL)
                    236:                        *(ep++) = '\0';
                    237:
                    238:                resp = cvs_resp_getbyname(sp);
                    239:                if (resp != NULL)
                    240:                        ;
                    241:
                    242:                if (ep != NULL)
                    243:                        sp = ep + 1;
                    244:        } while (ep != NULL);
1.1       jfb       245:
                    246:        return (0);
                    247: }
                    248:
                    249: static int
                    250: cvs_req_directory(int reqid, char *line)
                    251: {
                    252:
1.5       jfb       253:        return (0);
                    254: }
                    255:
                    256: /*
                    257:  * cvs_req_case()
                    258:  *
                    259:  * Handler for the `Case' requests, which toggles case sensitivity ON or OFF
                    260:  */
                    261: static int
                    262: cvs_req_case(int reqid, char *line)
                    263: {
                    264:        cvs_nocase = 1;
1.2       jfb       265:        return (0);
                    266: }
                    267:
                    268:
                    269: static int
                    270: cvs_req_argument(int reqid, char *line)
                    271: {
                    272:        char *nap;
                    273:
                    274:        if (cvs_req_nargs == CVS_PROTO_MAXARG) {
                    275:                cvs_log(LP_ERR, "too many arguments");
                    276:                return (-1);
                    277:        }
                    278:
                    279:        if (reqid == CVS_REQ_ARGUMENT) {
                    280:                cvs_req_args[cvs_req_nargs] = strdup(line);
                    281:                if (cvs_req_args[cvs_req_nargs] == NULL) {
                    282:                        cvs_log(LP_ERRNO, "failed to copy argument");
                    283:                        return (-1);
                    284:                }
                    285:                cvs_req_nargs++;
1.6       deraadt   286:        } else if (reqid == CVS_REQ_ARGUMENTX) {
1.2       jfb       287:                if (cvs_req_nargs == 0)
                    288:                        cvs_log(LP_WARN, "no argument to append to");
                    289:                else {
                    290:                        asprintf(&nap, "%s%s", cvs_req_args[cvs_req_nargs - 1],
                    291:                            line);
                    292:                        if (nap == NULL) {
                    293:                                cvs_log(LP_ERRNO,
                    294:                                    "failed to append to argument");
                    295:                                return (-1);
                    296:                        }
                    297:                        free(cvs_req_args[cvs_req_nargs - 1]);
                    298:                        cvs_req_args[cvs_req_nargs - 1] = nap;
                    299:                }
1.3       jfb       300:        }
                    301:
                    302:        return (0);
                    303: }
                    304:
                    305:
                    306: static int
                    307: cvs_req_globalopt(int reqid, char *line)
                    308: {
                    309:        if ((*line != '-') || (*(line + 2) != '\0')) {
                    310:                cvs_log(LP_ERR,
                    311:                    "invalid `Global_option' request format");
                    312:                return (-1);
                    313:        }
                    314:
                    315:        switch (*(line + 1)) {
                    316:        case 'l':
                    317:                cvs_nolog = 1;
                    318:                break;
                    319:        case 'n':
                    320:                break;
                    321:        case 'Q':
                    322:                verbosity = 0;
                    323:                break;
                    324:        case 'q':
                    325:                if (verbosity > 1)
                    326:                        verbosity = 1;
                    327:                break;
                    328:        case 'r':
                    329:                cvs_readonly = 1;
                    330:                break;
                    331:        case 't':
                    332:                cvs_trace = 1;
                    333:                break;
                    334:        default:
                    335:                cvs_log(LP_ERR, "unknown global option `%s'", line);
                    336:                return (-1);
1.2       jfb       337:        }
1.8       jfb       338:
                    339:        return (0);
                    340: }
                    341:
                    342:
                    343: /*
                    344:  * cvs_req_gzipstream()
                    345:  *
                    346:  * Handler for the `Gzip-stream' request, which enables compression at the
                    347:  * level given along with the request.  After this request has been processed,
                    348:  * all further connection data should be compressed.
                    349:  */
                    350:
                    351: static int
                    352: cvs_req_gzipstream(int reqid, char *line)
                    353: {
                    354:        char *ep;
                    355:        long val;
                    356:
                    357:        val = strtol(line, &ep, 10);
                    358:        if ((line[0] == '\0') || (*ep != '\0')) {
                    359:                cvs_log(LP_ERR, "invalid Gzip-stream level `%s'", line);
                    360:                return (-1);
                    361:        } else if ((errno == ERANGE) && ((val < 0) || (val > 9))) {
                    362:                cvs_log(LP_ERR, "Gzip-stream level %ld out of range", val);
                    363:                return (-1);
                    364:        }
                    365:
                    366:        cvs_compress = (int)val;
1.1       jfb       367:
                    368:        return (0);
                    369: }
                    370:
                    371:
                    372: static int
                    373: cvs_req_version(int reqid, char *line)
                    374: {
                    375:        cvs_printf("%s\n", CVS_VERSION);
                    376:        return (0);
                    377: }