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