home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume16 / ecu3 / part25 < prev    next >
Internet Message Format  |  1991-01-06  |  48KB

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