17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 1989 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <stdio.h> 307c478bd9Sstevel@tonic-gate #include <ctype.h> 317c478bd9Sstevel@tonic-gate #include <sys/types.h> 327c478bd9Sstevel@tonic-gate #include <sys/stat.h> 337c478bd9Sstevel@tonic-gate #include <errno.h> 34*5d54f3d8Smuffin #include <malloc.h> 35*5d54f3d8Smuffin #include <strings.h> 36*5d54f3d8Smuffin #include <stdlib.h> 37*5d54f3d8Smuffin #include <unistd.h> 387c478bd9Sstevel@tonic-gate 39*5d54f3d8Smuffin char *getpass(); 407c478bd9Sstevel@tonic-gate 417c478bd9Sstevel@tonic-gate #define DEFAULT 1 427c478bd9Sstevel@tonic-gate #define LOGIN 2 437c478bd9Sstevel@tonic-gate #define PASSWD 3 447c478bd9Sstevel@tonic-gate #define NOTIFY 4 457c478bd9Sstevel@tonic-gate #define WRITE 5 467c478bd9Sstevel@tonic-gate #define YES 6 477c478bd9Sstevel@tonic-gate #define NO 7 487c478bd9Sstevel@tonic-gate #define COMMAND 8 497c478bd9Sstevel@tonic-gate #define FORCE 9 507c478bd9Sstevel@tonic-gate #define ID 10 517c478bd9Sstevel@tonic-gate #define MACHINE 11 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate #define MAXTOKEN 11 547c478bd9Sstevel@tonic-gate #define NTOKENS (MAXTOKEN - 1 + 2 + 1) /* two duplicates and null, minus id */ 557c478bd9Sstevel@tonic-gate 56*5d54f3d8Smuffin static void rnetrc(char *, char **, char **); 57*5d54f3d8Smuffin static int token(void); 58*5d54f3d8Smuffin 597c478bd9Sstevel@tonic-gate static struct ruserdata { 607c478bd9Sstevel@tonic-gate char tokval[100]; 617c478bd9Sstevel@tonic-gate struct toktab { 627c478bd9Sstevel@tonic-gate char *tokstr; 637c478bd9Sstevel@tonic-gate int tval; 647c478bd9Sstevel@tonic-gate } toktab[NTOKENS]; 657c478bd9Sstevel@tonic-gate FILE *cfile; 66*5d54f3d8Smuffin } *ruserdata, *_ruserdata(void); 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate static struct ruserdata * 70*5d54f3d8Smuffin _ruserdata(void) 717c478bd9Sstevel@tonic-gate { 72*5d54f3d8Smuffin struct ruserdata *d = ruserdata; 737c478bd9Sstevel@tonic-gate struct toktab *t; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate if (d == 0) { 767c478bd9Sstevel@tonic-gate if ((d = (struct ruserdata *) 777c478bd9Sstevel@tonic-gate calloc(1, sizeof(struct ruserdata))) == NULL) { 787c478bd9Sstevel@tonic-gate return(NULL); 797c478bd9Sstevel@tonic-gate } 807c478bd9Sstevel@tonic-gate ruserdata = d; 817c478bd9Sstevel@tonic-gate t = d->toktab; 827c478bd9Sstevel@tonic-gate t->tokstr = "default"; t++->tval = DEFAULT; 837c478bd9Sstevel@tonic-gate t->tokstr = "login"; t++->tval = LOGIN; 847c478bd9Sstevel@tonic-gate t->tokstr = "password"; t++->tval = PASSWD; 857c478bd9Sstevel@tonic-gate t->tokstr = "notify"; t++->tval = NOTIFY; 867c478bd9Sstevel@tonic-gate t->tokstr = "write"; t++->tval = WRITE; 877c478bd9Sstevel@tonic-gate t->tokstr = "yes"; t++->tval = YES; 887c478bd9Sstevel@tonic-gate t->tokstr = "y"; t++->tval = YES; 897c478bd9Sstevel@tonic-gate t->tokstr = "no"; t++->tval = NO; 907c478bd9Sstevel@tonic-gate t->tokstr = "n"; t++->tval = NO; 917c478bd9Sstevel@tonic-gate t->tokstr = "command"; t++->tval = COMMAND; 927c478bd9Sstevel@tonic-gate t->tokstr = "force"; t++->tval = FORCE; 937c478bd9Sstevel@tonic-gate t->tokstr = "machine"; t++->tval = MACHINE; 947c478bd9Sstevel@tonic-gate t->tokstr = 0; t->tval = 0; 957c478bd9Sstevel@tonic-gate } 967c478bd9Sstevel@tonic-gate return(d); 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate 99*5d54f3d8Smuffin void 100*5d54f3d8Smuffin _ruserpass(char *host, char **aname, char **apass) 1017c478bd9Sstevel@tonic-gate { 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate if (*aname == 0 || *apass == 0) 1047c478bd9Sstevel@tonic-gate rnetrc(host, aname, apass); 1057c478bd9Sstevel@tonic-gate if (*aname == 0) { 1067c478bd9Sstevel@tonic-gate char *myname = getlogin(); 1077c478bd9Sstevel@tonic-gate *aname = malloc(16); 1087c478bd9Sstevel@tonic-gate printf("Name (%s:%s): ", host, myname); 1097c478bd9Sstevel@tonic-gate fflush(stdout); 1107c478bd9Sstevel@tonic-gate if (read(2, *aname, 16) <= 0) 1117c478bd9Sstevel@tonic-gate exit(1); 1127c478bd9Sstevel@tonic-gate if ((*aname)[0] == '\n') 1137c478bd9Sstevel@tonic-gate *aname = myname; 1147c478bd9Sstevel@tonic-gate else 1157c478bd9Sstevel@tonic-gate if (index(*aname, '\n')) 1167c478bd9Sstevel@tonic-gate *index(*aname, '\n') = 0; 1177c478bd9Sstevel@tonic-gate } 1187c478bd9Sstevel@tonic-gate if (*aname && *apass == 0) { 1197c478bd9Sstevel@tonic-gate printf("Password (%s:%s): ", host, *aname); 1207c478bd9Sstevel@tonic-gate fflush(stdout); 1217c478bd9Sstevel@tonic-gate *apass = getpass(""); 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate 126*5d54f3d8Smuffin static void 127*5d54f3d8Smuffin rnetrc(char *host, char **aname, char **apass) 1287c478bd9Sstevel@tonic-gate { 129*5d54f3d8Smuffin struct ruserdata *d = _ruserdata(); 1307c478bd9Sstevel@tonic-gate char *hdir, buf[BUFSIZ]; 1317c478bd9Sstevel@tonic-gate int t; 1327c478bd9Sstevel@tonic-gate struct stat stb; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate if (d == 0) 1357c478bd9Sstevel@tonic-gate return; 1367c478bd9Sstevel@tonic-gate 1377c478bd9Sstevel@tonic-gate hdir = getenv("HOME"); 1387c478bd9Sstevel@tonic-gate if (hdir == NULL) 1397c478bd9Sstevel@tonic-gate hdir = "."; 1407c478bd9Sstevel@tonic-gate sprintf(buf, "%s/.netrc", hdir); 1417c478bd9Sstevel@tonic-gate d->cfile = fopen(buf, "r"); 1427c478bd9Sstevel@tonic-gate if (d->cfile == NULL) { 1437c478bd9Sstevel@tonic-gate if (errno != ENOENT) 1447c478bd9Sstevel@tonic-gate perror(buf); 1457c478bd9Sstevel@tonic-gate return; 1467c478bd9Sstevel@tonic-gate } 1477c478bd9Sstevel@tonic-gate next: 1487c478bd9Sstevel@tonic-gate while ((t = token())) switch(t) { 1497c478bd9Sstevel@tonic-gate 1507c478bd9Sstevel@tonic-gate case DEFAULT: 1517c478bd9Sstevel@tonic-gate (void) token(); 1527c478bd9Sstevel@tonic-gate continue; 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate case MACHINE: 1557c478bd9Sstevel@tonic-gate if (token() != ID || strcmp(host, d->tokval)) 1567c478bd9Sstevel@tonic-gate continue; 1577c478bd9Sstevel@tonic-gate while ((t = token()) && t != MACHINE) switch(t) { 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate case LOGIN: 1607c478bd9Sstevel@tonic-gate if (token()) 1617c478bd9Sstevel@tonic-gate if (*aname == 0) { 1627c478bd9Sstevel@tonic-gate *aname = malloc(strlen(d->tokval) + 1); 1637c478bd9Sstevel@tonic-gate strcpy(*aname, d->tokval); 1647c478bd9Sstevel@tonic-gate } else { 1657c478bd9Sstevel@tonic-gate if (strcmp(*aname, d->tokval)) 1667c478bd9Sstevel@tonic-gate goto next; 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate break; 1697c478bd9Sstevel@tonic-gate case PASSWD: 1707c478bd9Sstevel@tonic-gate if (fstat(fileno(d->cfile), &stb) >= 0 1717c478bd9Sstevel@tonic-gate && (stb.st_mode & 077) != 0) { 1727c478bd9Sstevel@tonic-gate fprintf(stderr, "Error - .netrc file not correct mode.\n"); 1737c478bd9Sstevel@tonic-gate fprintf(stderr, "Remove password or correct mode.\n"); 1747c478bd9Sstevel@tonic-gate exit(1); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate if (token() && *apass == 0) { 1777c478bd9Sstevel@tonic-gate *apass = malloc(strlen(d->tokval) + 1); 1787c478bd9Sstevel@tonic-gate strcpy(*apass, d->tokval); 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate break; 1817c478bd9Sstevel@tonic-gate case COMMAND: 1827c478bd9Sstevel@tonic-gate case NOTIFY: 1837c478bd9Sstevel@tonic-gate case WRITE: 1847c478bd9Sstevel@tonic-gate case FORCE: 1857c478bd9Sstevel@tonic-gate (void) token(); 1867c478bd9Sstevel@tonic-gate break; 1877c478bd9Sstevel@tonic-gate default: 1887c478bd9Sstevel@tonic-gate fprintf(stderr, "Unknown .netrc option %s\n", d->tokval); 1897c478bd9Sstevel@tonic-gate break; 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate goto done; 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate done: 1947c478bd9Sstevel@tonic-gate fclose(d->cfile); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 197*5d54f3d8Smuffin static int 198*5d54f3d8Smuffin token(void) 1997c478bd9Sstevel@tonic-gate { 200*5d54f3d8Smuffin struct ruserdata *d = _ruserdata(); 2017c478bd9Sstevel@tonic-gate char *cp; 2027c478bd9Sstevel@tonic-gate int c; 2037c478bd9Sstevel@tonic-gate struct toktab *t; 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if (d == 0) 2067c478bd9Sstevel@tonic-gate return(0); 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate if (feof(d->cfile)) 2097c478bd9Sstevel@tonic-gate return (0); 2107c478bd9Sstevel@tonic-gate while ((c = getc(d->cfile)) != EOF && 2117c478bd9Sstevel@tonic-gate (c == '\n' || c == '\t' || c == ' ' || c == ',')) 2127c478bd9Sstevel@tonic-gate continue; 2137c478bd9Sstevel@tonic-gate if (c == EOF) 2147c478bd9Sstevel@tonic-gate return (0); 2157c478bd9Sstevel@tonic-gate cp = d->tokval; 2167c478bd9Sstevel@tonic-gate if (c == '"') { 2177c478bd9Sstevel@tonic-gate while ((c = getc(d->cfile)) != EOF && c != '"') { 2187c478bd9Sstevel@tonic-gate if (c == '\\') 2197c478bd9Sstevel@tonic-gate c = getc(d->cfile); 2207c478bd9Sstevel@tonic-gate *cp++ = c; 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate } else { 2237c478bd9Sstevel@tonic-gate *cp++ = c; 2247c478bd9Sstevel@tonic-gate while ((c = getc(d->cfile)) != EOF 2257c478bd9Sstevel@tonic-gate && c != '\n' && c != '\t' && c != ' ' && c != ',') { 2267c478bd9Sstevel@tonic-gate if (c == '\\') 2277c478bd9Sstevel@tonic-gate c = getc(d->cfile); 2287c478bd9Sstevel@tonic-gate *cp++ = c; 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate } 2317c478bd9Sstevel@tonic-gate *cp = 0; 2327c478bd9Sstevel@tonic-gate if (d->tokval[0] == 0) 2337c478bd9Sstevel@tonic-gate return (0); 2347c478bd9Sstevel@tonic-gate for (t = d->toktab; t->tokstr; t++) 2357c478bd9Sstevel@tonic-gate if (!strcmp(t->tokstr, d->tokval)) 2367c478bd9Sstevel@tonic-gate return (t->tval); 2377c478bd9Sstevel@tonic-gate return (ID); 2387c478bd9Sstevel@tonic-gate } 239