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