1 /* $NetBSD: supscan.c,v 1.17 2009/10/16 22:45:18 christos Exp $ */
4 * Copyright (c) 1992 Carnegie Mellon University
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
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 **********************************************************************
43 * Revision 1.14 92/08/11 12:08:30 mrt
44 * Picked up Brad's deliniting and variable argument changes
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.
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
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.
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
69 * Revision 1.10 89/08/03 19:49:33 mja
70 * Updated to use v*printf() in place of _doprnt().
73 * Revision 1.9 89/06/18 14:41:37 gm0w
74 * Fixed up some notify messages of errors to use "SUP:" prefix.
77 * 13-May-88 Glenn Marcy (gm0w) at Carnegie-Mellon University
78 * Changed goaway to longjmp back to top-level to scan next
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.
86 * 27-Dec-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
87 * Removed nameserver support (which means to use a new
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
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 **********************************************************************
117 #include <sys/time.h>
118 #include <sys/resource.h>
119 #include <sys/param.h>
120 #include "supcdefs.h"
121 #include "supextern.h"
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 */
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 */
177 if (getrlimit(RLIMIT_DATA
, &dlim
) == -1)
178 goaway("Error getting resource limit (%s)",
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)",
188 init(argc
, argv
); /* process arguments */
189 for (c
= firstC
; c
; c
= c
->Cnext
) {
193 (void) chdir(basedir
);
194 scantime
= time((time_t *) NULL
);
196 printf("SUP Scan for %s starting at %s", collname
,
198 (void) fflush(stdout
);
199 if (!setjmp(sjbuf
)) {
200 makescanlists(); /* record names in scan files */
201 scantime
= time((time_t *) NULL
);
203 printf("SUP Scan for %s completed at %s",
204 collname
, ctime(&scantime
));
207 "SUP: Scan for %s aborted at %s", collname
,
210 (void) fflush(stdout
);
212 while ((c
= firstC
) != NULL
) {
213 firstC
= firstC
->Cnext
;
222 /*****************************************
223 *** I N I T I A L I Z A T I O N ***
224 *****************************************/
229 fprintf(stderr
, "Usage: supscan [ -vq ] collection [ basedir ]\n");
230 fprintf(stderr
, " supscan [ -vq ] -f dirfile\n");
231 fprintf(stderr
, " supscan [ -vq ] -s\n");
236 init(int argc
, char **argv
)
238 char buf
[STRINGLENGTH
], fbuf
[STRINGLENGTH
], *p
, *q
;
242 char *filename
= NULL
;
248 while (argc
> 1 && argv
[1][0] == '-') {
249 switch (argv
[1][1]) {
268 fprintf(stderr
, "supscan: Invalid flag %s ignored\n",
270 (void) fflush(stderr
);
276 (void) sprintf(fbuf
, FILEDIRS
, DEFDIR
);
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
) {
291 if (strchr("#;:", *p
))
293 collname
= nxtarg(&p
, " \t=");
294 p
= skipover(p
, " \t=");
297 *c
= getscancoll(filename
, estrdup(collname
),
305 if (argc
< 2 && fflag
) {
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
) {
314 if (strchr("#;:", *p
))
316 q
= nxtarg(&p
, " \t=");
317 p
= skipover(p
, " \t=");
318 *c
= getscancoll(filename
, estrdup(q
), estrdup(p
));
325 if (argc
< 2 || argc
> 3)
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
;
338 if (basedir
== NULL
) {
339 if ((f
= fopen(filename
, "r")) != NULL
) {
340 while ((p
= fgets(buf
, STRINGLENGTH
, f
)) != NULL
) {
344 if (strchr("#;:", *p
))
346 q
= nxtarg(&p
, " \t=");
347 if (strcmp(q
, collname
) == 0) {
348 p
= skipover(p
, " \t=");
349 basedir
= estrdup(p
);
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",
366 (void) sprintf(buf
, FILEPREFIX
, collname
);
367 if ((f
= fopen(buf
, "r")) != NULL
) {
368 while ((p
= fgets(buf
, STRINGLENGTH
, f
)) != NULL
) {
372 if (strchr("#;:", *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
);
386 if ((c
= (SCAN_COLLECTION
*) malloc(sizeof(SCAN_COLLECTION
))) == NULL
)
387 quit(1, "supscan: can't malloc collection structure\n");
396 goaway(const char *fmt
, ...)
401 vfprintf(stderr
, fmt
, ap
);
403 (void) putc('\n', stderr
);
404 (void) fflush(stderr
);
405 longjmp(sjbuf
, TRUE
);
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
437 hostlen
= strlen(host
);
439 return (strncasecmp(myhost
, host
,
440 hostlen
< myhostlen
? hostlen
: myhostlen
) == 0);