home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1740 / scled.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-28  |  17.9 KB  |  826 lines

  1. /*
  2.     $Id: scled.c,v 2.5 90/08/26 11:35:26 sw Exp $
  3. */
  4.  
  5. #include <sys/types.h>
  6. #include <sys/tty.h>
  7.  
  8. #include <sys/termio.h>
  9.  
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <fcntl.h>
  13. #include <sys/ioctl.h>
  14. #include <errno.h>
  15.  
  16. #include <sys/cledio.h>
  17. #include <sys/cled.h>
  18.  
  19. int            cols = -1;
  20. unchar                  *buf;
  21. unchar                  inpbuf[256];
  22. struct termio           tio;
  23. extern unchar           *malloc(),*getenv();
  24.  
  25. FILE                    *ifp;
  26. int                     cledp;
  27.  
  28. unchar                  *cledfn = (unchar *) "/dev/cled";
  29. unchar            *empty = (unchar *) "";
  30.  
  31. struct cle_stats        stats;
  32.  
  33. struct items
  34. {
  35.     int                     numb;
  36.     char                    *str;
  37. };
  38.  
  39. struct items            tcap_seq[] =
  40. {
  41.     {TCAP_CLREOL,"clreol"},
  42.     {TCAP_SETINV,"setinv"},
  43.     {TCAP_SETNORM,"setnorm"},
  44.     {TCAP_SAVE,"save"},
  45.     {TCAP_RESTORE,"restore"},
  46.     {TCAP_FLASH,"flash"},
  47.     0
  48. };
  49.  
  50. struct items            func_names[] =
  51. {
  52.     {CLEFUN_INSERT,"insert"},
  53.     {CLEFUN_INSERT,"overstrike"},
  54.     {CLEFUN_GOTOBOL,"goto_bol"},
  55.     {CLEFUN_GOTOEOL,"goto_eol"},
  56.     {CLEFUN_DELWLFT,"del_word_left"},
  57.     {CLEFUN_DELWRIT,"del_word_right"},
  58.     {CLEFUN_DELBOL,"del_to_bol"},
  59.     {CLEFUN_DELEOL,"del_to_eol"},
  60.     {CLEFUN_CURSL,"cursor_left"},
  61.     {CLEFUN_CURSR,"cursor_right"},
  62.     {CLEFUN_DELCLFT,"del_char_left"},
  63.     {CLEFUN_DELCRIT,"del_char_right"},
  64.     {CLEFUN_REFRESH,"refresh"},
  65.     {CLEFUN_PREVIOUS,"previous"},
  66.     {CLEFUN_NEXT,"next"},
  67.     {CLEFUN_FIND,"find"},
  68.     {CLEFUN_NEWLINE,"newline"},
  69.     {CLEFUN_ESCAPE,"superquote"},
  70.     {CLEFUN_NOP,"nop"},
  71.     {CLEFUN_BELL,"bell"},
  72.     {CLEFUN_SKIPWR,"skip_word_right"},
  73.     {CLEFUN_SKIPWL,"skip_word_left"},
  74.     {CLEFUN_PURGE,"purge"},
  75.     {CLEFUN_META,"meta"},
  76.     {CLEFUN_ANSI,"ansi"},
  77.     {0,0}
  78. };
  79.  
  80. unchar                  *rev_funcnames[CLEFUN_MAX];
  81. unchar                  *rev_tcapnames[TCAP_COUNT];
  82. unchar                  *set_tcapnames[TCAP_COUNT];
  83. char            *tcap_defs[TCAP_COUNT];
  84.  
  85. struct cle_stats        stats;
  86. int                     line = 0,errors = 0;
  87. unchar                  delim[] = " \t\n";
  88. unchar                  *pathptrs[4];
  89.  
  90. #define ACC_EXISTS  0
  91. #define ACC_EXECUTE 1
  92. #define ACC_WRITE   2
  93. #define ACC_READ    4
  94.  
  95.  
  96. static unchar        *rev_keyname(key)
  97.     int                key;
  98. {
  99.     static unchar            name[8];
  100.  
  101.     if (CLEKEY_CHAR(key))
  102.         (void) sprintf(name,"M-%c",key);
  103.     else    (void) sprintf(name,"^%c",(key == 0x7F) ? '?' : key+'@');
  104.  
  105.     return name;
  106. }
  107.  
  108. /*
  109.    get_pathname is a function that takes as input an array of unchar *'s
  110.    which are presumed to be path names and a unchar * which is assumed to be
  111.    a filename. It builds a real filename by gluing each of the path names
  112.    successively to the filename and doing an access test on the composite
  113.    name. It returns a pointer to the composite string if the file is
  114.    accessable otherwise it returns null.
  115.  
  116.    At entry: paths - ptr to (unchar *) 0 terminated array of unchar pointers each
  117.    pointing to null terminated pathname string. filename - ptr to filename
  118.    string amode - access mode which to use to test according to the
  119.    following: 00 - check for file existance 01 - check for execute (search)
  120.    02 - check for write 04 - check for read At exit: returns ptr to composite
  121.    string from malloc'd memory if file accessable else returns NULL.
  122. */
  123.  
  124. unchar                  *get_pathname(paths,filename,amode)
  125.     unchar                  **paths,*filename;
  126.     int                     amode;
  127. {
  128.     unchar                  *s;
  129.     int                     fnlen;
  130.  
  131.     fnlen = strlen(filename) + 1;
  132.     if (filename[0] == '/' ||
  133.     (filename[0] == '.' && filename[1] == '/' ||
  134.         (filename[1] == '.' && filename[2] == '/')))
  135.     paths = (unchar **) 0;
  136.  
  137.     while (paths != (unchar **) 0 && *paths != (unchar *) 0)
  138.     {
  139.     int                     plen;
  140.  
  141.     plen = strlen(*paths);
  142.     s = malloc(plen + fnlen);
  143.     strcpy(s,*paths);
  144.     strcat(s,filename);
  145.     if (access(s,amode) == 0)
  146.         return s;
  147.     free(s);
  148.     ++paths;
  149.     }
  150.  
  151.     /* check the filename without a path */
  152.     if (access(filename,amode) == 0)
  153.     {
  154.     s = malloc(fnlen);
  155.     strcpy(s,filename);
  156.     return s;
  157.     }
  158.     return (unchar *) 0;
  159. }
  160.  
  161. int                     show_error(what,token)
  162.     unchar                  *what,*token;
  163. {
  164.     if (token == 0)
  165.     fprintf(stderr,"Missing %s on line %d\n",what,line);
  166.     else
  167.     fprintf(stderr,"Unknown %s {%s} on line %d\n",what,token,line);
  168.     ++errors;
  169. }
  170.  
  171. unchar                  *outfile = 0;
  172. unchar                  *inpfile = 0;
  173.  
  174. #ifdef NOISY
  175. dump_text(ptr,len)
  176.     unchar                  *ptr;
  177.     int                     len;
  178. {
  179.     int                     i,j;
  180.     unchar                  *l;
  181.  
  182.     while (len > 0)
  183.     {
  184.     l = ptr;
  185.     j = (len > 32) ? 32 : len;
  186.     for (i = 0; i < j; ++i)
  187.         fprintf(stderr,"%02X ",*(l + i));
  188.     fputs("\n",stderr);
  189.     for (i = 0; i < j; ++i)
  190.         fprintf(stderr," %c ",(*(l + i) > ' ') ? *(l + i) : '.');
  191.     fputs("\n",stderr);
  192.     ptr += j;
  193.     len -= j;
  194.     }
  195. }
  196.  
  197. #endif
  198.  
  199. void                    ioctl_error(old)
  200.     struct set_key          *old;
  201. {
  202.     int                     key,kie,func;
  203.     unchar                  *kp;
  204.     struct set_key          *skp;
  205.  
  206.     skp = (struct set_key *) buf;
  207.     kp = (unchar *) (skp + 1);
  208.     kp += skp->kdbuf_len * 2;
  209.  
  210.     if (old->kdbuf_len != skp->kdbuf_len)
  211.     {
  212.     kie = *kp++;
  213.     func = *kp++;
  214.     fprintf(stderr,"Error setting Key 0x%02X (%s) to func 0x%02X (%s)\n",
  215.         kie,((kie < CLEKEY_MAX) ? rev_keyname(kie) : empty),
  216.         func,((func < CLEFUN_MAX) ? rev_funcnames[func] : empty));
  217.     }
  218.     else if (old->tcapbuf_len != skp->tcapbuf_len)
  219.     {
  220.     int                     i;
  221.     unchar                  *t,*s;
  222.  
  223.     i = strlen(kp) + 1;
  224.     if ((t = (unchar *) malloc(i)) == (unchar *) 0)
  225.     {
  226.         fprintf(stderr,"Cannot get %d bytes reporting tcap_set failure",i);
  227.         return;
  228.     }
  229.  
  230.     kie = *kp++;
  231.     for (s = t; i > 0; --i,++kp)
  232.         *s++ = (*kp >= ' ' && *kp < 0177) ? *kp : '.';
  233.     *s = 0;
  234.     fprintf(stderr,"Error setting string 0x%02X (%s) to \"%s\"\n",
  235.         kie,((kie < TCAP_COUNT) ? rev_tcapnames[kie] : empty),t);
  236.     free(t);
  237.     }
  238.     else
  239.     {
  240.     fprintf(stderr,"Error %d setting keys/tcap strings in cled\n",errno);
  241.     fprintf(stderr,"before modes = %08X, kdbuf_len = %d, tcapbuf_len = %d\n",
  242.         old->modes,old->kdbuf_len,old->tcapbuf_len);
  243.     fprintf(stderr,"after  modes = %08X, kdbuf_len = %d, tcapbuf_len = %d\n",
  244.         skp->modes,skp->kdbuf_len,skp->tcapbuf_len);
  245.     }
  246. }
  247.  
  248. void                    read_setup()
  249. {
  250.     int                     i,anslen = 0;
  251.     unchar                  *kp,*ap,*abp,*ifn;
  252.     struct set_key          *skp;
  253.  
  254.     if (inpfile == (unchar *) 0)
  255.     inpfile = (unchar *) ".cledrc";
  256.     pathptrs[0] = (unchar *) "./";
  257.  
  258.     ap = getenv("CLED");
  259.     if (ap != (unchar *) 0 && (i = strlen(ap)) > 0)
  260.     {
  261.     if (ap[i - 1] != '/')
  262.     {
  263.         kp = malloc(strlen(ap) + 2);
  264.         strcpy(kp,ap);
  265.         strcat(kp,"/");
  266.         ap = kp;
  267.     }
  268.     }
  269.  
  270.     pathptrs[1] = ap;
  271.     ap = getenv("HOME");
  272.     if (ap != (unchar *) 0 && (i = strlen(ap)) > 0)
  273.     {
  274.     if (ap[i - 1] != '/')
  275.     {
  276.         kp = malloc(strlen(ap) + 2);
  277.         strcpy(kp,ap);
  278.         strcat(kp,"/");
  279.         ap = kp;
  280.     }
  281.     }
  282.  
  283.     pathptrs[2] = ap;
  284.     ifn = get_pathname(pathptrs,inpfile,ACC_READ);
  285.     if (ifn == (unchar *) 0)
  286.     {
  287.     if (buf != 0)
  288.         free(buf);
  289.     buf = (unchar *) 0;
  290.     return;
  291.     }
  292.  
  293.     ifp = fopen(ifn,"r");
  294.     if (ifp == 0)
  295.     {
  296.     sprintf(inpbuf,"Unable to open input: %s\n\t",ifn);
  297.     perror(inpbuf);
  298.     exit(1);
  299.     }
  300.  
  301.     tcap_defs[TCAP_CLREOL]    = TCAP_CLREOL_STR;
  302.     tcap_defs[TCAP_SETINV]    = TCAP_SETINV_STR;
  303.     tcap_defs[TCAP_SETNORM]    = TCAP_SETNORM_STR;
  304.     tcap_defs[TCAP_SAVE]    = TCAP_SAVE_STR;
  305.     tcap_defs[TCAP_RESTORE]    = TCAP_RESTORE_STR;
  306.     tcap_defs[TCAP_FLASH]    = TCAP_FLASH_STR;
  307.  
  308.     i = 256 + sizeof (struct set_key) + CLEKEY_MAX * 2;
  309.     buf = (unchar *) malloc(i * 2);
  310.     if (buf == 0)
  311.     {
  312.     fprintf(stderr,"Unable to allocate %d bytes\n",i);
  313.     exit(1);
  314.     }
  315.  
  316.     skp = (struct set_key *) buf;
  317.     skp->kdbuf_len = 0;
  318.     skp->tcapbuf_len = 0;
  319.     skp->modes = 0;
  320.  
  321.     kp = (unchar *) (skp + 1);    /* point to key space */
  322.     abp = ap = kp + CLEKEY_MAX * 2;
  323.     while (fgets(inpbuf,sizeof (inpbuf),ifp) != NULL)
  324.     {
  325.     unchar                  *tok1,*tok2,c;
  326.     extern unchar           *strtok();
  327.  
  328.     ++line;
  329.     tok1 = strtok(inpbuf,delim);
  330.     if (tok1 == 0)
  331.         continue;
  332.  
  333.     if (strcmp(tok1,"columns") == 0)
  334.     {
  335.         tok1 = strtok((unchar *) 0,delim);
  336.         if (tok1 == 0)
  337.         {
  338.         show_error("mode",tok1);
  339.         continue;
  340.         }
  341.  
  342.         cols = atoi(tok1);
  343.         if (cols >= 8 || cols <= MAXLINE)
  344.         continue;
  345.  
  346.         cols = -1;
  347.  
  348.         show_error("mode",tok1);
  349.         continue;
  350.     }
  351.  
  352.     if (strcmp(tok1,"mode") == 0)
  353.     {
  354.         tok1 = strtok((unchar *) 0,delim);
  355.         if (tok1 == 0)
  356.         {
  357.         show_error("mode",tok1);
  358.         continue;
  359.         }
  360.  
  361.         if (strcmp(tok1,"insert") == 0)
  362.         {
  363.         skp->modes |= CLEMODE_INSERT;
  364.         continue;
  365.         }
  366.  
  367.         if (strcmp(tok1,"overstrike") == 0)
  368.         {
  369.         skp->modes |= CLEMODE_OVER;
  370.         continue;
  371.         }
  372.  
  373.         show_error("mode",tok1);
  374.         continue;
  375.     }
  376.  
  377.     if (strcmp(tok1,"key") == 0)
  378.     {
  379.         int                     key,func;
  380.  
  381.         tok1 = strtok((unchar *) 0,delim);
  382.         if (tok1 == 0)
  383.         {
  384.         show_error("keyname",tok1);
  385.         continue;
  386.         }
  387.  
  388.         if (tok1[0] == '^')
  389.         key = (tok1[1] == '?') ? 0x7F : CLEKEY_CTL(tok1[1]);
  390.         else if (tok1[0] == '_')
  391.         key = CLEKEY_ESC(tok1[1]);
  392.         else if (tok1[0] == 'M' && tok1[1] == '-')
  393.         key = CLEKEY_ESC(tok1[2]);
  394.         else
  395.         {
  396.         show_error("keyname",tok1);
  397.         continue;
  398.         }
  399.  
  400.         tok1 = strtok((unchar *) 0,delim);
  401.         if (tok1 == 0)
  402.         {
  403.         show_error("function name",tok1);
  404.         continue;
  405.         }
  406.  
  407.         for (func = 0; func_names[func].numb > 0; ++func)
  408.         if (strcmp(func_names[func].str,tok1) == 0)
  409.             break;
  410.  
  411.         if (func_names[func].numb == 0)
  412.         {
  413.         show_error("function name",tok1);
  414.         continue;
  415.         }
  416.  
  417.         skp->kdbuf_len += 1;
  418.         *kp++ = key;
  419.         *kp++ = func_names[func].numb;
  420.         continue;
  421.     }
  422.  
  423.     if (strcmp(tok1,"string") == 0)
  424.     {
  425.         int                     ans;
  426.         unchar                  *s;
  427.  
  428.         tok1 = strtok((unchar *) 0,delim);
  429.         if (tok1 == 0)
  430.         {
  431.         show_error("string name",tok1);
  432.         continue;
  433.         }
  434.  
  435.         for (ans = 0; tcap_seq[ans].str != 0; ++ans)
  436.         if (strcmp(tcap_seq[ans].str,tok1) == 0)
  437.             break;
  438.  
  439.         if (tcap_seq[ans].str == 0)
  440.         {
  441.         show_error("string name",tok1);
  442.         continue;
  443.         }
  444.  
  445.         tok1 = strtok((unchar *) 0,"\"\r\n");
  446.         if (set_tcapnames[ans] != (unchar *) 0)
  447.         {
  448.         anslen -= strlen(set_tcapnames[ans]) - 1;
  449.         if (anslen < 0)
  450.             anslen = 0;
  451.         free(set_tcapnames[ans]);
  452.         }
  453.  
  454.         if (tok1 != (unchar *) 0)
  455.         {
  456.         s = (unchar *) set_tcapnames[ans] = malloc(strlen(tok1) + 1);
  457.         if (s == (unchar *) 0)
  458.         {
  459.             fprintf(stderr,"Unable to allocate %d bytes of mem\n",
  460.             strlen(tok1) + 1);
  461.             exit(1);
  462.         }
  463.  
  464.         while (*tok1)
  465.         {
  466.             unchar                  c,*tp;
  467.  
  468.             c = *s++ = *tok1++;
  469.             if (c == '\\')
  470.             {
  471.             int                     val;
  472.  
  473.             tp = tok1 - 1;
  474.             switch ((c = *tok1++))
  475.             {
  476.             case 't':    val = '\t';    break;
  477.             case 'r':    val = '\r';    break;
  478.             case 'n':    val = '\n';    break;
  479.             case 'f':    val = '\f';    break;
  480.             case 'v':    val = '\v';    break;
  481.  
  482.             case '0':
  483.                 if (*tok1 < '0' || *tok1 > '7')
  484.                 {
  485.                 val = 0;
  486.                 fprintf(stderr,"Warning: null in string on line %d\n",line);
  487.                 break;
  488.                 }
  489.  
  490.             case '1':
  491.             case '2':
  492.             case '3':
  493.                 val = (c - '0') << 6;
  494.                 if (*tok1 < '0' || *tok1 > '7')
  495.                 {
  496.                     show_error("string constant",tp);
  497.                     break;
  498.                 }
  499.                 val |= (*tok1++ - '0') << 3;
  500.                 if (*tok1 < '0' || *tok1 > '7')
  501.                 {
  502.                     show_error("string constant",tp);
  503.                     break;
  504.                 }
  505.                 val |= *tok1++ - '0';
  506.                 break;
  507.  
  508.  
  509.             default:
  510.                 val = c;
  511.             }
  512.             *(s - 1) = val;
  513.             }
  514.         }
  515.         *s++ = 0;
  516.         anslen += s - set_tcapnames[ans];
  517.         }
  518.         else
  519.         {
  520.         s = set_tcapnames[ans] = malloc(1);
  521.         if (s == (unchar *) 0)
  522.         {
  523.             fprintf(stderr,"Unable to allocate 1 byte");
  524.             exit(1);
  525.         }
  526.         *s = 0;
  527.         anslen += 1;
  528.         }
  529.         continue;
  530.     }
  531.     show_error("keyword",tok1);
  532.     }
  533.  
  534.     if (anslen > stats.tcapsize)
  535.     {
  536.     fprintf(stderr,"Error: Total length of all strings is greater than %d\n",
  537.         stats.tcapsize);
  538.     exit(1);
  539.     }
  540.     if (anslen != 0)
  541.     {
  542.     unchar                  *bp;
  543.  
  544.     bp = buf + sizeof (struct set_key) + skp->kdbuf_len * 2;
  545.     skp->tcapbuf_len = 0;
  546.     for (i = 0; i < sizeof (set_tcapnames) / sizeof (unchar *); ++i)
  547.     {
  548.         if (set_tcapnames[i] != (unchar *) 0)
  549.         {
  550.         if (strcmp(tcap_defs[i],set_tcapnames[i]) != 0)
  551.         {
  552.             int                     sln;
  553.  
  554.             *bp++ = i;
  555.             strcpy(bp,set_tcapnames[i]);
  556.             sln = strlen(bp) + 1;
  557.             bp += sln;
  558.             skp->tcapbuf_len += sln + 1;
  559.         }
  560.         free(set_tcapnames[i]);
  561.         set_tcapnames[i] = (unchar *) 0;
  562.         }
  563.     }
  564.  
  565. #ifdef NOISY
  566.     fprintf(stderr,"Found %d bytes of ascii defines:\n",skp->tcapbuf_len);
  567.     bp = buf + sizeof (struct set_key) + skp->kdbuf_len * 2;
  568.     dump_text(bp,skp->tcapbuf_len);
  569. #endif
  570.     }
  571.  
  572. #ifdef NOISY
  573.     fprintf(stderr,"Found modes = %02X, %d key defines, %d bytes of tcap defines and %d errors\n",
  574.     skp->modes,skp->kdbuf_len,skp->tcapbuf_len,errors);
  575. #endif
  576. }
  577.  
  578. void                    make_output()
  579. {
  580.     int                     i;
  581.     unchar                  *bp,*kp,*ascp;
  582.     FILE                    *ofp;
  583.     struct set_key          *kstr;
  584.  
  585.     ofp = fopen(outfile,"w");
  586.     if (ofp == 0)
  587.     {
  588.     sprintf(inpbuf,"Unable to open %s for write\n\t",outfile);
  589.     perror(inpbuf);
  590.     exit(1);
  591.     }
  592.  
  593.     if (ioctl(fileno(stderr),LDGETCOLS,&cols) < 0)
  594.     {
  595.     perror("error getting # of columns from cled\n\t");
  596.     exit(1);
  597.     }
  598.  
  599.     i = 256 + sizeof (struct set_key) + CLEKEY_MAX * 2;
  600.     bp = malloc(i);
  601.     if (ioctl(fileno(stderr),LDGETBF,bp) < 0)
  602.     {
  603.     perror("error getting key buf from cled\n\t");
  604.     exit(1);
  605.     }
  606.  
  607.     kstr = (struct set_key *) bp;
  608.     kp = bp + sizeof (struct set_key);
  609.     ascp = kp + kstr->kdbuf_len;
  610.  
  611. #ifdef NOISY
  612.     fprintf(stderr,"kstr=%08X, kp=%08X, ascp=%08X, key_len=%d, asc_len=%d\n",
  613.     kstr,kp,ascp,kstr->kdbuf_len,kstr->tcapbuf_len);
  614.     dump_text(ascp,kstr->tcapbuf_len);
  615. #endif
  616.  
  617.     fprintf(ofp,"columns %d\n",cols);
  618.     fprintf(ofp,"mode %s\n",(kstr->modes & CLEMODE_INSERT) ? "insert" : "overstrike");
  619.  
  620.     for (i = 0; i < kstr->kdbuf_len; ++i)
  621.     {
  622.     int                     func,j;
  623.  
  624.     func = *kp++;
  625.     if (func == 0)
  626.         continue;
  627.     if (func >= CLEFUN_MAX)
  628.     {
  629.         fprintf(stderr,"cled returned an unknown function of 0x%02X assigned to key 0x%02X\n",
  630.         func,i);
  631.         continue;
  632.     }
  633.     if (i >= CLEKEY_MAX)
  634.     {
  635.         fprintf(stderr,"cled returned unknown key 0x%02X assigned to function %s\n",
  636.         i,rev_funcnames[func]);
  637.         continue;
  638.     }
  639.     if (func != CLEFUN_BELL)
  640.         fprintf(ofp,"key %s %s\n",rev_keyname(i),rev_funcnames[func]);
  641.     }
  642.  
  643.     for (i = 0; i < kstr->tcapbuf_len;)
  644.     {
  645.     int                     j;
  646.  
  647.     j = *ascp++;
  648.     if (j >= TCAP_COUNT)
  649.         fprintf(stderr,"cled returned an unknown tcap_seq of {%s} assigned to 0x%02X\n",
  650.         ascp,j);
  651.     else
  652.     {
  653.         unchar                  *b,*s,c;
  654.  
  655.         s = inpbuf;
  656.         *s = 0;
  657.         b = ascp;
  658.         while ((c = *b++) != 0)
  659.         {
  660.         if (c < ' ')
  661.         {
  662.             switch (c)
  663.             {
  664.             case '\t':    strcat(s,"\\t");    break;
  665.             case '\r':    strcat(s,"\\r");    break;
  666.             case '\n':    strcat(s,"\\n");    break;
  667.             case '\f':    strcat(s,"\\f");    break;
  668.             case '\v':    strcat(s,"\\v");    break;
  669.             default:    sprintf(s,"\\%03o",c);
  670.             }
  671.  
  672.             s += strlen(s);
  673.             continue;
  674.         }
  675.         else if (c == '\\')
  676.         {
  677.             *s++ = '\\';
  678.             *s++ = '\\';
  679.         }
  680.         else
  681.             *s++ = c;
  682.  
  683.         *s = 0;
  684.         }
  685.         fprintf(ofp,"string %s \"%s\"\n",rev_tcapnames[j],inpbuf);
  686.     }
  687.     j = strlen(ascp) + 1;
  688.     i += j + 1;
  689.     ascp += j;
  690.     }
  691.     fclose(ofp);
  692. }
  693.  
  694. #define OPT_OUTPUT 0x01
  695. #define OPT_ERROR  0x80
  696.  
  697. main(argc,argv)
  698.     int                     argc;
  699.     unchar                  **argv;
  700. {
  701.     int                     i,opts;
  702.     unchar                  *kp,*ap,*abp;
  703.     struct set_key          *skp;
  704.  
  705.     for (opts = 0,i = 1; i < argc; ++i)
  706.     {
  707.     unchar                  *opt;
  708.  
  709.     opt = argv[i];
  710.     if (*opt == '-')
  711.     {
  712.         if (i + 1 >= argc)
  713.         {
  714.         opts |= OPT_ERROR;
  715.         fprintf(stderr,"%s option requires a parameter\n",opt);
  716.         continue;
  717.         }
  718.         if (opt[1] == 'o')
  719.         {
  720.         opts |= OPT_OUTPUT;
  721.         ++i;
  722.         outfile = argv[i];
  723.         continue;
  724.         }
  725.         opts |= OPT_ERROR;
  726.         continue;
  727.     }
  728.     inpfile = argv[i];
  729.     }
  730.  
  731.     if ((opts & OPT_ERROR) != 0)
  732.     {
  733.     fprintf(stderr,"Usage: %s [-o output_filename] [input_filename]\n",argv[0]);
  734.     exit(1);
  735.     }
  736.  
  737.     for (i = 0; i < CLEFUN_MAX; ++i)
  738.     rev_funcnames[func_names[i].numb] = (unchar *) func_names[i].str;
  739.     for (i = 0; i < TCAP_COUNT; ++i)
  740.     rev_tcapnames[tcap_seq[i].numb] = (unchar *) tcap_seq[i].str;
  741.  
  742. #ifdef NOISY
  743.     fprintf(stderr,"stderr fildes = %d. isatty() = %d\n",fileno(stderr),
  744.     isatty(fileno(stderr)));
  745. #endif
  746.  
  747.     if (!isatty(fileno(stderr)))
  748.     {
  749.     fprintf(stderr,"stderr is not a tty. Can't set discipline\n");
  750.     exit(1);
  751.     }
  752.  
  753.     if (ioctl(fileno(stderr),TCGETA,&tio) < 0)
  754.     {
  755.     perror("Error obtaining termio struct from stderr\n\t");
  756.     exit(1);
  757.     }
  758.  
  759.     cledp = open(cledfn,O_RDWR);
  760.     if (cledp < 0)
  761.     {
  762.     fprintf(stderr,"cled not installed on the system\n");
  763.     exit(1);
  764.     }
  765.  
  766.     if (ioctl(cledp,LDGETS,&stats) < 0)
  767.     {
  768.     sprintf(inpbuf,"Error doing LDGETS ioctl to %s\n\t",cledfn);
  769.     perror(inpbuf);
  770.     exit(1);
  771.     }
  772.     close(cledp);
  773.  
  774.     if (stats.line == 0)
  775.     {
  776.     fprintf(stderr,"cled is not installed as a line discipline\n");
  777.     exit(1);
  778.     }
  779.  
  780. #if 0
  781.     if (stats.ledbufs <= stats.ledbufs_used ||
  782.     stats.ttybufs <= stats.ttybufs_used)
  783.     {
  784.     fprintf(stderr,"No buffers available. ttybufs free = %d, ledbufs free = %d\n",
  785.         stats.ttybufs - stats.ttybufs_used,stats.ledbufs - stats.ledbufs_used);
  786.     exit(1);
  787.     }
  788. #endif
  789.  
  790.     tio.c_line = stats.line;
  791.     tio.c_lflag |= CLEDFLAGS;
  792.     if (ioctl(fileno(stderr),TCSETA,&tio) < 0)
  793.     {
  794.     sprintf(inpbuf,"Error setting line discipline to %d\n\t",stats.line);
  795.     perror(inpbuf);
  796.     exit(1);
  797.     }
  798.  
  799.     if ((opts & OPT_OUTPUT) != 0)
  800.     make_output();
  801.  
  802.     read_setup();
  803.     if (cols > 0)
  804.     if (ioctl(fileno(stderr),LDSETCOLS,&cols) < 0)
  805.     {
  806.         perror("error setting # of columns in cled\n\t");
  807.         fprintf(stderr,"columns %d\n",cols);
  808.         exit(1);
  809.     }
  810.  
  811.     if (buf != (unchar *) 0)
  812.     {
  813.     struct set_key          old;
  814.  
  815.     old = *(struct set_key *) buf;
  816.     if (ioctl(fileno(stderr),LDSETBF,buf) < 0)
  817.     {
  818.         perror("error setting key buf in cled\n\t");
  819.         ioctl_error(&old);
  820.         exit(1);
  821.     }
  822.     }
  823.  
  824.     return 0;
  825. }
  826.