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