Create a branch for working on csrss and co.
[reactos.git] / base / applications / network / ftp / ruserpass.c
1 /*
2 * Copyright (c) 1985 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 */
17
18 #ifndef lint
19 static char sccsid[] = "@(#)ruserpass.c 5.1 (Berkeley) 3/1/89";
20 #endif /* not lint */
21
22 #include "precomp.h"
23 //#include <utmp.h>
24
25 struct utmp *getutmp();
26 static FILE *cfile;
27
28 #ifndef MAXHOSTNAMELEN
29 #define MAXHOSTNAMELEN 64
30 #endif
31
32 #define DEFAULT 1
33 #define LOGIN 2
34 #define PASSWD 3
35 #define ACCOUNT 4
36 #define MACDEF 5
37 #define ID 10
38 #define MACH 11
39
40 static char tokval[100];
41
42 static struct toktab {
43 const char *tokstr;
44 int tval;
45 } toktab[]= {
46 {"default", DEFAULT},
47 {"login", LOGIN},
48 {"password", PASSWD},
49 {"passwd", PASSWD},
50 {"account", ACCOUNT},
51 {"machine", MACH},
52 {"macdef", MACDEF},
53 {0, 0}
54 };
55
56 extern char *hostname;
57 static int token(void);
58
59 int ruserpass(const char *host, char **aname, char **apass, char **aacct)
60 {
61 const char *hdir, *mydomain;
62 char buf[BUFSIZ], *tmp;
63 char myname[MAXHOSTNAMELEN];
64 int t, i, c, usedefault = 0;
65 struct stat stb;
66
67 hdir = getenv("HOME");
68 if (hdir == NULL)
69 hdir = ".";
70 (void) sprintf(buf, "%s/.netrc", hdir);
71 cfile = fopen(buf, "r");
72 if (cfile == NULL) {
73 if (errno != ENOENT)
74 perror(buf);
75 return(0);
76 }
77
78
79 if (gethostname(myname, sizeof(myname)) < 0)
80 myname[0] = '\0';
81 if ((mydomain = index(myname, '.')) == NULL)
82 mydomain = "";
83 next:
84 while ((t = token())) switch(t) {
85
86 case DEFAULT:
87 usedefault = 1;
88 /* FALL THROUGH */
89
90 case MACH:
91 if (!usedefault) {
92 if (token() != ID)
93 continue;
94 /*
95 * Allow match either for user's input host name
96 * or official hostname. Also allow match of
97 * incompletely-specified host in local domain.
98 */
99 if (strcasecmp(host, tokval) == 0)
100 goto match;
101 if (strcasecmp(hostname, tokval) == 0)
102 goto match;
103 if ((tmp = index(hostname, '.')) != NULL &&
104 strcasecmp(tmp, mydomain) == 0 &&
105 strncasecmp(hostname, tokval, tmp - hostname) == 0 &&
106 tokval[tmp - hostname] == '\0')
107 goto match;
108 if ((tmp = index(host, '.')) != NULL &&
109 strcasecmp(tmp, mydomain) == 0 &&
110 strncasecmp(host, tokval, tmp - host) == 0 &&
111 tokval[tmp - host] == '\0')
112 goto match;
113 continue;
114 }
115 match:
116 while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
117
118 case LOGIN:
119 if (token()) {
120 if (*aname == 0) {
121 *aname = malloc((unsigned) strlen(tokval) + 1);
122 (void) strcpy(*aname, tokval);
123 } else {
124 if (strcmp(*aname, tokval))
125 goto next;
126 }
127 }
128 break;
129 case PASSWD:
130 if (strcmp(*aname, "anonymous") &&
131 fstat(fileno(cfile), &stb) >= 0 &&
132 (stb.st_mode & 077) != 0) {
133 fprintf(stderr, "Error - .netrc file not correct mode.\n");
134 fprintf(stderr, "Remove password or correct mode.\n");
135 goto bad;
136 }
137 if (token() && *apass == 0) {
138 *apass = malloc((unsigned) strlen(tokval) + 1);
139 (void) strcpy(*apass, tokval);
140 }
141 break;
142 case ACCOUNT:
143 if (fstat(fileno(cfile), &stb) >= 0
144 && (stb.st_mode & 077) != 0) {
145 fprintf(stderr, "Error - .netrc file not correct mode.\n");
146 fprintf(stderr, "Remove account or correct mode.\n");
147 goto bad;
148 }
149 if (token() && *aacct == 0) {
150 *aacct = malloc((unsigned) strlen(tokval) + 1);
151 (void) strcpy(*aacct, tokval);
152 }
153 break;
154 case MACDEF:
155 if (proxy) {
156 (void) fclose(cfile);
157 return(0);
158 }
159 while ((c=getc(cfile)) != EOF && (c == ' ' || c == '\t'));
160 if (c == EOF || c == '\n') {
161 printf("Missing macdef name argument.\n");
162 goto bad;
163 }
164 if (macnum == 16) {
165 printf("Limit of 16 macros have already been defined\n");
166 goto bad;
167 }
168 tmp = macros[macnum].mac_name;
169 *tmp++ = c;
170 for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
171 !isspace(c); ++i) {
172 *tmp++ = c;
173 }
174 if (c == EOF) {
175 printf("Macro definition missing null line terminator.\n");
176 goto bad;
177 }
178 *tmp = '\0';
179 if (c != '\n') {
180 while ((c=getc(cfile)) != EOF && c != '\n');
181 }
182 if (c == EOF) {
183 printf("Macro definition missing null line terminator.\n");
184 goto bad;
185 }
186 if (macnum == 0) {
187 macros[macnum].mac_start = macbuf;
188 }
189 else {
190 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
191 }
192 tmp = macros[macnum].mac_start;
193 while (tmp != macbuf + 4096) {
194 if ((c=getc(cfile)) == EOF) {
195 printf("Macro definition missing null line terminator.\n");
196 goto bad;
197 }
198 *tmp = c;
199 if (*tmp == '\n') {
200 if (*(tmp-1) == '\0') {
201 macros[macnum++].mac_end = tmp - 1;
202 break;
203 }
204 *tmp = '\0';
205 }
206 tmp++;
207 }
208 if (tmp == macbuf + 4096) {
209 printf("4K macro buffer exceeded\n");
210 goto bad;
211 }
212 break;
213 default:
214 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
215 break;
216 }
217 goto done;
218 }
219 done:
220 (void) fclose(cfile);
221 return(0);
222 bad:
223 (void) fclose(cfile);
224 return(-1);
225 }
226
227 static int token(void)
228 {
229 char *cp;
230 int c;
231 struct toktab *t;
232
233 if (feof(cfile))
234 return (0);
235 while ((c = getc(cfile)) != EOF &&
236 (c == '\r' || c == '\n' || c == '\t' || c == ' ' || c == ','))
237 continue;
238 if (c == EOF)
239 return (0);
240 cp = tokval;
241 if (c == '"') {
242 while ((c = getc(cfile)) != EOF && c != '"') {
243 if (c == '\\')
244 c = getc(cfile);
245 *cp++ = c;
246 }
247 } else {
248 *cp++ = c;
249 while ((c = getc(cfile)) != EOF
250 && c != '\n' && c != '\t' && c != ' ' && c != ',' && c != '\r') {
251 if (c == '\\')
252 c = getc(cfile);
253 *cp++ = c;
254 }
255 }
256 *cp = 0;
257 if (tokval[0] == 0)
258 return (0);
259 for (t = toktab; t->tokstr; t++)
260 if (!strcmp(t->tokstr, tokval))
261 return (t->tval);
262 return (ID);
263 }