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

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