|
|
1.1 root 1: static char sccsid[] = "@(#)netrc.c 4.1 (Berkeley) 9/12/82";
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.