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