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