diff --git a/usr.sbin/sup/Makefile b/usr.sbin/sup/Makefile index fce18cf35b23..8809889f0612 100644 --- a/usr.sbin/sup/Makefile +++ b/usr.sbin/sup/Makefile @@ -42,13 +42,14 @@ # SITE = NETBSD #SITE = CMUCS +RENAMELOG = \"/usr/local/etc/sup.moved\" NETBSD_DEFINES = -UMACH -DVAR_TMP -DHAS_DAEMON AFS_DEFINES = -DAFS -I/usr/afsws/include OSF_DEFINES = -UMACH -DOSF -D_BSD -noshrlib -g -DNEED_VSNPRINTF -DVAR_TMP CMUCS_DEFINES = -DMACH -DDOPRINT_VA -DNEED_VPRINTF NON_MACH_DEFINES = -UMACH #DEFS = -UCMUCS -UCMU ${${SITE}_DEFINES} -DEFS = -UCMUCS -UCMU ${NETBSD_DEFINES} +DEFS = -UCMUCS -UCMU ${NETBSD_DEFINES} -DRENAMELOG=${RENAMELOG} #INSTALLATION PARAMETERS NETBSD_BINDIR = /usr/local/bin @@ -60,8 +61,9 @@ CFLAGS = ${DEFS} -O -I. SUPCL = supcmain.o supcvers.o supcparse.o supcname.o \ supcmisc.o supcmeat.o SUPS = scm.o scmio.o stree.o log.o supmsg.o netcrypt.o -EXTRA = atoo.o errmsg.o expand.o ffilecopy.o filecopy.o nxtarg.o \ - path.o quit.o run.o salloc.o skipto.o vprintf.o +EXTRA = atoo.o errmsg.o expand.o ffilecopy.o filecopy.o \ + nxtarg.o path.o quit.o run.o salloc.o skipto.o \ + vprintf.o PROGRAMS = sup supscan supfilesrv @@ -76,9 +78,9 @@ USE_CRYPT = yes .endif .if defined(USE_CRYPT) -NETBSD_LIBS = -lcrypt -lutil +NETBSD_LIBS = -lcipher -lcrypt -lutil .else -NETBSD_LIBS = -lutil +NETBSD_LIBS = -lcrypt -lutil .endif CMUCS_LIBS = -lsys OSF_LIBS = -lbsd diff --git a/usr.sbin/sup/lib/ffilecopy.c b/usr.sbin/sup/lib/ffilecopy.c index 4cb42621af38..edef88323b47 100644 --- a/usr.sbin/sup/lib/ffilecopy.c +++ b/usr.sbin/sup/lib/ffilecopy.c @@ -58,7 +58,7 @@ FILE *here, *there; if (fflush (there) == EOF) /* flush pending output */ return (EOF); -#ifdef __386BSD__ +#ifdef __FreeBSD__ if ((here->_r) > 0) { /* flush buffered input */ i = write (therefile, here->_p, here->_r); if (i != here->_r) return (EOF); @@ -76,7 +76,7 @@ FILE *here, *there; i = filecopy (herefile, therefile); /* fast file copy */ if (i < 0) return (EOF); -#ifdef __386BSD__ +#ifdef __FreeBSD__ (here->_flags) |= __SEOF; /* indicate EOF */ #else (here->_flag) |= _IOEOF; /* indicate EOF */ diff --git a/usr.sbin/sup/lib/libc.h b/usr.sbin/sup/lib/libc.h index 108f70175332..03d7d0509243 100644 --- a/usr.sbin/sup/lib/libc.h +++ b/usr.sbin/sup/lib/libc.h @@ -26,6 +26,11 @@ ********************************************************************** * HISTORY * $Log: libc.h,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:33 jkh * Current sup with compression support. * @@ -81,6 +86,10 @@ #ifndef _LIBC_H_ #define _LIBC_H_ 1 +#if defined(__hpux) +#define __P(x) x +#endif + #ifndef _TYPES_ #include #endif /* _TYPES_ */ @@ -195,6 +204,26 @@ typedef int (*PFI)(); #if defined(c_plusplus) typedef int (*PFI2)(...); #endif /* c_plusplus */ + +#if defined(__hpux) +extern int utimes(char *, struct timeval *); + +#ifndef LOCK_SH +#define LOCK_SH 1 +#endif +#ifndef LOCK_EX +#define LOCK_EX 2 +#endif +#ifndef LOCK_NB +#define LOCK_NB 4 +#endif +#ifndef LOCK_UN +#define LOCK_UN 8 +#endif + +extern int flock(int, int); +#endif /* __hpux */ + #if 0 extern void abort(void); extern int abs(int); diff --git a/usr.sbin/sup/lib/log.c b/usr.sbin/sup/lib/log.c index 4879cf7a07f8..2974b4aab131 100644 --- a/usr.sbin/sup/lib/log.c +++ b/usr.sbin/sup/lib/log.c @@ -27,6 +27,11 @@ ********************************************************************** * HISTORY * $Log: log.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:33 jkh * Current sup with compression support. * @@ -52,8 +57,13 @@ */ #include +#ifdef __hpux +#include +#include +#else #include #include +#endif #if __STDC__ #include #else @@ -72,7 +82,7 @@ logopen(program) char *program; { if (opened) return; - openlog(program,LOG_PID,LOG_DAEMON); + openlog(program,LOG_PID,LOG_LOCAL1); opened++; } diff --git a/usr.sbin/sup/lib/run.c b/usr.sbin/sup/lib/run.c index 9072ebedc7dc..0e9a581beeb5 100644 --- a/usr.sbin/sup/lib/run.c +++ b/usr.sbin/sup/lib/run.c @@ -47,6 +47,11 @@ ********************************************************************** * HISTORY * $Log: run.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:33 jkh * Current sup with compression support. * @@ -95,6 +100,7 @@ #include #include #include +#define MAXARGS 100 static int dorun(); @@ -123,10 +129,14 @@ va_dcl { int val; va_list ap; - + char *args[MAXARGS]; + int argno=0; + va_start(ap); - val = runvp (name,ap); + while (argno < MAXARGS + && (args[argno++] = va_arg(ap, char *)) != (char *)0); va_end(ap); + val = runvp (name,args); return (val); } diff --git a/usr.sbin/sup/lib/scan.c b/usr.sbin/sup/lib/scan.c index e68bcddbfa2b..9547ab6074a7 100644 --- a/usr.sbin/sup/lib/scan.c +++ b/usr.sbin/sup/lib/scan.c @@ -28,6 +28,11 @@ ********************************************************************** * HISTORY * $Log: scan.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:33 jkh * Current sup with compression support. * @@ -122,13 +127,13 @@ static char *options[] = { typedef enum { /* /list file lines */ LUPGRADE, LOMIT, LBACKUP, LEXECUTE, LINCLUDE, LNOACCT, LOMITANY, LALWAYS, - LSYMLINK, LRSYMLINK + LSYMLINK, LRSYMLINK, LRENAME } LISTTYPE; static char *ltname[] = { "upgrade", "omit", "backup", "execute", "include", "noaccount", "omitany", "always", - "symlink", "rsymlink", + "symlink", "rsymlink", "rename", 0 }; @@ -365,9 +370,11 @@ register TREE *t; if (newonly && (t->Tflags&FNEW) == 0) return (SCMOK); - newt = Tinsert (&listT,t->Tname,FALSE); + newt = Tinsert (&listT,t->Tname,t->Tflags&FRENAME ? TRUE : FALSE); if (newt == NULL) return (SCMOK); + if(t->Tnewname) + newt->Tnewname = salloc(t->Tnewname); newt->Tmode = t->Tmode; newt->Tflags = t->Tflags; newt->Tmtime = t->Tmtime; @@ -473,6 +480,10 @@ char *fname; case LUPGRADE: t = &upgT; break; + case LRENAME: + t = &flagsT; + flags = FRENAME; + break; case LBACKUP: t = &flagsT; flags = FBACKUP; @@ -522,7 +533,7 @@ char *fname; if (*q == 0) _argbreak = ')'; else - expTinsert (q,&execT,0,r); + expTinsert (q,&execT,0,r,NULL); } while (_argbreak != ')'); continue; } @@ -533,22 +544,37 @@ char *fname; while (*(q=nxtarg(&p," \t"))) { if (lt == LOMITANY) (void) Tinsert (t,q,FALSE); + else if( lt == LRENAME ) + if(*(r=nxtarg(&p," \t"))) + { + expTinsert (q,t,flags,(char *)NULL,r); + /* + * Omit the file it is being + * renamed to, to avoid confusion + */ + expTinsert (r,&omitT,0, + (char *)NULL, (char *)NULL); + } + else + printf("Rename %s without destination " + "file. Skipping...\n", q); else - expTinsert (q,t,flags,(char *)NULL); + expTinsert (q,t,flags,(char *)NULL,(char *)NULL); } } (void) fclose (f); } static -expTinsert (p,t,flags,exec) +expTinsert (p,t,flags,exec, q) char *p; +char *q; TREE **t; int flags; char *exec; { register int n, i; - register TREE *newt; + register TREE *newt, *ts; char *speclist[SPECNUMBER]; char buf[STRINGLENGTH]; @@ -557,18 +583,25 @@ char *exec; newt = Tinsert (t,speclist[i],TRUE); newt->Tflags |= flags; if (exec) { - (void) sprintf (buf,exec,speclist[i]); + if((ts = Tsearch(flagsT, speclist[i])) + && ts->Tflags&FRENAME) + (void) sprintf (buf,exec,ts->Tnewname); + else + (void) sprintf (buf,exec,speclist[i]); (void) Tinsert (&newt->Texec,buf,FALSE); } + if (q) + newt->Tnewname = salloc(q); free (speclist[i]); } } static -listone (t) /* expand and add one name from upgrade list */ +listone(t) /* expand and add one name from upgrade list */ TREE *t; { - listentry(t->Tname,t->Tname,(char *)NULL,(t->Tflags&FALWAYS) != 0); + listentry(t->Tname,t->Tname,(char *)NULL, + (t->Tflags&FALWAYS) != 0); return (SCMOK); } @@ -644,8 +677,11 @@ register struct stat *st; t->Tctime = st->st_ctime; t->Tmtime = st->st_mtime; if (new) t->Tflags |= FNEW; - if (ts = Tsearch (flagsT,name)) + if (ts = Tsearch (flagsT,name)){ t->Tflags |= ts->Tflags; + if(t->Tflags&FRENAME) + t->Tnewname = salloc(ts->Tnewname); + } if (ts = Tsearch (execT,name)) { t->Texec = ts->Texec; ts->Texec = NULL; @@ -831,6 +867,10 @@ char *scanfile; p++; ts.Tflags |= FNOACCT; } + if (*p == 'R') { + p++; + ts.Tflags |= FRENAME; + } if ((q = index (p,' ')) == NULL) goaway ("scanfile format inconsistant"); *q++ = '\0'; @@ -845,6 +885,15 @@ char *scanfile; goaway ("scanfile format inconsistant"); *q++ = 0; ts.Tmtime = atoi (p); + p = q; + ts.Tnewname = NULL; + if (ts.Tflags & FRENAME){ + if ((q = index (p,' ')) == NULL) + goaway ("scanfile format inconsistant"); + *q++ = '\0'; + ts.Tnewname = salloc(q); + q = p; + } if (ts.Tctime > lasttime) ts.Tflags |= FNEW; else if (newonly) { @@ -863,6 +912,7 @@ char *scanfile; t->Tflags = ts.Tflags; t->Tctime = ts.Tctime; t->Tmtime = ts.Tmtime; + t->Tnewname = ts.Tnewname; } (void) fclose (f); return (TRUE); @@ -925,8 +975,14 @@ FILE **scanF; if (t->Tflags&FBACKUP) fprintf (*scanF,"B"); if (t->Tflags&FNOACCT) fprintf (*scanF,"N"); - fprintf (*scanF,"%o %d %d %s\n", + if (t->Tflags&FRENAME) fprintf (*scanF,"R"); + + fprintf (*scanF,"%o %d %d", t->Tmode,t->Tctime,t->Tmtime,t->Tname); + if ( t->Tflags&FRENAME) + fprintf (*scanF," %s %s\n",t->Tname, t->Tnewname); + else + fprintf (*scanF," %s\n", t->Tname); (void) Tprocess (t->Texec,recordexec,*scanF); return (SCMOK); } diff --git a/usr.sbin/sup/lib/scm.c b/usr.sbin/sup/lib/scm.c index 5d71bccc8ae4..9b793e2912e5 100644 --- a/usr.sbin/sup/lib/scm.c +++ b/usr.sbin/sup/lib/scm.c @@ -69,6 +69,11 @@ * since Tahoe version of does not define them. * * $Log: scm.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.2 1994/06/20 06:04:04 rgrimes * Humm.. they did a lot of #if __STDC__ but failed to properly prototype * the code. Also fixed one bad argument to a wait3 call. @@ -208,7 +213,7 @@ char scmversion[] = "4.3 BSD"; * PROTOTYPES */ #if __STDC__ -int scmerr __P((int, char *,...)); +int scmerr __P((int, FILE *, char *,...)); #endif /************************* *** M A C R O S *** @@ -245,31 +250,31 @@ char *server; int one = 1; if (myhost () == NULL) - return (scmerr (-1,"Local hostname not known")); + return (scmerr (-1, stderr, "Local hostname not known")); if ((sp = getservbyname(server,"tcp")) == 0) { if (strcmp(server, FILEPORT) == 0) port = htons((u_short)FILEPORTNUM); else if (strcmp(server, DEBUGFPORT) == 0) port = htons((u_short)DEBUGFPORTNUM); else - return (scmerr (-1,"Can't find %s server description",server)); - (void) scmerr (-1,"%s/tcp: unknown service: using port %d", + return (scmerr (-1, stderr, "Can't find %s server description",server)); + (void) scmerr (-1, stderr, "%s/tcp: unknown service: using port %d", server,port); } else port = sp->s_port; endservent (); sock = socket (AF_INET,SOCK_STREAM,0); if (sock < 0) - return (scmerr (errno,"Can't create socket for connections")); + return (scmerr (errno, stderr, "Can't create socket for connections")); if (setsockopt (sock,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(int)) < 0) - (void) scmerr (errno,"Can't set SO_REUSEADDR socket option"); + (void) scmerr (errno, stderr, "Can't set SO_REUSEADDR socket option"); (void) bzero ((char *)&sin,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = port; if (bind (sock,(struct sockaddr *)&sin,sizeof(sin)) < 0) - return (scmerr (errno,"Can't bind socket for connections")); + return (scmerr (errno, stderr, "Can't bind socket for connections")); if (listen (sock,NCONNECTS) < 0) - return (scmerr (errno,"Can't listen on socket")); + return (scmerr (errno, stderr, "Can't listen on socket")); return (SCMOK); } @@ -284,16 +289,16 @@ service () netfile = accept (sock,(struct sockaddr *)&from,&len); } while (netfile < 0 && errno == EINTR); if (netfile < 0) - return (scmerr (errno,"Can't accept connections")); + return (scmerr (errno, stderr, "Can't accept connections")); remoteaddr = from.sin_addr; if (read(netfile,(char *)&x,sizeof(int)) != sizeof(int)) - return (scmerr (errno,"Can't transmit data on connection")); + return (scmerr (errno, stderr, "Can't transmit data on connection")); if (x == 0x01020304) swapmode = 0; else if (x == 0x04030201) swapmode = 1; else - return (scmerr (-1,"Unexpected byteswap mode %x",x)); + return (scmerr (-1, stderr, "Unexpected byteswap mode %x",x)); return (SCMOK); } @@ -354,7 +359,7 @@ int *t,*b; s = *t; *t -= s; } - (void) scmerr (-1,"Will retry in %d seconds",s); + (void) scmerr (-1, stdout, "Will retry in %d seconds",s); sleep (s); return (1); } @@ -376,9 +381,9 @@ int *retry; else if (strcmp(server, DEBUGFPORT) == 0) port = htons((u_short)DEBUGFPORTNUM); else - return (scmerr (-1,"Can't find %s server description", + return (scmerr (-1, stderr, "Can't find %s server description", server)); - (void) scmerr (-1,"%s/tcp: unknown service: using port %d", + (void) scmerr (-1, stderr, "%s/tcp: unknown service: using port %d", server,port); } else port = sp->s_port; @@ -387,7 +392,7 @@ int *retry; sin.sin_addr.s_addr = inet_addr (hostname); if (sin.sin_addr.s_addr == (u_long) INADDR_NONE) { if ((h = gethostbyname (hostname)) == NULL) - return (scmerr (-1,"Can't find host entry for %s", + return (scmerr (-1, stderr, "Can't find host entry for %s", hostname)); hostname = h->h_name; (void) bcopy (h->h_addr,(char *)&sin.sin_addr,h->h_length); @@ -397,11 +402,11 @@ int *retry; for (;;) { netfile = socket (AF_INET,SOCK_STREAM,0); if (netfile < 0) - return (scmerr (errno,"Can't create socket")); + return (scmerr (errno, stderr, "Can't create socket")); tin = sin; if (connect(netfile,(struct sockaddr *)&tin,sizeof(tin)) >= 0) break; - (void) scmerr (errno,"Can't connect to server for %s",server); + (void) scmerr (errno, stderr, "Can't connect to server for %s",server); (void) close(netfile); if (!dobackoff (retry,&backoff)) return (SCMERR); @@ -522,6 +527,8 @@ char *name; struct hostent *h; struct in_addr addr; char **ap; + if(!strcmp(name,"*")) + return (1); if ((addr.s_addr = inet_addr(name)) != (u_long) INADDR_NONE) return (addr.s_addr == remoteaddr.s_addr); if ((h = gethostbyname (name)) == 0) @@ -535,7 +542,7 @@ char *name; } #if __STDC__ -int scmerr (int errno,char *fmt,...) +int scmerr (int errno,FILE *filedes,char *fmt,...) #else /*VARARGS*//*ARGSUSED*/ int scmerr (va_alist) @@ -544,15 +551,16 @@ va_dcl { #if !__STDC__ int errno; + FILE *filedes; char *fmt; #endif va_list ap; - (void) fflush (stdout); + (void) fflush (filedes); if (progpid > 0) - fprintf (stderr,"%s %d: ",program,progpid); + fprintf (filedes,"%s %d: ",program,progpid); else - fprintf (stderr,"%s: ",program); + fprintf (filedes,"%s: ",program); #if __STDC__ va_start(ap,fmt); #else @@ -560,13 +568,13 @@ va_dcl errno = va_arg(ap,int); fmt = va_arg(ap,char *); #endif - vfprintf(stderr, fmt, ap); + vfprintf(filedes, fmt, ap); va_end(ap); if (errno >= 0) - fprintf (stderr,": %s\n",errmsg(errno)); + fprintf (filedes,": %s\n",errmsg(errno)); else - fprintf (stderr,"\n"); - (void) fflush (stderr); + fprintf (filedes,"\n"); + (void) fflush (filedes); return (SCMERR); } diff --git a/usr.sbin/sup/lib/scmio.c b/usr.sbin/sup/lib/scmio.c index cde2c9f7b6cd..713ceefabcb2 100644 --- a/usr.sbin/sup/lib/scmio.c +++ b/usr.sbin/sup/lib/scmio.c @@ -109,6 +109,11 @@ ********************************************************************** * HISTORY * $Log: scmio.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:33 jkh * Current sup with compression support. * @@ -249,13 +254,13 @@ char *data; } if (x <= 0) { if (errno == EPIPE) - return (scmerr (-1,"Network write timed out")); + return (scmerr (-1,stderr,"Network write timed out")); if (errno) - return (scmerr (errno,"Write error on network")); - return (scmerr (-1,"Write retries failed")); + return (scmerr (errno,stderr,"Write error on network")); + return (scmerr (-1,stderr,"Write retries failed")); } if (x != count) - return (scmerr (-1,"Write error on network returned %d on write of %d",x,count)); + return (scmerr (-1,stderr,"Write error on network returned %d on write of %d",x,count)); return (SCMOK); } @@ -280,7 +285,7 @@ int msg; if (scmdebug > 1) loginfo ("SCM Writing message %d",msg); if (bufptr) - return (scmerr (-1,"Buffering already enabled")); + return (scmerr (-1,stderr,"Buffering already enabled")); bufptr = buffers; bufptr->b_ptr = bufptr->b_data; bufptr->b_cnt = 0; @@ -298,7 +303,7 @@ writemend () /* write end of message */ x = writedata (sizeof(int),(char *)&x); if (x != SCMOK) return (x); if (bufptr == NULL) - return (scmerr (-1,"Buffering already disabled")); + return (scmerr (-1,stderr,"Buffering already disabled")); if (bufptr->b_cnt == 0) { bufptr = NULL; return (SCMOK); @@ -351,7 +356,7 @@ int f; struct stat statbuf; if (fstat(f,&statbuf) < 0) - return (scmerr (errno,"Can't access open file for message")); + return (scmerr (errno,stderr,"Can't access open file for message")); filesize = statbuf.st_size; y = byteswap(filesize); x = writedata (sizeof(int),(char *)&y); @@ -375,9 +380,9 @@ int f; } while (x == SCMOK && number > 0); } if (sum != filesize) - return (scmerr (-1,"File size error on output message")); + return (scmerr (-1,stderr,"File size error on output message")); if (number < 0) - return (scmerr (errno,"Read error on file output message")); + return (scmerr (errno,stderr,"Read error on file output message")); return (x); } @@ -431,7 +436,7 @@ char *data; if (count < 0) { if (bufptr + count < buffer) - return (scmerr (-1,"No space in buffer %d",count)); + return (scmerr (-1,stderr,"No space in buffer %d",count)); bufptr += count; bufcnt -= count; bcopy (data,bufptr,-count); @@ -463,16 +468,21 @@ char *data; tries = 0; for (;;) { imask = 1 << netfile; +#if defined(__hpux) + if (select(32,&imask,(int *)0,(int *)0,&timout) < 0) +#else if (select(32,(fd_set *)&imask,(fd_set *)0,(fd_set *)0,&timout) < 0) +#endif imask = 1; errno = 0; if (imask) x = read (netfile,p,n); else - return (scmerr (-1,"Timeout on network input")); + return (scmerr (-1,stderr,"Timeout on network input")); if (x > 0) break; if (x == 0) - return (scmerr (-1,"Premature EOF on network input")); + return (scmerr (-1,stderr,"Premature EOF on network " + "input")); if (errno) break; if (++tries > RETRIES) break; if (scmdebug > 0) @@ -480,8 +490,8 @@ char *data; } if (x < 0) { if (errno) - return (scmerr (errno,"Read error on network")); - return (scmerr (-1,"Read retries failed")); + return (scmerr (errno,stderr,"Read error on network")); + return (scmerr (-1,stderr,"Read retries failed")); } p += x; n -= x; @@ -538,7 +548,7 @@ int msg; /* if message is unexpected, send back SCMHUH */ /* check for MSGGOAWAY in case he noticed problems first */ if (m != MSGGOAWAY) - return (scmerr (-1,"Received unexpected message %d",m)); + return (scmerr (-1,stderr,"Received unexpected message %d",m)); (void) netcrypt ((char *)NULL); (void) readstring (&goawayreason); (void) readmend (); @@ -555,7 +565,7 @@ readmend () x = readdata (sizeof(int),(char *)&y); y = byteswap(y); if (x == SCMOK && y != ENDCOUNT) - return (scmerr (-1,"Error reading end of message")); + return (scmerr (-1,stderr,"Error reading end of message")); return (x); } @@ -567,7 +577,7 @@ readskip () /* skip over one input block */ x = readcount (&n); if (x != SCMOK) return (x); if (n < 0) - return (scmerr (-1,"Invalid message count %d",n)); + return (scmerr (-1,stderr,"Invalid message count %d",n)); while (x == SCMOK && n > 0) { x = readdata (XFERSIZE(n),buf); n -= XFERSIZE(n); @@ -583,9 +593,9 @@ int *buf; x = readcount (&y); if (x != SCMOK) return (x); if (y < 0) - return (scmerr (-1,"Invalid message count %d",y)); + return (scmerr (-1,stderr,"Invalid message count %d",y)); if (y != sizeof(int)) - return (scmerr (-1,"Size error for int message is %d",y)); + return (scmerr (-1,stderr,"Size error for int message is %d",y)); x = readdata (sizeof(int),(char *)&y); (*buf) = byteswap(y); if (scmdebug > 2) @@ -609,11 +619,11 @@ register char **buf; return (SCMOK); } if (count < 0) - return (scmerr (-1,"Invalid message count %d",count)); + return (scmerr (-1,stderr,"Invalid message count %d",count)); if (scmdebug > 3) loginfo ("SCM Reading string count %d",count); if ((p = (char *)malloc ((unsigned)count+1)) == NULL) - return (scmerr (-1,"Can't malloc %d bytes for string",count)); + return (scmerr (-1,stderr,"Can't malloc %d bytes for string",count)); if (cryptflag) { x = getcryptbuf (count+1); if (x == SCMOK) x = readdata (count,cryptbuf); @@ -647,7 +657,7 @@ int f; x = readcount (&count); if (x != SCMOK) return (x); if (count < 0) - return (scmerr (-1,"Invalid message count %d",count)); + return (scmerr (-1,stderr,"Invalid message count %d",count)); while (x == SCMOK && count > 0) { if (cryptflag) { x = readdata (XFERSIZE(count),cryptbuf); @@ -709,7 +719,11 @@ crosspatch () FD_ZERO (&xbits); FD_SET (0,&ibits); FD_SET (netfile,&ibits); +#if defined(__hpux) + if ((c = select(16, (int *)&ibits, (int *)&obits, (int *)&xbits, +#else if ((c = select(16, &ibits, &obits, &xbits, +#endif (struct timeval *)NULL)) < 1) { if (c == -1) { if (errno == EINTR) { diff --git a/usr.sbin/sup/lib/stree.c b/usr.sbin/sup/lib/stree.c index 0170b3be83f7..5b094308ae5b 100644 --- a/usr.sbin/sup/lib/stree.c +++ b/usr.sbin/sup/lib/stree.c @@ -28,6 +28,11 @@ ********************************************************************** * HISTORY * $Log: stree.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:34 jkh * Current sup with compression support. * @@ -77,6 +82,7 @@ register TREE **t; Tfree (&((*t)->Tlo)); Tfree (&((*t)->Thi)); if ((*t)->Tname) free ((*t)->Tname); + if ((*t)->Tnewname) free ((*t)->Tnewname); if ((*t)->Tuser) free ((*t)->Tuser); if ((*t)->Tgroup) free ((*t)->Tgroup); free (*(char **)t); @@ -90,6 +96,7 @@ char *p; register TREE *t; t = (TREE *) malloc (sizeof (TREE)); t->Tname = (p == NULL) ? NULL : salloc (p); + t->Tnewname = NULL; t->Tflags = 0; t->Tuid = 0; t->Tgid = 0; diff --git a/usr.sbin/sup/lib/sup.h b/usr.sbin/sup/lib/sup.h index 0b5f07ee5a72..12f03c3da901 100644 --- a/usr.sbin/sup/lib/sup.h +++ b/usr.sbin/sup/lib/sup.h @@ -39,6 +39,11 @@ * across the network to save BandWidth * * $Log: sup.h,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:34 jkh * Current sup with compression support. * @@ -101,8 +106,8 @@ /* PGMVERSION is defined separately in each program */ extern char scmversion[]; /* string version of scm */ -#define PROTOVERSION 8 /* version of network protocol */ -#define SCANVERSION 2 /* version of scan file format */ +#define PROTOVERSION 9 /* version of network protocol */ +#define SCANVERSION 3 /* version of scan file format */ /* TCP servers for name server and file server */ #define FILEPORT "supfilesrv" @@ -182,6 +187,7 @@ extern char scmversion[]; /* string version of scm */ struct treestruct { /* fields for file information */ char *Tname; /* path component name */ + char *Tnewname; /* Used for renameing files */ int Tflags; /* flags of file */ int Tmode; /* st_mode of file */ char *Tuser; /* owner of file */ @@ -220,6 +226,7 @@ typedef struct tliststruct TREELIST; #define FBACKUP 02 /* backup of file is allowed */ #define FNOACCT 04 /* don't set file information */ #define FUPDATE 010 /* only set file information */ +#define FRENAME 020 /* Rename this file while updating */ #define FNEEDED 0100000 /* file needed for upgrade */ /* version 3 compatability */ diff --git a/usr.sbin/sup/lib/supmsg.c b/usr.sbin/sup/lib/supmsg.c index 38949109e152..b12c945462f5 100644 --- a/usr.sbin/sup/lib/supmsg.c +++ b/usr.sbin/sup/lib/supmsg.c @@ -31,6 +31,11 @@ * across the network to save BandWidth * * $Log: supmsg.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:35 jkh * Current sup with compression support. * @@ -299,6 +304,7 @@ int msgrefuse () * list files message */ extern TREE *listT; /* tree of files to list */ +extern TREE *renameT; /* tree of rename target files */ extern long scantime; /* time that collection was scanned */ static int listone (t) @@ -307,6 +313,8 @@ register TREE *t; register int x; x = writestring (t->Tname); + if ( protver > 8 ) + if (x == SCMOK) x = writestring (t->Tnewname); if (x == SCMOK) x = writeint ((int)t->Tmode); if (x == SCMOK) x = writeint ((int)t->Tflags); if (x == SCMOK) x = writeint (t->Tmtime); @@ -323,19 +331,25 @@ int msglist () if (x == SCMOK) x = writeint ((int)scantime); if (x == SCMOK) x = writemend (); } else { - char *name; + char *name, *newname = NULL; int mode,flags,mtime; register TREE *t; x = readmsg (MSGLIST); if (x == SCMOK) x = readstring (&name); while (x == SCMOK) { if (name == NULL) break; - x = readint (&mode); + if (protver > 8){ + x = readstring (&newname); + if (x == SCMOK) x = readint (&mode); + } + else + x = readint (&mode); if (x == SCMOK) x = readint (&flags); if (x == SCMOK) x = readint (&mtime); if (x != SCMOK) break; t = Tinsert (&listT,name,TRUE); free (name); + t->Tnewname = newname; t->Tmode = mode; t->Tflags = flags; t->Tmtime = mtime; @@ -474,6 +488,8 @@ va_dcl return (x); } if (x == SCMOK) x = writestring (t->Tname); + if (protver > 8) + if (x == SCMOK) x = writestring (t->Tnewname); if (x == SCMOK) x = writeint (t->Tmode); if (t->Tmode == 0) { if (x == SCMOK) x = writemend (); @@ -499,6 +515,8 @@ va_dcl if (x == SCMOK) x = (*xferfile) (NULL,args); return (x); } + if (protver > 8) + if (x == SCMOK) x = readstring (&t->Tnewname); if (x == SCMOK) x = readint (&t->Tmode); if (t->Tmode == 0) { x = readmend (); diff --git a/usr.sbin/sup/lib/supmsg.h b/usr.sbin/sup/lib/supmsg.h index b30ea9a46a45..e6185c486ba0 100644 --- a/usr.sbin/sup/lib/supmsg.h +++ b/usr.sbin/sup/lib/supmsg.h @@ -33,6 +33,11 @@ * across the network to save BandWidth * * $Log: supmsg.h,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:35 jkh * Current sup with compression support. * @@ -170,6 +175,7 @@ EXTERN TREE *refuseT; /* tree of files to refuse */ /* msglist */ EXTERN TREE *listT; /* tree of files to list */ +EXTERN TREE *renameT; /* tree of file rename targets */ EXTERN long scantime; /* time that collection was scanned */ /* msgneed */ diff --git a/usr.sbin/sup/lib/vprintf.c b/usr.sbin/sup/lib/vprintf.c index 235a5f17c601..2c1a309702a7 100644 --- a/usr.sbin/sup/lib/vprintf.c +++ b/usr.sbin/sup/lib/vprintf.c @@ -28,6 +28,11 @@ ********************************************************************** * HISTORY * $Log: vprintf.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:47 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.1.1.1 1993/08/21 00:46:35 jkh * Current sup with compression support. * @@ -118,9 +123,16 @@ vsnprintf(s, n, fmt, args) { FILE fakebuf; +#ifdef __hpux + fakebuf._flag = _IODUMMY+_IOWRT;/* no _IOWRT: avoid stdio bug */ + fakebuf._base = fakebuf._ptr = s; + fakebuf._cnt = n-1; + fakebuf.__fileL = fakebuf.__fileH = 0xff; +#else fakebuf._flag = _IOSTRG+_IOWRT; /* no _IOWRT: avoid stdio bug */ fakebuf._ptr = s; fakebuf._cnt = n-1; +#endif _doprnt(fmt, args, &fakebuf); fakebuf._cnt++; putc('\0', &fakebuf); diff --git a/usr.sbin/sup/sup/sup.1 b/usr.sbin/sup/sup/sup.1 index fa35f5d5a4ee..0e860c68c83d 100644 --- a/usr.sbin/sup/sup/sup.1 +++ b/usr.sbin/sup/sup/sup.1 @@ -23,6 +23,11 @@ .\""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" .\" HISTORY .\" $Log: sup.1,v $ +.\" Revision 1.1.1.1 1995/12/26 04:54:46 peter +.\" Import the unmodified version of the sup that we are using. +.\" The heritage of this version is not clear. It appears to be NetBSD +.\" derived from some time ago. +.\" .\" Revision 1.2 1994/08/11 02:46:19 rich .\" Added extensions written by David Dawes. From the man page: .\" @@ -59,7 +64,7 @@ .\" 04-Apr-85 Steven Shafer (sas) at Carnegie-Mellon University .\" Created. .\" -.TH SUP 1 02/08/92 +.TH SUP 1 03/15/95 .CM 4 .SH "NAME" sup \- software upgrade protocol @@ -247,6 +252,41 @@ upgrade will be performed. Messages will be printed that indicate what would happen if an actual upgrade were done. .TP +.B -i +Normally, +.I sup +will fail to upgrade any files that are \fBETXTBSY\fR. +The +.B -i +flag, or the +.B unlinkbusy +supfile option, will cause +.I sup +to try to upgrade a busy file by unlinking it before the +replacement file is installed. The option is intended for +environments where upgrades to possibly running binaries or +libraries will take place. Some operating systems \fB(HPUX)\fR +do not allow the unlink system call to succeed on ETXTBSY files. +If the unlink does not succeed, an attempt is made to rename the +file to filename.sup#sup-pid.moved. The new name is logged in either +the system default rename log file, \fB/usr/local/etc/sup.moved\fR, +or in a logfile as set by the \fBrenamelog\fR supfile option. The +logfile allows for easy deletion of ETXTBSY files once they are no +longer in use. A typical time to perform the deletions is at system +boot time with something similar to: +.TP +.ce 1 +cat /usr/local/etc/sup.moved | xargs rm -rf +.TP +.B -I +The +.B -I +flag overrides and disables the +.B -i +flag and the +.B unlinkbusy +supfile option. +.TP .B -k .I Sup will check the modification times of @@ -537,6 +577,19 @@ project's file collection from all users running .I sup to upgrade that collection. .TP +.BI renamelog= filename +When the +.B +unlinkbusy +or +.B +-i +option is enabled, but the system cannot unlink a busy file, it +will rename it instead and log the new filename. Logging will +occur to the system default rename log file or to the specified +.IR filename +in the renamelog entry of a supfile. +.TP .B backup As described above under the .B -b @@ -562,6 +615,11 @@ As described above under the .B -o flag. .TP +.B unlinkbusy +As described above under the +.B -i +flag. +.TP .B noupdate As described above under the .B -u @@ -729,6 +787,12 @@ The always command is identical to upgrade, except that omit and omitany commands do not affect filenames specified with the always command. .TP +\fBrename\fR \fIfilename\fR \fIdest-filename\fR... +The rename command allows for a file on the server to be placed on the +client under a different name. To prevent confusion and ease its use, +the rename option implicitly omits any files on the server that have +the same name as \fIdest-filename\fR. +.TP \fBomit\fR \fIfilename\fR ... The specified file(s) (or directories) will be excluded from the list of files to be upgraded. @@ -796,7 +860,9 @@ As described above, the client must invoke .I sup with the .B -e -flag to allow the automatic execution of command files. +flag to allow the automatic execution of command files. The timestamp +of the upgraded file is maintained even if the executed command might +change it so as to prevent an upgrade with every \fIsup\fR. .TP \fBinclude\fR \fIlistfile\fR ... The specified @@ -862,6 +928,9 @@ lock file for a collection <\fIbase-directory\fR>\fB/sup/\fR<\fIcollection\fR>\fB/logfile log file for a collection .TP +\fB/usr/local/etc/sup.moved\fR +log file for files renamed by the \fBunlinkbusy\fR option +.TP <\fIbase-directory\fR>\fB/sup/\fR<\fIcollection\fR>\fB/prefix file containing the name of the prefix directory for a collection diff --git a/usr.sbin/sup/sup/supcdefs.h b/usr.sbin/sup/sup/supcdefs.h index c348fd207688..dface51f6d13 100644 --- a/usr.sbin/sup/sup/supcdefs.h +++ b/usr.sbin/sup/sup/supcdefs.h @@ -33,6 +33,11 @@ * across the network to save BandWidth * * $Log: supcdefs.h,v $ + * Revision 1.1.1.1 1995/12/26 04:54:46 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.3 1994/08/11 02:46:21 rich * Added extensions written by David Dawes. From the man page: * @@ -118,6 +123,7 @@ struct collstruct { /* one per collection to be upgraded */ char *Clogin; /* remote login name */ char *Cpswd; /* remote password */ char *Ccrypt; /* data encryption key */ + char *Crenamelog; /* Where to log files moved when busy */ int Ctimeout; /* timeout for backoff */ int Cflags; /* collection flags */ int Cnogood; /* upgrade no good, "when" unchanged */ @@ -126,19 +132,20 @@ struct collstruct { /* one per collection to be upgraded */ }; typedef struct collstruct COLLECTION; -#define CFALL 00001 -#define CFBACKUP 00002 -#define CFDELETE 00004 -#define CFEXECUTE 00010 -#define CFLIST 00020 -#define CFLOCAL 00040 -#define CFMAIL 00100 -#define CFOLD 00200 -#define CFVERBOSE 00400 -#define CFKEEP 01000 -#define CFURELSUF 02000 -#define CFCOMPRESS 04000 -#define CFNOUPDATE 010000 +#define CFALL 0x0001 +#define CFBACKUP 0x0002 +#define CFDELETE 0x0004 +#define CFEXECUTE 0x0008 +#define CFLIST 0x0010 +#define CFLOCAL 0x0020 +#define CFMAIL 0x0040 +#define CFOLD 0x0080 +#define CFVERBOSE 0x0100 +#define CFKEEP 0x0200 +#define CFURELSUF 0x0400 +#define CFCOMPRESS 0x0800 +#define CFNOUPDATE 0x1000 +#define CFUNLINKBUSY 0x2000 /************************* *** M A C R O S *** @@ -149,7 +156,7 @@ typedef struct collstruct COLLECTION; * C prototypes */ #if __STDC__ -void done __P((int value,char *fmt,...)); -void goaway __P((char *fmt,...)); -void notify __P((char *fmt,...)); +void done __P((int value,char *fmt,...)); +void goaway __P((char *fmt,...)); +void notify __P((char *fmt,...)); #endif diff --git a/usr.sbin/sup/sup/supcmain.c b/usr.sbin/sup/sup/supcmain.c index 0b25af1e3416..47fb9b5478a6 100644 --- a/usr.sbin/sup/sup/supcmain.c +++ b/usr.sbin/sup/sup/supcmain.c @@ -174,6 +174,11 @@ * across the network to save BandWidth * * $Log: supcmain.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:46 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.2 1994/08/11 02:46:22 rich * Added extensions written by David Dawes. From the man page: * @@ -418,7 +423,11 @@ char **argv; int fd; loginfo ("SUP Restarting %s with new supfile %s", progname,supfname); +#ifdef __hpux + for (fd = 256; fd > 3; fd--) +#else for (fd = getdtablesize (); fd > 3; fd--) +#endif (void) close (fd); execv (progname,argv); logquit (1,"Restart failed"); @@ -551,6 +560,14 @@ int *oflagsp,*aflagsp; case 'm': oflags |= CFMAIL; break; + case 'i': + oflags |= CFUNLINKBUSY; + aflags &= ~CFUNLINKBUSY; + break; + case 'I': + oflags &= ~CFUNLINKBUSY; + aflags |= CFUNLINKBUSY; + break; case 'o': oflags |= CFOLD; aflags &= ~CFOLD; diff --git a/usr.sbin/sup/sup/supcmeat.c b/usr.sbin/sup/sup/supcmeat.c index 101107479b10..2b2db06ebe7d 100644 --- a/usr.sbin/sup/sup/supcmeat.c +++ b/usr.sbin/sup/sup/supcmeat.c @@ -32,6 +32,11 @@ * across the network to save BandWidth * * $Log: supcmeat.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:46 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.4 1994/08/11 02:46:23 rich * Added extensions written by David Dawes. From the man page: * @@ -156,6 +161,8 @@ jmp_buf sjbuf; /* jump location for network errors */ int dontjump; /* flag to void sjbuf */ int cancompress=FALSE; /* Can we do compression? */ int docompress=FALSE; /* Do we do compression? */ +int dounlinkbusy=FALSE; /* Should we try to unlink busy files?*/ +FILE *renamelog=NULL; /* Where we log renamed files */ extern COLLECTION *thisC; /* collection list pointer */ extern int rpauseflag; /* don't disable resource pausing */ @@ -492,7 +499,8 @@ int listfiles () int needone(), denyone(), deleteone(); char buf[STRINGLENGTH]; char relsufix[STRINGLENGTH]; - register char *p,*q; + TREE *t; + register char *p,*q,*r; register FILE *f; register int x; @@ -506,8 +514,14 @@ int listfiles () if (f) { while (p = fgets (buf,STRINGLENGTH,f)) { if (q = index (p,'\n')) *q = '\0'; + if (r = index (p,' ')) *r++ = '\0'; if (index ("#;:",*p)) continue; - (void) Tinsert (&lastT,p,FALSE); + t = Tinsert (&lastT,p,FALSE); + if(t && r) + { + t->Tnewname = salloc(r); + t->Tflags = FRENAME; + } } (void) fclose (f); } @@ -532,6 +546,7 @@ int listfiles () goaway ("Error reading file list from file server"); if (thisC->Cprefix) (void) chdir (thisC->Cprefix); needT = NULL; + renameT = NULL; (void) Tprocess (listT,needone); Tfree (&listT); x = msgneed (); @@ -548,6 +563,8 @@ int listfiles () if (thisC->Cflags&(CFALL|CFDELETE|CFOLD)) (void) Trprocess (lastT,deleteone); Tfree (&refuseT); + Tfree (&renameT); + renameT = NULL; } needone (t) @@ -556,17 +573,26 @@ register TREE *t; register TREE *newt; register int exists, fetch; struct stat sbuf; + char *name; newt = Tinsert (&lastT,t->Tname,TRUE); newt->Tflags |= FUPDATE; + if(t->Tflags&FRENAME) { + newt->Tflags |= FRENAME; + newt->Tnewname = salloc(t->Tnewname); + name = t->Tnewname; + Tinsert(&renameT,t->Tnewname); + } + else + name = t->Tname; fetch = TRUE; if ((thisC->Cflags&CFALL) == 0) { if ((t->Tflags&FNEW) == 0 && (thisC->Cflags&CFOLD) == 0) return (SCMOK); if ((t->Tmode&S_IFMT) == S_IFLNK) - exists = (lstat (t->Tname,&sbuf) == 0); + exists = (lstat (name,&sbuf) == 0); else - exists = (stat (t->Tname,&sbuf) == 0); + exists = (stat (name,&sbuf) == 0); /* This is moderately complicated: If the file is the wrong type or doesn't exist, we need to fetch the whole file. If the file is a special file, we @@ -592,12 +618,12 @@ register TREE *t; else return (SCMOK); } /* If we get this far, we're either doing an update or a full fetch. */ + newt = Tinsert (&needT,t->Tname,TRUE); if (!fetch && t->Tmode == sbuf.st_mode && (t->Tmode&S_IFMT) == S_IFREG && (thisC->Cflags&CFNOUPDATE)) { vnotify ("SUP update avoided for %s\n", t->Tname); - return (SCMOK); + return (SCMOK); } - newt = Tinsert (&needT,t->Tname,TRUE); if (!fetch && (t->Tmode&S_IFMT) == S_IFREG) newt->Tflags |= FUPDATE; return (SCMOK); @@ -615,12 +641,15 @@ TREE *t; { struct stat sbuf; register int x; - register char *name = t->Tname; + register char *name = t->Tflags & FRENAME ? t->Tnewname : t->Tname; if (t->Tflags&FUPDATE) /* in current upgrade list */ return (SCMOK); if (lstat(name,&sbuf) < 0) /* doesn't exist */ return (SCMOK); + if (Tlookup (renameT, name)) /* it is a file we're going to replace + return (SCMOK); * by renaming another target. + */ /* is it a symbolic link ? */ if ((sbuf.st_mode & S_IFMT) == S_IFLNK) { if (Tlookup (refuseT,name)) { @@ -723,6 +752,10 @@ recvfiles () if (docompress) vnotify("SUP Using compressed file transfer\n"); } + /* Should we attempt to unlink files that are busy? */ + dounlinkbusy = (thisC->Cflags & CFUNLINKBUSY); + if(dounlinkbusy) + vnotify("SUP Will attempt to unlink busy files\n"); recvmore = TRUE; upgradeT = NULL; do { @@ -735,6 +768,8 @@ recvfiles () goaway ("Error receiving file from file server"); Tfree (&upgradeT); } while (recvmore); + if( renamelog ) + fclose( renamelog ); } /* prepare the target, if necessary */ @@ -779,7 +814,7 @@ struct stat *statp; } if ((statp->st_mode&S_IFMT) == S_IFDIR) { if (rmdir (name) < 0) - runp ("rm","rm","-rf",name,0); + runp ("rm","rm","-rf",name,(char *)0); } else (void) unlink (name); if (stat (name,statp) < 0) { @@ -799,7 +834,7 @@ va_list ap; struct stat sbuf; int linkone (),execone (); int *recvmore = va_arg(ap,int *); - + char *name; /* check for end of file list */ if (t == NULL) { *recvmore = FALSE; @@ -812,8 +847,9 @@ va_list ap; thisC->Cnogood = TRUE; return (SCMOK); } - if (prepare (t->Tname,t->Tmode&S_IFMT,&new,&sbuf)) { - notify ("SUP: Can't prepare path for %s\n",t->Tname); + name = t->Tflags & FRENAME ? t->Tnewname : t->Tname; + if (prepare (name,t->Tmode&S_IFMT,&new,&sbuf)) { + notify ("SUP: Can't prepare path for %s\n",name); if ((t->Tmode&S_IFMT) == S_IFREG) { x = readskip (); /* skip over file */ if (x != SCMOK) @@ -841,8 +877,8 @@ va_list ap; return (SCMOK); } if ((t->Tmode&S_IFMT) == S_IFREG) - (void) Tprocess (t->Tlink,linkone,t->Tname); - (void) Tprocess (t->Texec,execone); + (void) Tprocess (t->Tlink,linkone,name); + (void) Tprocess (t->Texec,execone,name); return (SCMOK); } @@ -852,15 +888,16 @@ register int new; register struct stat *statp; { struct timeval tbuf[2]; + char *name = t->Tflags & FRENAME ? t->Tnewname : t->Tname; if (new) { if (thisC->Cflags&CFLIST) { - vnotify ("SUP Would create directory %s\n",t->Tname); + vnotify ("SUP Would create directory %s\n",name); return (FALSE); } - (void) mkdir (t->Tname,0755); - if (stat (t->Tname,statp) < 0) { - notify ("SUP: Can't create directory %s\n",t->Tname); + (void) mkdir (name,0755); + if (stat (name,statp) < 0) { + notify ("SUP: Can't create directory %s\n",name); return (TRUE); } } @@ -875,17 +912,17 @@ register struct stat *statp; return (FALSE); } if (thisC->Cflags&CFLIST) { - vnotify ("SUP Would update directory %s\n",t->Tname); + vnotify ("SUP Would update directory %s\n",name); return (FALSE); } if ((t->Tflags&FNOACCT) == 0) { - (void) chown (t->Tname,t->Tuid,t->Tgid); - (void) chmod (t->Tname,t->Tmode&S_IMODE); + (void) chown (name,t->Tuid,t->Tgid); + (void) chmod (name,t->Tmode&S_IMODE); } tbuf[0].tv_sec = time((long *)NULL); tbuf[0].tv_usec = 0; tbuf[1].tv_sec = t->Tmtime; tbuf[1].tv_usec = 0; - (void) utimes (t->Tname,tbuf); - vnotify ("SUP %s directory %s\n",new?"Created":"Updated",t->Tname); + (void) utimes (name,tbuf); + vnotify ("SUP %s directory %s\n",new?"Created":"Updated",name); return (FALSE); } @@ -897,29 +934,30 @@ register struct stat *statp; char buf[STRINGLENGTH]; int n; register char *linkname; + char *name = t->Tflags & FRENAME ? t->Tnewname : t->Tname; - if (t->Tlink == NULL || t->Tlink->Tname == NULL) { + if (t->Tlink == NULL || name == NULL) { notify ("SUP: Missing linkname for symbolic link %s\n", t->Tname); return (TRUE); } linkname = t->Tlink->Tname; if (!new && (t->Tflags&FNEW) == 0 && - (n = readlink (t->Tname,buf,sizeof(buf))) >= 0 && + (n = readlink (name,buf,sizeof(buf))) >= 0 && (n == strlen (linkname)) && (strncmp (linkname,buf,n) == 0)) return (FALSE); if (thisC->Cflags&CFLIST) { vnotify ("SUP Would %s symbolic link %s to %s\n", - new?"create":"update",t->Tname,linkname); + new?"create":"update",name,linkname); return (FALSE); } if (!new) - (void) unlink (t->Tname); - if (symlink (linkname,t->Tname) < 0 || lstat(t->Tname,statp) < 0) { - notify ("SUP: Unable to create symbolic link %s\n",t->Tname); + (void) unlink (name); + if (symlink (linkname,name) < 0 || lstat(name,statp) < 0) { + notify ("SUP: Unable to create symbolic link %s\n",name); return (TRUE); } - vnotify ("SUP Created symbolic link %s to %s\n",t->Tname,linkname); + vnotify ("SUP Created symbolic link %s to %s\n",name,linkname); return (FALSE); } @@ -934,6 +972,7 @@ register struct stat *statp; struct timeval tbuf[2]; register int x; register char *p; + char *name = t->Tflags & FRENAME ? t->Tnewname : t->Tname; if (t->Tflags&FUPDATE) { if ((t->Tflags&FNOACCT) == 0) { @@ -950,17 +989,17 @@ register struct stat *statp; return (FALSE); } if (thisC->Cflags&CFLIST) { - vnotify ("SUP Would update file %s\n",t->Tname); + vnotify ("SUP Would update file %s\n",name); return (FALSE); } - vnotify ("SUP Updating file %s\n",t->Tname); + vnotify ("SUP Updating file %s\n",name); if ((t->Tflags&FNOACCT) == 0) { - (void) chown (t->Tname,t->Tuid,t->Tgid); - (void) chmod (t->Tname,t->Tmode&S_IMODE); + (void) chown (name,t->Tuid,t->Tgid); + (void) chmod (name,t->Tmode&S_IMODE); } tbuf[0].tv_sec = time((long *)NULL); tbuf[0].tv_usec = 0; tbuf[1].tv_sec = t->Tmtime; tbuf[1].tv_usec = 0; - (void) utimes (t->Tname,tbuf); + (void) utimes (name,tbuf); return (FALSE); } if (thisC->Cflags&CFLIST) { @@ -972,22 +1011,22 @@ register struct stat *statp; p = "receive old"; else p = "receive"; - vnotify ("SUP Would %s file %s\n",p,t->Tname); + vnotify ("SUP Would %s file %s\n",p,name); return (FALSE); } - vnotify ("SUP Receiving file %s\n",t->Tname); + vnotify ("SUP Receiving file %s\n",name); if (!new && (t->Tmode&S_IFMT) == S_IFREG && (t->Tflags&FBACKUP) && (thisC->Cflags&CFBACKUP)) { - fin = fopen (t->Tname,"r"); /* create backup */ + fin = fopen (name,"r"); /* create backup */ if (fin == NULL) { x = readskip (); /* skip over file */ if (x != SCMOK) goaway ("Can't skip file transfer"); notify ("SUP: Can't open %s to create backup\n", - t->Tname); + name); return (TRUE); /* mark upgrade as nogood */ } - path (t->Tname,dirpart,filepart); + path (name,dirpart,filepart); (void) sprintf (filename,FILEBACKUP,dirpart,filepart); fout = fopen (filename,"w"); if (fout == NULL) { @@ -1006,20 +1045,20 @@ register struct stat *statp; ffilecopy (fin,fout); (void) fclose (fin); (void) fclose (fout); - vnotify ("SUP Backup of %s created\n", t->Tname); + vnotify ("SUP Backup of %s created\n", name); } - x = copyfile (t->Tname,(char *)NULL); + x = copyfile (name,(char *)NULL); if (x) return (TRUE); if ((t->Tflags&FNOACCT) == 0) { /* convert user and group names to local ids */ ugconvert (t->Tuser,t->Tgroup,&t->Tuid,&t->Tgid,&t->Tmode); - (void) chown (t->Tname,t->Tuid,t->Tgid); - (void) chmod (t->Tname,t->Tmode&S_IMODE); + (void) chown (name,t->Tuid,t->Tgid); + (void) chmod (name,t->Tmode&S_IMODE); } tbuf[0].tv_sec = time((long *)NULL); tbuf[0].tv_usec = 0; tbuf[1].tv_sec = t->Tmtime; tbuf[1].tv_usec = 0; - (void) utimes (t->Tname,tbuf); + (void) utimes (name,tbuf); return (FALSE); } @@ -1067,9 +1106,12 @@ register char **fname; return (SCMOK); } -execone (t) /* execute command for file */ +execone (t,name) /* execute command for file */ register TREE *t; +register char **name; { + struct stat sbuf; + struct timeval tbuf[2]; union wait w; if (thisC->Cflags&CFLIST) { @@ -1082,6 +1124,10 @@ register TREE *t; } vnotify ("SUP Executing %s\n",t->Tname); + if (lstat(*name,&sbuf)){ + notify ("SUP Unable to stat file %s\n", *name); + sbuf.st_ino = 0; + } w.w_status = system (t->Tname); if (WIFEXITED(w) && w.w_retcode != 0) { notify ("SUP: Execute command returned failure status %#o\n", @@ -1096,6 +1142,14 @@ register TREE *t; w.w_stopsig); thisC->Cnogood = TRUE; } + if ((sbuf.st_ino != 0) && (sbuf.st_mode&S_IFMT) != S_IFLNK){ + (void) chown (*name,sbuf.st_uid,sbuf.st_gid); + (void) chmod (*name,(sbuf.st_mode)&0x1ff); + tbuf[0].tv_sec = time((long *)NULL); tbuf[0].tv_usec = 0; + tbuf[1].tv_sec = sbuf.st_mtime; tbuf[1].tv_usec = 0; + (void) utimes (*name,tbuf); + } + return (SCMOK); } @@ -1108,6 +1162,7 @@ char *from; /* 0 if reading from network */ char tname[STRINGLENGTH]; char sys_com[STRINGLENGTH]; struct stat sbuf; + int retried = 0; static int thispid = 0; /* process id # */ @@ -1241,6 +1296,7 @@ char *from; /* 0 if reading from network */ return (FALSE); } /* uncompress it first */ +retry: if (docompress) { /* make sure file permissions don't cause a problem */ (void) unlink (to); @@ -1274,6 +1330,48 @@ char *from; /* 0 if reading from network */ tof = open (to,(O_WRONLY|O_CREAT|O_TRUNC),0600); if (tof < 0) { (void) close (fromf); + /* Here we can tell if it is ETXTBSY and try this loop + again */ + if( dounlinkbusy && errno == ETXTBSY && !retried ) { + /* Try to unlink the destination */ + if( unlink(to) == 0 ){ + vnotify ("SUP: Removed busy file %s\n", to); + retried = 1; + goto retry; + } + /* + * Some OSs (ie. HP-UX), return ETXTBUSY on unlinking + * a busy file. We try to rename it instead and log + * the filename so it can be removed later. + */ + else if( errno == ETXTBSY ) { + char mname[STRINGLENGTH]; + + sprintf(mname, "%s.sup.#%d.moved", to, thispid); + + if( rename(to, mname) == 0) { + vnotify ("SUP: Moved busy file %s to %s\n", to, + mname); + if(renamelog == NULL) { + renamelog = fopen(thisC->Crenamelog, "a"); + if( renamelog == NULL ) { + notify ("SUP: Cannot open rename log file %s: " + "%s\n",thisC->Crenamelog,errmsg (-1)); + } + else { + fprintf(renamelog, "%s\n", mname); + fflush(renamelog); + } + } + else { + fprintf(renamelog, "%s\n", mname); + fflush(renamelog); + } + retried = 1; + goto retry; + } + } + } notify ("SUP: Can't create %s from temp file: %s\n", to,errmsg (-1)); (void) unlink (tname); @@ -1399,7 +1497,10 @@ TREE *t; FILE **finishfile; { if ((thisC->Cflags&CFDELETE) == 0 || (t->Tflags&FUPDATE)) - fprintf (*finishfile,"%s\n",t->Tname); + if(t->Tflags&FRENAME) + fprintf(*finishfile,"%s %s\n",t->Tname,t->Tnewname); + else + fprintf (*finishfile,"%s\n",t->Tname); return (SCMOK); } diff --git a/usr.sbin/sup/sup/supcparse.c b/usr.sbin/sup/sup/supcparse.c index 1b55f1ead66c..82aefd9038a8 100644 --- a/usr.sbin/sup/sup/supcparse.c +++ b/usr.sbin/sup/sup/supcparse.c @@ -32,6 +32,11 @@ * across the network to save BandWidth * * $Log: supcparse.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:46 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.2 1994/08/11 02:46:25 rich * Added extensions written by David Dawes. From the man page: * @@ -82,11 +87,13 @@ static char _argbreak; extern char _argbreak; /* break character from nxtarg */ #endif +char default_renamelog[] = RENAMELOG; + typedef enum { /* supfile options */ OHOST, OBASE, OHOSTBASE, OPREFIX, ORELEASE, - ONOTIFY, OLOGIN, OPASSWORD, OCRYPT, + ONOTIFY, OLOGIN, OPASSWORD, OCRYPT, ORENAMELOG, OBACKUP, ODELETE, OEXECUTE, OOLD, OTIMEOUT, OKEEP, OURELSUF, - OCOMPRESS, ONOUPDATE + OCOMPRESS, ONOUPDATE, OUNLINKBUSY } OPTION; struct option { @@ -102,6 +109,7 @@ struct option { "login", OLOGIN, "password", OPASSWORD, "crypt", OCRYPT, + "renamelog", ORENAMELOG, "backup", OBACKUP, "delete", ODELETE, "execute", OEXECUTE, @@ -110,7 +118,8 @@ struct option { "keep", OKEEP, "use-rel-suffix", OURELSUF, "compress", OCOMPRESS, - "noupdate", ONOUPDATE + "noupdate", ONOUPDATE, + "unlinkbusy", OUNLINKBUSY, }; passdelim (ptr,delim) /* skip over delimiter */ @@ -143,6 +152,7 @@ char *collname,*args; c->Clogin = NULL; c->Cpswd = NULL; c->Ccrypt = NULL; + c->Crenamelog = default_renamelog; c->Ctimeout = 3*60*60; /* default to 3 hours instead of no timeout */ c->Cflags = 0; c->Cnogood = FALSE; @@ -209,6 +219,11 @@ char *collname,*args; arg = nxtarg (&args," \t"); c->Ccrypt = salloc (arg); break; + case ORENAMELOG: + passdelim (&args,'='); + arg = nxtarg (&args," \t"); + c->Crenamelog= salloc (arg); + break; case OBACKUP: c->Cflags |= CFBACKUP; break; @@ -233,6 +248,9 @@ char *collname,*args; case ONOUPDATE: c->Cflags |= CFNOUPDATE; break; + case OUNLINKBUSY: + c->Cflags |= CFUNLINKBUSY; + break; case OTIMEOUT: passdelim (&args,'='); arg = nxtarg (&args," \t"); diff --git a/usr.sbin/sup/supfilesrv/supfilesrv.c b/usr.sbin/sup/supfilesrv/supfilesrv.c index dd4dbffc718e..ee345a6c016f 100644 --- a/usr.sbin/sup/supfilesrv/supfilesrv.c +++ b/usr.sbin/sup/supfilesrv/supfilesrv.c @@ -25,10 +25,11 @@ /* * supfilesrv -- SUP File Server * - * Usage: supfilesrv [-l] [-P] [-N] + * Usage: supfilesrv [-l] [-P] [-N] [-R] * -l "live" -- don't fork daemon * -P "debug ports" -- use debugging network ports * -N "debug network" -- print debugging messages for network i/o + * -R "RCS mode" -- if file is an rcs file, use co to get contents * ********************************************************************** * HISTORY @@ -41,6 +42,11 @@ * across the network to save BandWidth * * $Log: supfilesrv.c,v $ + * Revision 1.1.1.1 1995/12/26 04:54:48 peter + * Import the unmodified version of the sup that we are using. + * The heritage of this version is not clear. It appears to be NetBSD + * derived from some time ago. + * * Revision 1.4 1994/08/11 02:46:26 rich * Added extensions written by David Dawes. From the man page: * @@ -280,6 +286,7 @@ long time (); uid_t getuid (); int maxchildren; +int maxfriends = -1; /* * These are used to save the stat information from the crosspatch crypt @@ -327,18 +334,27 @@ int live; /* -l flag */ int dbgportsq; /* -P flag */ extern int scmdebug; /* -N flag */ extern int netfile; +#ifdef RCS +int candorcs; /* -R flag */ +int dorcs = FALSE; +#endif char *clienthost; /* host name of client */ +int friend; /* The client is a friend of us */ int nchildren; /* number of children that exist */ char *prefix; /* collection pathname prefix */ char *release; /* collection release name */ char *cryptkey; /* encryption key if non-null */ +#ifdef CVS +char *cvs_root; /* RCS root */ +#endif +char *rcs_branch; /* RCS branch name */ int lockfd; /* descriptor of lock file */ /* global variables for scan functions */ int trace = FALSE; /* directory scan trace */ -int cancompress=FALSE; /* Can we compress files */ -int docompress=FALSE; /* Do we compress files */ +int cancompress = FALSE; /* Can we compress files */ +int docompress = FALSE; /* Do we compress files */ HASH *uidH[HASHSIZE]; /* for uid and gid lookup */ HASH *gidH[HASHSIZE]; @@ -350,7 +366,7 @@ char *fmttime (); /* time format routine */ * PROTOTYPES */ #if __STDC__ -void goaway __P((char *,...)); +void goaway __P((char *,...)); #endif #ifdef LOG_PID_PATHNAME @@ -442,13 +458,20 @@ char **argv; /* * Child status signal handler */ - void chldsig() { +#if defined(__hpux) || defined(__FreeBSD__) int w; +#else + union wait w; +#endif +#ifdef __hpux + while (wait3(&w, WNOHANG, (int *)0) > 0) { +#else while (wait3(&w, WNOHANG, (struct rusage *)0) > 0) { +#endif if (nchildren) nchildren--; } } @@ -474,6 +497,9 @@ char **argv; int maxsleep; register FILE *f; +#ifdef RCS + candorcs = FALSE; +#endif live = FALSE; dbgportsq = FALSE; scmdebug = 0; @@ -500,6 +526,12 @@ char **argv; argv++; maxchildren = atoi(argv[0]); break; + case 'F': + if (--argc < 1) + quit (1,"Missing arg to -F\n"); + argv++; + maxfriends = atoi(argv[0]); + break; case 'H': if (--argc < 3) quit (1,"Missing args to -H\n"); @@ -510,6 +542,11 @@ char **argv; argc -= 2; argv += 2; break; +#ifdef RCS + case 'R': + candorcs = TRUE; + break; +#endif default: fprintf (stderr,"Unknown flag %s ignored\n",argv[0]); break; @@ -517,6 +554,11 @@ char **argv; --argc; argv++; } + if (maxfriends == -1) + maxfriends = 2*maxchildren; + else + maxfriends += maxchildren; /* due to the way we check */ + if (clienthost == NULL) { if (argc != 0) usage (); @@ -621,6 +663,10 @@ answer () basedir = NULL; prefix = NULL; release = NULL; + rcs_branch = NULL; +#ifdef CVS + cvs_root = NULL; +#endif goawayreason = NULL; donereason = NULL; lockfd = -1; @@ -642,7 +688,11 @@ answer () (void) dup2 (netfile,0); (void) dup2 (netfile,1); (void) dup2 (netfile,2); +#ifdef __hpux + fd = 256; +#else fd = getdtablesize (); +#endif while (--fd > 2) (void) close (fd); execv (xargv[0],xargv); @@ -656,6 +706,10 @@ answer () if (basedir) free (basedir); if (prefix) free (prefix); if (release) free (release); + if (rcs_branch) free (rcs_branch); +#ifdef CVS + if (cvs_root) free (cvs_root); +#endif if (goawayreason) { if (donereason == goawayreason) donereason = NULL; @@ -778,6 +832,15 @@ setup () goaway ("Error sending setup reply to client"); return; } +#ifdef RCS + if (candorcs && release != NULL && + (strncmp(release, "RCS.", 4) == 0)) { + rcs_branch = salloc(&release[4]); + free(release); + release = salloc("RCS"); + dorcs = TRUE; + } +#endif if (release == NULL) release = salloc (DEFRELEASE); if (basedir == NULL || *basedir == '\0') { @@ -824,7 +887,7 @@ setup () if (prefix) (void) chdir (basedir); if (x < 0) goaway ("Can't stat base/prefix directory"); - if (nchildren >= maxchildren) { + if (nchildren >= maxfriends) { setupack = FSETUPBUSY; (void) msgsetupack (); if (protver >= 6) longjmp (sjbuf,TRUE); @@ -861,7 +924,16 @@ setup () q = nxtarg (&p," \t"); if ((not = (*q == '!')) && *++q == '\0') q = nxtarg (&p," \t"); - hostok = (not == (matchhost(q) == 0)); + if ((friend = (*q == '+')) && *++q == '\0') + q = nxtarg (&p," \t"); + hostok = matchhost(q); + if (hostok && not) { + setupack = FSETUPHOST; + (void) msgsetupack (); + if (protver >= 6) longjmp (sjbuf,TRUE); + goaway ("Host blacklisted for %s", + collname); + } if (hostok) { while ((*p == ' ') || (*p == '\t')) p++; if (*p) cryptkey = salloc (p); @@ -878,6 +950,12 @@ setup () } } } + if (!friend && nchildren >= maxchildren) { + setupack = FSETUPBUSY; + (void) msgsetupack (); + if (protver >= 6) longjmp (sjbuf,TRUE); + goaway ("Sup client told to try again later"); + } /* try to lock collection */ (void) sprintf (buf,FILELOCK,collname); x = open (buf,O_RDONLY,0); @@ -1111,6 +1189,17 @@ sendfiles () /* send all files */ for (tl = listTL; tl != NULL; tl = tl->TLnext) { cdprefix (tl->TLprefix); +#ifdef CVS + if (candorcs) { + cvs_root = getcwd(NULL, 256); + if (access("CVSROOT", F_OK) < 0) + dorcs = FALSE; + else { + loginfo("is a CVSROOT \"%s\"\n", cvs_root); + dorcs = TRUE; + } + } +#endif (void) Tprocess (tl->TLtree,sendone); } /* send directories in reverse order */ @@ -1132,7 +1221,8 @@ TREE *t; { register int x,fd; register int fdtmp; - char sys_com[STRINGLENGTH], temp_file[STRINGLENGTH]; + char sys_com[STRINGLENGTH], temp_file[STRINGLENGTH], rcs_file[STRINGLENGTH]; + union wait status; char *uconvert(),*gconvert(); int sendfile (); @@ -1146,20 +1236,74 @@ TREE *t; fd = -1; /* no open file */ if ((t->Tmode&S_IFMT) == S_IFREG) { if (!listonly && (t->Tflags&FUPDATE) == 0) { - if (docompress) { - tmpnam(temp_file); - sprintf(sys_com, "gzip -c < %s > %s\n", t->Tname, temp_file); - if (system(sys_com) < 0) { - /* Just in case */ - unlink(temp_file); - goaway ("We died trying to compress"); - t->Tmode = 0; - } - fd = open (temp_file,O_RDONLY,0); - } - else - fd = open (t->Tname,O_RDONLY,0); - if (fd < 0) t->Tmode = 0; +#ifdef RCS + if (dorcs) { + char rcs_release[STRINGLENGTH]; + + tmpnam(rcs_file); + if (strcmp(&t->Tname[strlen(t->Tname)-2], ",v") == 0) { + t->Tname[strlen(t->Tname)-2] = '\0'; + if (rcs_branch != NULL) +#ifdef CVS + sprintf(rcs_release, "-r %s", rcs_branch); +#else + sprintf(rcs_release, "-r%s", rcs_branch); +#endif + else + rcs_release[0] = '\0'; +#ifdef CVS + sprintf(sys_com, "cvs -d %s -r -l -Q co -p %s %s > %s\n", cvs_root, rcs_release, t->Tname, rcs_file); +#else + sprintf(sys_com, "co -q -p %s %s > %s 2> /dev/null\n", rcs_release, t->Tname, rcs_file); +#endif + /*loginfo("using rcs mode \"%s\"\n", sys_com);*/ + status.w_status = system(sys_com); + if (status.w_status < 0 || status.w_retcode) { + /* Just in case */ + unlink(rcs_file); + if (status.w_status < 0) { + goaway ("We died trying to \"%s\"", sys_com); + t->Tmode = 0; + } + else { + /*logerr("rcs command failed \"%s\" = %d\n", + sys_com, status.w_retcode);*/ + t->Tflags |= FUPDATE; + } + } + else if (docompress) { + tmpnam(temp_file); + sprintf(sys_com, "/usr/local/bin/gzip -c < %s > %s\n", rcs_file, temp_file); + if (system(sys_com) < 0) { + /* Just in case */ + unlink(temp_file); + unlink(rcs_file); + goaway ("We died trying to \"%s\"", sys_com); + t->Tmode = 0; + } + fd = open (temp_file,O_RDONLY,0); + } + else + fd = open (rcs_file,O_RDONLY,0); + } + } +#endif + if (fd == -1) { + if (docompress) { + tmpnam(temp_file); + sprintf(sys_com, "gzip -c < %s > %s\n", t->Tname, temp_file); + if (system(sys_com) != 0) { + /* Just in case */ + unlink(temp_file); + goaway ("We died trying to \"%s\"", sys_com); + t->Tmode = 0; + } + fd = open (temp_file,O_RDONLY,0); + } + else + fd = open (t->Tname,O_RDONLY,0); + } + if (fd < 0 && (t->Tflags&FUPDATE) == 0) t->Tmode = 0; } if (t->Tmode) { t->Tuser = salloc (uconvert (t->Tuid)); @@ -1169,6 +1313,10 @@ TREE *t; x = msgrecv (sendfile,fd); if (docompress) unlink(temp_file); +#ifdef RCS + if (dorcs) + unlink(rcs_file); +#endif if (x != SCMOK) goaway ("Error sending file to client"); return (SCMOK); }