Annotation of src/usr.bin/rcs/rcsprog.c, Revision 1.18
1.18 ! joris 1: /* $OpenBSD: rcsprog.c,v 1.17 2005/09/30 17:34:58 joris Exp $ */
1.1 deraadt 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:
1.6 joris 27: #include <sys/param.h>
1.1 deraadt 28: #include <sys/wait.h>
1.8 joris 29: #include <sys/stat.h>
1.1 deraadt 30:
1.3 joris 31: #include <ctype.h>
1.1 deraadt 32: #include <err.h>
1.3 joris 33: #include <errno.h>
1.1 deraadt 34: #include <pwd.h>
1.3 joris 35: #include <signal.h>
36: #include <string.h>
1.1 deraadt 37: #include <stdio.h>
38: #include <stdlib.h>
39: #include <unistd.h>
40:
41: #include "log.h"
42: #include "rcs.h"
1.9 joris 43: #include "rcsprog.h"
1.1 deraadt 44: #include "strtab.h"
45:
46: const char rcs_version[] = "OpenCVS RCS version 3.6";
1.12 joris 47: int verbose = 1;
1.1 deraadt 48:
49: struct rcs_prog {
50: char *prog_name;
51: int (*prog_hdlr)(int, char **);
1.2 deraadt 52: void (*prog_usage)(void);
1.1 deraadt 53: } programs[] = {
1.2 deraadt 54: { "rcs", rcs_main, rcs_usage },
1.17 joris 55: { "ci", checkin_main, checkin_usage },
1.11 joris 56: { "co", checkout_main, checkout_usage },
1.2 deraadt 57: { "rcsclean", NULL, NULL },
1.18 ! joris 58: { "rcsdiff", rcsdiff_main, rcsdiff_usage },
1.7 joris 59: { "ident", NULL, NULL },
1.1 deraadt 60: };
61:
1.9 joris 62: int
63: rcs_statfile(char *fname, char *out, size_t len)
64: {
65: int l;
66: char *s;
67: char filev[MAXPATHLEN], fpath[MAXPATHLEN];
68: struct stat st;
69:
70: l = snprintf(filev, sizeof(filev), "%s%s", fname, RCS_FILE_EXT);
71: if (l == -1 || l >= (int)sizeof(filev))
72: return (-1);
73:
1.16 joris 74: if ((stat(RCSDIR, &st) != -1) && (st.st_mode & S_IFDIR)) {
1.9 joris 75: l = snprintf(fpath, sizeof(fpath), "%s/%s", RCSDIR, filev);
76: if (l == -1 || l >= (int)sizeof(fpath))
77: return (-1);
78: } else {
79: strlcpy(fpath, filev, sizeof(fpath));
80: }
81:
82: if (stat(fpath, &st) == -1) {
83: cvs_log(LP_ERRNO, "%s", fpath);
84: return (-1);
85: }
86:
87: strlcpy(out, fpath, len);
1.14 xsa 88: if (verbose == 1) {
1.12 joris 89: if (!strcmp(__progname, "co")) {
90: printf("%s --> ", filev);
91: if ((s = strrchr(filev, ',')) != NULL) {
92: *s = '\0';
93: printf("%s\n", fname);
94: }
95: } else {
96: printf("RCS file: %s\n", fpath);
1.9 joris 97: }
98: }
99:
100: return (0);
101: }
1.1 deraadt 102:
103: int
104: main(int argc, char **argv)
105: {
106: u_int i;
107: int ret;
108:
109: ret = -1;
110: cvs_strtab_init();
1.9 joris 111: cvs_log_init(LD_STD, 0);
1.1 deraadt 112:
113: for (i = 0; i < (sizeof(programs)/sizeof(programs[0])); i++)
1.2 deraadt 114: if (strcmp(__progname, programs[i].prog_name) == 0) {
115: usage = programs[i].prog_usage;
1.1 deraadt 116: ret = programs[i].prog_hdlr(argc, argv);
1.2 deraadt 117: break;
118: }
1.1 deraadt 119:
120: cvs_strtab_cleanup();
121:
122: return (ret);
123: }
124:
125:
126: void
127: rcs_usage(void)
128: {
129: fprintf(stderr,
1.2 deraadt 130: "usage: %s [-hiLMUV] [-a users] [-b [rev]] [-c string] "
131: "[-e users] [-k opt] file ...\n", __progname);
1.1 deraadt 132: }
133:
134: /*
135: * rcs_main()
136: *
137: * Handler for the `rcs' program.
138: * Returns 0 on success, or >0 on error.
139: */
140: int
141: rcs_main(int argc, char **argv)
142: {
143: int i, ch, flags, kflag, lkmode;
1.10 joris 144: char fpath[MAXPATHLEN];
1.1 deraadt 145: char *oldfile, *alist, *comment, *elist, *unp, *sp;
146: mode_t fmode;
147: RCSFILE *file;
148:
149: kflag = lkmode = -1;
150: fmode = 0;
151: flags = RCS_RDWR;
152: oldfile = alist = comment = elist = NULL;
153:
1.12 joris 154: while ((ch = getopt(argc, argv, "A:a:b::c:e::hik:LMqUV")) != -1) {
1.1 deraadt 155: switch (ch) {
156: case 'A':
157: oldfile = optarg;
158: break;
159: case 'a':
160: alist = optarg;
161: break;
162: case 'c':
163: comment = optarg;
164: break;
165: case 'e':
166: elist = optarg;
167: break;
168: case 'h':
1.2 deraadt 169: (usage)();
1.1 deraadt 170: exit(0);
171: case 'i':
172: flags |= RCS_CREATE;
173: break;
174: case 'k':
175: kflag = rcs_kflag_get(optarg);
176: if (RCS_KWEXP_INVAL(kflag)) {
177: cvs_log(LP_ERR,
178: "invalid keyword substitution mode `%s'",
179: optarg);
180: exit(1);
181: }
182: break;
183: case 'L':
184: if (lkmode == RCS_LOCK_LOOSE)
185: cvs_log(LP_WARN, "-U overriden by -L");
186: lkmode = RCS_LOCK_STRICT;
187: break;
188: case 'M':
189: /* ignore for the moment */
190: break;
1.12 joris 191: case 'q':
192: verbose = 0;
193: break;
1.1 deraadt 194: case 'U':
195: if (lkmode == RCS_LOCK_STRICT)
196: cvs_log(LP_WARN, "-L overriden by -U");
197: lkmode = RCS_LOCK_LOOSE;
198: break;
199: case 'V':
200: printf("%s\n", rcs_version);
201: exit(0);
202: default:
1.2 deraadt 203: (usage)();
1.1 deraadt 204: exit(1);
205: }
206: }
207:
208: argc -= optind;
209: argv += optind;
210: if (argc == 0) {
211: cvs_log(LP_ERR, "no input file");
1.5 joris 212: (usage)();
1.1 deraadt 213: exit(1);
214: }
215:
216: for (i = 0; i < argc; i++) {
1.9 joris 217: if (rcs_statfile(argv[i], fpath, sizeof(fpath)) < 0)
1.8 joris 218: continue;
1.6 joris 219:
220: file = rcs_open(fpath, flags, fmode);
221: if (file == NULL)
222: continue;
1.1 deraadt 223:
224: /* entries to add to the access list */
225: if (alist != NULL) {
226: unp = alist;
227: do {
228: sp = strchr(unp, ',');
229: if (sp != NULL)
230: *(sp++) = '\0';
231:
232: rcs_access_add(file, unp);
233:
234: unp = sp;
235: } while (sp != NULL);
236: }
237:
238: if (comment != NULL)
239: rcs_comment_set(file, comment);
240:
241: if (kflag != -1)
242: rcs_kwexp_set(file, kflag);
243:
244: if (lkmode != -1)
245: rcs_lock_setmode(file, lkmode);
246:
247: rcs_close(file);
1.9 joris 248:
1.14 xsa 249: if (verbose == 1)
1.12 joris 250: printf("done\n");
1.1 deraadt 251: }
252:
253: return (0);
254: }