|
|
1.1 ! root 1: /* ! 2: sub.c ! 3: ! 4: support procedures ! 5: ! 6: the following procedures end up reading the passwd file ! 7: or the passwdf file and are to be avoided. ! 8: ! 9: getpwuid(uid) ! 10: getpwnam(sn) ! 11: PwdCurrent() ! 12: getenv("HOME") maybe if hget, hgethome don't work ! 13: SnFromUid(uid) maybe if hashed passwd stuff doesn't work ! 14: SnCurrent() maybe if getlogin fails calls SnFromUid(uid) ! 15: getpwf() ! 16: passwdent(uid,sn) ! 17: */ ! 18: ! 19: # include "defs.h" ! 20: # include "config.h" ! 21: ! 22: /* global variables */ ! 23: int debugflg = DBV; /* debug flag */ ! 24: char local = LOCAL; /* the machine we're on */ ! 25: struct userinfo status; ! 26: ! 27: char netcmd[] = NETCMD; ! 28: char resfile[] = RESFILE; ! 29: char senddir[] = SENDDIR; ! 30: char Bsh[] = BINSH; ! 31: ! 32: char shomedir[100]; ! 33: ! 34: /* ! 35: passwdent() ! 36: ! 37: Read the password file looking for current user's entry. ! 38: Fill in the status structure. ! 39: Has the (dangerous) side effect of giving a value to getenv("HOME"). ! 40: */ ! 41: passwdent() ! 42: { ! 43: register char *u; ! 44: register struct passwd *pwd; ! 45: pwd = PwdCurrent(); ! 46: if(pwd == NULL){ ! 47: err("Bad uid/username\n"); ! 48: return; ! 49: } ! 50: strcpy(status.localname,pwd->pw_name); ! 51: status.muid = guid(pwd->pw_uid,pwd->pw_gid); ! 52: status.mgid = pwd->pw_gid; ! 53: if(isdigit(pwd->pw_gecos[0]))status.jobno = atoi(pwd->pw_gecos); ! 54: else status.jobno = 32767; ! 55: strcpy(status.dir,pwd->pw_dir); ! 56: strcpy(shomedir,pwd->pw_dir); /* side effect */ ! 57: u = pwd->pw_shell; ! 58: if(u[0] == 0 || strcmp(u,"/bin/sbash") == 0)u= Bsh; ! 59: strcpy(status.loginshell,u); ! 60: } ! 61: /* ! 62: promptlogin(mchto) ! 63: ! 64: ask user for login and passwd on mchto. ! 65: make sure status.localname has a value before calling ! 66: this. One way is to call passwdent(). ! 67: */ ! 68: promptlogin(mchto) ! 69: char mchto; ! 70: { ! 71: char buf[BUFSIZ], mch; ! 72: FILE *wf; ! 73: int c; ! 74: if(status.mpasswd[0] == 0 || status.login[0] == 0 || status.force){ ! 75: wf = fopen("/dev/tty","r"); ! 76: if(wf != NULL){ ! 77: if(status.login[0]==0 || status.force){ ! 78: fprintf(stderr,"Name (%s:%s): ",longname(mchto), ! 79: status.localname); ! 80: if(fgets(buf, BUFSIZ, wf) != buf){ ! 81: perror("fgets"); ! 82: exit(EX_OSERR); ! 83: } ! 84: c = strlen(buf); ! 85: buf[c > 0 ? c-1 : 0] = 0; ! 86: if(c > 10){ ! 87: err("Login name too long.\n"); ! 88: exit(EX_USAGE); ! 89: } ! 90: if(FMemberSCh(buf,' ')){ ! 91: err("Login names don't have blanks in them.\n"); ! 92: exit(EX_USAGE); ! 93: } ! 94: if(buf[0] == 0)strcpy(buf,status.localname); ! 95: mch = MchSFromAddr(status.login,buf); ! 96: if(mch != local && mch != mchto){ ! 97: err( ! 98: "Must specify login name on %s machine\n", ! 99: longname(mchto)); ! 100: exit(EX_USAGE); ! 101: } ! 102: } ! 103: if(strcmp(status.login,"network") != 0 ! 104: && (status.mpasswd[0]== 0 || status.force)){ ! 105: sprintf(buf,"Password (%s:%s):", ! 106: longname(mchto), status.login); ! 107: strcpy(status.mpasswd,getpass(buf)); ! 108: } ! 109: fclose(wf); ! 110: } ! 111: } ! 112: if(status.login[0] == 0) strcpy(status.login,status.localname); ! 113: if(status.mpasswd[0] == 0)strcpy(status.mpasswd,"\"\""); ! 114: status.force = 0; ! 115: } ! 116: ! 117: #define tst(a,b) (*mode == 'r'? (b) : (a)) ! 118: #define RDR 0 ! 119: #define WTR 1 ! 120: static int popen_pid[20]; ! 121: ! 122: /* return a file descriptor suitable for writing, send to ! 123: user toaddress from fromaddress, ! 124: if cautious != 0 then don't do any forwarding ! 125: hopcnt is passed thru the mail program. ! 126: normal value is 0 ! 127: */ ! 128: FILE * ! 129: mailopen(toaddress, fromaddress, cautious, hopcnt) ! 130: char *toaddress, *fromaddress; ! 131: int cautious, hopcnt; ! 132: { ! 133: char cmd[100]; ! 134: char *mode = "w"; ! 135: int p[2]; ! 136: register myside, hisside, pid; ! 137: char shopcnt[20]; ! 138: ! 139: if(pipe(p) < 0) ! 140: return NULL; ! 141: myside = tst(p[WTR], p[RDR]); ! 142: hisside = tst(p[RDR], p[WTR]); ! 143: while((pid = fork()) == -1)sleep(2); ! 144: if(pid == 0) { ! 145: /* myside and hisside reverse roles in child */ ! 146: close(myside); ! 147: /* ! 148: dup2(hisside, tst(0, 1)); ! 149: */ ! 150: close(0); ! 151: dup(hisside); ! 152: close(hisside); ! 153: sprintf(shopcnt,"%d",hopcnt); ! 154: if(fromaddress != NULL){ ! 155: /* by convention, MAILFWD1 may forward this mail ! 156: and response messages shouldn't be forwarded */ ! 157: if(!cautious && !FMemberSCh(toaddress,'/')){ ! 158: # ifdef DELIVERM ! 159: mexecl("/etc/delivermail", ! 160: "delivermail", "-ee", "-r", fromaddress, ! 161: "-h",shopcnt, toaddress, 0); ! 162: # endif ! 163: mexecl(MAILFWD1, "mail","-r",fromaddress, ! 164: "-h",shopcnt,toaddress,0); ! 165: } ! 166: mexecl(SYSMAIL2, "mail","-d","-r",fromaddress, ! 167: "-h", shopcnt,toaddress,0); ! 168: } else { ! 169: if(!cautious && !FMemberSCh(toaddress,'/')){ ! 170: # ifdef DELIVERM ! 171: mexecl("/etc/delivermail", ! 172: "delivermail", "-ee", "-h", shopcnt, ! 173: toaddress, 0); ! 174: # endif ! 175: mexecl(MAILFWD1, "mail","-h", shopcnt, ! 176: toaddress,0); ! 177: } ! 178: mexecl(SYSMAIL2, "mail","-d","-h", shopcnt,toaddress,0); ! 179: } ! 180: perror(SYSMAIL2); ! 181: exit(EX_UNAVAILABLE); ! 182: } ! 183: if(pid == -1) ! 184: return NULL; ! 185: popen_pid[myside] = pid; ! 186: close(hisside); ! 187: return(fdopen(myside, mode)); ! 188: } ! 189: ! 190: mailclose(ptr) ! 191: FILE *ptr; ! 192: { ! 193: register f, r, (*hstat)(), (*istat)(), (*qstat)(); ! 194: int status; ! 195: ! 196: f = fileno(ptr); ! 197: fclose(ptr); ! 198: istat = signal(SIGINT, SIG_IGN); ! 199: qstat = signal(SIGQUIT, SIG_IGN); ! 200: hstat = signal(SIGHUP, SIG_IGN); ! 201: while((r = wait(&status)) != popen_pid[f] && r != -1) ! 202: ; ! 203: if(r == -1) ! 204: status = -1; ! 205: signal(SIGINT, istat); ! 206: signal(SIGQUIT, qstat); ! 207: signal(SIGHUP, hstat); ! 208: return(status); ! 209: } ! 210: ! 211: /* determine through machine */ ! 212: gothru(from,to){ ! 213: register int i; ! 214: switch(from){ ! 215: # ifdef RAND ! 216: case 'a': i = configA[to-'a']; break; ! 217: case 'b': i = configB[to-'a']; break; ! 218: case 'c': i = configC[to-'a']; break; ! 219: # endif ! 220: # ifdef NOSC ! 221: case 'a': i = configA[to-'a']; break; ! 222: case 'c': i = configC[to-'a']; break; ! 223: case 'm': i = configM[to-'a']; break; ! 224: # endif ! 225: # ifdef BERKELEY ! 226: /* for Berkeley */ ! 227: case 'a': i = configA[to-'a']; break; ! 228: case 'b': i = configB[to-'a']; break; ! 229: case 'c': i = configC[to-'a']; break; ! 230: case 'd': i = configD[to-'a']; break; ! 231: case 'e': i = configE[to-'a']; break; ! 232: case 'f': i = configF[to-'a']; break; ! 233: case 'i': i = configI[to-'a']; break; ! 234: case 'j': i = configJ[to-'a']; break; ! 235: case 'k': i = configK[to-'a']; break; ! 236: case 'l': i = configL[to-'a']; break; ! 237: case 'm': i = configM[to-'a']; break; ! 238: case 'o': i = configO[to-'a']; break; ! 239: case 'q': i = configQ[to-'a']; break; ! 240: case 'r': i = configR[to-'a']; break; ! 241: case 's': i = configS[to-'a']; break; ! 242: case 't': i = configT[to-'a']; break; ! 243: case 'v': i = configV[to-'a']; break; ! 244: case 'x': i = configX[to-'a']; break; ! 245: case 'y': i = configY[to-'a']; break; ! 246: case 'z': i = configZ[to-'a']; break; ! 247: # endif ! 248: default: i = 0; break; ! 249: } ! 250: return(i); ! 251: } ! 252: /* ! 253: harg(string,pargc,pargv) ! 254: ! 255: A curious procedure which takes a pointer to an argc, and a ! 256: pointer to an argv, and parses them so that the ! 257: argument following the flag is copied into string. ! 258: pargv[0] must be the flag argument. ! 259: handles both ! 260: -my ! 261: and ! 262: -m y ! 263: for the net command. ! 264: */ ! 265: harg(ans,pargc,pargv) ! 266: char *ans,*pargc,***pargv;{ ! 267: if((*pargv)[0][2]) /* no space */ ! 268: strcpy(ans,(*pargv)[0] + 2); ! 269: else { /* space, get next arg */ ! 270: strcpy(ans,(*pargv)[1]); ! 271: (*pargc)--; ! 272: (*pargv)++; ! 273: } ! 274: } ! 275: ! 276: /* prints out commands before executing them */ ! 277: /*VARARGS0*/ ! 278: mexecl(s) ! 279: char *s;{ ! 280: int *p = (int *)&s; ! 281: register int i; ! 282: if(debugflg){ ! 283: for(i=0; p[i]; i++)err("%s ",p[i]); ! 284: putc('\n',stderr); ! 285: } ! 286: execl(p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10],p[11], ! 287: p[12],p[13],p[14],p[15],0); ! 288: } ! 289: /* prints out commands before executing them */ ! 290: mexecv(s,p) ! 291: register char *s, **p;{ ! 292: register int i; ! 293: if(debugflg){ ! 294: err("%s ",s); ! 295: for(i=0; p[i]; i++)err("%s ",p[i]); ! 296: putc('\n',stderr); ! 297: } ! 298: execv(s,p); ! 299: } ! 300: ! 301: /*VARARGS0*/ ! 302: /* fills in -l - -p from commands like rcp */ ! 303: /* must be called with at least two arguments */ ! 304: kexecl(s) ! 305: char *s; { ! 306: char *a[20], i = 2, j = 2; ! 307: char **p = (char **)&s; ! 308: a[0] = p[0]; ! 309: a[1] = p[1]; ! 310: if(status.login[0]){ ! 311: a[i++] = "-l"; ! 312: a[i++] = status.login; ! 313: } ! 314: if(status.mpasswd[0]){ ! 315: a[i++] = "-p"; ! 316: a[i++] = status.mpasswd; ! 317: } ! 318: if(status.nonotify)a[i++] = "-b"; ! 319: if(status.force) a[i++] = "-f"; ! 320: if(status.quiet) a[i++] = "-q"; ! 321: if(status.nowrite) a[i++] = "-n"; ! 322: while(p[j])a[i++] = p[j++]; ! 323: a[i] = 0; ! 324: mexecl(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],a[10],a[11], ! 325: a[12],a[13],a[14],a[15],0); ! 326: } ! 327: ! 328: /* ! 329: MchSFromAddr(sn,addr) ! 330: ! 331: take an address of the form "mach:username" ! 332: and return mch as the 1 char code of "mach" and ! 333: in sn put "username". ! 334: If addr has no colon in it, return mch==local, sn==addr. ! 335: Return 0 for mch if host unknown. ! 336: */ ! 337: MchSFromAddr(sn,addr) ! 338: char *sn, *addr; ! 339: { ! 340: char fcolon = 0, *s, mch, stemp[BUFSIZ]; ! 341: ! 342: /* assume addr is a local address */ ! 343: ! 344: strcpy(stemp,addr); ! 345: s = stemp; ! 346: while(*s){ ! 347: if(*s == ':'){ ! 348: fcolon = 1; ! 349: *s++ = 0; ! 350: break; ! 351: } ! 352: s++; ! 353: } ! 354: if(fcolon != 1){ ! 355: /* sn better be the right size for addr */ ! 356: mch = local; ! 357: strcpy(sn,addr); ! 358: return(mch); ! 359: } ! 360: ! 361: /* addr has a colon in it, s pts to name */ ! 362: mch = lookup(stemp); ! 363: strcpy(sn,s); ! 364: return(mch); ! 365: } ! 366: ! 367: ! 368: /* returns a single character for machine S */ ! 369: /* returns 0 for unknown host */ ! 370: lookup(s) ! 371: register char *s; { ! 372: register struct tt *t; ! 373: if(strlen(s) == 1)return(isupper(*s) ? tolower(*s) : *s); ! 374: for(t = table; t->bigname; t++) ! 375: if(streql(s,t->bigname) == 0)return(t->lname); ! 376: return(0); ! 377: } ! 378: ! 379: /* returns a long name (string) for single character machine c */ ! 380: char *longname(c) ! 381: register char c; ! 382: { ! 383: register struct tt *t; ! 384: if(c == 0)return("UNKNOWN"); ! 385: for(t = table; t->bigname; t++) ! 386: if(c == t->lname)return(t->bigname); ! 387: return("UNKNOWN"); ! 388: } ! 389: /* ! 390: FMemberSCh(s,ch) ! 391: ! 392: return 1 if ch is a character in string s. ! 393: 0 otherwise. ! 394: */ ! 395: FMemberSCh(s,ch) ! 396: register char *s, ch; ! 397: { ! 398: while(*s)if(*s++ == ch)return(1); ! 399: return(0); ! 400: } ! 401: ! 402: /* return a static string with the form "X hrs X mins X secs" */ ! 403: /* t is # of secs */ ! 404: char *comptime(t) ! 405: long t; { ! 406: static char str[30]; ! 407: char buf[20]; ! 408: long w; ! 409: str[0] = 0; ! 410: w = t/3600L; ! 411: if(w > 0L){ ! 412: sprintf(buf,"%ld hr ",w); ! 413: strcat(str,buf); ! 414: } ! 415: t = t % 3600L; ! 416: w = t/60L; ! 417: if(w > 0L){ ! 418: sprintf(buf,"%ld min ",w); ! 419: strcat(str,buf); ! 420: } ! 421: t = t % 60L; ! 422: sprintf(buf,"%ld sec",t); ! 423: strcat(str,buf); ! 424: return(str); ! 425: } ! 426: /* ! 427: parseparmlist(string) ! 428: ! 429: parses variable parameter lists in string, ! 430: as defined in genparmlist in net.c ! 431: */ ! 432: parseparmlist(parmlist) ! 433: char *parmlist; ! 434: { ! 435: while(*parmlist && *parmlist != '(')parmlist++; ! 436: } ! 437: ! 438: /* just like strcmp except upper- and lower-case are ignored */ ! 439: streql(s1,s2) ! 440: char *s1, *s2; { ! 441: char a,b; ! 442: while(*s1 && *s2){ ! 443: a = isupper(*s1) ? tolower(*s1) : *s1; ! 444: b = isupper(*s2) ? tolower(*s2) : *s2; ! 445: if(a < b)return(-1); ! 446: if(a > b)return(1); ! 447: s1++, s2++; ! 448: } ! 449: if(*s2)return(-1); ! 450: if(*s1)return(1); ! 451: return(0); ! 452: } ! 453: /* VARARGS0 */ ! 454: err(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) { ! 455: fprintf(stderr,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r); ! 456: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.