Commit | Line | Data |
---|---|---|
2c049c08 | 1 | static char sccsid[] = "@(#)mach.c 4.2 (Berkeley) %G%"; |
40da0d40 KM |
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 | |
24 | submit(a) {} | |
2c049c08 DC |
25 | # endif |
26 | # endif | |
40da0d40 KM |
27 | |
28 | # ifdef FUID | |
29 | setgid() {}; | |
2c049c08 | 30 | # endif |
40da0d40 KM |
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 | */ | |
40 | mchown(sfn,uid,gid) | |
41 | char *sfn; | |
42 | int uid; | |
43 | int gid; | |
44 | { | |
45 | # ifndef V6 | |
46 | chown(sfn,uid,gid); | |
2c049c08 | 47 | # else |
40da0d40 KM |
48 | # ifndef FUID |
49 | uid = uidmask(uid); | |
50 | uid = ((gid&0377) << 8) | (uid & 0377); | |
2c049c08 | 51 | # endif |
40da0d40 KM |
52 | chown(sfn,uid); |
53 | if(debugflg) | |
54 | fprintf(stderr, "chown %s to %d(%o)\n",sfn,uid,uid); | |
2c049c08 | 55 | # endif |
40da0d40 KM |
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 | */ | |
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 | } | |
2c049c08 | 81 | # endif |
40da0d40 KM |
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 | } | |
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); | |
2c049c08 | 97 | # endif |
40da0d40 KM |
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 */ | |
2c049c08 | 107 | guid(uid,gid){ |
40da0d40 KM |
108 | uid = uidmask(uid); |
109 | # ifdef FUID | |
110 | return((uid & 0377) | (gid << 8)); | |
2c049c08 | 111 | # else |
40da0d40 | 112 | return(uid); |
2c049c08 DC |
113 | # endif |
114 | } | |
40da0d40 KM |
115 | |
116 | # ifdef OLDTTY | |
117 | isatty(i){ | |
118 | return(ttyn(i) != 'x'); | |
119 | } | |
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 | } | |
2c049c08 | 127 | # endif |
40da0d40 KM |
128 | |
129 | # ifdef CCTTY | |
130 | # undef ttyname() | |
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) | |
2c049c08 | 140 | # endif |
40da0d40 KM |
141 | |
142 | /* expand control chars in string 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 | */ | |
2c049c08 DC |
190 | # endif |
191 | # endif | |
40da0d40 KM |
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 | */ | |
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; | |
2c049c08 | 211 | # endif |
40da0d40 KM |
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 | } | |
2c049c08 | 227 | # else |
40da0d40 KM |
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 | } | |
2c049c08 | 237 | # endif |
40da0d40 KM |
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 | ||
250 | ioctl(a,b,c){ | |
251 | return(0); /* always succeeds */ | |
252 | } | |
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 | } | |
260 | long gettime(){ | |
261 | long tt; | |
262 | time(&tt); | |
263 | return(tt); | |
264 | } | |
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 | */ | |
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(); | |
2c049c08 | 290 | # endif |
40da0d40 KM |
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(); | |
2c049c08 DC |
295 | # endif |
296 | # endif | |
40da0d40 KM |
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 * | |
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 | ||
326 | setpwent() | |
327 | { | |
328 | debug("reading passwd\n"); | |
329 | if( pwf == NULL ) | |
330 | pwf = fopen( PASSWD, "r" ); | |
331 | else | |
332 | rewind( pwf ); | |
333 | } | |
334 | ||
335 | endpwent() | |
336 | { | |
337 | if( pwf != NULL ){ | |
338 | fclose( pwf ); | |
339 | pwf = NULL; | |
340 | } | |
341 | } | |
342 | ||
343 | static char * | |
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 * | |
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 * | |
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 | */ | |
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 * | |
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 | } | |
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 * | |
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 | ||
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 | ||
537 | umask(n){} | |
538 | ||
40da0d40 | 539 | /* end of non-vax v7 routines */ |
2c049c08 | 540 | # endif |
40da0d40 KM |
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 * | |
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 | } | |
2c049c08 | 573 | # endif |
40da0d40 KM |
574 | |
575 | return(getpwuid(uidmask(getuid()))); | |
576 | } | |
577 | /*VARARGS0*/ | |
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 | } |