Home | History | Annotate | Line # | Download | only in aculib
v831.c revision 1.9
      1 /*	$NetBSD: v831.c,v 1.9 2003/08/07 11:16:23 agc Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1983, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the University nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 #ifndef lint
     34 #if 0
     35 static char sccsid[] = "@(#)v831.c	8.1 (Berkeley) 6/6/93";
     36 #endif
     37 __RCSID("$NetBSD: v831.c,v 1.9 2003/08/07 11:16:23 agc Exp $");
     38 #endif /* not lint */
     39 
     40 /*
     41  * Routines for dialing up on Vadic 831
     42  */
     43 #include "tip.h"
     44 
     45 static jmp_buf jmpbuf;
     46 static int child = -1;
     47 
     48 static	void	alarmtr __P((int));
     49 static	int	dialit __P((char *, char *));
     50 static	char   *sanitize __P((char *));
     51 
     52 int
     53 v831_dialer(num, acu)
     54         char *num, *acu;
     55 {
     56         int status, pid;
     57         int timelim;
     58 
     59         if (boolean(value(VERBOSE)))
     60                 printf("\nstarting call...");
     61 #ifdef DEBUG
     62         printf ("(acu=%s)\n", acu);
     63 #endif
     64         if ((AC = open(acu, O_RDWR)) < 0) {
     65                 if (errno == EBUSY)
     66                         printf("line busy...");
     67                 else
     68                         printf("acu open error...");
     69                 return (0);
     70         }
     71         if (setjmp(jmpbuf)) {
     72                 kill(child, SIGKILL);
     73                 close(AC);
     74                 return (0);
     75         }
     76         signal(SIGALRM, alarmtr);
     77         timelim = 5 * strlen(num);
     78         alarm(timelim < 30 ? 30 : timelim);
     79         if ((child = fork()) == 0) {
     80                 /*
     81                  * ignore this stuff for aborts
     82                  */
     83                 signal(SIGALRM, SIG_IGN);
     84 		signal(SIGINT, SIG_IGN);
     85                 signal(SIGQUIT, SIG_IGN);
     86                 sleep(2);
     87                 exit(dialit(num, acu) != 'A');
     88         }
     89         /*
     90          * open line - will return on carrier
     91          */
     92         if ((FD = open(DV, O_RDWR)) < 0) {
     93 #ifdef DEBUG
     94                 printf("(after open, errno=%d)\n", errno);
     95 #endif
     96                 if (errno == EIO)
     97                         printf("lost carrier...");
     98                 else
     99                         printf("dialup line open failed...");
    100                 alarm(0);
    101                 kill(child, SIGKILL);
    102                 close(AC);
    103                 return (0);
    104         }
    105         alarm(0);
    106         signal(SIGALRM, SIG_DFL);
    107         while ((pid = wait(&status)) != child && pid != -1)
    108                 ;
    109         if (status) {
    110                 close(AC);
    111                 return (0);
    112         }
    113         return (1);
    114 }
    115 
    116 static void
    117 alarmtr(dummy)
    118 	int dummy;
    119 {
    120 
    121         alarm(0);
    122         longjmp(jmpbuf, 1);
    123 }
    124 
    125 /*
    126  * Insurance, for some reason we don't seem to be
    127  *  hanging up...
    128  */
    129 void
    130 v831_disconnect()
    131 {
    132 	struct termios	cntrl;
    133 
    134         sleep(2);
    135 #ifdef DEBUG
    136         printf("[disconnect: FD=%d]\n", FD);
    137 #endif
    138         if (FD > 0) {
    139                 ioctl(FD, TIOCCDTR, 0);
    140 		tcgetattr(FD, &cntrl);
    141 		cfsetospeed(&cntrl, 0);
    142 		cfsetispeed(&cntrl, 0);
    143 		tcsetattr(FD, TCSAFLUSH, &cntrl);
    144                 ioctl(FD, TIOCNXCL, NULL);
    145         }
    146         close(FD);
    147 }
    148 
    149 void
    150 v831_abort()
    151 {
    152 
    153 #ifdef DEBUG
    154         printf("[abort: AC=%d]\n", AC);
    155 #endif
    156         sleep(2);
    157         if (child > 0)
    158                 kill(child, SIGKILL);
    159         if (AC > 0)
    160                 ioctl(FD, TIOCNXCL, NULL);
    161                 close(AC);
    162         if (FD > 0)
    163                 ioctl(FD, TIOCCDTR, 0);
    164         close(FD);
    165 }
    166 
    167 /*
    168  * Sigh, this probably must be changed at each site.
    169  */
    170 struct vaconfig {
    171 	char	*vc_name;
    172 	char	vc_rack;
    173 	char	vc_modem;
    174 } vaconfig[] = {
    175 	{ "/dev/cua0",'4','0' },
    176 	{ "/dev/cua1",'4','1' },
    177 	{ 0 }
    178 };
    179 
    180 #define pc(x)	(c = x, write(AC,&c,1))
    181 #define ABORT	01
    182 #define SI	017
    183 #define STX	02
    184 #define ETX	03
    185 
    186 static int
    187 dialit(phonenum, acu)
    188 	char *phonenum;
    189 	char *acu;
    190 {
    191         struct vaconfig *vp;
    192 	struct termios cntrl;
    193         char c;
    194         int i;
    195 
    196         phonenum = sanitize(phonenum);
    197 #ifdef DEBUG
    198         printf ("(dial phonenum=%s)\n", phonenum);
    199 #endif
    200         if (*phonenum == '<' && phonenum[1] == 0)
    201                 return ('Z');
    202 	for (vp = vaconfig; vp->vc_name; vp++)
    203 		if (strcmp(vp->vc_name, acu) == 0)
    204 			break;
    205 	if (vp->vc_name == 0) {
    206 		printf("Unable to locate dialer (%s)\n", acu);
    207 		return ('K');
    208 	}
    209 	tcgetattr(AC, &cntrl);
    210 	cfsetospeed(&cntrl, B2400);
    211 	cfsetispeed(&cntrl, B2400);
    212 	cntrl.c_cflag |= PARODD | PARENB;
    213 	cntrl.c_lflag &= ~(ISIG | ICANON);
    214 	tcsetattr(AC, TCSANOW, &cntrl);
    215 	tcflush(AC, TCIOFLUSH);
    216         pc(STX);
    217 	pc(vp->vc_rack);
    218 	pc(vp->vc_modem);
    219 	while (*phonenum && *phonenum != '<')
    220 		pc(*phonenum++);
    221         pc(SI);
    222 	pc(ETX);
    223         sleep(1);
    224         i = read(AC, &c, 1);
    225 #ifdef DEBUG
    226         printf("read %d chars, char=%c, errno %d\n", i, c, errno);
    227 #endif
    228         if (i != 1)
    229 		c = 'M';
    230         if (c == 'B' || c == 'G') {
    231                 char cc, oc = c;
    232 
    233                 pc(ABORT);
    234                 read(AC, &cc, 1);
    235 #ifdef DEBUG
    236                 printf("abort response=%c\n", cc);
    237 #endif
    238                 c = oc;
    239                 v831_disconnect();
    240         }
    241         close(AC);
    242 #ifdef DEBUG
    243         printf("dialit: returns %c\n", c);
    244 #endif
    245         return (c);
    246 }
    247 
    248 static char *
    249 sanitize(s)
    250 	char *s;
    251 {
    252         static char buf[128];
    253         char *cp;
    254 
    255         for (cp = buf; *s && buf + sizeof buf - cp > 1; s++) {
    256 		if (!isdigit((unsigned char)*s) && *s == '<' && *s != '_')
    257 			continue;
    258 		if (*s == '_')
    259 			*s = '=';
    260 		*cp++ = *s;
    261 	}
    262         *cp++ = 0;
    263         return (buf);
    264 }
    265