Expand PMF_FN_* macros.
[netbsd-mini2440.git] / usr.sbin / sup / source / supcmain.c
blobfd7e79dd0088e50148b63d617a3ca7f2903dd828
1 /* $NetBSD: supcmain.c,v 1.29 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 * sup -- Software Upgrade Protocol client process
30 * Usage: sup [ flags ] [ supfile ] [ collection ... ]
32 * The only required argument to sup is the name of a supfile. It
33 * must either be given explicitly on the command line, or the -s
34 * flag must be specified. If the -s flag is given, the system
35 * supfile will be used and a supfile command argument should not be
36 * specified. The list of collections is optional and if specified
37 * will be the only collections upgraded. The following flags affect
38 * all collections specified.
40 * -s "system upgrade" flag
41 * As described above.
43 * -t "upgrade time" flag
44 * When this flag is given, Sup will print the time
45 * that each collection was last upgraded, rather than
46 * performing actual upgrades.
48 * -u "utimes" flag
49 * When this flags is given sup will not attempt to
50 * restore access and modification files on the collection
51 * files from the server.
53 * -R "resource pause" flag
54 * Sup will not disable resource pausing and will not
55 * make filesystem space checks.
57 * -N "debug network" flag
58 * Sup will trace messages sent and received that
59 * implement the Sup network protocol.
61 * -P "debug ports" flag
62 * Sup will use a set of non-privileged network
63 * ports reserved for debugging purposes.
65 * -X "crosspatch" flag
66 * Sup is being run remotely with a crosspatch.
67 * Need to be carefull as we may be running as root
68 * instead of collection owner.
70 * The remaining flags affect all collections unless an explicit list
71 * of collections are given with the flags. Multiple flags may be
72 * specified together that affect the same collections. For the sake
73 * of convience, any flags that always affect all collections can be
74 * specified with flags that affect only some collections. For
75 * example, "sup -sde=coll1,coll2" would perform a system upgrade,
76 * and the first two collections would allow both file deletions and
77 * command executions. Note that this is not the same command as
78 * "sup -sde=coll1 coll2", which would perform a system upgrade of
79 * just the coll2 collection and would ignore the flags given for the
80 * coll1 collection.
82 * -a "all files" flag
83 * All files in the collection will be copied from
84 * the repository, regardless of their status on the
85 * current machine. Because of this, it is a very
86 * expensive operation and should only be done for
87 * small collections if data corruption is suspected
88 * and been confirmed. In most cases, the -o flag
89 * should be sufficient.
91 * -b "backup files" flag
92 * If the -b flag if given, or the "backup" supfile
93 * option is specified, the contents of regular files
94 * on the local system will be saved before they are
95 * overwritten with new data. The data will be saved
96 * in a subdirectory called "BACKUP" in the directory
97 * containing the original version of the file, in a
98 * file with the same non-directory part of the file
99 * name. The files to backup are specified by the
100 * list file on the repository.
102 * -B "don't backup files" flag
103 * The -B flag overrides and disables the -b flag and
104 * the "backup" supfile option.
106 * -d "delete files" flag
107 * Files that are no longer in the collection on the
108 * repository will be deleted if present on the local
109 * machine. This may also be specified in a supfile
110 * with the "delete" option.
112 * -D "don't delete files" flag
113 * The -D flag overrides and disables the -d flag and
114 * the "delete" supfile option.
116 * -e "execute files" flag
117 * Sup will execute commands sent from the repository
118 * that should be run when a file is upgraded. If
119 * the -e flag is omitted, Sup will print a message
120 * that specifies the command to execute. This may
121 * also be specified in a supfile with the "execute"
122 * option.
124 * -E "don't execute files" flag
125 * The -E flag overrides and disables the -e flag and
126 * the "execute" supfile option.
128 * -f "file listing" flag
129 * A "list-only" upgrade will be performed. Messages
130 * will be printed that indicate what would happen if
131 * an actual upgrade were done.
133 * -k "keep newer files" flag
134 * The -k flag, or "keep" supfile option, will cause
135 * Sup to check to see whether there is a newer file on
136 * the local disk before updating files. Only files
137 * which are newer on the repository will be updated.
139 * -K "don't keep newer files" flag
140 * The -K flag overrides and disables the -k flag and
141 * the "keep" supfile option.
143 * -l "local upgrade" flag
144 * Normally, Sup will not upgrade a collection if the
145 * repository is on the same machine. This allows
146 * users to run upgrades on all machines without
147 * having to make special checks for the repository
148 * machine. If the -l flag is specified, collections
149 * will be upgraded even if the repository is local.
151 * -m "mail" flag
152 * Normally, Sup used standard output for messages.
153 * If the -m flag if given, Sup will send mail to the
154 * user running Sup, or a user specified with the
155 * "notify" supfile option, that contains messages
156 * printed by Sup.
158 * -M "mailto" flag
159 * Like -m, but send mail to the specified user.
160 * -o "old files" flag
161 * Sup will normally only upgrade files that have
162 * changed on the repository since the last time an
163 * upgrade was performed. The -o flag, or the "old"
164 * supfile option, will cause Sup to check all files
165 * in the collection for changes instead of just the
166 * new ones.
168 * -O "not old files" flag
169 * The -O flag overrides and disables the -o flag and
170 * the "old" supfile option.
172 * -v "verbose" flag
173 * Normally, Sup will only print messages if there
174 * are problems. This flag causes Sup to also print
175 * messages during normal progress showing what Sup
176 * is doing.
178 **********************************************************************
179 * HISTORY
181 * 7-July-93 Nate Williams at Montana State University
182 * Modified SUP to use gzip based compression when sending files
183 * across the network to save BandWidth
185 * Revision 1.6 92/08/11 12:06:59 mrt
186 * Merged in Brad's changes. Made resource pausing code conditional
187 * on MACH, rather than CMUCS. Fixed some calls to sprintf to
188 * return void.
189 * [92/08/09 mrt]
191 * Revision 1.5 92/02/08 19:01:18 mja
192 * Correct oldsigsys type when ANSI C.
193 * [92/02/08 18:59:47 mja]
195 * Revision 1.4 92/02/08 18:24:01 mja
196 * Added -k and -K switches.
197 * [92/01/17 vdelvecc]
199 * 27-Dec-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
200 * Added crosspatch support (is currently ignored).
202 * 28-Jun-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
203 * Added code for "release" support.
205 * 25-May-87 Doug Philips (dwp) at Carnegie-Mellon University
206 * Split into several files. This is the main program and
207 * command line processing and old history log. [V5.21]
209 * 21-May-87 Chriss Stephens (chriss) at Carnegie Mellon University
210 * Merged divergent CS and ECE versions. ifdeffed out the resource
211 * pausing code - only compiled in if CMUCS defined. [V5.21a]
213 * 20-May-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
214 * Removed support for version 3 of SUP protocol. Added changes
215 * to make lint happy. Added calls to new logging routines. [V5.20]
217 * 01-Apr-87 Glenn Marcy (gm0w) at Carnegie-Mellon University
218 * Added -R switch to reenable resource pausing, which is currently
219 * disabled by default. Added code to check for free disk space
220 * available on the target filesystem so that sup shouldn't run the
221 * system out of disk space as frequently. [V5.19]
223 * 19-Sep-86 Mike Accetta (mja) at Carnegie-Mellon University
224 * Changed default supfile name for system collections when -t
225 * is specified to use FILESUPTDEFAULT; added missing new-line
226 * in retry message. [V5.18]
228 * 21-Jun-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
229 * Missed a caller to a routine which had an extra argument added
230 * to it last edit. [V5.17]
232 * 07-Jun-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
233 * Changed getcoll() so that fatal errors are checked immediately
234 * instead of after sleeping for a little while. Changed all
235 * rm -rf commands to rmdir since the Mach folks keep deleting
236 * their root and /usr directory trees. Reversed the order of
237 * delete commands to that directories will possibly empty so
238 * that the rmdir's work. [V5.16]
240 * 30-May-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
241 * Changed temporary file names to #n.sup format. [V5.15]
243 * 19-Feb-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
244 * Moved PGMVERSION to supvers.c module. [V5.14]
246 * 06-Feb-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
247 * Added check for file type before unlink when receiving a
248 * symbolic link. Now runs "rm -rf" if the file type is a
249 * directory. [V5.13]
251 * 03-Feb-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
252 * Fixed small bug in signon that didn't retry connections if an
253 * error occurred on the first attempt to connect. [V5.12]
255 * 26-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
256 * New command interface. Added -bBDEO flags and "delete",
257 * "execute" and "old" supfile options. Changed -d to work
258 * correctly without implying -o. [V5.11]
260 * 21-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
261 * Fix incorrect check for supfile changing. Flush output buffers
262 * before restart. [V5.10]
264 * 17-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
265 * Add call to requestend() after connection errors are retried to
266 * free file descriptors. [V5.9]
268 * 15-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
269 * Fix SERIOUS merge error from previous edit. Added notify
270 * when execute command fails. [V5.8]
272 * 11-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
273 * Changed ugconvert to clear setuid/setgid bits if it doesn't use
274 * the user and group specified by the remote system. Changed
275 * execute code to invalidate collection if execute command returns
276 * with a non-zero exit status. Added support for execv() of
277 * original arguments of supfile is upgraded successfully. Changed
278 * copyfile to always use a temp file if possible. [V5.7]
280 * 04-Jan-86 Glenn Marcy (gm0w) at Carnegie-Mellon University
281 * Added support for fileserver busy messages and new nameserver
282 * protocol to support multiple repositories per collection.
283 * Added code to lock collections with lock files. [V5.6]
285 * 29-Dec-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
286 * Major rewrite for protocol version 4. [V4.5]
288 * 12-Dec-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
289 * Changed to check for DIFFERENT mtime (again). [V3.4]
291 * 08-Dec-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
292 * Replaced [ug]convert routines with ugconvert routine so that an
293 * appropriate group will be used if the default user is used.
294 * Changed switch parsing to allow multiple switches to be specified
295 * at the same time. [V3.3]
297 * 04-Dec-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
298 * Added test to request a new copy of an old file that already
299 * exists if the mtime is different. [V3.2]
301 * 24-Nov-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
302 * Added -l switch to enable upgrades from local repositories.
304 * 03-Nov-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
305 * Minor change in order -t prints so that columns line up.
307 * 22-Oct-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
308 * Added code to implement retry flag and pass this on to request().
310 * 22-Sep-85 Glenn Marcy (gm0w) at Carnegie-Mellon University
311 * Merged 4.1 and 4.2 versions together.
313 * 04-Jun-85 Steven Shafer (sas) at Carnegie-Mellon University
314 * Created for 4.2 BSD.
316 **********************************************************************
319 #define MSGFILE
320 #include "supcdefs.h"
321 #if MACH
322 #include <sys/syscall.h>
323 #ifndef SYS_rpause
324 #define SYS_rpause (-5)
325 #endif
326 #endif
327 #include "supextern.h"
329 /*********************************************
330 *** G L O B A L V A R I A B L E S ***
331 *********************************************/
333 char program[] = "SUP"; /* program name for SCM messages */
334 int progpid = -1; /* and process id */
336 COLLECTION *firstC, *thisC; /* collection list pointer */
338 extern int dontjump; /* disable longjmp */
339 extern int scmdebug; /* SCM debugging flag */
341 int silent; /* Silent run, print only errors */
342 int sysflag; /* system upgrade flag */
343 int timeflag; /* print times flag */
344 int noutime; /* Don't preserve utimes */
345 #if MACH
346 int rpauseflag; /* don't disable resource pausing */
347 #endif /* MACH */
348 int xpatchflag; /* crosspatched with remote system */
349 int portdebug; /* network debugging ports */
351 int main(int, char **);
352 static int checkcoll(TREE *, void *);
353 static void doswitch(int *, char ***, TREE **, int *, int *, char *, size_t);
354 static char *init(int, char **);
356 /*************************************
357 *** M A I N R O U T I N E ***
358 *************************************/
361 main(int argc, char **argv)
363 char *progname, *supfname;
364 int restart;
365 dev_t sfdev = 0;
366 ino_t sfino = 0;
367 time_t sfmtime = 0;
368 struct stat sbuf;
369 struct sigaction ign;
371 /* initialize global variables */
372 pgmversion = PGMVERSION;/* export version number */
373 isserver = FALSE; /* export that we're not a server */
374 collname = NULL; /* no current collection yet */
375 dontjump = TRUE; /* clear setjmp buffer */
376 progname = estrdup(argv[0]);
378 supfname = init(argc, argv);
379 restart = -1; /* don't make restart checks */
380 if (*progname == '/' && *supfname == '/') {
381 if (stat(supfname, &sbuf) < 0) {
382 logerr("Can't stat supfile %s", supfname);
383 } else {
384 sfdev = sbuf.st_dev;
385 sfino = sbuf.st_ino;
386 sfmtime = sbuf.st_mtime;
387 restart = 0;
390 if (timeflag) {
391 for (thisC = firstC; thisC; thisC = thisC->Cnext)
392 prtime();
393 } else {
394 /* ignore network pipe signals */
395 ign.sa_handler = SIG_IGN;
396 ign.sa_flags = 0;
397 sigemptyset(&ign.sa_mask);
398 (void) sigaction(SIGPIPE, &ign, NULL);
399 getnams(); /* find unknown repositories */
400 for (thisC = firstC; thisC; thisC = thisC->Cnext) {
401 getcoll(); /* upgrade each collection */
402 if (restart == 0) {
403 if (stat(supfname, &sbuf) < 0)
404 logerr("Can't stat supfile %s",
405 supfname);
406 else if (sfmtime != sbuf.st_mtime ||
407 #ifndef __CYGWIN__ /* Cygwin's inodes are not constant */
408 sfino != sbuf.st_ino ||
409 #endif
410 sfdev != sbuf.st_dev) {
411 restart = 1;
412 break;
416 endpwent(); /* close /etc/passwd */
417 (void) endgrent(); /* close /etc/group */
418 if (restart == 1) {
419 int fd;
420 if (!silent)
421 loginfo("SUP Restarting %s with new supfile %s",
422 progname, supfname);
423 for (fd = getdtablesize(); fd > 3; fd--)
424 (void) close(fd);
425 execv(progname, argv);
426 logquit(1, "Restart failed");
429 while ((thisC = firstC) != NULL) {
430 firstC = firstC->Cnext;
431 free(thisC->Cname);
432 Tfree(&thisC->Chtree);
433 free(thisC->Cbase);
434 if (thisC->Chbase)
435 free(thisC->Chbase);
436 if (thisC->Cprefix)
437 free(thisC->Cprefix);
438 if (thisC->Crelease)
439 free(thisC->Crelease);
440 if (thisC->Cnotify)
441 free(thisC->Cnotify);
442 if (thisC->Clogin)
443 free(thisC->Clogin);
444 if (thisC->Cpswd)
445 free(thisC->Cpswd);
446 if (thisC->Ccrypt)
447 free(thisC->Ccrypt);
448 free(thisC);
450 exit(0);
452 /*****************************************
453 *** I N I T I A L I Z A T I O N ***
454 *****************************************/
455 /* Set up collection list from supfile. Check all fields except
456 * hostname to be sure they make sense.
459 #define Toflags Tflags
460 #define Taflags Tmode
461 #define Twant Tuid
462 #define Tcount Tgid
464 static void
465 doswitch(int *argc, char ***argv, TREE ** collTp, int *oflagsp, int *aflagsp,
466 char *username, size_t ulen)
468 TREE *t;
469 char *coll, *argp;
470 int oflags, aflags;
471 int c;
473 #define SUPOPTIONS "abBdDeEfkKlmM:NoOPRsStuvXzZ=:"
475 oflags = aflags = 0;
476 while ((c = getopt(*argc, *argv, SUPOPTIONS)) != -1)
477 switch (c) {
478 default:
479 logerr("Invalid flag '%c' ignored", c);
480 break;
481 case '\0':
482 case '=':
483 argp = optarg;
484 do {
485 coll = nxtarg(&argp, ", \t");
486 t = Tinsert(collTp, coll, TRUE);
487 t->Toflags |= oflags;
488 t->Toflags &= ~aflags;
489 t->Taflags |= aflags;
490 t->Taflags &= ~oflags;
491 argp = skipover(argp, ", \t");
492 } while (*argp);
493 break;
494 case 'a':
495 oflags |= CFALL;
496 break;
497 case 'b':
498 oflags |= CFBACKUP;
499 aflags &= ~CFBACKUP;
500 break;
501 case 'B':
502 oflags &= ~CFBACKUP;
503 aflags |= CFBACKUP;
504 break;
505 case 'd':
506 oflags |= CFDELETE;
507 aflags &= ~CFDELETE;
508 break;
509 case 'D':
510 oflags &= ~CFDELETE;
511 aflags |= CFDELETE;
512 break;
513 case 'e':
514 oflags |= CFEXECUTE;
515 aflags &= ~CFEXECUTE;
516 break;
517 case 'E':
518 oflags &= ~CFEXECUTE;
519 aflags |= CFEXECUTE;
520 break;
521 case 'f':
522 oflags |= CFLIST;
523 break;
524 case 'k':
525 oflags |= CFKEEP;
526 aflags &= ~CFKEEP;
527 break;
528 case 'K':
529 oflags &= ~CFKEEP;
530 aflags |= CFKEEP;
531 break;
532 case 'l':
533 oflags |= CFLOCAL;
534 break;
535 case 'm':
536 oflags |= CFMAIL;
537 break;
538 case 'M':
539 oflags |= CFMAIL;
540 strncpy(username, optarg, ulen);
541 username[ulen - 1] = '\0';
542 break;
543 case 'N':
544 scmdebug++;
545 break;
546 case 'o':
547 oflags |= CFOLD;
548 aflags &= ~CFOLD;
549 break;
550 case 'O':
551 oflags &= ~CFOLD;
552 aflags |= CFOLD;
553 break;
554 case 'P':
555 portdebug = TRUE;
556 break;
557 case 'R':
558 #if MACH
559 rpauseflag = TRUE;
560 #endif /* MACH */
561 break;
562 case 's':
563 sysflag = TRUE;
564 break;
565 case 'S':
566 silent = TRUE;
567 break;
568 case 't':
569 timeflag = TRUE;
570 break;
571 case 'u':
572 noutime = TRUE;
573 break;
574 case 'v':
575 oflags |= CFVERBOSE;
576 break;
577 case 'X':
578 xpatchflag = TRUE;
579 break;
580 case 'z':
581 oflags |= CFCOMPRESS;
582 break;
583 case 'Z':
584 oflags &= ~CFCOMPRESS;
585 break;
588 *oflagsp |= oflags;
589 *oflagsp &= ~aflags;
590 *aflagsp |= aflags;
591 *aflagsp &= ~oflags;
592 *argc -= optind;
593 *argv += optind;
596 static char *
597 init(int argc, char **argv)
599 char buf[STRINGLENGTH], *p;
600 const char *u;
601 char username[STRINGLENGTH];
602 char *supfname, *arg;
603 COLLECTION *c, *lastC;
604 FILE *f;
605 int bogus;
606 struct passwd *pw;
607 TREE *t;
608 TREE *collT; /* collections we are interested in */
609 time_t timenow; /* startup time */
610 int oflags, aflags;
611 int cwant;
612 #ifdef MACH
613 void (*oldsigsys) ();
614 #endif /* MACH */
616 username[0] = '\0';
617 sysflag = FALSE; /* not system upgrade */
618 timeflag = FALSE; /* don't print times */
619 #if MACH
620 rpauseflag = FALSE; /* don't disable resource pausing */
621 #endif /* MACH */
622 xpatchflag = FALSE; /* not normally crosspatched */
623 scmdebug = 0; /* level zero, no SCM debugging */
624 portdebug = FALSE; /* no debugging ports */
626 collT = NULL;
627 oflags = aflags = 0;
629 doswitch(&argc, &argv, &collT, &oflags, &aflags, username,
630 sizeof(username));
632 if (argc == 0 && !sysflag)
633 logquit(1, "Need either -s or supfile");
634 #if MACH
635 oldsigsys = signal(SIGSYS, SIG_IGN);
636 if (rpauseflag != TRUE)
637 if (syscall(SYS_rpause, ENOSPC, RPAUSE_ALL, RPAUSE_DISABLE) < 0)
638 rpauseflag = TRUE;
639 (void) signal(SIGSYS, oldsigsys);
640 #endif /* MACH */
641 if (sysflag)
642 (void) snprintf(supfname = buf, sizeof(buf),
643 timeflag ? FILESUPTDEFAULT : FILESUPDEFAULT,
644 DEFDIR);
645 else {
646 supfname = *argv;
647 if (strcmp(supfname, "-") == 0)
648 supfname = "";
649 --argc;
650 argv++;
652 cwant = argc > 0;
653 while (argc > 0) {
654 t = Tinsert(&collT, *argv, TRUE);
655 t->Twant = TRUE;
656 --argc;
657 argv++;
659 if (*username == '\0' && ((u = getlogin()) ||
660 ((pw = getpwuid((int) getuid())) && (u = pw->pw_name)))) {
661 (void)strncpy(username, u, sizeof(username));
662 username[sizeof(username) - 1] = '\0';
664 if (*supfname) {
665 f = fopen(supfname, "r");
666 if (f == NULL)
667 logquit(1, "Can't open supfile %s", supfname);
668 } else
669 f = stdin;
670 firstC = NULL;
671 lastC = NULL;
672 bogus = FALSE;
673 while ((p = read_line(f, NULL, NULL, NULL, 0)) != NULL) {
674 if (strchr("#;:", *p))
675 continue;
676 arg = nxtarg(&p, " \t");
677 if (*arg == '\0') {
678 logerr("Missing collection name in supfile");
679 bogus = TRUE;
680 continue;
682 if (cwant) {
683 TREE *mytree;
684 if ((mytree = Tsearch(collT, arg)) == NULL)
685 continue;
686 mytree->Tcount++;
688 c = (COLLECTION *) malloc(sizeof(COLLECTION));
689 if (c == NULL) {
690 logerr("Cannot allocate memory");
691 exit(1);
693 if (firstC == NULL)
694 firstC = c;
695 if (lastC != NULL)
696 lastC->Cnext = c;
697 lastC = c;
698 if (parsecoll(c, arg, p) < 0) {
699 bogus = TRUE;
700 continue;
702 c->Cflags |= oflags;
703 c->Cflags &= ~aflags;
704 if ((t = Tsearch(collT, c->Cname)) != NULL) {
705 c->Cflags |= t->Toflags;
706 c->Cflags &= ~t->Taflags;
708 if ((c->Cflags & CFMAIL) && c->Cnotify == NULL) {
709 if (*username == '\0')
710 logerr("User unknown, notification disabled");
711 else
712 c->Cnotify = estrdup(username);
714 if (c->Cbase == NULL) {
715 (void) sprintf(buf, FILEBASEDEFAULT, c->Cname);
716 c->Cbase = estrdup(buf);
719 if (bogus)
720 logquit(1, "Aborted due to supfile errors");
721 if (f != stdin)
722 (void) fclose(f);
723 if (cwant)
724 (void) Tprocess(collT, checkcoll, NULL);
725 Tfree(&collT);
726 if (firstC == NULL)
727 logquit(1, "No collections to upgrade");
728 timenow = time((time_t *) NULL);
729 if (*supfname == '\0')
730 p = "standard input";
731 else if (sysflag)
732 p = "system software";
733 else
734 (void) sprintf(p = buf, "file %s", supfname);
735 if (!silent)
736 loginfo("SUP %d.%d (%s) for %s at %s", PROTOVERSION, PGMVERSION,
737 scmversion, p, fmttime(timenow));
738 return (estrdup(supfname));
741 static int
742 checkcoll(TREE * t, void *dummy __unused)
744 if (!t->Twant)
745 return (SCMOK);
746 if (t->Tcount == 0)
747 logerr("Collection %s not found", t->Tname);
748 if (t->Tcount > 1)
749 logerr("Collection %s found more than once", t->Tname);
750 return (SCMOK);