/* * Copyright (c) 1992 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software_Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ /* * sup misc. routines, include list processing. ********************************************************************** * HISTORY * $Log: supcmisc.c,v $ * Revision 1.3 1996/09/05 16:50:10 christos * - for portability make sure that we never use "" as a pathname, always convert * it to "." * - include sockio.h if needed to define SIOCGIFCONF (for svr4) * - use POSIX signals and wait macros * - add -S silent flag, so that the client does not print messages unless there * is something wrong * - use flock or lockf as appropriate * - use fstatfs or fstatvfs to find out if a filesystem is mounted over nfs, * don't depend on the major() = 255 hack; it only works on legacy systems. * - use gzip -cf to make sure that gzip compresses the file even when the file * would expand. * - punt on defining vsnprintf if _IOSTRG is not defined; use sprintf... * * To compile sup on systems other than NetBSD, you'll need a copy of daemon.c, * vis.c, vis.h and sys/cdefs.h. Maybe we should keep those in the distribution? * * Revision 1.2 1995/06/03 21:21:57 christos * Changes to write ascii timestamps in the when files. * Looked into making it 64 bit clean, but it is hopeless. * Added little program to convert from the old timestamp files * into the new ones. * * Revision 1.1.1.1 1993/05/21 14:52:18 cgd * initial import of CMU's SUP to NetBSD * * Revision 1.5 92/08/11 12:07:22 mrt * Added release to FILEWHEN name. * Brad's changes: delinted and updated variable arguement usage. * [92/07/26 mrt] * * Revision 1.3 89/08/15 15:31:28 bww * Updated to use v*printf() in place of _doprnt(). * From "[89/04/19 mja]" at CMU. * [89/08/15 bww] * * 27-Dec-87 Glenn Marcy (gm0w) at Carnegie-Mellon University * Fixed bug in ugconvert() which left pw uninitialized. * * 25-May-87 Doug Philips (dwp) at Carnegie-Mellon University * Split off from sup.c and changed goaway to use printf * instead of notify if thisC is NULL. * ********************************************************************** */ #if __STDC__ #include #else #include #endif #include "supcdefs.h" struct liststruct { /* uid and gid lists */ char *Lname; /* name */ int Lnumber; /* uid or gid */ struct liststruct *Lnext; }; typedef struct liststruct LIST; #define HASHBITS 4 #define HASHSIZE (1<Cflags&CFURELSUF) && thisC->Crelease) (void) sprintf (relsufix,".%s",thisC->Crelease); else relsufix[0] = '\0'; if (chdir (thisC->Cbase) < 0) logerr ("Can't change to base directory %s for collection %s", thisC->Cbase,thisC->Cname); twhen = getwhen(thisC->Cname,relsufix); (void) strcpy (buf,ctime (&twhen)); buf[strlen(buf)-1] = '\0'; loginfo ("Last update occurred at %s for collection %s", buf,thisC->Cname); } int establishdir (fname) char *fname; { char dpart[STRINGLENGTH],fpart[STRINGLENGTH]; path (fname,dpart,fpart); return (estabd (fname,dpart)); } int estabd (fname,dname) char *fname,*dname; { char dpart[STRINGLENGTH],fpart[STRINGLENGTH]; struct stat sbuf; register int x; if (stat (dname,&sbuf) >= 0) return (FALSE); /* exists */ path (dname,dpart,fpart); if (strcmp (fpart,".") == 0) { /* dname is / or . */ notify ("SUP: Can't create directory %s for %s\n",dname,fname); return (TRUE); } x = estabd (fname,dpart); if (x) return (TRUE); (void) mkdir (dname,0755); if (stat (dname,&sbuf) < 0) { /* didn't work */ notify ("SUP: Can't create directory %s for %s\n",dname,fname); return (TRUE); } vnotify ("SUP Created directory %s for %s\n",dname,fname); return (FALSE); } /*************************************** *** L I S T R O U T I N E S *** ***************************************/ static int Lhash (name) char *name; { /* Hash function is: HASHSIZE * (strlen mod HASHSIZE) * + (char mod HASHSIZE) * where "char" is last character of name (if name is non-null). */ register int len; register char c; len = strlen (name); if (len > 0) c = name[len-1]; else c = 0; return (((len&HASHMASK)<Lname = name; l->Lnumber = number; l->Lnext = table[lno]; table[lno] = l; } static LIST *Llookup (table,name) LIST **table; char *name; { register int lno; register LIST *l; lno = Lhash (name); for (l = table[lno]; l && strcmp(l->Lname,name) != 0; l = l->Lnext); return (l); } ugconvert (uname,gname,uid,gid,mode) char *uname,*gname; int *uid,*gid,*mode; { register LIST *u,*g; register struct passwd *pw; register struct group *gr; struct stat sbuf; static int defuid = -1; static int defgid; static int first = TRUE; if (first) { bzero ((char *)uidL, sizeof (uidL)); bzero ((char *)gidL, sizeof (gidL)); first = FALSE; } pw = NULL; if (u = Llookup (uidL,uname)) *uid = u->Lnumber; else if (pw = getpwnam (uname)) { Linsert (uidL,salloc(uname),pw->pw_uid); *uid = pw->pw_uid; } if (u || pw) { if (g = Llookup (gidL,gname)) { *gid = g->Lnumber; return; } if (gr = getgrnam (gname)) { Linsert (gidL,salloc(gname),gr->gr_gid); *gid = gr->gr_gid; return; } if (pw == NULL) pw = getpwnam (uname); *mode &= ~S_ISGID; *gid = pw->pw_gid; return; } *mode &= ~(S_ISUID|S_ISGID); if (defuid >= 0) { *uid = defuid; *gid = defgid; return; } if (stat (".",&sbuf) < 0) { *uid = defuid = getuid (); *gid = defgid = getgid (); return; } *uid = defuid = sbuf.st_uid; *gid = defgid = sbuf.st_gid; } /********************************************* *** U T I L I T Y R O U T I N E S *** *********************************************/ #if __STDC__ notify (char *fmt,...) /* record error message */ #else /*VARARGS*//*ARGSUSED*/ notify (va_alist) /* record error message */ va_dcl #endif { #if !__STDC__ char *fmt; #endif char buf[STRINGLENGTH]; char collrelname[STRINGLENGTH]; long tloc; static FILE *noteF = NULL; /* mail program on pipe */ va_list ap; #if __STDC__ va_start(ap,fmt); #else va_start(ap); fmt = va_arg(ap,char *); #endif if (fmt == NULL) { if (noteF && noteF != stdout) (void) pclose (noteF); noteF = NULL; return; } if ((thisC->Cflags&CFURELSUF) && thisC->Crelease) (void) sprintf (collrelname,"%s-%s",collname,thisC->Crelease); else (void) strcpy (collrelname,collname); if (noteF == NULL) { if ((thisC->Cflags&CFMAIL) && thisC->Cnotify) { (void) sprintf (buf,"mail -s \"SUP Upgrade of %s\" %s >/dev/null", collrelname,thisC->Cnotify); noteF = popen (buf,"w"); if (noteF == NULL) { logerr ("Can't send mail to %s for %s", thisC->Cnotify,collrelname); noteF = stdout; } } else noteF = stdout; tloc = time ((long *)NULL); fprintf (noteF,"SUP Upgrade of %s at %s", collrelname,ctime (&tloc)); (void) fflush (noteF); } vfprintf(noteF,fmt,ap); va_end(ap); (void) fflush (noteF); } lockout (on) /* lock out interrupts */ int on; { static sigset_t oset; sigset_t nset; if (on) { sigemptyset(&nset); sigaddset(&nset, SIGHUP); sigaddset(&nset, SIGINT); sigaddset(&nset, SIGTERM); sigaddset(&nset, SIGQUIT); (void) sigprocmask(SIG_BLOCK, &nset, &oset); } else { (void) sigprocmask(SIG_SETMASK, &oset, NULL); } } char *fmttime (time) long time; { static char buf[STRINGLENGTH]; int len; (void) strcpy (buf,ctime (&time)); len = strlen(buf+4)-6; (void) strncpy (buf,buf+4,len); buf[len] = '\0'; return (buf); }