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

Defined functions

FMemberSCh defined in line 438; used 4 times
chtoinx defined in line 232; used 39 times
err defined in line 497; used 19 times
mexecv defined in line 327; used 3 times
streql defined in line 482; used 4 times

Defined variables

Bsh defined in line 33; used 1 times
  • in line 77
debugflg defined in line 26; used 4 times
local defined in line 27; used 2 times
netcmd defined in line 30; never used
popen_pid defined in line 137; used 2 times
resfile defined in line 31; never used
sccsid defined in line 1; never used
senddir defined in line 32; never used
shomedir defined in line 35; used 1 times
  • in line 75
status defined in line 28; used 37 times

Defined macros

NPARMS defined in line 299; used 6 times
RDR defined in line 135; used 2 times
WTR defined in line 136; used 2 times
tst defined in line 134; used 2 times
Last modified: 1983-01-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2115
Valid CSS Valid XHTML 1.0 Strict