]> diplodocus.org Git - nmh/blob - sbr/ruserpass.c
* I had alphabetized the --configure options in the --help output
[nmh] / sbr / 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 * $Id$
18 */
19
20 #include <h/mh.h>
21 #include <pwd.h>
22 #include <errno.h>
23
24 static FILE *cfile;
25
26 #ifndef MAXHOSTNAMELEN
27 # define MAXHOSTNAMELEN 64
28 #endif
29
30 #define DEFAULT 1
31 #define LOGIN 2
32 #define PASSWD 3
33 #define ACCOUNT 4
34 #define MACDEF 5
35 #define ID 10
36 #define MACH 11
37
38 static char tokval[100];
39
40 struct toktab {
41 char *tokstr;
42 int tval;
43 };
44
45 static struct toktab toktabs[] = {
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 /*
57 * prototypes
58 */
59 static int token(void);
60
61
62 int
63 ruserpass(char *host, char **aname, char **apass)
64 {
65 char *hdir, buf[BUFSIZ];
66 int t, usedefault = 0;
67 struct stat stb;
68 extern int errno;
69
70 hdir = getenv("HOME");
71 if (hdir == NULL)
72 hdir = ".";
73 snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
74 cfile = fopen(buf, "r");
75 if (cfile == NULL) {
76 if (errno != ENOENT)
77 perror(buf);
78 goto done;
79 }
80
81 while ((t = token())) {
82 switch(t) {
83 case DEFAULT:
84 usedefault = 1;
85 /* FALL THROUGH */
86
87 case MACH:
88 if (!usedefault) {
89 if (token() != ID)
90 continue;
91 /*
92 * Allow match either for user's host name.
93 */
94 if (strcasecmp(host, tokval) == 0)
95 goto match;
96 continue;
97 }
98 match:
99 while ((t = token()) && t != MACH && t != DEFAULT) {
100 switch(t) {
101 case LOGIN:
102 if (token() && *aname == 0) {
103 *aname = malloc((size_t) strlen(tokval) + 1);
104 strcpy(*aname, tokval);
105 }
106 break;
107 case PASSWD:
108 if (fstat(fileno(cfile), &stb) >= 0 &&
109 (stb.st_mode & 077) != 0) {
110 fprintf(stderr, "Error - .netrc file not correct mode.\n");
111 fprintf(stderr, "Remove password or correct mode.\n");
112 goto bad;
113 }
114 if (token() && *apass == 0) {
115 *apass = malloc((size_t) strlen(tokval) + 1);
116 strcpy(*apass, tokval);
117 }
118 break;
119 case ACCOUNT:
120 break;
121
122 case MACDEF:
123 goto done_close;
124 break;
125 default:
126 fprintf(stderr, "Unknown .netrc keyword %s\n", tokval);
127 break;
128 }
129 }
130 goto done;
131 }
132 }
133
134 done_close:
135 fclose(cfile);
136
137 done:
138 if (!*aname) {
139 char tmp[80];
140 char *myname;
141
142 if ((myname = getlogin()) == NULL) {
143 struct passwd *pp;
144
145 if ((pp = getpwuid (getuid())) != NULL)
146 myname = pp->pw_name;
147 }
148 printf("Name (%s:%s): ", host, myname);
149
150 fgets(tmp, sizeof(tmp) - 1, stdin);
151 tmp[strlen(tmp) - 1] = '\0';
152 if (*tmp != '\0') {
153 myname = tmp;
154 }
155
156 *aname = malloc((size_t) strlen(myname) + 1);
157 strcpy (*aname, myname);
158 }
159
160 if (!*apass) {
161 char prompt[256];
162 char *mypass;
163
164 snprintf(prompt, sizeof(prompt), "Password (%s:%s): ", host, *aname);
165 mypass = (char *)getpass (prompt);
166
167 if (*mypass == '\0') {
168 mypass = *aname;
169 }
170
171 *apass = malloc((size_t) strlen(mypass) + 1);
172 strcpy (*apass, mypass);
173 }
174
175 return(0);
176 bad:
177 fclose(cfile);
178 return(-1);
179 }
180
181 static int
182 token(void)
183 {
184 char *cp;
185 int c;
186 struct toktab *t;
187
188 if (feof(cfile))
189 return (0);
190 while ((c = getc(cfile)) != EOF &&
191 (c == '\n' || c == '\t' || c == ' ' || c == ','))
192 continue;
193 if (c == EOF)
194 return (0);
195 cp = tokval;
196 if (c == '"') {
197 while ((c = getc(cfile)) != EOF && c != '"') {
198 if (c == '\\')
199 c = getc(cfile);
200 *cp++ = c;
201 }
202 } else {
203 *cp++ = c;
204 while ((c = getc(cfile)) != EOF
205 && c != '\n' && c != '\t' && c != ' ' && c != ',') {
206 if (c == '\\')
207 c = getc(cfile);
208 *cp++ = c;
209 }
210 }
211 *cp = 0;
212 if (tokval[0] == 0)
213 return (0);
214 for (t = toktabs; t->tokstr; t++)
215 if (!strcmp(t->tokstr, tokval))
216 return (t->tval);
217 return (ID);
218 }