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