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 /* from UCB 4.2 82/10/10 */ 29 30 #include <stdio.h> 31 #include <ctype.h> 32 #include <sys/types.h> 33 #include <sys/stat.h> 34 #include <errno.h> 35 36 char *malloc(), *index(), *getenv(), *getpass(), *getlogin(); 37 38 #define DEFAULT 1 39 #define LOGIN 2 40 #define PASSWD 3 41 #define NOTIFY 4 42 #define WRITE 5 43 #define YES 6 44 #define NO 7 45 #define COMMAND 8 46 #define FORCE 9 47 #define ID 10 48 #define MACHINE 11 49 50 #define MAXTOKEN 11 51 #define NTOKENS (MAXTOKEN - 1 + 2 + 1) /* two duplicates and null, minus id */ 52 53 static struct ruserdata { 54 char tokval[100]; 55 struct toktab { 56 char *tokstr; 57 int tval; 58 } toktab[NTOKENS]; 59 FILE *cfile; 60 } *ruserdata, *_ruserdata(); 61 62 63 static struct ruserdata * 64 _ruserdata() 65 { 66 register struct ruserdata *d = ruserdata; 67 struct toktab *t; 68 69 if (d == 0) { 70 if ((d = (struct ruserdata *) 71 calloc(1, sizeof(struct ruserdata))) == NULL) { 72 return(NULL); 73 } 74 ruserdata = d; 75 t = d->toktab; 76 t->tokstr = "default"; t++->tval = DEFAULT; 77 t->tokstr = "login"; t++->tval = LOGIN; 78 t->tokstr = "password"; t++->tval = PASSWD; 79 t->tokstr = "notify"; t++->tval = NOTIFY; 80 t->tokstr = "write"; t++->tval = WRITE; 81 t->tokstr = "yes"; t++->tval = YES; 82 t->tokstr = "y"; t++->tval = YES; 83 t->tokstr = "no"; t++->tval = NO; 84 t->tokstr = "n"; t++->tval = NO; 85 t->tokstr = "command"; t++->tval = COMMAND; 86 t->tokstr = "force"; t++->tval = FORCE; 87 t->tokstr = "machine"; t++->tval = MACHINE; 88 t->tokstr = 0; t->tval = 0; 89 } 90 return(d); 91 } 92 93 94 _ruserpass(host, aname, apass) 95 char *host, **aname, **apass; 96 { 97 98 if (*aname == 0 || *apass == 0) 99 rnetrc(host, aname, apass); 100 if (*aname == 0) { 101 char *myname = getlogin(); 102 *aname = malloc(16); 103 printf("Name (%s:%s): ", host, myname); 104 fflush(stdout); 105 if (read(2, *aname, 16) <= 0) 106 exit(1); 107 if ((*aname)[0] == '\n') 108 *aname = myname; 109 else 110 if (index(*aname, '\n')) 111 *index(*aname, '\n') = 0; 112 } 113 if (*aname && *apass == 0) { 114 printf("Password (%s:%s): ", host, *aname); 115 fflush(stdout); 116 *apass = getpass(""); 117 } 118 } 119 120 121 static 122 rnetrc(host, aname, apass) 123 char *host, **aname, **apass; 124 { 125 register struct ruserdata *d = _ruserdata(); 126 char *hdir, buf[BUFSIZ]; 127 int t; 128 struct stat stb; 129 extern int errno; 130 131 if (d == 0) 132 return; 133 134 hdir = getenv("HOME"); 135 if (hdir == NULL) 136 hdir = "."; 137 sprintf(buf, "%s/.netrc", hdir); 138 d->cfile = fopen(buf, "r"); 139 if (d->cfile == NULL) { 140 if (errno != ENOENT) 141 perror(buf); 142 return; 143 } 144 next: 145 while ((t = token())) switch(t) { 146 147 case DEFAULT: 148 (void) token(); 149 continue; 150 151 case MACHINE: 152 if (token() != ID || strcmp(host, d->tokval)) 153 continue; 154 while ((t = token()) && t != MACHINE) switch(t) { 155 156 case LOGIN: 157 if (token()) 158 if (*aname == 0) { 159 *aname = malloc(strlen(d->tokval) + 1); 160 strcpy(*aname, d->tokval); 161 } else { 162 if (strcmp(*aname, d->tokval)) 163 goto next; 164 } 165 break; 166 case PASSWD: 167 if (fstat(fileno(d->cfile), &stb) >= 0 168 && (stb.st_mode & 077) != 0) { 169 fprintf(stderr, "Error - .netrc file not correct mode.\n"); 170 fprintf(stderr, "Remove password or correct mode.\n"); 171 exit(1); 172 } 173 if (token() && *apass == 0) { 174 *apass = malloc(strlen(d->tokval) + 1); 175 strcpy(*apass, d->tokval); 176 } 177 break; 178 case COMMAND: 179 case NOTIFY: 180 case WRITE: 181 case FORCE: 182 (void) token(); 183 break; 184 default: 185 fprintf(stderr, "Unknown .netrc option %s\n", d->tokval); 186 break; 187 } 188 goto done; 189 } 190 done: 191 fclose(d->cfile); 192 } 193 194 static 195 token() 196 { 197 register struct ruserdata *d = _ruserdata(); 198 char *cp; 199 int c; 200 struct toktab *t; 201 202 if (d == 0) 203 return(0); 204 205 if (feof(d->cfile)) 206 return (0); 207 while ((c = getc(d->cfile)) != EOF && 208 (c == '\n' || c == '\t' || c == ' ' || c == ',')) 209 continue; 210 if (c == EOF) 211 return (0); 212 cp = d->tokval; 213 if (c == '"') { 214 while ((c = getc(d->cfile)) != EOF && c != '"') { 215 if (c == '\\') 216 c = getc(d->cfile); 217 *cp++ = c; 218 } 219 } else { 220 *cp++ = c; 221 while ((c = getc(d->cfile)) != EOF 222 && c != '\n' && c != '\t' && c != ' ' && c != ',') { 223 if (c == '\\') 224 c = getc(d->cfile); 225 *cp++ = c; 226 } 227 } 228 *cp = 0; 229 if (d->tokval[0] == 0) 230 return (0); 231 for (t = d->toktab; t->tokstr; t++) 232 if (!strcmp(t->tokstr, d->tokval)) 233 return (t->tval); 234 return (ID); 235 } 236 237