Commit | Line | Data |
---|---|---|
1c15e888 | 1 | static char sccsid[] = "@(#)netrc.c 4.1 (Berkeley) 9/12/82"; |
fcec3d5e KM |
2 | |
3 | /* sccs id variable */ | |
4 | static 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 | ||
15 | Note: | |
16 | commandfile() | |
17 | will read the passwd file | |
18 | if getenv(HOME) searches the passwd file | |
19 | ||
20 | Table 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 | ||
31 | Fabry has suggested that machine names be more general: | |
32 | that you be able to say: | |
33 | ||
34 | cory: fabry on Cory | |
35 | caf: caf on Cory | |
36 | c: fabry on C | |
37 | ||
38 | so the formulation would look like: | |
39 | ||
40 | default key | |
41 | key: machine login passwd ... | |
42 | key: .... | |
43 | ||
44 | and so on | |
45 | ||
46 | Gould 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 | ||
52 | Init file example: | |
53 | format 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 | ||
59 | if remote == 0, default is A | |
60 | ||
61 | passwords 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 */ | |
94 | struct userinfo status; | |
95 | struct 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 */ | |
109 | static char tokval[100]; | |
110 | ||
111 | static 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 | ||
143 | static 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 | */ | |
155 | commandfile(){ | |
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 | */ | |
172 | rdnetfile(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 | */ | |
202 | static 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 | } | |
288 | static 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 | } | |
320 | static 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 | } |