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

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