[NTDLL]
[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 <sys/types.h>
23 #include <stdio.h>
24 //#include <utmp.h>
25 #include <ctype.h>
26 #include <sys/stat.h>
27 #include <errno.h>
28 #include "ftp_var.h"
29 #include "prototypes.h"
30 #include <winsock.h>
31
32 struct utmp *getutmp();
33 static FILE *cfile;
34
35 #ifndef MAXHOSTNAMELEN
36 #define MAXHOSTNAMELEN 64
37 #endif
38
39 #define DEFAULT 1
40 #define LOGIN 2
41 #define PASSWD 3
42 #define ACCOUNT 4
43 #define MACDEF 5
44 #define ID 10
45 #define MACH 11
46
47 static char tokval[100];
48
49 static struct toktab {
50 const char *tokstr;
51 int tval;
52 } toktab[]= {
53 {"default", DEFAULT},
54 {"login", LOGIN},
55 {"password", PASSWD},
56 {"passwd", PASSWD},
57 {"account", ACCOUNT},
58 {"machine", MACH},
59 {"macdef", MACDEF},
60 {0, 0}
61 };
62
63 extern char *hostname;
64 static int token(void);
65
66 int ruserpass(const char *host, char **aname, char **apass, char **aacct)
67 {
68 const char *hdir, *mydomain;
69 char buf[BUFSIZ], *tmp;
70 char myname[MAXHOSTNAMELEN];
71 int t, i, c, usedefault = 0;
72 struct stat stb;
73
74 hdir = getenv("HOME");
75 if (hdir == NULL)
76 hdir = ".";
77 (void) sprintf(buf, "%s/.netrc", hdir);
78 cfile = fopen(buf, "r");
79 if (cfile == NULL) {
80 if (errno != ENOENT)
81 perror(buf);
82 return(0);
83 }
84
85
86 if (gethostname(myname, sizeof(myname)) < 0)
87 myname[0] = '\0';
88 if ((mydomain = index(myname, '.')) == NULL)
89 mydomain = "";
90 next:
91 while ((t = token())) switch(t) {
92
93 case DEFAULT:
94 usedefault = 1;
95 /* FALL THROUGH */
96
97 case MACH:
98 if (!usedefault) {
99 if (token() != ID)
100 continue;
101 /*
102 * Allow match either for user's input host name
103 * or official hostname. Also allow match of
104 * incompletely-specified host in local domain.
105 */
106 if (strcasecmp(host, tokval) == 0)
107 goto match;
108 if (strcasecmp(hostname, tokval) == 0)
109 goto match;
110 if ((tmp = index(hostname, '.')) != NULL &&
111 strcasecmp(tmp, mydomain) == 0 &&
112 strncasecmp(hostname, tokval, tmp - hostname) == 0 &&
113 tokval[tmp - hostname] == '\0')
114 goto match;
115 if ((tmp = index(host, '.')) != NULL &&
116 strcasecmp(tmp, mydomain) == 0 &&
117 strncasecmp(host, tokval, tmp - host) == 0 &&
118 tokval[tmp - host] == '\0')
119 goto match;
120 continue;
121 }
122 match:
123 while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
124
125 case LOGIN:
126 if (token()) {
127 if (*aname == 0) {
128 *aname = malloc((unsigned) strlen(tokval) + 1);
129 (void) strcpy(*aname, tokval);
130 } else {
131 if (strcmp(*aname, tokval))
132 goto next;
133 }
134 }
135 break;
136 case PASSWD:
137 if (strcmp(*aname, "anonymous") &&
138 fstat(fileno(cfile), &stb) >= 0 &&
139 (stb.st_mode & 077) != 0) {
140 fprintf(stderr, "Error - .netrc file not correct mode.\n");
141 fprintf(stderr, "Remove password or correct mode.\n");
142 goto bad;
143 }
144 if (token() && *apass == 0) {
145 *apass = malloc((unsigned) strlen(tokval) + 1);
146 (void) strcpy(*apass, tokval);
147 }
148 break;
149 case ACCOUNT:
150 if (fstat(fileno(cfile), &stb) >= 0
151 && (stb.st_mode & 077) != 0) {
152 fprintf(stderr, "Error - .netrc file not correct mode.\n");
153 fprintf(stderr, "Remove account or correct mode.\n");
154 goto bad;
155 }
156 if (token() && *aacct == 0) {
157 *aacct = malloc((unsigned) strlen(tokval) + 1);
158 (void) strcpy(*aacct, tokval);
159 }
160 break;
161 case MACDEF:
162 if (proxy) {
163 (void) fclose(cfile);
164 return(0);
165 }
166 while ((c=getc(cfile)) != EOF && (c == ' ' || c == '\t'));
167 if (c == EOF || c == '\n') {
168 printf("Missing macdef name argument.\n");
169 goto bad;
170 }
171 if (macnum == 16) {
172 printf("Limit of 16 macros have already been defined\n");
173 goto bad;
174 }
175 tmp = macros[macnum].mac_name;
176 *tmp++ = c;
177 for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
178 !isspace(c); ++i) {
179 *tmp++ = c;
180 }
181 if (c == EOF) {
182 printf("Macro definition missing null line terminator.\n");
183 goto bad;
184 }
185 *tmp = '\0';
186 if (c != '\n') {
187 while ((c=getc(cfile)) != EOF && c != '\n');
188 }
189 if (c == EOF) {
190 printf("Macro definition missing null line terminator.\n");
191 goto bad;
192 }
193 if (macnum == 0) {
194 macros[macnum].mac_start = macbuf;
195 }
196 else {
197 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
198 }
199 tmp = macros[macnum].mac_start;
200 while (tmp != macbuf + 4096) {
201 if ((c=getc(cfile)) == EOF) {
202 printf("Macro definition missing null line terminator.\n");
203 goto bad;
204 }
205 *tmp = c;
206 if (*tmp == '\n') {
207 if (*(tmp-1) == '\0') {
208 macros[macnum++].mac_end = tmp - 1;
209 break;
210 }
211 *tmp = '\0';
212 }
213 tmp++;
214 }
215 if (tmp == macbuf + 4096) {
216 printf("4K macro buffer exceeded\n");
217 goto bad;
218 }
219 break;
220 default:
221 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
222 break;
223 }
224 goto done;
225 }
226 done:
227 (void) fclose(cfile);
228 return(0);
229 bad:
230 (void) fclose(cfile);
231 return(-1);
232 }
233
234 static int token(void)
235 {
236 char *cp;
237 int c;
238 struct toktab *t;
239
240 if (feof(cfile))
241 return (0);
242 while ((c = getc(cfile)) != EOF &&
243 (c == '\r' || c == '\n' || c == '\t' || c == ' ' || c == ','))
244 continue;
245 if (c == EOF)
246 return (0);
247 cp = tokval;
248 if (c == '"') {
249 while ((c = getc(cfile)) != EOF && c != '"') {
250 if (c == '\\')
251 c = getc(cfile);
252 *cp++ = c;
253 }
254 } else {
255 *cp++ = c;
256 while ((c = getc(cfile)) != EOF
257 && c != '\n' && c != '\t' && c != ' ' && c != ',' && c != '\r') {
258 if (c == '\\')
259 c = getc(cfile);
260 *cp++ = c;
261 }
262 }
263 *cp = 0;
264 if (tokval[0] == 0)
265 return (0);
266 for (t = toktab; t->tokstr; t++)
267 if (!strcmp(t->tokstr, tokval))
268 return (t->tval);
269 return (ID);
270 }