Annotation of src/usr.bin/cvs/modules.c, Revision 1.18
1.18 ! deraadt 1: /* $OpenBSD: modules.c,v 1.17 2014/01/08 13:23:55 okan Exp $ */
1.1 joris 2: /*
3: * Copyright (c) 2008 Joris Vink <joris@openbsd.org>
4: *
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.
8: *
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.
16: */
17:
1.18 ! deraadt 18: #include <sys/types.h>
1.1 joris 19: #include <sys/dirent.h>
20: #include <sys/resource.h>
21:
1.9 tobias 22: #include <ctype.h>
1.1 joris 23: #include <stdlib.h>
24: #include <string.h>
25:
26: #include "cvs.h"
27: #include "config.h"
28:
29: TAILQ_HEAD(, module_info) modules;
30:
1.3 joris 31: struct module_checkout *current_module = NULL;
32: char *module_repo_root = NULL;
33:
1.1 joris 34: void
35: cvs_parse_modules(void)
36: {
37: cvs_log(LP_TRACE, "cvs_parse_modules()");
38:
39: TAILQ_INIT(&modules);
40: cvs_read_config(CVS_PATH_MODULES, modules_parse_line);
41: }
42:
43: void
1.10 joris 44: cvs_modules_list(void)
45: {
46: struct module_info *mi;
47:
48: TAILQ_FOREACH(mi, &modules, m_list)
1.16 joris 49: cvs_printf("%s\n", mi->mi_str);
1.10 joris 50: }
51:
1.12 joris 52: int
1.7 joris 53: modules_parse_line(char *line, int lineno)
1.1 joris 54: {
55: int flags;
1.7 joris 56: struct module_info *mi;
1.10 joris 57: char *bline, *val, *p, *module, *sp, *dp;
1.18 ! deraadt 58: char *dirname, fpath[PATH_MAX], *prog;
1.1 joris 59:
1.11 joris 60: prog = NULL;
1.10 joris 61: bline = xstrdup(line);
62:
1.1 joris 63: flags = 0;
64: p = val = line;
1.17 okan 65: while (!isspace((unsigned char)*p) && *p != '\0')
1.1 joris 66: p++;
67:
1.7 joris 68: if (*p == '\0')
69: goto bad;
70:
1.1 joris 71: *(p++) = '\0';
72: module = val;
73:
1.17 okan 74: while (isspace((unsigned char)*p))
1.1 joris 75: p++;
76:
1.7 joris 77: if (*p == '\0')
78: goto bad;
1.1 joris 79:
80: val = p;
1.17 okan 81: while (!isspace((unsigned char)*p) && *p != '\0')
1.1 joris 82: p++;
83:
84: while (val[0] == '-') {
85: p = val;
1.17 okan 86: while (!isspace((unsigned char)*p) && *p != '\0')
1.1 joris 87: p++;
88:
1.7 joris 89: if (*p == '\0')
90: goto bad;
1.1 joris 91:
92: *(p++) = '\0';
93:
94: switch (val[1]) {
95: case 'a':
1.3 joris 96: if (flags & MODULE_TARGETDIR) {
97: cvs_log(LP_NOTICE, "cannot use -a with -d");
1.11 joris 98: goto bad;
1.3 joris 99: }
100: flags |= MODULE_ALIAS;
101: break;
102: case 'd':
103: if (flags & MODULE_ALIAS) {
104: cvs_log(LP_NOTICE, "cannot use -d with -a");
1.11 joris 105: goto bad;
1.3 joris 106: }
107: flags |= MODULE_TARGETDIR;
108: break;
109: case 'l':
110: flags |= MODULE_NORECURSE;
1.8 joris 111: break;
112: case 'o':
113: if (flags != 0 || prog != NULL) {
114: cvs_log(LP_NOTICE,
115: "-o cannot be used with other flags");
1.11 joris 116: goto bad;
1.8 joris 117: }
118:
1.9 tobias 119: val = p;
1.17 okan 120: while (!isspace((unsigned char)*val) && *val != '\0')
1.9 tobias 121: val++;
122: if (*val == '\0')
1.8 joris 123: goto bad;
124:
125: *(val++) = '\0';
126: prog = xstrdup(p);
127: p = val;
128: flags |= MODULE_RUN_ON_CHECKOUT;
1.1 joris 129: break;
1.4 joris 130: case 'i':
1.7 joris 131: if (flags != 0 || prog != NULL) {
1.4 joris 132: cvs_log(LP_NOTICE,
133: "-i cannot be used with other flags");
1.11 joris 134: goto bad;
1.4 joris 135: }
1.7 joris 136:
137: if ((val = strchr(p, ' ' )) == NULL)
138: goto bad;
139:
140: *(val++) = '\0';
141: prog = xstrdup(p);
142: p = val;
1.4 joris 143: flags |= MODULE_RUN_ON_COMMIT;
144: break;
1.10 joris 145: default:
146: goto bad;
1.1 joris 147: }
148:
149: val = p;
150: }
151:
1.7 joris 152: if (*val == '\0')
153: goto bad;
1.4 joris 154:
1.1 joris 155: mi = xmalloc(sizeof(*mi));
156: mi->mi_name = xstrdup(module);
1.3 joris 157: mi->mi_flags = flags;
1.7 joris 158: mi->mi_prog = prog;
1.10 joris 159: mi->mi_str = bline;
1.4 joris 160:
161: dirname = NULL;
1.14 joris 162: RB_INIT(&(mi->mi_modules));
163: RB_INIT(&(mi->mi_ignores));
164:
1.9 tobias 165: for (sp = val; *sp != '\0'; sp = dp) {
166: dp = sp;
1.17 okan 167: while (!isspace((unsigned char)*dp) && *dp != '\0')
1.9 tobias 168: dp++;
169: if (*dp != '\0')
1.4 joris 170: *(dp++) = '\0';
171:
172: if (mi->mi_flags & MODULE_ALIAS) {
1.5 joris 173: if (sp[0] == '!') {
174: if (strlen(sp) < 2)
175: fatal("invalid ! pattern");
1.15 joris 176: cvs_file_get((sp + 1), 0,
177: &(mi->mi_ignores), 0);
1.5 joris 178: } else {
1.15 joris 179: cvs_file_get(sp, 0,
180: &(mi->mi_modules), 0);
1.5 joris 181: }
1.4 joris 182: } else if (sp == val) {
183: dirname = sp;
184: } else {
185: if (sp[0] == '!') {
1.5 joris 186: if (strlen(sp) < 2)
187: fatal("invalid ! pattern");
188:
1.4 joris 189: sp++;
190: (void)xsnprintf(fpath, sizeof(fpath), "%s/%s",
191: dirname, sp);
1.15 joris 192: cvs_file_get(fpath, 0,
193: &(mi->mi_ignores), 0);
1.4 joris 194: } else {
195: (void)xsnprintf(fpath, sizeof(fpath), "%s/%s",
196: dirname, sp);
1.15 joris 197: cvs_file_get(fpath, 0,
198: &(mi->mi_modules), 0);
1.4 joris 199: }
200: }
201: }
202:
1.14 joris 203: if (!(mi->mi_flags & MODULE_ALIAS) && RB_EMPTY(&(mi->mi_modules)))
1.15 joris 204: cvs_file_get(dirname, 0, &(mi->mi_modules), 0);
1.4 joris 205:
1.1 joris 206: TAILQ_INSERT_TAIL(&modules, mi, m_list);
1.12 joris 207: return (0);
1.7 joris 208:
209: bad:
1.11 joris 210: if (prog != NULL)
211: xfree(prog);
212: xfree(bline);
1.7 joris 213: cvs_log(LP_NOTICE, "malformed line in CVSROOT/modules: %d", lineno);
1.12 joris 214: return (0);
1.1 joris 215: }
216:
1.3 joris 217: struct module_checkout *
1.1 joris 218: cvs_module_lookup(char *name)
219: {
1.3 joris 220: struct module_checkout *mc;
1.1 joris 221: struct module_info *mi;
222:
1.3 joris 223: mc = xmalloc(sizeof(*mc));
224:
1.1 joris 225: TAILQ_FOREACH(mi, &modules, m_list) {
1.3 joris 226: if (!strcmp(name, mi->mi_name)) {
1.4 joris 227: mc->mc_modules = mi->mi_modules;
228: mc->mc_ignores = mi->mi_ignores;
229: mc->mc_canfree = 0;
1.7 joris 230: mc->mc_name = mi->mi_name;
1.3 joris 231: mc->mc_flags = mi->mi_flags;
1.7 joris 232: mc->mc_prog = mi->mi_prog;
1.3 joris 233: return (mc);
234: }
1.1 joris 235: }
236:
1.14 joris 237: RB_INIT(&(mc->mc_modules));
238: RB_INIT(&(mc->mc_ignores));
1.15 joris 239: cvs_file_get(name, 0, &(mc->mc_modules), 0);
1.4 joris 240: mc->mc_canfree = 1;
1.7 joris 241: mc->mc_name = name;
1.13 tobias 242: mc->mc_flags = MODULE_ALIAS;
1.7 joris 243: mc->mc_prog = NULL;
1.3 joris 244:
245: return (mc);
1.1 joris 246: }