xref: /csrg-svn/old/berknet/sub.c (revision 8207)
1*8207Smckusick static char sccsid[] = "@(#)sub.c	4.1	(Berkeley)	09/12/82";
2*8207Smckusick 
3*8207Smckusick /*
4*8207Smckusick 	sub.c
5*8207Smckusick 
6*8207Smckusick 	support procedures
7*8207Smckusick 
8*8207Smckusick 	the following procedures end up reading the passwd file
9*8207Smckusick 	or the passwdf file and are to be avoided.
10*8207Smckusick 
11*8207Smckusick 	getpwuid(uid)
12*8207Smckusick 	getpwnam(sn)
13*8207Smckusick 	PwdCurrent()
14*8207Smckusick 	getenv("HOME")		maybe if hget, hgethome don't work
15*8207Smckusick 	SnFromUid(uid)		maybe if hashed passwd stuff doesn't work
16*8207Smckusick 	SnCurrent()		maybe if getlogin fails calls SnFromUid(uid)
17*8207Smckusick 	getpwf()
18*8207Smckusick 	passwdent(uid,sn)
19*8207Smckusick */
20*8207Smckusick 
21*8207Smckusick # include "defs.h"
22*8207Smckusick # include "config.h"
23*8207Smckusick # ifndef V6
24*8207Smckusick # include <varargs.h>
25*8207Smckusick # endif V6
26*8207Smckusick 
27*8207Smckusick /* global variables */
28*8207Smckusick int debugflg = DBV;	/* debug flag */
29*8207Smckusick char local = LOCAL;	/* the machine we're on */
30*8207Smckusick struct userinfo status;
31*8207Smckusick 
32*8207Smckusick char netcmd[]  =	NETCMD;
33*8207Smckusick char resfile[] = 	RESFILE;
34*8207Smckusick char senddir[] =	SENDDIR;
35*8207Smckusick char Bsh[] =		BINSH;
36*8207Smckusick 
37*8207Smckusick char shomedir[100];
38*8207Smckusick 
39*8207Smckusick /*
40*8207Smckusick 	passwdent()
41*8207Smckusick 
42*8207Smckusick 	Read the password file looking for current user's entry.
43*8207Smckusick 	Fill in the status structure.
44*8207Smckusick 	Has the (dangerous) side effect of giving a value to getenv("HOME").
45*8207Smckusick */
46*8207Smckusick passwdent()
47*8207Smckusick {
48*8207Smckusick 	register char *u;
49*8207Smckusick 	register struct passwd *pwd;
50*8207Smckusick #ifdef CRN
51*8207Smckusick 	register struct gecos *gcos;
52*8207Smckusick #endif
53*8207Smckusick 	pwd = PwdCurrent();
54*8207Smckusick 	if(pwd == NULL){
55*8207Smckusick 		err("Bad uid/username\n");
56*8207Smckusick 		return;
57*8207Smckusick 	}
58*8207Smckusick 	strcpy(status.localname,pwd->pw_name);
59*8207Smckusick 	status.muid = guid(pwd->pw_uid,pwd->pw_gid);
60*8207Smckusick 	status.mgid = pwd->pw_gid;
61*8207Smckusick #ifdef CRN
62*8207Smckusick 	if( (gcos=pwgecos( pwd->pw_gecos) ) == NULL )
63*8207Smckusick 		strcpy( status.jobno, MAGICCRN );
64*8207Smckusick 	else {
65*8207Smckusick 		if( debugflg )
66*8207Smckusick 			debug( "crn found = %s\n", gcos->gc_crn );
67*8207Smckusick 		if( isalpha( gcos->gc_crn[0] ) ||
68*8207Smckusick 			isdigit( gcos->gc_crn[0] ) )
69*8207Smckusick 			strcpy( status.jobno, gcos->gc_crn );
70*8207Smckusick 		else
71*8207Smckusick 			strcpy( status.jobno, MAGICCRN );
72*8207Smckusick 	}
73*8207Smckusick #else
74*8207Smckusick 	strcpy( status.jobno, "XYZZ" );
75*8207Smckusick #endif
76*8207Smckusick 	strcpy(status.dir,pwd->pw_dir);
77*8207Smckusick 	strcpy(shomedir,pwd->pw_dir);		/* side effect */
78*8207Smckusick 	u = pwd->pw_shell;
79*8207Smckusick 	if(u[0] == 0 || strcmp(u,"/bin/sbash") == 0)u= Bsh;
80*8207Smckusick 	strcpy(status.loginshell,u);
81*8207Smckusick 	}
82*8207Smckusick /*
83*8207Smckusick 	promptlogin(mchto)
84*8207Smckusick 
85*8207Smckusick 	ask user for login and passwd on mchto.
86*8207Smckusick 	make sure status.localname has a value before calling
87*8207Smckusick 	this.  One way is to call passwdent().
88*8207Smckusick */
89*8207Smckusick promptlogin(mchto)
90*8207Smckusick 	char mchto;
91*8207Smckusick {
92*8207Smckusick 	char buf[BUFSIZ], mch;
93*8207Smckusick 	FILE *wf;
94*8207Smckusick 	int c;
95*8207Smckusick 	if(status.mpasswd[0] == 0 || status.login[0] == 0 || status.force){
96*8207Smckusick 		wf = fopen("/dev/tty","r");
97*8207Smckusick 		if(wf != NULL){
98*8207Smckusick 			if(status.login[0]==0 || status.force){
99*8207Smckusick 				fprintf(stderr,"Name (%s:%s): ",longname(mchto),
100*8207Smckusick 					status.localname);
101*8207Smckusick 				if(fgets(buf, BUFSIZ, wf) != buf){
102*8207Smckusick 					perror("fgets");
103*8207Smckusick 					exit(EX_OSERR);
104*8207Smckusick 					}
105*8207Smckusick 				c = strlen(buf);
106*8207Smckusick 				buf[c > 0 ? c-1 : 0] = 0;
107*8207Smckusick 				if(c > 10){
108*8207Smckusick 					err("Login name too long.\n");
109*8207Smckusick 					exit(EX_USAGE);
110*8207Smckusick 					}
111*8207Smckusick 				if(FMemberSCh(buf,' ')){
112*8207Smckusick 					err("Login names don't have blanks in them.\n");
113*8207Smckusick 					exit(EX_USAGE);
114*8207Smckusick 					}
115*8207Smckusick 				if(buf[0] == 0)strcpy(buf,status.localname);
116*8207Smckusick 				mch = MchSFromAddr(status.login,buf);
117*8207Smckusick 				if(mch != local && mch != mchto){
118*8207Smckusick 					err(
119*8207Smckusick 				"Must specify login name on %s machine\n",
120*8207Smckusick 						longname(mchto));
121*8207Smckusick 					exit(EX_USAGE);
122*8207Smckusick 				}
123*8207Smckusick 			}
124*8207Smckusick 			if(strcmp(status.login,"network") != 0
125*8207Smckusick 				&& (status.mpasswd[0]== 0 || status.force)){
126*8207Smckusick 				sprintf(buf,"Password (%s:%s):",
127*8207Smckusick 					longname(mchto), status.login);
128*8207Smckusick 				strcpy(status.mpasswd,getpass(buf));
129*8207Smckusick 				}
130*8207Smckusick 			fclose(wf);
131*8207Smckusick 			}
132*8207Smckusick 		}
133*8207Smckusick 	if(status.login[0] == 0) strcpy(status.login,status.localname);
134*8207Smckusick 	if(status.mpasswd[0] == 0)strcpy(status.mpasswd,"\"\"");
135*8207Smckusick 	status.force = 0;
136*8207Smckusick 	}
137*8207Smckusick 
138*8207Smckusick #define	tst(a,b)	(*mode == 'r'? (b) : (a))
139*8207Smckusick #define	RDR	0
140*8207Smckusick #define	WTR	1
141*8207Smckusick static	int	popen_pid[20];
142*8207Smckusick 
143*8207Smckusick /* return a file descriptor suitable for writing, send to
144*8207Smckusick   user toaddress from fromaddress,
145*8207Smckusick   if cautious != 0 then don't do any forwarding
146*8207Smckusick   hopcnt is passed thru the mail program.
147*8207Smckusick 	  normal value is 0
148*8207Smckusick   */
149*8207Smckusick FILE *
150*8207Smckusick mailopen(toaddress, fromaddress, cautious, hopcnt)
151*8207Smckusick char *toaddress, *fromaddress;
152*8207Smckusick int cautious, hopcnt;
153*8207Smckusick {
154*8207Smckusick 	char	cmd[100];
155*8207Smckusick 	char	*mode = "w";
156*8207Smckusick 	int p[2];
157*8207Smckusick 	register myside, hisside, pid;
158*8207Smckusick 	char shopcnt[20];
159*8207Smckusick 
160*8207Smckusick 	if(pipe(p) < 0)
161*8207Smckusick 		return NULL;
162*8207Smckusick 	myside = tst(p[WTR], p[RDR]);
163*8207Smckusick 	hisside = tst(p[RDR], p[WTR]);
164*8207Smckusick 	while((pid = fork()) == -1)sleep(2);
165*8207Smckusick 	if(pid == 0) {
166*8207Smckusick 		/* myside and hisside reverse roles in child */
167*8207Smckusick 		close(myside);
168*8207Smckusick 		/*
169*8207Smckusick 		dup2(hisside, tst(0, 1));
170*8207Smckusick 		*/
171*8207Smckusick 		close(0);
172*8207Smckusick 		dup(hisside);
173*8207Smckusick 		close(hisside);
174*8207Smckusick 		sprintf(shopcnt,"%d",hopcnt);
175*8207Smckusick 		if(fromaddress != NULL){
176*8207Smckusick 			/* by convention, MAILFWD1 may forward this mail
177*8207Smckusick 			   and response messages shouldn't be forwarded */
178*8207Smckusick 			if(!cautious && !FMemberSCh(toaddress,'/')){
179*8207Smckusick # ifdef DELIVERM
180*8207Smckusick 				mexecl("/etc/delivermail",
181*8207Smckusick 					"delivermail", "-ee", "-r", fromaddress,
182*8207Smckusick 					"-h",shopcnt, toaddress, 0);
183*8207Smckusick # endif
184*8207Smckusick 				mexecl(MAILFWD1, "mail","-r",fromaddress,
185*8207Smckusick 					"-h",shopcnt,toaddress,0);
186*8207Smckusick 			}
187*8207Smckusick 			mexecl(SYSMAIL2, "mail","-d","-r",fromaddress,
188*8207Smckusick 				"-h", shopcnt,toaddress,0);
189*8207Smckusick 		} else {
190*8207Smckusick 			if(!cautious && !FMemberSCh(toaddress,'/')){
191*8207Smckusick # ifdef DELIVERM
192*8207Smckusick 				mexecl("/etc/delivermail",
193*8207Smckusick 					"delivermail", "-ee", "-h", shopcnt,
194*8207Smckusick 					toaddress, 0);
195*8207Smckusick # endif
196*8207Smckusick 				mexecl(MAILFWD1, "mail","-h", shopcnt,
197*8207Smckusick 					toaddress,0);
198*8207Smckusick 			}
199*8207Smckusick 			mexecl(SYSMAIL2, "mail","-d","-h", shopcnt,toaddress,0);
200*8207Smckusick 		}
201*8207Smckusick 		perror(SYSMAIL2);
202*8207Smckusick 		exit(EX_UNAVAILABLE);
203*8207Smckusick 	}
204*8207Smckusick 	if(pid == -1)
205*8207Smckusick 		return NULL;
206*8207Smckusick 	popen_pid[myside] = pid;
207*8207Smckusick 	close(hisside);
208*8207Smckusick 	return(fdopen(myside, mode));
209*8207Smckusick }
210*8207Smckusick 
211*8207Smckusick mailclose(ptr)
212*8207Smckusick FILE *ptr;
213*8207Smckusick {
214*8207Smckusick 	register f, r, (*hstat)(), (*istat)(), (*qstat)();
215*8207Smckusick 	int status;
216*8207Smckusick 
217*8207Smckusick 	f = fileno(ptr);
218*8207Smckusick 	fclose(ptr);
219*8207Smckusick 	istat = signal(SIGINT, SIG_IGN);
220*8207Smckusick 	qstat = signal(SIGQUIT, SIG_IGN);
221*8207Smckusick 	hstat = signal(SIGHUP, SIG_IGN);
222*8207Smckusick 	while((r = wait(&status)) != popen_pid[f] && r != -1)
223*8207Smckusick 		;
224*8207Smckusick 	if(r == -1)
225*8207Smckusick 		status = -1;
226*8207Smckusick 	signal(SIGINT, istat);
227*8207Smckusick 	signal(SIGQUIT, qstat);
228*8207Smckusick 	signal(SIGHUP, hstat);
229*8207Smckusick 	return(status);
230*8207Smckusick }
231*8207Smckusick 
232*8207Smckusick /*
233*8207Smckusick 	ch means 'a'-'z', inx in 0..25
234*8207Smckusick 	ch means '0'-'9', inx in 26..35
235*8207Smckusick */
236*8207Smckusick chtoinx(ch) {
237*8207Smckusick 	if('a' <= ch && ch <= 'z')
238*8207Smckusick 		return(ch - 'a');
239*8207Smckusick 	if('0' <= ch && ch <= '9')
240*8207Smckusick 		return((ch - '0') + 26);
241*8207Smckusick 	err("bad ch");
242*8207Smckusick }
243*8207Smckusick 
244*8207Smckusick /*
245*8207Smckusick 	inx is 0..25 means 'a'-'z'
246*8207Smckusick 	inx is 26..35 means '0'-'9'
247*8207Smckusick */
248*8207Smckusick inxtoch(inx) {
249*8207Smckusick 	if(0 <= inx && inx <= 25)
250*8207Smckusick 		return(inx + 'a');
251*8207Smckusick 	if(26 <= inx && inx <= 35)
252*8207Smckusick 		return('0' + (inx - 26));
253*8207Smckusick 	err("bad ch");
254*8207Smckusick }
255*8207Smckusick 
256*8207Smckusick /* determine through machine */
257*8207Smckusick gothru(from,to){
258*8207Smckusick 	register int i;
259*8207Smckusick 	switch(from){
260*8207Smckusick # ifdef RAND
261*8207Smckusick 	case 'a':	i = configA[chtoinx(to)]; break;
262*8207Smckusick 	case 'b':	i = configB[chtoinx(to)]; break;
263*8207Smckusick 	case 'c':	i = configC[chtoinx(to)]; break;
264*8207Smckusick # endif
265*8207Smckusick # ifdef NOSC
266*8207Smckusick 	case 'a':	i = configA[chtoinx(to)]; break;
267*8207Smckusick 	case 'c':	i = configC[chtoinx(to)]; break;
268*8207Smckusick 	case 'm':	i = configM[chtoinx(to)]; break;
269*8207Smckusick # endif
270*8207Smckusick # ifdef BERKELEY
271*8207Smckusick 	/* for Berkeley */
272*8207Smckusick 	case 'a':	i = configA[chtoinx(to)]; break;
273*8207Smckusick 	case 'b':	i = configB[chtoinx(to)]; break;
274*8207Smckusick 	case 'c':	i = configC[chtoinx(to)]; break;
275*8207Smckusick 	case 'd':	i = configD[chtoinx(to)]; break;
276*8207Smckusick 	case 'e':	i = configE[chtoinx(to)]; break;
277*8207Smckusick 	case 'f':	i = configF[chtoinx(to)]; break;
278*8207Smckusick 	case 'g':	i = configG[chtoinx(to)]; break;
279*8207Smckusick 	case 'i':	i = configI[chtoinx(to)]; break;
280*8207Smckusick 	case 'j':	i = configJ[chtoinx(to)]; break;
281*8207Smckusick 	case 'k':	i = configK[chtoinx(to)]; break;
282*8207Smckusick 	case 'l':	i = configL[chtoinx(to)]; break;
283*8207Smckusick 	case 'm':	i = configM[chtoinx(to)]; break;
284*8207Smckusick 	case 'n':	i = configN[chtoinx(to)]; break;
285*8207Smckusick 	case 'o':	i = configO[chtoinx(to)]; break;
286*8207Smckusick 	case 'p':	i = configP[chtoinx(to)]; break;
287*8207Smckusick 	case 'q':	i = configQ[chtoinx(to)]; break;
288*8207Smckusick 	case 'r':	i = configR[chtoinx(to)]; break;
289*8207Smckusick 	case 's':	i = configS[chtoinx(to)]; break;
290*8207Smckusick 	case 't':	i = configT[chtoinx(to)]; break;
291*8207Smckusick 	case 'v':	i = configV[chtoinx(to)]; break;
292*8207Smckusick 	case 'x':	i = configX[chtoinx(to)]; break;
293*8207Smckusick 	case 'y':	i = configY[chtoinx(to)]; break;
294*8207Smckusick 	case 'z':	i = configZ[chtoinx(to)]; break;
295*8207Smckusick # endif
296*8207Smckusick 	default:	i = 0; break;
297*8207Smckusick 	}
298*8207Smckusick 	return(i);
299*8207Smckusick 	}
300*8207Smckusick 
301*8207Smckusick # define NPARMS 20
302*8207Smckusick /* prints out commands before executing them */
303*8207Smckusick /*VARARGS0*/
304*8207Smckusick mexecl(va_alist)
305*8207Smckusick   	va_dcl
306*8207Smckusick {
307*8207Smckusick 	char *arr[NPARMS], *file, *f;
308*8207Smckusick 	va_list ap;
309*8207Smckusick 	register int i;
310*8207Smckusick 	va_start(ap);
311*8207Smckusick 	file = va_arg(ap, char *);
312*8207Smckusick 	i = 0;
313*8207Smckusick 	while(f = va_arg(ap, char *)){
314*8207Smckusick 		if(i >= NPARMS){
315*8207Smckusick 			err("too many args");
316*8207Smckusick 			arr[NPARMS-1] = NULL;
317*8207Smckusick 			break;
318*8207Smckusick 			}
319*8207Smckusick 		if(debugflg) err("'%s' ",f);
320*8207Smckusick 		arr[i++] = f;
321*8207Smckusick 		}
322*8207Smckusick 	arr[i] = NULL;
323*8207Smckusick 	va_end(ap);
324*8207Smckusick 	if(debugflg) putc('\n',stderr);
325*8207Smckusick 	execv(file, arr);
326*8207Smckusick 	}
327*8207Smckusick 
328*8207Smckusick /* prints out commands before executing them */
329*8207Smckusick mexecv(s,p)
330*8207Smckusick   register char *s, **p;{
331*8207Smckusick 	register int i;
332*8207Smckusick 	if(debugflg){
333*8207Smckusick 		err("'%s' ",s);
334*8207Smckusick 		for(i=0; p[i]; i++)err("'%s' ",p[i]);
335*8207Smckusick 		putc('\n',stderr);
336*8207Smckusick 		}
337*8207Smckusick 	execv(s,p);
338*8207Smckusick 	}
339*8207Smckusick 
340*8207Smckusick /*VARARGS0*/
341*8207Smckusick /* fills in -l - -p from commands like rcp */
342*8207Smckusick /* must be called with at least two arguments */
343*8207Smckusick kexecl(va_alist)
344*8207Smckusick   va_dcl
345*8207Smckusick {
346*8207Smckusick 	char *a[NPARMS], i = 1, *file;
347*8207Smckusick 	va_list ap;
348*8207Smckusick 	va_start(ap);
349*8207Smckusick 	file = va_arg(ap, char *);
350*8207Smckusick 	a[0] = va_arg(ap, char *);
351*8207Smckusick 	if(status.login[0]){
352*8207Smckusick 		a[i++] = "-l";
353*8207Smckusick 		a[i++] = status.login;
354*8207Smckusick 		}
355*8207Smckusick 	if(status.mpasswd[0]){
356*8207Smckusick 		a[i++] = "-p";
357*8207Smckusick 		a[i++] = status.mpasswd;
358*8207Smckusick 		}
359*8207Smckusick 	if(status.nonotify)a[i++] = "-b";
360*8207Smckusick 	if(status.force)   a[i++] = "-f";
361*8207Smckusick 	if(status.quiet)   a[i++] = "-q";
362*8207Smckusick 	if(status.nowrite) a[i++] = "-n";
363*8207Smckusick 	while (a[i++] = va_arg(ap, char *)){
364*8207Smckusick 		if(i >= NPARMS){
365*8207Smckusick 			err("too many args");
366*8207Smckusick 			a[NPARMS-1] = NULL;
367*8207Smckusick 			break;
368*8207Smckusick 			}
369*8207Smckusick 		};
370*8207Smckusick 	mexecv(file, a);
371*8207Smckusick 	}
372*8207Smckusick 
373*8207Smckusick /*
374*8207Smckusick 	MchSFromAddr(sn,addr)
375*8207Smckusick 
376*8207Smckusick 	take an address of the form "mach:username"
377*8207Smckusick 	and return mch as the 1 char code of "mach" and
378*8207Smckusick 	in sn put "username".
379*8207Smckusick 	If addr has no colon in it, return mch==local, sn==addr.
380*8207Smckusick 	Return 0 for mch if host unknown.
381*8207Smckusick */
382*8207Smckusick MchSFromAddr(sn,addr)
383*8207Smckusick 	char *sn, *addr;
384*8207Smckusick {
385*8207Smckusick 	char fcolon = 0, *s, mch, stemp[BUFSIZ];
386*8207Smckusick 
387*8207Smckusick 	/* assume addr is a local address */
388*8207Smckusick 
389*8207Smckusick 	strcpy(stemp,addr);
390*8207Smckusick 	s = stemp;
391*8207Smckusick 	while(*s){
392*8207Smckusick 		if(*s == ':'){
393*8207Smckusick 			fcolon = 1;
394*8207Smckusick 			*s++ = 0;
395*8207Smckusick 			break;
396*8207Smckusick 		}
397*8207Smckusick 		s++;
398*8207Smckusick 	}
399*8207Smckusick 	if(fcolon != 1){
400*8207Smckusick 		/* sn better be the right size for addr */
401*8207Smckusick 		mch = local;
402*8207Smckusick 		strcpy(sn,addr);
403*8207Smckusick 		return(mch);
404*8207Smckusick 	}
405*8207Smckusick 
406*8207Smckusick 	/* addr has a colon in it, s pts to name */
407*8207Smckusick 	mch = lookup(stemp);
408*8207Smckusick 	strcpy(sn,s);
409*8207Smckusick 	return(mch);
410*8207Smckusick }
411*8207Smckusick 
412*8207Smckusick 
413*8207Smckusick /* returns a single character for machine S */
414*8207Smckusick /* returns 0 for unknown host */
415*8207Smckusick lookup(s)
416*8207Smckusick   register char *s; {
417*8207Smckusick 	register struct tt *t;
418*8207Smckusick 	if(strlen(s) == 1)return(isupper(*s) ? tolower(*s) : *s);
419*8207Smckusick 	for(t = table; t->bigname; t++)
420*8207Smckusick 		if(streql(s,t->bigname) == 0)return(t->lname);
421*8207Smckusick 	return(0);
422*8207Smckusick 	}
423*8207Smckusick 
424*8207Smckusick /* returns a long name (string) for single character machine c */
425*8207Smckusick char *longname(c)
426*8207Smckusick   register char c;
427*8207Smckusick 	{
428*8207Smckusick 	register struct tt *t;
429*8207Smckusick 	if(c == 0)return("UNKNOWN");
430*8207Smckusick 	for(t = table; t->bigname; t++)
431*8207Smckusick 		if(c == t->lname)return(t->bigname);
432*8207Smckusick 	return("UNKNOWN");
433*8207Smckusick 	}
434*8207Smckusick /*
435*8207Smckusick 	FMemberSCh(s,ch)
436*8207Smckusick 
437*8207Smckusick 	return 1 if ch is a character in string s.
438*8207Smckusick 	0 otherwise.
439*8207Smckusick */
440*8207Smckusick FMemberSCh(s,ch)
441*8207Smckusick 	register char *s, ch;
442*8207Smckusick {
443*8207Smckusick 	while(*s)if(*s++ == ch)return(1);
444*8207Smckusick 	return(0);
445*8207Smckusick }
446*8207Smckusick 
447*8207Smckusick /* return a static string with the form "X hrs X mins X secs" */
448*8207Smckusick /* t is # of secs */
449*8207Smckusick char *comptime(t)
450*8207Smckusick   long t; {
451*8207Smckusick 	static char str[30];
452*8207Smckusick 	char buf[20];
453*8207Smckusick 	long w;
454*8207Smckusick 	str[0] = 0;
455*8207Smckusick 	w = t/3600L;
456*8207Smckusick 	if(w > 0L){
457*8207Smckusick 		sprintf(buf,"%ld hr ",w);
458*8207Smckusick 		strcat(str,buf);
459*8207Smckusick 		}
460*8207Smckusick 	t = t % 3600L;
461*8207Smckusick 	w = t/60L;
462*8207Smckusick 	if(w > 0L){
463*8207Smckusick 		sprintf(buf,"%ld min ",w);
464*8207Smckusick 		strcat(str,buf);
465*8207Smckusick 		}
466*8207Smckusick 	t = t % 60L;
467*8207Smckusick 	sprintf(buf,"%ld sec",t);
468*8207Smckusick 	strcat(str,buf);
469*8207Smckusick 	return(str);
470*8207Smckusick 	}
471*8207Smckusick /*
472*8207Smckusick 	parseparmlist(string)
473*8207Smckusick 
474*8207Smckusick 	parses variable parameter lists in string,
475*8207Smckusick 	as defined in genparmlist in net.c
476*8207Smckusick */
477*8207Smckusick parseparmlist(parmlist)
478*8207Smckusick 	char *parmlist;
479*8207Smckusick {
480*8207Smckusick 	while(*parmlist && *parmlist != '(')parmlist++;
481*8207Smckusick }
482*8207Smckusick 
483*8207Smckusick /* just like strcmp except upper- and lower-case are ignored */
484*8207Smckusick streql(s1,s2)
485*8207Smckusick   char *s1, *s2; {
486*8207Smckusick 	char a,b;
487*8207Smckusick 	while(*s1 && *s2){
488*8207Smckusick 		a = isupper(*s1) ? tolower(*s1) : *s1;
489*8207Smckusick 		b = isupper(*s2) ? tolower(*s2) : *s2;
490*8207Smckusick 		if(a < b)return(-1);
491*8207Smckusick 		if(a > b)return(1);
492*8207Smckusick 		s1++, s2++;
493*8207Smckusick 		}
494*8207Smckusick 	if(*s2)return(-1);
495*8207Smckusick 	if(*s1)return(1);
496*8207Smckusick 	return(0);
497*8207Smckusick 	}
498*8207Smckusick /* VARARGS0 */
499*8207Smckusick err(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) {
500*8207Smckusick 	fprintf(stderr,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r);
501*8207Smckusick 	}
502