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

Annotation of src/usr.bin/cvs/server.c, Revision 1.106

1.106   ! naddy       1: /*     $OpenBSD: server.c,v 1.105 2017/08/28 19:33:20 otto Exp $       */
1.1       jfb         2: /*
1.29      joris       3:  * Copyright (c) 2006 Joris Vink <joris@openbsd.org>
1.1       jfb         4:  *
1.29      joris       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.
1.1       jfb         8:  *
1.29      joris       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.
1.1       jfb        16:  */
                     17:
1.73      tobias     18: #include <sys/types.h>
1.55      otto       19: #include <sys/stat.h>
                     20:
                     21: #include <errno.h>
                     22: #include <fcntl.h>
                     23: #include <libgen.h>
1.68      tobias     24: #include <stdio.h>
1.55      otto       25: #include <stdlib.h>
                     26: #include <string.h>
                     27: #include <unistd.h>
1.1       jfb        28:
                     29: #include "cvs.h"
1.29      joris      30: #include "remote.h"
                     31:
                     32: struct cvs_resp cvs_responses[] = {
                     33:        /* this is what our server uses, the client should support it */
                     34:        { "Valid-requests",     1,      cvs_client_validreq, RESP_NEEDED },
                     35:        { "ok",                 0,      cvs_client_ok, RESP_NEEDED},
                     36:        { "error",              0,      cvs_client_error, RESP_NEEDED },
                     37:        { "E",                  0,      cvs_client_e, RESP_NEEDED },
                     38:        { "M",                  0,      cvs_client_m, RESP_NEEDED },
                     39:        { "Checked-in",         0,      cvs_client_checkedin, RESP_NEEDED },
                     40:        { "Updated",            0,      cvs_client_updated, RESP_NEEDED },
                     41:        { "Merged",             0,      cvs_client_merged, RESP_NEEDED },
                     42:        { "Removed",            0,      cvs_client_removed, RESP_NEEDED },
1.99      joris      43:        { "Remove-entry",       0,      cvs_client_remove_entry, 0 },
                     44:        { "Set-static-directory",       0,
                     45:            cvs_client_set_static_directory, 0 },
                     46:        { "Clear-static-directory",     0,
                     47:            cvs_client_clear_static_directory, 0 },
                     48:        { "Set-sticky",         0,      cvs_client_set_sticky, 0 },
                     49:        { "Clear-sticky",       0,      cvs_client_clear_sticky, 0 },
1.29      joris      50:
                     51:        /* unsupported responses until told otherwise */
                     52:        { "New-entry",                  0,      NULL, 0 },
                     53:        { "Created",                    0,      NULL, 0 },
                     54:        { "Update-existing",            0,      NULL, 0 },
                     55:        { "Rcs-diff",                   0,      NULL, 0 },
                     56:        { "Patched",                    0,      NULL, 0 },
                     57:        { "Mode",                       0,      NULL, 0 },
                     58:        { "Mod-time",                   0,      NULL, 0 },
                     59:        { "Checksum",                   0,      NULL, 0 },
                     60:        { "Copy-file",                  0,      NULL, 0 },
                     61:        { "Template",                   0,      NULL, 0 },
                     62:        { "Set-checkin-prog",           0,      NULL, 0 },
                     63:        { "Set-update-prog",            0,      NULL, 0 },
                     64:        { "Notified",                   0,      NULL, 0 },
                     65:        { "Module-expansion",           0,      NULL, 0 },
                     66:        { "Wrapper-rcsOption",          0,      NULL, 0 },
                     67:        { "Mbinary",                    0,      NULL, 0 },
                     68:        { "F",                          0,      NULL, 0 },
                     69:        { "MT",                         0,      NULL, 0 },
                     70:        { "",                           -1,     NULL, 0 }
                     71: };
1.1       jfb        72:
1.29      joris      73: int    cvs_server(int, char **);
                     74: char   *cvs_server_path = NULL;
1.1       jfb        75:
1.29      joris      76: static char *server_currentdir = NULL;
1.88      tobias     77: static char **server_argv;
1.29      joris      78: static int server_argc = 1;
1.8       joris      79:
1.90      joris      80: extern int disable_fast_checkout;
                     81:
1.17      jfb        82: struct cvs_cmd cvs_cmd_server = {
1.78      tobias     83:        CVS_OP_SERVER, CVS_USE_WDIR, "server", { "", "" },
1.29      joris      84:        "server mode",
1.17      jfb        85:        NULL,
1.29      joris      86:        NULL,
                     87:        NULL,
                     88:        cvs_server
1.17      jfb        89: };
1.1       jfb        90:
1.14      joris      91:
1.1       jfb        92: int
                     93: cvs_server(int argc, char **argv)
                     94: {
1.29      joris      95:        char *cmd, *data;
                     96:        struct cvs_req *req;
                     97:
1.68      tobias     98:        if (argc > 1)
                     99:                fatal("server does not take any extra arguments");
                    100:
1.70      tobias    101:        /* Be on server-side very verbose per default. */
                    102:        verbosity = 2;
                    103:
1.68      tobias    104:        setvbuf(stdin, NULL, _IOLBF, 0);
                    105:        setvbuf(stdout, NULL, _IOLBF, 0);
                    106:
                    107:        cvs_server_active = 1;
                    108:
1.88      tobias    109:        server_argv = xcalloc(server_argc + 1, sizeof(*server_argv));
1.29      joris     110:        server_argv[0] = xstrdup("server");
                    111:
1.58      ray       112:        (void)xasprintf(&cvs_server_path, "%s/cvs-serv%d", cvs_tmpdir,
                    113:            getpid());
1.29      joris     114:
                    115:        if (mkdir(cvs_server_path, 0700) == -1)
                    116:                fatal("failed to create temporary server directory: %s, %s",
                    117:                    cvs_server_path, strerror(errno));
                    118:
                    119:        if (chdir(cvs_server_path) == -1)
                    120:                fatal("failed to change directory to '%s'", cvs_server_path);
                    121:
                    122:        for (;;) {
                    123:                cmd = cvs_remote_input();
                    124:
                    125:                if ((data = strchr(cmd, ' ')) != NULL)
                    126:                        (*data++) = '\0';
                    127:
                    128:                req = cvs_remote_get_request_info(cmd);
                    129:                if (req == NULL)
                    130:                        fatal("request '%s' is not supported by our server",
                    131:                            cmd);
                    132:
                    133:                if (req->hdlr == NULL)
                    134:                        fatal("opencvs server does not support '%s'", cmd);
1.63      joris     135:
                    136:                if ((req->flags & REQ_NEEDDIR) && (server_currentdir == NULL))
                    137:                        fatal("`%s' needs a directory to be sent with "
                    138:                            "the `Directory` request first", cmd);
1.29      joris     139:
                    140:                (*req->hdlr)(data);
1.103     nicm      141:                free(cmd);
1.14      joris     142:        }
                    143:
1.29      joris     144:        return (0);
                    145: }
                    146:
                    147: void
                    148: cvs_server_send_response(char *fmt, ...)
                    149: {
1.85      tobias    150:        int i;
1.29      joris     151:        va_list ap;
1.59      ray       152:        char *data;
1.29      joris     153:
                    154:        va_start(ap, fmt);
1.85      tobias    155:        i = vasprintf(&data, fmt, ap);
1.29      joris     156:        va_end(ap);
1.85      tobias    157:        if (i == -1)
1.86      tobias    158:                fatal("cvs_server_send_response: could not allocate memory");
1.14      joris     159:
1.30      joris     160:        cvs_log(LP_TRACE, "%s", data);
1.29      joris     161:        cvs_remote_output(data);
1.103     nicm      162:        free(data);
1.29      joris     163: }
                    164:
                    165: void
                    166: cvs_server_root(char *data)
                    167: {
1.68      tobias    168:        if (data == NULL)
                    169:                fatal("Missing argument for Root");
                    170:
                    171:        if (current_cvsroot != NULL)
                    172:                return;
                    173:
                    174:        if (data[0] != '/' || (current_cvsroot = cvsroot_get(data)) == NULL)
                    175:                fatal("Invalid Root specified!");
1.73      tobias    176:
                    177:        cvs_parse_configfile();
1.81      joris     178:        cvs_parse_modules();
1.73      tobias    179:        umask(cvs_umask);
1.29      joris     180: }
                    181:
                    182: void
                    183: cvs_server_validresp(char *data)
                    184: {
                    185:        int i;
                    186:        char *sp, *ep;
                    187:        struct cvs_resp *resp;
                    188:
1.57      ray       189:        if ((sp = data) == NULL)
                    190:                fatal("Missing argument for Valid-responses");
                    191:
1.29      joris     192:        do {
                    193:                if ((ep = strchr(sp, ' ')) != NULL)
                    194:                        *ep = '\0';
                    195:
                    196:                resp = cvs_remote_get_response_info(sp);
                    197:                if (resp != NULL)
                    198:                        resp->supported = 1;
                    199:
                    200:                if (ep != NULL)
                    201:                        sp = ep + 1;
                    202:        } while (ep != NULL);
                    203:
                    204:        for (i = 0; cvs_responses[i].supported != -1; i++) {
                    205:                resp = &cvs_responses[i];
                    206:                if ((resp->flags & RESP_NEEDED) &&
                    207:                    resp->supported != 1) {
                    208:                        fatal("client does not support required '%s'",
                    209:                            resp->name);
1.1       jfb       210:                }
1.29      joris     211:        }
                    212: }
1.1       jfb       213:
1.29      joris     214: void
                    215: cvs_server_validreq(char *data)
                    216: {
                    217:        BUF *bp;
                    218:        char *d;
                    219:        int i, first;
                    220:
                    221:        first = 0;
1.100     ray       222:        bp = buf_alloc(512);
1.29      joris     223:        for (i = 0; cvs_requests[i].supported != -1; i++) {
                    224:                if (cvs_requests[i].hdlr == NULL)
1.5       jfb       225:                        continue;
1.1       jfb       226:
1.29      joris     227:                if (first != 0)
1.100     ray       228:                        buf_putc(bp, ' ');
1.29      joris     229:                else
                    230:                        first++;
                    231:
1.100     ray       232:                buf_puts(bp, cvs_requests[i].name);
1.29      joris     233:        }
                    234:
1.100     ray       235:        buf_putc(bp, '\0');
                    236:        d = buf_release(bp);
1.29      joris     237:
                    238:        cvs_server_send_response("Valid-requests %s", d);
                    239:        cvs_server_send_response("ok");
1.103     nicm      240:        free(d);
1.42      xsa       241: }
                    242:
                    243: void
1.43      xsa       244: cvs_server_static_directory(char *data)
                    245: {
                    246:        FILE *fp;
1.102     deraadt   247:        char fpath[PATH_MAX];
1.43      xsa       248:
1.102     deraadt   249:        (void)xsnprintf(fpath, PATH_MAX, "%s/%s",
1.54      xsa       250:            server_currentdir, CVS_PATH_STATICENTRIES);
1.43      xsa       251:
                    252:        if ((fp = fopen(fpath, "w+")) == NULL) {
                    253:                cvs_log(LP_ERRNO, "%s", fpath);
1.51      otto      254:                return;
1.43      xsa       255:        }
                    256:        (void)fclose(fp);
                    257: }
                    258:
                    259: void
1.42      xsa       260: cvs_server_sticky(char *data)
                    261: {
                    262:        FILE *fp;
1.102     deraadt   263:        char tagpath[PATH_MAX];
1.42      xsa       264:
1.57      ray       265:        if (data == NULL)
                    266:                fatal("Missing argument for Sticky");
                    267:
1.102     deraadt   268:        (void)xsnprintf(tagpath, PATH_MAX, "%s/%s",
1.54      xsa       269:            server_currentdir, CVS_PATH_TAG);
1.42      xsa       270:
1.43      xsa       271:        if ((fp = fopen(tagpath, "w+")) == NULL) {
1.42      xsa       272:                cvs_log(LP_ERRNO, "%s", tagpath);
1.51      otto      273:                return;
1.42      xsa       274:        }
                    275:
                    276:        (void)fprintf(fp, "%s\n", data);
                    277:        (void)fclose(fp);
1.29      joris     278: }
                    279:
                    280: void
                    281: cvs_server_globalopt(char *data)
                    282: {
1.57      ray       283:        if (data == NULL)
                    284:                fatal("Missing argument for Global_option");
                    285:
1.38      xsa       286:        if (!strcmp(data, "-l"))
                    287:                cvs_nolog = 1;
1.29      joris     288:
                    289:        if (!strcmp(data, "-n"))
                    290:                cvs_noexec = 1;
1.38      xsa       291:
                    292:        if (!strcmp(data, "-Q"))
                    293:                verbosity = 0;
                    294:
1.70      tobias    295:        if (!strcmp(data, "-q"))
                    296:                verbosity = 1;
                    297:
1.38      xsa       298:        if (!strcmp(data, "-r"))
                    299:                cvs_readonly = 1;
                    300:
                    301:        if (!strcmp(data, "-t"))
                    302:                cvs_trace = 1;
1.39      xsa       303: }
                    304:
                    305: void
                    306: cvs_server_set(char *data)
                    307: {
                    308:        char *ep;
                    309:
1.57      ray       310:        if (data == NULL)
                    311:                fatal("Missing argument for Set");
                    312:
1.39      xsa       313:        ep = strchr(data, '=');
                    314:        if (ep == NULL)
                    315:                fatal("no = in variable assignment");
                    316:
                    317:        *(ep++) = '\0';
                    318:        if (cvs_var_set(data, ep) < 0)
                    319:                fatal("cvs_server_set: cvs_var_set failed");
1.29      joris     320: }
1.1       jfb       321:
1.29      joris     322: void
                    323: cvs_server_directory(char *data)
                    324: {
                    325:        CVSENTRIES *entlist;
1.83      xsa       326:        char *dir, *repo, *parent, *entry, *dirn, *p;
1.106   ! naddy     327:        char parentbuf[PATH_MAX], dirnbuf[PATH_MAX];
1.68      tobias    328:
                    329:        if (current_cvsroot == NULL)
                    330:                fatal("No Root specified for Directory");
1.29      joris     331:
                    332:        dir = cvs_remote_input();
1.49      joris     333:        STRIP_SLASH(dir);
                    334:
                    335:        if (strlen(dir) < strlen(current_cvsroot->cr_dir))
1.29      joris     336:                fatal("cvs_server_directory: bad Directory request");
                    337:
1.49      joris     338:        repo = dir + strlen(current_cvsroot->cr_dir);
                    339:
                    340:        /*
                    341:         * This is somewhat required for checkout, as the
                    342:         * directory request will be:
                    343:         *
                    344:         * Directory .
                    345:         * /path/to/cvs/root
                    346:         */
                    347:        if (repo[0] == '\0')
                    348:                p = xstrdup(".");
                    349:        else
                    350:                p = xstrdup(repo + 1);
                    351:
1.65      joris     352:        cvs_mkpath(p, NULL);
1.29      joris     353:
1.106   ! naddy     354:        if (strlcpy(dirnbuf, p, sizeof(dirnbuf)) >= sizeof(dirnbuf))
        !           355:                fatal("cvs_server_directory: truncation");
        !           356:        if ((dirn = basename(dirnbuf)) == NULL)
1.29      joris     357:                fatal("cvs_server_directory: %s", strerror(errno));
                    358:
1.106   ! naddy     359:        if (strlcpy(parentbuf, p, sizeof(parentbuf)) >= sizeof(parentbuf))
        !           360:                fatal("cvs_server_directory: truncation");
        !           361:        if ((parent = dirname(parentbuf)) == NULL)
1.29      joris     362:                fatal("cvs_server_directory: %s", strerror(errno));
                    363:
                    364:        if (strcmp(parent, ".")) {
1.83      xsa       365:                entry = xmalloc(CVS_ENT_MAXLINELEN);
                    366:                cvs_ent_line_str(dirn, NULL, NULL, NULL, NULL, 1, 0,
                    367:                    entry, CVS_ENT_MAXLINELEN);
                    368:
1.29      joris     369:                entlist = cvs_ent_open(parent);
                    370:                cvs_ent_add(entlist, entry);
1.103     nicm      371:                free(entry);
1.1       jfb       372:        }
                    373:
1.104     mmcc      374:        free(server_currentdir);
1.61      ray       375:        server_currentdir = p;
1.29      joris     376:
1.103     nicm      377:        free(dir);
1.29      joris     378: }
                    379:
                    380: void
                    381: cvs_server_entry(char *data)
                    382: {
                    383:        CVSENTRIES *entlist;
                    384:
1.57      ray       385:        if (data == NULL)
                    386:                fatal("Missing argument for Entry");
                    387:
1.29      joris     388:        entlist = cvs_ent_open(server_currentdir);
                    389:        cvs_ent_add(entlist, data);
                    390: }
                    391:
                    392: void
                    393: cvs_server_modified(char *data)
                    394: {
1.41      xsa       395:        int fd;
1.29      joris     396:        size_t flen;
                    397:        mode_t fmode;
                    398:        const char *errstr;
1.102     deraadt   399:        char *mode, *len, fpath[PATH_MAX];
1.29      joris     400:
1.57      ray       401:        if (data == NULL)
                    402:                fatal("Missing argument for Modified");
                    403:
1.90      joris     404:        /* sorry, we have to use TMP_DIR */
                    405:        disable_fast_checkout = 1;
                    406:
1.29      joris     407:        mode = cvs_remote_input();
                    408:        len = cvs_remote_input();
                    409:
                    410:        cvs_strtomode(mode, &fmode);
1.103     nicm      411:        free(mode);
1.29      joris     412:
                    413:        flen = strtonum(len, 0, INT_MAX, &errstr);
                    414:        if (errstr != NULL)
                    415:                fatal("cvs_server_modified: %s", errstr);
1.103     nicm      416:        free(len);
1.29      joris     417:
1.102     deraadt   418:        (void)xsnprintf(fpath, PATH_MAX, "%s/%s", server_currentdir, data);
1.29      joris     419:
                    420:        if ((fd = open(fpath, O_WRONLY | O_CREAT | O_TRUNC)) == -1)
                    421:                fatal("cvs_server_modified: %s: %s", fpath, strerror(errno));
                    422:
1.48      joris     423:        cvs_remote_receive_file(fd, flen);
1.29      joris     424:
                    425:        if (fchmod(fd, 0600) == -1)
                    426:                fatal("cvs_server_modified: failed to set file mode");
                    427:
                    428:        (void)close(fd);
                    429: }
                    430:
                    431: void
                    432: cvs_server_useunchanged(char *data)
                    433: {
                    434: }
                    435:
                    436: void
                    437: cvs_server_unchanged(char *data)
                    438: {
1.102     deraadt   439:        char fpath[PATH_MAX];
1.29      joris     440:        CVSENTRIES *entlist;
                    441:        struct cvs_ent *ent;
1.71      joris     442:        char sticky[CVS_ENT_MAXLINELEN];
                    443:        char rev[CVS_REV_BUFSZ], entry[CVS_ENT_MAXLINELEN];
1.29      joris     444:
1.57      ray       445:        if (data == NULL)
                    446:                fatal("Missing argument for Unchanged");
                    447:
1.90      joris     448:        /* sorry, we have to use TMP_DIR */
                    449:        disable_fast_checkout = 1;
                    450:
1.102     deraadt   451:        (void)xsnprintf(fpath, PATH_MAX, "%s/%s", server_currentdir, data);
1.29      joris     452:
                    453:        entlist = cvs_ent_open(server_currentdir);
                    454:        ent = cvs_ent_get(entlist, data);
                    455:        if (ent == NULL)
                    456:                fatal("received Unchanged request for non-existing file");
                    457:
1.71      joris     458:        sticky[0] = '\0';
                    459:        if (ent->ce_tag != NULL)
                    460:                (void)xsnprintf(sticky, sizeof(sticky), "T%s", ent->ce_tag);
                    461:
                    462:        rcsnum_tostr(ent->ce_rev, rev, sizeof(rev));
                    463:        (void)xsnprintf(entry, sizeof(entry), "/%s/%s/%s/%s/%s",
                    464:            ent->ce_name, rev, CVS_SERVER_UNCHANGED, ent->ce_opts ?
                    465:            ent->ce_opts : "", sticky);
1.29      joris     466:
                    467:        cvs_ent_free(ent);
1.71      joris     468:        cvs_ent_add(entlist, entry);
1.29      joris     469: }
                    470:
                    471: void
                    472: cvs_server_questionable(char *data)
                    473: {
1.94      joris     474:        CVSENTRIES *entlist;
                    475:        char entry[CVS_ENT_MAXLINELEN];
                    476:
                    477:        if (data == NULL)
                    478:                fatal("Questionable request with no data attached");
                    479:
                    480:        (void)xsnprintf(entry, sizeof(entry), "/%s/%c///", data,
                    481:            CVS_SERVER_QUESTIONABLE);
                    482:
                    483:        entlist = cvs_ent_open(server_currentdir);
                    484:        cvs_ent_add(entlist, entry);
                    485:
1.90      joris     486:        /* sorry, we have to use TMP_DIR */
                    487:        disable_fast_checkout = 1;
1.29      joris     488: }
                    489:
                    490: void
                    491: cvs_server_argument(char *data)
                    492: {
1.57      ray       493:        if (data == NULL)
                    494:                fatal("Missing argument for Argument");
1.29      joris     495:
1.101     deraadt   496:        server_argv = xreallocarray(server_argv, server_argc + 2,
1.88      tobias    497:            sizeof(*server_argv));
                    498:        server_argv[server_argc] = xstrdup(data);
                    499:        server_argv[++server_argc] = NULL;
1.37      xsa       500: }
                    501:
                    502: void
                    503: cvs_server_argumentx(char *data)
                    504: {
1.66      joris     505:        int idx;
                    506:        size_t len;
                    507:
1.87      tobias    508:        if (server_argc == 1)
1.66      joris     509:                fatal("Protocol Error: ArgumentX without previous argument");
                    510:
                    511:        idx = server_argc - 1;
                    512:
                    513:        len = strlen(server_argv[idx]) + strlen(data) + 2;
1.101     deraadt   514:        server_argv[idx] = xreallocarray(server_argv[idx], len, sizeof(char));
1.66      joris     515:        strlcat(server_argv[idx], "\n", len);
                    516:        strlcat(server_argv[idx], data, len);
1.44      xsa       517: }
                    518:
                    519: void
                    520: cvs_server_update_patches(char *data)
                    521: {
                    522:        /*
                    523:         * This does not actually do anything.
                    524:         * It is used to tell that the server is able to
                    525:         * generate patches when given an `update' request.
                    526:         * The client must issue the -u argument to `update'
                    527:         * to receive patches.
                    528:         */
1.29      joris     529: }
                    530:
                    531: void
1.31      xsa       532: cvs_server_add(char *data)
                    533: {
                    534:        if (chdir(server_currentdir) == -1)
                    535:                fatal("cvs_server_add: %s", strerror(errno));
                    536:
                    537:        cvs_cmdop = CVS_OP_ADD;
1.78      tobias    538:        cmdp->cmd_flags = cvs_cmd_add.cmd_flags;
1.31      xsa       539:        cvs_add(server_argc, server_argv);
1.50      joris     540:        cvs_server_send_response("ok");
                    541: }
                    542:
                    543: void
                    544: cvs_server_import(char *data)
                    545: {
                    546:        if (chdir(server_currentdir) == -1)
                    547:                fatal("cvs_server_import: %s", strerror(errno));
                    548:
                    549:        cvs_cmdop = CVS_OP_IMPORT;
1.78      tobias    550:        cmdp->cmd_flags = cvs_cmd_import.cmd_flags;
1.50      joris     551:        cvs_import(server_argc, server_argv);
1.31      xsa       552:        cvs_server_send_response("ok");
                    553: }
1.35      xsa       554:
                    555: void
                    556: cvs_server_admin(char *data)
                    557: {
                    558:        if (chdir(server_currentdir) == -1)
                    559:                fatal("cvs_server_admin: %s", strerror(errno));
                    560:
                    561:        cvs_cmdop = CVS_OP_ADMIN;
1.78      tobias    562:        cmdp->cmd_flags = cvs_cmd_admin.cmd_flags;
1.35      xsa       563:        cvs_admin(server_argc, server_argv);
                    564:        cvs_server_send_response("ok");
                    565: }
                    566:
1.40      xsa       567: void
                    568: cvs_server_annotate(char *data)
                    569: {
                    570:        if (chdir(server_currentdir) == -1)
                    571:                fatal("cvs_server_annotate: %s", strerror(errno));
                    572:
                    573:        cvs_cmdop = CVS_OP_ANNOTATE;
1.78      tobias    574:        cmdp->cmd_flags = cvs_cmd_annotate.cmd_flags;
1.80      tobias    575:        cvs_annotate(server_argc, server_argv);
                    576:        cvs_server_send_response("ok");
                    577: }
                    578:
                    579: void
                    580: cvs_server_rannotate(char *data)
                    581: {
                    582:        if (chdir(server_currentdir) == -1)
                    583:                fatal("cvs_server_rannotate: %s", strerror(errno));
                    584:
                    585:        cvs_cmdop = CVS_OP_RANNOTATE;
                    586:        cmdp->cmd_flags = cvs_cmd_rannotate.cmd_flags;
1.40      xsa       587:        cvs_annotate(server_argc, server_argv);
                    588:        cvs_server_send_response("ok");
                    589: }
1.31      xsa       590:
                    591: void
1.29      joris     592: cvs_server_commit(char *data)
                    593: {
                    594:        if (chdir(server_currentdir) == -1)
                    595:                fatal("cvs_server_commit: %s", strerror(errno));
                    596:
                    597:        cvs_cmdop = CVS_OP_COMMIT;
1.78      tobias    598:        cmdp->cmd_flags = cvs_cmd_commit.cmd_flags;
1.29      joris     599:        cvs_commit(server_argc, server_argv);
1.49      joris     600:        cvs_server_send_response("ok");
                    601: }
                    602:
                    603: void
                    604: cvs_server_checkout(char *data)
1.77      tobias    605: {
                    606:        if (chdir(server_currentdir) == -1)
1.49      joris     607:                fatal("cvs_server_checkout: %s", strerror(errno));
                    608:
                    609:        cvs_cmdop = CVS_OP_CHECKOUT;
1.78      tobias    610:        cmdp->cmd_flags = cvs_cmd_checkout.cmd_flags;
1.49      joris     611:        cvs_checkout(server_argc, server_argv);
1.29      joris     612:        cvs_server_send_response("ok");
                    613: }
                    614:
                    615: void
                    616: cvs_server_diff(char *data)
                    617: {
                    618:        if (chdir(server_currentdir) == -1)
                    619:                fatal("cvs_server_diff: %s", strerror(errno));
                    620:
                    621:        cvs_cmdop = CVS_OP_DIFF;
1.78      tobias    622:        cmdp->cmd_flags = cvs_cmd_diff.cmd_flags;
1.82      tobias    623:        cvs_diff(server_argc, server_argv);
                    624:        cvs_server_send_response("ok");
                    625: }
                    626:
                    627: void
                    628: cvs_server_rdiff(char *data)
                    629: {
                    630:        if (chdir(server_currentdir) == -1)
                    631:                fatal("cvs_server_rdiff: %s", strerror(errno));
                    632:
                    633:        cvs_cmdop = CVS_OP_RDIFF;
                    634:        cmdp->cmd_flags = cvs_cmd_rdiff.cmd_flags;
1.29      joris     635:        cvs_diff(server_argc, server_argv);
1.76      tobias    636:        cvs_server_send_response("ok");
                    637: }
                    638:
                    639: void
                    640: cvs_server_export(char *data)
1.77      tobias    641: {
                    642:        if (chdir(server_currentdir) == -1)
                    643:                fatal("cvs_server_export: %s", strerror(errno));
1.76      tobias    644:
                    645:        cvs_cmdop = CVS_OP_EXPORT;
1.78      tobias    646:        cmdp->cmd_flags = cvs_cmd_export.cmd_flags;
1.90      joris     647:        cvs_export(server_argc, server_argv);
1.34      xsa       648:        cvs_server_send_response("ok");
                    649: }
                    650:
                    651: void
                    652: cvs_server_init(char *data)
                    653: {
1.69      tobias    654:        if (data == NULL)
                    655:                fatal("Missing argument for init");
                    656:
                    657:        if (current_cvsroot != NULL)
                    658:                fatal("Root in combination with init is not supported");
                    659:
                    660:        if ((current_cvsroot = cvsroot_get(data)) == NULL)
                    661:                fatal("Invalid argument for init");
1.34      xsa       662:
                    663:        cvs_cmdop = CVS_OP_INIT;
1.78      tobias    664:        cmdp->cmd_flags = cvs_cmd_init.cmd_flags;
1.34      xsa       665:        cvs_init(server_argc, server_argv);
1.64      xsa       666:        cvs_server_send_response("ok");
                    667: }
                    668:
                    669: void
                    670: cvs_server_release(char *data)
                    671: {
                    672:        if (chdir(server_currentdir) == -1)
1.67      xsa       673:                fatal("cvs_server_release: %s", strerror(errno));
1.64      xsa       674:
                    675:        cvs_cmdop = CVS_OP_RELEASE;
1.78      tobias    676:        cmdp->cmd_flags = cvs_cmd_release.cmd_flags;
1.64      xsa       677:        cvs_release(server_argc, server_argv);
1.31      xsa       678:        cvs_server_send_response("ok");
                    679: }
                    680:
                    681: void
                    682: cvs_server_remove(char *data)
                    683: {
                    684:        if (chdir(server_currentdir) == -1)
                    685:                fatal("cvs_server_remove: %s", strerror(errno));
                    686:
                    687:        cvs_cmdop = CVS_OP_REMOVE;
1.78      tobias    688:        cmdp->cmd_flags = cvs_cmd_remove.cmd_flags;
1.31      xsa       689:        cvs_remove(server_argc, server_argv);
1.29      joris     690:        cvs_server_send_response("ok");
                    691: }
                    692:
                    693: void
                    694: cvs_server_status(char *data)
                    695: {
                    696:        if (chdir(server_currentdir) == -1)
                    697:                fatal("cvs_server_status: %s", strerror(errno));
                    698:
                    699:        cvs_cmdop = CVS_OP_STATUS;
1.78      tobias    700:        cmdp->cmd_flags = cvs_cmd_status.cmd_flags;
1.29      joris     701:        cvs_status(server_argc, server_argv);
                    702:        cvs_server_send_response("ok");
                    703: }
                    704:
                    705: void
                    706: cvs_server_log(char *data)
                    707: {
                    708:        if (chdir(server_currentdir) == -1)
                    709:                fatal("cvs_server_log: %s", strerror(errno));
                    710:
                    711:        cvs_cmdop = CVS_OP_LOG;
1.78      tobias    712:        cmdp->cmd_flags = cvs_cmd_log.cmd_flags;
1.62      niallo    713:        cvs_getlog(server_argc, server_argv);
                    714:        cvs_server_send_response("ok");
                    715: }
1.79      xsa       716:
1.62      niallo    717: void
                    718: cvs_server_rlog(char *data)
                    719: {
1.74      tobias    720:        if (chdir(current_cvsroot->cr_dir) == -1)
1.67      xsa       721:                fatal("cvs_server_rlog: %s", strerror(errno));
1.62      niallo    722:
                    723:        cvs_cmdop = CVS_OP_RLOG;
1.78      tobias    724:        cmdp->cmd_flags = cvs_cmd_rlog.cmd_flags;
1.32      xsa       725:        cvs_getlog(server_argc, server_argv);
                    726:        cvs_server_send_response("ok");
                    727: }
                    728:
                    729: void
                    730: cvs_server_tag(char *data)
                    731: {
                    732:        if (chdir(server_currentdir) == -1)
                    733:                fatal("cvs_server_tag: %s", strerror(errno));
                    734:
                    735:        cvs_cmdop = CVS_OP_TAG;
1.78      tobias    736:        cmdp->cmd_flags = cvs_cmd_tag.cmd_flags;
1.75      tobias    737:        cvs_tag(server_argc, server_argv);
                    738:        cvs_server_send_response("ok");
                    739: }
                    740:
                    741: void
                    742: cvs_server_rtag(char *data)
                    743: {
                    744:        if (chdir(current_cvsroot->cr_dir) == -1)
1.77      tobias    745:                fatal("cvs_server_rtag: %s", strerror(errno));
1.75      tobias    746:
                    747:        cvs_cmdop = CVS_OP_RTAG;
1.78      tobias    748:        cmdp->cmd_flags = cvs_cmd_rtag.cmd_flags;
1.33      xsa       749:        cvs_tag(server_argc, server_argv);
1.29      joris     750:        cvs_server_send_response("ok");
                    751: }
                    752:
                    753: void
                    754: cvs_server_update(char *data)
                    755: {
                    756:        if (chdir(server_currentdir) == -1)
                    757:                fatal("cvs_server_update: %s", strerror(errno));
1.14      joris     758:
1.29      joris     759:        cvs_cmdop = CVS_OP_UPDATE;
1.78      tobias    760:        cmdp->cmd_flags = cvs_cmd_update.cmd_flags;
1.29      joris     761:        cvs_update(server_argc, server_argv);
1.36      xsa       762:        cvs_server_send_response("ok");
                    763: }
                    764:
                    765: void
                    766: cvs_server_version(char *data)
                    767: {
                    768:        cvs_cmdop = CVS_OP_VERSION;
1.78      tobias    769:        cmdp->cmd_flags = cvs_cmd_version.cmd_flags;
1.36      xsa       770:        cvs_version(server_argc, server_argv);
1.29      joris     771:        cvs_server_send_response("ok");
1.47      joris     772: }
                    773:
                    774: void
                    775: cvs_server_update_entry(const char *resp, struct cvs_file *cf)
                    776: {
1.58      ray       777:        char *p;
1.102     deraadt   778:        char repo[PATH_MAX], fpath[PATH_MAX];
1.47      joris     779:
                    780:        if ((p = strrchr(cf->file_rpath, ',')) != NULL)
                    781:                *p = '\0';
                    782:
1.102     deraadt   783:        cvs_get_repository_path(cf->file_wd, repo, PATH_MAX);
                    784:        (void)xsnprintf(fpath, PATH_MAX, "%s/%s", repo, cf->file_name);
1.65      joris     785:
1.58      ray       786:        cvs_server_send_response("%s %s/", resp, cf->file_wd);
1.65      joris     787:        cvs_remote_output(fpath);
1.47      joris     788:
                    789:        if (p != NULL)
                    790:                *p = ',';
1.65      joris     791: }
                    792:
                    793: void
1.105     otto      794: cvs_server_set_sticky(const char *dir, char *tag)
1.65      joris     795: {
1.102     deraadt   796:        char fpath[PATH_MAX];
                    797:        char repo[PATH_MAX];
1.65      joris     798:
1.102     deraadt   799:        cvs_get_repository_path(dir, repo, PATH_MAX);
                    800:        (void)xsnprintf(fpath, PATH_MAX, "%s/", repo);
1.65      joris     801:
1.93      joris     802:        cvs_server_send_response("Set-sticky %s/", dir);
1.65      joris     803:        cvs_remote_output(fpath);
1.72      joris     804:        cvs_remote_output(tag);
1.65      joris     805: }
                    806:
                    807: void
                    808: cvs_server_clear_sticky(char *dir)
                    809: {
1.102     deraadt   810:        char fpath[PATH_MAX];
                    811:        char repo[PATH_MAX];
1.65      joris     812:
1.102     deraadt   813:        cvs_get_repository_path(dir, repo, PATH_MAX);
                    814:        (void)xsnprintf(fpath, PATH_MAX, "%s/", repo);
1.65      joris     815:
1.93      joris     816:        cvs_server_send_response("Clear-sticky %s//", dir);
1.65      joris     817:        cvs_remote_output(fpath);
1.96      joris     818: }
                    819:
                    820: void
                    821: cvs_server_exp_modules(char *module)
                    822: {
                    823:        struct module_checkout *mo;
                    824:        struct cvs_filelist *fl;
                    825:
                    826:        if (server_argc != 2)
                    827:                fatal("expand-modules with no arguments");
                    828:
                    829:        mo = cvs_module_lookup(server_argv[1]);
                    830:
                    831:        RB_FOREACH(fl, cvs_flisthead, &(mo->mc_modules))
                    832:                cvs_server_send_response("Module-expansion %s", fl->file_path);
                    833:        cvs_server_send_response("ok");
                    834:
                    835:        server_argc--;
1.103     nicm      836:        free(server_argv[1]);
1.96      joris     837:        server_argv[1] = NULL;
1.1       jfb       838: }