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

  1. From: wht@n4hgf.uucp (Warren Tucker)
  2. Newsgroups: comp.sources.misc
  3. Subject: v16i051:  ECU async comm package rev 3.0, Part27/35
  4. Message-ID: <1991Jan6.053857.28743@sparky.IMD.Sterling.COM>
  5. Date: 6 Jan 91 05:38:57 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 971ff391 7d5ff2f7 6592c424 6f01aef2
  8.  
  9. Submitted-by: wht@n4hgf.uucp (Warren Tucker)
  10. Posting-number: Volume 16, Issue 51
  11. Archive-name: ecu3/part27
  12.  
  13. ---- Cut Here and feed the following to sh ----
  14. #!/bin/sh
  15. # This is part 27 of ecu3
  16. if touch 2>&1 | fgrep 'amc' > /dev/null
  17.  then TOUCH=touch
  18.  else TOUCH=true
  19. fi
  20. # ============= gendial/dceT1000.c ==============
  21. if test ! -d 'gendial'; then
  22.     echo 'x - creating directory gendial'
  23.     mkdir 'gendial'
  24. fi
  25. echo 'x - extracting gendial/dceT1000.c (Text)'
  26. sed 's/^X//' << 'SHAR_EOF' > 'gendial/dceT1000.c' &&
  27. X/* CHK=0xFF53 */
  28. X#define WHT
  29. X/*+-------------------------------------------------------------------------
  30. X    dceTBPlus.c - DCE-specific portion of generic SCO UUCP dialer
  31. X    Driver for Telebit Trailblazer Plus
  32. X    wht@n4hgf.Mt-Park.GA.US
  33. X--------------------------------------------------------------------------*/
  34. X/*+:EDITS:*/
  35. X/*:11-29-1990-18:31-r@n4hgf-revision/1st releasable */
  36. X/*:07-20-1990-00:10-wht@n4hgf-creation */
  37. X
  38. X#include "dialer.h"
  39. X
  40. X/*
  41. X * DCE_DTR_low_msec - milliseconds to hold DTR low to ensure DCE
  42. X *                    sees the transition; this value may be changed
  43. X *                    as necessary before each call to ltoggleDTR(),
  44. X * but, generally, a constant value will do.
  45. X */
  46. Xlong DCE_DTR_low_msec = 500;
  47. X
  48. X/*
  49. X * DCE_DTR_high_msec - milliseconds DTR must remain high before the
  50. X *                     DCE may be expected to be ready to be commanded
  51. X */
  52. Xlong DCE_DTR_high_msec = 500;
  53. X
  54. X/*
  55. X * DCE_write_pase_msec - milliseconds to pause between each character
  56. X *                       sent to the DCE (zero if streaming I/O is
  57. X *                       permitted); this value may be changed as
  58. X * necessary before each call to lwrite(), but, generally, a constant
  59. X * value will do.  Note that this value is used to feed a value to nap(),
  60. X * which has a granularity of .010 seconds on UNIX/386, .020 on XENIX/286
  61. X * and .050 seconds on XENIX/86.
  62. X */
  63. Xlong DCE_write_pace_msec = 0;
  64. X
  65. X/*
  66. X * DCE_name     - short name for DCE
  67. X * DCE_revision - revision number for this module
  68. X */
  69. Xchar *DCE_name = "Telebit T1000";
  70. Xchar *DCE_revision = "1.00";
  71. X
  72. X/*
  73. X * DCE_hangup_CBAUD - baud rate to use for hanging up DCE
  74. X *                    and readying it for dial in access
  75. X *                    (BXXX mask); use a value of zero if the speed
  76. X *                    specified by the invoker is to be used.
  77. X * This value is useful for DCEs such as the early Hayes 2400
  78. X * which are so unfortunately compatible with their 1200 predecessor
  79. X * that they refuse to answer at 2400 baud unless you last spoke to
  80. X * them at that rate. For such bad boys, use B2400 below.
  81. X */
  82. Xint DCE_hangup_CBAUD = 0;
  83. X/* int DCE_hangup_CBAUD = B2400; */
  84. X
  85. X/*
  86. X * DCE_results - a table of DCE response strings and a token
  87. X *               code for each; when you call lread() or lread_ignore(),
  88. X *               if the read routine detects one of the strings,
  89. X * the appropriate code is returned.  If no string matches, then
  90. X * lread()/lread_ignore examines the DCE result string for a
  91. X * numeric value; if one is found, the numeric value or'd with
  92. X * 0x40000000 is returned (in this way, e.g., you can read "modem
  93. X * S registers").  If nothing agrees with this search, lread()
  94. X * will abort the program with RC|FAIL|RCE_TIMOUT, lread_ignore()
  95. X * will return -1.  You may use any value between 0 and 0x3FFFFFFF.
  96. X * This module is the only consumer  of the codes, although they
  97. X * are decoded by gendial.c's _lread()
  98. X */
  99. X
  100. X/* flag bits */
  101. X#define rfConnect        0x00800000
  102. X#define rfREL            0x00400000
  103. X#define rfFAST            0x00200000
  104. X#define rfMASK            0x0000FFFF    /* mask off rfBits */
  105. X
  106. X/* unique codes */
  107. X#define rOk                0
  108. X#define rNoCarrier        1
  109. X#define rError            2
  110. X#define rNoDialTone     3
  111. X#define rBusy            4
  112. X#define rNoAnswer        5
  113. X#define rRring            6
  114. X#define rConnect300        (  300  | rfConnect)
  115. X#define rConnect1200    ( 1200  | rfConnect)
  116. X#define rConnect2400    ( 2400  | rfConnect)
  117. X#define rConnect300R    (  300  | rfConnect | rfREL)
  118. X#define rConnect1200R    ( 1200  | rfConnect | rfREL)
  119. X#define rConnect2400R    ( 2400  | rfConnect | rfREL)
  120. X#define rConnectFASTK    (19200  | rfConnect | rfFAST)    /* may be 9600 */
  121. X#define rConnectFASTX    (19200  | rfConnect | rfFAST)
  122. X#define rConnectFASTU    (19200  | rfConnect | rfFAST)
  123. X#define rConnectFAST    (19200  | rfConnect | rfFAST)
  124. X
  125. XDCE_RESULT DCE_results[] =
  126. X{
  127. X    { "OK",                        rOk,            },
  128. X    { "NO CARRIER",                rNoCarrier,        },
  129. X    { "ERROR",                    rError            },
  130. X    { "NO DIALTONE",            rNoDialTone,    },
  131. X    { "BUSY",                    rBusy            },
  132. X    { "NO ANSWER",                rNoAnswer        },
  133. X    { "RRING",                    rRring            },
  134. X    { "CONNECT 300/REL",        rConnect300R    },
  135. X    { "CONNECT 1200/REL",        rConnect1200R    },
  136. X    { "CONNECT 2400/REL",        rConnect2400R    },
  137. X    { "CONNECT 300",            rConnect300        },
  138. X    { "CONNECT 1200",            rConnect1200    },
  139. X    { "CONNECT 2400",            rConnect2400    },
  140. X    { "CONNECT FAST/KERM",        rConnectFASTK    },
  141. X    { "CONNECT FAST/XMDM",        rConnectFASTX    },
  142. X    { "CONNECT FAST/UUCP",        rConnectFASTU    },
  143. X    { "CONNECT FAST",            rConnectFAST    },
  144. X    { (char *)0,                -1                }        /* end table */
  145. X};
  146. X
  147. X/*+-------------------------------------------------------------------------
  148. X    DCE_baud_to_CBAUD(baud) - check for valid baud rates supported by DCE
  149. X
  150. X  DCE dependent function must validate baud rates supported by DCE
  151. X  returns baud rate in struct termio c_cflag fashion
  152. X  or terminates program with error
  153. X--------------------------------------------------------------------------*/
  154. Xint
  155. XDCE_baud_to_CBAUD(baud)
  156. Xunsigned int baud;
  157. X{
  158. X    switch(baud)
  159. X    {
  160. X        case 110:  return(B110);
  161. X        case 300:  return(B300);
  162. X        case 1200: return(B1200);
  163. X        case 2400: return(B2400);
  164. X        case 9600: return(B9600);
  165. X
  166. X#if defined(B19200)
  167. X        case 19200: return(B19200);
  168. X#else
  169. X#ifdef EXTA
  170. X        case 19200: return(EXTA);
  171. X#endif
  172. X#endif
  173. X
  174. X#if defined(B38400)
  175. X        case 38400: return(B38400);
  176. X#else
  177. X#ifdef EXTB
  178. X        case 38400: return(EXTB);
  179. X#endif
  180. X#endif
  181. X
  182. X    }
  183. X    myexit(RC_FAIL | RCE_SPEED);
  184. X}    /* end of DCE_baud_to_CBAUD */
  185. X
  186. X/*+-------------------------------------------------------------------------
  187. X    sync_Telebit() - sync modem with our DTE speed
  188. X--------------------------------------------------------------------------*/
  189. Xvoid
  190. Xsync_Telebit()
  191. X{
  192. Xregister int maxretry = 8;
  193. Xregister int count;
  194. Xunsigned char rdchar;
  195. X
  196. X    while(maxretry--)
  197. X    {
  198. X        lflush();
  199. X        write(fddce,"a",1);
  200. X        count = 5;
  201. X        while(count)    /* wait 50-200 msec for character, depending on HZ */
  202. X        {
  203. X            if(rdchk(fddce))
  204. X                break;
  205. X            nap(50L);
  206. X            count--;
  207. X        }
  208. X        if(count && (read(fddce,&rdchar,1) == 1) && (rdchar == 'a'))
  209. X            return;
  210. X    }
  211. X
  212. X    DEBUG(1,"Telebit SYNC FAILED\n",0);
  213. X    myexit(RC_FAIL | RCE_TIMOUT);
  214. X
  215. X}    /* end of sync_Telebit */
  216. X
  217. X/*+-------------------------------------------------------------------------
  218. X    init_TBPlus() - init TBPlus from scratch, assuming nothing
  219. X
  220. X    reset to factory defaults, then set
  221. X    E0          no local echo in command mode
  222. X    F1          no local echo in data transfer mode
  223. X    M0          speaker off
  224. X    Q4          generate reult codes, but not RING
  225. X    V1          verbal result codes
  226. X    X3          extended result codes
  227. X    S0=1        answer on first ring
  228. X    S2=1        escape to "unusual" value
  229. X    S11=50      50 msec DTMF timing
  230. X    S45=1       enable remote access
  231. X    S48=1       all 8 bits are significant
  232. X    S50=0       use automatic connect speed determination
  233. X    S51=255     default to 9600 and typeahead
  234. X    S52=2       go on hook when dtr drops and reset to NV-RAM
  235. X    S53=1       DCD signal follows remote carrier, DSR on when modem ready
  236. X    S54=3       pass BREAK signal to remote modem
  237. X    S55=0       respond to command escape sequence
  238. X    S58=2       DTE uses CTS/RTS flow control.
  239. X    S64=1       ignore characters sent by DTE while answering
  240. X    S66=0       don't lock interface speed, just go with the flow.
  241. X    S68=255     DCE uses whatever flow control DTE uses
  242. X    S92=1       PEP tones at the end of answer sequence
  243. X    S95=0       no MNP
  244. X    S110=255    use data compression when the remote modem requests it.
  245. X    S111=255    accept any protocol
  246. X--------------------------------------------------------------------------*/
  247. Xvoid
  248. Xinit_TBPlus()
  249. X{
  250. Xregister itmp;
  251. Xint maxretry = 4;
  252. Xchar *init0 = "AT&FE0F1M0Q4V1X3\r";
  253. Xchar *init1 = "ATS0=1S2=1S11=50S45=1S48=1S50=0S51=255S52=2S53=1S54=3\r";
  254. Xchar *init2 = "ATS55=0S58=2S64=1S66=0S68=255S92=1S95=0S110=255S111=255\r";
  255. X
  256. X    DEBUG(7,"INITIALIZING %s\n",dce_name);
  257. X
  258. X    ltoggleDTR(0L);
  259. X
  260. X    sync_Telebit();
  261. X
  262. X    /*
  263. X     * set to factory default (bless them for this command)
  264. X     * and a few initial beachhead values
  265. X     */
  266. X    for(itmp = 0; itmp < maxretry; itmp++)
  267. X    {
  268. X        lwrite("AT&FE0F1M0Q4V1X3\r");
  269. X        if(lread(2) == rOk)
  270. X            break;
  271. X    }
  272. X    if(itmp == maxretry)
  273. X    {
  274. X        DEBUG(1,"INIT FAILED (init0)\n",0);
  275. X        myexit(RC_FAIL | RCE_TIMOUT);
  276. X    }
  277. X
  278. X    /*
  279. X     * send initialization string 1
  280. X     */
  281. X    for(itmp = 0; itmp < maxretry; itmp++)
  282. X    {
  283. X        lwrite(init1);
  284. X        if(lread(2) == rOk)
  285. X            break;
  286. X    }
  287. X    if(itmp == maxretry)
  288. X    {
  289. X        DEBUG(1,"INIT FAILED (init1)\n",0);
  290. X        myexit(RC_FAIL | RCE_TIMOUT);
  291. X    }
  292. X
  293. X    /*
  294. X     * send initialization string 2
  295. X     */
  296. X    for(itmp = 0; itmp < maxretry; itmp++)
  297. X    {
  298. X        lwrite(init2);
  299. X        if(lread(2) == rOk)
  300. X            break;
  301. X    }
  302. X    if(itmp == maxretry)
  303. X    {
  304. X        DEBUG(1,"INIT FAILED (init2)\n",0);
  305. X        myexit(RC_FAIL | RCE_TIMOUT);
  306. X    }
  307. X
  308. X}    /* end of init_TBPlus */
  309. X
  310. X/*+-------------------------------------------------------------------------
  311. X    DCE_hangup() - issue hangup command to DCE
  312. X
  313. XThis function should do whatever is necessary to ensure
  314. X1) any active connection is terminated
  315. X2) the DCE is ready to receive an incoming call if DTR is asserted
  316. X3) the DCE will not accept an incoming call if DTR is false
  317. X
  318. XThe function should return when done.
  319. X
  320. XAny necessary switch setting or other configuration necessary for this
  321. Xfunction to succeed should be documented at the top of the module.
  322. X--------------------------------------------------------------------------*/
  323. Xvoid
  324. XDCE_hangup()
  325. X{
  326. X    DEBUG(7,"RESETING %s\n",dce_name);
  327. X    ltoggle_DTR(0L);
  328. X    nap(100L);
  329. X    init_TBPlus();
  330. X
  331. X}    /* end of DCE_hangup */
  332. X
  333. X/*+-------------------------------------------------------------------------
  334. X    DCE_dial(telno) - dial a remote DCE
  335. X
  336. XThis function should connect to the remote DCE and use any success
  337. Xindication to modify the tty baud rate if necessary before returning.
  338. X
  339. XUpon successful connection, return 0.
  340. X
  341. XUpon unsuccessful connection, return RC_FAIL or'd with an appropriate
  342. XRCE_XXX value from dialer.h.
  343. X
  344. Xlwrite() is used to write to the DCE.
  345. X
  346. Xlread() and lread_ignore() are used to read from the DCE.  Read timeouts
  347. Xfrom calling lread() will result automatically in the proper error
  348. Xtermination of the program.  Read timeouts from calling lread_ignore()
  349. Xreturn -1; you handle the execption here.
  350. X
  351. XAny necessary coding of phone numbers, switch settings or other
  352. Xconfiguration necessary for this function to succeed should be
  353. Xdocumented at the top of the module.
  354. X
  355. XTelebit Plus-specific comments:
  356. X S0=0        dont allow connect while dialing
  357. X S54=3       pass BREAK signal to remote modem
  358. X S64=0       abort dialing if characters sent by DTE
  359. X S66=1       lock the interface speed
  360. X S110=0      disable data compression unless requested otherwise
  361. X--------------------------------------------------------------------------*/
  362. Xint
  363. XDCE_dial(telno)
  364. Xchar *telno;
  365. X{
  366. Xchar cmd[128];
  367. Xchar phone[50];
  368. Xint s50_set = 0;
  369. Xint s111_set = 0;
  370. Xint timeout;
  371. Xint result;
  372. Xint rrings = 0;
  373. Xlong then;
  374. Xlong now;
  375. Xchar *cptr;
  376. Xchar *dialout_default = "ATS0=0S7=40S54=3S64=0S66=1S110=0\r";
  377. X#define MDVALID     "0123456789CcEeFfKkMmNnPpRrSsUuWwXx*#,!/()-"
  378. X
  379. X/* preliminary setup */
  380. X    translate("=,-,",telno);
  381. X    if(strspn(telno,MDVALID) != strlen(telno))
  382. X    {
  383. X        DEBUG(1,"phone number has invalid characters\n",0);
  384. X        return(RC_FAIL | RCE_PHNO);
  385. X    }
  386. X    if(decode_phone_number(telno,phone,sizeof(phone)))
  387. X    {
  388. X        DEBUG(1,"phone number too long\n",0);
  389. X        return(RC_FAIL | RCE_PHNO);
  390. X    }
  391. X
  392. X/* walk through dialer codes, doing custom setup */
  393. X    strcpy(cmd,"AT");
  394. X    cptr = cmd + strlen(cmd);
  395. X    if(dialer_codes['C' - 'A'])
  396. X    {
  397. X        DEBUG(5,"COMPRESSION requested\n",0);
  398. X        strcat(cmd,"S110=1");
  399. X    }
  400. X    if(dialer_codes['E' - 'A'])
  401. X    {
  402. X        DEBUG(5,"ECHO SUPPRESSION requested\n",0);
  403. X        strcat(cmd,"S121=1");
  404. X    }
  405. X    if(dialer_codes['F' - 'A'])
  406. X    {
  407. X        DEBUG(5,"XON/XOFF FLOW CONTROL requested\n",0);
  408. X        strcat(cmd,"S58=3");
  409. X    }
  410. X    if(dialer_codes['K' - 'A'])
  411. X    {
  412. X        DEBUG(5,"KERMIT requested\n",0);
  413. X        strcat(cmd,"S111=10");
  414. X        s111_set++;
  415. X    }
  416. X    if(dialer_codes['X' - 'A'])
  417. X    {
  418. X        DEBUG(5,"XMODEM requested\n",0);
  419. X        strcat(cmd,"S111=20");
  420. X        s111_set++;
  421. X    }
  422. X    if(dialer_codes['U' - 'A'])
  423. X    {
  424. X        DEBUG(5,"UUCP requested\n",0);
  425. X        strcat(cmd,"S111=30");
  426. X        s111_set++;
  427. X    }
  428. X    if(dialer_codes['M' - 'A'])
  429. X    {
  430. X        DEBUG(5,"MNP requested\n",0);
  431. X        strcat(cmd,"S95=1");
  432. X    }
  433. X
  434. X    if((dialer_codes['P' - 'A']) || s111_set || (hiCBAUD >= B9600))
  435. X    {
  436. X        if(hiCBAUD < B9600)
  437. X        {
  438. X            DEBUG(1,"baud rate not high enough for PEP\n",0);
  439. X            return(RC_FAIL | RCE_SPEED);
  440. X        }
  441. X        if(dialer_codes['P' - 'A'])
  442. X            DEBUG(5,"PEP requested\n",0);
  443. X        else
  444. X            DEBUG(5,"PEP inferred: speed >= 9600\n",0);
  445. X
  446. X        dialer_codes['P' - 'A'] = 1;
  447. X        strcat(cmd,"S50=255");
  448. X    }
  449. X
  450. X
  451. X    DEBUG(6,"--> issuing default setup command\n",0);
  452. X    sync_Telebit();
  453. X    lwrite(dialout_default);
  454. X    if(lread(2) != rOk)
  455. X    {
  456. X        DEBUG(1,"default dialout setup failed\n",0);
  457. X        return(RC_FAIL | RCE_NULL);
  458. X    }
  459. X
  460. X/* issue the custom setup command */
  461. X    if(*cptr)
  462. X    {
  463. X        DEBUG(5,"--> issuing custom setup cmd\n",0);
  464. X        strcat(cmd,"\r");
  465. X        sync_Telebit();
  466. X        lwrite(cmd);
  467. X        if(lread(2) != rOk)
  468. X        {
  469. X            DEBUG(1,"custom modem setup failed\n",0);
  470. X            return(RC_FAIL | RCE_NULL);
  471. X        }
  472. X    }
  473. X
  474. X/*
  475. X * calculate a timeout for the connect
  476. X * allow a minimum of 40 seconds, but if PEP, 90
  477. X * also if long distance (North American calculation here)
  478. X * make it 132 (S7 is calculated as timeout * .9)
  479. X */
  480. X    timeout = 40;
  481. X    if((phone[0] == '1') && (phone[0] != '0'))
  482. X        timeout = 132;
  483. X    if((timeout < 90) && dialer_codes['P' - 'A'])
  484. X        timeout = 90;
  485. X    for(cptr = phone; cptr = strchr(cptr,','); cptr++)
  486. X        timeout += 2;    /* add extra time for pause characters */
  487. X    DEBUG(6,"timeout waiting for connect = %d seconds\n",timeout);
  488. X
  489. X/* indicate non-root should not see DTE->DCE traffic */
  490. X    secure = 1;
  491. X
  492. X/*
  493. X * build and issue the actual dialing command
  494. X * if root, let him see number, otherwise just say "remote system"
  495. X */
  496. X    DEBUG(1,"--> dialing %s\n", (uid) ? "remote system" : telno);
  497. X#ifdef WHT
  498. X    if(!strncmp(*gargv,"ECU",3))
  499. X        dialer_codes['S' - 'A'] = 1;
  500. X#endif
  501. X    sprintf(cmd,"ATM%dS7=%dDT%s\r",
  502. X        ((dialer_codes['S' - 'A']) && !(dialer_codes['N' - 'A'])) ? 1 : 0,
  503. X        (timeout * 9) / 10,telno);
  504. X
  505. X    /* cmd string can only be 80 characters including "AT" */
  506. X    if(strlen(cmd) > 80)
  507. X    {
  508. X        DEBUG(1,"phone number string too long\n",0);
  509. X        cleanup(RC_FAIL | RCE_PHNO);
  510. X    }
  511. X
  512. X    sync_Telebit();
  513. X    lwrite(cmd);
  514. X
  515. X/* indicate non-root can see DTE->DCE traffic */
  516. X    secure = 0;
  517. X
  518. X/* wait for connect */
  519. XWAIT_FOR_CONNECT:
  520. X    time(&then);
  521. X    result = lread(timeout);
  522. X    if(!(result & rfConnect))
  523. X    {
  524. X        switch(result & rfMASK)
  525. X        {
  526. X        case rNoCarrier:
  527. X            return(RC_FAIL | ((rrings > 2) ? RCE_ANSWER : RCE_NOTONE));
  528. X        case rNoDialTone:
  529. X            return(RC_FAIL | RCE_NOTONE);
  530. X        case rBusy:
  531. X            return(RC_FAIL | RCE_BUSY);
  532. X        case rNoAnswer:
  533. X            return(RC_FAIL | RCE_ANSWER);
  534. X        case rRring:
  535. X            if(rrings++ > 7)
  536. X                return(RC_FAIL | RCE_ANSWER);
  537. X            time(&now);
  538. X            if((timeout -= ((int)(then - now))) > 0)
  539. X                goto WAIT_FOR_CONNECT;
  540. X        case rError:
  541. X        default:
  542. X            return(RC_FAIL | RCE_NULL);
  543. X        }
  544. X    }
  545. X
  546. X    return(0);        /* succeeded */
  547. X
  548. X}    /* end of DCE_dial */
  549. X
  550. X/**********************************************************
  551. X*  You probably do not need to modify the code below here *
  552. X**********************************************************/
  553. X
  554. X/*+-------------------------------------------------------------------------
  555. X    DCE_abort(sig) - dial attempt aborted
  556. X
  557. X sig =  0 if non-signal abort (read timeout, most likely)
  558. X     != 0 if non-SIGALRM signal caught
  559. X
  560. X extern int dialing set  1 if dialing request was active,
  561. X                    else 0 if hangup request was active
  562. X
  563. XThis is a chance for the DCE-specific code to do anything it
  564. Xneeds to cl,ean up after a failure.  Note that if a dialing
  565. Xcall fails, it is the responsibility of the higher-level
  566. Xprogram calling the dialer to call it again with a hangup request, so
  567. Xthis function is usually a no-op.
  568. X--------------------------------------------------------------------------*/
  569. Xvoid
  570. XDCE_abort(sig)
  571. Xint sig;
  572. X{
  573. X    DEBUG(10,"DCE_abort(%d);\n",sig);
  574. X}    /* end of DCE_abort */
  575. X
  576. X/*+-------------------------------------------------------------------------
  577. X    DCE_exit(exitcode) - "last chance for gas" in this incarnation
  578. X
  579. XThe independent portion of the dialer program calls this routine in
  580. Xlieu of exit() in every case except one (see DCE_argv_hook() below).
  581. XNormally, this function just passes it's argument to exit(), but
  582. Xany necessary post-processing can be done.  The function must,
  583. Xhowever, eventually call exit(exitcode);
  584. X--------------------------------------------------------------------------*/
  585. Xvoid
  586. XDCE_exit(exitcode)
  587. Xint exitcode;
  588. X{
  589. X    DEBUG(10,"DCE_exit(%d);\n",exitcode);
  590. X    exit(exitcode);
  591. X}    /* end of DCE_exit */
  592. X
  593. X/*+-------------------------------------------------------------------------
  594. X    DCE_argv_hook(argc,argv,optind,unrecognized_switches)
  595. X
  596. XThis hook gives DCE-specific code a chance to look over the entire
  597. Xcommand line, such as for -z Telebit processing.
  598. X
  599. Xargc andf argv are the same values passed to main(),
  600. X
  601. Xoptind is the value of optind at the end of normal getopt processing.
  602. X
  603. Xunrecognized_switches is the count of switches not handled by main().
  604. XSpecifically, -h and -x are standard switches.
  605. X
  606. XNormally, this function should just return RC_FAIL|RCE_ARGS if there are
  607. Xany unrecognized switches, otherwise zero.  If you keep your nose clean
  608. Xthough, you can do anything you need to do here and exit the program.
  609. X
  610. XNote: only simple switches (with no argument) may be used with this
  611. Xfacility if the functrion is to return,' since main()'s getopt() will
  612. Xstop processing switches if it runs into an unrecognized switch with an
  613. Xargument.
  614. X
  615. XIf the function returns a non-zero value, then the value will be passed
  616. XDIRECTLY to exit() with no further ado.  Thus, a non-zero value must be
  617. Xof the format expected by dialer program callers, with RC_FAIL set as a
  618. Xminimum.
  619. X--------------------------------------------------------------------------*/
  620. Xint
  621. XDCE_argv_hook(argc,argv,optind,unrecognized_switches)
  622. Xint argc;
  623. Xchar **argv;
  624. Xint optind;
  625. Xint unrecognized_switches;
  626. X{
  627. X    if(unrecognized_switches)
  628. X        return(RC_FAIL | RCE_ARGS);
  629. X    return(0);
  630. X}    /* end of DCE_argv_hook */
  631. X
  632. X/* vi: set tabstop=4 shiftwidth=4: */
  633. SHAR_EOF
  634. $TOUCH -am 1226050290 'gendial/dceT1000.c' &&
  635. chmod 0644 gendial/dceT1000.c ||
  636. echo 'restore of gendial/dceT1000.c failed'
  637. Wc_c="`wc -c < 'gendial/dceT1000.c'`"
  638. test 17704 -eq "$Wc_c" ||
  639.     echo 'gendial/dceT1000.c: original size 17704, current size' "$Wc_c"
  640. # ============= gendial/dceMPAD.c ==============
  641. echo 'x - extracting gendial/dceMPAD.c (Text)'
  642. sed 's/^X//' << 'SHAR_EOF' > 'gendial/dceMPAD.c' &&
  643. X/* CHK=0xFF53 */
  644. X#define WHT
  645. X/*+-------------------------------------------------------------------------
  646. X    dceMPAD.c - DCE-specific portion of generic SCO UUCP dialer
  647. X    Driver for ATT Tridom MPAD VSAT modem emulation
  648. X    wht@n4hgf.Mt-Park.GA.US
  649. X--------------------------------------------------------------------------*/
  650. X/*+:EDITS:*/
  651. X/*:11-29-1990-18:31-r@n4hgf-revision/1st releasable */
  652. X/*:11-29-1990-17:48-wht@n4hgf-creation */
  653. X
  654. X#include "dialer.h"
  655. X
  656. X/*
  657. X * DCE_DTR_low_msec - milliseconds to hold DTR low to ensure DCE
  658. X *                    sees the transition; this value may be changed
  659. X *                    as necessary before each call to ltoggleDTR(),
  660. X * but, generally, a constant value will do.
  661. X */
  662. Xlong DCE_DTR_low_msec = 50;
  663. X
  664. X/*
  665. X * DCE_DTR_high_msec - milliseconds DTR must remain high before the
  666. X *                     DCE may be expected to be ready to be commanded
  667. X */
  668. Xlong DCE_DTR_high_msec = 50;
  669. X
  670. X/*
  671. X * DCE_write_pase_msec - milliseconds to pause between each character
  672. X *                       sent to the DCE (zero if streaming I/O is
  673. X *                       permitted); this value may be changed as
  674. X * necessary before each call to lwrite(), but, generally, a constant
  675. X * value will do.  Note that this value is used to feed a value to nap(),
  676. X * which has a granularity of .010 seconds on UNIX/386, .020 on XENIX/286
  677. X * and .050 seconds on XENIX/86.
  678. X */
  679. Xlong DCE_write_pace_msec = 0;
  680. X
  681. X/*
  682. X * DCE_name     - short name for DCE
  683. X * DCE_revision - revision number for this module
  684. X */
  685. Xchar *DCE_name = "ATT Tridom MPAD";
  686. Xchar *DCE_revision = "x1.00";
  687. X
  688. X/*
  689. X * DCE_hangup_CBAUD - baud rate to use for hanging up DCE
  690. X *                    and readying it for dial in access
  691. X *                    (BXXX mask); use a value of zero if the speed
  692. X *                    specified by the invoker is to be used.
  693. X * This value is useful for DCEs such as the early Hayes 2400
  694. X * which are so unfortunately compatible with their 1200 predecessor
  695. X * that they refuse to answer at 2400 baud unless you last spoke to
  696. X * them at that rate. For such bad boys, use B2400 below.
  697. X */
  698. Xint DCE_hangup_CBAUD = 0;
  699. X/* int DCE_hangup_CBAUD = B2400; */
  700. X
  701. X/*
  702. X * DCE_results - a table of DCE response strings and a token
  703. X *               code for each; when you call lread() or lread_ignore(),
  704. X *               if the read routine detects one of the strings,
  705. X * the appropriate code is returned.  If no string matches, then
  706. X * lread()/lread_ignore examines the DCE result string for a
  707. X * numeric value; if one is found, the numeric value or'd with
  708. X * 0x40000000 is returned (in this way, e.g., you can read "modem
  709. X * S registers").  If nothing agrees with this search, lread()
  710. X * will abort the program with RC|FAIL|RCE_TIMOUT, lread_ignore()
  711. X * will return -1.  You may use any value between 0 and 0x3FFFFFFF.
  712. X * This module is the only consumer  of the codes, although they
  713. X * are decoded by gendial.c's _lread()
  714. X */
  715. X
  716. X/* flag bits */
  717. X#define rfConnect        0x00800000
  718. X#define rfMASK            0x0000FFFF    /* mask off rfBits */
  719. X
  720. X/* unique codes */
  721. X#define rOk                0
  722. X#define rNoCarrier        1
  723. X#define rError            2
  724. X#define rNoDialTone     3
  725. X#define rBusy            4
  726. X#define rNoAnswer        5
  727. X#define rRring            6
  728. X#define rConnect300        (  300  | rfConnect)
  729. X#define rConnect1200    ( 1200  | rfConnect)
  730. X#define rConnect2400    ( 2400  | rfConnect)
  731. X#define rConnect4800    ( 4800  | rfConnect)
  732. X#define rConnect9600    ( 9600  | rfConnect)
  733. X#define rConnect9600    ( 9600  | rfConnect)
  734. X#define rConnect19200    (19200  | rfConnect)
  735. X#define rConnect38400    (38400  | rfConnect)
  736. X
  737. XDCE_RESULT DCE_results[] =
  738. X{
  739. X    { "OK",                    rOk,            },
  740. X    { "NO CARRIER",            rNoCarrier,        },
  741. X    { "ERROR",                rError            },
  742. X    { "BUSY",                rBusy            },
  743. X    { "NO ANSWER",            rNoAnswer        },
  744. X    { "NO DIAL TONE",       rNoDialTone     },
  745. X    { "KDIR SENDX ERROR",   rNoDialTone     },  /* MPAD software error */
  746. X    { "KDIR UNRESPONSIVE",  rNoDialTone     },
  747. X    { "KDIR BUSY",          rBusy           },
  748. X    { "KDIR BAD REQUEST",   rError          },  /* number 0 or >11 length */
  749. X    { "NO SUCH NUMBER",     rNoAnswer       },
  750. X    { "KDIR LOGIC ERROR",   rNoDialTone     },  /* MPAD software error */
  751. X    { "KDIR NOT AVAIL",     rNoDialTone     },
  752. X    { "TP4 STATE ERROR",    rNoDialTone     },  /* rain fade */
  753. X    { "TP4 GIVE UP",        rBusy           },  /* rain fade */
  754. X    { "TP4 ERROR RESP",     rBusy           },  /* transient problem */
  755. X    { "NET DEACT",          rNoDialTone     },  /* net op deactivated port */
  756. X    { "CONNECT 300",        rConnect300        },
  757. X    { "CONNECT 1200",        rConnect1200    },
  758. X    { "CONNECT 4800",        rConnect4800    },
  759. X    { "CONNECT 9600",        rConnect9600    },
  760. X    { "CONNECT 19200",        rConnect19200    },
  761. X    { "CONNECT 38400",        rConnect38400    },
  762. X    { (char *)0,            -1                }        /* end table */
  763. X};
  764. X
  765. X/*+-------------------------------------------------------------------------
  766. X    DCE_baud_to_CBAUD(baud) - check for valid baud rates supported by DCE
  767. X
  768. X  DCE dependent function must validate baud rates supported by DCE
  769. X  returns baud rate in struct termio c_cflag fashion
  770. X  or terminates program with error
  771. X--------------------------------------------------------------------------*/
  772. Xint
  773. XDCE_baud_to_CBAUD(baud)
  774. Xunsigned int baud;
  775. X{
  776. X    switch(baud)
  777. X    {
  778. X        case 110:  return(B110);
  779. X        case 300:  return(B300);
  780. X        case 1200: return(B1200);
  781. X        case 2400: return(B2400);
  782. X        case 9600: return(B9600);
  783. X
  784. X#if defined(B19200)
  785. X        case 19200: return(B19200);
  786. X#else
  787. X#ifdef EXTA
  788. X        case 19200: return(EXTA);
  789. X#endif
  790. X#endif
  791. X
  792. X#if defined(B38400)
  793. X        case 38400: return(B38400);
  794. X#else
  795. X#ifdef EXTB
  796. X        case 38400: return(EXTB);
  797. X#endif
  798. X#endif
  799. X
  800. X    }
  801. X    myexit(RC_FAIL | RCE_SPEED);
  802. X}    /* end of DCE_baud_to_CBAUD */
  803. X
  804. X/*+-------------------------------------------------------------------------
  805. X    sync_MPAD() - sync modem with our DTE speed
  806. X--------------------------------------------------------------------------*/
  807. Xvoid
  808. Xsync_MPAD()
  809. X{
  810. Xregister int maxretry = 8;
  811. Xregister int count;
  812. Xunsigned char rdchar;
  813. X
  814. X    while(maxretry--)
  815. X    {
  816. X        lflush();
  817. X        write(fddce,"a",1);
  818. X        count = 5;
  819. X        while(count)    /* wait 50-200 msec for character, depending on HZ */
  820. X        {
  821. X            if(rdchk(fddce))
  822. X                break;
  823. X            nap(50L);
  824. X            count--;
  825. X        }
  826. X        if(count && (read(fddce,&rdchar,1) == 1) && (rdchar == 'a'))
  827. X            return;
  828. X        write(fddce,"atq0v1e1\r",9);
  829. X        nap(500L);
  830. X    }
  831. X
  832. X    DEBUG(1,"MPAD SYNC FAILED\n",0);
  833. X    myexit(RC_FAIL | RCE_TIMOUT);
  834. X
  835. X}    /* end of sync_MPAD */
  836. X
  837. X/*+-------------------------------------------------------------------------
  838. X    init_MPAD() - init MPAD from scratch, assuming nothing
  839. X--------------------------------------------------------------------------*/
  840. Xvoid
  841. Xinit_MPAD()
  842. X{
  843. Xregister itmp;
  844. Xint maxretry = 4;
  845. Xchar *init0 = "ATE0Q0V1X99S0=1S2=1\r";
  846. X
  847. X    DEBUG(7,"INITIALIZING %s\n",dce_name);
  848. X    ltoggleDTR(0L);
  849. X    sync_MPAD();
  850. X
  851. X    /*
  852. X     * set to factory default (bless them for this command)
  853. X     * and a few initial beachhead values
  854. X     */
  855. X    for(itmp = 0; itmp < maxretry; itmp++)
  856. X    {
  857. X        lwrite("AT&FE0F1M0Q4V1X3\r");
  858. X        if(lread(2) == rOk)
  859. X            break;
  860. X    }
  861. X    if(itmp == maxretry)
  862. X    {
  863. X        DEBUG(1,"INIT FAILED (init0)\n",0);
  864. X        myexit(RC_FAIL | RCE_TIMOUT);
  865. X    }
  866. X
  867. X}    /* end of init_MPAD */
  868. X
  869. X/*+-------------------------------------------------------------------------
  870. X    DCE_hangup() - issue hangup command to DCE
  871. X
  872. XThis function should do whatever is necessary to ensure
  873. X1) any active connection is terminated
  874. X2) the DCE is ready to receive an incoming call if DTR is asserted
  875. X3) the DCE will not accept an incoming call if DTR is false
  876. X
  877. XThe function should return when done.
  878. X
  879. XAny necessary switch setting or other configuration necessary for this
  880. Xfunction to succeed should be documented at the top of the module.
  881. X--------------------------------------------------------------------------*/
  882. Xvoid
  883. XDCE_hangup()
  884. X{
  885. X    ltoggleDTR(0L);
  886. X    init_MPAD();
  887. X
  888. X}    /* end of DCE_hangup */
  889. X
  890. X/*+-------------------------------------------------------------------------
  891. X    DCE_dial(telno) - dial a remote DCE
  892. X
  893. XThis function should connect to the remote DCE and use any success
  894. Xindication to modify the tty baud rate if necessary before returning.
  895. X
  896. XUpon successful connection, return 0.
  897. X
  898. XUpon unsuccessful connection, return RC_FAIL or'd with an appropriate
  899. XRCE_XXX value from dialer.h.
  900. X
  901. Xlwrite() is used to write to the DCE.
  902. X
  903. Xlread() and lread_ignore() are used to read from the DCE.  Read timeouts
  904. Xfrom calling lread() will result automatically in the proper error
  905. Xtermination of the program.  Read timeouts from calling lread_ignore()
  906. Xreturn -1; you handle the execption here.
  907. X
  908. XAny necessary coding of phone numbers, switch settings or other
  909. Xconfiguration necessary for this function to succeed should be
  910. Xdocumented at the top of the module.
  911. X
  912. XMPAD Plus-specific comments:
  913. X Q0          do not be quiet
  914. X E0          do not echo
  915. X V1          verbal result codes
  916. X S0=0        dont allow connect while dialing
  917. X X99         full result codes
  918. X--------------------------------------------------------------------------*/
  919. Xint
  920. XDCE_dial(telno)
  921. Xchar *telno;
  922. X{
  923. Xchar cmd[128];
  924. Xchar phone[50];
  925. Xint s50_set = 0;
  926. Xint s111_set = 0;
  927. Xint timeout;
  928. Xint result;
  929. Xint rrings = 0;
  930. Xlong then;
  931. Xlong now;
  932. Xchar *cptr;
  933. Xchar *dialout_default = "ATQ0E0V1E0S0=0X99\r";
  934. X#define MDVALID     "0123456789NnSs()-"
  935. X
  936. X/* preliminary setup */
  937. X    translate("=,-,",telno);
  938. X    if(strspn(telno,MDVALID) != strlen(telno))
  939. X    {
  940. X        DEBUG(1,"phone number has invalid characters\n",0);
  941. X        return(RC_FAIL | RCE_PHNO);
  942. X    }
  943. X    if(decode_phone_number(telno,phone,sizeof(phone)))
  944. X    {
  945. X        DEBUG(1,"phone number too long\n",0);
  946. X        return(RC_FAIL | RCE_PHNO);
  947. X    }
  948. X
  949. X/* walk through dialer codes, doing custom setup */
  950. X    strcpy(cmd,"AT");
  951. X    cptr = cmd + strlen(cmd);
  952. X
  953. X    DEBUG(6,"--> issuing default setup command\n",0);
  954. X    sync_MPAD();
  955. X    lwrite(dialout_default);
  956. X    if(lread(2) != rOk)
  957. X    {
  958. X        DEBUG(1,"default dialout setup failed\n",0);
  959. X        return(RC_FAIL | RCE_NULL);
  960. X    }
  961. X
  962. X/* issue the custom setup command */
  963. X    if(*cptr)
  964. X    {
  965. X        DEBUG(5,"--> issuing custom setup cmd\n",0);
  966. X        strcat(cmd,"\r");
  967. X        sync_MPAD();
  968. X        lwrite(cmd);
  969. X        if(lread(2) != rOk)
  970. X        {
  971. X            DEBUG(1,"custom modem setup failed\n",0);
  972. X            return(RC_FAIL | RCE_NULL);
  973. X        }
  974. X    }
  975. X
  976. X/*
  977. X * calculate a timeout for the connect
  978. X */
  979. X    timeout = 20;
  980. X    DEBUG(6,"timeout waiting for connect = %d seconds\n",timeout);
  981. X
  982. X/* indicate non-root should not see DTE->DCE traffic */
  983. X    secure = 1;
  984. X
  985. X/*
  986. X * build and issue the actual dialing command
  987. X * if root, let him see number, otherwise just say "remote system"
  988. X */
  989. X    DEBUG(1,"--> dialing %s\n", (uid) ? "remote system" : telno);
  990. X    sprintf(cmd,"ATS7=%dDT%s\r",(timeout * 9) / 10,telno);
  991. X
  992. X    /* cmd string can only be 40 characters including "AT" */
  993. X    if(strlen(cmd) > 40)
  994. X    {
  995. X        DEBUG(1,"phone number string too long\n",0);
  996. X        cleanup(RC_FAIL | RCE_PHNO);
  997. X    }
  998. X
  999. X    sync_MPAD();
  1000. X    lwrite(cmd);
  1001. X
  1002. X/* indicate non-root can see DTE->DCE traffic */
  1003. X    secure = 0;
  1004. X
  1005. X/* wait for connect */
  1006. XWAIT_FOR_CONNECT:
  1007. X    time(&then);
  1008. X    result = lread(timeout);
  1009. X    if(!(result & rfConnect))
  1010. X    {
  1011. X        switch(result & rfMASK)
  1012. X        {
  1013. X        case rNoCarrier:
  1014. X            return(RC_FAIL | ((rrings > 2) ? RCE_ANSWER : RCE_NOTONE));
  1015. X        case rNoDialTone:
  1016. X            return(RC_FAIL | RCE_NOTONE);
  1017. X        case rBusy:
  1018. X            return(RC_FAIL | RCE_BUSY);
  1019. X        case rNoAnswer:
  1020. X            return(RC_FAIL | RCE_ANSWER);
  1021. X        case rRring:
  1022. X            if(rrings++ > 7)
  1023. X                return(RC_FAIL | RCE_ANSWER);
  1024. X            time(&now);
  1025. X            if((timeout -= ((int)(then - now))) > 0)
  1026. X                goto WAIT_FOR_CONNECT;
  1027. X        case rError:
  1028. X        default:
  1029. X            return(RC_FAIL | RCE_NULL);
  1030. X        }
  1031. X    }
  1032. X
  1033. X    return(0);        /* succeeded */
  1034. X
  1035. X}    /* end of DCE_dial */
  1036. X
  1037. X/**********************************************************
  1038. X*  You probably do not need to modify the code below here *
  1039. X**********************************************************/
  1040. X
  1041. X/*+-------------------------------------------------------------------------
  1042. X    DCE_abort(sig) - dial attempt aborted
  1043. X
  1044. X sig =  0 if non-signal abort (read timeout, most likely)
  1045. X     != 0 if non-SIGALRM signal caught
  1046. X
  1047. X extern int dialing set  1 if dialing request was active,
  1048. X                    else 0 if hangup request was active
  1049. X
  1050. XThis is a chance for the DCE-specific code to do anything it
  1051. Xneeds to cl,ean up after a failure.  Note that if a dialing
  1052. Xcall fails, it is the responsibility of the higher-level
  1053. Xprogram calling the dialer to call it again with a hangup request, so
  1054. Xthis function is usually a no-op.
  1055. X--------------------------------------------------------------------------*/
  1056. Xvoid
  1057. XDCE_abort(sig)
  1058. Xint sig;
  1059. X{
  1060. X    DEBUG(10,"DCE_abort(%d);\n",sig);
  1061. X}    /* end of DCE_abort */
  1062. X
  1063. X/*+-------------------------------------------------------------------------
  1064. X    DCE_exit(exitcode) - "last chance for gas" in this incarnation
  1065. X
  1066. XThe independent portion of the dialer program calls this routine in
  1067. Xlieu of exit() in every case except one (see DCE_argv_hook() below).
  1068. XNormally, this function just passes it's argument to exit(), but
  1069. Xany necessary post-processing can be done.  The function must,
  1070. Xhowever, eventually call exit(exitcode);
  1071. X--------------------------------------------------------------------------*/
  1072. Xvoid
  1073. XDCE_exit(exitcode)
  1074. Xint exitcode;
  1075. X{
  1076. X    DEBUG(10,"DCE_exit(%d);\n",exitcode);
  1077. X    exit(exitcode);
  1078. X}    /* end of DCE_exit */
  1079. X
  1080. X/*+-------------------------------------------------------------------------
  1081. X    DCE_argv_hook(argc,argv,optind,unrecognized_switches)
  1082. X
  1083. XThis hook gives DCE-specific code a chance to look over the entire
  1084. Xcommand line, such as for -z processing.
  1085. X
  1086. Xargc andf argv are the same values passed to main(),
  1087. X
  1088. Xoptind is the value of optind at the end of normal getopt processing.
  1089. X
  1090. Xunrecognized_switches is the count of switches not handled by main().
  1091. XSpecifically, -h and -x are standard switches.
  1092. X
  1093. XNormally, this function should just return RC_FAIL|RCE_ARGS if there are
  1094. Xany unrecognized switches, otherwise zero.  If you keep your nose clean
  1095. Xthough, you can do anything you need to do here and exit the program.
  1096. X
  1097. XNote: only simple switches (with no argument) may be used with this
  1098. Xfacility if the functrion is to return,' since main()'s getopt() will
  1099. Xstop processing switches if it runs into an unrecognized switch with an
  1100. Xargument.
  1101. X
  1102. XIf the function returns a non-zero value, then the value will be passed
  1103. XDIRECTLY to exit() with no further ado.  Thus, a non-zero value must be
  1104. Xof the format expected by dialer program callers, with RC_FAIL set as a
  1105. Xminimum.
  1106. X--------------------------------------------------------------------------*/
  1107. Xint
  1108. XDCE_argv_hook(argc,argv,optind,unrecognized_switches)
  1109. Xint argc;
  1110. Xchar **argv;
  1111. Xint optind;
  1112. Xint unrecognized_switches;
  1113. X{
  1114. X    if(unrecognized_switches)
  1115. X        return(RC_FAIL | RCE_ARGS);
  1116. X    return(0);
  1117. X}    /* end of DCE_argv_hook */
  1118. X
  1119. X/* vi: set tabstop=4 shiftwidth=4: */
  1120. SHAR_EOF
  1121. $TOUCH -am 1226050090 'gendial/dceMPAD.c' &&
  1122. chmod 0644 gendial/dceMPAD.c ||
  1123. echo 'restore of gendial/dceMPAD.c failed'
  1124. Wc_c="`wc -c < 'gendial/dceMPAD.c'`"
  1125. test 14315 -eq "$Wc_c" ||
  1126.     echo 'gendial/dceMPAD.c: original size 14315, current size' "$Wc_c"
  1127. # ============= xsel386/fixttiocom.c ==============
  1128. if test ! -d 'xsel386'; then
  1129.     echo 'x - creating directory xsel386'
  1130.     mkdir 'xsel386'
  1131. fi
  1132. echo 'x - extracting xsel386/fixttiocom.c (Text)'
  1133. sed 's/^X//' << 'SHAR_EOF' > 'xsel386/fixttiocom.c' &&
  1134. X/*+-------------------------------------------------------------------------
  1135. X    fixttiocom.c - change ttiocom to Ttiocom calls in /usr/sys/sys/libsys.a
  1136. XThis program patched my Xenix 386 2.3.1 system library (a copy of which
  1137. Xhad been named libfix.a, fixed, verified, then moved to libsys.a)
  1138. X--------------------------------------------------------------------------*/
  1139. X/*+:EDITS:*/
  1140. X/*:08-14-1990-20:40-wht@n4hgf-ecu3.00-flush old edit history */
  1141. X
  1142. X#include <stdio.h>
  1143. X#include <sys/types.h>
  1144. X#include <fcntl.h>
  1145. X
  1146. Xchar *lib = "libfix.a";
  1147. X
  1148. X/* file positions where names needed changing */
  1149. X#define PLACE1 0xdcaL
  1150. X#define PLACE2 0x1b1cbL
  1151. X#define PLACE3 0x1c41bL
  1152. X
  1153. X/*+-------------------------------------------------------------------------
  1154. X    main(argc,argv,envp)
  1155. X--------------------------------------------------------------------------*/
  1156. Xmain(argc,argv,envp)
  1157. Xint argc;
  1158. Xchar **argv;
  1159. Xchar **envp;
  1160. X{
  1161. Xint fd = open(lib,O_RDWR,0);
  1162. Xunsigned char ch1,ch2,ch3;
  1163. Xlong lseek();
  1164. X
  1165. X    if(fd < 0)
  1166. X    {
  1167. X        perror(lib);
  1168. X        exit(9);
  1169. X    }
  1170. X
  1171. X    if(lseek(fd,PLACE1,0) != PLACE1)
  1172. X    {
  1173. X        perror("seek1");
  1174. X        exit(1);
  1175. X    }
  1176. X    if(read(fd,&ch1,1) != 1)
  1177. X    {
  1178. X        perror("read1");
  1179. X        exit(1);
  1180. X    }
  1181. X    printf("char 1 = %02x\n",ch1);
  1182. X
  1183. X    if(lseek(fd,PLACE2,0) != PLACE2)
  1184. X    {
  1185. X        perror("seek2");
  1186. X        exit(2);
  1187. X    }
  1188. X    if(read(fd,&ch2,2) != 2)
  1189. X    {
  1190. X        perror("read2");
  1191. X        exit(2);
  1192. X    }
  1193. X    printf("char 2 = %02x\n",ch2);
  1194. X
  1195. X
  1196. X    if(lseek(fd,PLACE3,0) != PLACE3)
  1197. X    {
  1198. X        perror("seek3");
  1199. X        exit(3);
  1200. X    }
  1201. X    if(read(fd,&ch3,1) != 1)
  1202. X    {
  1203. X        perror("read3");
  1204. X        exit(3);
  1205. X    }
  1206. X    printf("char 3 = %02x\n",ch3);
  1207. X
  1208. X    if((ch1 != 't') || (ch2 != 't') || (ch3 != 't'))
  1209. X        exit(8);
  1210. X    if(lseek(fd,PLACE1,0) != PLACE1)
  1211. X    {
  1212. X        perror("seek1");
  1213. X        exit(1);
  1214. X    }
  1215. X    write(fd,"T",1);
  1216. X    if(lseek(fd,PLACE2,0) != PLACE2)
  1217. X    {
  1218. X        perror("seek1");
  1219. X        exit(1);
  1220. X    }
  1221. X    write(fd,"T",1);
  1222. X    if(lseek(fd,PLACE3,0) != PLACE3)
  1223. X    {
  1224. X        perror("seek1");
  1225. X        exit(1);
  1226. X    }
  1227. X    write(fd,"T",1);
  1228. X    printf("done\n");
  1229. X    close(fd);
  1230. X
  1231. X    exit(0);
  1232. X}    /* end of main */
  1233. X
  1234. X/* vi: set tabstop=4 shiftwidth=4: */
  1235. X/* end of fixttiocom.c */
  1236. SHAR_EOF
  1237. $TOUCH -am 0814204290 'xsel386/fixttiocom.c' &&
  1238. chmod 0644 xsel386/fixttiocom.c ||
  1239. echo 'restore of xsel386/fixttiocom.c failed'
  1240. Wc_c="`wc -c < 'xsel386/fixttiocom.c'`"
  1241. test 1949 -eq "$Wc_c" ||
  1242.     echo 'xsel386/fixttiocom.c: original size 1949, current size' "$Wc_c"
  1243. # ============= xsel386/select-update ==============
  1244. echo 'x - extracting xsel386/select-update (Text)'
  1245. sed 's/^X//' << 'SHAR_EOF' > 'xsel386/select-update' &&
  1246. XSubject: Re: Select(S) in Xenix 386 2.3.2
  1247. XNewsgroups: comp.unix.xenix
  1248. XKeywords: select, serial, pipes
  1249. XReferences: <117@accsys.acc.uu.no> <172@prmmbx.UUCP>
  1250. X
  1251. XIn article <172@prmmbx.UUCP>, csch@netcs.UUCP (Clemens Schrimpe) writes:
  1252. X> ivar@acc.uu.no (Ivar Hosteng) writes:
  1253. X> <> I have experienced some problems using the select call in Xenix 386 V2.3.2.
  1254. X> <> It does not seems to detect when a pipe gets ready to been read from.
  1255. X> This is, because there is no provision to select on pipes!
  1256. X> Why? The stuff is almost totally ported 1:1 from the Berkeley code and
  1257. X> in BSD pipes should consist of AF_UNIX sockets, on which you can naturally
  1258. X> select.
  1259. X> I was very angry, when I found this out after hours of digging with adb in
  1260. X> the kernel. But I also tried the same on a SUN under SunOS 4.0 and it doesn't
  1261. X> work either ... seems to be a common illness ???
  1262. X> (I wonder, because the code for that is very simple ... ??? ...)
  1263. X> 
  1264. X> <> I also 
  1265. X> <> have trouble using select on a serial port.  When I do that the input
  1266. X> <> turns into garbage.  This does not occur when I use select on the
  1267. X> <> multiscreen ttys (tty01-tty12).
  1268. X> Hehe - we had just the same!
  1269. X> Here is the solution (thanks to my colleague Stefan Koehler, who took one
  1270. X> look at my screen, into which I had starred for hours, to find it ...)
  1271. X> 
  1272. X> Select is implemented by an undocumented ioctl
  1273. X>     (0xFFFF == IOC_SELECT -> [sys/slect.h])
  1274. X> which is handled by ttiocom() for all devices using the standard
  1275. X> SYS-V linediscipline!
  1276. X> 
  1277. X> The ioctl-routine for the serial devices [sioioctl()] just calls 
  1278. X> ttiocom() [after some undefinable VPIX stuff ???] and
  1279. X> if it returns NON-ZERO it calls sioparam(), which adjusts certain
  1280. X> parameters and garbles the output!
  1281. X> OK so far. Now: The Bug lies in the ttiocom-code within the check
  1282. X> for IOC_SELECT. After detecting the IOC_SELECT, the ttiocom calls
  1283. X> the select-code and returns NOTHING, which means that if EAX is
  1284. X> non-zero (randomly) sioparam() is called and garbles the output.
  1285. X> 
  1286. X> The Fix: (quick and dirty)
  1287. X> Write a routine called "ttiocom", which might look like this:
  1288. X> 
  1289. X> ttiocom(ttyp, com, arg, flag)
  1290. X> struct tty *ttyp;
  1291. X> int com, arg, flag;    /* there should be better types for this :-) */
  1292. X> {
  1293. X>     if (com == IOC_SELECT)
  1294. X>     {
  1295. X>         ttselect(ttyp, flag);
  1296. X>         return(0);    /*** THIS IS IMPORTANT ***/
  1297. X>     }
  1298. X>     return(Ttiocom(ttyp, com ,arg, flag));
  1299. X> }
  1300. X> 
  1301. X> Compile something like this, then use whatever you have (GNU-Emacs is
  1302. X> great in patching strings in binaries) to patch /usr/sys/sys/libsys.a
  1303. X> to change the original ttiocom into Ttiocom !
  1304. X> Link in your code and -by some magic reason- experience a full blown
  1305. X> select on your System V / Xenix machine!!!
  1306. X> 
  1307. X> Have fun playing around with it -
  1308. X> 
  1309. X>     Clemens Schrimpe, netCS Informationstechnik GmbH Berlin
  1310. X> --
  1311. X> UUCP:        csch@netcs        BITNET:    csch@db0tui6.BITNET
  1312. X> ARPA/NSF:    csch@garp.mit.edu    PSI: PSI%45300033047::CSCH
  1313. X> PHONE:        +49-30-24 42 37        FAX: +49-30-24 38 00
  1314. X> BTX:        0303325016-0003        TELEX: 186672 net d
  1315. X
  1316. X
  1317. SHAR_EOF
  1318. $TOUCH -am 0626113689 'xsel386/select-update' &&
  1319. chmod 0644 xsel386/select-update ||
  1320. echo 'restore of xsel386/select-update failed'
  1321. Wc_c="`wc -c < 'xsel386/select-update'`"
  1322. test 2981 -eq "$Wc_c" ||
  1323.     echo 'xsel386/select-update: original size 2981, current size' "$Wc_c"
  1324. # ============= xsel386/select.asm ==============
  1325. echo 'x - extracting xsel386/select.asm (Text)'
  1326. sed 's/^X//' << 'SHAR_EOF' > 'xsel386/select.asm' &&
  1327. X;  CHK=0x1E37
  1328. X;+----------------------------------------------------------
  1329. X; select(S)
  1330. X;
  1331. X;#include <stdio.h>
  1332. X;#include <sys/select.h>
  1333. X;#include <fcntl.h>
  1334. X;
  1335. X;main(argc,argv,envp)
  1336. X;int argc;
  1337. X;char **argv;
  1338. X;char **envp;
  1339. X;{
  1340. X;struct timeval t;
  1341. X;int readfds;
  1342. X;int fd = open("/dev/null",O_RDONLY,0);
  1343. X;
  1344. X;    readfds = 1<<fd | 1<<0;
  1345. X;
  1346. X;    t.tv_sec = 5;
  1347. X;    t.tv_usec = 0;
  1348. X;
  1349. X;    printf("%d\n",select(32,&readfds,0,0,&t));
  1350. X;    printf("%08x\n",readfds);
  1351. X;    exit(0);
  1352. X;}    /* end of main */
  1353. X;
  1354. X;-----------------------------------------------------------
  1355. X
  1356. X    title    select
  1357. X
  1358. X    .386
  1359. X
  1360. XSYSNUM    equ     2428h
  1361. X
  1362. Xextrn    _errno:dword
  1363. X
  1364. Xpublic  _select
  1365. X
  1366. X_TEXT    segment  dword use32 public 'CODE'
  1367. X    assume   cs: _TEXT
  1368. X_select    proc near
  1369. X    mov    eax, SYSNUM        ; Get system call number.
  1370. X
  1371. X    ;
  1372. X    ; I don't even pretend to understand masm syntax.  I tried
  1373. X    ; the following line (and variations) without any success.
  1374. X    ;
  1375. X
  1376. X;    call    far 7:0            ; Switch to kernel and call SYSNUM.
  1377. X
  1378. X    ;
  1379. X    ; Don't laugh, it works.
  1380. X    ;
  1381. X
  1382. X    db 9ah
  1383. X    dw 0,0
  1384. X    dw 7
  1385. X
  1386. X    jb    short _cerror        ; below == error.
  1387. X
  1388. X;    xor    eax, eax        ; zero return value (no error).
  1389. X    ret                ; done.
  1390. X
  1391. X_cerror:
  1392. X    mov    _errno, eax        ; Save error code in _errno.
  1393. X    mov    eax, -1            ; Return -1 (as error).
  1394. X    ret                ; done.
  1395. X
  1396. X_select    endp
  1397. X
  1398. X_TEXT    ends
  1399. X
  1400. X    end
  1401. X; vi: set tabstop=8 :
  1402. SHAR_EOF
  1403. $TOUCH -am 0507233990 'xsel386/select.asm' &&
  1404. chmod 0644 xsel386/select.asm ||
  1405. echo 'restore of xsel386/select.asm failed'
  1406. Wc_c="`wc -c < 'xsel386/select.asm'`"
  1407. test 1237 -eq "$Wc_c" ||
  1408.     echo 'xsel386/select.asm: original size 1237, current size' "$Wc_c"
  1409. true || echo 'restore of xsel386/select.txt failed'
  1410. echo End of part 27, continue with part 28
  1411. exit 0
  1412. --------------------------------------------------------------------
  1413. Warren Tucker, TuckerWare emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
  1414. Hacker Extraordinaire  d' async PADs,  pods,  proteins and protocols
  1415.  
  1416. exit 0 # Just in case...
  1417. -- 
  1418. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1419. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1420. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1421. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1422.