1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 1994 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate /* 34*7c478bd9Sstevel@tonic-gate * create a Datakit connection to a remote destination 35*7c478bd9Sstevel@tonic-gate */ 36*7c478bd9Sstevel@tonic-gate #ifndef DIAL 37*7c478bd9Sstevel@tonic-gate static char SCCSID[] = "@(#)dkdial.c 2.7+BNU DKHOST 87/03/09"; 38*7c478bd9Sstevel@tonic-gate #endif 39*7c478bd9Sstevel@tonic-gate /* 40*7c478bd9Sstevel@tonic-gate * COMMKIT(TM) Software - Datakit(R) VCS Interface Release 2.0 V1 41*7c478bd9Sstevel@tonic-gate */ 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate #include <fcntl.h> 44*7c478bd9Sstevel@tonic-gate #include "dk.h" 45*7c478bd9Sstevel@tonic-gate #include <stdio.h> 46*7c478bd9Sstevel@tonic-gate #include <signal.h> 47*7c478bd9Sstevel@tonic-gate #define SIGRTN void 48*7c478bd9Sstevel@tonic-gate #include <setjmp.h> 49*7c478bd9Sstevel@tonic-gate #include <sysexits.h> 50*7c478bd9Sstevel@tonic-gate #include <errno.h> 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate 53*7c478bd9Sstevel@tonic-gate #define DK_DEFWAIT 89 /* default time to wait for dial return */ 54*7c478bd9Sstevel@tonic-gate #define DK_MAXWAIT 600 /* maximum wait to allow the caller - 10 min */ 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate GLOBAL unsigned int dk_timewait = DK_DEFWAIT; /* Caller to dkdial might modify */ 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate static char Conn_Msg[] = "Can't connect to %s: %s\n"; 60*7c478bd9Sstevel@tonic-gate static char Resp_Msg[] = "No response from Datakit"; 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate static SIGRTN timout(); /* Alarm signal handler */ 63*7c478bd9Sstevel@tonic-gate static void setalarm(), usralarm(); 64*7c478bd9Sstevel@tonic-gate EXTERN int dkndial(); 65*7c478bd9Sstevel@tonic-gate static int Elapsed; /* Alarm time elapsed during dial */ 66*7c478bd9Sstevel@tonic-gate static int Timer; /* Current alarm setting */ 67*7c478bd9Sstevel@tonic-gate static short TimeErr; /* Alarm clock rang */ 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate extern char *getenv(); 70*7c478bd9Sstevel@tonic-gate EXTERN int dk_verbose, dk_errno; 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate GLOBAL int 73*7c478bd9Sstevel@tonic-gate dkdial(dest) 74*7c478bd9Sstevel@tonic-gate char *dest; 75*7c478bd9Sstevel@tonic-gate { 76*7c478bd9Sstevel@tonic-gate return(dkndial(dest, atoi(getenv("DKINTF")))); 77*7c478bd9Sstevel@tonic-gate } 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate GLOBAL int 80*7c478bd9Sstevel@tonic-gate dkndial(dest, intf) 81*7c478bd9Sstevel@tonic-gate char *dest; 82*7c478bd9Sstevel@tonic-gate { 83*7c478bd9Sstevel@tonic-gate short fd; /* Channel Descriptor */ 84*7c478bd9Sstevel@tonic-gate SIGRTN (*SigWas)(); /* Caller's alarm handler */ 85*7c478bd9Sstevel@tonic-gate unsigned int TimWas; /* Caller's alarm clock */ 86*7c478bd9Sstevel@tonic-gate char *key; 87*7c478bd9Sstevel@tonic-gate struct diocdial { 88*7c478bd9Sstevel@tonic-gate struct diocreq iocb; 89*7c478bd9Sstevel@tonic-gate char dialstring[128]; 90*7c478bd9Sstevel@tonic-gate } ioreq; 91*7c478bd9Sstevel@tonic-gate char dial_dev[32]; 92*7c478bd9Sstevel@tonic-gate 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate sprintf(dial_dev, "/dev/dk/dial%d", intf); 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate /* 97*7c478bd9Sstevel@tonic-gate ** Clear our elapsed time and save caller's alarm stuff. 98*7c478bd9Sstevel@tonic-gate */ 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate Timer = Elapsed = 0; 101*7c478bd9Sstevel@tonic-gate SigWas = signal(SIGALRM, timout); 102*7c478bd9Sstevel@tonic-gate TimWas = alarm(0); 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* 105*7c478bd9Sstevel@tonic-gate ** If requested timeout interval is unreasonable, use the default. 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate if ((dk_timewait == 0) || (dk_timewait > DK_MAXWAIT)) 109*7c478bd9Sstevel@tonic-gate dk_timewait = DK_DEFWAIT; 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate /* 112*7c478bd9Sstevel@tonic-gate ** Do an alarm protected open of the dial device 113*7c478bd9Sstevel@tonic-gate */ 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate setalarm(dk_timewait); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate if ((fd = open(dial_dev, O_RDWR)) < 0) { 118*7c478bd9Sstevel@tonic-gate setalarm(0); 119*7c478bd9Sstevel@tonic-gate if (dk_verbose) 120*7c478bd9Sstevel@tonic-gate fprintf(stderr, "dkdial: Can't open %s\n", dial_dev); 121*7c478bd9Sstevel@tonic-gate usralarm(TimWas, SigWas); 122*7c478bd9Sstevel@tonic-gate if (errno == EBUSY) 123*7c478bd9Sstevel@tonic-gate return(dk_errno = -EX_TEMPFAIL); 124*7c478bd9Sstevel@tonic-gate else 125*7c478bd9Sstevel@tonic-gate return(dk_errno = -EX_OSFILE); 126*7c478bd9Sstevel@tonic-gate } 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate /* 129*7c478bd9Sstevel@tonic-gate ** If the caller has a DKKEY, use it. 130*7c478bd9Sstevel@tonic-gate */ 131*7c478bd9Sstevel@tonic-gate 132*7c478bd9Sstevel@tonic-gate if((key = getenv("DKKEY")) != NULL && getuid() == geteuid()) 133*7c478bd9Sstevel@tonic-gate sprintf(ioreq.dialstring, "%s\n%s", dest, key); 134*7c478bd9Sstevel@tonic-gate else 135*7c478bd9Sstevel@tonic-gate strcpy(ioreq.dialstring, dest); 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate ioreq.iocb.req_traffic = 0; 138*7c478bd9Sstevel@tonic-gate ioreq.iocb.req_1param = 0; 139*7c478bd9Sstevel@tonic-gate ioreq.iocb.req_2param = 0; 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate /* 142*7c478bd9Sstevel@tonic-gate ** Try to dial the call. If the alarm expires during the ioctl, 143*7c478bd9Sstevel@tonic-gate ** the ioctl will return in error. 144*7c478bd9Sstevel@tonic-gate */ 145*7c478bd9Sstevel@tonic-gate 146*7c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIODIAL, &ioreq) < 0) { 147*7c478bd9Sstevel@tonic-gate setalarm(0); 148*7c478bd9Sstevel@tonic-gate if (dk_verbose) 149*7c478bd9Sstevel@tonic-gate if (TimeErr) 150*7c478bd9Sstevel@tonic-gate fprintf(stderr, Conn_Msg, Resp_Msg, ioreq.dialstring); 151*7c478bd9Sstevel@tonic-gate else 152*7c478bd9Sstevel@tonic-gate fprintf(stderr, Conn_Msg, ioreq.dialstring, dkerr(ioreq.iocb.req_error)); 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate setalarm(2); /* Don't wait forever on close */ 155*7c478bd9Sstevel@tonic-gate close(fd); 156*7c478bd9Sstevel@tonic-gate usralarm(TimWas, SigWas); 157*7c478bd9Sstevel@tonic-gate if (errno == EBUSY) 158*7c478bd9Sstevel@tonic-gate return(-dkerrmap(dk_errno = -EX_TEMPFAIL)); 159*7c478bd9Sstevel@tonic-gate else 160*7c478bd9Sstevel@tonic-gate return(-dkerrmap(dk_errno = ioreq.iocb.req_error)); 161*7c478bd9Sstevel@tonic-gate } 162*7c478bd9Sstevel@tonic-gate usralarm(TimWas, SigWas); 163*7c478bd9Sstevel@tonic-gate return (fd); 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate /* 167*7c478bd9Sstevel@tonic-gate ** timout() is the alarm clock signal handling routine. It is called 168*7c478bd9Sstevel@tonic-gate ** whenever the alarm clock expires during dial processing. 169*7c478bd9Sstevel@tonic-gate */ 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 172*7c478bd9Sstevel@tonic-gate static SIGRTN 173*7c478bd9Sstevel@tonic-gate timout(arg) 174*7c478bd9Sstevel@tonic-gate int arg; 175*7c478bd9Sstevel@tonic-gate { 176*7c478bd9Sstevel@tonic-gate TimeErr++; 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate 179*7c478bd9Sstevel@tonic-gate /* 180*7c478bd9Sstevel@tonic-gate ** setalarm() is called to request an alarm at a future time. The residual 181*7c478bd9Sstevel@tonic-gate ** from the previous alarm (if any) is added to the elapsed time counter. 182*7c478bd9Sstevel@tonic-gate */ 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate static void 185*7c478bd9Sstevel@tonic-gate setalarm(Seconds) 186*7c478bd9Sstevel@tonic-gate { 187*7c478bd9Sstevel@tonic-gate TimeErr = 0; 188*7c478bd9Sstevel@tonic-gate (void) signal(SIGALRM, timout); 189*7c478bd9Sstevel@tonic-gate Elapsed += Timer - alarm(Seconds); 190*7c478bd9Sstevel@tonic-gate Timer = Seconds; 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate /* 194*7c478bd9Sstevel@tonic-gate ** usralarm() is used to restore the alarm service for the caller. 195*7c478bd9Sstevel@tonic-gate */ 196*7c478bd9Sstevel@tonic-gate 197*7c478bd9Sstevel@tonic-gate static void 198*7c478bd9Sstevel@tonic-gate usralarm(TimWas, SigWas) 199*7c478bd9Sstevel@tonic-gate int TimWas; /* Caller's alarm clock */ 200*7c478bd9Sstevel@tonic-gate SIGRTN (*SigWas)(); /* Caller's alarm handler */ 201*7c478bd9Sstevel@tonic-gate { 202*7c478bd9Sstevel@tonic-gate Elapsed += Timer - alarm(0); 203*7c478bd9Sstevel@tonic-gate (void) signal(SIGALRM, SigWas); 204*7c478bd9Sstevel@tonic-gate if (TimWas > 0) { 205*7c478bd9Sstevel@tonic-gate TimWas -= Elapsed; 206*7c478bd9Sstevel@tonic-gate if (TimWas < 2) 207*7c478bd9Sstevel@tonic-gate TimWas = 2; 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate alarm(TimWas); 210*7c478bd9Sstevel@tonic-gate } 211