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

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