[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.105

1.105   ! otto        1: /*     $OpenBSD: server.c,v 1.104 2015/12/09 17:55:42 mmcc 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.68      tobias    327:
                    328:        if (current_cvsroot == NULL)
                    329:                fatal("No Root specified for Directory");
1.29      joris     330:
                    331:        dir = cvs_remote_input();
1.49      joris     332:        STRIP_SLASH(dir);
                    333:
                    334:        if (strlen(dir) < strlen(current_cvsroot->cr_dir))
1.29      joris     335:                fatal("cvs_server_directory: bad Directory request");
                    336:
1.49      joris     337:        repo = dir + strlen(current_cvsroot->cr_dir);
                    338:
                    339:        /*
                    340:         * This is somewhat required for checkout, as the
                    341:         * directory request will be:
                    342:         *
                    343:         * Directory .
                    344:         * /path/to/cvs/root
                    345:         */
                    346:        if (repo[0] == '\0')
                    347:                p = xstrdup(".");
                    348:        else
                    349:                p = xstrdup(repo + 1);
                    350:
1.65      joris     351:        cvs_mkpath(p, NULL);
1.29      joris     352:
1.49      joris     353:        if ((dirn = basename(p)) == NULL)
1.29      joris     354:                fatal("cvs_server_directory: %s", strerror(errno));
                    355:
1.49      joris     356:        if ((parent = dirname(p)) == NULL)
1.29      joris     357:                fatal("cvs_server_directory: %s", strerror(errno));
                    358:
                    359:        if (strcmp(parent, ".")) {
1.83      xsa       360:                entry = xmalloc(CVS_ENT_MAXLINELEN);
                    361:                cvs_ent_line_str(dirn, NULL, NULL, NULL, NULL, 1, 0,
                    362:                    entry, CVS_ENT_MAXLINELEN);
                    363:
1.29      joris     364:                entlist = cvs_ent_open(parent);
                    365:                cvs_ent_add(entlist, entry);
1.103     nicm      366:                free(entry);
1.1       jfb       367:        }
                    368:
1.104     mmcc      369:        free(server_currentdir);
1.61      ray       370:        server_currentdir = p;
1.29      joris     371:
1.103     nicm      372:        free(dir);
1.29      joris     373: }
                    374:
                    375: void
                    376: cvs_server_entry(char *data)
                    377: {
                    378:        CVSENTRIES *entlist;
                    379:
1.57      ray       380:        if (data == NULL)
                    381:                fatal("Missing argument for Entry");
                    382:
1.29      joris     383:        entlist = cvs_ent_open(server_currentdir);
                    384:        cvs_ent_add(entlist, data);
                    385: }
                    386:
                    387: void
                    388: cvs_server_modified(char *data)
                    389: {
1.41      xsa       390:        int fd;
1.29      joris     391:        size_t flen;
                    392:        mode_t fmode;
                    393:        const char *errstr;
1.102     deraadt   394:        char *mode, *len, fpath[PATH_MAX];
1.29      joris     395:
1.57      ray       396:        if (data == NULL)
                    397:                fatal("Missing argument for Modified");
                    398:
1.90      joris     399:        /* sorry, we have to use TMP_DIR */
                    400:        disable_fast_checkout = 1;
                    401:
1.29      joris     402:        mode = cvs_remote_input();
                    403:        len = cvs_remote_input();
                    404:
                    405:        cvs_strtomode(mode, &fmode);
1.103     nicm      406:        free(mode);
1.29      joris     407:
                    408:        flen = strtonum(len, 0, INT_MAX, &errstr);
                    409:        if (errstr != NULL)
                    410:                fatal("cvs_server_modified: %s", errstr);
1.103     nicm      411:        free(len);
1.29      joris     412:
1.102     deraadt   413:        (void)xsnprintf(fpath, PATH_MAX, "%s/%s", server_currentdir, data);
1.29      joris     414:
                    415:        if ((fd = open(fpath, O_WRONLY | O_CREAT | O_TRUNC)) == -1)
                    416:                fatal("cvs_server_modified: %s: %s", fpath, strerror(errno));
                    417:
1.48      joris     418:        cvs_remote_receive_file(fd, flen);
1.29      joris     419:
                    420:        if (fchmod(fd, 0600) == -1)
                    421:                fatal("cvs_server_modified: failed to set file mode");
                    422:
                    423:        (void)close(fd);
                    424: }
                    425:
                    426: void
                    427: cvs_server_useunchanged(char *data)
                    428: {
                    429: }
                    430:
                    431: void
                    432: cvs_server_unchanged(char *data)
                    433: {
1.102     deraadt   434:        char fpath[PATH_MAX];
1.29      joris     435:        CVSENTRIES *entlist;
                    436:        struct cvs_ent *ent;
1.71      joris     437:        char sticky[CVS_ENT_MAXLINELEN];
                    438:        char rev[CVS_REV_BUFSZ], entry[CVS_ENT_MAXLINELEN];
1.29      joris     439:
1.57      ray       440:        if (data == NULL)
                    441:                fatal("Missing argument for Unchanged");
                    442:
1.90      joris     443:        /* sorry, we have to use TMP_DIR */
                    444:        disable_fast_checkout = 1;
                    445:
1.102     deraadt   446:        (void)xsnprintf(fpath, PATH_MAX, "%s/%s", server_currentdir, data);
1.29      joris     447:
                    448:        entlist = cvs_ent_open(server_currentdir);
                    449:        ent = cvs_ent_get(entlist, data);
                    450:        if (ent == NULL)
                    451:                fatal("received Unchanged request for non-existing file");
                    452:
1.71      joris     453:        sticky[0] = '\0';
                    454:        if (ent->ce_tag != NULL)
                    455:                (void)xsnprintf(sticky, sizeof(sticky), "T%s", ent->ce_tag);
                    456:
                    457:        rcsnum_tostr(ent->ce_rev, rev, sizeof(rev));
                    458:        (void)xsnprintf(entry, sizeof(entry), "/%s/%s/%s/%s/%s",
                    459:            ent->ce_name, rev, CVS_SERVER_UNCHANGED, ent->ce_opts ?
                    460:            ent->ce_opts : "", sticky);
1.29      joris     461:
                    462:        cvs_ent_free(ent);
1.71      joris     463:        cvs_ent_add(entlist, entry);
1.29      joris     464: }
                    465:
                    466: void
                    467: cvs_server_questionable(char *data)
                    468: {
1.94      joris     469:        CVSENTRIES *entlist;
                    470:        char entry[CVS_ENT_MAXLINELEN];
                    471:
                    472:        if (data == NULL)
                    473:                fatal("Questionable request with no data attached");
                    474:
                    475:        (void)xsnprintf(entry, sizeof(entry), "/%s/%c///", data,
                    476:            CVS_SERVER_QUESTIONABLE);
                    477:
                    478:        entlist = cvs_ent_open(server_currentdir);
                    479:        cvs_ent_add(entlist, entry);
                    480:
1.90      joris     481:        /* sorry, we have to use TMP_DIR */
                    482:        disable_fast_checkout = 1;
1.29      joris     483: }
                    484:
                    485: void
                    486: cvs_server_argument(char *data)
                    487: {
1.57      ray       488:        if (data == NULL)
                    489:                fatal("Missing argument for Argument");
1.29      joris     490:
1.101     deraadt   491:        server_argv = xreallocarray(server_argv, server_argc + 2,
1.88      tobias    492:            sizeof(*server_argv));
                    493:        server_argv[server_argc] = xstrdup(data);
                    494:        server_argv[++server_argc] = NULL;
1.37      xsa       495: }
                    496:
                    497: void
                    498: cvs_server_argumentx(char *data)
                    499: {
1.66      joris     500:        int idx;
                    501:        size_t len;
                    502:
1.87      tobias    503:        if (server_argc == 1)
1.66      joris     504:                fatal("Protocol Error: ArgumentX without previous argument");
                    505:
                    506:        idx = server_argc - 1;
                    507:
                    508:        len = strlen(server_argv[idx]) + strlen(data) + 2;
1.101     deraadt   509:        server_argv[idx] = xreallocarray(server_argv[idx], len, sizeof(char));
1.66      joris     510:        strlcat(server_argv[idx], "\n", len);
                    511:        strlcat(server_argv[idx], data, len);
1.44      xsa       512: }
                    513:
                    514: void
                    515: cvs_server_update_patches(char *data)
                    516: {
                    517:        /*
                    518:         * This does not actually do anything.
                    519:         * It is used to tell that the server is able to
                    520:         * generate patches when given an `update' request.
                    521:         * The client must issue the -u argument to `update'
                    522:         * to receive patches.
                    523:         */
1.29      joris     524: }
                    525:
                    526: void
1.31      xsa       527: cvs_server_add(char *data)
                    528: {
                    529:        if (chdir(server_currentdir) == -1)
                    530:                fatal("cvs_server_add: %s", strerror(errno));
                    531:
                    532:        cvs_cmdop = CVS_OP_ADD;
1.78      tobias    533:        cmdp->cmd_flags = cvs_cmd_add.cmd_flags;
1.31      xsa       534:        cvs_add(server_argc, server_argv);
1.50      joris     535:        cvs_server_send_response("ok");
                    536: }
                    537:
                    538: void
                    539: cvs_server_import(char *data)
                    540: {
                    541:        if (chdir(server_currentdir) == -1)
                    542:                fatal("cvs_server_import: %s", strerror(errno));
                    543:
                    544:        cvs_cmdop = CVS_OP_IMPORT;
1.78      tobias    545:        cmdp->cmd_flags = cvs_cmd_import.cmd_flags;
1.50      joris     546:        cvs_import(server_argc, server_argv);
1.31      xsa       547:        cvs_server_send_response("ok");
                    548: }
1.35      xsa       549:
                    550: void
                    551: cvs_server_admin(char *data)
                    552: {
                    553:        if (chdir(server_currentdir) == -1)
                    554:                fatal("cvs_server_admin: %s", strerror(errno));
                    555:
                    556:        cvs_cmdop = CVS_OP_ADMIN;
1.78      tobias    557:        cmdp->cmd_flags = cvs_cmd_admin.cmd_flags;
1.35      xsa       558:        cvs_admin(server_argc, server_argv);
                    559:        cvs_server_send_response("ok");
                    560: }
                    561:
1.40      xsa       562: void
                    563: cvs_server_annotate(char *data)
                    564: {
                    565:        if (chdir(server_currentdir) == -1)
                    566:                fatal("cvs_server_annotate: %s", strerror(errno));
                    567:
                    568:        cvs_cmdop = CVS_OP_ANNOTATE;
1.78      tobias    569:        cmdp->cmd_flags = cvs_cmd_annotate.cmd_flags;
1.80      tobias    570:        cvs_annotate(server_argc, server_argv);
                    571:        cvs_server_send_response("ok");
                    572: }
                    573:
                    574: void
                    575: cvs_server_rannotate(char *data)
                    576: {
                    577:        if (chdir(server_currentdir) == -1)
                    578:                fatal("cvs_server_rannotate: %s", strerror(errno));
                    579:
                    580:        cvs_cmdop = CVS_OP_RANNOTATE;
                    581:        cmdp->cmd_flags = cvs_cmd_rannotate.cmd_flags;
1.40      xsa       582:        cvs_annotate(server_argc, server_argv);
                    583:        cvs_server_send_response("ok");
                    584: }
1.31      xsa       585:
                    586: void
1.29      joris     587: cvs_server_commit(char *data)
                    588: {
                    589:        if (chdir(server_currentdir) == -1)
                    590:                fatal("cvs_server_commit: %s", strerror(errno));
                    591:
                    592:        cvs_cmdop = CVS_OP_COMMIT;
1.78      tobias    593:        cmdp->cmd_flags = cvs_cmd_commit.cmd_flags;
1.29      joris     594:        cvs_commit(server_argc, server_argv);
1.49      joris     595:        cvs_server_send_response("ok");
                    596: }
                    597:
                    598: void
                    599: cvs_server_checkout(char *data)
1.77      tobias    600: {
                    601:        if (chdir(server_currentdir) == -1)
1.49      joris     602:                fatal("cvs_server_checkout: %s", strerror(errno));
                    603:
                    604:        cvs_cmdop = CVS_OP_CHECKOUT;
1.78      tobias    605:        cmdp->cmd_flags = cvs_cmd_checkout.cmd_flags;
1.49      joris     606:        cvs_checkout(server_argc, server_argv);
1.29      joris     607:        cvs_server_send_response("ok");
                    608: }
                    609:
                    610: void
                    611: cvs_server_diff(char *data)
                    612: {
                    613:        if (chdir(server_currentdir) == -1)
                    614:                fatal("cvs_server_diff: %s", strerror(errno));
                    615:
                    616:        cvs_cmdop = CVS_OP_DIFF;
1.78      tobias    617:        cmdp->cmd_flags = cvs_cmd_diff.cmd_flags;
1.82      tobias    618:        cvs_diff(server_argc, server_argv);
                    619:        cvs_server_send_response("ok");
                    620: }
                    621:
                    622: void
                    623: cvs_server_rdiff(char *data)
                    624: {
                    625:        if (chdir(server_currentdir) == -1)
                    626:                fatal("cvs_server_rdiff: %s", strerror(errno));
                    627:
                    628:        cvs_cmdop = CVS_OP_RDIFF;
                    629:        cmdp->cmd_flags = cvs_cmd_rdiff.cmd_flags;
1.29      joris     630:        cvs_diff(server_argc, server_argv);
1.76      tobias    631:        cvs_server_send_response("ok");
                    632: }
                    633:
                    634: void
                    635: cvs_server_export(char *data)
1.77      tobias    636: {
                    637:        if (chdir(server_currentdir) == -1)
                    638:                fatal("cvs_server_export: %s", strerror(errno));
1.76      tobias    639:
                    640:        cvs_cmdop = CVS_OP_EXPORT;
1.78      tobias    641:        cmdp->cmd_flags = cvs_cmd_export.cmd_flags;
1.90      joris     642:        cvs_export(server_argc, server_argv);
1.34      xsa       643:        cvs_server_send_response("ok");
                    644: }
                    645:
                    646: void
                    647: cvs_server_init(char *data)
                    648: {
1.69      tobias    649:        if (data == NULL)
                    650:                fatal("Missing argument for init");
                    651:
                    652:        if (current_cvsroot != NULL)
                    653:                fatal("Root in combination with init is not supported");
                    654:
                    655:        if ((current_cvsroot = cvsroot_get(data)) == NULL)
                    656:                fatal("Invalid argument for init");
1.34      xsa       657:
                    658:        cvs_cmdop = CVS_OP_INIT;
1.78      tobias    659:        cmdp->cmd_flags = cvs_cmd_init.cmd_flags;
1.34      xsa       660:        cvs_init(server_argc, server_argv);
1.64      xsa       661:        cvs_server_send_response("ok");
                    662: }
                    663:
                    664: void
                    665: cvs_server_release(char *data)
                    666: {
                    667:        if (chdir(server_currentdir) == -1)
1.67      xsa       668:                fatal("cvs_server_release: %s", strerror(errno));
1.64      xsa       669:
                    670:        cvs_cmdop = CVS_OP_RELEASE;
1.78      tobias    671:        cmdp->cmd_flags = cvs_cmd_release.cmd_flags;
1.64      xsa       672:        cvs_release(server_argc, server_argv);
1.31      xsa       673:        cvs_server_send_response("ok");
                    674: }
                    675:
                    676: void
                    677: cvs_server_remove(char *data)
                    678: {
                    679:        if (chdir(server_currentdir) == -1)
                    680:                fatal("cvs_server_remove: %s", strerror(errno));
                    681:
                    682:        cvs_cmdop = CVS_OP_REMOVE;
1.78      tobias    683:        cmdp->cmd_flags = cvs_cmd_remove.cmd_flags;
1.31      xsa       684:        cvs_remove(server_argc, server_argv);
1.29      joris     685:        cvs_server_send_response("ok");
                    686: }
                    687:
                    688: void
                    689: cvs_server_status(char *data)
                    690: {
                    691:        if (chdir(server_currentdir) == -1)
                    692:                fatal("cvs_server_status: %s", strerror(errno));
                    693:
                    694:        cvs_cmdop = CVS_OP_STATUS;
1.78      tobias    695:        cmdp->cmd_flags = cvs_cmd_status.cmd_flags;
1.29      joris     696:        cvs_status(server_argc, server_argv);
                    697:        cvs_server_send_response("ok");
                    698: }
                    699:
                    700: void
                    701: cvs_server_log(char *data)
                    702: {
                    703:        if (chdir(server_currentdir) == -1)
                    704:                fatal("cvs_server_log: %s", strerror(errno));
                    705:
                    706:        cvs_cmdop = CVS_OP_LOG;
1.78      tobias    707:        cmdp->cmd_flags = cvs_cmd_log.cmd_flags;
1.62      niallo    708:        cvs_getlog(server_argc, server_argv);
                    709:        cvs_server_send_response("ok");
                    710: }
1.79      xsa       711:
1.62      niallo    712: void
                    713: cvs_server_rlog(char *data)
                    714: {
1.74      tobias    715:        if (chdir(current_cvsroot->cr_dir) == -1)
1.67      xsa       716:                fatal("cvs_server_rlog: %s", strerror(errno));
1.62      niallo    717:
                    718:        cvs_cmdop = CVS_OP_RLOG;
1.78      tobias    719:        cmdp->cmd_flags = cvs_cmd_rlog.cmd_flags;
1.32      xsa       720:        cvs_getlog(server_argc, server_argv);
                    721:        cvs_server_send_response("ok");
                    722: }
                    723:
                    724: void
                    725: cvs_server_tag(char *data)
                    726: {
                    727:        if (chdir(server_currentdir) == -1)
                    728:                fatal("cvs_server_tag: %s", strerror(errno));
                    729:
                    730:        cvs_cmdop = CVS_OP_TAG;
1.78      tobias    731:        cmdp->cmd_flags = cvs_cmd_tag.cmd_flags;
1.75      tobias    732:        cvs_tag(server_argc, server_argv);
                    733:        cvs_server_send_response("ok");
                    734: }
                    735:
                    736: void
                    737: cvs_server_rtag(char *data)
                    738: {
                    739:        if (chdir(current_cvsroot->cr_dir) == -1)
1.77      tobias    740:                fatal("cvs_server_rtag: %s", strerror(errno));
1.75      tobias    741:
                    742:        cvs_cmdop = CVS_OP_RTAG;
1.78      tobias    743:        cmdp->cmd_flags = cvs_cmd_rtag.cmd_flags;
1.33      xsa       744:        cvs_tag(server_argc, server_argv);
1.29      joris     745:        cvs_server_send_response("ok");
                    746: }
                    747:
                    748: void
                    749: cvs_server_update(char *data)
                    750: {
                    751:        if (chdir(server_currentdir) == -1)
                    752:                fatal("cvs_server_update: %s", strerror(errno));
1.14      joris     753:
1.29      joris     754:        cvs_cmdop = CVS_OP_UPDATE;
1.78      tobias    755:        cmdp->cmd_flags = cvs_cmd_update.cmd_flags;
1.29      joris     756:        cvs_update(server_argc, server_argv);
1.36      xsa       757:        cvs_server_send_response("ok");
                    758: }
                    759:
                    760: void
                    761: cvs_server_version(char *data)
                    762: {
                    763:        cvs_cmdop = CVS_OP_VERSION;
1.78      tobias    764:        cmdp->cmd_flags = cvs_cmd_version.cmd_flags;
1.36      xsa       765:        cvs_version(server_argc, server_argv);
1.29      joris     766:        cvs_server_send_response("ok");
1.47      joris     767: }
                    768:
                    769: void
                    770: cvs_server_update_entry(const char *resp, struct cvs_file *cf)
                    771: {
1.58      ray       772:        char *p;
1.102     deraadt   773:        char repo[PATH_MAX], fpath[PATH_MAX];
1.47      joris     774:
                    775:        if ((p = strrchr(cf->file_rpath, ',')) != NULL)
                    776:                *p = '\0';
                    777:
1.102     deraadt   778:        cvs_get_repository_path(cf->file_wd, repo, PATH_MAX);
                    779:        (void)xsnprintf(fpath, PATH_MAX, "%s/%s", repo, cf->file_name);
1.65      joris     780:
1.58      ray       781:        cvs_server_send_response("%s %s/", resp, cf->file_wd);
1.65      joris     782:        cvs_remote_output(fpath);
1.47      joris     783:
                    784:        if (p != NULL)
                    785:                *p = ',';
1.65      joris     786: }
                    787:
                    788: void
1.105   ! otto      789: cvs_server_set_sticky(const char *dir, char *tag)
1.65      joris     790: {
1.102     deraadt   791:        char fpath[PATH_MAX];
                    792:        char repo[PATH_MAX];
1.65      joris     793:
1.102     deraadt   794:        cvs_get_repository_path(dir, repo, PATH_MAX);
                    795:        (void)xsnprintf(fpath, PATH_MAX, "%s/", repo);
1.65      joris     796:
1.93      joris     797:        cvs_server_send_response("Set-sticky %s/", dir);
1.65      joris     798:        cvs_remote_output(fpath);
1.72      joris     799:        cvs_remote_output(tag);
1.65      joris     800: }
                    801:
                    802: void
                    803: cvs_server_clear_sticky(char *dir)
                    804: {
1.102     deraadt   805:        char fpath[PATH_MAX];
                    806:        char repo[PATH_MAX];
1.65      joris     807:
1.102     deraadt   808:        cvs_get_repository_path(dir, repo, PATH_MAX);
                    809:        (void)xsnprintf(fpath, PATH_MAX, "%s/", repo);
1.65      joris     810:
1.93      joris     811:        cvs_server_send_response("Clear-sticky %s//", dir);
1.65      joris     812:        cvs_remote_output(fpath);
1.96      joris     813: }
                    814:
                    815: void
                    816: cvs_server_exp_modules(char *module)
                    817: {
                    818:        struct module_checkout *mo;
                    819:        struct cvs_filelist *fl;
                    820:
                    821:        if (server_argc != 2)
                    822:                fatal("expand-modules with no arguments");
                    823:
                    824:        mo = cvs_module_lookup(server_argv[1]);
                    825:
                    826:        RB_FOREACH(fl, cvs_flisthead, &(mo->mc_modules))
                    827:                cvs_server_send_response("Module-expansion %s", fl->file_path);
                    828:        cvs_server_send_response("ok");
                    829:
                    830:        server_argc--;
1.103     nicm      831:        free(server_argv[1]);
1.96      joris     832:        server_argv[1] = NULL;
1.1       jfb       833: }