xref: /csrg-svn/old/berknet/net.c (revision 8220)
1*8220Smckusick static char sccsid[] = "@(#)net.c	4.2	(Berkeley)	09/12/82";
28191Smckusick 
38191Smckusick /* sccs id variable */
48191Smckusick static char *net_sid = "@(#)net.c	1.8";
58191Smckusick 
68191Smckusick # include "defs.h"
78191Smckusick /* must be setuid root */
88191Smckusick /*
98191Smckusick 	net - -b -c cmd -f -i file -l name -mmach -n -o file -p passwd
108191Smckusick 		-r file -s file -u uid -w -x -y -z command
118191Smckusick 
128191Smckusick 	-	take from standard input
138191Smckusick 	-b	never send anything back
148191Smckusick 	-c cmd	think of this as a "cmd" *
158191Smckusick 	-f	force prompting of user name and password
168191Smckusick 	-i file	remote stdin *
178191Smckusick 	-l name remote login name
188191Smckusick 	-m Mach	remote machine
198191Smckusick 	-n	do not write back anything, always mail them back
208191Smckusick 	-o file	remote stdout & stderr *
218191Smckusick 	-p pass remote password
228191Smckusick 	-q 	quiet option, send back only if rcode !=0 or if there is stdout
238191Smckusick 	-r file	local response file
248191Smckusick 	-s file	local stdin file *
258191Smckusick 
268191Smckusick 	(super users only, always skip login/passwd check:)
278191Smckusick 	-u uid	net queue files should be owned by uid (16 bits)
288191Smckusick 	-w	this is a write/mail response cmd *
298191Smckusick 	-x	this is being forwarded through us to another machine *
308191Smckusick 	-y	skip login/password check *
318191Smckusick 	-z	this is a response file being returned *
328191Smckusick 
338191Smckusick 	* = not documented in net(NEW)
348191Smckusick 
358191Smckusick */
368191Smckusick /*
378191Smckusick 	code	option	reason
388191Smckusick 	q		normal request
398191Smckusick 	w	-w	message to be written back
408191Smckusick 	 	-x	being forwarded through us
418191Smckusick 	y	-y	simply skips login check (used by netlpr)
428191Smckusick 	s	-z	normal response
438191Smckusick */
448191Smckusick /* global variables */
458191Smckusick struct userinfo status;
468191Smckusick 
478191Smckusick /* local variables */
488191Smckusick static char dfname[]=		DFNAME;
498191Smckusick 
main(argc,argv)508191Smckusick main(argc, argv)
518191Smckusick   char **argv; {
528191Smckusick 	register int i;
538191Smckusick 	int outerror(),uid;
548191Smckusick 	char localin[FNS], skey[30];
558191Smckusick 	char buf[BUFSIZ], suid[10];
568191Smckusick 	char sin =0, zopt = 0, wopt = 0, yopt = 0, xopt = 0;
578191Smckusick 	char *s,**sargv;
588191Smckusick 	long cnt = 0L, maxfile = MAXFILELARGE;
598191Smckusick 	FILE *file, *temp, *rfile;
608191Smckusick 	struct utmp *putmp;
618191Smckusick 	struct stat statbuf;
628191Smckusick 	struct header hd;
638191Smckusick 
648191Smckusick 	debugflg = DBV;
658191Smckusick 	hd.hd_scmdact[0] = hd.hd_srespfile[0] = hd.hd_soutfile[0] = 0;
668191Smckusick 	hd.hd_sinfile[0] = hd.hd_scmdvirt[0] = hd.hd_sttyname[0] = 0;
678191Smckusick 	localin[0] = 0;
688191Smckusick 	suid[0] = 0;
698191Smckusick 	sargv = argv;
708191Smckusick 
718191Smckusick 	if(isatty(0)) strcat(hd.hd_sttyname,ttyname(0));
728191Smckusick 	else if(isatty(2)) strcat(hd.hd_sttyname,ttyname(2));
738191Smckusick 	remote = 0;
748191Smckusick 	if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
758191Smckusick 		signal(SIGHUP, outerror);
768191Smckusick 	if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
778191Smckusick 		signal(SIGQUIT, outerror);
788191Smckusick 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
798191Smckusick 		signal(SIGINT, outerror);
808191Smckusick 	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
818191Smckusick 		signal(SIGTERM, outerror);
828191Smckusick 
838191Smckusick 	while(argc > 1 && argv[1][0] == '-'){
848191Smckusick 		argc--; argv++;
858191Smckusick 		switch(argv[0][1]){
868191Smckusick 		case 0:
878191Smckusick 			sin++;
888191Smckusick 			break;
898191Smckusick 		case 'b':
908191Smckusick 			status.nonotify++;
918191Smckusick 			break;
928191Smckusick 		case 'c':
938191Smckusick 			harg(hd.hd_scmdvirt);
948191Smckusick 			break;
958191Smckusick 		case 'f':
968191Smckusick 			status.force++;
978191Smckusick 			break;
988191Smckusick 		case 'i':
998191Smckusick 			harg(hd.hd_sinfile);
1008191Smckusick 			break;
1018191Smckusick 		case 'l':
1028191Smckusick 			harg(status.login);
1038191Smckusick 			break;
1048191Smckusick 		case 'm':
1058191Smckusick 			harg(buf);
1068191Smckusick 			remote = lookup(buf);
1078191Smckusick 			if(remote == 0){
1088191Smckusick 				fprintf(stderr,"Unknown machine %s\n",buf);
1098191Smckusick 				exit(EX_NOHOST);
1108191Smckusick 			}
1118191Smckusick 			break;
1128191Smckusick 		case 'n':
1138191Smckusick 			status.nowrite++;
1148191Smckusick 			break;
1158191Smckusick 		case 'o':
1168191Smckusick 			harg(hd.hd_soutfile);
1178191Smckusick 			break;
1188191Smckusick 		case 'p':
1198191Smckusick 			harg(status.mpasswd);
1208191Smckusick 			if(status.mpasswd[0] == 0)
1218191Smckusick 			  	strcpy(status.mpasswd,"\n\n");
1228191Smckusick 			break;
1238191Smckusick 		case 'q':
1248191Smckusick 			status.quiet++;
1258191Smckusick 			break;
1268191Smckusick 		case 'r':
1278191Smckusick 			harg(buf);
1288191Smckusick 			addir(hd.hd_srespfile,buf);
1298191Smckusick 			break;
1308191Smckusick 		case 's':
1318191Smckusick 			harg(localin);
1328191Smckusick 			break;
1338191Smckusick 		case 'u':
1348191Smckusick 			harg(suid);
1358191Smckusick 			break;
1368191Smckusick 		case 'w':
1378191Smckusick 			wopt++;
1388191Smckusick 			break;
1398191Smckusick 		case 'x':
1408191Smckusick 			xopt++;
1418191Smckusick 			break;
1428191Smckusick 		case 'y':
1438191Smckusick 			yopt++;
1448191Smckusick 			break;
1458191Smckusick 		case 'z':
1468191Smckusick 			zopt++;
1478191Smckusick 			break;
1488191Smckusick 		default:
1498191Smckusick 			fprintf(stderr,"Unknown option %s\n",argv[0]);
1508191Smckusick 			break;
1518191Smckusick 		}
1528191Smckusick 		}
1538191Smckusick 	while(argc > 1){
1548191Smckusick 		argc--; argv++;
1558191Smckusick 		strcat(hd.hd_scmdact,argv[0]);
1568191Smckusick 		strcat(hd.hd_scmdact," ");
1578191Smckusick 		}
1588191Smckusick 	sargv[1] = 0;		/* so ps won't show passwd ??? */
1598191Smckusick 	hd.hd_uidfrom = uid = getuid();
1608191Smckusick 	hd.hd_gidfrom = getgid();
1618191Smckusick 	hd.hd_code = 'q';
1628191Smckusick 	if(zopt || wopt || yopt || xopt || suid[0] != 0){
1638191Smckusick 		/* check z or w or y or x option permission */
1648191Smckusick # ifndef TESTING
1658191Smckusick 		/* check effective user id ?? */
1668191Smckusick 		if (uid != SUPERUSER && uid != NUID) {
1678191Smckusick 			fprintf(stderr, "Error: Not super-user\n");
1688191Smckusick 			fprintf(stderr,"zopt %d wopt %d yopt %d xopt %d suid[0] %s\n", zopt, wopt, yopt, xopt, suid);
1698191Smckusick 			fprintf(stderr,"uid %d\n", uid);
1708191Smckusick 			debugflg = 1;
1718191Smckusick 			printhd(&hd);
1728191Smckusick 			outerror(EX_UNAVAILABLE);
1738191Smckusick 			}
1748191Smckusick # endif
1758191Smckusick 		hd.hd_code = zopt? 's': 'w';
1768191Smckusick 		hd.hd_code = yopt? 'y': hd.hd_code;
1778191Smckusick 		if (status.mpasswd[0] == 0)	/* no passwd required */
1788191Smckusick 			strcpy(status.mpasswd, "\n");
1798191Smckusick 		debug("zopt %d wopt %d yopt %d xopt %d suid[0] %s\n", zopt, wopt, yopt, xopt, suid);
1808191Smckusick 		debug("uid %d\n", uid);
1818191Smckusick 		if(xopt)
1828191Smckusick 			setuid(SUPERUSER);
1838191Smckusick 	}
1848191Smckusick #ifdef CRN
1858191Smckusick 	strcpy( status.jobno, MAGICCRN );	/* default (invalid) crn */
1868191Smckusick #else
1878191Smckusick 	strcpy( status.jobno, "XYZZ");		/* default (invalid) crn */
1888191Smckusick #endif
1898191Smckusick 
1908191Smckusick 	if(hd.hd_code == 'q' && !xopt){
1918191Smckusick 		/* read passwd file, get status.localname & crn */
1928191Smckusick 		passwdent();
1938191Smckusick 	}
1948191Smckusick 
1958191Smckusick 	/* sets remote,status.login,status.force,status.mpasswd,
1968191Smckusick 		status.nonotify, status.nowrite */
1978191Smckusick 	/* may read passwd file if getenv(HOME) reads it */
1988191Smckusick 	commandfile();
1998191Smckusick 	if(status.force)status.login[0] = status.mpasswd[0] = 0;
2008191Smckusick 
2018191Smckusick 	/* look up login name and passwd in the environment */
2028191Smckusick 	envloginpasswd(remote,status.login,status.mpasswd);
2038191Smckusick 
2048191Smckusick 
2058191Smckusick 	if(remote == 0)remote = getremote(local);
2068191Smckusick # ifndef TESTING
2078191Smckusick 	if(remote == local){
2088191Smckusick 		fprintf(stderr,"Request sent to local machine - doesn't make sense\n");
2098191Smckusick 		/* outerror(); */
2108191Smckusick 		}
2118191Smckusick # endif
2128191Smckusick 	strcat(status.defcmd," ");
2138191Smckusick 	if(strlen(hd.hd_scmdact) == 0)strcpy(hd.hd_scmdact,status.defcmd);
2148191Smckusick 	hd.hd_scmdact[strlen(hd.hd_scmdact)-1] = 0;
2158191Smckusick 	do {
2168191Smckusick 		mktemp(dfname); /* make until unique!! */
2178191Smckusick 	} while(stat(dfname,&statbuf) >= 0);
2188191Smckusick 	/* determine through machine */
2198191Smckusick 	i = gothru(local,remote);
2208191Smckusick 	if(i == 0){
2218191Smckusick 		s = longname(remote);
2228191Smckusick 		if(s != 0)fprintf(stderr,"No path to %s machine.\n",s);
2238191Smckusick 		else fprintf(stderr,"Unknown machine\n");
2248191Smckusick 		outerror(EX_NOHOST);
2258191Smckusick 		}
2268191Smckusick 	dfname[strlen(dfname)-11] = i;		/* set directory */
2278191Smckusick 	dfname[strlen(dfname)-7] = i;		/* set file (unused) */
2288191Smckusick 	/* check to see if data files are directories */
2298191Smckusick 	if(isdirectory(hd.hd_srespfile) || isdirectory(hd.hd_sinfile) || isdirectory(hd.hd_soutfile)){
2308191Smckusick 		fprintf(stderr,"%s is a directory, must be a file\n",
2318191Smckusick 			isdirectory(hd.hd_srespfile)    ? hd.hd_srespfile :
2328191Smckusick 			isdirectory(hd.hd_sinfile)  ? hd.hd_sinfile :
2338191Smckusick 			hd.hd_soutfile);
2348191Smckusick 		outerror(EX_USAGE);
2358191Smckusick 	}
2368191Smckusick 	if(suid[0] != 0)uid = atoi(suid);
2378191Smckusick 	if(hd.hd_srespfile[0]){
2388191Smckusick 		if(strcmp(hd.hd_srespfile,"/dev/tty") == 0){
2398191Smckusick 		fprintf(stderr,"Can't have /dev/tty as response file.\n");
2408191Smckusick 			outerror(EX_USAGE);
2418191Smckusick 			}
2428191Smckusick 		if(stat(hd.hd_srespfile,&statbuf) == -1){
2438191Smckusick 			strcpy(buf,hd.hd_srespfile);
2448191Smckusick 			s = &buf[0];
2458191Smckusick 			s = s + strlen(buf) - 1;
2468191Smckusick 			while(*s != '/' && s > &(buf[0]))s--;
2478191Smckusick 			*s = 0;
2488191Smckusick 			debug("chkdir %s",buf);
2498191Smckusick 			if(strlen(buf) == 0)strcpy(buf,".");
2508191Smckusick 			if(access(buf,2) == -1){
2518191Smckusick 				perror(buf);
2528191Smckusick 				outerror(EX_USAGE);
2538191Smckusick 				}
2548191Smckusick 			if((rfile=fopen(hd.hd_srespfile,"w")) == NULL){
2558191Smckusick 				perror(hd.hd_srespfile);
2568191Smckusick 				outerror(EX_USAGE);
2578191Smckusick 				}
2588191Smckusick 			chmod(hd.hd_srespfile,0600);
2598191Smckusick 			fclose(rfile);
2608191Smckusick 			mchown(hd.hd_srespfile,uid,hd.hd_gidfrom);
2618191Smckusick 			}
2628191Smckusick 		else if(access(hd.hd_srespfile,2) == -1){
2638191Smckusick 			perror(hd.hd_srespfile);
2648191Smckusick 			outerror(EX_USAGE);
2658191Smckusick 			}
2668191Smckusick 		else if(getsize(&statbuf) != 0L){
2678191Smckusick 			fprintf(stderr,"%s must have 0-length or not exist\n",
2688191Smckusick 				hd.hd_srespfile);
2698191Smckusick 			outerror(EX_USAGE);
2708191Smckusick 		}
2718191Smckusick 	}
2728191Smckusick 	/* go ahead and prompt for login name and passwd, if neccessary,
2738191Smckusick 	   as long as the X option has not been specified */
2748191Smckusick 	if(hd.hd_code == 'q' && !xopt)promptlogin(remote);
2758191Smckusick 
2768191Smckusick 	/* at this point, we create the dfa... file */
2778191Smckusick 	file = fopen(dfname,"w");
2788191Smckusick 	if(file == NULL){
2798191Smckusick 		perror(dfname);
2808191Smckusick 		outerror(EX_OSERR);
2818191Smckusick 		}
2828191Smckusick 	chmod(dfname,0600);
2838191Smckusick 	mchown(dfname,uid,getgid());
2848191Smckusick 	if(xopt)goto stickit;
2858191Smckusick 	if(status.mpasswd[0] == '\n')
2868191Smckusick 		status.mpasswd[0] = 0;
2878191Smckusick 	if(status.mpasswd[0] == 0 && hd.hd_code == 'q' &&
2888191Smckusick 		strcmp(status.login,"network") != 0){
2898191Smckusick 		fprintf(stderr,"Zero-length password not allowed\n");
2908191Smckusick 		outerror(EX_USAGE);
2918191Smckusick 		}
2928191Smckusick 	if(hd.hd_code == 'q' && (streql(status.login,"root") == 0 ||
2938191Smckusick 		streql(status.login,"ruut") == 0)){
2948191Smckusick 		fprintf(stderr,"Can't login as root through the network\n");
2958191Smckusick 		outerror(EX_USAGE);
2968191Smckusick 		}
2978191Smckusick 	makeuukey(skey,status.login,remote);
2988191Smckusick 	nbsencrypt(status.mpasswd,skey,hd.hd_sencpasswd);
2998191Smckusick 	enmask(status.mpasswd);
3008191Smckusick 	hd.hd_lttytime = 0;
3018191Smckusick 	if(hd.hd_sttyname[0] && status.nowrite == 0){
3028191Smckusick 		putmp = getutmp(hd.hd_sttyname);
3038191Smckusick 		if(putmp != NULL) hd.hd_lttytime = putmp->ut_time;
3048191Smckusick 	}
3058191Smckusick /*
3068191Smckusick 	debug("p:%s:\n",status.mpasswd);
3078191Smckusick */
3088191Smckusick 	/* write the header info onto 'file' */
3098191Smckusick 	hd.hd_mchto = remote;
3108191Smckusick 	hd.hd_mesgid.msg_mch = hd.hd_mchfrom = local;
3118191Smckusick 	hd.hd_vmajor = VMAJOR;
3128191Smckusick 	hd.hd_vminor = VMINOR;
3138191Smckusick 	strcpy(hd.hd_snto,status.login);
3148191Smckusick 	strcpy(hd.hd_snfrom,status.localname);
3158191Smckusick 	strcpy(hd.hd_spasswd,status.mpasswd);
3168191Smckusick 	strcpy(hd.hd_ijobno, status.jobno );
3178191Smckusick 	hd.hd_mesgid.msg_ltime = hd.hd_ltimesent = gettime();
3188191Smckusick 	hd.hd_fquiet = status.quiet;
3198191Smckusick 	hd.hd_fnonotify = status.nonotify;
3208191Smckusick 	hd.hd_mesgid.msg_pid = getpid();
3218191Smckusick 	hd.hd_fcompressed = 0;
3228191Smckusick 	/* handle account pairs, accounts which do not require
3238191Smckusick 	   a passwd if you are logged in on the same one here */
3248191Smckusick 	hd.hd_facctpair = fisacctpair(&hd);
3258191Smckusick 
3268191Smckusick 	writehdfd(&hd,file);
3278191Smckusick 	printhd(&hd);
3288191Smckusick stickit:
3298191Smckusick 	if(sin)
3308191Smckusick 		while((i = fread(buf,1,BUFSIZ,stdin)) > 0){
3318191Smckusick 			if(fwrite(buf,1,i,file) != i){
3328191Smckusick 				perror("net queue file");
3338191Smckusick 				outerror(EX_OSFILE);
3348191Smckusick 				}
3358191Smckusick 			if((cnt += i) > maxfile)goto toobig;
3368191Smckusick 			if(feof(stdin))break;
3378191Smckusick 			}
3388191Smckusick 	else if(localin[0]){
3398191Smckusick 		if(access(localin,4) == -1){
3408191Smckusick 			perror(localin);
3418191Smckusick 			outerror(EX_OSFILE);
3428191Smckusick 			}
3438191Smckusick 		temp = fopen(localin,"r");
3448191Smckusick 		if(temp == NULL){
3458191Smckusick 			perror(localin);
3468191Smckusick 			outerror(EX_OSFILE);
3478191Smckusick 			}
3488191Smckusick 		while((i = fread(buf,1,BUFSIZ,temp)) > 0){
3498191Smckusick 			if((cnt += i) > maxfile)goto toobig;
3508191Smckusick 			if(fwrite(buf,1,i,file) != i){
3518191Smckusick 				perror("net queue file");
3528191Smckusick 				outerror(EX_OSFILE);
3538191Smckusick 				}
3548191Smckusick 			}
3558191Smckusick 		fclose(temp);
3568191Smckusick 		}
3578191Smckusick 	fclose(file);
3588191Smckusick 	chmod(dfname,0400);
3598191Smckusick 	dfname[strlen(dfname)-9] = 'c';
3608191Smckusick 	file = fopen(dfname,"w");
3618191Smckusick 	chmod(dfname,0400);
3628191Smckusick 	fclose(file);
3638191Smckusick 	mchown(dfname,uid,getgid());
3648191Smckusick 	exit(EX_OK);
3658191Smckusick toobig:
3668191Smckusick 	fprintf(stderr,"No more than %ld bytes can be sent\n",maxfile);
3678191Smckusick 	outerror(EX_USAGE);		/* no return */
3688191Smckusick 	}
3698191Smckusick /*
3708191Smckusick    called if there is an error, makes sure that the files created
3718191Smckusick    are deleted and the terminal is reset to echo
3728191Smckusick */
outerror(ret)3738191Smckusick outerror(ret){
3748191Smckusick 	register int i;
3758191Smckusick 	struct sgttyb stt;
3768191Smckusick 	signal(SIGHUP,SIG_IGN); signal(SIGINT,SIG_IGN);
3778191Smckusick 	signal(SIGQUIT,SIG_IGN); signal(SIGTERM,SIG_IGN);
3788191Smckusick 	unlink(dfname);
3798191Smckusick 	i = strlen(dfname) - 9;
3808191Smckusick 	dfname[i] = (dfname[i] == 'c' ? 'd' : 'c');
3818191Smckusick 	unlink(dfname);
3828191Smckusick 	if(gtty(0,&stt) >= 0){
3838191Smckusick 		stt.sg_flags |= ECHO;
3848191Smckusick 		stty(0,&stt);
3858191Smckusick 		}
3868191Smckusick 	exit(ret);
3878191Smckusick 	}
enmask(s)3888191Smckusick enmask(s)
3898191Smckusick   register char *s; {
3908191Smckusick 	while(*s){
3918191Smckusick 		*s &= 0177;		/* strip quote bites */
3928191Smckusick 		*s++ ^= 040;		/* invert upper-lower */
3938191Smckusick 		}
3948191Smckusick 	}
addir(s,t)3958191Smckusick addir(s,t)
3968191Smckusick   register char *s, *t; {
3978191Smckusick 	if(t[0] == '/')strcpy(s,t);
3988191Smckusick 	else {
3998191Smckusick 		gwd(s);
4008191Smckusick 		strcat(s,t);
4018191Smckusick 		}
4028191Smckusick 	}
4038191Smckusick 
4048191Smckusick /* returns true if phd is an account pair, false otherwise */
fisacctpair(phd)4058191Smckusick fisacctpair(phd)
4068191Smckusick register struct header *phd;
4078191Smckusick {
4088191Smckusick 	return(0);
4098191Smckusick }
4108191Smckusick 
4118191Smckusick 
4128191Smckusick 
4138191Smckusick static struct stat x;
4148191Smckusick static struct direct y;
4158191Smckusick static int off = -1;
4168191Smckusick 
4178191Smckusick 
4188191Smckusick /* these three routines gwd, cat, ckroot and
4198191Smckusick    data structures x, y, off, do a pwd to string name */
4208191Smckusick #ifdef V6
421*8220Smckusick static FILE *file;
422*8220Smckusick 
gwd(name)4238191Smckusick gwd(name)
4248191Smckusick   register char *name; {
4258191Smckusick 	*name = 0;
4268191Smckusick 	for(;;){
4278191Smckusick 		stat(".",&x);
4288191Smckusick 		if((file = fopen("..","r")) == NULL)break;
4298191Smckusick 		do {
4308191Smckusick 			if(fread(&y,1,sizeof y,file) != sizeof y)break;
4318191Smckusick 			} while(y.d_ino != x.st_ino);
4328191Smckusick 		fclose(file);
4338191Smckusick 		if(y.d_ino == ROOTINO){
4348191Smckusick 			ckroot(name);
4358191Smckusick 			break;
4368191Smckusick 			}
4378191Smckusick 		if(cat(name))break;
4388191Smckusick 		chdir("..");
4398191Smckusick 		}
4408191Smckusick 	chdir(name);
4418191Smckusick 	}
ckroot(name)4428191Smckusick ckroot(name)
4438191Smckusick   char *name; {
4448191Smckusick 	register int i;
4458191Smckusick 	if(stat(y.d_name,&x) < 0)return;
4468191Smckusick 	i = x.st_dev;
4478191Smckusick 	if(chdir("/") < 0)return;
4488191Smckusick 	if((file = fopen("/","r")) == NULL)return;
4498191Smckusick 	do {
4508191Smckusick 		if(fread(&y,1,sizeof y,file) != sizeof y)return;
4518191Smckusick 		if(y.d_ino == 0)continue;
4528191Smckusick 		if(stat(y.d_name,&x) < 0)return;
4538191Smckusick 		} while(x.st_dev!=i || (x.st_mode&S_IFMT)!=S_IFDIR);
4548191Smckusick 	if(strcmp(y.d_name,".") != 0 && strcmp(y.d_name,"..") != 0)
4558191Smckusick 		if(cat(name))return;
4568191Smckusick 	i = strlen(name);
4578191Smckusick 	name[i+1] = 0;
4588191Smckusick 	while(--i >= 0)name[i + 1] = name[i];
4598191Smckusick 	name[0] = '/';
4608191Smckusick 	return;
4618191Smckusick 	}
4628191Smckusick #else
463*8220Smckusick static DIR *file;
4648191Smckusick static struct stat xx;
4658191Smckusick 
gwd(name)4668191Smckusick gwd(name)
4678191Smckusick   register char *name;  {
4688191Smckusick 	int rdev, rino;
4698191Smckusick 	register int i;
470*8220Smckusick 	register struct direct *dp;
4718191Smckusick 
4728191Smckusick 	*name = 0;
4738191Smckusick 	stat("/", &x);
4748191Smckusick 	rdev = x.st_dev;
4758191Smckusick 	rino = x.st_ino;
4768191Smckusick 	for (;;) {
4778191Smckusick 		stat(".", &x);
4788191Smckusick 		if (x.st_ino == rino && x.st_dev == rdev)
4798191Smckusick 			break;
480*8220Smckusick 		if ((file = opendir("..")) == NULL)
4818191Smckusick 			break;
482*8220Smckusick 		fstat(file->dd_fd, &xx);
4838191Smckusick 		chdir("..");
4848191Smckusick 		if (x.st_dev == xx.st_dev) {
4858191Smckusick 			if (x.st_ino == xx.st_ino)
4868191Smckusick 				break;
4878191Smckusick 			do
488*8220Smckusick 				if ((dp = readdir(file)) == NULL)
4898191Smckusick 					break;
490*8220Smckusick 			while (dp->d_ino != x.st_ino);
4918191Smckusick 		}
4928191Smckusick 		else do {
493*8220Smckusick 			if ((dp = readdir(file)) == NULL)
4948191Smckusick 				break;
495*8220Smckusick 			stat(dp->d_name, &xx);
4968191Smckusick 		} while (xx.st_ino != x.st_ino || xx.st_dev != x.st_dev);
497*8220Smckusick 		blkcpy(dp, &y, DIRSIZ(dp));
498*8220Smckusick 		closedir(file);
4998191Smckusick 		if (cat(name))
5008191Smckusick 			break;
5018191Smckusick 	}
5028191Smckusick 	i = strlen(name);
5038191Smckusick 	name[i+1] = 0;
5048191Smckusick 	while (--i >= 0) name[i+1] = name[i];
5058191Smckusick 	name[0] = '/';
5068191Smckusick }
5078191Smckusick #endif
5088191Smckusick 
cat(name)5098191Smckusick cat(name)
5108191Smckusick   register char *name; {		/* return 1 to exit */
5118191Smckusick 	register int i,j;
5128191Smckusick 	i = -1;
5138191Smckusick 	while(y.d_name[++i] != 0);
5148191Smckusick 	if((off+i+2) > 511)return(1);
5158191Smckusick 	for(j = off +1; j >= 0; --j)name[j+i+1] = name[j];
5168191Smckusick 	off = i + off + 1;
5178191Smckusick 	name[i] = '/';
5188191Smckusick 	for(--i; i>= 0; --i)name[i] = y.d_name[i];
5198191Smckusick 	return(0);
5208191Smckusick 	}
5218191Smckusick 
5228191Smckusick 
5238191Smckusick /*
5248191Smckusick 	this function takes a file name and tells whether it is a
5258191Smckusick 	directory or on. Returns 1 if so, 0 otherwise.
5268191Smckusick 	null strings etc. return 0.
5278191Smckusick */
isdirectory(fn)5288191Smckusick isdirectory(fn)
5298191Smckusick 	char *fn;
5308191Smckusick {
5318191Smckusick 	int i,ret=0;
5328191Smckusick 	if(fn == NULL || *fn == 0)return(0);
5338191Smckusick 	i = strlen(fn);
5348191Smckusick 	if(i == 1){
5358191Smckusick 		if(strcmp(fn,".")       == 0)ret = 1;
5368191Smckusick 		if(strcmp(fn,"/")       == 0)ret = 1;
5378191Smckusick 	}
5388191Smckusick 	else if(i == 2){
5398191Smckusick 		if(strcmp(fn,"..")      == 0)ret = 1;
5408191Smckusick 		if(strcmp(fn,"/.")      == 0)ret = 1;
5418191Smckusick 	}
5428191Smckusick 	else {
5438191Smckusick 		if(strcmp(fn+i-2,"/.")  == 0)ret = 1;
5448191Smckusick 		if(strcmp(fn+i-3,"/..") == 0)ret = 1;
5458191Smckusick 	}
5468191Smckusick 	return(ret);
5478191Smckusick }
548*8220Smckusick 
blkcpy(from,to,size)549*8220Smckusick blkcpy(from, to, size)
550*8220Smckusick 	register *from, *to;
551*8220Smckusick 	register int size;
552*8220Smckusick {
553*8220Smckusick 	while (size-- > 0)
554*8220Smckusick 		*to++ = *from++;
555*8220Smckusick }
556