home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume21 / ecu / part27 < prev    next >
Encoding:
Text File  |  1991-08-05  |  53.4 KB  |  1,845 lines

  1. Newsgroups: comp.sources.misc
  2. From: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
  3. Subject:  v21i079:  ecu - ECU async comm package rev 3.10, Part27/37
  4. Message-ID: <1991Aug4.163124.18914@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 72df10a56514d67e609619069cdfd5fb
  6. Date: Sun, 4 Aug 1991 16:31:24 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: Warren Tucker <wht@n4hgf.Mt-Park.GA.US>
  10. Posting-number: Volume 21, Issue 79
  11. Archive-name: ecu/part27
  12. Environment: SCO, XENIX, ISC
  13. Supersedes: ecu3: Volume 16, Issue 25-59
  14.  
  15. ---- Cut Here and feed the following to sh ----
  16. #!/bin/sh
  17. # this is ecu310.27 (part 27 of ecu310)
  18. # do not concatenate these parts, unpack them in order with /bin/sh
  19. # file gendial/dceTBPlus.c continued
  20. #
  21. if touch 2>&1 | fgrep 'amc' > /dev/null
  22.  then TOUCH=touch
  23.  else TOUCH=true
  24. fi
  25. if test ! -r _shar_seq_.tmp; then
  26.     echo 'Please unpack part 1 first!'
  27.     exit 1
  28. fi
  29. (read Scheck
  30.  if test "$Scheck" != 27; then
  31.     echo Please unpack part "$Scheck" next!
  32.     exit 1
  33.  else
  34.     exit 0
  35.  fi
  36. ) < _shar_seq_.tmp || exit 1
  37. if test ! -f _shar_wnt_.tmp; then
  38.     echo 'x - still skipping gendial/dceTBPlus.c'
  39. else
  40. echo 'x - continuing file gendial/dceTBPlus.c'
  41. sed 's/^X//' << 'SHAR_EOF' >> 'gendial/dceTBPlus.c' &&
  42. X    S50=0       use automatic connect speed determination
  43. X    S51=252     set serial port baud rate automatically (no typeahead)
  44. X    S52=2       go on hook when DTR drops and reset to NV-RAM
  45. X    S53=1       DCD signal follows remote carrier, DSR on when modem ready
  46. X    S54=3       pass BREAK signal to remote modem
  47. X    S55=0       respond to command escape sequence
  48. X    S58=2       DTE uses CTS/RTS flow control.
  49. X    S64=1       ignore characters sent by DTE while answering
  50. X    S66=0       don't lock interface speed, just go with the flow.
  51. X    S68=255     DCE uses whatever flow control DTE uses
  52. X    S92=1       PEP tones at the end of answer sequence
  53. X    S95=0       no MNP
  54. X    S110=255    use data compression when the remote modem requests it.
  55. X    S111=255    accept any protocol
  56. X--------------------------------------------------------------------------*/
  57. Xvoid
  58. Xinit_TBPlus()
  59. X{
  60. Xregister itmp;
  61. Xint maxretry = 4;
  62. Xchar *init0 = "AT&FE0F1M0Q4V1X3\r";
  63. Xchar *init1 = "ATS0=1S2=1S11=50S45=1S48=1S50=0S51=252S52=2S53=1S54=3\r";
  64. Xchar *init2 = "ATS55=0S58=2S64=1S66=0S68=255S92=1S95=0S110=255S111=255\r";
  65. X
  66. X    DEBUG(7,"INITIALIZING %s\n",dce_name);
  67. X    ltoggleDTR(0L);
  68. X    sync_Telebit();
  69. X
  70. X    /*
  71. X     * set to factory default (bless them for this command)
  72. X     * and a few initial beachhead values
  73. X     */
  74. X    for(itmp = 0; itmp < maxretry; itmp++)
  75. X    {
  76. X        lwrite(init0);
  77. X        if(lread(2) == rOk)
  78. X            break;
  79. X    }
  80. X    if(itmp == maxretry)
  81. X    {
  82. X        DEBUG(1,"INIT FAILED (init0)\n",0);
  83. X        myexit(RC_FAIL | RCE_TIMOUT);
  84. X    }
  85. X
  86. X    /*
  87. X     * send initialization string 1
  88. X     */
  89. X    for(itmp = 0; itmp < maxretry; itmp++)
  90. X    {
  91. X        lwrite(init1);
  92. X        if(lread(2) == rOk)
  93. X            break;
  94. X    }
  95. X    if(itmp == maxretry)
  96. X    {
  97. X        DEBUG(1,"INIT FAILED (init1)\n",0);
  98. X        myexit(RC_FAIL | RCE_TIMOUT);
  99. X    }
  100. X
  101. X    /*
  102. X     * send initialization string 2
  103. X     */
  104. X    for(itmp = 0; itmp < maxretry; itmp++)
  105. X    {
  106. X        lwrite(init2);
  107. X        if(lread(2) == rOk)
  108. X            break;
  109. X    }
  110. X    if(itmp == maxretry)
  111. X    {
  112. X        DEBUG(1,"INIT FAILED (init2)\n",0);
  113. X        myexit(RC_FAIL | RCE_TIMOUT);
  114. X    }
  115. X
  116. X}    /* end of init_TBPlus */
  117. X
  118. X/*+-------------------------------------------------------------------------
  119. X    DCE_hangup() - issue hangup command to DCE
  120. X
  121. XThis function should do whatever is necessary to ensure
  122. X1) any active connection is terminated
  123. X2) the DCE is ready to receive an incoming call if DTR is asserted
  124. X3) the DCE will not accept an incoming call if DTR is false
  125. X
  126. XThe function should return when done.
  127. X
  128. XAny necessary switch setting or other configuration necessary for this
  129. Xfunction to succeed should be documented at the top of the module.
  130. X--------------------------------------------------------------------------*/
  131. Xvoid
  132. XDCE_hangup()
  133. X{
  134. X#ifdef TRUSTING
  135. X    DEBUG(7,"--> reseting %s\n",dce_name);
  136. X    ltoggleDTR(0L);
  137. X    lwrite("ATZ\r");
  138. X    (void)lread_ignore(1);
  139. X#else /* !TRUSTING */
  140. X    init_TBPlus();
  141. X#endif
  142. X
  143. X}    /* end of DCE_hangup */
  144. X
  145. X/*+-------------------------------------------------------------------------
  146. X    DCE_dial(telno) - dial a remote DCE
  147. X
  148. XThis function should connect to the remote DCE and use any success
  149. Xindication to modify the tty baud rate if necessary before returning.
  150. X
  151. XUpon successful connection, return 0.
  152. X
  153. XUpon unsuccessful connection, return RC_FAIL or'd with an appropriate
  154. XRCE_XXX value from dialer.h.
  155. X
  156. Xlwrite() is used to write to the DCE.
  157. X
  158. Xlread() and lread_ignore() are used to read from the DCE.  Read timeouts
  159. Xfrom calling lread() will result automatically in the proper error
  160. Xtermination of the program.  Read timeouts from calling lread_ignore()
  161. Xreturn -1; you handle the execption here.
  162. X
  163. XAny necessary coding of phone numbers, switch settings or other
  164. Xconfiguration necessary for this function to succeed should be
  165. Xdocumented at the top of the module.
  166. X
  167. XTelebit Plus-specific comments:
  168. X S0=0        dont allow connect while dialing
  169. X S54=3       pass BREAK signal to remote modem
  170. X S64=0       abort dialing if characters sent by DTE
  171. X S66=1       lock the interface speed
  172. X S110=0      disable data compression unless requested otherwise
  173. X--------------------------------------------------------------------------*/
  174. Xint
  175. XDCE_dial(telno)
  176. Xchar *telno;
  177. X{
  178. Xchar cmd[128];
  179. Xchar phone[50];
  180. Xint s111_set = 0;
  181. Xint timeout;
  182. Xint result;
  183. Xint rrings = 0;
  184. Xlong then;
  185. Xlong now;
  186. Xchar *cptr;
  187. Xchar *dialout_default = "ATS0=0S7=40S54=3S64=0S66=1S110=0\r";
  188. X#define MDVALID     "0123456789CcEeFfKkMmNnPpRrSsUuWwXx*#,!/()-"
  189. X
  190. X/* preliminary setup */
  191. X    translate("=,-,",telno);
  192. X    if(strspn(telno,MDVALID) != strlen(telno))
  193. X    {
  194. X        DEBUG(1,"phone number has invalid characters\n",0);
  195. X        return(RC_FAIL | RCE_PHNO);
  196. X    }
  197. X    if(decode_phone_number(telno,phone,sizeof(phone)))
  198. X    {
  199. X        DEBUG(1,"phone number too long\n",0);
  200. X        return(RC_FAIL | RCE_PHNO);
  201. X    }
  202. X
  203. X/* walk through dialer codes, doing custom setup */
  204. X    strcpy(cmd,"AT");
  205. X    cptr = cmd + strlen(cmd);
  206. X    if(dialer_codes['C' - 'A'])
  207. X    {
  208. X        DEBUG(5,"COMPRESSION requested\n",0);
  209. X        strcat(cmd,"S110=1");
  210. X    }
  211. X    if(dialer_codes['E' - 'A'])
  212. X    {
  213. X        DEBUG(5,"ECHO SUPPRESSION requested\n",0);
  214. X        strcat(cmd,"S121=1");
  215. X    }
  216. X    if(dialer_codes['F' - 'A'])
  217. X    {
  218. X        DEBUG(5,"XON/XOFF FLOW CONTROL requested\n",0);
  219. X        strcat(cmd,"S58=3");
  220. X    }
  221. X    if(dialer_codes['K' - 'A'])
  222. X    {
  223. X        DEBUG(5,"KERMIT requested\n",0);
  224. X        strcat(cmd,"S111=10");
  225. X        s111_set++;
  226. X    }
  227. X    if(dialer_codes['X' - 'A'])
  228. X    {
  229. X        DEBUG(5,"XMODEM requested\n",0);
  230. X        strcat(cmd,"S111=20");
  231. X        s111_set++;
  232. X    }
  233. X    if(dialer_codes['U' - 'A'])
  234. X    {
  235. X        DEBUG(5,"UUCP requested\n",0);
  236. X        strcat(cmd,"S111=30");
  237. X        s111_set++;
  238. X    }
  239. X    if(dialer_codes['M' - 'A'])
  240. X    {
  241. X        DEBUG(5,"MNP requested\n",0);
  242. X        strcat(cmd,"S95=1");
  243. X    }
  244. X
  245. X    if((dialer_codes['P' - 'A']) || s111_set || (hiCBAUD >= B9600))
  246. X    {
  247. X        if(hiCBAUD < B9600)
  248. X        {
  249. X            DEBUG(1,"baud rate not high enough for PEP\n",0);
  250. X            return(RC_FAIL | RCE_SPEED);
  251. X        }
  252. X        if(dialer_codes['P' - 'A'])
  253. X            DEBUG(5,"PEP requested\n",0);
  254. X        else
  255. X            DEBUG(5,"PEP inferred: speed >= 9600\n",0);
  256. X
  257. X        dialer_codes['P' - 'A'] = 1;
  258. X        strcat(cmd,"S50=255");
  259. X    }
  260. X
  261. X
  262. X    DEBUG(6,"--> issuing default setup command\n",0);
  263. X    sync_Telebit();
  264. X    lwrite(dialout_default);
  265. X    if(lread(2) != rOk)
  266. X    {
  267. X        DEBUG(1,"default dialout setup failed\n",0);
  268. X        return(RC_FAIL | RCE_NULL);
  269. X    }
  270. X
  271. X/* issue the custom setup command */
  272. X    if(*cptr)
  273. X    {
  274. X        DEBUG(5,"--> issuing custom setup cmd\n",0);
  275. X        strcat(cmd,"\r");
  276. X        sync_Telebit();
  277. X        lwrite(cmd);
  278. X        if(lread(2) != rOk)
  279. X        {
  280. X            DEBUG(1,"custom modem setup failed\n",0);
  281. X            return(RC_FAIL | RCE_NULL);
  282. X        }
  283. X    }
  284. X
  285. X/*
  286. X * calculate a timeout for the connect
  287. X * allow a minimum of 40 seconds, but if PEP, 90
  288. X * also if long distance (North American calculation here)
  289. X * make it 132 (S7 is calculated as timeout * .9)
  290. X */
  291. X    timeout = 40;
  292. X    if((phone[0] == '1') && (phone[0] != '0'))
  293. X        timeout = 132;
  294. X    if((timeout < 90) && dialer_codes['P' - 'A'])
  295. X        timeout = 90;
  296. X    for(cptr = phone; cptr = strchr(cptr,','); cptr++)
  297. X        timeout += 2;    /* add extra time for pause characters */
  298. X    DEBUG(6,"timeout waiting for connect = %d seconds\n",timeout);
  299. X
  300. X/* indicate non-root should not see DTE->DCE traffic */
  301. X    secure = 1;
  302. X
  303. X/*
  304. X * build and issue the actual dialing command
  305. X * if root, let him see number, otherwise just say "remote system"
  306. X */
  307. X    DEBUG(1,"--> dialing %s\n", (!ecu_calling & uid) ? "remote system" : telno);
  308. X#ifdef WHT
  309. X    if(!strncmp(*gargv,"ECU",3))
  310. X        dialer_codes['S' - 'A'] = 1;
  311. X#endif
  312. X    sprintf(cmd,"ATM%dS7=%dDT%s\r",
  313. X        ((dialer_codes['S' - 'A']) && !(dialer_codes['N' - 'A'])) ? 1 : 0,
  314. X        (timeout * 9) / 10,phone);
  315. X
  316. X    /* cmd string can only be 80 characters including "AT" */
  317. X    if(strlen(cmd) > 80)
  318. X    {
  319. X        DEBUG(1,"phone number string too long\n",0);
  320. X        cleanup(RC_FAIL | RCE_PHNO);
  321. X    }
  322. X
  323. X    sync_Telebit();
  324. X    lwrite(cmd);
  325. X
  326. X/* indicate non-root can see DTE->DCE traffic */
  327. X    secure = 0;
  328. X
  329. X/* wait for connect */
  330. XWAIT_FOR_CONNECT:
  331. X    time(&then);
  332. X    result = lread(timeout);
  333. X    if(!(result & rfConnect))
  334. X    {
  335. X        switch(result & rfMASK)
  336. X        {
  337. X        case rNoCarrier:
  338. X            return(RC_FAIL | ((rrings > 2) ? RCE_ANSWER : RCE_NOTONE));
  339. X        case rNoDialTone:
  340. X            return(RC_FAIL | RCE_NOTONE);
  341. X        case rBusy:
  342. X            return(RC_FAIL | RCE_BUSY);
  343. X        case rNoAnswer:
  344. X            return(RC_FAIL | RCE_ANSWER);
  345. X        case rRring:
  346. X            if(rrings++ > 7)
  347. X                return(RC_FAIL | RCE_ANSWER);
  348. X            time(&now);
  349. X            if((timeout -= ((int)(then - now))) > 0)
  350. X                goto WAIT_FOR_CONNECT;
  351. X        case rError:
  352. X        default:
  353. X            return(RC_FAIL | RCE_NULL);
  354. X        }
  355. X    }
  356. X
  357. X    return(0);        /* succeeded */
  358. X
  359. X}    /* end of DCE_dial */
  360. X
  361. X/**********************************************************
  362. X*  You probably do not need to modify the code below here *
  363. X**********************************************************/
  364. X
  365. X/*+-------------------------------------------------------------------------
  366. X    DCE_abort(sig) - dial attempt aborted
  367. X
  368. X sig =  0 if non-signal abort (read timeout, most likely)
  369. X     != 0 if non-SIGALRM signal caught
  370. X
  371. X extern int dialing set  1 if dialing request was active,
  372. X                    else 0 if hangup request was active
  373. X
  374. XThis is a chance for the DCE-specific code to do anything it
  375. Xneeds to cl,ean up after a failure.  Note that if a dialing
  376. Xcall fails, it is the responsibility of the higher-level
  377. Xprogram calling the dialer to call it again with a hangup request, so
  378. Xthis function is usually a no-op.
  379. X--------------------------------------------------------------------------*/
  380. Xvoid
  381. XDCE_abort(sig)
  382. Xint sig;
  383. X{
  384. X    DEBUG(10,"DCE_abort(%d);\n",sig);
  385. X}    /* end of DCE_abort */
  386. X
  387. X/*+-------------------------------------------------------------------------
  388. X    DCE_exit(exitcode) - "last chance for gas" in this incarnation
  389. X
  390. XThe independent portion of the dialer program calls this routine in
  391. Xlieu of exit() in every case except one (see DCE_argv_hook() below).
  392. XNormally, this function just passes it's argument to exit(), but
  393. Xany necessary post-processing can be done.  The function must,
  394. Xhowever, eventually call exit(exitcode);
  395. X--------------------------------------------------------------------------*/
  396. Xvoid
  397. XDCE_exit(exitcode)
  398. Xint exitcode;
  399. X{
  400. X    DEBUG(10,"DCE_exit(%d);\n",exitcode);
  401. X    exit(exitcode);
  402. X}    /* end of DCE_exit */
  403. X
  404. X/*+-------------------------------------------------------------------------
  405. X    DCE_argv_hook(argc,argv,optind,unrecognized_switches)
  406. X
  407. XThis hook gives DCE-specific code a chance to look over the entire
  408. Xcommand line, such as for -z Telebit processing.
  409. X
  410. Xargc andf argv are the same values passed to main(),
  411. X
  412. Xoptind is the value of optind at the end of normal getopt processing.
  413. X
  414. Xunrecognized_switches is the count of switches not handled by main().
  415. XSpecifically, -h and -x are standard switches.
  416. X
  417. XNormally, this function should just return RC_FAIL|RCE_ARGS if there are
  418. Xany unrecognized switches, otherwise zero.  If you keep your nose clean
  419. Xthough, you can do anything you need to do here and exit the program.
  420. X
  421. XNote: only simple switches (with no argument) may be used with this
  422. Xfacility if the functrion is to return,' since main()'s getopt() will
  423. Xstop processing switches if it runs into an unrecognized switch with an
  424. Xargument.
  425. X
  426. XIf the function returns a non-zero value, then the value will be passed
  427. XDIRECTLY to exit() with no further ado.  Thus, a non-zero value must be
  428. Xof the format expected by dialer program callers, with RC_FAIL set as a
  429. Xminimum.
  430. X--------------------------------------------------------------------------*/
  431. Xint
  432. XDCE_argv_hook(argc,argv,optind,unrecognized_switches)
  433. Xint argc;
  434. Xchar **argv;
  435. Xint optind;
  436. Xint unrecognized_switches;
  437. X{
  438. X    if(unrecognized_switches)
  439. X        return(RC_FAIL | RCE_ARGS);
  440. X    return(0);
  441. X}    /* end of DCE_argv_hook */
  442. X
  443. X/* vi: set tabstop=4 shiftwidth=4: */
  444. SHAR_EOF
  445. echo 'File gendial/dceTBPlus.c is complete' &&
  446. $TOUCH -am 0725125891 'gendial/dceTBPlus.c' &&
  447. chmod 0644 gendial/dceTBPlus.c ||
  448. echo 'restore of gendial/dceTBPlus.c failed'
  449. Wc_c="`wc -c < 'gendial/dceTBPlus.c'`"
  450. test 17953 -eq "$Wc_c" ||
  451.     echo 'gendial/dceTBPlus.c: original size 17953, current size' "$Wc_c"
  452. rm -f _shar_wnt_.tmp
  453. fi
  454. # ============= gendial/dceUSR24.c ==============
  455. if test -f 'gendial/dceUSR24.c' -a X"$1" != X"-c"; then
  456.     echo 'x - skipping gendial/dceUSR24.c (File already exists)'
  457.     rm -f _shar_wnt_.tmp
  458. else
  459. > _shar_wnt_.tmp
  460. echo 'x - extracting gendial/dceUSR24.c (Text)'
  461. sed 's/^X//' << 'SHAR_EOF' > 'gendial/dceUSR24.c' &&
  462. X/*+------------------------------------------------------------------------- dceUSR24.c - DCE-specific portion of generic SCO UUCP dialer
  463. X    Driver for USR Courier 2400
  464. X    wht@n4hgf.Mt-Park.GA.US
  465. X
  466. X Necessary DCE switch setting or other configuration:
  467. X   enable onhook upon loss of DTR
  468. X
  469. XThis dialer does not use the X6 quick dial feature, nor voice detection.
  470. XQuick dial tone recognition often fqails due to the telco granting
  471. Xdial tone ahead of the actual time it is ready to accept dialing.
  472. XVoice recognition fails when dialing 0+ with a credit card, as in "Thank
  473. Xyou for using ATT" - CLICK - "VOICE".
  474. X
  475. X--------------------------------------------------------------------------*/
  476. X/*+:EDITS:*/
  477. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  478. X/*:07-25-1991-04:34-wht@n4hgf-add naps around writes */
  479. X/*:04-16-1991-18:18-wht@n4hgf-creation from template */
  480. X
  481. X#include "dialer.h"
  482. X
  483. X/*
  484. X * DCE_DTR_low_msec - milliseconds to hold DTR low to ensure DCE
  485. X *                    sees the transition; this value may be changed
  486. X *                    as necessary before each call to ltoggleDTR(),
  487. X * but, generally, a constant value will do.
  488. X */
  489. Xlong DCE_DTR_low_msec = 500L;
  490. X
  491. X/*
  492. X * DCE_DTR_high_msec - milliseconds DTR must remain high before the
  493. X *                     DCE may be expected to be ready to be commanded
  494. X */
  495. Xlong DCE_DTR_high_msec = 1000L;
  496. X
  497. X/*
  498. X * DCE_write_pase_msec - milliseconds to pause between each character
  499. X *                       sent to the DCE (zero if streaming I/O is
  500. X *                       permitted); this value may be changed as
  501. X * necessary before each call to lwrite(), but, generally, a constant
  502. X * value will do.  Note that this value is used to feed a value to nap(),
  503. X * which has a granularity of .010 seconds on UNIX/386, .020 on XENIX/286
  504. X * and .050 seconds on XENIX/86.
  505. X */
  506. Xlong DCE_write_pace_msec = 40;
  507. X
  508. X/*
  509. X * DCE_name     - short name for DCE
  510. X * DCE_revision - revision number for this module
  511. X */
  512. Xchar *DCE_name = "USR Courier 2400";
  513. Xchar *DCE_revision = "1.10";
  514. X
  515. X/*
  516. X * DCE_hangup_CBAUD - baud rate to use for hanging up DCE
  517. X *                    and readying it for dial in access
  518. X *                    (BXXX mask); use a value of zero if the speed
  519. X *                    specified by the invoker is to be used.
  520. X * This value is useful for DCEs such as the early Hayes 2400
  521. X * which are so unfortunately compatible with their 1200 predecessor
  522. X * that they refuse to answer at 2400 baud unless you last spoke to
  523. X * them at that rate. For such bad boys, use B2400 below.
  524. X */
  525. Xint DCE_hangup_CBAUD = B2400;
  526. X
  527. X/*
  528. X * DCE_results - a table of DCE response strings and a token
  529. X *               code for each; when you call lread() or lread_ignore(),
  530. X *               if the read routine detects one of the strings,
  531. X * the appropriate code is returned.  If no string matches, then
  532. X * lread()/lread_ignore examines the DCE result string for a
  533. X * numeric value; if one is found, the numeric value or'd with
  534. X * 0x4000 is returned (in this way, e.g., you can read "modem
  535. X * S registers."  If nothing agrees with this search, lread()
  536. X * will abort the program with RC|FAIL|RCE_TIMOUT, lread_ignore()
  537. X * will return -1.  You may use any value between 0 and 0x3FFFFFFF.
  538. X * This module is the only consumer  of the codes, although they
  539. X * are decoded by gendial.c's _lread()
  540. X */
  541. X#define rfConnect        0x00400000
  542. X#define rfMASK            0x000000FF
  543. X
  544. X#define rOk                0
  545. X#define rNoCarrier        1
  546. X#define rError            2
  547. X#define rNoDialTone        3
  548. X#define rBusy            4
  549. X#define rNoAnswer        5
  550. X#define rVoice            6
  551. X#define rConnect300        (7 | rfConnect)
  552. X#define rConnect1200    (8 | rfConnect)
  553. X#define rConnect2400    (9 | rfConnect)
  554. X
  555. XDCE_RESULT DCE_results[] =
  556. X{
  557. X    { "OK",                        rOk,            },
  558. X    { "NO CARRIER",                rNoCarrier,        },
  559. X    { "ERROR",                    rError            },
  560. X    { "NO DIALTONE",            rNoDialTone,    },
  561. X    { "BUSY",                    rBusy            },
  562. X    { "NO ANSWER",                rNoAnswer        },
  563. X    { "VOICE",                    rVoice            },
  564. X    { "CONNECT",                rConnect300        },
  565. X    { "CONNECT 1200",            rConnect1200    },
  566. X    { "CONNECT 2400",            rConnect2400    },
  567. X    { (char *)0,                -1                }        /* end table */
  568. X};
  569. X
  570. X/*+-------------------------------------------------------------------------
  571. X    DCE_baud_to_CBAUD(baud) - check for valid baud rates supported by DCE
  572. X
  573. X  DCE dependent function must validate baud rates supported by DCE
  574. X  returns baud rate in struct termio c_cflag fashion
  575. X  or terminates program with error
  576. X--------------------------------------------------------------------------*/
  577. Xint
  578. XDCE_baud_to_CBAUD(baud)
  579. Xunsigned int baud;
  580. X{
  581. X    switch(baud)
  582. X    {
  583. X        case 50:   return(B50);        /* delete the ones you dont handle */
  584. X        case 75:   return(B75);
  585. X        case 110:  return(B110);
  586. X        case 134:  return(B134);
  587. X        case 150:  return(B150);
  588. X        case 300:  return(B300);
  589. X        case 1200: return(B1200);
  590. X        case 2400: return(B2400);
  591. X        case 4800: return(B4800);
  592. X        case 9600: return(B9600);
  593. X
  594. X#if defined(B19200)
  595. X        case 19200: return(B19200);
  596. X#else
  597. X#ifdef EXTA
  598. X        case 19200: return(EXTA);
  599. X#endif
  600. X#endif
  601. X
  602. X#if defined(B38400)
  603. X        case 38400: return(B38400);
  604. X#else
  605. X#ifdef EXTB
  606. X        case 38400: return(EXTB);
  607. X#endif
  608. X#endif
  609. X
  610. X    }
  611. X    myexit(RC_FAIL | RCE_SPEED);
  612. X#if defined(__GNUC__) && defined(__OPTIMIZE__)
  613. X    return(0);    /* I wish this wasn't necessary to avoid warnings */
  614. X#endif
  615. X}    /* end of DCE_baud_to_CBAUD */
  616. X
  617. X/*+-------------------------------------------------------------------------
  618. X    DCE_hangup() - issue hangup command to DCE
  619. X
  620. XThis function should do whatever is necessary to ensure
  621. X1) any active connection is terminated
  622. X2) the DCE is ready to receive an incoming call if DTR is asserted
  623. X3) the DCE will not accept an incoming call if DTR is false
  624. X
  625. XThe function should return when done.
  626. X
  627. XYou must set any switches necessary to make modem hang up on loss of DTR
  628. X--------------------------------------------------------------------------*/
  629. Xvoid
  630. XDCE_hangup()
  631. X{
  632. Xstruct termio temp;
  633. Xint itmp;
  634. Xint maxretry = 4;
  635. X
  636. X    DEBUG(3,"--> reseting %s\n",DCE_name);
  637. X
  638. X    /*
  639. X     * drop DTR and pause a while
  640. X     */
  641. X    temp = dce_termio;
  642. X    temp.c_cflag &= ~CBAUD;        /* use B0 */
  643. X    ioctl(fddce,TCSETA,&temp);    /* drop DTR */
  644. X    nap((DCE_DTR_low_msec) ? DCE_DTR_low_msec : 300L);
  645. X
  646. X    /*
  647. X     * raise DTR and pause a while
  648. X     */
  649. X    ioctl(fddce,TCSETA,&dce_termio);    /* raise DTR */
  650. X    nap((DCE_DTR_high_msec) ? DCE_DTR_high_msec : 1500L);
  651. X
  652. X    /*
  653. X     * reset modem completely
  654. X     */
  655. X    lwrite("AAAAAATZ\r");
  656. X    nap(2000L);
  657. X    lflush();
  658. X
  659. X    /*
  660. X     * set up modem
  661. X     */
  662. X    for(itmp = 0; itmp < maxretry; itmp++)
  663. X    {
  664. X        lwrite("ATS0=1M0Q0V1X3\r");
  665. X        if(lread(2) == rOk)
  666. X            break;
  667. X        nap(500L);
  668. X    }
  669. X    if(itmp == maxretry)
  670. X    {
  671. X        DEBUG(1,"INIT FAILED (init0)\n",0);
  672. X        myexit(RC_FAIL | RCE_TIMOUT);
  673. X    }
  674. X
  675. X    /*
  676. X     * shut up - no result codes
  677. X     */
  678. X    nap(500L);
  679. X    lwrite("ATQ1\r");
  680. X    nap(750L);
  681. X
  682. X}    /* end of DCE_hangup */
  683. X
  684. X/*+-------------------------------------------------------------------------
  685. X    DCE_dial(telno) - dial a remote DCE
  686. X
  687. XThis function should connect to the remote DCE and use any success
  688. Xindication to modify the tty baud rate if necessary before returning.
  689. X
  690. XUpon successful connection, return 0.
  691. X
  692. XUpon unsuccessful connection, return RC_FAIL or'd with an appropriate
  693. XRCE_XXX value from dialer.h.
  694. X
  695. Xlwrite() is used to write to the DCE.
  696. X
  697. Xlread() and lread_ignore() are used to read from the DCE.  Read timeouts
  698. Xfrom calling lread() will result automatically in the proper error
  699. Xtermination of the program.  Read timeouts from calling lread_ignore()
  700. Xreturn -1; you handle the execption here.
  701. X
  702. XAny necessary coding of phone numbers, switch settings or other
  703. Xconfiguration necessary for this function to succeed should be
  704. Xdocumented at the top of the module.
  705. X--------------------------------------------------------------------------*/
  706. Xint
  707. XDCE_dial(telno)
  708. Xchar *telno;
  709. X{
  710. Xchar cmd[128];
  711. Xchar phone[50];
  712. Xlong timeout;
  713. Xint result;
  714. Xchar *cptr;
  715. Xchar *dialout_default = "ATS0=0S7=40Q0M0V1E0X3\r";
  716. X#define MDVALID     "0123456789NnSs*#,!/()-"
  717. Xstruct termio temp;
  718. Xint itmp;
  719. Xint maxretry = 4;
  720. X
  721. X/* if root, let him see number, otherwise just say "remote system" */
  722. X    DEBUG(1,"DIALING %s\n", (uid) ? "remote system" : telno);
  723. X
  724. X    /*
  725. X     * drop DTR and pause a while
  726. X     */
  727. X    temp = dce_termio;
  728. X    temp.c_cflag &= ~CBAUD;        /* use B0 */
  729. X    ioctl(fddce,TCSETA,&temp);    /* drop DTR */
  730. X    nap((DCE_DTR_low_msec) ? DCE_DTR_low_msec : 300L);
  731. X
  732. X    /*
  733. X     * raise DTR and pause a while
  734. X     */
  735. X    ioctl(fddce,TCSETA,&dce_termio);    /* raise DTR */
  736. X    nap((DCE_DTR_high_msec) ? DCE_DTR_high_msec : 1500L);
  737. X
  738. X    translate("=,-,",telno);
  739. X    if(strspn(telno,MDVALID) != strlen(telno))
  740. X    {
  741. X        DEBUG(1,"phone number has invalid characters\n",0);
  742. X        return(RC_FAIL | RCE_PHNO);
  743. X    }
  744. X    if(decode_phone_number(telno,phone,sizeof(phone)))
  745. X    {
  746. X        DEBUG(1,"phone number too long\n",0);
  747. X        return(RC_FAIL | RCE_PHNO);
  748. X    }
  749. X
  750. X    /*
  751. X     * wake up modem
  752. X     */
  753. X    DEBUG(6,"--> waking up modem\n",0);
  754. X    for(itmp = 0; itmp < maxretry; itmp++)
  755. X    {
  756. X        lwrite(dialout_default);
  757. X        if(lread(2) == rOk)
  758. X            break;
  759. X        nap(200L);
  760. X    }
  761. X    if(itmp == maxretry)
  762. X    {
  763. X        DEBUG(1,"DIAL INIT FAILED\n",0);
  764. X        myexit(RC_FAIL | RCE_TIMOUT);
  765. X    }
  766. X
  767. X    /*
  768. X     * calculate a timeout for the connect
  769. X     * allow a minimum of 40 seconds
  770. X     * if long distance (North American calculation here)
  771. X     * make it 132 (S7 is calculated as timeout * .95)
  772. X     */
  773. X    timeout = 40L;
  774. X    if((phone[0] == '1') && (phone[0] != '0'))
  775. X        timeout = 132L;
  776. X    if((timeout < 90L) && (dialer_codes['V' - 'A'] || dialer_codes['P' - 'A']))
  777. X        timeout = 90L;
  778. X    for(cptr = phone; cptr = strchr(cptr,','); cptr++)
  779. X        timeout += 2L;    /* add extra time for pause characters */
  780. X    DEBUG(6,"timeout waiting for connect = %ld seconds\n",timeout);
  781. X
  782. X    /*
  783. X     * do custom setup here to conserve 40 char max cmd for telno
  784. X     */
  785. X#ifdef WHT
  786. X    if(!strncmp(*gargv,"ECU",3))
  787. X        dialer_codes['S' - 'A'] = 1;
  788. X#endif
  789. X    sprintf(cmd,"ATM%dS7=%dS11=40T\r",
  790. X        ((dialer_codes['S' - 'A']) && !(dialer_codes['N' - 'A'])) ? 1 : 0,
  791. X        (int)((timeout * 95L) / 100L));
  792. X    DEBUG(6,"--> setting speaker, DTMF dialing and wait for carrier time\n",0);
  793. X    nap(200L);
  794. X    for(itmp = 0; itmp < maxretry; itmp++)
  795. X    {
  796. X        lwrite(cmd);
  797. X        if(lread(2) == rOk)
  798. X            break;
  799. X        nap(200L);
  800. X    }
  801. X    if(itmp == maxretry)
  802. X    {
  803. X        DEBUG(1,"DIAL INIT FAILED\n",0);
  804. X        myexit(RC_FAIL | RCE_TIMOUT);
  805. X    }
  806. X
  807. X
  808. X/* indicate non-root should not see DTE->DCE traffic */
  809. X    secure = 1;
  810. X
  811. X/*
  812. X * build and issue the actual dialing command
  813. X * if root, let him see number, otherwise just say "remote system"
  814. X */
  815. X    DEBUG(1,"--> dialing %s\n", (!ecu_calling & uid) ? "remote system" : telno);
  816. X    sprintf(cmd,"ATD%s\r",phone);
  817. X
  818. X    /* cmd string can only be 40 characters including "AT" */
  819. X    if(strlen(cmd) > 40)
  820. X    {
  821. X        DEBUG(1,"phone number string too long\n",0);
  822. X        cleanup(RC_FAIL | RCE_PHNO);
  823. X    }
  824. X    nap(200L);
  825. X    lwrite(cmd);
  826. X
  827. X/* indicate non-root can see DTE->DCE traffic */
  828. X    secure = 0;
  829. X
  830. X/* wait for connect */
  831. X    result = lread(timeout);
  832. X    if(!(result & rfConnect))
  833. X    {
  834. X        switch(result & rfMASK)
  835. X        {
  836. X        case rNoCarrier:
  837. X            return(RC_FAIL | RCE_NOCARR);
  838. X        case rVoice:    /* if you get voice, certainly wrong number */
  839. X        case rNoDialTone:
  840. X            return(RC_FAIL | RCE_NOTONE);
  841. X        case rBusy:
  842. X            return(RC_FAIL | RCE_BUSY);
  843. X        case rNoAnswer:
  844. X            return(RC_FAIL | RCE_ANSWER);
  845. X        case rError:
  846. X        default:
  847. X            return(RC_FAIL | RCE_NULL);
  848. X        }
  849. X    }
  850. X
  851. X/* indicate non-root can see DTE->DCE traffic */
  852. X    secure = 0;
  853. X    return(0);        /* succeeded */
  854. X
  855. X}    /* end of DCE_dial */
  856. X
  857. X/**********************************************************
  858. X*  You probably do not need to modify the code below here *
  859. X**********************************************************/
  860. X
  861. X/*+-------------------------------------------------------------------------
  862. X    DCE_abort(sig) - dial attempt aborted
  863. X
  864. X sig =  0 if non-signal abort (read timeout, most likely)
  865. X     != 0 if non-SIGALRM signal caught
  866. X
  867. X extern int dialing set  1 if dialing request was active,
  868. X                    else 0 if hangup request was active
  869. X
  870. XThis is a chance for the DCE-specific code to do anything it
  871. Xneeds to cl,ean up after a failure.  Note that if a dialing
  872. Xcall fails, it is the responsibility of the higher-level
  873. Xprogram calling the dialer to call it again with a hangup request, so
  874. Xthis function is usually a no-op.
  875. X--------------------------------------------------------------------------*/
  876. Xvoid
  877. XDCE_abort(sig)
  878. Xint sig;
  879. X{
  880. X    DEBUG(10,"DCE_abort(%d);\n",sig);
  881. X}    /* end of DCE_abort */
  882. X
  883. X/*+-------------------------------------------------------------------------
  884. X    DCE_exit(exitcode) - "last chance for gas" in this incarnation
  885. X
  886. XThe independent portion of the dialer program calls this routine in
  887. Xlieu of exit() in every case except one (see DCE_argv_hook() below).
  888. XNormally, this function just passes it's argument to exit(), but
  889. Xany necessary post-processing can be done.  The function must,
  890. Xhowever, eventually call exit(exitcode);
  891. X--------------------------------------------------------------------------*/
  892. Xvoid
  893. XDCE_exit(exitcode)
  894. Xint exitcode;
  895. X{
  896. X    DEBUG(10,"DCE_exit(%d);\n",exitcode);
  897. X    exit(exitcode);
  898. X}    /* end of DCE_exit */
  899. X
  900. X/*+-------------------------------------------------------------------------
  901. X    DCE_argv_hook(argc,argv,optind,unrecognized_switches)
  902. X
  903. XThis hook gives DCE-specific code a chance to look over the entire
  904. Xcommand line, such as for -z Telebit processing.
  905. X
  906. Xargc andf argv are the same values passed to main(),
  907. X
  908. Xoptind is the value of optind at the end of normal getopt processing.
  909. X
  910. Xunrecognized_switches is the count of switches not handled by main().
  911. XSpecifically, -h and -x are standard switches.
  912. X
  913. XNormally, this function should just return RC_FAIL|RCE_ARGS if there are
  914. Xany unrecognized switches, otherwise zero.  If you keep your nose clean
  915. Xthough, you can do anything you need to do here and exit the program.
  916. X
  917. XNote: only simple switches (with no argument) may be used with this
  918. Xfacility if the functrion is to return,' since main()'s getopt() will
  919. Xstop processing switches if it runs into an unrecognized switch with an
  920. Xargument.
  921. X
  922. XIf the function returns a non-zero value, then the value will be passed
  923. XDIRECTLY to exit() with no further ado.  Thus, a non-zero value must be
  924. Xof the format expected by dialer program callers, with RC_FAIL set as a
  925. Xminimum.
  926. X--------------------------------------------------------------------------*/
  927. Xint
  928. XDCE_argv_hook(argc,argv,optind,unrecognized_switches)
  929. Xint argc;
  930. Xchar **argv;
  931. Xint optind;
  932. Xint unrecognized_switches;
  933. X{
  934. X    if(unrecognized_switches)
  935. X        return(RC_FAIL | RCE_ARGS);
  936. X    return(0);
  937. X}    /* end of DCE_argv_hook */
  938. X
  939. X/* vi: set tabstop=4 shiftwidth=4: */
  940. SHAR_EOF
  941. $TOUCH -am 0725125891 'gendial/dceUSR24.c' &&
  942. chmod 0644 gendial/dceUSR24.c ||
  943. echo 'restore of gendial/dceUSR24.c failed'
  944. Wc_c="`wc -c < 'gendial/dceUSR24.c'`"
  945. test 14126 -eq "$Wc_c" ||
  946.     echo 'gendial/dceUSR24.c: original size 14126, current size' "$Wc_c"
  947. rm -f _shar_wnt_.tmp
  948. fi
  949. # ============= gendial/dialer.h ==============
  950. if test -f 'gendial/dialer.h' -a X"$1" != X"-c"; then
  951.     echo 'x - skipping gendial/dialer.h (File already exists)'
  952.     rm -f _shar_wnt_.tmp
  953. else
  954. > _shar_wnt_.tmp
  955. echo 'x - extracting gendial/dialer.h (Text)'
  956. sed 's/^X//' << 'SHAR_EOF' > 'gendial/dialer.h' &&
  957. X/*+-------------------------------------------------------------------------
  958. X    dialer.h - SCO UUCP generic dialer program definitions
  959. X    wht%n4hgf.uucp@emory.mathcs.emory.edu -or- emory!n4hgf!wht
  960. X--------------------------------------------------------------------------*/
  961. X/*+:EDITS:*/
  962. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  963. X/*:03-12-1991-19:11-wht@n4hgf-if ecu dialing, show complete call progress */
  964. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  965. X
  966. X#include <stdio.h>
  967. X#include <ctype.h>
  968. X#include <errno.h>
  969. X#include <fcntl.h>
  970. X#include <setjmp.h>
  971. X#include <signal.h>
  972. X#include <string.h>
  973. X#include <memory.h>
  974. X#include <sys/types.h>
  975. X#include <sys/errno.h>
  976. X#include <sys/stat.h>
  977. X#include <termio.h>
  978. X#include <time.h>
  979. X#include <pwd.h>
  980. X
  981. X#define ff fprintf
  982. X#define se stderr
  983. X
  984. Xlong time();
  985. Xstruct passwd *getpwnam();
  986. X
  987. Xextern int errno;
  988. Xextern char *sys_errlist[];
  989. X
  990. Xextern int gargc;                    /* global copy of main's argv */
  991. Xextern char **gargv;                /* global copy of main's argv */
  992. Xextern char *dce_name;                /* full pathname of ACU device */
  993. Xextern char *telno;                    /* phone number if dial type request */
  994. Xextern struct termio dce_termio;    /* last termio for device */
  995. Xextern int Debug;                    /* set per -x flag */
  996. Xextern int dialing;                    /* set while dialing in progress */
  997. Xextern int fddce;                    /* file descriptor for dce_name */
  998. Xextern int DialerExitCode;             /* return code */
  999. Xextern int status;                    /* set on errors */
  1000. Xextern int hangup_flag;                /* set when DCE being hung up */
  1001. Xextern int hiCBAUD;                    /* highest permissible baud rate */
  1002. Xextern int loCBAUD;                    /* lowest permissible baud rate */
  1003. Xextern struct passwd *passwd;        /* pointer to password entry of invoker */
  1004. Xextern int uid;                        /* user id of executor */
  1005. Xextern int uid_uucp;                /* user id of uucp */
  1006. Xextern int secure;                    /* non-zero to suppress display of secure
  1007. X                                     * DCE traffic
  1008. X                                     */
  1009. Xextern int ecu_calling;                /* true if ecu dialing */
  1010. X
  1011. Xunsigned char dialer_codes[26];    /* A-Z embedded phone number codes */
  1012. X/* return codes: these are set up so that an abort signal at any time can */
  1013. X/* set the fail bit and return to the caller with the correct status */
  1014. X#define    SUCCESS        0
  1015. X#define    RC_FAIL        0x80    /* 1 = failed to connect */
  1016. X#define    RC_ENABLED    0x10    /* enabled flag: 1 = ungetty -r required to
  1017. X                             * restore the line
  1018. X                             */
  1019. X#define    RC_BAUD        0x0f    /* CBAUD connected at (0=same as dialed speed) */
  1020. X
  1021. X/* DCE result device independent flag */
  1022. X#define    rfNumeric    0x40000000
  1023. X
  1024. X/* program exit codes */
  1025. X#define    RCE_NULL    0    /* general purpose or unknown error code */
  1026. X#define    RCE_INUSE    1    /* line in use */
  1027. X#define    RCE_SIG        2    /* signal aborted dialer */
  1028. X#define    RCE_ARGS    3    /* invalid arguments */
  1029. X#define    RCE_PHNO    4    /* invalid phone number */
  1030. X#define    RCE_SPEED    5    /* invalid baud rate -or- bad connect baud */
  1031. X#define    RCE_OPEN    6    /* can't open line */
  1032. X#define    RCE_IOCTL    7    /* ioctl error */
  1033. X#define    RCE_TIMOUT    8    /* timeout */
  1034. X#define    RCE_NOTONE    9    /* no dial tone */
  1035. X#define    RCE_HANGUP    10    /* hangup failed */
  1036. X#define RCE_NORESP    11    /* Modem didn't respond. */
  1037. X#define    RCE_BUSY    13    /* phone is busy */
  1038. X#define    RCE_NOCARR    14    /* no carrier */
  1039. X#define    RCE_ANSWER    15    /* no answer */
  1040. X
  1041. X/* ungetty return codes */
  1042. X#define    UG_NOTENAB    0
  1043. X#define    UG_ENAB        1
  1044. X#define    UG_RESTART    1
  1045. X#define    UG_FAIL        2
  1046. X
  1047. X/* size for various buffers */
  1048. X#define MAXLINE        80
  1049. X
  1050. X/* How many errors allowed before call retry fails */
  1051. X#define    DIAL_ERRORS_MAX    4
  1052. X
  1053. X/* DCE message to code mapping struct ... array DCE_results of these
  1054. X * must be terminated with { (char *)0,0 } */
  1055. Xtypedef struct dce_result
  1056. X{
  1057. X    char *result;
  1058. X    long code;
  1059. X} DCE_RESULT;
  1060. X
  1061. X#define DEBUG(level,fmt,arg) if (Debug >= level) fprintf(stderr,fmt,arg)
  1062. X#if !defined(DBG)
  1063. X#define    DBG    0
  1064. X#endif
  1065. X
  1066. X/*
  1067. X * what the hell does __STDC__ mean in reality?  An __STDC__ compiler is
  1068. X * more nouveau than an older one.  ANSI C (or 'D') just stirred new
  1069. X * food for "standard" readers who went off and did what they wanted
  1070. X * to do.  We use __STDC__ to decide between two opinions of
  1071. X * what constitute "ANSI prototypes."  As of this writing, __STDC__ is
  1072. X * defined by the UNIX (MSC 5) compiler and not by the XENIX (MSC 4)
  1073. X * compiler.  We handle the GNU C compiler too.
  1074. X */
  1075. X#if defined(__STDC__) && !defined(__GNUC__)
  1076. Xint DCE_baud_to_CBAUD(unsigned int );
  1077. Xvoid DCE_hangup(void );
  1078. Xint DCE_dial(char *);
  1079. Xvoid DCE_abort(int );
  1080. Xvoid DCE_exit(int );
  1081. Xint DCE_argv_hook(int ,char **,int ,int );
  1082. Xint get_uucp_uid(void );
  1083. Xint instr(char *,char *);
  1084. Xvoid translate(char *,char *);
  1085. Xint decode_phone_number(char *,char *,int );
  1086. Xchar *make_printable(unsigned char );
  1087. Xchar *RCE_text(int );
  1088. Xvoid myexit(int );
  1089. XSIGTYPE dial_abort(int );
  1090. Xvoid cleanup(int );
  1091. Xint SIGALRM_abort(int );
  1092. XSIGTYPE SIGALRM_alert(int );
  1093. Xlong _lread(int ,int );
  1094. Xlong lread_ignore(int );
  1095. Xlong lread(int );
  1096. Xint lflush(void );
  1097. Xvoid _lputc(char );
  1098. Xvoid _lputc_paced(long ,char );
  1099. Xvoid _lputs(char *);
  1100. Xvoid _lputs_paced(long ,char *);
  1101. Xint lwrite(char *);
  1102. Xint ltoggleDTR(long );
  1103. Xint call_ungetty(char );
  1104. Xvoid display_termio(struct termio *,char *);
  1105. Xint open_dce(void );
  1106. Xint main(int ,char **);
  1107. X#else
  1108. Xint DCE_baud_to_CBAUD();
  1109. Xvoid DCE_hangup();
  1110. Xint DCE_dial();
  1111. Xvoid DCE_abort();
  1112. Xvoid DCE_exit();
  1113. Xint DCE_argv_hook();
  1114. Xint get_uucp_uid();
  1115. Xint instr();
  1116. Xvoid translate();
  1117. Xint decode_phone_number();
  1118. Xchar *make_printable();
  1119. Xchar *RCE_text();
  1120. Xvoid myexit();
  1121. XSIGTYPE dial_abort();
  1122. Xvoid cleanup();
  1123. XSIGTYPE SIGALRM_alert();
  1124. Xint SIGALRM_abort();
  1125. Xlong _lread();
  1126. Xlong lread_ignore();
  1127. Xlong lread();
  1128. Xint lflush();
  1129. Xvoid _lputc();
  1130. Xvoid _lputc_paced();
  1131. Xvoid _lputs();
  1132. Xvoid _lputs_paced();
  1133. Xint lwrite();
  1134. Xint ltoggleDTR();
  1135. Xint call_ungetty();
  1136. Xvoid display_termio();
  1137. Xint open_dce();
  1138. Xint main();
  1139. X#endif
  1140. X
  1141. X/* vi: set tabstop=4 shiftwidth=4: */
  1142. X/* end of dialer.h */
  1143. SHAR_EOF
  1144. $TOUCH -am 0725125891 'gendial/dialer.h' &&
  1145. chmod 0644 gendial/dialer.h ||
  1146. echo 'restore of gendial/dialer.h failed'
  1147. Wc_c="`wc -c < 'gendial/dialer.h'`"
  1148. test 5687 -eq "$Wc_c" ||
  1149.     echo 'gendial/dialer.h: original size 5687, current size' "$Wc_c"
  1150. rm -f _shar_wnt_.tmp
  1151. fi
  1152. # ============= gendial/gendial.c ==============
  1153. if test -f 'gendial/gendial.c' -a X"$1" != X"-c"; then
  1154.     echo 'x - skipping gendial/gendial.c (File already exists)'
  1155.     rm -f _shar_wnt_.tmp
  1156. else
  1157. > _shar_wnt_.tmp
  1158. echo 'x - extracting gendial/gendial.c (Text)'
  1159. sed 's/^X//' << 'SHAR_EOF' > 'gendial/gendial.c' &&
  1160. X/* CHK=0xC086 */
  1161. Xchar *revision = "1.10";
  1162. X/*+-------------------------------------------------------------------------
  1163. X    gendial.c - SCO UUCP dialer program device independent portion
  1164. X    wht@n4hgf.Mt-Park.GA.US
  1165. X
  1166. X  Configuration symbols:
  1167. X    HDB_UUCP        defined if HDB UUCP used on system, else old Version 2 
  1168. X
  1169. X  Defined functions:
  1170. X    RCE_text(value)
  1171. X    SIGALRM_alert(sig)
  1172. X    _lputc(lchar)
  1173. X    _lputc_paced(pace_msec,lchar)
  1174. X    _lputs(string)
  1175. X    _lputs_paced(pace_msec,string)
  1176. X    _lread(rtime,error_ok)
  1177. X    call_ungetty(call_type)
  1178. X    cleanup(stat)
  1179. X    decode_phone_number(userphno,result,resultlen)
  1180. X    dial_abort(sig)
  1181. X    display_termio(ttt,text)
  1182. X    get_uucp_uid()
  1183. X    instr(s1,s2)
  1184. X    lflush()
  1185. X    lread(rtime)
  1186. X    lread_ignore(rtime)
  1187. X    ltoggleDTR(msec)
  1188. X    lwrite(str)
  1189. X    main(argc,argv)
  1190. X    make_printable(ch)
  1191. X    myexit(code)
  1192. X    open_dce()
  1193. X    translate(ttab,str)
  1194. X
  1195. X  Usage:    dial ttyname telnumber speed 
  1196. X            dial -h ttyname speed
  1197. X
  1198. X  ttyname may be of style "ttyxx" or "/dev/ttyxx" (this is not standard)
  1199. X
  1200. X  Returns:
  1201. X        0x80    bit = 1 if connection failed
  1202. X        0x10    bit = 1 if line is also used for dialin #if !defined(OLDUUCP)
  1203. X        0x0f    if msb=1: error code
  1204. X                if msb=0: connected baud rate (0=same as dialed baud)
  1205. X                Note: this dialer always returns 0 in the low nibble
  1206. X                since cu and uucp expect it
  1207. X
  1208. X  Note: getty calls the dialer with -h whenever it starts up on a line
  1209. X  enabled in /etc/ttys and listed in Devices with this dialer.
  1210. X
  1211. X  Error codes are split into two categories:
  1212. X
  1213. X    1) (codes 0-11) Local problems are defined as tty port, or DCE
  1214. X    problems: problems that can be worked around by using a different
  1215. X    device.
  1216. X
  1217. X    2) (codes 12-15) Remote problems are phone busy, no answer, etc.:
  1218. X    attempt to connect to this remote system should be stopped.
  1219. X
  1220. X  Note: This dialer can be used both for the old "Version 2" 
  1221. X  new HoneyDanBer UUCP.  In HDB, uugetty is used and ungetty is not
  1222. X  necessary. Define HDB_UUCP for HDB UUCP.
  1223. X
  1224. X  Note: This version of the dialer will NOT display the telephone number
  1225. X  on the console unless the actual uid is root.  If dial logging is
  1226. X  used, make sure the dial_ttyXX.log file is precreated, owned by root
  1227. X  and has -rw--w--w- mode (0622).  Now, if uucico would just suppress
  1228. X  username and password information it sends out!
  1229. X
  1230. X--------------------------------------------------------------------------*/
  1231. X/*+:EDITS:*/
  1232. X/*:07-25-1991-12:58-wht@n4hgf-ECU release 3.10 */
  1233. X/*:05-01-1991-21:28-wht@n4hgf-add dial timing */
  1234. X/*:03-12-1991-19:11-wht@n4hgf-if ecu dialing, show complete call progress */
  1235. X/*:07-19-1990-17:14-root@n4hgf-modify lread fata timeout handler */
  1236. X/*:05-26-1990-02:15-wht@n4hgf-creation */
  1237. X
  1238. X#include "dialer.h"
  1239. X
  1240. X/* must be defined by device dependent module */
  1241. Xextern long DCE_DTR_low_msec;        /* msecs DTR must be low to be recognized */
  1242. Xextern long DCE_DTR_high_msec;        /* msecs for DCE to recover */
  1243. Xextern long DCE_write_pace_msec;    /* msecs between chars written to DCE */
  1244. Xextern DCE_RESULT DCE_results[];    /* DCE result codes */
  1245. Xextern char *DCE_name;                /* name of DCE */
  1246. Xextern char *DCE_revision;            /* DCE-dependent code revision */
  1247. Xextern short DCE_hangup_CBAUD;        /* BXXX DCE hangup baud rate or zero */
  1248. X
  1249. X/* globals available to device dependent module */
  1250. Xint gargc;                    /* global copy of main's argv */
  1251. Xchar **gargv;                /* global copy of main's argv */
  1252. Xchar *dce_name;                    /* full pathname of ACU device */
  1253. Xchar *telno = (char *)0;    /* phone number if dial type request */
  1254. Xstruct termio dce_termio;    /* last termio for device */
  1255. Xint Debug = DBG;            /* set per -x flag */
  1256. Xint dialing = 0;            /* set while dialing in progress */
  1257. Xint fddce = -1;                /* file descriptor for dce_name */
  1258. Xint DialerExitCode = RC_FAIL; /* return code */
  1259. Xint status = 0;                /* set on errors */
  1260. Xint hangup_flag = 0;        /* set when DCE being hung up */
  1261. Xint hiCBAUD;                /* highest permissible baud rate */
  1262. Xint loCBAUD;                /* lowest permissible baud rate */
  1263. Xstruct passwd *passwd;
  1264. Xint uid;                    /* user id of executor */
  1265. Xint uid_uucp;                /* user id of uucp */
  1266. Xint secure = 0;                /* non-zero to suppress display of secure
  1267. X                             * DCE traffic
  1268. X                             */
  1269. Xint ecu_calling = 0;        /* true if ecu is dialing */
  1270. X
  1271. Xunsigned char dialer_codes[26];    /* A-Z embedded phone number codes */
  1272. X
  1273. Xjmp_buf    SIGALRM_alert_jmpbuf;
  1274. XDCE_RESULT *last_result;
  1275. X
  1276. X/*+-------------------------------------------------------------------------
  1277. X    get_uucp_uid()
  1278. X--------------------------------------------------------------------------*/
  1279. Xint
  1280. Xget_uucp_uid()
  1281. X{
  1282. X
  1283. X    passwd = getpwnam("uucp");
  1284. X    endpwent();
  1285. X    if(passwd)
  1286. X        return(passwd->pw_uid);
  1287. X    else
  1288. X        return(-1);
  1289. X}    /* end of get_uucp_uid */
  1290. X
  1291. X/*+-------------------------------------------------------------------------
  1292. X    instr(s1,s2)
  1293. X
  1294. X  find s2 in s1; returns 1 if found, 0 if not found
  1295. X--------------------------------------------------------------------------*/
  1296. Xinstr(s1,s2)
  1297. Xregister char *s1;
  1298. Xchar *s2;
  1299. X{
  1300. X    register len = strlen(s2);
  1301. X    while(s1 = strchr(s1,*s2))
  1302. X    {
  1303. X        if(!strncmp(s2,s1,len))
  1304. X            return(1);
  1305. X        s1++;
  1306. X    }
  1307. X    return(0);
  1308. X}    /* end of instr */
  1309. X
  1310. X/*+-------------------------------------------------------------------------
  1311. X    translate(ttab,str)
  1312. X
  1313. X  translate the pairs of characters present in the first string
  1314. X  whenever the first of the pair appears in the second string
  1315. X  (this routine from standard SCO dialer code)
  1316. X--------------------------------------------------------------------------*/
  1317. Xvoid
  1318. Xtranslate(ttab,str)
  1319. Xregister char *ttab;
  1320. Xchar *str;
  1321. X{
  1322. X    register char *cptr;
  1323. X
  1324. X    while(*ttab && *(ttab + 1))
  1325. X    {
  1326. X        for(cptr = str; *cptr; cptr++)
  1327. X        {
  1328. X            if(*ttab == *cptr)
  1329. X                *cptr = *(ttab + 1);
  1330. X        }
  1331. X        ttab += 2;
  1332. X    }
  1333. X}    /* end of translate */
  1334. X
  1335. X/*+-------------------------------------------------------------------------
  1336. X    decode_phone_number(userphno,result,resultlen)
  1337. X
  1338. Xdecode user flags in phone number, returning phone number in
  1339. Xresult, character flags in global dialer_codes[], 'A' or 'a'
  1340. Xresults in dialer_codes[0] being 1, etc.  Only letter codes are
  1341. Xextracted.
  1342. X
  1343. XFor example, if userphno contains "123,D45f", result returned
  1344. X"123,45" and only elements 3 and 5 of dialer_codes set to 1
  1345. X
  1346. XFunction returns 0 if successful, -1 if result buffer too small
  1347. X--------------------------------------------------------------------------*/
  1348. Xint
  1349. Xdecode_phone_number(userphno,result,resultlen)
  1350. Xregister char *userphno;
  1351. Xregister char *result;
  1352. Xint resultlen;
  1353. X{
  1354. Xregister itmp;
  1355. X
  1356. X    for(itmp = 0; itmp < sizeof(dialer_codes); itmp++)
  1357. X        dialer_codes[itmp] = 0;
  1358. X
  1359. X    if(!resultlen)
  1360. X        return(-1);
  1361. X    resultlen--;    /* leave room for null */
  1362. X
  1363. X    while(*userphno)
  1364. X    {
  1365. X        if(isalpha(*userphno))
  1366. X            dialer_codes[*userphno - ((isupper(*userphno)) ? 'A' : 'a')] = 1;
  1367. X        else
  1368. X        {
  1369. X            if(!resultlen--)
  1370. X                return(-1);
  1371. X            *result++ = *userphno;
  1372. X        }
  1373. X        userphno++;
  1374. X    }
  1375. X    *result = 0;
  1376. X    return(0);
  1377. X}    /* end of decode_phone_number */
  1378. X
  1379. X/*+-------------------------------------------------------------------------
  1380. X    make_printable(ch) - make a character "printable"
  1381. X--------------------------------------------------------------------------*/
  1382. Xchar *
  1383. Xmake_printable(ch)
  1384. Xunsigned char ch;
  1385. X{
  1386. Xstatic char buffer[10];
  1387. Xchar *cptr;
  1388. X#define    to_print(x)    ((x)<' '?((x)+'@'):'?')
  1389. X
  1390. X    cptr = buffer;
  1391. X    /* if not root or uucp and info needs securing */
  1392. X    if(!ecu_calling && uid && (uid != uid_uucp) && secure)
  1393. X    {
  1394. X        *cptr++ = '?';    /* hide it */
  1395. X        *cptr = 0;
  1396. X        return(buffer);
  1397. X    }
  1398. X
  1399. X    if(iscntrl(ch) || !isprint(ch))
  1400. X    {
  1401. X        if(!isascii(ch))
  1402. X        {            /* Top bit is set */
  1403. X            *cptr++ = 'M';
  1404. X            *cptr++ = '-';
  1405. X            ch = toascii(ch);            /* Strip it */
  1406. X        }
  1407. X        if(iscntrl(ch))
  1408. X        {
  1409. X            *cptr++ = '^';
  1410. X            ch = to_print(ch);            /* Make it printable */
  1411. X        }
  1412. X    }
  1413. X    *cptr++ = ch;
  1414. X    *cptr = 0;
  1415. X    return(buffer);
  1416. X}    /* end of make_printable */
  1417. X
  1418. X/*+-------------------------------------------------------------------------
  1419. X    RCE_text(value)
  1420. X--------------------------------------------------------------------------*/
  1421. Xchar *
  1422. XRCE_text(value)
  1423. Xint value;
  1424. X{
  1425. Xstatic char errant[32];
  1426. X
  1427. X    switch(value & 0x0F)
  1428. X    {
  1429. X        case RCE_NULL: return("unknown or unclassified error");
  1430. X        case RCE_INUSE: return("line in use");
  1431. X        case RCE_SIG: return("killed with signal");
  1432. X        case RCE_ARGS: return("invalid arguments");
  1433. X        case RCE_PHNO: return("invalid phone number");
  1434. X        case RCE_SPEED: return("invalid line speed or bad connect speed");
  1435. X        case RCE_OPEN: return("cannot open line");
  1436. X        case RCE_IOCTL: return("ioctl error");
  1437. X        case RCE_TIMOUT: return("timeout");
  1438. X        case RCE_NOTONE: return("NO DIAL TONE");
  1439. X        case RCE_HANGUP: return("hangup failed\n");
  1440. X        case RCE_NORESP: return("DCE didn't respond.\n");
  1441. X        case RCE_BUSY: return("BUSY");
  1442. X        case RCE_NOCARR: return("NO CARRIER");
  1443. X        case RCE_ANSWER: return("NO ANSWER");
  1444. X    }
  1445. X    sprintf(errant,"code 0x%04x",value);
  1446. X    return(errant);
  1447. X
  1448. X}    /* end of RCE_text */
  1449. X
  1450. X/*+-------------------------------------------------------------------------
  1451. X    myexit(code) - all threads exit() thru here
  1452. X--------------------------------------------------------------------------*/
  1453. Xvoid
  1454. Xmyexit(code)
  1455. Xint code;
  1456. X{
  1457. X    if(dialing)
  1458. X    {
  1459. X        if(code & RC_FAIL)
  1460. X        {
  1461. X            DEBUG(1,"dial failed: %s\n",RCE_text(code));
  1462. X        }
  1463. X        else
  1464. X        {
  1465. X            DEBUG(1,"dial succeeded\n",0);
  1466. X        }
  1467. X    }
  1468. X    DCE_exit(code);    /* should not return */
  1469. X    exit(code);        /* in case it does */
  1470. X
  1471. X}    /* end of myexit */
  1472. X
  1473. X/*+-------------------------------------------------------------------------
  1474. X    dial_abort(sig)
  1475. X--------------------------------------------------------------------------*/
  1476. XSIGTYPE
  1477. Xdial_abort(sig)
  1478. Xint sig;
  1479. X{
  1480. X    if(sig)
  1481. X    {
  1482. X        DEBUG(2,"\ndialer received signal %d\n\n",sig);
  1483. X    }
  1484. X    else
  1485. X    {
  1486. X        DEBUG(2,"\ndialer aborted, fail status = %d\n",DialerExitCode);
  1487. X    }
  1488. X    DCE_abort(sig);
  1489. X    if(fddce != -1)
  1490. X    {
  1491. X        ioctl(fddce,TCGETA,&dce_termio);
  1492. X        dce_termio.c_cflag |= HUPCL;        /* make sure DCE hangs up */
  1493. X        ioctl(fddce,TCSETA,&dce_termio);
  1494. X        close(fddce);
  1495. X    }
  1496. X    if(sig)
  1497. X        DialerExitCode |= (RC_FAIL | RCE_SIG);
  1498. X    myexit(DialerExitCode);
  1499. X}    /* end of dial_abort */
  1500. X
  1501. X/*+-------------------------------------------------------------------------
  1502. X    cleanup(stat) - close device and exit
  1503. X--------------------------------------------------------------------------*/
  1504. Xvoid
  1505. Xcleanup(stat)
  1506. Xint stat;
  1507. X{
  1508. X    if(stat & RC_FAIL)
  1509. X    {    /* if we failed, drop DTR (in dial_abort) */
  1510. X        DialerExitCode = stat;
  1511. X        dial_abort(0);
  1512. X    }
  1513. X    else 
  1514. X        myexit(stat);
  1515. X}    /* end of cleanup */
  1516. X
  1517. X/*+-------------------------------------------------------------------------
  1518. X    SIGALRM_alert(sig) - catch alarm call and do longjmp
  1519. X--------------------------------------------------------------------------*/
  1520. XSIGTYPE
  1521. XSIGALRM_alert(sig)
  1522. Xint sig;
  1523. X{
  1524. X    longjmp(SIGALRM_alert_jmpbuf,1);
  1525. X}    /* end of SIGALRM_alert */
  1526. X
  1527. X/*+-------------------------------------------------------------------------
  1528. X    _lread(rtime,error_ok)
  1529. X
  1530. X  Common code for lread() and lread_ignore()
  1531. X
  1532. X  Returns DCE_RESULT->code from matching DCE_RESULT->result
  1533. X  or if no match is found and the first digit of the modem
  1534. X  response is numeric, the the numeric value is returned ored
  1535. X  with 0x4000.
  1536. X
  1537. X  If error_ok is true and a timeout occurs, -1 is returned.
  1538. X  If error_ok is false and a timeout occurs,
  1539. X     cleanup(RC_FAIL | RCE_TIMOUT | DialerExitCode);
  1540. X     is called, which results in dial_abort(0) thus DCE_abort(0)
  1541. X     being called.
  1542. X--------------------------------------------------------------------------*/
  1543. Xlong
  1544. X_lread(rtime,error_ok)
  1545. Xint rtime;
  1546. Xint error_ok;
  1547. X{
  1548. Xint itmp;
  1549. Xchar rdchar;
  1550. XDCE_RESULT *mr;
  1551. Xchar buf[MAXLINE];
  1552. Xchar *bp;
  1553. Xchar *cptr;
  1554. X
  1555. X    if(error_ok)
  1556. X    {
  1557. X        signal(SIGALRM,SIGALRM_alert);
  1558. X        if(setjmp(SIGALRM_alert_jmpbuf) != 0)
  1559. X        {
  1560. X            DEBUG(6,">>-%s\n","TIMEOUT (NON-FATAL)");
  1561. X            return(-1);
  1562. X        }
  1563. X    }
  1564. X    else
  1565. X    {
  1566. X        signal(SIGALRM,SIGALRM_alert);
  1567. X        if(setjmp(SIGALRM_alert_jmpbuf) != 0)
  1568. X        {
  1569. X            DEBUG(6,">>-%s\n","TIMEOUT (FATAL)");
  1570. X            cleanup(RC_FAIL | RCE_TIMOUT | DialerExitCode);
  1571. X        }
  1572. X    }
  1573. X
  1574. X    bp = buf;
  1575. X    alarm(rtime);
  1576. X    DEBUG(6,"DCE returned %s","<<");
  1577. X
  1578. X    while((itmp = read(fddce,&rdchar,1)) == 1)
  1579. X    {
  1580. X        *bp++ = (rdchar &= 0x7F);
  1581. X        DEBUG(6,"%s",make_printable(rdchar));
  1582. X        if(rdchar == 0x0A)
  1583. X            DEBUG(6,"\n",0);
  1584. X        if(bp >= buf + MAXLINE)
  1585. X        {
  1586. X            alarm(0);
  1587. X            DEBUG(6,"\n>>-FAIL (%s)\n","BUFFER OVERFLOW");
  1588. X            myexit(RC_FAIL | RCE_NULL);
  1589. X        }
  1590. X        *bp = 0;
  1591. X        if(rdchar == '\r')
  1592. X        {
  1593. X            cptr = buf;
  1594. X            if(*cptr == 0x0A)
  1595. X                cptr++;
  1596. X            for(mr = DCE_results; mr->result; ++mr)
  1597. X            {
  1598. X                if(instr(buf,mr->result))
  1599. X                {
  1600. X                    alarm(0);
  1601. X                    DEBUG(6,">>-%s\n","SUCCESS");
  1602. X                    if(strcmp(mr->result,"OK"))  /* not so modem independent */
  1603. X                        DEBUG(4,"got %s\n",mr->result);
  1604. X                    else
  1605. X                        DEBUG(6,"got %s\n",mr->result);
  1606. X                    last_result = mr;
  1607. X                    return(mr->code);
  1608. X                }
  1609. X            }
  1610. X
  1611. X            if(isdigit(*cptr))
  1612. X            {
  1613. X                alarm(0);
  1614. X                itmp = atoi(cptr);
  1615. X                DEBUG(6,">>-SUCCESS (NUMERIC RESULT %d)\n",itmp);
  1616. X                return(rfNumeric | itmp);
  1617. X            }
  1618. X
  1619. X            bp = buf;
  1620. X        }
  1621. X    }
  1622. X
  1623. X    alarm(0);
  1624. X    if(Debug >= 6)
  1625. X    {
  1626. X        ff(se,">>-FAIL (%s %d)",
  1627. X            (itmp < 0) ? "READ ERRNO" : "READ LENGTH",
  1628. X            (itmp < 0) ? errno : 0);
  1629. X    }
  1630. X    DEBUG(4," incomplete or no response\n",0);
  1631. X    return(-1);
  1632. X}    /* end of _lread */
  1633. X
  1634. X/*+-------------------------------------------------------------------------
  1635. X    lread_ignore(rtime)
  1636. X
  1637. X  Reads from the ACU until it finds a valid response (found in
  1638. X  DCE_results), a numeric result code (e.g., S-register value), or times
  1639. X  out after rtime seconds.  The numeric response feature is designed
  1640. X  for Hayes-style DCEs and may not be useful for other DCE types
  1641. X
  1642. X  Returns: DCE_RESULT code, numeric result + 128, or -1 on timeout or error
  1643. X--------------------------------------------------------------------------*/
  1644. Xlong
  1645. Xlread_ignore(rtime)
  1646. Xint rtime;
  1647. X{
  1648. X    return(_lread(rtime,1));
  1649. X}    /* end of lread_ignore */
  1650. X
  1651. X/*+-------------------------------------------------------------------------
  1652. X    lread(rtime)
  1653. X
  1654. X  Same as lread_ignore, but does not return on timeout or error
  1655. X--------------------------------------------------------------------------*/
  1656. Xlong
  1657. Xlread(rtime)
  1658. Xint rtime;
  1659. X{
  1660. Xint rtn = _lread(rtime,0);
  1661. X    if(rtn < 0)
  1662. X        myexit(RC_FAIL | RCE_TIMOUT);
  1663. X    return(rtn);
  1664. X}    /* end of lread */
  1665. X
  1666. X/*+-------------------------------------------------------------------------
  1667. X    lflush() - flushes input clists for DCE
  1668. X--------------------------------------------------------------------------*/
  1669. Xlflush()
  1670. X{
  1671. X    ioctl(fddce,TCFLSH,0);
  1672. X}    /* end of lflush */
  1673. X
  1674. X/*+-----------------------------------------------------------------------
  1675. X    _lputc(lchar) -- write char to comm line
  1676. X------------------------------------------------------------------------*/
  1677. Xvoid
  1678. X_lputc(lchar)
  1679. Xchar lchar;
  1680. X{
  1681. X    write(fddce,&lchar,1);
  1682. X    DEBUG(6,"%s",make_printable(lchar));
  1683. X}    /* end of _lputc */
  1684. X
  1685. X/*+-----------------------------------------------------------------------
  1686. X    _lputc_paced(pace_msec,lchar) -- write char to comm line with pacing
  1687. X------------------------------------------------------------------------*/
  1688. Xvoid
  1689. X_lputc_paced(pace_msec,lchar)
  1690. Xregister long pace_msec;
  1691. Xregister char lchar;
  1692. X{
  1693. X    _lputc(lchar);
  1694. X    if(pace_msec)
  1695. X        nap(pace_msec);
  1696. X}    /* end of _lputc_paced */
  1697. X
  1698. X/*+-----------------------------------------------------------------------
  1699. X    _lputs(string) -- write string to comm line
  1700. X------------------------------------------------------------------------*/
  1701. Xvoid
  1702. X_lputs(string)
  1703. Xregister char *string;
  1704. X{
  1705. X    while(*string)
  1706. X        _lputc(*string++);
  1707. X}
  1708. X
  1709. X/*+-----------------------------------------------------------------------
  1710. X    _lputs_paced(pace_msec,string) -- write string to comm line
  1711. X  with time between each character 
  1712. X------------------------------------------------------------------------*/
  1713. Xvoid
  1714. X_lputs_paced(pace_msec,string)
  1715. Xregister long pace_msec;
  1716. Xregister char *string;
  1717. X{
  1718. X    while(*string)
  1719. X        _lputc_paced(pace_msec,*string++);
  1720. X
  1721. X}    /* end of _lputs_paced */
  1722. X
  1723. X/*+-------------------------------------------------------------------------
  1724. X    lwrite(str) - output string to dce_name
  1725. X  Returns:    0 on completion, -1 on write errors.
  1726. X--------------------------------------------------------------------------*/
  1727. Xlwrite(str)
  1728. Xregister char *str;
  1729. X{
  1730. X
  1731. X    nap(200L);
  1732. X    DEBUG(6,"Sent DCE %s","<<");
  1733. X    _lputs_paced(DCE_write_pace_msec,str);
  1734. X    DEBUG(6,">>-%s\n","SUCCESS");
  1735. X    ioctl(fddce,TCSETAW,&dce_termio);    /* wait for I/O to drain */
  1736. X    return(0);
  1737. X
  1738. X}    /* end of lwrite */
  1739. X
  1740. X/*+-------------------------------------------------------------------------
  1741. X    ltoggleDTR(msec) - drop DTR, pause, raise DTR
  1742. X
  1743. XIf msec != 0, drop DTR for that period of time, else DCE_DTR_low_msec
  1744. XThis routine trusts that the DTE has already been opened and ioctl'ed
  1745. Xonce and that no error checking need be done; this may not catch all
  1746. Xchanges in the universe, but the assumption is not naive
  1747. X--------------------------------------------------------------------------*/
  1748. XltoggleDTR(msec)
  1749. Xlong msec;
  1750. X{
  1751. Xstruct termio temp;
  1752. X
  1753. X    /*
  1754. X     * drop DTR and pause a while
  1755. X     */
  1756. X    temp = dce_termio;
  1757. X    temp.c_cflag &= ~CBAUD;        /* use B0 */
  1758. X    ioctl(fddce,TCSETA,&temp);    /* drop DTR */
  1759. X    nap((msec) ? msec : 300L);
  1760. X
  1761. X    /*
  1762. X     * raise DTR and pause a while
  1763. X     */
  1764. X    ioctl(fddce,TCSETA,&dce_termio);    /* raise DTR */
  1765. X    if(DCE_DTR_high_msec)
  1766. X        nap(DCE_DTR_high_msec);
  1767. X
  1768. X}    /* end of ltoggleDTR */
  1769. X
  1770. X/*+-------------------------------------------------------------------------
  1771. X    call_ungetty(call_type)
  1772. X
  1773. Xtype: 'a' - acquire dce_name
  1774. X      't' - test to see if dce_name should be returned
  1775. X      'r' - return dce_name
  1776. X
  1777. XThis function is a no-op in HDB UUCP versions
  1778. X--------------------------------------------------------------------------*/
  1779. Xcall_ungetty(call_type)
  1780. Xchar call_type;
  1781. X{
  1782. X#if defined(HDB_UUCP)
  1783. X    switch(call_type)
  1784. X    {
  1785. X        case 'a': return(UG_NOTENAB);        /* simulate complete success */
  1786. X        case 't': return(UG_RESTART);        /* simulate need for re-setup */
  1787. X        case 'r': return(0);                /* simulate complete success */
  1788. X    }
  1789. X    return(0);
  1790. X#else /* HDB_UUCP */
  1791. Xint itmp;
  1792. Xint pid;
  1793. Xunsigned int wait_status;
  1794. Xstatic char *ungetty = "/usr/lib/uucp/ungetty";
  1795. X
  1796. X    if((pid = fork()) == 0)
  1797. X    {
  1798. X        if(Debug >= 5)
  1799. X            ff(se,"%s: %s %s called\n",*gargv,ungetty,dce_name);
  1800. X        switch(call_type)
  1801. X        {
  1802. X            case 'a':
  1803. X                execl(ungetty,"ungetty",dce_name + 5,(char *)0);
  1804. X                break;
  1805. X            case 't':
  1806. X                execl(ungetty,"ungetty","-t",dce_name + 5,(char *)0);
  1807. X                break;
  1808. X            case 'r':
  1809. X                execl(ungetty,"ungetty","-r",dce_name + 5,(char *)0);
  1810. X                break;
  1811. X        }
  1812. X        ff(se,"%s exec error %d (%s)\n",ungetty,errno,sys_errlist[errno]);
  1813. X        _exit(-1);
  1814. X    }
  1815. X
  1816. X    while(((itmp = wait(&wait_status)) != pid) && itmp != -1)
  1817. X        ;
  1818. X
  1819. X    if(Debug >= 6)
  1820. X        ff(se,"%s pid %d exit status 0x%04x\n",ungetty,itmp,wait_status);
  1821. X
  1822. X    return((wait_status >> 8) & 0xFF);
  1823. X#endif /* HDB_UUCP */
  1824. X}    /* end of call_ungetty */
  1825. X
  1826. X/*+-----------------------------------------------------------------------
  1827. X    display_termio(ttt)
  1828. SHAR_EOF
  1829. true || echo 'restore of gendial/gendial.c failed'
  1830. fi
  1831. echo 'End of ecu310 part 27'
  1832. echo 'File gendial/gendial.c is continued in part 28'
  1833. echo 28 > _shar_seq_.tmp
  1834. exit 0
  1835. --------------------------------------------------------------------
  1836. Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
  1837. Hacker Extraordinaire  d' async PADs,  pods,  proteins and protocols
  1838.  
  1839. exit 0 # Just in case...
  1840. -- 
  1841. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1842. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1843. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1844. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1845.