checked in for rick: add restart, size, modtime, newer, syst;
[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
ff00793c 19static char sccsid[] = "@(#)ruserpass.c 1.7 (Berkeley) %G%";
11c5f0a3 20#endif /* not lint */
3a38a184
GM
21
22struct macel {
23 char mac_name[9]; /* macro name */
24 char *mac_start; /* start of macro in macbuf */
25 char *mac_end; /* end of macro in macbuf */
26};
27
28extern int macnum, proxy; /* number of defined macros */
29extern struct macel macros[16], *macpt;
30extern char macbuf[4096];
31
385d0849 32#include <sys/types.h>
3a38a184
GM
33#include <stdio.h>
34#include <utmp.h>
35#include <ctype.h>
3a38a184
GM
36#include <sys/stat.h>
37#include <errno.h>
38
39char *renvlook(), *malloc(), *index(), *getenv(), *getpass(), *getlogin();
04480325 40char *strcpy();
3a38a184
GM
41struct utmp *getutmp();
42static FILE *cfile;
43
44ruserpass(host, aname, apass, aacct)
45 char *host, **aname, **apass, **aacct;
46{
47
48 /* renv(host, aname, apass, aacct);
49 if (*aname == 0 || *apass == 0) */
50 return(rnetrc(host, aname, apass, aacct));
51}
52
53#define DEFAULT 1
54#define LOGIN 2
55#define PASSWD 3
56#define ACCOUNT 4
57#define MACDEF 5
58#define ID 10
59#define MACHINE 11
60
61static char tokval[100];
62
63static struct toktab {
64 char *tokstr;
65 int tval;
66} toktab[]= {
67 "default", DEFAULT,
68 "login", LOGIN,
69 "password", PASSWD,
70 "account", ACCOUNT,
71 "machine", MACHINE,
72 "macdef", MACDEF,
73 0, 0
74};
75
76static
77rnetrc(host, aname, apass, aacct)
78 char *host, **aname, **apass, **aacct;
79{
04480325 80 char *hdir, buf[BUFSIZ], *tmp;
ff00793c 81 int t, i, c, usedefault = 0;
3a38a184
GM
82 struct stat stb;
83 extern int errno;
84
85 hdir = getenv("HOME");
86 if (hdir == NULL)
87 hdir = ".";
04480325 88 (void) sprintf(buf, "%s/.netrc", hdir);
3a38a184
GM
89 cfile = fopen(buf, "r");
90 if (cfile == NULL) {
91 if (errno != ENOENT)
92 perror(buf);
93 return(0);
94 }
95next:
96 while ((t = token())) switch(t) {
97
98 case DEFAULT:
ff00793c
MK
99 usedefault = 1;
100 /* FALL THROUGH */
3a38a184
GM
101
102 case MACHINE:
ff00793c 103 if (!usedefault && (token() != ID || strcmp(host, tokval)))
3a38a184
GM
104 continue;
105 while ((t = token()) && t != MACHINE) switch(t) {
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:
118 if (fstat(fileno(cfile), &stb) >= 0
119 && (stb.st_mode & 077) != 0) {
e6be46b8 120 fprintf(stderr, "Error - .netrc file not correct mode.\n");
3a38a184
GM
121 fprintf(stderr, "Remove password or correct mode.\n");
122 return(-1);
123 }
124 if (token() && *apass == 0) {
04480325
GM
125 *apass = malloc((unsigned) strlen(tokval) + 1);
126 (void) strcpy(*apass, tokval);
3a38a184
GM
127 }
128 break;
129 case ACCOUNT:
130 if (fstat(fileno(cfile), &stb) >= 0
131 && (stb.st_mode & 077) != 0) {
e6be46b8 132 fprintf(stderr, "Error - .netrc file not correct mode.\n");
3a38a184
GM
133 fprintf(stderr, "Remove account or correct mode.\n");
134 return(-1);
135 }
136 if (token() && *aacct == 0) {
04480325
GM
137 *aacct = malloc((unsigned) strlen(tokval) + 1);
138 (void) strcpy(*aacct, tokval);
3a38a184
GM
139 }
140 break;
141 case MACDEF:
142 if (proxy) {
143 return(0);
144 }
145 while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
146 if (c == EOF || c == '\n') {
147 printf("Missing macdef name argument.\n");
148 return(-1);
149 }
150 if (macnum == 16) {
151 printf("Limit of 16 macros have already been defined\n");
152 return(-1);
153 }
154 tmp = macros[macnum].mac_name;
155 *tmp++ = c;
156 for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
157 !isspace(c); ++i) {
158 *tmp++ = c;
159 }
160 if (c == EOF) {
161 printf("Macro definition missing null line terminator.\n");
162 return(-1);
163 }
164 *tmp = '\0';
165 if (c != '\n') {
166 while ((c=getc(cfile)) != EOF && c != '\n');
167 }
168 if (c == EOF) {
169 printf("Macro definition missing null line terminator.\n");
170 return(-1);
171 }
172 if (macnum == 0) {
173 macros[macnum].mac_start = macbuf;
174 }
175 else {
176 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
177 }
178 tmp = macros[macnum].mac_start;
179 while (tmp != macbuf + 4096) {
180 if ((c=getc(cfile)) == EOF) {
181 printf("Macro definition missing null line terminator.\n");
182 return(-1);
183 }
184 *tmp = c;
185 if (*tmp == '\n') {
186 if (*(tmp-1) == '\0') {
187 macros[macnum++].mac_end = tmp - 1;
188 break;
189 }
190 *tmp = '\0';
191 }
192 tmp++;
193 }
194 if (tmp == macbuf + 4096) {
195 printf("4K macro buffer exceeded\n");
196 return(-1);
197 }
198 break;
199 default:
e6be46b8 200 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
3a38a184
GM
201 break;
202 }
203 goto done;
204 }
205done:
04480325
GM
206 (void) fclose(cfile);
207 return(0);
3a38a184
GM
208}
209
210static
211token()
212{
213 char *cp;
214 int c;
215 struct toktab *t;
216
217 if (feof(cfile))
218 return (0);
219 while ((c = getc(cfile)) != EOF &&
220 (c == '\n' || c == '\t' || c == ' ' || c == ','))
221 continue;
222 if (c == EOF)
223 return (0);
224 cp = tokval;
225 if (c == '"') {
226 while ((c = getc(cfile)) != EOF && c != '"') {
227 if (c == '\\')
228 c = getc(cfile);
229 *cp++ = c;
230 }
231 } else {
232 *cp++ = c;
233 while ((c = getc(cfile)) != EOF
234 && c != '\n' && c != '\t' && c != ' ' && c != ',') {
235 if (c == '\\')
236 c = getc(cfile);
237 *cp++ = c;
238 }
239 }
240 *cp = 0;
241 if (tokval[0] == 0)
242 return (0);
243 for (t = toktab; t->tokstr; t++)
244 if (!strcmp(t->tokstr, tokval))
245 return (t->tval);
246 return (ID);
247}