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