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