xref: /original-bsd/old/berknet/mach.c (revision e3a5797f)
1 static char sccsid[] = "@(#)mach.c	4.2	(Berkeley)	10/02/82";
2 
3 /* sccs id variable */
4 static char *mach_sid = "@(#)mach.c	1.6";
5 /*
6 
7    This file is meant to handle all the machine
8    dependencies in the network code.
9    Everything is conditionally compiled.
10 
11    It can be uses w/o network stuff to simulate
12    v7 for other programs, too.
13 */
14 # include <stdio.h>
15 # include "mach.h"
16 
17 char shomedir[100];
18 
19 int debugflg;
20 
21 /* the CC and SRC machines have the submit() call */
22 # ifndef CC
23 # ifndef SRC
submit(a)24 submit(a) {}
25 # endif
26 # endif
27 
28 # ifdef FUID
setgid()29 setgid() {};
30 # endif
31 
32 /*
33    Set the owner uid/gid of a file.
34    On v7, this is done by the chown command
35    with three args - (file, uid, gid).
36    On Vanilla V6 this is done using the
37    top byte of the second parameter as the gid byte.
38    On Berkeley Funny uids on V6, no gid is specified.
39 */
mchown(sfn,uid,gid)40 mchown(sfn,uid,gid)
41 	char *sfn;
42 	int uid;
43 	int gid;
44 {
45 # ifndef V6
46 	chown(sfn,uid,gid);
47 # else
48 # ifndef FUID
49 		uid = uidmask(uid);
50 		uid = ((gid&0377) << 8) | (uid & 0377);
51 # endif
52 	chown(sfn,uid);
53 	if(debugflg)
54 		fprintf(stderr, "chown %s to %d(%o)\n",sfn,uid,uid);
55 # endif
56 }
57 
58 
59 /*
60 	SnFromuid(uid)
61 
62 	The login name corresponding to uid.
63 	Reads the password file.
64 	Successive calls overwrite the static string returned.
65 	Returns NULL if error.
66 */
SnFromUid(uid)67 char *SnFromUid(uid)
68 	register int uid;
69 {
70 	register struct passwd *pwd;
71 	static int ouid = -1;
72 	static char oresult[20] = "";
73 	uid = uidmask(uid);
74 	if(uid == ouid)
75 		return(oresult);
76 # ifdef HPASSWD
77 	if(getname(uid,oresult) == 0){
78 		ouid = uid;
79 		return(oresult);
80 	}
81 # endif
82 	pwd = getpwuid(uid);
83 	if(pwd != NULL){
84 		strcpy(oresult,pwd->pw_name);
85 		ouid = uid;
86 		return(oresult);
87 	}
88 	return(NULL);
89 }
uidfromsn(sn)90 uidfromsn(sn)
91 register char *sn;
92 {
93 	register int him = -1;
94 	register struct passwd *pwd;
95 # ifdef HPASSWD
96 	him = getuserid(sn);
97 # endif
98 	if(him == -1){
99 		pwd = getpwnam(sn);
100 		if(pwd != NULL)him = guid(pwd->pw_uid,pwd->pw_gid);
101 		}
102 	return(him);
103 }
104 
105 /* handle the regular unix and local mods difference for user id's */
106 /* this call returns the 1 word uid = to what getuid will return */
guid(uid,gid)107 guid(uid,gid){
108 	uid = uidmask(uid);
109 # ifdef FUID
110 	return((uid & 0377) | (gid << 8));
111 # else
112 	return(uid);
113 # endif
114 	}
115 
116 # ifdef OLDTTY
isatty(i)117 isatty(i){
118 	return(ttyn(i) != 'x');
119 	}
ttyname(i)120 char *ttyname(i){		/* return NULL if not TTY */
121 	char c;
122 	static char ttystr[] = "/dev/ttyx";
123 	c = ttyn(i);
124 	ttystr[8] = c;
125 	return(c == 'x' ? NULL : ttystr);
126 	}
127 # endif
128 
129 # ifdef CCTTY
130 # undef ttyname()
myttyname(i)131 char *myttyname(i){		/* return NULL for non tty */
132 	static char s[15],*p;
133 	p = ttyname(i);
134 	if(p == NULL)return(NULL);
135 	strcpy(s,"/dev/");
136 	strcat(s,p);
137 	return(s);
138 	}
139 # define ttyname(S) myttyname(S)
140 # endif
141 
142 /* expand control chars in string s */
expandcc(s)143 expandcc(s)
144   register char *s; {
145 	char stemp[100];
146 	register char *p;
147 
148 	if(s == NULL)return;
149 	strcpy(stemp,s);
150 	p = stemp;
151 	while(*p){
152 		if(!isprint(*p)){
153 			*s++ = '^';
154 			*s++ = *p++ + 0140;
155 		}
156 		else *s++ = *p++;
157 	}
158 }
159 
160 /* get passwd from passwdf */
161 getpwdf(pwd)
162   struct passwd *pwd; {
163 # ifdef PASSWDF
164 # ifndef TESTING
165 	register char *p, *q;
166 	char buf1[BUFSIZ], found;
167 	FILE *pw;
168 	debug("reading passwdf\n");
169 	pwd->pw_passwd[0] = 0;
170 	pw = fopen("/etc/passwdf","r");
171 	if(pw == NULL) return;
172 	found = 0;
173 	while(fgets(buf1,BUFSIZ,pw) != NULL){
174 		for(p=buf1; *p && *p != ':'; p++);
175 		*p = 0;
176 		if(strcmp(buf1,pwd->pw_name) == 0){
177 			found = 1;
178 			break;
179 			}
180 		}
181 	fclose(pw);
182 	if(!found)return;
183 	q = ++p;
184 	for(;*p && *p != ':';p++);
185 	*p = 0;
186 	strcpy(pwd->pw_passwd,q);
187 	/*
188 	debug("user %s passwd %s %s",pwd->pw_name,pwd->pw_passwd);
189 	*/
190 # endif
191 # endif
192 	}
193 /*
194 	getutmp()
195 	return a pointer to the system utmp structure associated with
196 	terminal sttyname, e.g. "/dev/tty3"
197 	Is version independent-- will work on v6 systems
198 	return NULL if error
199 */
getutmp(sttyname)200 struct utmp *getutmp(sttyname)
201 char *sttyname;
202 {
203 # ifdef OLDTTY
204 	struct v6utmp {
205 		char v6ut_name[8];
206 		char v6ut_tty;
207 		char v6ut_fill;
208 		long v6ut_time;
209 		int  v6ut_fl1;
210 		} v6utmpstr;
211 # endif
212 	static struct utmp utmpstr;
213 	FILE *fdutmp;
214 
215 	debug("reading utmp\n");
216 	if(sttyname == NULL || sttyname[0] == 0)return(NULL);
217 
218 	fdutmp = fopen("/etc/utmp","r");
219 	if(fdutmp == NULL)return(NULL);
220 
221 # ifndef OLDTTY
222 	while(fread(&utmpstr,1,sizeof utmpstr,fdutmp) == sizeof utmpstr)
223 		if(strcmp(utmpstr.ut_line,sttyname+5) == 0){
224 			fclose(fdutmp);
225 			return(&utmpstr);
226 		}
227 # else
228 	while(fread(&v6utmpstr,1,sizeof v6utmpstr,fdutmp) == sizeof v6utmpstr)
229 		if(v6utmpstr.v6ut_tty == sttyname[8]){
230 			strcpy(utmpstr.ut_name,v6utmpstr.v6ut_name);
231 			strcpy(utmpstr.ut_line,"ttyx");
232 			utmpstr.ut_line[3] = v6utmpstr.v6ut_tty;
233 			utmpstr.ut_time = v6utmpstr.v6ut_time;
234 			fclose(fdutmp);
235 			return(&utmpstr);
236 		}
237 # endif
238 	fclose(fdutmp);
239 	return(NULL);
240 }
241 
242 /*
243    these are all the v7 routines not available on the v6 machines
244 */
245 
246 # ifdef V6
247 
248 char **environ;			/* global environment pointer */
249 
ioctl(a,b,c)250 ioctl(a,b,c){
251 	return(0);		/* always succeeds */
252 	}
atol(s)253 long atol(s)
254   register char *s; {
255 	long i = 0;
256 	while('0' <= *s && *s <= '9')
257 		i = i * 10 + (*s++ - '0');
258 	return(i);
259 	}
gettime()260 long gettime(){
261 	long tt;
262 	time(&tt);
263 	return(tt);
264 	}
getsize(str)265 long getsize(str)
266   struct stat *str; {
267 	long wk;
268 	wk = ((long)(str->st_size0 & 0377)) << 16;
269 	wk += (long)((unsigned)str->st_size1);
270 	return(wk);
271 	}
272 /*
273 	getenv("HOME")
274 
275 	always returns home directory.
276 	returns NULL if there is error.
277 */
getenv()278 char *getenv(){
279 	register char *shdir = NULL;
280 	register struct passwd *pwd;
281 	register int it;
282 	if(shomedir[0] != 0)return(shomedir);
283 # ifdef BERKELEY
284 	/* hget only works on Berkeley machines */
285 	it = ttyn(2);
286 # ifdef OLDTTY
287 	if(it == 'x')it = ttyn(1);
288 	if(it == 'x')it = ttyn(0);
289 	if(it != 'x' && hget(it) == 0)shdir = hgethome();
290 # endif
291 # ifdef CCTTY
292 	if(it == -1)it = ttyn(1);
293 	if(it == -1)it = ttyn(0);
294 	if(it != -1 && hget(it) == 0)shdir = hgethome();
295 # endif
296 # endif
297 	if(shdir == NULL){
298 		pwd = PwdCurrent();
299 		if(pwd != NULL)shdir = pwd->pw_dir;
300 		}
301 	if(shdir != NULL)strcpy(shomedir,shdir);
302 	return(shdir);
303 	}
304 
305 /* doesn't handle split passwd files */
306 struct passwd *
getpwuid(uid)307 getpwuid(uid)
308 register uid;
309 {
310 	register struct passwd *p;
311 	struct passwd *getpwent();
312 
313 	uid = uidmask(uid);
314 	setpwent();
315 	while( (p = getpwent()) && guid(p->pw_uid,p->pw_gid) != uid );
316 	endpwent();
317 	return(p);
318 }
319 
320 static char PASSWD[]	= "/etc/passwd";
321 static char EMPTY[] = "";
322 static FILE *pwf = NULL;
323 static char line[BUFSIZ+1];
324 static struct passwd passwd;
325 
setpwent()326 setpwent()
327 {
328 	debug("reading passwd\n");
329 	if( pwf == NULL )
330 		pwf = fopen( PASSWD, "r" );
331 	else
332 		rewind( pwf );
333 }
334 
endpwent()335 endpwent()
336 {
337 	if( pwf != NULL ){
338 		fclose( pwf );
339 		pwf = NULL;
340 	}
341 }
342 
343 static char *
pwskip(p)344 pwskip(p)
345 register char *p;
346 {
347 	while( *p && *p != ':' )
348 		++p;
349 	if( *p ) *p++ = 0;
350 	return(p);
351 }
352 
353 struct passwd *
getpwent()354 getpwent()
355 {
356 	register char *p;
357 
358 	if (pwf == NULL) {
359 		if( (pwf = fopen( PASSWD, "r" )) == NULL )
360 			return(0);
361 	}
362 	p = fgets(line, BUFSIZ, pwf);
363 	if (p==NULL)
364 		return(0);
365 	passwd.pw_name = p;
366 	p = pwskip(p);
367 	passwd.pw_passwd = p;
368 	p = pwskip(p);
369 	passwd.pw_uid = atoi(p);
370 	passwd.pw_uid = uidmask(passwd.pw_uid);
371 	p = pwskip(p);
372 	passwd.pw_gid = atoi(p);
373 	passwd.pw_quota = 0;
374 	passwd.pw_comment = EMPTY;
375 	p = pwskip(p);
376 	passwd.pw_gecos = p;
377 	p = pwskip(p);
378 	passwd.pw_dir = p;
379 	p = pwskip(p);
380 	passwd.pw_shell = p;
381 	while(*p && *p != '\n') p++;
382 	*p = '\0';
383 	return(&passwd);
384 }
385 
386 struct passwd *
getpwnam(name)387 getpwnam(name)
388 char *name;
389 {
390 	register struct passwd *p;
391 	struct passwd *getpwent();
392 
393 	setpwent();
394 	while( (p = getpwent()) && strcmp(name,p->pw_name) );
395 	endpwent();
396 	return(p);
397 }
398 /*
399 	getlogin()
400 
401 	Return current user name by looking at /etc/utmp (calls getutmp()).
402 	Returns NULL if not found.
403 */
getlogin()404 char *getlogin()
405 {
406 	register struct utmp *putmp;
407 	register char *s;
408 	char sttyname[30];
409 
410 	if(isatty(2))strcpy(sttyname,ttyname(2));
411 	else if(isatty(0))strcpy(sttyname,ttyname(0));
412 	else if(isatty(1))strcpy(sttyname,ttyname(1));
413 	else return(NULL);
414 
415 	putmp = getutmp(sttyname);
416 	if(putmp == NULL)return(NULL);
417 	s = putmp->ut_name;
418 	while(*s != 0 && *s != ' ')s++;
419 	*s = 0;
420 	if(putmp->ut_name[0] == 0)return(NULL);
421 	return(putmp->ut_name);
422 }
423 /*
424  * Unix routine to do an "fopen" on file descriptor
425  * The mode has to be repeated because you can't query its
426  * status
427  */
428 
429 FILE *
fdopen(fd,mode)430 fdopen(fd, mode)
431 register char *mode;
432 {
433 	extern int errno;
434 	register FILE *iop;
435 	extern FILE *_lastbuf;
436 
437 	for (iop = _iob; iop->_flag&(_IOREAD|_IOWRT); iop++)
438 		if (iop >= _lastbuf)
439 			return(NULL);
440 	iop->_cnt = 0;
441 	iop->_file = fd;
442 	if (*mode != 'r') {
443 		iop->_flag |= _IOWRT;
444 		if (*mode == 'a')
445 			lseek(fd, 0L, 2);
446 	} else
447 		iop->_flag |= _IOREAD;
448 	return(iop);
449 }
system(s)450 system(s)
451 char *s;
452 {
453 	int status, pid, w;
454 	register int (*istat)(), (*qstat)();
455 
456 	while((pid = fork()) == -1)sleep(2);
457 	if (pid == 0) {
458 		execl("/bin/sh", "sh", "-c", s, 0);
459 		_exit(127);
460 	}
461 	istat = signal(SIGINT, SIG_IGN);
462 	qstat = signal(SIGQUIT, SIG_IGN);
463 	while ((w = wait(&status)) != pid && w != -1)
464 		;
465 	if (w == -1)
466 		status = -1;
467 	signal(SIGINT, istat);
468 	signal(SIGQUIT, qstat);
469 	return(status);
470 }
471 
472 char *
getpass(prompt)473 getpass(prompt)
474 char *prompt;
475 {
476 	struct sgttyb ttyb;
477 	int flags;
478 	register char *p;
479 	register c;
480 	FILE *fi = NULL;
481 	static char pbuf[9];
482 	int (*signal())();
483 	int (*sig)();
484 
485 	/*	modified because Cory needs super-user to stty /dev/tty */
486 	if ((fi = fopen("/dev/tty", "r")) == NULL)
487 		fi = stdin;
488 	else
489 		setbuf(fi, (char *)NULL);
490 	if(gtty(fileno(fi),&ttyb) < 0){
491 		pbuf[0] = 0;
492 		return(pbuf);
493 	}
494 	/*
495 	if(gtty(0,&ttyb) >= 0)fi = stdin;
496 	else if(gtty(2,&ttyb) >= 0)fi = stderr;
497 	else {
498 		pbuf[0] = 0;
499 		return(pbuf);
500 		}
501 	*/
502 	sig = signal(SIGINT, SIG_IGN);
503 	flags = ttyb.sg_flags;
504 	ttyb.sg_flags &= ~ECHO;
505 	if(stty(fileno(fi), &ttyb) < 0) perror("stty:");
506 	fprintf(stderr, prompt);
507 	for (p=pbuf; (c = getc(fi))!='\n' && c!=EOF;) {
508 		if (p < &pbuf[8])
509 			*p++ = c;
510 	}
511 	*p = '\0';
512 	fprintf(stderr, "\n");
513 	ttyb.sg_flags = flags;
514 	stty(fileno(fi), &ttyb);
515 	signal(SIGINT, sig);
516 	if (fi != stdin)
517 		fclose(fi);
518 	return(pbuf);
519 }
520 /*
521  * Compare strings (at most n bytes):  s1>s2: >0  s1==s2: 0  s1<s2: <0
522  */
523 
strncmp(s1,s2,n)524 strncmp(s1, s2, n)
525 register char *s1, *s2;
526 register n;
527 {
528 
529 	while (--n >= 0 && *s1 == *s2++)
530 		if (*s1++ == '\0')
531 			return(0);
532 	return(n<0 ? 0 : *s1 - *--s2);
533 }
534 
535 /* set the umask, ignore in v6 */
536 
umask(n)537 umask(n){}
538 
539 /* end of non-vax v7 routines */
540 # endif
541 /*
542 	PwdCurrent()
543 
544 	Read the password file and return pwd to
545 	entry for current user.
546 	Return NULL if error.
547 
548 	This code is a little screwed up because of the conventions
549 	regarding the state of the utmp file after someone su's--
550 	either to root or to another person.
551 	The final decision was to return getpwuid(getuid) if
552 	the machine has one login name per userid,
553 	and if there are multiple login names per userid, to
554 	search the passwd file for the getlogin() name and return
555 	the passwd file entry for that.
556 	If there is no utmp entry, just use the userid.
557 	This means that people who su on machine with multiple
558 	user-id's will get the passwd entry for the account recorded
559 	in the utmp file, not their current userid.
560 */
561 struct passwd *
PwdCurrent()562 PwdCurrent()
563 {
564 	register struct passwd *pwd;
565 	register char *sn;
566 
567 # ifdef MULTNAMS
568 	sn = getlogin();
569 	if(sn != NULL && sn[0] != 0 && sn[0] != ' '){
570 		pwd = getpwnam(sn);
571 		if(pwd != NULL)return(pwd);
572 	}
573 # endif
574 
575 	return(getpwuid(uidmask(getuid())));
576 }
577 /*VARARGS0*/
debug(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t)578 debug(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t)
579 char *s; {
580 	if(debugflg){
581 		printf(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,t);
582 		putchar('\n');
583 		}
584 	}
585