Expand PMF_FN_* macros.
[netbsd-mini2440.git] / usr.sbin / sup / source / supscan.c
blobe3cd354802600fe07dc7d7e694d990de7e90d2c8
1 /* $NetBSD: supscan.c,v 1.17 2009/10/16 22:45:18 christos Exp $ */
3 /*
4 * Copyright (c) 1992 Carnegie Mellon University
5 * All Rights Reserved.
7 * Permission to use, copy, modify and distribute this software and its
8 * documentation is hereby granted, provided that both the copyright
9 * notice and this permission notice appear in all copies of the
10 * software, derivative works or modified versions, and any portions
11 * thereof, and that both notices appear in supporting documentation.
13 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
14 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
15 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
17 * Carnegie Mellon requests users of this software to return to
19 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
20 * School of Computer Science
21 * Carnegie Mellon University
22 * Pittsburgh PA 15213-3890
24 * any improvements or extensions that they make and grant Carnegie Mellon
25 * the rights to redistribute these changes.
28 * supscan -- SUP Scan File Builder
30 * Usage: supscan [ -v ] collection [ basedir ]
31 * supscan [ -v ] -f dirfile
32 * supscan [ -v ] -s
33 * -f "file" -- use dirfile instead of system coll.dir
34 * -s "system" -- perform scan for system supfile
35 * -v "verbose" -- print messages as you go
36 * collection -- name of the desired collection if not -s
37 * basedir -- name of the base directory, if not
38 * the default or recorded in coll.dir
39 * dirfile -- name of replacement for system coll.dir.
41 **********************************************************************
42 * HISTORY
43 * Revision 1.14 92/08/11 12:08:30 mrt
44 * Picked up Brad's deliniting and variable argument changes
45 * [92/08/10 mrt]
47 * Revision 1.13 92/02/08 18:04:44 dlc
48 * Once again revised localhost(). Do not use gethostbyname() at
49 * all, but assume that the host names in the coll.host file are at
50 * least a prefix of the fully qualified name. Modcoll (and related
51 * scripts) will maintain this fact.
52 * [92/02/08 dlc]
54 * Revision 1.12 91/08/17 23:35:31 dlc
55 * Changes to localhost() function:
56 * - Use host name in kernel for local host name; assume it is
57 * fully qualified.
58 * - If gethostbyname() of host to see if we are the repository
59 * fails, with TRY_AGAIN or NO_RECOVERY, then use the "host"
60 * parameter. Print a diagnostic in this case.
61 * [91/08/17 dlc]
63 * Revision 1.11 90/04/04 10:53:01 dlc
64 * Changed localhost to retry getting the local host name 4 times with
65 * 30 second sleep intervals before aborting; after 4 tries, things are
66 * probably too messed up for the supscan to do anything useful
67 * [90/04/04 dlc]
69 * Revision 1.10 89/08/03 19:49:33 mja
70 * Updated to use v*printf() in place of _doprnt().
71 * [89/04/19 mja]
73 * Revision 1.9 89/06/18 14:41:37 gm0w
74 * Fixed up some notify messages of errors to use "SUP:" prefix.
75 * [89/06/18 gm0w]
77 * 13-May-88 Glenn Marcy (gm0w) at Carnegie-Mellon University
78 * Changed goaway to longjmp back to top-level to scan next
79 * collection. [V7.6]
81 * 19-Feb-88 Glenn Marcy (gm0w) at Carnegie-Mellon University
82 * Added -f <filename> switch to scan all (or part) of the
83 * collections in a file of collection/base-directory pairs.
84 * [V7.5]
86 * 27-Dec-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
87 * Removed nameserver support (which means to use a new
88 * datafile).
90 * 09-Sep-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
91 * Use case-insensitive hostname comparison.
93 * 28-Jun-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
94 * Added code for "release" support. [V6.4]
96 * 05-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
97 * Changed collection setup errors to be non-fatal. [V5.3]
99 * 29-Dec-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
100 * Moved most of the scanning code to scan.c. [V4.2]
102 * 02-Nov-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
103 * Added "-s" option.
105 * 22-Sep-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
106 * Merged 4.1 and 4.2 versions together.
108 * 04-Jun-85 Steven Shafer (sas) at Carnegie-Mellon University
109 * Created for 4.2 BSD.
111 **********************************************************************
114 #include <netdb.h>
115 #include <setjmp.h>
116 #include <stdarg.h>
117 #include <sys/time.h>
118 #include <sys/resource.h>
119 #include <sys/param.h>
120 #include "supcdefs.h"
121 #include "supextern.h"
122 #include "libc.h"
123 #include "c.h"
125 #define PGMVERSION 6
127 /*******************************************
128 *** D A T A S T R U C T U R E S ***
129 *******************************************/
131 struct scan_collstruct { /* one per collection to be upgraded */
132 char *Cname; /* collection name */
133 char *Cbase; /* local base directory */
134 char *Cprefix; /* local collection pathname prefix */
135 struct scan_collstruct *Cnext; /* next collection */
137 typedef struct scan_collstruct SCAN_COLLECTION;
139 /*********************************************
140 *** G L O B A L V A R I A B L E S ***
141 *********************************************/
143 int trace; /* -v flag */
144 int quiet; /* -q flag */
146 SCAN_COLLECTION *firstC; /* collection list pointer */
147 char *collname; /* collection name */
148 char *basedir; /* base directory name */
149 char *prefix; /* collection pathname prefix */
150 time_t lasttime = 0; /* time of last upgrade */
151 time_t scantime; /* time of this scan */
152 int newonly = FALSE; /* new files only */
153 jmp_buf sjbuf; /* jump location for errors */
155 TREELIST *listTL; /* list of all files specified by <coll>.list */
156 TREE *listT; /* final list of files in collection */
157 TREE *refuseT = NULL; /* list of all files specified by <coll>.list */
160 void usage(void);
161 void init(int, char **);
162 static SCAN_COLLECTION *getscancoll(char *, char *, char *);
163 int localhost(char *);
164 int main(int, char **);
166 /*************************************
167 *** M A I N R O U T I N E ***
168 *************************************/
171 main(int argc, char **argv)
173 SCAN_COLLECTION * volatile c; /* Avoid longjmp clobbering */
174 #ifdef RLIMIT_DATA
175 struct rlimit dlim;
177 if (getrlimit(RLIMIT_DATA, &dlim) == -1)
178 goaway("Error getting resource limit (%s)",
179 strerror(errno));
180 if (dlim.rlim_cur != dlim.rlim_max) {
181 dlim.rlim_cur = dlim.rlim_max;
182 if (setrlimit(RLIMIT_DATA, &dlim) == -1)
183 goaway("Error setting resource limit (%s)",
184 strerror(errno));
186 #endif
188 init(argc, argv); /* process arguments */
189 for (c = firstC; c; c = c->Cnext) {
190 collname = c->Cname;
191 basedir = c->Cbase;
192 prefix = c->Cprefix;
193 (void) chdir(basedir);
194 scantime = time((time_t *) NULL);
195 if (!quiet)
196 printf("SUP Scan for %s starting at %s", collname,
197 ctime(&scantime));
198 (void) fflush(stdout);
199 if (!setjmp(sjbuf)) {
200 makescanlists(); /* record names in scan files */
201 scantime = time((time_t *) NULL);
202 if (!quiet)
203 printf("SUP Scan for %s completed at %s",
204 collname, ctime(&scantime));
205 } else
206 fprintf(stderr,
207 "SUP: Scan for %s aborted at %s", collname,
208 ctime(&scantime));
209 if (!quiet)
210 (void) fflush(stdout);
212 while ((c = firstC) != NULL) {
213 firstC = firstC->Cnext;
214 free(c->Cname);
215 free(c->Cbase);
216 if (c->Cprefix)
217 free(c->Cprefix);
218 free(c);
220 exit(0);
222 /*****************************************
223 *** I N I T I A L I Z A T I O N ***
224 *****************************************/
226 void
227 usage(void)
229 fprintf(stderr, "Usage: supscan [ -vq ] collection [ basedir ]\n");
230 fprintf(stderr, " supscan [ -vq ] -f dirfile\n");
231 fprintf(stderr, " supscan [ -vq ] -s\n");
232 exit(1);
235 void
236 init(int argc, char **argv)
238 char buf[STRINGLENGTH], fbuf[STRINGLENGTH], *p, *q;
239 FILE *f;
240 SCAN_COLLECTION **c;
241 int fflag, sflag;
242 char *filename = NULL;
244 quiet = FALSE;
245 trace = FALSE;
246 fflag = FALSE;
247 sflag = FALSE;
248 while (argc > 1 && argv[1][0] == '-') {
249 switch (argv[1][1]) {
250 case 'f':
251 fflag = TRUE;
252 if (argc == 2)
253 usage();
254 --argc;
255 argv++;
256 filename = argv[1];
257 break;
258 case 'q':
259 quiet = TRUE;
260 break;
261 case 'v':
262 trace = TRUE;
263 break;
264 case 's':
265 sflag = TRUE;
266 break;
267 default:
268 fprintf(stderr, "supscan: Invalid flag %s ignored\n",
269 argv[1]);
270 (void) fflush(stderr);
272 --argc;
273 argv++;
275 if (!fflag) {
276 (void) sprintf(fbuf, FILEDIRS, DEFDIR);
277 filename = fbuf;
279 if (sflag) {
280 if (argc != 1)
281 usage();
282 firstC = NULL;
283 c = &firstC;
284 (void) sprintf(buf, FILEHOSTS, DEFDIR);
285 if ((f = fopen(buf, "r")) == NULL)
286 quit(1, "supscan: Unable to open %s\n", buf);
287 while ((p = fgets(buf, STRINGLENGTH, f)) != NULL) {
288 q = strchr(p, '\n');
289 if (q)
290 *q = 0;
291 if (strchr("#;:", *p))
292 continue;
293 collname = nxtarg(&p, " \t=");
294 p = skipover(p, " \t=");
295 if (!localhost(p))
296 continue;
297 *c = getscancoll(filename, estrdup(collname),
298 (char *) NULL);
299 if (*c)
300 c = &((*c)->Cnext);
302 (void) fclose(f);
303 return;
305 if (argc < 2 && fflag) {
306 firstC = NULL;
307 c = &firstC;
308 if ((f = fopen(filename, "r")) == NULL)
309 quit(1, "supscan: Unable to open %s\n", filename);
310 while ((p = fgets(buf, STRINGLENGTH, f)) != NULL) {
311 q = strchr(p, '\n');
312 if (q)
313 *q = 0;
314 if (strchr("#;:", *p))
315 continue;
316 q = nxtarg(&p, " \t=");
317 p = skipover(p, " \t=");
318 *c = getscancoll(filename, estrdup(q), estrdup(p));
319 if (*c)
320 c = &((*c)->Cnext);
322 (void) fclose(f);
323 return;
325 if (argc < 2 || argc > 3)
326 usage();
327 firstC = getscancoll(filename, estrdup(argv[1]),
328 argc > 2 ? estrdup(argv[2]) : (char *) NULL);
331 static SCAN_COLLECTION *
332 getscancoll(char *filename, char *collname, char *basedir)
334 char buf[STRINGLENGTH], *p, *q;
335 FILE *f;
336 SCAN_COLLECTION *c;
338 if (basedir == NULL) {
339 if ((f = fopen(filename, "r")) != NULL) {
340 while ((p = fgets(buf, STRINGLENGTH, f)) != NULL) {
341 q = strchr(p, '\n');
342 if (q)
343 *q = 0;
344 if (strchr("#;:", *p))
345 continue;
346 q = nxtarg(&p, " \t=");
347 if (strcmp(q, collname) == 0) {
348 p = skipover(p, " \t=");
349 basedir = estrdup(p);
350 break;
353 (void) fclose(f);
355 if (basedir == NULL) {
356 (void) sprintf(buf, FILEBASEDEFAULT, collname);
357 basedir = estrdup(buf);
360 if (chdir(basedir) < 0) {
361 fprintf(stderr, "supscan: Can't chdir to base directory %s for %s\n",
362 basedir, collname);
363 return (NULL);
365 prefix = NULL;
366 (void) sprintf(buf, FILEPREFIX, collname);
367 if ((f = fopen(buf, "r")) != NULL) {
368 while ((p = fgets(buf, STRINGLENGTH, f)) != NULL) {
369 q = strchr(p, '\n');
370 if (q)
371 *q = 0;
372 if (strchr("#;:", *p))
373 continue;
374 prefix = estrdup(p);
375 if (chdir(prefix) < 0) {
376 fprintf(stderr, "supscan: can't chdir to %s from base directory %s for %s\n",
377 prefix, basedir, collname);
378 fclose(f);
379 free(prefix);
380 return (NULL);
382 break;
384 (void) fclose(f);
386 if ((c = (SCAN_COLLECTION *) malloc(sizeof(SCAN_COLLECTION))) == NULL)
387 quit(1, "supscan: can't malloc collection structure\n");
388 c->Cname = collname;
389 c->Cbase = basedir;
390 c->Cprefix = prefix;
391 c->Cnext = NULL;
392 return (c);
395 void
396 goaway(const char *fmt, ...)
398 va_list ap;
400 va_start(ap, fmt);
401 vfprintf(stderr, fmt, ap);
402 va_end(ap);
403 (void) putc('\n', stderr);
404 (void) fflush(stderr);
405 longjmp(sjbuf, TRUE);
408 int
409 localhost(char *host)
411 static char myhost[MAXHOSTNAMELEN + 1];
412 static unsigned int myhostlen;
413 unsigned int hostlen;
415 if (*myhost == '\0') {
417 * We assume that the host name in the kernel is the
418 * fully qualified form.
420 if (gethostname(myhost, sizeof(myhost)) < 0) {
421 quit(1, "supscan: can't get kernel host name\n");
423 myhost[sizeof(myhost) - 1] = '\0';
424 myhostlen = strlen(myhost);
427 * Here, we assume that the 'host' parameter from the
428 * coll.host file is at least a prefix of the fully qualified
429 * host name of some machine. This will be true when modcoll(8)
430 * (and related scripts) maintain the relevant files, but if
431 * a person makes a manual change, problems could result. In
432 * particular, if a nicname, such as "Y" for "GANDALF.CS.CMU.EDU"
433 * is present in the coll.host file, things will not work as
434 * expected.
437 hostlen = strlen(host);
439 return (strncasecmp(myhost, host,
440 hostlen < myhostlen ? hostlen : myhostlen) == 0);