1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 1989 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <ctype.h> 31 #include <sys/types.h> 32 #include <sys/stat.h> 33 #include <errno.h> 34 #include <malloc.h> 35 #include <strings.h> 36 #include <stdlib.h> 37 #include <unistd.h> 38 39 char *getpass(); 40 41 #define DEFAULT 1 42 #define LOGIN 2 43 #define PASSWD 3 44 #define NOTIFY 4 45 #define WRITE 5 46 #define YES 6 47 #define NO 7 48 #define COMMAND 8 49 #define FORCE 9 50 #define ID 10 51 #define MACHINE 11 52 53 #define MAXTOKEN 11 54 #define NTOKENS (MAXTOKEN - 1 + 2 + 1) /* two duplicates and null, minus id */ 55 56 static void rnetrc(char *, char **, char **); 57 static int token(void); 58 59 static struct ruserdata { 60 char tokval[100]; 61 struct toktab { 62 char *tokstr; 63 int tval; 64 } toktab[NTOKENS]; 65 FILE *cfile; 66 } *ruserdata, *_ruserdata(void); 67 68 69 static struct ruserdata * 70 _ruserdata(void) 71 { 72 struct ruserdata *d = ruserdata; 73 struct toktab *t; 74 75 if (d == 0) { 76 if ((d = (struct ruserdata *) 77 calloc(1, sizeof(struct ruserdata))) == NULL) { 78 return(NULL); 79 } 80 ruserdata = d; 81 t = d->toktab; 82 t->tokstr = "default"; t++->tval = DEFAULT; 83 t->tokstr = "login"; t++->tval = LOGIN; 84 t->tokstr = "password"; t++->tval = PASSWD; 85 t->tokstr = "notify"; t++->tval = NOTIFY; 86 t->tokstr = "write"; t++->tval = WRITE; 87 t->tokstr = "yes"; t++->tval = YES; 88 t->tokstr = "y"; t++->tval = YES; 89 t->tokstr = "no"; t++->tval = NO; 90 t->tokstr = "n"; t++->tval = NO; 91 t->tokstr = "command"; t++->tval = COMMAND; 92 t->tokstr = "force"; t++->tval = FORCE; 93 t->tokstr = "machine"; t++->tval = MACHINE; 94 t->tokstr = 0; t->tval = 0; 95 } 96 return(d); 97 } 98 99 void 100 _ruserpass(char *host, char **aname, char **apass) 101 { 102 103 if (*aname == 0 || *apass == 0) 104 rnetrc(host, aname, apass); 105 if (*aname == 0) { 106 char *myname = getlogin(); 107 *aname = malloc(16); 108 printf("Name (%s:%s): ", host, myname); 109 fflush(stdout); 110 if (read(2, *aname, 16) <= 0) 111 exit(1); 112 if ((*aname)[0] == '\n') 113 *aname = myname; 114 else 115 if (index(*aname, '\n')) 116 *index(*aname, '\n') = 0; 117 } 118 if (*aname && *apass == 0) { 119 printf("Password (%s:%s): ", host, *aname); 120 fflush(stdout); 121 *apass = getpass(""); 122 } 123 } 124 125 126 static void 127 rnetrc(char *host, char **aname, char **apass) 128 { 129 struct ruserdata *d = _ruserdata(); 130 char *hdir, buf[BUFSIZ]; 131 int t; 132 struct stat stb; 133 134 if (d == 0) 135 return; 136 137 hdir = getenv("HOME"); 138 if (hdir == NULL) 139 hdir = "."; 140 sprintf(buf, "%s/.netrc", hdir); 141 d->cfile = fopen(buf, "r"); 142 if (d->cfile == NULL) { 143 if (errno != ENOENT) 144 perror(buf); 145 return; 146 } 147 next: 148 while ((t = token())) switch(t) { 149 150 case DEFAULT: 151 (void) token(); 152 continue; 153 154 case MACHINE: 155 if (token() != ID || strcmp(host, d->tokval)) 156 continue; 157 while ((t = token()) && t != MACHINE) switch(t) { 158 159 case LOGIN: 160 if (token()) 161 if (*aname == 0) { 162 *aname = malloc(strlen(d->tokval) + 1); 163 strcpy(*aname, d->tokval); 164 } else { 165 if (strcmp(*aname, d->tokval)) 166 goto next; 167 } 168 break; 169 case PASSWD: 170 if (fstat(fileno(d->cfile), &stb) >= 0 171 && (stb.st_mode & 077) != 0) { 172 fprintf(stderr, "Error - .netrc file not correct mode.\n"); 173 fprintf(stderr, "Remove password or correct mode.\n"); 174 exit(1); 175 } 176 if (token() && *apass == 0) { 177 *apass = malloc(strlen(d->tokval) + 1); 178 strcpy(*apass, d->tokval); 179 } 180 break; 181 case COMMAND: 182 case NOTIFY: 183 case WRITE: 184 case FORCE: 185 (void) token(); 186 break; 187 default: 188 fprintf(stderr, "Unknown .netrc option %s\n", d->tokval); 189 break; 190 } 191 goto done; 192 } 193 done: 194 fclose(d->cfile); 195 } 196 197 static int 198 token(void) 199 { 200 struct ruserdata *d = _ruserdata(); 201 char *cp; 202 int c; 203 struct toktab *t; 204 205 if (d == 0) 206 return(0); 207 208 if (feof(d->cfile)) 209 return (0); 210 while ((c = getc(d->cfile)) != EOF && 211 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 212 continue; 213 if (c == EOF) 214 return (0); 215 cp = d->tokval; 216 if (c == '"') { 217 while ((c = getc(d->cfile)) != EOF && c != '"') { 218 if (c == '\\') 219 c = getc(d->cfile); 220 *cp++ = c; 221 } 222 } else { 223 *cp++ = c; 224 while ((c = getc(d->cfile)) != EOF 225 && c != '\n' && c != '\t' && c != ' ' && c != ',') { 226 if (c == '\\') 227 c = getc(d->cfile); 228 *cp++ = c; 229 } 230 } 231 *cp = 0; 232 if (d->tokval[0] == 0) 233 return (0); 234 for (t = d->toktab; t->tokstr; t++) 235 if (!strcmp(t->tokstr, d->tokval)) 236 return (t->tval); 237 return (ID); 238 } 239