Annotation of src/usr.bin/cvs/rcsprog.c, Revision 1.5
1.5 ! jfb 1: /* $OpenBSD: rcsprog.c,v 1.4 2005/04/11 18:02:58 joris Exp $ */
1.1 jfb 2: /*
3: * Copyright (c) 2005 Jean-Francois Brousseau <jfb@openbsd.org>
4: * All rights reserved.
5: *
6: * Redistribution and use in source and binary forms, with or without
7: * modification, are permitted provided that the following conditions
8: * are met:
9: *
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. The name of the author may not be used to endorse or promote products
13: * derived from this software without specific prior written permission.
14: *
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18: * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25: */
26:
27: #include <sys/types.h>
28: #include <sys/wait.h>
29:
30: #include <err.h>
31: #include <pwd.h>
32: #include <errno.h>
33: #include <stdio.h>
34: #include <ctype.h>
35: #include <stdlib.h>
36: #include <unistd.h>
37: #include <signal.h>
38: #include <string.h>
39:
40: #include "log.h"
41: #include "rcs.h"
1.3 joris 42: #include "strtab.h"
1.1 jfb 43:
44: extern char *__progname;
45:
46:
47: const char rcs_version[] = "OpenCVS RCS version 3.6";
48:
49: void rcs_usage (void);
50: int rcs_main (int, char **);
51:
52:
53:
54: struct rcs_prog {
55: char *prog_name;
56: int (*prog_hdlr)(int, char **);
57: } programs[] = {
58: { "rcs", rcs_main },
59: { "ci", NULL },
60: { "co", NULL },
61: { "rcsclean", NULL },
62: { "rcsdiff", NULL },
63: };
64:
65:
66: int
67: main(int argc, char **argv)
68: {
69: u_int i;
1.3 joris 70: int ret;
71:
72: ret = -1;
73: cvs_strtab_init();
1.1 jfb 74:
75: for (i = 0; i < (sizeof(programs)/sizeof(programs[0])); i++)
76: if (strcmp(__progname, programs[i].prog_name) == 0)
1.3 joris 77: ret = programs[i].prog_hdlr(argc, argv);
1.1 jfb 78:
1.3 joris 79: cvs_strtab_cleanup();
1.1 jfb 80:
1.3 joris 81: return (ret);
1.1 jfb 82: }
83:
84:
85: void
86: rcs_usage(void)
87: {
88: fprintf(stderr,
1.2 jmc 89: "Usage: %s [-hiLMUV] [-a users] [-b [rev]] [-c string] "
1.1 jfb 90: "[-e users] [-k opt] file ...\n"
91: "\t-a users\tAdd the login names in the comma-separated <users>\n"
92: "\t-b rev\t\tSet the head revision to <rev>\n"
93: "\t-c string\tSet the comment leader to <string>\n"
94: "\t-e users\tRemove the login names in the comma-separated <users>\n"
95: "\t-h\t\tPrint the program's usage and exit\n"
96: "\t-i\t\tCreate a new empty RCS file\n"
97: "\t-k opt\t\tSet the keyword expansion mode to <opt>\n"
98: "\t-L\t\tEnable strict locking on the specified files\n"
99: "\t-M\t\tDisable mail warning about lock breaks\n"
100: "\t-U\t\tDisable strict locking on the specified files\n"
101: "\t-V\t\tPrint the program's version string and exit\n",
102: __progname);
103: }
104:
105:
106: /*
107: * rcs_main()
108: *
109: * Handler for the `rcs' program.
110: * Returns 0 on success, or >0 on error.
111: */
112: int
113: rcs_main(int argc, char **argv)
114: {
115: int i, ch, flags, kflag, lkmode;
116: char *oldfile, *alist, *comment, *elist, *unp, *sp;
117: mode_t fmode;
118: RCSFILE *file;
119:
120: kflag = lkmode = -1;
121: fmode = 0;
1.5 ! jfb 122: flags = RCS_RDWR;
1.1 jfb 123: oldfile = alist = comment = elist = NULL;
124:
125: cvs_log_init(LD_STD, 0);
126:
127: while ((ch = getopt(argc, argv, "A:a:b::c:e::hik:LMUV")) != -1) {
128: switch (ch) {
129: case 'A':
130: oldfile = optarg;
131: break;
132: case 'a':
133: alist = optarg;
134: break;
135: case 'c':
136: comment = optarg;
137: break;
138: case 'e':
139: elist = optarg;
140: break;
141: case 'h':
142: rcs_usage();
143: exit(0);
144: case 'i':
1.5 ! jfb 145: flags |= RCS_CREATE;
1.1 jfb 146: break;
147: case 'k':
148: kflag = rcs_kflag_get(optarg);
149: if (RCS_KWEXP_INVAL(kflag)) {
150: cvs_log(LP_ERR,
151: "invalid keyword substitution mode `%s'",
152: optarg);
153: exit(1);
154: }
155: break;
156: case 'L':
157: if (lkmode == RCS_LOCK_LOOSE)
158: cvs_log(LP_WARN, "-U overriden by -L");
159: lkmode = RCS_LOCK_STRICT;
160: break;
161: case 'M':
162: /* ignore for the moment */
163: break;
164: case 'U':
165: if (lkmode == RCS_LOCK_STRICT)
166: cvs_log(LP_WARN, "-L overriden by -U");
167: lkmode = RCS_LOCK_LOOSE;
168: break;
169: case 'V':
170: printf("%s\n", rcs_version);
171: exit(0);
172: default:
173: rcs_usage();
174: exit(1);
175: }
176: }
177:
178: argc -= optind;
179: argv += optind;
180: if (argc == 0) {
181: cvs_log(LP_ERR, "no input file");
182: exit(1);
183: }
184:
185: for (i = 0; i < argc; i++) {
186: printf("RCS file: %s\n", argv[0]);
187: file = rcs_open(argv[0], flags, fmode);
188: if (file == NULL) {
189: return (1);
190: }
191:
192: /* entries to add to the access list */
193: if (alist != NULL) {
194: unp = alist;
195: do {
196: sp = strchr(unp, ',');
197: if (sp != NULL)
198: *(sp++) = '\0';
199:
200: rcs_access_add(file, unp);
201:
202: unp = sp;
203: } while (sp != NULL);
204: }
205:
206: if (comment != NULL)
207: rcs_comment_set(file, comment);
208:
209: if (kflag != -1)
210: rcs_kwexp_set(file, kflag);
211:
212: if (lkmode != -1)
213: rcs_lock_setmode(file, lkmode);
214:
215: rcs_close(file);
216: printf("done\n");
217: }
218:
219: return (0);
220: }