BSD 4_1c_2 release
[unix-history] / usr / src / ucb / berknet / netrc.c
static char sccsid[] = "@(#)netrc.c 4.1 (Berkeley) 9/12/82";
/* sccs id variable */
static char *netrc_sid = "@(#)netrc.c 1.2";
/*
netrc.c
procedures to read and parse the .netrc file
You may call:
commandfile() to read the file.
rdnetfile(cfile) to read the file.
Note:
commandfile()
will read the passwd file
if getenv(HOME) searches the passwd file
Table of netrc options
option default
------ -------
default default machine
login string current login
password string -
notify yes/no yes
write yes/no yes
command string -
force yes/no no
Fabry has suggested that machine names be more general:
that you be able to say:
cory: fabry on Cory
caf: caf on Cory
c: fabry on C
so the formulation would look like:
default key
key: machine login passwd ...
key: ....
and so on
Gould has suggested the format be:
pseudo cory real Cory login fabry
pseudo caf real Cory login caf
pseudo c real C login fabry
Init file example:
format local C remote A
default A
machine A local C link /dev/net-A speed 9
machine Cory local C link /dev/net-Cory speed 9
if remote == 0, default is A
passwords work as follows:
passwd = "\n" means no password
*/
# include "defs.h"
/* tokens, returned by parser */
# define MACHINE 1
# define LOGIN 2
# define PASSWORD 3
# define ONLYUID 4
# define NOTIFY 5
# define QUIET 6
# define COMMAND 7
# define ID 8
# define YES 9
# define DEFAULT 10
# define WRITE 11
# define NO 12
# define FORCE 13
# define LOCALTOK 14
# define LINK 15
# define SPEED 16
# define LENGTH 18
# define DEBUGTOK 19
# define ALTIME 20
# define ALCOUNT 21
# define HISPEEDLINK 22
# define EIGHTBIT 23
# define INSPEED 24
# define OUTSPEED 25
/* global */
struct userinfo status;
struct daemonparms netd = {
LINKS, /* inspeed */
LINKS, /* outspeed */
MAXBREAD, /* maxbread */
ATIME, /* atime */
ATIME, /* oatime */
"/dev/null", /* device */
SIZE, /* datasize */
1, /* trynetl */
0 /* onlyuid */
/* rest are all zero */
};
/* local */
static char tokval[100];
static struct tokstruct {
char *tokstr;
int tval;
} toktab[]= {
"machine", MACHINE,
"login", LOGIN,
"password", PASSWORD,
"onlyuid", ONLYUID,
"notify", NOTIFY,
"command", COMMAND,
"yes", YES,
"y", YES,
"no", NO,
"n", NO,
"default", DEFAULT,
"write", WRITE,
"force", FORCE,
"quiet", QUIET,
"local", LOCALTOK,
"speed", SPEED,
"link", LINK,
"length", LENGTH,
"debug", DEBUGTOK,
"time", ALTIME,
"count", ALCOUNT,
"hispeedlink", HISPEEDLINK,
"8bit", EIGHTBIT,
"inspeed", INSPEED,
"outspeed", OUTSPEED,
0, 0
};
static struct stat statbuf;
/*
commandfile()
this procedure reads in and parses the .netrc file.
when you call this, if the remote machine is to be explicitely
set, the global variable "remote" must have a value.
on return, if it is non-zero, "remote" will have the
remote machine the data was collected for.
status.localname need not have a value.
*/
commandfile(){
char *hdir, buf[BUFSIZ];
FILE *cfile;
hdir = getenv("HOME");
if(hdir == NULL)hdir = ".";
sprintf(buf,"%s/.netrc",hdir);
/*
debug("file %s",buf);
*/
cfile = fopen(buf,"r");
if(cfile == NULL)return;
rdnetfile(cfile);
fclose(cfile);
}
/*
read the file cfile and parse
*/
rdnetfile(cfile)
FILE *cfile;
{
int t;
if(cfile == NULL)return;
if(fstat(fileno(cfile),&statbuf) < 0 || (statbuf.st_mode & 0444) == 0)
return;
while((t = token(cfile))){
switch(t){
case DEFAULT:
if(token(cfile) == ID && remote == 0)remote = lookup(tokval);
/*
debug("rem %c\n",remote);
*/
break;
case MACHINE:
if(remote == 0)remote = getremote(local);
if(token(cfile) != ID)continue;
if(remote != lookup(tokval))continue;
/* this is the entry for the remote mach we want */
getnetline(cfile);
return;
break;
}
}
return;
}
/*
read a line of the file
*/
static getnetline(cfile)
FILE *cfile;
{
int t;
while((t = token(cfile))){
switch(t){
/* these options are usually in the .netrc file */
case MACHINE: return;
case LOGIN:
if(token(cfile) && status.login[0] == 0)
strcpy(status.login,tokval);
break;
case PASSWORD:
if(fstat(fileno(cfile),&statbuf) >= 0
&& (statbuf.st_mode & 077) != 0){
err("Error - .netrc file not correct mode.\n");
err("Remove password or correct mode.\n");
exit(EX_USAGE);
}
if(token(cfile) && status.mpasswd[0] == 0)
strcpy(status.mpasswd,tokval);
/*
debug("mp:%s:%s\n",status.mpasswd,tokval);
*/
break;
case NOTIFY:
status.nonotify = token(cfile) == NO;
break;
case WRITE:
status.nowrite = token(cfile) == NO;
break;
case COMMAND:
if(token(cfile) && status.defcmd[0] == 0)
strcpy(status.defcmd,tokval);
break;
case QUIET:
status.quiet = token(cfile) == YES;
break;
case FORCE:
status.force = token(cfile) == YES;
break;
/* these options are usually in /usr/net/initfile */
case LOCALTOK:
if(token(cfile))local = lookup(tokval);
break;
case LINK:
if(token(cfile))strcpy(netd.dp_device,tokval);
break;
case SPEED:
if(token(cfile))
netd.dp_inspeed = netd.dp_outspeed=atoi(tokval);
break;
case INSPEED:
if(token(cfile))netd.dp_inspeed = atoi(tokval);
break;
case OUTSPEED:
if(token(cfile))netd.dp_outspeed = atoi(tokval);
break;
case LENGTH:
if(token(cfile))netd.dp_datasize = atoi(tokval);
break;
case DEBUGTOK:
debugflg++;
break;
case ALTIME:
if(token(cfile))netd.dp_oatime = atoi(tokval);
break;
case ALCOUNT:
if(token(cfile))netd.dp_maxbread = atoi(tokval);
break;
case ONLYUID:
if(token(cfile))netd.dp_onlyuid = atoi(tokval);
break;
case EIGHTBIT:
netd.dp_use8bit++;
break;
case HISPEEDLINK:
if(token(cfile))strcpy(netd.dp_hispeedlink,tokval);
break;
default:
err("Unknown .netrc option %s\n",tokval);
break;
}
}
}
static token(cfile)
FILE *cfile;
{ /* returns next token in cfile, 0 on EOF */
char *p;
int c;
if(feof(cfile))return(0);
while((c = getc(cfile)) != EOF && (c == '\n' || c == '\t'
|| c == ' ' || c == ','));
/* next char begins token */
if(c == EOF)return(0);
p = tokval;
if(c == '"'){ /* process quoted string */
while((c = getc(cfile)) != EOF && c != '"'){
if(c == '\\')c = getc(cfile);
*p++ = c;
}
}
else {
*p++ = c;
while((c = getc(cfile)) != EOF && c != '\n' && c != '\t'
&& c != ' ' && c != ','){
if(c == '\\')c = getc(cfile);
*p++ = c;
}
}
*p = 0;
if(tokval[0] == 0)return(0);
/*
debug("tok %s",tokval);
*/
return(tlookup(tokval));
}
static tlookup(str)
char *str; {
struct tokstruct *p;
for(p = toktab; p->tokstr; p++)
if(streql(p->tokstr,str) == 0){
return(p->tval);
}
return(ID);
}