|
|
1.1 root 1: static char sccsid[] = "@(#)mach.c 4.2 (Berkeley) 10/2/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
24: submit(a) {}
25: # endif
26: # endif
27:
28: # ifdef FUID
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: */
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: */
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: }
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 */
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
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: }
127: # endif
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)
140: # endif
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: */
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: */
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:
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();
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 *
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:
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 *
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*/
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.