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

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