BSD 4_3_Reno release
[unix-history] / usr / src / old / berknet / netrc.c
CommitLineData
1c15e888 1static char sccsid[] = "@(#)netrc.c 4.1 (Berkeley) 9/12/82";
fcec3d5e
KM
2
3/* sccs id variable */
4static char *netrc_sid = "@(#)netrc.c 1.2";
5/*
6
7 netrc.c
8
9 procedures to read and parse the .netrc file
10
11 You may call:
12 commandfile() to read the file.
13 rdnetfile(cfile) to read the file.
14
15Note:
16 commandfile()
17 will read the passwd file
18 if getenv(HOME) searches the passwd file
19
20Table of netrc options
21 option default
22 ------ -------
23 default default machine
24 login string current login
25 password string -
26 notify yes/no yes
27 write yes/no yes
28 command string -
29 force yes/no no
30
31Fabry has suggested that machine names be more general:
32that you be able to say:
33
34 cory: fabry on Cory
35 caf: caf on Cory
36 c: fabry on C
37
38so the formulation would look like:
39
40 default key
41 key: machine login passwd ...
42 key: ....
43
44and so on
45
46Gould has suggested the format be:
47
48 pseudo cory real Cory login fabry
49 pseudo caf real Cory login caf
50 pseudo c real C login fabry
51
52Init file example:
53format local C remote A
54
55 default A
56 machine A local C link /dev/net-A speed 9
57 machine Cory local C link /dev/net-Cory speed 9
58
59if remote == 0, default is A
60
61passwords work as follows:
62 passwd = "\n" means no password
63
64*/
65# include "defs.h"
66
67/* tokens, returned by parser */
68# define MACHINE 1
69# define LOGIN 2
70# define PASSWORD 3
71# define ONLYUID 4
72# define NOTIFY 5
73# define QUIET 6
74# define COMMAND 7
75# define ID 8
76# define YES 9
77# define DEFAULT 10
78# define WRITE 11
79# define NO 12
80# define FORCE 13
81# define LOCALTOK 14
82# define LINK 15
83# define SPEED 16
84# define LENGTH 18
85# define DEBUGTOK 19
86# define ALTIME 20
87# define ALCOUNT 21
88# define HISPEEDLINK 22
89# define EIGHTBIT 23
90# define INSPEED 24
91# define OUTSPEED 25
92
93/* global */
94struct userinfo status;
95struct daemonparms netd = {
96 LINKS, /* inspeed */
97 LINKS, /* outspeed */
98 MAXBREAD, /* maxbread */
99 ATIME, /* atime */
100 ATIME, /* oatime */
101 "/dev/null", /* device */
102 SIZE, /* datasize */
103 1, /* trynetl */
104 0 /* onlyuid */
105 /* rest are all zero */
106};
107
108/* local */
109static char tokval[100];
110
111static struct tokstruct {
112 char *tokstr;
113 int tval;
114} toktab[]= {
115 "machine", MACHINE,
116 "login", LOGIN,
117 "password", PASSWORD,
118 "onlyuid", ONLYUID,
119 "notify", NOTIFY,
120 "command", COMMAND,
121 "yes", YES,
122 "y", YES,
123 "no", NO,
124 "n", NO,
125 "default", DEFAULT,
126 "write", WRITE,
127 "force", FORCE,
128 "quiet", QUIET,
129 "local", LOCALTOK,
130 "speed", SPEED,
131 "link", LINK,
132 "length", LENGTH,
133 "debug", DEBUGTOK,
134 "time", ALTIME,
135 "count", ALCOUNT,
136 "hispeedlink", HISPEEDLINK,
137 "8bit", EIGHTBIT,
138 "inspeed", INSPEED,
139 "outspeed", OUTSPEED,
140 0, 0
141 };
142
143static struct stat statbuf;
144
145/*
146 commandfile()
147
148 this procedure reads in and parses the .netrc file.
149 when you call this, if the remote machine is to be explicitely
150 set, the global variable "remote" must have a value.
151 on return, if it is non-zero, "remote" will have the
152 remote machine the data was collected for.
153 status.localname need not have a value.
154*/
155commandfile(){
156 char *hdir, buf[BUFSIZ];
157 FILE *cfile;
158 hdir = getenv("HOME");
159 if(hdir == NULL)hdir = ".";
160 sprintf(buf,"%s/.netrc",hdir);
161/*
162 debug("file %s",buf);
163*/
164 cfile = fopen(buf,"r");
165 if(cfile == NULL)return;
166 rdnetfile(cfile);
167 fclose(cfile);
168 }
169/*
170 read the file cfile and parse
171*/
172rdnetfile(cfile)
173 FILE *cfile;
174{
175 int t;
176 if(cfile == NULL)return;
177 if(fstat(fileno(cfile),&statbuf) < 0 || (statbuf.st_mode & 0444) == 0)
178 return;
179 while((t = token(cfile))){
180 switch(t){
181 case DEFAULT:
182 if(token(cfile) == ID && remote == 0)remote = lookup(tokval);
183 /*
184 debug("rem %c\n",remote);
185 */
186 break;
187 case MACHINE:
188 if(remote == 0)remote = getremote(local);
189 if(token(cfile) != ID)continue;
190 if(remote != lookup(tokval))continue;
191 /* this is the entry for the remote mach we want */
192 getnetline(cfile);
193 return;
194 break;
195 }
196 }
197 return;
198 }
199/*
200 read a line of the file
201*/
202static getnetline(cfile)
203 FILE *cfile;
204{
205 int t;
206 while((t = token(cfile))){
207 switch(t){
208 /* these options are usually in the .netrc file */
209 case MACHINE: return;
210 case LOGIN:
211 if(token(cfile) && status.login[0] == 0)
212 strcpy(status.login,tokval);
213 break;
214 case PASSWORD:
215 if(fstat(fileno(cfile),&statbuf) >= 0
216 && (statbuf.st_mode & 077) != 0){
217 err("Error - .netrc file not correct mode.\n");
218 err("Remove password or correct mode.\n");
219 exit(EX_USAGE);
220 }
221 if(token(cfile) && status.mpasswd[0] == 0)
222 strcpy(status.mpasswd,tokval);
223 /*
224 debug("mp:%s:%s\n",status.mpasswd,tokval);
225 */
226 break;
227 case NOTIFY:
228 status.nonotify = token(cfile) == NO;
229 break;
230 case WRITE:
231 status.nowrite = token(cfile) == NO;
232 break;
233 case COMMAND:
234 if(token(cfile) && status.defcmd[0] == 0)
235 strcpy(status.defcmd,tokval);
236 break;
237 case QUIET:
238 status.quiet = token(cfile) == YES;
239 break;
240 case FORCE:
241 status.force = token(cfile) == YES;
242 break;
243
244 /* these options are usually in /usr/net/initfile */
245 case LOCALTOK:
246 if(token(cfile))local = lookup(tokval);
247 break;
248 case LINK:
249 if(token(cfile))strcpy(netd.dp_device,tokval);
250 break;
251 case SPEED:
252 if(token(cfile))
253 netd.dp_inspeed = netd.dp_outspeed=atoi(tokval);
254 break;
255 case INSPEED:
256 if(token(cfile))netd.dp_inspeed = atoi(tokval);
257 break;
258 case OUTSPEED:
259 if(token(cfile))netd.dp_outspeed = atoi(tokval);
260 break;
261 case LENGTH:
262 if(token(cfile))netd.dp_datasize = atoi(tokval);
263 break;
264 case DEBUGTOK:
265 debugflg++;
266 break;
267 case ALTIME:
268 if(token(cfile))netd.dp_oatime = atoi(tokval);
269 break;
270 case ALCOUNT:
271 if(token(cfile))netd.dp_maxbread = atoi(tokval);
272 break;
273 case ONLYUID:
274 if(token(cfile))netd.dp_onlyuid = atoi(tokval);
275 break;
276 case EIGHTBIT:
277 netd.dp_use8bit++;
278 break;
279 case HISPEEDLINK:
280 if(token(cfile))strcpy(netd.dp_hispeedlink,tokval);
281 break;
282 default:
283 err("Unknown .netrc option %s\n",tokval);
284 break;
285 }
286 }
287 }
288static token(cfile)
289 FILE *cfile;
290{ /* returns next token in cfile, 0 on EOF */
291 char *p;
292 int c;
293 if(feof(cfile))return(0);
294 while((c = getc(cfile)) != EOF && (c == '\n' || c == '\t'
295 || c == ' ' || c == ','));
296 /* next char begins token */
297 if(c == EOF)return(0);
298 p = tokval;
299 if(c == '"'){ /* process quoted string */
300 while((c = getc(cfile)) != EOF && c != '"'){
301 if(c == '\\')c = getc(cfile);
302 *p++ = c;
303 }
304 }
305 else {
306 *p++ = c;
307 while((c = getc(cfile)) != EOF && c != '\n' && c != '\t'
308 && c != ' ' && c != ','){
309 if(c == '\\')c = getc(cfile);
310 *p++ = c;
311 }
312 }
313 *p = 0;
314 if(tokval[0] == 0)return(0);
315/*
316 debug("tok %s",tokval);
317*/
318 return(tlookup(tokval));
319 }
320static tlookup(str)
321 char *str; {
322 struct tokstruct *p;
323 for(p = toktab; p->tokstr; p++)
324 if(streql(p->tokstr,str) == 0){
325 return(p->tval);
326 }
327 return(ID);
328 }