|
|
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: also options:
56: vaxtovax, length, debug
57:
58: speed: speeds baud setting
59: 300 7
60: 1200 9
61: 9600 13
62: onlyuid:
63: should be a decimal uid, as returned by getuid()
64: if 0 is considered ignored.
65:
66: passwords work as follows:
67: passwd = "\n" means no password
68:
69: */
70: # include "defs.h"
71:
72: /* tokens, returned by parser */
73: # define MACHINE 1
74: # define LOGIN 2
75: # define PASSWORD 3
76: # define ONLYUID 4
77: # define NOTIFY 5
78: # define COMMAND 7
79: # define ID 8
80: # define YES 9
81: # define DEFAULT 10
82: # define WRITE 11
83: # define NO 12
84: # define FORCE 13
85: # define LOCALTOK 14
86: # define LINK 15
87: # define SPEED 16
88: # define VAXTOVAX 17
89: # define LENGTH 18
90: # define DEBUGTOK 19
91: # define ALTIME 20
92: # define ALCOUNT 21
93:
94: /* global */
95: char vaxtovax;
96: int linkspeed;
97: char local;
98: int maxbread;
99: int atime;
100: char device[20];
101: int datasize;
102: int onlyuid = 0;
103:
104: /* local */
105: static char tokval[BUFSIZ];
106:
107: static struct tokstruct {
108: char *tokstr;
109: int tval;
110: } toktab[]= {
111: "machine", MACHINE,
112: "login", LOGIN,
113: "password", PASSWORD,
114: "onlyuid", ONLYUID,
115: "notify", NOTIFY,
116: "command", COMMAND,
117: "yes", YES,
118: "y", YES,
119: "no", NO,
120: "n", NO,
121: "default", DEFAULT,
122: "write", WRITE,
123: "force", FORCE,
124: "local", LOCALTOK,
125: "speed", SPEED,
126: "link", LINK,
127: "vaxtovax", VAXTOVAX,
128: "length", LENGTH,
129: "debug", DEBUGTOK,
130: "time", ALTIME,
131: "count", ALCOUNT,
132: 0, 0
133: };
134:
135: static struct stat statbuf;
136:
137: /*
138: commandfile()
139:
140: this procedure reads in and parses the .netrc file.
141: when you call this, if the remote machine is to be explicitely
142: set, the global variable "remote" must have a value.
143: on return, if it is non-zero, "remote" will have the
144: remote machine the data was collected for.
145: status.localname need not have a value.
146: */
147: commandfile(){
148: char *hdir, buf[BUFSIZ];
149: FILE *cfile;
150: hdir = getenv("HOME");
151: if(hdir == NULL)hdir = ".";
152: sprintf(buf,"%s/.netrc",hdir);
153: /*
154: debug("file %s",buf);
155: */
156: cfile = fopen(buf,"r");
157: if(cfile == NULL)return;
158: rdnetfile(cfile);
159: fclose(cfile);
160: }
161: /*
162: read the file cfile and parse
163: */
164: rdnetfile(cfile)
165: FILE *cfile;
166: {
167: int t;
168: if(cfile == NULL)return;
169: if(fstat(fileno(cfile),&statbuf) < 0 || (statbuf.st_mode & 0444) == 0)
170: return;
171: while((t = token(cfile))){
172: switch(t){
173: case DEFAULT:
174: if(token(cfile) == ID && remote == 0)remote = lookup(tokval);
175: /*
176: debug("rem %c\n",remote);
177: */
178: break;
179: case MACHINE:
180: if(remote == 0)remote = getremote(local);
181: if(token(cfile) != ID)continue;
182: if(remote != lookup(tokval))continue;
183: /* this is the entry for the remote mach we want */
184: getnetline(cfile);
185: return;
186: break;
187: }
188: }
189: return;
190: }
191: /*
192: read a line of the file
193: */
194: static getnetline(cfile)
195: FILE *cfile;
196: {
197: int t;
198: while((t = token(cfile))){
199: switch(t){
200: /* these options are usually in the .netrc file */
201: case MACHINE: return;
202: case LOGIN:
203: if(token(cfile) && status.login[0] == 0)
204: strcpy(status.login,tokval);
205: break;
206: case PASSWORD:
207: if(fstat(fileno(cfile),&statbuf) >= 0
208: && (statbuf.st_mode & 077) != 0){
209: err("Error - .netrc file not correct mode.\n");
210: err("Remove password or correct mode.\n");
211: exit(1);
212: }
213: if(token(cfile) && status.mpasswd[0] == 0)
214: strcpy(status.mpasswd,tokval);
215: /*
216: debug("mp:%s:%s\n",status.mpasswd,tokval);
217: */
218: break;
219: case NOTIFY:
220: status.nonotify = token(cfile) == NO;
221: break;
222: case WRITE:
223: status.nowrite = token(cfile) == NO;
224: break;
225: case COMMAND:
226: if(token(cfile) && status.defcmd[0] == 0)
227: strcpy(status.defcmd,tokval);
228: break;
229: case FORCE:
230: status.force = token(cfile) == YES;
231: break;
232:
233: /* these options are usually in /usr/net/initfile */
234: case LOCALTOK:
235: if(token(cfile))local = lookup(tokval);
236: break;
237: case LINK:
238: if(token(cfile))strcpy(device,tokval);
239: break;
240: case SPEED:
241: if(token(cfile))linkspeed = atoi(tokval);
242: break;
243: case VAXTOVAX:
244: vaxtovax++;
245: break;
246: case LENGTH:
247: if(token(cfile))datasize = atoi(tokval);
248: break;
249: case DEBUGTOK:
250: debugflg++;
251: break;
252: case ALTIME:
253: if(token(cfile))atime = atoi(tokval);
254: break;
255: case ALCOUNT:
256: if(token(cfile))maxbread = atoi(tokval);
257: break;
258: case ONLYUID:
259: if(token(cfile))onlyuid = atoi(tokval);
260: break;
261: default:
262: err("Unknown .netrc option %s\n",tokval);
263: break;
264: }
265: }
266: }
267: static token(cfile)
268: FILE *cfile;
269: { /* returns next token in cfile, 0 on EOF */
270: char *p;
271: int c;
272: if(feof(cfile))return(0);
273: while((c = getc(cfile)) != EOF && (c == '\n' || c == '\t'
274: || c == ' ' || c == ','));
275: /* next char begins token */
276: if(c == EOF)return(0);
277: p = tokval;
278: if(c == '"'){ /* process quoted string */
279: while((c = getc(cfile)) != EOF && c != '"'){
280: if(c == '\\')c = getc(cfile);
281: *p++ = c;
282: }
283: }
284: else {
285: *p++ = c;
286: while((c = getc(cfile)) != EOF && c != '\n' && c != '\t'
287: && c != ' ' && c != ','){
288: if(c == '\\')c = getc(cfile);
289: *p++ = c;
290: }
291: }
292: *p = 0;
293: if(tokval[0] == 0)return(0);
294: /*
295: debug("tok %s",tokval);
296: */
297: return(tlookup(tokval));
298: }
299: static tlookup(str)
300: char *str; {
301: struct tokstruct *p;
302: for(p = toktab; p->tokstr; p++)
303: if(streql(p->tokstr,str) == 0){
304: return(p->tval);
305: }
306: return(ID);
307: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.