home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / layers.zoo / layers.2 < prev    next >
Text File  |  1990-06-11  |  48KB  |  1,815 lines

  1.  
  2. #! /bin/sh
  3. # This is a shell archive, meaning:
  4. # 1. Remove everything above the #! /bin/sh line.
  5. # 2. Save the resulting text in a file.
  6. # 3. Execute the file with /bin/sh (not csh) to create the files:
  7. #
  8. #    layers.h
  9. #    layersize.c
  10. #    layertitle.c
  11. #    macbput.c
  12. #    makefile
  13. #    protocol.c
  14. #
  15. # This archive created: Thu May 31 21:58:11 1990
  16. # By:    Roger L. Long (macintosh@dhw68k.cts.com)
  17. export PATH; PATH=/bin:$PATH
  18. echo shar: extracting "'layers.h'" '(2049 characters)'
  19. if test -f 'layers.h'
  20. then
  21.     echo shar: will not over-write existing file "'layers.h'"
  22. else
  23. sed 's/^X//' << \SHAR_EOF > 'layers.h'
  24. X/*             Copyright (C) 1989 by David W. Trissel 
  25. X *
  26. X *  Not derived from licensed software.
  27. X *
  28. X * Permission is granted to freely use, copy, modify, and redistribute
  29. X * this software, provided that no attempt is made to gain profit from it,
  30. X * the author is not construed to be liable for any results of using the
  31. X * software, alterations are clearly marked as such, and this notice is
  32. X * not modified.
  33. X *
  34. X */
  35. X
  36. X#define MAXPCHAN    7                        /* maximum layers supported */
  37. X
  38. X#define MAXSTR        200
  39. X#define    MAXARGS        64
  40. X#define MAXLINE        1024
  41. X#define IOSIZE        800                        /* data gulp handling size */
  42. X
  43. X/* WARNING - packet sizes must be insured to never match the ESCAPE char */
  44. X#define    ESCAPE        '}'                        /* datalink escape character */
  45. X
  46. X#define DO         if (Dflag)                    /* for debugging */
  47. X
  48. X/* miscelaneous common data */
  49. Xextern    int    Dflag;                            /* debug dump indicator flag */
  50. X
  51. X/* Shape structure passed between MacLayers and ourselves */
  52. Xstruct Shape
  53. X{    short    worigv;                            /* verical window bit origin */
  54. X    short    worigh;                            /* horizontal window bit origin */
  55. X    short    wlines;                            /* window height */
  56. X    short    wchars;                            /* window width */
  57. X    short    wfont;                            /* window font size */
  58. X    short    wattr;                            /* window attributes */
  59. X};
  60. X
  61. X#define Wa_shell    0x01                    /* window is a shell */
  62. X
  63. X
  64. X  /* The following modules define the complete protocol/server interface */
  65. X
  66. X                /* layers.c */
  67. X
  68. Xextern void FQuit(/* exitcode */);
  69. Xextern void ReceiveQuit();
  70. Xextern void ReceiveNew(/* chanid, shape */);
  71. Xextern void ReceiveDelete(/* chanid */);
  72. Xextern void ReceiveSignal(/* chanid, signal */);
  73. Xextern void    ReceiveData(/* chanid, buff, cnt */);
  74. Xextern void ReceiveReshape(/*chanid, shape */);
  75. Xextern void DEBUG(/* format, arg1, arg2, arg3, arg4 */);
  76. X
  77. X                /* protocol.c */
  78. X
  79. Xextern int    InitLink();
  80. Xextern int    TopChannel();
  81. Xextern int    SendNew(/* shape */);
  82. Xextern void    SendTitle(/* chan, buff, cnt */);
  83. Xextern void SendDelete(/* chan */);
  84. Xextern void SendQuit();
  85. Xextern void    SendReshape(/* chan, shape */);
  86. Xextern void    SendData(/* chan, buff, cnt */);
  87. Xextern void    ProcessStreamin();
  88. SHAR_EOF
  89. if test 2049 -ne "`wc -c < 'layers.h'`"
  90. then
  91.     echo shar: error transmitting "'layers.h'" '(should have been 2049 characters)'
  92. fi
  93. fi # end of overwriting check
  94. echo shar: extracting "'layersize.c'" '(3586 characters)'
  95. if test -f 'layersize.c'
  96. then
  97.     echo shar: will not over-write existing file "'layersize.c'"
  98. else
  99. sed 's/^X//' << \SHAR_EOF > 'layersize.c'
  100. X/*             Copyright (C) 1989 by David W. Trissel 
  101. X *
  102. X *  Not derived from licensed software.
  103. X *
  104. X * Permission is granted to freely use, copy, modify, and redistribute
  105. X * this software, provided that no attempt is made to gain profit from it,
  106. X * the author is not construed to be liable for any results of using the
  107. X * software, alterations are clearly marked as such, and this notice is
  108. X * not modified.
  109. X *
  110. X */
  111. X                /*         All rights reserved.        */
  112. X
  113. X        /* layersize - update BSD Sun Unix with window size information */
  114. X
  115. X#include <stdio.h>
  116. X#include <errno.h>
  117. X#include <sys/ioctl.h>
  118. X
  119. Xextern int sys_nerr;
  120. Xextern char    *sys_errlist[];
  121. X
  122. Xstatic void gotsyserr(/* char * */);
  123. Xstatic void goterr(/* char * */);
  124. Xstatic int    getnumber(/* char * */);
  125. X
  126. X
  127. X                        /* main() - update BSD window size */
  128. X
  129. Xmain(ac, av)
  130. Xint            ac;                            /* argument count */
  131. Xchar        **av;                        /* argument vector */
  132. X{
  133. X    struct winsize wsize;                /* window size structure for ioctl() */
  134. X    char        *ap;                    /* argument scan pointer */
  135. X    int            lines;                    /* new lines value */
  136. X    int            cols;                    /* new columns value */
  137. X
  138. X    if (--ac != 2)
  139. X        goterr("Missing lines and column options");
  140. X
  141. X    /* get window size (actually do this to set xpixel and ypixel values) */
  142. X    if (ioctl(0, TIOCGWINSZ, &wsize) == -1)
  143. X        gotsyserr("No window support in host"); /* terminate with message */
  144. X
  145. X    /* scan looking for -l and -c line and column numeric sizes */
  146. X    lines = cols = 0;                    /* reset values */
  147. X    while (ac > 0)
  148. X      {    ap = *++av;                        /* point to next argument string */
  149. X        if (ac-- > 0 && *ap == '-')        /* if option ... */
  150. X        switch (ap[1])
  151. X        { case 'l':        /* lines */
  152. X            lines = getnumber(&ap[2]);
  153. X            break;
  154. X
  155. X          case 'c':        /* columns */
  156. X            cols = getnumber(&ap[2]);
  157. X            break;
  158. X
  159. X          default:
  160. X            goterr("Usupported option"); /* unsupported option */
  161. X            break;
  162. X
  163. X        } /* end '-' argument */
  164. X        else
  165. X            goterr("Unsupported parameter"); /* unsupported parameter */
  166. X
  167. X      } /* end while argument vector scan */
  168. X            
  169. X    /* must have both lines and columns */
  170. X    if (lines == 0 || cols == 0)
  171. X        goterr("Must specify both lines and columns");
  172. X
  173. X    wsize.ws_col = cols;                /* set columns */
  174. X    wsize.ws_row = lines;                /* set lines */
  175. X    /* update the kernel */
  176. X    if (ioctl(0, TIOCSWINSZ, &wsize) == -1)
  177. X        gotsyserr("Failed to update window size"); /* didn't go */
  178. X
  179. X} 
  180. X
  181. X
  182. X                /* goterr() - issue error and terminate */
  183. X
  184. Xstatic void
  185. Xgoterr(msg)
  186. Xchar        *msg;                        /* error message string */
  187. X{
  188. X    printf("%s\n", msg);                /* send error message to user */
  189. X    exit(1);                            /* terminate with error */
  190. X
  191. X} /* goterr() */
  192. X
  193. X
  194. X                /* gotsyserror() - system error return */
  195. X
  196. Xstatic void
  197. Xgotsyserr(msg)
  198. Xchar        *msg;                        /* error string */
  199. X{
  200. X    if (errno > 0 && errno < sys_nerr)
  201. X        printf("%s: %s\n", msg, sys_errlist[errno]);
  202. X    else
  203. X        printf("%s: Error %d\n", msg, errno);
  204. X
  205. X    exit(1);                            /* exit with failure */
  206. X
  207. X} /* gotsyserr() */
  208. X
  209. X
  210. X                    /* getnumber() - parse option number */
  211. X
  212. Xstatic int
  213. Xgetnumber(str)
  214. Xchar        *str;                        /* start of option string */
  215. X{
  216. X    int            n;                        /* number being built */
  217. X
  218. X    if (str == NULL)
  219. X        goterr("Invalid numeric in option");
  220. X
  221. X    /* skip any leading delimiters */
  222. X    while (*str && (*str == ' ' || *str == '\t'))
  223. X        str++;
  224. X
  225. X    for(n=0; *str && *str >= '0' && *str <= '9'; str++)
  226. X        n = n*10 + *str - '0';            /* add next digit in */
  227. X
  228. X    /* make sure number terminates legally */
  229. X    switch (*str)
  230. X    { case '\0':
  231. X      case ' ':
  232. X      case '\t':
  233. X      case '\n':
  234. X        if (n <= 0 || n > 200)
  235. X            goterr("Number out of range");
  236. X        break;                            /* these are OK */
  237. X
  238. X      default:
  239. X        goterr("Invalid numeric in option");
  240. X
  241. X    } /* end switch */
  242. X
  243. X    return ( n );                        /* return the number */
  244. X
  245. X} /* getnumber() */
  246. SHAR_EOF
  247. if test 3586 -ne "`wc -c < 'layersize.c'`"
  248. then
  249.     echo shar: error transmitting "'layersize.c'" '(should have been 3586 characters)'
  250. fi
  251. fi # end of overwriting check
  252. echo shar: extracting "'layertitle.c'" '(1242 characters)'
  253. if test -f 'layertitle.c'
  254. then
  255.     echo shar: will not over-write existing file "'layertitle.c'"
  256. else
  257. sed 's/^X//' << \SHAR_EOF > 'layertitle.c'
  258. X/*             Copyright (C) 1989 by David W. Trissel
  259. X *
  260. X *  Not derived from licensed software.
  261. X *
  262. X * Permission is granted to freely use, copy, modify, and redistribute
  263. X * this software, provided that no attempt is made to gain profit from it,
  264. X * the author is not construed to be liable for any results of using the
  265. X * software, alterations are clearly marked as such, and this notice is
  266. X * not modified.
  267. X *
  268. X */
  269. X                /*         All rights reserved.        */
  270. X
  271. X            /* layertitle - utility to specify window title */
  272. X
  273. X#include <stdio.h>
  274. X
  275. X#define ESC 0x1b
  276. X
  277. X            /* main() - send string designating layers window title */
  278. X
  279. Xmain(ac, av)
  280. Xint         ac;                         /* argument count */
  281. Xchar        **av;                       /* argument vector */
  282. X{
  283. X    char        *ap;                    /* argument scan pointer */
  284. X
  285. X    if (--ac != 1)
  286. X      { printf("usage: layertitle \"new window title\"\n");
  287. X        exit(1);
  288. X      }
  289. X       
  290. X    ap = *++av;                         /* point to argument string */
  291. X
  292. X    /* Transmit the title string in the ANSI Private Message format
  293. X    ** which is
  294. X    **              ESC '^' message ESC '\'
  295. X    */
  296. X    printf("%c%c%s%c%c", ESC, '^', ap, ESC, '\\');
  297. X
  298. X}  /* main() */
  299. SHAR_EOF
  300. if test 1242 -ne "`wc -c < 'layertitle.c'`"
  301. then
  302.     echo shar: error transmitting "'layertitle.c'" '(should have been 1242 characters)'
  303. fi
  304. fi # end of overwriting check
  305. echo shar: extracting "'macbput.c'" '(9383 characters)'
  306. if test -f 'macbput.c'
  307. then
  308.     echo shar: will not over-write existing file "'macbput.c'"
  309. else
  310. sed 's/^X//' << \SHAR_EOF > 'macbput.c'
  311. X/*
  312. X * (originally macput) -- send file to Macintosh using MacBinary XMODEM protocol
  313. X * Dave Johnson, Brown University Computer Science
  314. X *
  315. X * (c) 1984 Brown University 
  316. X * may be used but not sold without permission
  317. X *
  318. X */
  319. X
  320. X/* To compile:    
  321. X                  cc -O -o macbput macbput.c
  322. X    (Sun 4.2 BSD) cc -O -DSUNBSD42 -o macbput macbput.c
  323. X    (System V)    cc -O -DSYSV -o macbput macbput.c
  324. X
  325. X   Latest modifications 10/20/88 by Trissel -
  326. X
  327. X 1. General cleanup by removal of unused definitions and headers.
  328. X 2. Added #ifdefs to support System V and BSD 4.2 Sun compilation.
  329. X 3. Removed ancient Macterminal Beta 0.5X code.
  330. X 4. Fixed bad bug where XMODEM block count was not bumped up
  331. X    after the first fork transfer.
  332. X
  333. X    Dave Trissel
  334. X    Motorola Inc.
  335. X    ut-sally!oakhill!davet
  336. X
  337. X   This code is fundamentally from two earlier programmers:
  338. X
  339. X    Jon Hueras
  340. X    Symantec/THINK Technologies
  341. X    singer@endor.harvard.edu
  342. X
  343. X    who added 2-Byte CRC capability to code from:
  344. X
  345. X    Dave Johnson
  346. X    ddj%brown@csnet-relay.arpa
  347. X    Brown University Computer Science
  348. X
  349. X   who did the initial MacTerminal 1.1 transfer protocol.
  350. X*/
  351. X
  352. X/* If you have System V define the following: */
  353. X    /* #define SYSV */
  354. X
  355. X/* Sun BSD 4.2 systems should define the following: */
  356. X    /* #define SUNBSD42 */
  357. X
  358. X#include <stdio.h>
  359. X#include <signal.h>
  360. X#include <setjmp.h>
  361. X#ifdef SYSV
  362. X#include <termio.h>
  363. X#else
  364. X#include <sgtty.h>
  365. X#endif
  366. X#include <sys/types.h>
  367. X#include <sys/stat.h>
  368. X
  369. X#ifdef SUNBSD42
  370. X/* RAW is no longer being found on latest Sun system (??) (Trissel) */
  371. X#define RAW 0x20
  372. X#endif
  373. X
  374. X#define RECORDBYTES 132
  375. X#define DATABYTES 128
  376. X#define NAMEBYTES 63
  377. X
  378. X#define RETRIES 10
  379. X#define ACKTIMO 10
  380. X
  381. X#define MAXRECNO 0xff
  382. X#define BYTEMASK 0xff
  383. X
  384. X#define TMO -1
  385. X#define DUP '\000'
  386. X#define SOH '\001'
  387. X#define EOT '\004'
  388. X#define ACK '\006'
  389. X#define NAK '\025'
  390. X#define CAN '\030'
  391. X#define EEF '\032'
  392. X#define ESC '\033'
  393. X
  394. X#define H_NLENOFF 1
  395. X#define H_NAMEOFF 2
  396. X/* 65 <-> 80 is the FInfo structure */
  397. X#define H_TYPEOFF 65
  398. X#define H_AUTHOFF 69
  399. X
  400. X#define H_LOCKOFF 81
  401. X#define H_DLENOFF 83
  402. X#define H_RLENOFF 87
  403. X#define H_CTIMOFF 91
  404. X#define H_MTIMOFF 95
  405. X
  406. X#define H_OLD_DLENOFF 81
  407. X#define H_OLD_RLENOFF 85
  408. X
  409. X#define TEXT 0
  410. X#define DATA 1
  411. X#define RSRC 2
  412. X#define FULL 3
  413. X
  414. Xint mode, txtmode;
  415. X
  416. Xstruct macheader {
  417. X    char m_name[NAMEBYTES+1];
  418. X    char m_type[4];
  419. X    char m_author[4];
  420. X    long m_datalen;
  421. X    long m_rsrclen;
  422. X    long m_createtime;
  423. X    long m_modifytime;
  424. X} mh;
  425. X
  426. Xstruct filenames {
  427. X    char f_info[256];
  428. X    char f_data[256];
  429. X    char f_rsrc[256];
  430. X} files;
  431. X
  432. Xint recno, crc;
  433. Xchar buf[DATABYTES];
  434. X
  435. Xchar usage[] =
  436. X    "usage: \"macbput [-rdu] [-t type] [-c creator] [-n name] filename\"\n";
  437. X
  438. Xmain(ac, av)
  439. Xchar **av;
  440. X{
  441. X    int n;
  442. X    char *filename;
  443. X
  444. X    if (ac == 1) {
  445. X        fprintf(stderr, usage);
  446. X        exit(1);
  447. X    }
  448. X
  449. X    mode = FULL;
  450. X    ac--; av++;
  451. X    while (ac) {
  452. X        if (av[0][0] == '-') {
  453. X            switch (av[0][1]) {
  454. X            case 'r':
  455. X                mode = RSRC;
  456. X                strncpy(mh.m_type, "????", 4);
  457. X                strncpy(mh.m_author, "????", 4);
  458. X                break;
  459. X            case 'u':
  460. X                mode = TEXT;
  461. X                strncpy(mh.m_type, "TEXT", 4);
  462. X                strncpy(mh.m_author, "MACA", 4);
  463. X                break;
  464. X            case 'd':
  465. X                mode = DATA;
  466. X                strncpy(mh.m_type, "????", 4);
  467. X                strncpy(mh.m_author, "????", 4);
  468. X                break;
  469. X            case 'n':
  470. X                if (ac > 1) {
  471. X                    ac--; av++;
  472. X                    n = strlen(av[0]);
  473. X                    if (n > NAMEBYTES) n = NAMEBYTES;
  474. X                    strncpy(mh.m_name, av[0], n);
  475. X                    mh.m_name[n] = '\0';
  476. X                    break;
  477. X                }
  478. X                else goto bad_usage;
  479. X            case 't':
  480. X                if (ac > 1) {
  481. X                    ac--; av++;
  482. X                    strncpy(mh.m_type, av[0], 4);
  483. X                    break;
  484. X                }
  485. X                else goto bad_usage;
  486. X            case 'c':
  487. X                if (ac > 1) {
  488. X                    ac--; av++;
  489. X                    strncpy(mh.m_author, av[0], 4);
  490. X                    break;
  491. X                }
  492. X                else goto bad_usage;
  493. X            default:
  494. Xbad_usage:
  495. X                fprintf(stderr, usage);
  496. X                exit(1);
  497. X            }
  498. X        }
  499. X        else {
  500. X            filename = av[0];
  501. X        }
  502. X        ac--; av++;
  503. X    }
  504. X
  505. X    setup_tty();
  506. X    find_files(filename, mode);
  507. X    if (mode != FULL)
  508. X        forge_info();
  509. X
  510. X    if (send_sync()) {
  511. X        recno = 1;
  512. X        txtmode = 0;
  513. X        send_file(files.f_info, 1);
  514. X
  515. X        if (mode != FULL)
  516. X            unlink(files.f_info);
  517. X
  518. X        if (mode == TEXT) txtmode++;
  519. X        send_file(files.f_data, 1);
  520. X
  521. X        txtmode = 0;
  522. X        send_file(files.f_rsrc, 0);
  523. X    }
  524. X    reset_tty();
  525. X}
  526. X
  527. Xfind_files(filename, mode)
  528. Xchar *filename;
  529. X{
  530. X    int n, tdiff;
  531. X    struct stat stbuf;
  532. X
  533. X    sprintf(files.f_data, "%s.data", filename);
  534. X    sprintf(files.f_rsrc, "%s.rsrc", filename);
  535. X
  536. X    if (mode == FULL) {
  537. X        sprintf(files.f_info, "%s.info", filename);
  538. X        if (stat(files.f_info, &stbuf) != 0) {
  539. X            perror(files.f_info);
  540. X            cleanup(-1);
  541. X        }
  542. X        return;
  543. X    }
  544. X    else {
  545. X        strcpy(files.f_info, "#machdrXXXXXX");
  546. X        mktemp(files.f_info);
  547. X    }
  548. X
  549. X    if (mode == RSRC) {
  550. X        strcpy(files.f_data, "/dev/null");
  551. X        if (stat(files.f_rsrc, &stbuf) != 0) {
  552. X            strcpy(files.f_rsrc, filename);
  553. X            if (stat(files.f_rsrc, &stbuf) != 0) {
  554. X                perror(files.f_rsrc);
  555. X                cleanup(-1);
  556. X            }
  557. X        }
  558. X        mh.m_datalen = 0;
  559. X        mh.m_rsrclen = stbuf.st_size;
  560. X    }
  561. X    else {
  562. X        strcpy(files.f_rsrc, "/dev/null");
  563. X        if (stat(files.f_data, &stbuf) != 0) {
  564. X            sprintf(files.f_data, "%s.text", filename);
  565. X            if (stat(files.f_data, &stbuf) != 0) {
  566. X                strcpy(files.f_data, filename);
  567. X                if (stat(files.f_data, &stbuf) != 0) {
  568. X                    perror(files.f_data);
  569. X                    cleanup(-1);
  570. X                }
  571. X            }
  572. X        }
  573. X        mh.m_datalen = stbuf.st_size;
  574. X        mh.m_rsrclen = 0;
  575. X    }
  576. X
  577. X    if (mh.m_name[0] == '\0') {
  578. X        n = strlen(filename);
  579. X        if (n > NAMEBYTES) n = NAMEBYTES;
  580. X        strncpy(mh.m_name, filename, n);
  581. X        mh.m_name[n] = '\0';
  582. X    }
  583. X}
  584. X
  585. Xforge_info()
  586. X{
  587. X    int n;
  588. X    char *np;
  589. X    FILE *fp;
  590. X
  591. X    for (np = mh.m_name; *np; np++)
  592. X        if (*np == '_') *np = ' ';
  593. X
  594. X    buf[H_NLENOFF] = n = np - mh.m_name;
  595. X    strncpy(buf + H_NAMEOFF, mh.m_name, n);
  596. X    strncpy(buf + H_TYPEOFF, mh.m_type, 4);
  597. X    strncpy(buf + H_AUTHOFF, mh.m_author, 4);
  598. X    put4(buf + H_DLENOFF, mh.m_datalen);
  599. X    put4(buf + H_RLENOFF, mh.m_rsrclen);
  600. X    put4(buf + H_CTIMOFF, mh.m_createtime);
  601. X    put4(buf + H_MTIMOFF, mh.m_modifytime);
  602. X    fp = fopen(files.f_info, "w");
  603. X    if (fp == NULL) {
  604. X        perror("temp file");
  605. X        cleanup(-1);
  606. X    }
  607. X    fwrite(buf, 1, DATABYTES, fp);
  608. X    fclose(fp);
  609. X}
  610. X
  611. Xsend_sync()
  612. X    {
  613. X        int c;
  614. X        
  615. X        tputc(ESC);
  616. X        tputc('b');
  617. X
  618. X        for (;;) {
  619. X
  620. X            if ((c = tgetc(ACKTIMO)) == TMO)
  621. X              {
  622. X                return(0);
  623. X                }
  624. X
  625. X            if (c == NAK)
  626. X              {
  627. X                return(1);
  628. X                }
  629. X
  630. X            if (c == 'C') {
  631. X                crc++;
  632. X                return(1);
  633. X            }
  634. X        }
  635. X    }
  636. X
  637. Xsend_file(fname, more)
  638. Xchar *fname;
  639. Xint more;
  640. X{
  641. X    register int status, i, n;
  642. X    FILE *inf;
  643. X
  644. X    inf = fopen(fname, "r");
  645. X    if (inf == NULL) {
  646. X        perror(fname);
  647. X        cleanup(-1);
  648. X    }
  649. X    for (;;) {
  650. X        n = fread(buf, 1, DATABYTES, inf);
  651. X        if (n > 0) {
  652. X            for (i = 0; i < RETRIES; i++) {
  653. X                send_rec(buf, DATABYTES);
  654. X                while ((status = tgetc(ACKTIMO)) != ACK && status != NAK && status != CAN);
  655. X                if (status != NAK)
  656. X                    break;
  657. X            } 
  658. X            if (status != ACK) {
  659. X                if (status != CAN)
  660. X                    while ((status = tgetc(ACKTIMO)) != CAN);
  661. X                fclose(inf);
  662. X                cleanup(-1);
  663. X                /* NOTREACHED */
  664. X            }
  665. X        }
  666. X        if (n < DATABYTES) {
  667. X            if (!more) {
  668. X                tputc(EOT);
  669. X                tgetc(ACKTIMO);
  670. X            }
  671. X            return;
  672. X        }
  673. X        recno++;
  674. X        recno &= MAXRECNO;
  675. X    }
  676. X}
  677. X
  678. Xsend_rec(buf, recsize)
  679. Xchar buf[];
  680. Xint recsize;
  681. X{
  682. X    int i, cksum;
  683. X    char *bp;
  684. X    if (txtmode || !crc) {
  685. X        cksum = 0;
  686. X        bp = buf;
  687. X        for (i = 0; i < recsize; i++, bp++) {
  688. X            if (txtmode && *bp == '\n')
  689. X                *bp = '\r';
  690. X            cksum += *bp;
  691. X        }
  692. X    }
  693. X
  694. X    if (crc)
  695. X        cksum = calcrc(buf, recsize);
  696. X
  697. X    tputc(SOH);
  698. X    tputc((char) recno);
  699. X    tputc((char) (MAXRECNO - recno));
  700. X    tputrec(buf, recsize);
  701. X    
  702. X    if (crc) {
  703. X        tputc((char) (cksum >> 8));
  704. X        tputc((char) cksum);
  705. X    } else
  706. X        tputc((char) cksum);
  707. X}
  708. X
  709. Xstatic int ttyfd;
  710. Xstatic FILE *ttyf;
  711. Xstatic jmp_buf timobuf;
  712. X
  713. Xtgetc(timeout)
  714. Xint timeout;
  715. X{
  716. X    int c;
  717. X
  718. X    if (setjmp(timobuf))
  719. X        return TMO;
  720. X
  721. X    alarm(timeout);
  722. X    c = getc(ttyf);
  723. X    alarm(0);
  724. X
  725. X    if (c == -1)    /* probably hung up or logged off */
  726. X        return EOT;
  727. X    else
  728. X        return c & BYTEMASK;
  729. X}
  730. X
  731. Xtputrec(buf, count)
  732. Xchar *buf;
  733. Xint count;
  734. X{
  735. X    write(ttyfd, buf, count);
  736. X}
  737. X
  738. Xtputc(c)
  739. Xchar c;
  740. X{
  741. X    write(ttyfd, &c, 1);
  742. X}
  743. X
  744. Xtimedout()
  745. X{
  746. X    signal(SIGALRM, timedout);    /* for pre-4.2 systems */
  747. X    longjmp(timobuf, 1);
  748. X}
  749. X
  750. X#ifdef SYSV
  751. Xstatic struct termio otty, ntty;
  752. X#else
  753. Xstatic struct sgttyb otty, ntty;
  754. X#endif
  755. X
  756. X/* should turn messages off */
  757. X
  758. Xsetup_tty()
  759. X{
  760. X    int cleanup();
  761. X    int timedout();
  762. X
  763. X    ttyf = stdin;
  764. X    ttyfd = fileno(stdout);
  765. X#ifdef SYSV
  766. X    ioctl(ttyfd, TCGETA, &otty);        /* get termio info */
  767. X#else
  768. X    ioctl(ttyfd, TIOCGETP, &otty);
  769. X#endif
  770. X    signal(SIGHUP, cleanup);
  771. X    signal(SIGINT, cleanup);
  772. X    signal(SIGQUIT, cleanup);
  773. X    signal(SIGTERM, cleanup);
  774. X    signal(SIGALRM, timedout);
  775. X    ntty = otty;
  776. X#ifdef SYSV
  777. X    ntty.c_iflag = BRKINT;                /* only interrupt on break */
  778. X    ntty.c_oflag = 0;                    /* no output processing */
  779. X    ntty.c_cflag |= CS8;                /* 8 bit characters */
  780. X    ntty.c_lflag = 0;                    /* no echoing */
  781. X    ntty.c_cc[VEOF] = 1;                /* "MIN" minimum chars before input */
  782. X    ntty.c_cc[VEOL] = 1;                /* "TIME" maximum .1 secs before feed */
  783. X    ioctl(ttyfd, TCSETAF, &ntty);        /* set mode and flush input */
  784. X#else
  785. X    ntty.sg_flags = RAW;
  786. X    ioctl(ttyfd, TIOCSETP, &ntty);
  787. X#endif
  788. X}
  789. X
  790. Xreset_tty()
  791. X{
  792. X    if (ttyf != NULL) {
  793. X#ifdef SYSV
  794. X        ioctl(ttyfd, TCSETAF, &otty);    /* reset after output drains */
  795. X#else
  796. X        sleep (5);                        /* wait for output to drain */
  797. X        ioctl(ttyfd, TIOCSETP, &otty);
  798. X#endif
  799. X    }
  800. X}
  801. X
  802. Xcleanup(sig)
  803. Xint sig;
  804. X{
  805. X    reset_tty();
  806. X    exit(sig);
  807. X}
  808. X
  809. Xput4(bp, value)
  810. Xchar *bp;
  811. Xlong value;
  812. X{
  813. X    register int i, c;
  814. X
  815. X    for (i = 0; i < 4; i++) {
  816. X        c = (value >> 24) & BYTEMASK;
  817. X        value <<= 8;
  818. X        *bp++ = c;
  819. X    }
  820. X}
  821. X
  822. Xint calcrc(ptr,    count)
  823. Xchar *ptr;
  824. Xint count;
  825. X    {
  826. X        int    crc, i;
  827. X
  828. X        crc    = 0;
  829. X        while (--count >= 0) {
  830. X         crc ^= ((int) *ptr++) << 8;
  831. X         for (i = 0; i < 8; ++i)
  832. X                 if (crc & 0x8000)
  833. X             crc = crc <<    1 ^ 0x1021;
  834. X                 else
  835. X             crc <<= 1;
  836. X         }
  837. X        return (crc    & 0xFFFF);
  838. X    }
  839. SHAR_EOF
  840. if test 9383 -ne "`wc -c < 'macbput.c'`"
  841. then
  842.     echo shar: error transmitting "'macbput.c'" '(should have been 9383 characters)'
  843. fi
  844. fi # end of overwriting check
  845. echo shar: extracting "'makefile'" '(1674 characters)'
  846. if test -f 'makefile'
  847. then
  848.     echo shar: will not over-write existing file "'makefile'"
  849. else
  850. sed 's/^X//' << \SHAR_EOF > 'makefile'
  851. X#                   Makefile for Layers 1.0
  852. X
  853. XBIN    = /usr/local
  854. XMANDIR = /usr/local/manl
  855. X
  856. XPGM    = layers
  857. XPGM2   = layersize
  858. XPGM3   = layertitle
  859. XPGM4   = macbput
  860. XMS     = l
  861. XCFLAGS = -O
  862. XCFILES = layers.c protocol.c
  863. XOFILES = layers.o protocol.o
  864. X
  865. Xall: $(PGM) $(PGM2) $(PGM3) $(PGM4)
  866. X
  867. X$(PGM): $(OFILES)
  868. X    $(CC) $(CFLAGS) -o $(PGM) $(OFILES)
  869. X
  870. X#    $(CC) $(CFLAGS) -o $(PGM) $(OFILES) -ltermcap
  871. X
  872. Xlayers.o: layers.c layers.h
  873. X    $(CC) $(CFLAGS) -c layers.c
  874. X
  875. Xprotocol.o: protocol.c layers.h
  876. X    $(CC) $(CFLAGS) -c protocol.c
  877. X
  878. X$(PGM2): layersize.o
  879. X    $(CC) $(CFLAGS) -o $(PGM2) layersize.o
  880. X
  881. X$(PGM3): layertitle.o
  882. X    $(CC) $(CFLAGS) -o $(PGM3) layertitle.o
  883. X
  884. X$(PGM4): macbput.o
  885. X    $(CC) $(CFLAGS) -o $(PGM4) macbput.o
  886. X
  887. Xlayersize.o: layersize.c
  888. X    $(CC) $(CFLAGS) -c layersize.c
  889. X
  890. Xlayertitle.o: layertitle.c
  891. X    $(CC) $(CFLAGS) -c layertitle.c
  892. X
  893. Xmacbput.o: macbput.c
  894. X    $(CC) $(CFLAGS) -c macbput.c
  895. X
  896. Xinstall: $(PGM) $(PGM2) $(PGM3) $(PGM4)
  897. X    rm -f $(BIN)/$(PGM)
  898. X    install -c -s -o root -g daemon -m 4711 $(PGM) $(BIN)/$(PGM)
  899. X    install -c -s $(PGM2) $(BIN)/$(PGM2)
  900. X    install -c -s $(PGM3) $(BIN)/$(PGM3)
  901. X#    install -c -s $(PGM4) $(BIN)/$(PGM4)
  902. X
  903. Xinstallnopriv: $(PGM) $(PGM2) $(PGM3) $(PGM4)
  904. X    rm -f $(BIN)/$(PGM)
  905. X    install -c -s $(PGM) $(BIN)/$(PGM)
  906. X    install -c -s $(PGM2) $(BIN)/$(PGM2)
  907. X    install -c -s $(PGM3) $(BIN)/$(PGM3)
  908. X#    install -c -s $(PGM4) $(BIN)/$(PGM4)
  909. X
  910. Xmanpage: layers.1
  911. X    rm -f $(MANDIR)/$(PGM).$(MS)
  912. X    cp layers.1 $(MANDIR)/$(PGM).$(MS)
  913. X    chmod 664 $(MANDIR)/$(PGM).$(MS)
  914. X
  915. Xclean:
  916. X    rm -f a.out core $(PGM) $(PGM2) $(PGM3) $(PGM4) *.o
  917. X
  918. Xshar: makefile 
  919. X    shar README layers.1 makefile layers.h layers.c \
  920. X    protocol.c layersize.c layertitle.c MacLayers.sit.Hqx MacLayers.doc \
  921. X    macbput.c macbput.1 >layers.shar
  922. SHAR_EOF
  923. if test 1674 -ne "`wc -c < 'makefile'`"
  924. then
  925.     echo shar: error transmitting "'makefile'" '(should have been 1674 characters)'
  926. fi
  927. fi # end of overwriting check
  928. echo shar: extracting "'protocol.c'" '(25546 characters)'
  929. if test -f 'protocol.c'
  930. then
  931.     echo shar: will not over-write existing file "'protocol.c'"
  932. else
  933. sed 's/^X//' << \SHAR_EOF > 'protocol.c'
  934. X/*             Copyright (C) 1989 by David W. Trissel 
  935. X *
  936. X *              Not derived from licensed software.
  937. X *
  938. X * Permission is granted to freely use, copy, modify, and redistribute
  939. X * this software, provided that no attempt is made to gain profit from it,
  940. X * the author is not construed to be liable for any results of using the
  941. X * software, alterations are clearly marked as such, and this notice is
  942. X * not modified.
  943. X *
  944. X */
  945. X
  946. X#include    <stdio.h>
  947. X#include    <signal.h>
  948. X#include    <errno.h>
  949. X#include    "layers.h"
  950. X
  951. X                /* protocol.c - BSD MacLayers protocol driver */
  952. X
  953. X/*    This module handles all interaction with the Macintosh MacLayers
  954. X**    program. Services provided are:
  955. X**
  956. X**        InitLink()    - initialize link to MacLayers
  957. X**
  958. X**        TopChannel() - return highest prority channel
  959. X**
  960. X**        SendNew()    - request new layer channel of MacLayers
  961. X**
  962. X**        SendTitle() - change window title to given string (NOT IMPLENTED YET)
  963. X**
  964. X**        SendDelete()- tell MacLayers indicated layer has died
  965. X**
  966. X**        SendQuit()    - order MacLayers to terminate layers mode
  967. X**
  968. X**        SendData()    - send output to indicated channel's window
  969. X**
  970. X**        SendReshape() - send Shape structure to MacLayers
  971. X**
  972. X**        ProcessStreamin() - data is ready to be processed from MacLayers
  973. X**
  974. X*/
  975. X
  976. X#define DUMPALL
  977. X#undef    DUMPALL
  978. X
  979. X/* C library calls */
  980. Xunsigned alarm();                /* alarm system call */
  981. X
  982. Xstatic int        GetData();
  983. Xstatic void        Packet();
  984. Xstatic void        Parse();
  985. Xstatic void        AwaitInput();
  986. Xstatic void        asciishape();
  987. Xstatic void        fill4();
  988. Xstatic void        fill2();
  989. Xstatic void        fill1();
  990. Xstatic int        parseshape();
  991. Xstatic unsigned    get4();
  992. Xstatic unsigned    get2();
  993. Xstatic unsigned    get1();
  994. X
  995. Xstatic char        inbuff[IOSIZE];        /* input buffer from MacLayers */
  996. Xstatic char     *inpos;                /* current input position in buffer */
  997. Xstatic int        insize = 0;            /* characters left to process */
  998. Xstatic int        Outstream = -1;        /* current output stream channel */
  999. Xstatic int        Instream = -1;        /* current input stream channel */
  1000. X
  1001. Xstatic struct Shape    SNshape;        /* SendNew() shape response */
  1002. Xstatic int        SNresp = 0;            /* SendNew() reponse poll flag */
  1003. Xstatic int        SNchan = 0;            /* SendNew() channel return */
  1004. X#define SN_WAITING    -1000            /* SendNew() waiting response value */
  1005. X
  1006. X#define ATTRSIZE    15                /* size of window attribute string */
  1007. X
  1008. X#define FLUSH    fflush(stdout)
  1009. X
  1010. X
  1011. X                /* Initlink() - initialize link with MacLayers */
  1012. X
  1013. X/* Returns:
  1014. X**                0 - linkup failed
  1015. X**                1 - linkup successful, Maclayers now in protocol mode
  1016. X*/
  1017. X
  1018. Xint
  1019. XInitlink()
  1020. X{
  1021. X    int Outstream = -1;                /* no default stream yet */
  1022. X    int    Instream = -1;                /* no default stream yet */
  1023. X    int        num1, num2, num3;        /* scanf item result */
  1024. X    int        err;                    /* error code */
  1025. X
  1026. X#define WAITTIME    10                /* second wait response time */
  1027. X#define INITTIME    2                /* wait time after succesful startup */
  1028. X
  1029. X    /* we must non-buffer input since all input must be immediate */
  1030. X    setbuf(stdin, NULL);            /* non-buffer all input */
  1031. X
  1032. X    /* send intitial request for terminal type and version number */
  1033. X    DO DEBUG("write: ESC [ c\n");
  1034. X    if ((err=printf("\033[c")) < 0)
  1035. X      {
  1036. X        DO DEBUG(" printf() error code %d\n", err);
  1037. X        return ( 0 );                /* problem with stdout */
  1038. X      }
  1039. X    FLUSH;                            /* force output buffer */
  1040. X
  1041. X    /* attempt to read "ESC [ ? 8 ; typedigits ; versiondigits c" */
  1042. X    num1 = num2 = num3 = -1;        /* default to unsupplied values */
  1043. X    (void) alarm(WAITTIME);            /* set timeout */
  1044. X    DO DEBUG(" doing first scanf\n");
  1045. X    (void) scanf("\033[?%d;%d;%dc", &num1, &num2, &num3);
  1046. X    (void) alarm(0);                /* cancel alarm */
  1047. X    DO DEBUG("read ESC [ ? %d ; %d; %d c\n", num1, num2, num3);
  1048. X    if (num1 != 8 || num2 != 10)
  1049. X        return ( 0 );                /* not correct response or layers term ID */
  1050. X
  1051. X    /* ask terminal if ENC_ENABLE is to be forced */
  1052. X    DO DEBUG("write: ESC [ F\n");
  1053. X    (void) printf("\033[F");
  1054. X    FLUSH;                            /* force output buffer */
  1055. X    (void) alarm(WAITTIME);            /* set timeout */
  1056. X
  1057. X    /* attempt to read "ESC [ flag F" (flag indicates ENC_ENABLE status) */
  1058. X    num1 = -1;                        /* default to invalid response */
  1059. X    (void) scanf("\033[%dF", &num1);
  1060. X    (void) alarm(0);                /* cancel alarm */
  1061. X    DO DEBUG("read ESC [ %d F\n", num1);
  1062. X    if (num1 != 2 && num1 != 0)
  1063. X        return ( 0 );                /* something's wrong */
  1064. X
  1065. X    /* now startup packet mode in non ENC_ENABLE processing */
  1066. X    DO DEBUG("write: ESC [ 2 ; 0 v\n");
  1067. X    (void) printf("\033[2;0v");        /* "ESC [ 2 ; 0 v" */
  1068. X    FLUSH;                            /* force output buffer */
  1069. X
  1070. X    /* we are now in packet mode */
  1071. X    sleep( INITTIME );                /* let Macintosh keep up with us */
  1072. X    return ( 1 );                    /* return successful startup */
  1073. X
  1074. X} /* Initlink() */
  1075. X
  1076. X
  1077. X            /* TopChannel() - return highest prority channel */
  1078. X
  1079. Xint
  1080. XTopChannel()
  1081. X{
  1082. X    return ( Instream );
  1083. X
  1084. X} /* TopChannel() */
  1085. X
  1086. X
  1087. X    /*
  1088. X    ** WARNING: Most of the following functions may be recursively called
  1089. X    **            as control commands are processed from the input stream
  1090. X    */
  1091. X
  1092. X
  1093. X            /* ProcessStreamin() - MacLayers has input to process */
  1094. X
  1095. Xvoid
  1096. XProcessStreamin()
  1097. X{
  1098. X    int        c;                        /* input character being processed */
  1099. X
  1100. X    DO DEBUG("ProcessStreamin()\n");
  1101. X
  1102. X    GetData(0);                        /* read some and don't timeout */
  1103. X
  1104. X    while (insize > 0)                /* while more data to process ... */
  1105. X        Parse();                    /* process next chuck of data */
  1106. X
  1107. X} /* ProcessStreamin() */
  1108. X
  1109. X
  1110. X        /* SendNew() - request new layer channel from MacLayers */
  1111. X
  1112. X/*    This command is unique in that it returns a response from MacLayers.
  1113. X**    To do this we continue processing the input stream until we get
  1114. X**    our return. (This leads to recursive conditions.) The variables
  1115. X**    'SNresp', 'SNshape' and 'SNchan' are set when our reply is received.
  1116. X*/
  1117. Xint
  1118. XSendNew(shape)
  1119. Xstruct Shape    *shape;                /* shape to use for new window */
  1120. X{
  1121. X    int            i;                    /* attribute count variable */
  1122. X    char        astring[ATTRSIZE];    /* copy of attribute string */
  1123. X
  1124. X    DO DEBUG("SendNew() new layer requested: '~%cA'\n", '1'+ATTRSIZE);
  1125. X
  1126. X    /* check for a recursive call */
  1127. X    if (SNresp == SN_WAITING)
  1128. X      {    DO DEBUG("return 0 - recursive call\n");
  1129. X        return ( 0 );                /* return failure */
  1130. X      }
  1131. X
  1132. X    putchar(ESCAPE);                /* send start of control packet char */
  1133. X    putchar('1' + ATTRSIZE);        /* send command size */
  1134. X    putchar('A');                    /* send command */
  1135. X    asciishape(shape, astring);        /* convert shape to string */
  1136. X    for (i=0; i < ATTRSIZE; i++)
  1137. X        putchar(astring[i]);        /* send next attribute digit */
  1138. X    FLUSH;
  1139. X
  1140. X    /* now stay here and process the input stream until we see our response */
  1141. X/**** THIS SHOULD BE ENHANCED TO TIMEOUT WITH GetData() AND REISSUE REQUEST */
  1142. X    SNresp = SN_WAITING;            /* indicate we are waiting a response */
  1143. X    while (SNresp == SN_WAITING)
  1144. X      { DO DEBUG(" while (SNresp %d == %d)\n", SNresp, SN_WAITING);
  1145. X        AwaitInput();                /* wait till input from MacLayers arrives */
  1146. X        ProcessStreamin();            /* process available input */
  1147. X      }
  1148. X
  1149. X    if (SNresp == -1)                /* if Maclayers rejected request */
  1150. X        SNchan = 0;                    /* return failure channel of zero */
  1151. X    else
  1152. X        *shape = SNshape;            /* else update shape structure */
  1153. X
  1154. X    DO DEBUG("SendNew() returning channel %d\n", SNchan);
  1155. X
  1156. X    return ( SNchan );                /* return the indicated channel */
  1157. X
  1158. X} /* SendNew() */
  1159. X
  1160. X
  1161. X            /* SendReshape() - send to shape to MacLayers */
  1162. X
  1163. Xvoid
  1164. XSendReshape(chan, shape)
  1165. Xint                chan;                /* channel shape belongs to */
  1166. Xstruct Shape    *shape;                /* shape to use for new window */
  1167. X{
  1168. X    int            i;                    /* attribute count variable */
  1169. X    char        astring[ATTRSIZE];    /* copy of attribute string */
  1170. X
  1171. X    DO DEBUG("SendReshape() reshape: '~%cA'\n", '2'+ATTRSIZE);
  1172. X
  1173. X    if (chan <= 0 || chan > MAXPCHAN)
  1174. X      {    DO DEBUG("BAD CHANNEL!!!\n");
  1175. X        return;                        /* ignore request */
  1176. X      }
  1177. X
  1178. X    putchar(ESCAPE);                /* send start of control packet char */
  1179. X    putchar('2' + ATTRSIZE);        /* send command size */
  1180. X    putchar('R');                    /* send command */
  1181. X    putchar(chan + '0');            /* send channel */
  1182. X    asciishape(shape, astring);        /* convert shape to string */
  1183. X    DO DEBUG("shape: %.*s\n", ATTRSIZE, astring);
  1184. X    for (i=0; i < ATTRSIZE; i++)
  1185. X        putchar(astring[i]);        /* send next attribute digit */
  1186. X    FLUSH;
  1187. X
  1188. X} /* SendReshape() */
  1189. X
  1190. X
  1191. X            /* SendTitle() - set layer's window title */
  1192. X
  1193. Xvoid
  1194. XSendTitle(chan, buff, cnt)
  1195. Xint            chan;                    /* layer window ID */
  1196. Xchar        *buff;                    /* new title string */
  1197. Xint            cnt;                    /* count of title length */
  1198. X{
  1199. X    int        i;                        /* work variable */
  1200. X
  1201. X    DO DEBUG("SendTitle(chan%d, len %d, '%.*s')\n", chan, cnt, cnt, buff);
  1202. X
  1203. X    if (chan <= 0 || chan > MAXPCHAN)
  1204. X      {    DO DEBUG("BAD CHANNEL!!!\n");
  1205. X        return;                        /* ignore request */
  1206. X      }
  1207. X
  1208. X    if (cnt < 0)
  1209. X      {    DO DEBUG("BAD COUNT!!!\n");
  1210. X        return;                        /* ignore request */
  1211. X      }
  1212. X
  1213. X    /* for now chop title size to 29 chars since that's MacLayer's limit */
  1214. X    if (cnt > 29)
  1215. X        cnt = 29;                    /* due to packet size limit */
  1216. X
  1217. X    /* we must guarantee that the size will not appear to be another ESCAPE */
  1218. X    if ('2' + cnt == ESCAPE)
  1219. X        cnt--;                        /* truncate to avoid ESCAPE ESCAPE */
  1220. X    
  1221. X    putchar(ESCAPE);                /* send start of control packet char */
  1222. X    putchar('2' + cnt);                /* send size of packet */
  1223. X    putchar('T');                    /* send command */
  1224. X    putchar(chan + '0');            /* send channel ID */
  1225. X    for (i=0; i<cnt; i++)
  1226. X        putchar(buff[i]);            /* send out title */
  1227. X    FLUSH;
  1228. X
  1229. X} /* SendTitle() */
  1230. X
  1231. X
  1232. X            /* SendDelete() - tell Maclayers layer died */
  1233. X
  1234. Xvoid
  1235. XSendDelete(chan)
  1236. Xint        chan;                        /* dead channel ID */
  1237. X{
  1238. X    DO DEBUG("SendDelete(%d) '~2D%d'\n", chan, chan);
  1239. X
  1240. X    if (chan <= 0 || chan > MAXPCHAN) /* check channel ID */
  1241. X      {    DO DEBUG("BAD CHANNEL!!!\n");
  1242. X        return;                        /* ignore request */
  1243. X      }
  1244. X
  1245. X    putchar(ESCAPE);                /* send control packet start char */
  1246. X    putchar('2');                    /* send command size */
  1247. X    putchar('D');                    /* send command character */
  1248. X    putchar(chan + '0');            /* channel ID in ascii */
  1249. X    FLUSH;
  1250. X
  1251. X} /* SendDelete() */
  1252. X
  1253. X
  1254. X            /* SendQuit() - order MacLayers to end layers mode */
  1255. X
  1256. Xvoid
  1257. XSendQuit(chan)
  1258. Xint        chan;                        /* dead channel ID */
  1259. X{
  1260. X    DO DEBUG("SendQuit() '~1E'\n");
  1261. X
  1262. X    putchar(ESCAPE);                /* send control packet start char */
  1263. X    putchar('1');                    /* send command size */
  1264. X    putchar('E');                    /* send command */
  1265. X    FLUSH;
  1266. X
  1267. X} /* SendQuit() */
  1268. X
  1269. X
  1270. X            /* SendData() - send output to layer's window */
  1271. X
  1272. Xvoid
  1273. XSendData(chan, buff, cnt)
  1274. Xint            chan;                    /* layer window ID */
  1275. Xunsigned char *buff;                /* new title string */
  1276. Xint            cnt;                    /* count of title length */
  1277. X{
  1278. X    unsigned c;                        /* output character being sent */
  1279. X
  1280. X    DO
  1281. X      {    int        dcnt;
  1282. X
  1283. X        DEBUG("SendData(chan %d, len %d, '", chan, cnt, cnt, buff);
  1284. X        for (dcnt=0; dcnt<cnt; dcnt++)
  1285. X            DEBUG("%c", buff[dcnt]); /* dump each char so null doesn't stop */
  1286. X        DEBUG("')\n");
  1287. X      }
  1288. X
  1289. X    if (chan <= 0 || chan > MAXPCHAN)
  1290. X      {    DO DEBUG("BAD CHANNEL!!!\n");
  1291. X        return;                        /* ignore request */
  1292. X      }
  1293. X
  1294. X    /* if new output channel stream then prefix redirect command */
  1295. X    if (chan != Outstream)
  1296. X      {    DO DEBUG("Redirecting output to %d '~2O%d'\n", chan, chan);
  1297. X        putchar(ESCAPE);            /* start of command sequence */
  1298. X        putchar('2');                /* send command size */
  1299. X        putchar('O');                /* send command */
  1300. X        putchar(chan + '0');        /* put out channel in ASCII */
  1301. X        Outstream = chan;            /* new output stream set */
  1302. X      }
  1303. X
  1304. X    /* transmit the buffer converting the ESCAPE sequence to double ESCAPE */
  1305. X    while (cnt--)
  1306. X      {    c = *buff++;                /* get next output character */
  1307. X#ifdef DUMPALL
  1308. X        DO DEBUG("outchar %c 0x%x\n", c, c);
  1309. X#endif
  1310. X        if (c == ESCAPE || c == (ESCAPE + 0x80))
  1311. X          {    putchar(c);                /* put it out twice */
  1312. X#ifdef DUMPALL
  1313. X            DO DEBUG(" Doubled Escape!\n");
  1314. X#endif
  1315. X          }
  1316. X        putchar(c);                    /* write character out */
  1317. X      }
  1318. X
  1319. X    FLUSH;                            /* force out queued output characters */
  1320. X        
  1321. X} /* SendData() */
  1322. X
  1323. X
  1324. X            /* Parse() - process next chunk of input stream */
  1325. X
  1326. Xstatic void
  1327. XParse()
  1328. X{
  1329. X#define    ST_NULL        0                /* not primed for next state yet */
  1330. X#define    ST_STREAM    1                /* processing default stream input */
  1331. X#define    ST_PKT        2                /* processing packet data */
  1332. X
  1333. X    int        c;                        /* input character being processed */
  1334. X
  1335. X    static    int state = ST_NULL;    /* current input state */
  1336. X    static    int psize = 0;            /* packet size */
  1337. X    static    int    rempsize = 0;        /* remembered packet size */
  1338. X    static    char pdata[MAXSTR];        /* area for packet data */
  1339. X    static    char *ppos;                /* packet read insert position */
  1340. X    static    int escapemode = 0;        /* processing escape character */
  1341. X    static    int    escapechar;            /* escape character being processed */
  1342. X    static    pchan = -1;                /* packet input stream channel */
  1343. X
  1344. X    while (insize-- > 0)            /* while more data */
  1345. X      {    c = *inpos++;                /* get next character */
  1346. X        switch (state)                /* process according to state */
  1347. X        { case ST_NULL:                /* prepare for new packet */
  1348. X            DO DEBUG("ST_NULL\n");
  1349. X            psize = 0;                /* clear packet size */
  1350. X            ppos = pdata;            /* start fill at data position */
  1351. X            pchan = Instream;        /* packet channel is current input stream */
  1352. X            state = ST_STREAM;        /* default is stream processing */
  1353. X
  1354. X          case ST_STREAM:
  1355. X            /* stream keyboard input for layer */
  1356. X            /* check for escape char with possible high bit on */
  1357. X#ifdef DUMPALL
  1358. X            DO DEBUG("ST_STREAM %x/%x esc %d insz %d\n",
  1359. X                        c, c & 0x7f, escapemode, insize);
  1360. X#endif
  1361. X            if (c == ESCAPE || c == (ESCAPE | 0x80))
  1362. X              {    if (escapemode && c == escapechar) /* previous was ESCAPE */
  1363. X                /* this is really a single ESCAPE character */
  1364. X                    escapemode = 0;        /* back out of ESCAPE mode */
  1365. X                else
  1366. X                    /* what do we do with back to back esc esc+0x80 ? */
  1367. X                  {    /* flag in escape mode */
  1368. X                    escapemode++;
  1369. X                    escapechar = c;        /* remember character used for escape */
  1370. X                    continue;            /* and continue scan */
  1371. X                  }
  1372. X              }
  1373. X            else
  1374. X            if (escapemode)
  1375. X              { /* this is the start of a control packet */
  1376. X                if (psize)                /* if we have previous data packet */
  1377. X                    Packet(pchan, psize, pdata); /* finish up previous pkt */
  1378. X                /* process packet size */
  1379. X                psize = (c & 0x7f) - '0'; /* save size byte */
  1380. X                if (psize <= 0 || psize > MAXSTR)
  1381. X                  {    /* bad size */
  1382. X                    DO DEBUG("Bad pkt size %d\n", psize);
  1383. X                    break;                /* trash this packet */
  1384. X                  }
  1385. X                rempsize = psize;        /* remember this size for later */
  1386. X#if 0
  1387. X                ptimo = rtimo;            /* start receive timeout */                
  1388. X#endif
  1389. X                escapemode = 0;            /* escape mode now off */
  1390. X                ppos = pdata;            /* initialize data store pointer */
  1391. X                state = ST_PKT;            /* expect packet data next */
  1392. X                continue;                /* continue scan */
  1393. X              }
  1394. X                  
  1395. X            /* process standard data output character for current stream */
  1396. X            
  1397. X            *ppos++ = c;                /* save next data character */
  1398. X                
  1399. X            if (++psize >= MAXSTR)        /* if packet full ... */
  1400. X              {    Packet(pchan, psize, pdata); /* process this packet */
  1401. X                break;                    /* end packet processing */
  1402. X              }                  
  1403. X            continue;                    /* continue scan */
  1404. X                                                
  1405. X          case ST_PKT:
  1406. X            /* process next paket data byte */
  1407. X            *ppos++ = c & 0x7f;        /* store next data byte */
  1408. X#ifdef DUMPALL
  1409. X            DO DEBUG("ST_PKT: %x sz %d\n", c & 0x7f, psize);
  1410. X#endif
  1411. X            if (--psize != 0)
  1412. X                continue;
  1413. X#if 0
  1414. X            if (crc((unsigned char *) &rpkt, rpkt.pkt.HEADER_DSIZE+2))
  1415. X                STATS(Scrcerr);            /* communications error */
  1416. X            else
  1417. X#endif
  1418. X            Packet(0, rempsize, pdata); /* process it */
  1419. X                
  1420. X            } /* end build packet switch */
  1421. X            
  1422. X#if 0
  1423. X        ptimo = 0;                        /* no more receive timeout */
  1424. X#endif
  1425. X        state = ST_NULL;                /* no more receive packet in progress */
  1426. X            
  1427. X      } /* end while (insize) */
  1428. X          
  1429. X    if (state == ST_STREAM && psize )    /* if we have some data ... */
  1430. X      {    Packet(Instream, psize, pdata); /* process this data */
  1431. X#if 0
  1432. X        ptimo = 0;                        /* no more receive timeout */
  1433. X#endif
  1434. X        state = ST_NULL;                /* no more receive packet in progress */
  1435. X      }
  1436. X
  1437. X} /* Parse() */
  1438. X
  1439. X
  1440. X        /* Packet() - prcess next input data string or control packet */
  1441. Xstatic void
  1442. XPacket(chan, size, buff)
  1443. Xint            chan;                        /* channel (0 if control packet) */
  1444. Xint            size;                        /* amount of data */
  1445. Xchar        *buff;                        /* pointer to packet data */
  1446. X{
  1447. X    static struct Shape shape;            /* Shape structure */
  1448. X
  1449. X    DO DEBUG("Packet(chan %d, size %d, '%.*s')\n", chan, size, size, buff);
  1450. X
  1451. X    /* verify channel */
  1452. X    if (chan < 0 || chan > MAXPCHAN)
  1453. X      {    DO DEBUG("BAD CHANNEL!!\n");
  1454. X        return;                            /* ignore bad channel */
  1455. X      }
  1456. X
  1457. X    /* if data packet (chan>0) feed data to server */
  1458. X    if (chan > 0)
  1459. X      {    ReceiveData(chan, buff, size);
  1460. X        return;                            /* we are through */
  1461. X      }
  1462. X
  1463. X    /* control packet (channel 0) */
  1464. X    chan = buff[1] - '0';                /* assume channel specified */
  1465. X    if (chan < 0 || chan > MAXPCHAN)    /* if invalid ... */
  1466. X        chan = 0;                        /* set to zero */
  1467. X
  1468. X    switch (buff[0])
  1469. X    { case 'I':        /* redirect stream */
  1470. X        DO DEBUG("CMD 'I' redirect stream to %c\n", buff[1]);
  1471. X        if (size != 2)                    /* verify size */
  1472. X            break;                        /* break if bad */
  1473. X        if (chan == 0)                    /* verify channel */
  1474. X            break;                        /* break if bad */
  1475. X        Instream = chan;                /* new instream channel */
  1476. X        return;                            /* we are through */
  1477. X
  1478. X      case 'A':        /* returned A_NEWLAYER packet */
  1479. X        DO DEBUG("CMD 'A' A_NEWLAYER response %c newchan %c SNresp %d\n",
  1480. X                    buff[2], buff[1], SNresp);
  1481. X        if (size != 3 + ATTRSIZE)
  1482. X            break;                        /* break if bad */
  1483. X
  1484. X        /* if SendNew() not waiting for a response this is invalid */
  1485. X        if (SNresp != SN_WAITING)
  1486. X            break;                        /* break if bad */
  1487. X
  1488. X        if (buff[2] == '1')                /* if response is "failed" ... */
  1489. X            SNresp = -1;                /* show -1 response */
  1490. X        else
  1491. X        if (buff[2] == '0')                /* if response is "success" ... */
  1492. X          {    if (chan == 0)                /* if invalid channel */
  1493. X                break;                    /* break if bad */
  1494. X            /* build shape structure for SendNew() */
  1495. X            if (parseshape(&SNshape, &buff[3]) == -1)
  1496. X                break;                    /* if invalid data then bad packet */
  1497. X            SNresp = 0;                    /* show good response */
  1498. X            SNchan = chan;                /* indicate channel returned */
  1499. X          }
  1500. X        else
  1501. X            break;                        /* break if bad */
  1502. X
  1503. X        DO DEBUG("SNresp = %d, SNchan = %d\n", SNresp, SNchan);
  1504. X        return;                            /* we are through */
  1505. X        
  1506. X      case 'N':        /* new layer creation */
  1507. X        DO DEBUG("CMD 'N' new layer creation newchan %c\n", buff[1]);
  1508. X        if (size != 2 + ATTRSIZE)        /* verify size */
  1509. X            break;                        /* break if bad */
  1510. X        if (chan == 0)                    /* verify channel */
  1511. X            break;                        /* break if bad */
  1512. X        /* build shape structure */
  1513. X        if (parseshape(&shape, &buff[2]) == -1)
  1514. X            break;                        /* if invalid data then bad packet */
  1515. X        ReceiveNew(chan, &shape);        /* pass to server */
  1516. X        return;                            /* packet is done */
  1517. X
  1518. X      case 'D':        /* deleted layer */
  1519. X        DO DEBUG("CMD 'D' deleted layer %c\n", buff[1]);
  1520. X        if (size != 2)                    /* verify size */
  1521. X            break;                        /* break if bad */
  1522. X        if (chan == 0)                    /* verify channel */
  1523. X            break;                        /* break if bad */
  1524. X        ReceiveDelete(chan);            /* pass on to server */
  1525. X        return;                            /* packet is done */
  1526. X
  1527. X      case 'E':        /* exit - awaiting shutdown */
  1528. X        DO DEBUG("CMD 'E' exit MacLayers awaiting shutdown msg\n");
  1529. X        if (size != 1)                    /* verify size */
  1530. X            break;                        /* break if bad */
  1531. X        ReceiveQuit();                    /* pass to server */
  1532. X        /* NOT REACHED*/
  1533. X        return;                            /* ?? should never reach here */
  1534. X
  1535. X      case 'R':        /* reshaped */
  1536. X        DO DEBUG("CMD 'R' reshape chan %c\n", buff[1]);
  1537. X
  1538. X        if (size != 2 + ATTRSIZE)        /* verify size */
  1539. X            break;                        /* break if bad */
  1540. X
  1541. X        if (chan == 0)                    /* verify channel */
  1542. X            break;                        /* break if bad */
  1543. X
  1544. X        /* build shape structure */
  1545. X        if (parseshape(&shape, &buff[2]) == -1)
  1546. X            break;                        /* if invalid data then bad packet */
  1547. X
  1548. X        ReceiveReshape(chan, &shape);     /* tell server about shape */
  1549. X        return;                            /* packet processed */
  1550. X
  1551. X      case 'S':        /* signal */
  1552. X        DO DEBUG("CMD 'S' SIGNAL chan %c sig %c\n", buff[1], buff[2]);
  1553. X        if (size != 3)                    /* verify size */
  1554. X            break;                        /* break if bad */
  1555. X        if (chan == 0)
  1556. X            break;                        /* break if bad */
  1557. X
  1558. X        if (buff[2] == '0')                /* if SIGINT */
  1559. X            size = SIGINT;                /* yes */
  1560. X        else
  1561. X        if (buff[2] == '1')                /* if SIGHUP */
  1562. X            size = SIGHUP;                /* yes */
  1563. X        else
  1564. X            break;                        /* invalid signal */
  1565. X            
  1566. X        ReceiveSignal(chan, size);        /* pass to server */
  1567. X        return;                            /* packet processed */
  1568. X
  1569. X      default:
  1570. X        DO DEBUG("ILLEGAL CONTROL PACKET!!!\n");
  1571. X        return;                            /* ignore bad packet */
  1572. X
  1573. X    } /* end command packet switch */
  1574. X
  1575. X    /* switch falls out if bad size or channel for given command */
  1576. X    DO DEBUG("Invalid size or channel!!!\n");    /* dump error */
  1577. X    return;                                /* ignore packet */
  1578. X
  1579. X} /* Packet() */
  1580. X
  1581. X
  1582. X            /* GetData() - read next input from MacLayers stream */
  1583. X
  1584. X/*    An input timout parameter can indicate that we return if nothing
  1585. X**    is read within a certain amount of seconds. The return code is:
  1586. X**
  1587. X**        0 - timeout occured and no data was read
  1588. X**
  1589. X**        1 - no timeout occured, data read
  1590. X*/
  1591. Xstatic int
  1592. XGetData(timeout)
  1593. Xint            timeout;                /* timeout in seconds (or zero) */
  1594. X{
  1595. X    int        result;                    /* return from read() */
  1596. X
  1597. X    DO DEBUG("GetData(timout %d)\n", timeout);
  1598. X
  1599. X    /* if buffer still has data simply return (SHOULD NOT OCCUR?) */
  1600. X    if (insize > 0)
  1601. X        return ( 1 );                /* act as through data read */
  1602. X    inpos = inbuff;                    /* next get will start at beginning */
  1603. X    insize = 0;                        /* default insize back to zero */
  1604. X
  1605. X    /* set timeout if we are to do so */
  1606. X    if (timeout)
  1607. X        (void) alarm(timeout);        /* set timeout in seconds */
  1608. X
  1609. X    /* do the read from stdin */
  1610. X    result = read(0, inbuff, IOSIZE);
  1611. X
  1612. X    /* if alarm was set cancel it now */
  1613. X    if (timeout)
  1614. X        (void) alarm(0);            /* cancel alarm */
  1615. X
  1616. X    /* check for timeout or error */
  1617. X    /* EWOULDBLOCK for no data avail -(but we should not see this) */
  1618. X    /* EINTR if signal stopped the read -(rare but could happen) */
  1619. X    if (result <= 0)
  1620. X        return ( 0 );                /* return nothing read */
  1621. X
  1622. X    /* return with fresh buffer data */
  1623. X    insize = result;
  1624. X    DO DEBUG("read %d bytes\n", insize);
  1625. X    return ( 1 );                    /* return OK code */
  1626. X
  1627. X} /* GetData() */
  1628. X
  1629. X
  1630. X            /* AwaitInput() - wait for more input from MacLayers */
  1631. X
  1632. Xstatic void
  1633. XAwaitInput()
  1634. X{
  1635. X    int        r;                        /*  read descriptor bits */
  1636. X
  1637. X    DO DEBUG("AwaitInput()\n");
  1638. X
  1639. X    do
  1640. X      {    r = 1<<0;                    /* wait for read from input device */
  1641. X        if (select(32, &r, NULL, NULL, NULL) == -1)    /* if problem waiting ... */
  1642. X          {    if (errno != EINTR)            /* if not simply signal taken ... */
  1643. X              {    /* SHOULD NOT OCCUR - shutdown layers */
  1644. X                DO DEBUG("AwaitInput: select error %d\n", errno);
  1645. X                printf("layers: AwaitInput: bad select %d\n", errno);
  1646. X                FQuit();                    /* shutdown layers */
  1647. X                /* NOT REACHED */
  1648. X              }
  1649. X          }
  1650. X      } while ((r & 1<<0) == 0);
  1651. X        
  1652. X} /* AwaitInput() */
  1653. X
  1654. X                /* asciishape() - convert Shape structure to ASCII */
  1655. Xstatic void
  1656. Xasciishape(shape, loc)
  1657. Xstruct Shape    *shape;                        /* Shape structure for channel */
  1658. Xchar            *loc;                        /* location to start filling result */
  1659. X{
  1660. X    char        *origloc;                    /* (for debuggin) */
  1661. X
  1662. X    origloc = loc;                            /* remember start of string */
  1663. X    fill4(&loc, shape->worigh);                /* origin h */
  1664. X    fill4(&loc, shape->worigv);                /* origin v */
  1665. X    fill2(&loc, shape->wlines);                /* lines high */
  1666. X    fill2(&loc, shape->wchars);                /* chars wide */
  1667. X    fill1(&loc, shape->wfont);                /* font size */
  1668. X    fill2(&loc, shape->wattr);                /* attributes */
  1669. X
  1670. X    DO DEBUG("asciishape(): %.*s\n", ATTRSIZE, origloc);
  1671. X
  1672. X} /* asciishape() */
  1673. X
  1674. X
  1675. X                    /* fill4() - convert parameter to ASCII */
  1676. X
  1677. Xstatic void
  1678. Xfill4(loc, valu)
  1679. Xchar        **loc;                            /* pointer to fill area pointer */
  1680. Xunsigned    valu;                            /* value to use */
  1681. X{
  1682. X    fill2(loc, valu>>8);                    /* fill high half word */
  1683. X    fill2(loc, valu & 0xff);                /* fill low half word */
  1684. X
  1685. X} /* fill4() */
  1686. X
  1687. X
  1688. X                    /* fill2() - convert parameter to ASCII */
  1689. X
  1690. Xstatic void
  1691. Xfill2(loc, valu)
  1692. Xchar        **loc;                            /* pointer to fill area pointer */
  1693. Xunsigned    valu;                            /* value to use */
  1694. X{
  1695. X    fill1(loc, valu>>4);                    /* fill high byte */
  1696. X    fill1(loc, valu & 0xf);                    /* fill low byte */
  1697. X    
  1698. X} /* fill2() */
  1699. X
  1700. X
  1701. X                    /* fill1() - convert parameter to ASCII */
  1702. X
  1703. Xstatic void
  1704. Xfill1(loc, valu)
  1705. Xchar        **loc;                            /* pointer to fill area pointer */
  1706. Xunsigned    valu;                            /* value to use */
  1707. X{
  1708. X    *(*loc)++ = "0123456789ABCDEF"[valu & 0xf]; /* return hex value */
  1709. X
  1710. X} /* fill1() */
  1711. X
  1712. X
  1713. X            /* parseshape() - convert ASCII image to Shape structure */
  1714. X                
  1715. Xstatic int    Badconvert;                        /* indicates bad conversion */
  1716. X
  1717. Xstatic int
  1718. Xparseshape(shape, loc)
  1719. Xstruct Shape    *shape;                        /* Shape structure for channel */
  1720. Xchar            *loc;                        /* location to start parsing */
  1721. X{
  1722. X    Badconvert = 0;                            /* clear bad characters indicator */
  1723. X    shape->worigh = get4(&loc);                /* origin h */
  1724. X    shape->worigv = get4(&loc);                /* origin v */
  1725. X    shape->wlines = get2(&loc);                /* lines high */
  1726. X    shape->wchars = get2(&loc);                /* chars wide */
  1727. X    shape->wfont = get1(&loc);                /* font size */
  1728. X    shape->wattr = get2(&loc);                /* attributes */
  1729. X
  1730. X    DO DEBUG("ParseShape(): origv %d, origh %d, lines %d, chars %d\n",
  1731. X                shape->worigv, shape->worigh, shape->wlines, shape->wchars);
  1732. X    DO DEBUG("   font %d, attr 0x%x, badconv %d\n",
  1733. X                    shape->wfont, shape->wattr, Badconvert);
  1734. X
  1735. X    return ( Badconvert ? -1 : 0 );            /* return conversion code */
  1736. X
  1737. X} /* parseshape() */
  1738. X
  1739. X
  1740. X                    /* get4() - convert ASCII to parameter */
  1741. X
  1742. Xstatic unsigned
  1743. Xget4(loc)
  1744. Xchar        **loc;                            /* pointer to fill area pointer */
  1745. X{
  1746. X    unsigned    hi;                            /* high portion */
  1747. X    unsigned    low;                        /* low portion */
  1748. X
  1749. X    hi = get2(loc);                            /* get high byte */
  1750. X    low = get2(loc);                        /* get low byte */
  1751. X
  1752. X    return ( (hi<<8) + low );                /* return word value */
  1753. X
  1754. X} /* get4() */
  1755. X
  1756. X
  1757. X                    /* get2() - convert ASCII to parameter */
  1758. X
  1759. Xstatic unsigned
  1760. Xget2(loc)
  1761. Xchar        **loc;                            /* pointer to fill area pointer */
  1762. X{
  1763. X    unsigned    hi;                            /* high portion */
  1764. X    unsigned    low;                        /* low portion */
  1765. X
  1766. X    hi = get1(loc);                            /* get high half */
  1767. X    low = get1(loc);                        /* get low half */
  1768. X
  1769. X    return ( (hi<<4) + low );                /* return byte value */
  1770. X    
  1771. X} /* get2() */
  1772. X
  1773. X
  1774. X                    /* get1() - convert ASCII to parameter */
  1775. X
  1776. X/*    This function sets 'Badconvert' if an invalid character is detected */
  1777. X
  1778. Xstatic unsigned
  1779. Xget1(loc)
  1780. Xchar        **loc;                            /* pointer to fill area pointer */
  1781. X{
  1782. X    int            c;                            /* character to convert */
  1783. X    
  1784. X    c = *(*loc)++;                            /* fetch character */
  1785. X    
  1786. X    if (c >= '0' && c <= '9')
  1787. X        /* zero through nine */
  1788. X        return ( c - '0' );                    /* return it's binary value */
  1789. X    
  1790. X    if (c >= 'a' && c <= 'f')
  1791. X        /* lower case hex */
  1792. X        return ( c - 'a' + 10);                /* return it's binary value */
  1793. X        
  1794. X    if (c >= 'A' && c <= 'F')
  1795. X        /* upper case hex */
  1796. X        return ( c - 'A' + 10);                /* return it's binary value */
  1797. X        
  1798. X    /* invalid digit! */
  1799. X    Badconvert++;                            /* set bad character flag */
  1800. X    return ( 0 );                            /* return a zero */
  1801. X
  1802. X} /* get1() */
  1803. SHAR_EOF
  1804. if test 25546 -ne "`wc -c < 'protocol.c'`"
  1805. then
  1806.     echo shar: error transmitting "'protocol.c'" '(should have been 25546 characters)'
  1807. fi
  1808. fi # end of overwriting check
  1809. #    End of shell archive
  1810. exit 0
  1811. --- end of part 2 ---
  1812.  
  1813.  
  1814.