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: }