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