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