static char sccsid
[] = "@(#)sub.c 4.5 (Berkeley) 1/5/83";
the following procedures end up reading the passwd file
or the passwdf file and are to be avoided.
getenv("HOME") maybe if hget, hgethome don't work
SnFromUid(uid) maybe if hashed passwd stuff doesn't work
SnCurrent() maybe if getlogin fails calls SnFromUid(uid)
int debugflg
= DBV
; /* debug flag */
char local
= LOCAL
; /* the machine we're on */
char resfile
[] = RESFILE
;
char senddir
[] = SENDDIR
;
Read the password file looking for current user's entry.
Fill in the status structure.
Has the (dangerous) side effect of giving a value to getenv("HOME").
register struct passwd
*pwd
;
register struct gecos
*gcos
;
err("Bad uid/username\n");
strcpy(status
.localname
,pwd
->pw_name
);
status
.muid
= guid(pwd
->pw_uid
,pwd
->pw_gid
);
status
.mgid
= pwd
->pw_gid
;
if( (gcos
=pwgecos( pwd
->pw_gecos
) ) == NULL
)
strcpy( status
.jobno
, MAGICCRN
);
debug( "crn found = %s\n", gcos
->gc_crn
);
if( isalpha( gcos
->gc_crn
[0] ) ||
isdigit( gcos
->gc_crn
[0] ) )
strcpy( status
.jobno
, gcos
->gc_crn
);
strcpy( status
.jobno
, MAGICCRN
);
strcpy( status
.jobno
, "XYZZ" );
strcpy(status
.dir
,pwd
->pw_dir
);
strcpy(shomedir
,pwd
->pw_dir
); /* side effect */
if(u
[0] == 0 || strcmp(u
,"/bin/sbash") == 0)u
= Bsh
;
strcpy(status
.loginshell
,u
);
ask user for login and passwd on mchto.
make sure status.localname has a value before calling
this. One way is to call passwdent().
if(status
.login
[0]==0 || status
.force
){
wf
= fopen("/dev/tty","r");
fprintf(stderr
,"Name (%s:%s): ",longname(mchto
),
if(fgets(buf
, BUFSIZ
, wf
) != buf
){
buf
[c
> 0 ? c
-1 : 0] = 0;
err("Login name too long.\n");
err("Login names don't have blanks in them.\n");
if(buf
[0] == 0)strcpy(buf
,status
.localname
);
mch
= MchSFromAddr(status
.login
,buf
);
if(mch
!= local
&& mch
!= mchto
){
err("Must specify login name on %s machine\n",
if(strcmp(status
.login
,"network") != 0
&& (status
.mpasswd
[0]== 0 || status
.force
)){
sprintf(buf
,"Password (%s:%s):",
longname(mchto
), status
.login
);
strcpy(status
.mpasswd
,getpass(buf
));
if(status
.login
[0] == 0) strcpy(status
.login
,status
.localname
);
if(status
.mpasswd
[0] == 0)strcpy(status
.mpasswd
,"\"\"");
#define tst(a,b) (*mode == 'r'? (b) : (a))
static int popen_pid
[20];
/* return a file descriptor suitable for writing, send to
user toaddress from fromaddress,
if cautious != 0 then don't do any forwarding
hopcnt is passed thru the mail program.
mailopen(toaddress
, fromaddress
, cautious
, hopcnt
)
char *toaddress
, *fromaddress
;
register myside
, hisside
, pid
;
myside
= tst(p
[WTR
], p
[RDR
]);
hisside
= tst(p
[RDR
], p
[WTR
]);
while((pid
= fork()) == -1)sleep(2);
/* myside and hisside reverse roles in child */
dup2(hisside, tst(0, 1));
sprintf(shopcnt
,"%d",hopcnt
);
/* by convention, MAILFWD1 may forward this mail
and response messages shouldn't be forwarded */
if(!cautious
&& !FMemberSCh(toaddress
,'/')){
mexecl("/usr/lib/sendmail",
"sendmail", "-oee", "-r", fromaddress
,
"-h",shopcnt
, toaddress
, 0);
mexecl(MAILFWD1
, "mail","-r",fromaddress
,
"-h",shopcnt
,toaddress
,0);
mexecl(SYSMAIL2
, "mail","-d","-r",fromaddress
,
"-h", shopcnt
,toaddress
,0);
if(!cautious
&& !FMemberSCh(toaddress
,'/')){
mexecl("/usr/lib/sendmail",
"sendmail", "-ee", "-h", shopcnt
,
mexecl(MAILFWD1
, "mail","-h", shopcnt
,
mexecl(SYSMAIL2
, "mail","-d","-h", shopcnt
,toaddress
,0);
return(fdopen(myside
, mode
));
register f
, r
, (*hstat
)(), (*istat
)(), (*qstat
)();
istat
= signal(SIGINT
, SIG_IGN
);
qstat
= signal(SIGQUIT
, SIG_IGN
);
hstat
= signal(SIGHUP
, SIG_IGN
);
while((r
= wait(&status
)) != popen_pid
[f
] && r
!= -1)
ch means 'a'-'z', inx in 0..25
ch means '0'-'9', inx in 26..35
if('a' <= ch
&& ch
<= 'z')
if('0' <= ch
&& ch
<= '9')
inx is 0..25 means 'a'-'z'
inx is 26..35 means '0'-'9'
if(0 <= inx
&& inx
<= 25)
if(26 <= inx
&& inx
<= 35)
return('0' + (inx
- 26));
/* determine through machine */
case 'a': i
= configA
[chtoinx(to
)]; break;
case 'b': i
= configB
[chtoinx(to
)]; break;
case 'c': i
= configC
[chtoinx(to
)]; break;
case 'a': i
= configA
[chtoinx(to
)]; break;
case 'c': i
= configC
[chtoinx(to
)]; break;
case 'm': i
= configM
[chtoinx(to
)]; break;
case 'a': i
= configA
[chtoinx(to
)]; break;
case 'b': i
= configB
[chtoinx(to
)]; break;
case 'c': i
= configC
[chtoinx(to
)]; break;
case 'd': i
= configD
[chtoinx(to
)]; break;
case 'e': i
= configE
[chtoinx(to
)]; break;
case 'f': i
= configF
[chtoinx(to
)]; break;
case 'g': i
= configG
[chtoinx(to
)]; break;
case 'h': i
= configH
[chtoinx(to
)]; break;
case 'i': i
= configI
[chtoinx(to
)]; break;
case 'j': i
= configJ
[chtoinx(to
)]; break;
case 'k': i
= configK
[chtoinx(to
)]; break;
case 'l': i
= configL
[chtoinx(to
)]; break;
case 'm': i
= configM
[chtoinx(to
)]; break;
case 'n': i
= configN
[chtoinx(to
)]; break;
case 'o': i
= configO
[chtoinx(to
)]; break;
case 'p': i
= configP
[chtoinx(to
)]; break;
case 'r': i
= configR
[chtoinx(to
)]; break;
case 's': i
= configS
[chtoinx(to
)]; break;
case 't': i
= configT
[chtoinx(to
)]; break;
case 'u': i
= configU
[chtoinx(to
)]; break;
case 'v': i
= configV
[chtoinx(to
)]; break;
case 'w': i
= configW
[chtoinx(to
)]; break;
case 'x': i
= configX
[chtoinx(to
)]; break;
case 'y': i
= configY
[chtoinx(to
)]; break;
case 'z': i
= configZ
[chtoinx(to
)]; break;
/* prints out commands before executing them */
char *arr
[NPARMS
], *file
, *f
;
file
= va_arg(ap
, char *);
while(f
= va_arg(ap
, char *)){
if(debugflg
) err("'%s' ",f
);
if(debugflg
) putc('\n',stderr
);
/* prints out commands before executing them */
for(i
=0; p
[i
]; i
++)err("'%s' ",p
[i
]);
/* fills in -l - -p from commands like rcp */
/* must be called with at least two arguments */
char *a
[NPARMS
], i
= 1, *file
;
file
= va_arg(ap
, char *);
a
[0] = va_arg(ap
, char *);
if(status
.nonotify
)a
[i
++] = "-b";
if(status
.force
) a
[i
++] = "-f";
if(status
.quiet
) a
[i
++] = "-q";
if(status
.nowrite
) a
[i
++] = "-n";
while (a
[i
++] = va_arg(ap
, char *)){
take an address of the form "mach:username"
and return mch as the 1 char code of "mach" and
If addr has no colon in it, return mch==local, sn==addr.
Return 0 for mch if host unknown.
char fcolon
= 0, *s
, mch
, stemp
[BUFSIZ
];
/* assume addr is a local address */
/* sn better be the right size for addr */
/* addr has a colon in it, s pts to name */
/* returns a single character for machine S */
/* returns 0 for unknown host */
if(strlen(s
) == 1)return(isupper(*s
) ? tolower(*s
) : *s
);
for(t
= table
; t
->bigname
; t
++)
if(streql(s
,t
->bigname
) == 0)return(t
->lname
);
/* returns a long name (string) for single character machine c */
if(c
== 0)return("UNKNOWN");
for(t
= table
; t
->bigname
; t
++)
if(c
== t
->lname
)return(t
->bigname
);
return 1 if ch is a character in string s.
while(*s
)if(*s
++ == ch
)return(1);
/* return a static string with the form "X hrs X mins X secs" */
sprintf(buf
,"%ld hr ",w
);
sprintf(buf
,"%ld min ",w
);
sprintf(buf
,"%ld sec",t
);
parses variable parameter lists in string,
as defined in genparmlist in net.c
while(*parmlist
&& *parmlist
!= '(')parmlist
++;
/* just like strcmp except upper- and lower-case are ignored */
a
= isupper(*s1
) ? tolower(*s1
) : *s1
;
b
= isupper(*s2
) ? tolower(*s2
) : *s2
;
err(s
,a
,b
,c
,d
,e
,f
,g
,h
,i
,j
,k
,l
,m
,n
,o
,p
,q
,r
) {
fprintf(stderr
,s
,a
,b
,c
,d
,e
,f
,g
,h
,i
,j
,k
,l
,m
,n
,o
,p
,q
,r
);