1 /* 2 * Copyright (c) 1983 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)v831.c 5.2 (Berkeley) 09/13/88"; 20 #endif /* not lint */ 21 22 /* 23 * Routines for dialing up on Vadic 831 24 */ 25 #include <sys/time.h> 26 27 #include "tip.h" 28 29 int v831_abort(); 30 static int alarmtr(); 31 extern errno; 32 33 static jmp_buf jmpbuf; 34 static int child = -1; 35 36 v831_dialer(num, acu) 37 char *num, *acu; 38 { 39 int status, pid, connected = 1; 40 register int timelim; 41 42 if (boolean(value(VERBOSE))) 43 printf("\nstarting call..."); 44 #ifdef DEBUG 45 printf ("(acu=%s)\n", acu); 46 #endif 47 if ((AC = open(acu, O_RDWR)) < 0) { 48 if (errno == EBUSY) 49 printf("line busy..."); 50 else 51 printf("acu open error..."); 52 return (0); 53 } 54 if (setjmp(jmpbuf)) { 55 kill(child, SIGKILL); 56 close(AC); 57 return (0); 58 } 59 signal(SIGALRM, alarmtr); 60 timelim = 5 * strlen(num); 61 alarm(timelim < 30 ? 30 : timelim); 62 if ((child = fork()) == 0) { 63 /* 64 * ignore this stuff for aborts 65 */ 66 signal(SIGALRM, SIG_IGN); 67 signal(SIGINT, SIG_IGN); 68 signal(SIGQUIT, SIG_IGN); 69 sleep(2); 70 exit(dialit(num, acu) != 'A'); 71 } 72 /* 73 * open line - will return on carrier 74 */ 75 if ((FD = open(DV, O_RDWR)) < 0) { 76 #ifdef DEBUG 77 printf("(after open, errno=%d)\n", errno); 78 #endif 79 if (errno == EIO) 80 printf("lost carrier..."); 81 else 82 printf("dialup line open failed..."); 83 alarm(0); 84 kill(child, SIGKILL); 85 close(AC); 86 return (0); 87 } 88 alarm(0); 89 #ifdef notdef 90 ioctl(AC, TIOCHPCL, 0); 91 #endif 92 signal(SIGALRM, SIG_DFL); 93 while ((pid = wait(&status)) != child && pid != -1) 94 ; 95 if (status) { 96 close(AC); 97 return (0); 98 } 99 return (1); 100 } 101 102 static 103 alarmtr() 104 { 105 106 alarm(0); 107 longjmp(jmpbuf, 1); 108 } 109 110 /* 111 * Insurance, for some reason we don't seem to be 112 * hanging up... 113 */ 114 v831_disconnect() 115 { 116 struct sgttyb cntrl; 117 118 sleep(2); 119 #ifdef DEBUG 120 printf("[disconnect: FD=%d]\n", FD); 121 #endif 122 if (FD > 0) { 123 ioctl(FD, TIOCCDTR, 0); 124 ioctl(FD, TIOCGETP, &cntrl); 125 cntrl.sg_ispeed = cntrl.sg_ospeed = 0; 126 ioctl(FD, TIOCSETP, &cntrl); 127 ioctl(FD, TIOCNXCL, (struct sgttyb *)NULL); 128 } 129 close(FD); 130 } 131 132 v831_abort() 133 { 134 135 #ifdef DEBUG 136 printf("[abort: AC=%d]\n", AC); 137 #endif 138 sleep(2); 139 if (child > 0) 140 kill(child, SIGKILL); 141 if (AC > 0) 142 ioctl(FD, TIOCNXCL, (struct sgttyb *)NULL); 143 close(AC); 144 if (FD > 0) 145 ioctl(FD, TIOCCDTR, 0); 146 close(FD); 147 } 148 149 /* 150 * Sigh, this probably must be changed at each site. 151 */ 152 struct vaconfig { 153 char *vc_name; 154 char vc_rack; 155 char vc_modem; 156 } vaconfig[] = { 157 { "/dev/cua0",'4','0' }, 158 { "/dev/cua1",'4','1' }, 159 { 0 } 160 }; 161 162 #define pc(x) (c = x, write(AC,&c,1)) 163 #define ABORT 01 164 #define SI 017 165 #define STX 02 166 #define ETX 03 167 168 static 169 dialit(phonenum, acu) 170 register char *phonenum; 171 char *acu; 172 { 173 register struct vaconfig *vp; 174 struct sgttyb cntrl; 175 char c, *sanitize(); 176 int i, two = 2; 177 178 phonenum = sanitize(phonenum); 179 #ifdef DEBUG 180 printf ("(dial phonenum=%s)\n", phonenum); 181 #endif 182 if (*phonenum == '<' && phonenum[1] == 0) 183 return ('Z'); 184 for (vp = vaconfig; vp->vc_name; vp++) 185 if (strcmp(vp->vc_name, acu) == 0) 186 break; 187 if (vp->vc_name == 0) { 188 printf("Unable to locate dialer (%s)\n", acu); 189 return ('K'); 190 } 191 ioctl(AC, TIOCGETP, &cntrl); 192 cntrl.sg_ispeed = cntrl.sg_ospeed = B2400; 193 cntrl.sg_flags = RAW | EVENP | ODDP; 194 ioctl(AC, TIOCSETP, &cntrl); 195 ioctl(AC, TIOCFLUSH, &two); 196 pc(STX); 197 pc(vp->vc_rack); 198 pc(vp->vc_modem); 199 while (*phonenum && *phonenum != '<') 200 pc(*phonenum++); 201 pc(SI); 202 pc(ETX); 203 sleep(1); 204 i = read(AC, &c, 1); 205 #ifdef DEBUG 206 printf("read %d chars, char=%c, errno %d\n", i, c, errno); 207 #endif 208 if (i != 1) 209 c = 'M'; 210 if (c == 'B' || c == 'G') { 211 char cc, oc = c; 212 213 pc(ABORT); 214 read(AC, &cc, 1); 215 #ifdef DEBUG 216 printf("abort response=%c\n", cc); 217 #endif 218 c = oc; 219 v831_disconnect(); 220 } 221 close(AC); 222 #ifdef DEBUG 223 printf("dialit: returns %c\n", c); 224 #endif 225 return (c); 226 } 227 228 static char * 229 sanitize(s) 230 register char *s; 231 { 232 static char buf[128]; 233 register char *cp; 234 235 for (cp = buf; *s; s++) { 236 if (!isdigit(*s) && *s == '<' && *s != '_') 237 continue; 238 if (*s == '_') 239 *s = '='; 240 *cp++ = *s; 241 } 242 *cp++ = 0; 243 return (buf); 244 } 245