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 'y':   i = configY[to-'a']; break;
 245:     case 'z':   i = configZ[to-'a']; break;
 246: # endif
 247:     default:    i = 0; break;
 248:     }
 249:     return(i);
 250:     }
 251: /*
 252: 	harg(string,pargc,pargv)
 253: 
 254: 	A curious procedure which takes a pointer to an argc, and a
 255: 	pointer to an argv, and parses them so that the
 256: 	argument following the flag is copied into string.
 257: 	pargv[0] must be the flag argument.
 258: 	handles both
 259: 		-my
 260: 	and
 261: 		-m y
 262: 	for the net command.
 263: */
 264: harg(ans,pargc,pargv)
 265:   char *ans,*pargc,***pargv;{
 266:     if((*pargv)[0][2])      /* no space */
 267:         strcpy(ans,(*pargv)[0] + 2);
 268:     else {              /* space, get next arg */
 269:         strcpy(ans,(*pargv)[1]);
 270:         (*pargc)--;
 271:         (*pargv)++;
 272:         }
 273:     }
 274: 
 275: /* prints out commands before executing them */
 276: /*VARARGS0*/
 277: mexecl(s)
 278:   char *s;{
 279:     int *p = (int *)&s;
 280:     register int i;
 281:     if(debugflg){
 282:         for(i=0; p[i]; i++)err("%s ",p[i]);
 283:         putc('\n',stderr);
 284:         }
 285:     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],
 286:     p[12],p[13],p[14],p[15],0);
 287:     }
 288: /* prints out commands before executing them */
 289: mexecv(s,p)
 290:   register char *s, **p;{
 291:     register int i;
 292:     if(debugflg){
 293:         err("%s ",s);
 294:         for(i=0; p[i]; i++)err("%s ",p[i]);
 295:         putc('\n',stderr);
 296:         }
 297:     execv(s,p);
 298:     }
 299: 
 300: /*VARARGS0*/
 301: /* fills in -l - -p from commands like rcp */
 302: /* must be called with at least two arguments */
 303: kexecl(s)
 304:   char *s;  {
 305:     char *a[20], i = 2, j = 2;
 306:     char **p = (char **)&s;
 307:     a[0] = p[0];
 308:     a[1] = p[1];
 309:     if(status.login[0]){
 310:         a[i++] = "-l";
 311:         a[i++] = status.login;
 312:         }
 313:     if(status.mpasswd[0]){
 314:         a[i++] = "-p";
 315:         a[i++] = status.mpasswd;
 316:         }
 317:     if(status.nonotify)a[i++] = "-b";
 318:     if(status.force)   a[i++] = "-f";
 319:     if(status.quiet)   a[i++] = "-q";
 320:     if(status.nowrite) a[i++] = "-n";
 321:     while(p[j])a[i++] = p[j++];
 322:     a[i] = 0;
 323:     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],
 324:     a[12],a[13],a[14],a[15],0);
 325:     }
 326: 
 327: /*
 328: 	MchSFromAddr(sn,addr)
 329: 
 330: 	take an address of the form "mach:username"
 331: 	and return mch as the 1 char code of "mach" and
 332: 	in sn put "username".
 333: 	If addr has no colon in it, return mch==local, sn==addr.
 334: 	Return 0 for mch if host unknown.
 335: */
 336: MchSFromAddr(sn,addr)
 337:     char *sn, *addr;
 338: {
 339:     char fcolon = 0, *s, mch, stemp[BUFSIZ];
 340: 
 341:     /* assume addr is a local address */
 342: 
 343:     strcpy(stemp,addr);
 344:     s = stemp;
 345:     while(*s){
 346:         if(*s == ':'){
 347:             fcolon = 1;
 348:             *s++ = 0;
 349:             break;
 350:         }
 351:         s++;
 352:     }
 353:     if(fcolon != 1){
 354:         /* sn better be the right size for addr */
 355:         mch = local;
 356:         strcpy(sn,addr);
 357:         return(mch);
 358:     }
 359: 
 360:     /* addr has a colon in it, s pts to name */
 361:     mch = lookup(stemp);
 362:     strcpy(sn,s);
 363:     return(mch);
 364: }
 365: 
 366: 
 367: /* returns a single character for machine S */
 368: /* returns 0 for unknown host */
 369: lookup(s)
 370:   register char *s; {
 371:     register struct tt *t;
 372:     if(strlen(s) == 1)return(isupper(*s) ? tolower(*s) : *s);
 373:     for(t = table; t->bigname; t++)
 374:         if(streql(s,t->bigname) == 0)return(t->lname);
 375:     return(0);
 376:     }
 377: 
 378: /* returns a long name (string) for single character machine c */
 379: char *longname(c)
 380:   register char c;
 381:     {
 382:     register struct tt *t;
 383:     if(c == 0)return("UNKNOWN");
 384:     for(t = table; t->bigname; t++)
 385:         if(c == t->lname)return(t->bigname);
 386:     return("UNKNOWN");
 387:     }
 388: /*
 389: 	FMemberSCh(s,ch)
 390: 
 391: 	return 1 if ch is a character in string s.
 392: 	0 otherwise.
 393: */
 394: FMemberSCh(s,ch)
 395:     register char *s, ch;
 396: {
 397:     while(*s)if(*s++ == ch)return(1);
 398:     return(0);
 399: }
 400: 
 401: /* return a static string with the form "X hrs X mins X secs" */
 402: /* t is # of secs */
 403: char *comptime(t)
 404:   long t; {
 405:     static char str[30];
 406:     char buf[20];
 407:     long w;
 408:     str[0] = 0;
 409:     w = t/3600L;
 410:     if(w > 0L){
 411:         sprintf(buf,"%ld hr ",w);
 412:         strcat(str,buf);
 413:         }
 414:     t = t % 3600L;
 415:     w = t/60L;
 416:     if(w > 0L){
 417:         sprintf(buf,"%ld min ",w);
 418:         strcat(str,buf);
 419:         }
 420:     t = t % 60L;
 421:     sprintf(buf,"%ld sec",t);
 422:     strcat(str,buf);
 423:     return(str);
 424:     }
 425: /*
 426: 	parseparmlist(string)
 427: 
 428: 	parses variable parameter lists in string,
 429: 	as defined in genparmlist in net.c
 430: */
 431: parseparmlist(parmlist)
 432:     char *parmlist;
 433: {
 434:     while(*parmlist && *parmlist != '(')parmlist++;
 435: }
 436: 
 437: /* just like strcmp except upper- and lower-case are ignored */
 438: streql(s1,s2)
 439:   char *s1, *s2; {
 440:     char a,b;
 441:     while(*s1 && *s2){
 442:         a = isupper(*s1) ? tolower(*s1) : *s1;
 443:         b = isupper(*s2) ? tolower(*s2) : *s2;
 444:         if(a < b)return(-1);
 445:         if(a > b)return(1);
 446:         s1++, s2++;
 447:         }
 448:     if(*s2)return(-1);
 449:     if(*s1)return(1);
 450:     return(0);
 451:     }
 452: /* VARARGS0 */
 453: err(s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) {
 454:     fprintf(stderr,s,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r);
 455:     }

Defined functions

FMemberSCh defined in line 394; used 4 times
err defined in line 453; used 15 times
mexecv defined in line 289; used 2 times
streql defined in line 438; used 4 times

Defined variables

Bsh defined in line 30; used 1 times
  • in line 58
debugflg defined in line 23; used 2 times
local defined in line 24; used 2 times
netcmd defined in line 27; never used
popen_pid defined in line 120; used 2 times
resfile defined in line 28; never used
senddir defined in line 29; never used
shomedir defined in line 32; used 1 times
  • in line 56
status defined in line 25; used 38 times

Defined macros

RDR defined in line 118; used 2 times
WTR defined in line 119; used 2 times
tst defined in line 117; used 2 times
Last modified: 1980-07-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1394
Valid CSS Valid XHTML 1.0 Strict