NetBSD/usr.sbin/sup/source/supcmisc.c
christos a6d86f0535 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.
1995-06-03 21:21:48 +00:00

337 lines
8.0 KiB
C

/*
* 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.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 <stdarg.h>
#else
#include <varargs.h>
#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<<HASHBITS)
#define HASHMASK (HASHSIZE-1)
#define LISTSIZE (HASHSIZE*HASHSIZE)
static LIST *uidL[LISTSIZE]; /* uid and gid lists */
static LIST *gidL[LISTSIZE];
extern COLLECTION *thisC; /* collection list pointer */
#if __STDC__
int notify (char *, ...);
#endif
/*************************************************
*** P R I N T U P D A T E T I M E S ***
*************************************************/
prtime ()
{
char buf[STRINGLENGTH];
char relsufix[STRINGLENGTH];
long twhen;
int f;
if ((thisC->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)<<HASHBITS)|(((int)c)&HASHMASK));
}
static
Linsert (table,name,number)
LIST **table;
char *name;
int number;
{
register LIST *l;
register int lno;
lno = Lhash (name);
l = (LIST *) malloc (sizeof(LIST));
l->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;
{
register int x;
static int lockmask;
if (on) {
x = sigmask (SIGHUP) | sigmask (SIGINT) |
sigmask (SIGQUIT) | sigmask (SIGTERM);
lockmask = sigblock (x);
}
else {
(void) sigsetmask (lockmask);
}
}
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);
}