home *** CD-ROM | disk | FTP | other *** search
- /*
- $Id: scled.c,v 2.5 90/08/26 11:35:26 sw Exp $
- */
-
- #include <sys/types.h>
- #include <sys/tty.h>
-
- #include <sys/termio.h>
-
- #include <stdio.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <errno.h>
-
- #include <sys/cledio.h>
- #include <sys/cled.h>
-
- int cols = -1;
- unchar *buf;
- unchar inpbuf[256];
- struct termio tio;
- extern unchar *malloc(),*getenv();
-
- FILE *ifp;
- int cledp;
-
- unchar *cledfn = (unchar *) "/dev/cled";
- unchar *empty = (unchar *) "";
-
- struct cle_stats stats;
-
- struct items
- {
- int numb;
- char *str;
- };
-
- struct items tcap_seq[] =
- {
- {TCAP_CLREOL,"clreol"},
- {TCAP_SETINV,"setinv"},
- {TCAP_SETNORM,"setnorm"},
- {TCAP_SAVE,"save"},
- {TCAP_RESTORE,"restore"},
- {TCAP_FLASH,"flash"},
- 0
- };
-
- struct items func_names[] =
- {
- {CLEFUN_INSERT,"insert"},
- {CLEFUN_INSERT,"overstrike"},
- {CLEFUN_GOTOBOL,"goto_bol"},
- {CLEFUN_GOTOEOL,"goto_eol"},
- {CLEFUN_DELWLFT,"del_word_left"},
- {CLEFUN_DELWRIT,"del_word_right"},
- {CLEFUN_DELBOL,"del_to_bol"},
- {CLEFUN_DELEOL,"del_to_eol"},
- {CLEFUN_CURSL,"cursor_left"},
- {CLEFUN_CURSR,"cursor_right"},
- {CLEFUN_DELCLFT,"del_char_left"},
- {CLEFUN_DELCRIT,"del_char_right"},
- {CLEFUN_REFRESH,"refresh"},
- {CLEFUN_PREVIOUS,"previous"},
- {CLEFUN_NEXT,"next"},
- {CLEFUN_FIND,"find"},
- {CLEFUN_NEWLINE,"newline"},
- {CLEFUN_ESCAPE,"superquote"},
- {CLEFUN_NOP,"nop"},
- {CLEFUN_BELL,"bell"},
- {CLEFUN_SKIPWR,"skip_word_right"},
- {CLEFUN_SKIPWL,"skip_word_left"},
- {CLEFUN_PURGE,"purge"},
- {CLEFUN_META,"meta"},
- {CLEFUN_ANSI,"ansi"},
- {0,0}
- };
-
- unchar *rev_funcnames[CLEFUN_MAX];
- unchar *rev_tcapnames[TCAP_COUNT];
- unchar *set_tcapnames[TCAP_COUNT];
- char *tcap_defs[TCAP_COUNT];
-
- struct cle_stats stats;
- int line = 0,errors = 0;
- unchar delim[] = " \t\n";
- unchar *pathptrs[4];
-
- #define ACC_EXISTS 0
- #define ACC_EXECUTE 1
- #define ACC_WRITE 2
- #define ACC_READ 4
-
-
- static unchar *rev_keyname(key)
- int key;
- {
- static unchar name[8];
-
- if (CLEKEY_CHAR(key))
- (void) sprintf(name,"M-%c",key);
- else (void) sprintf(name,"^%c",(key == 0x7F) ? '?' : key+'@');
-
- return name;
- }
-
- /*
- get_pathname is a function that takes as input an array of unchar *'s
- which are presumed to be path names and a unchar * which is assumed to be
- a filename. It builds a real filename by gluing each of the path names
- successively to the filename and doing an access test on the composite
- name. It returns a pointer to the composite string if the file is
- accessable otherwise it returns null.
-
- At entry: paths - ptr to (unchar *) 0 terminated array of unchar pointers each
- pointing to null terminated pathname string. filename - ptr to filename
- string amode - access mode which to use to test according to the
- following: 00 - check for file existance 01 - check for execute (search)
- 02 - check for write 04 - check for read At exit: returns ptr to composite
- string from malloc'd memory if file accessable else returns NULL.
- */
-
- unchar *get_pathname(paths,filename,amode)
- unchar **paths,*filename;
- int amode;
- {
- unchar *s;
- int fnlen;
-
- fnlen = strlen(filename) + 1;
- if (filename[0] == '/' ||
- (filename[0] == '.' && filename[1] == '/' ||
- (filename[1] == '.' && filename[2] == '/')))
- paths = (unchar **) 0;
-
- while (paths != (unchar **) 0 && *paths != (unchar *) 0)
- {
- int plen;
-
- plen = strlen(*paths);
- s = malloc(plen + fnlen);
- strcpy(s,*paths);
- strcat(s,filename);
- if (access(s,amode) == 0)
- return s;
- free(s);
- ++paths;
- }
-
- /* check the filename without a path */
- if (access(filename,amode) == 0)
- {
- s = malloc(fnlen);
- strcpy(s,filename);
- return s;
- }
- return (unchar *) 0;
- }
-
- int show_error(what,token)
- unchar *what,*token;
- {
- if (token == 0)
- fprintf(stderr,"Missing %s on line %d\n",what,line);
- else
- fprintf(stderr,"Unknown %s {%s} on line %d\n",what,token,line);
- ++errors;
- }
-
- unchar *outfile = 0;
- unchar *inpfile = 0;
-
- #ifdef NOISY
- dump_text(ptr,len)
- unchar *ptr;
- int len;
- {
- int i,j;
- unchar *l;
-
- while (len > 0)
- {
- l = ptr;
- j = (len > 32) ? 32 : len;
- for (i = 0; i < j; ++i)
- fprintf(stderr,"%02X ",*(l + i));
- fputs("\n",stderr);
- for (i = 0; i < j; ++i)
- fprintf(stderr," %c ",(*(l + i) > ' ') ? *(l + i) : '.');
- fputs("\n",stderr);
- ptr += j;
- len -= j;
- }
- }
-
- #endif
-
- void ioctl_error(old)
- struct set_key *old;
- {
- int key,kie,func;
- unchar *kp;
- struct set_key *skp;
-
- skp = (struct set_key *) buf;
- kp = (unchar *) (skp + 1);
- kp += skp->kdbuf_len * 2;
-
- if (old->kdbuf_len != skp->kdbuf_len)
- {
- kie = *kp++;
- func = *kp++;
- fprintf(stderr,"Error setting Key 0x%02X (%s) to func 0x%02X (%s)\n",
- kie,((kie < CLEKEY_MAX) ? rev_keyname(kie) : empty),
- func,((func < CLEFUN_MAX) ? rev_funcnames[func] : empty));
- }
- else if (old->tcapbuf_len != skp->tcapbuf_len)
- {
- int i;
- unchar *t,*s;
-
- i = strlen(kp) + 1;
- if ((t = (unchar *) malloc(i)) == (unchar *) 0)
- {
- fprintf(stderr,"Cannot get %d bytes reporting tcap_set failure",i);
- return;
- }
-
- kie = *kp++;
- for (s = t; i > 0; --i,++kp)
- *s++ = (*kp >= ' ' && *kp < 0177) ? *kp : '.';
- *s = 0;
- fprintf(stderr,"Error setting string 0x%02X (%s) to \"%s\"\n",
- kie,((kie < TCAP_COUNT) ? rev_tcapnames[kie] : empty),t);
- free(t);
- }
- else
- {
- fprintf(stderr,"Error %d setting keys/tcap strings in cled\n",errno);
- fprintf(stderr,"before modes = %08X, kdbuf_len = %d, tcapbuf_len = %d\n",
- old->modes,old->kdbuf_len,old->tcapbuf_len);
- fprintf(stderr,"after modes = %08X, kdbuf_len = %d, tcapbuf_len = %d\n",
- skp->modes,skp->kdbuf_len,skp->tcapbuf_len);
- }
- }
-
- void read_setup()
- {
- int i,anslen = 0;
- unchar *kp,*ap,*abp,*ifn;
- struct set_key *skp;
-
- if (inpfile == (unchar *) 0)
- inpfile = (unchar *) ".cledrc";
- pathptrs[0] = (unchar *) "./";
-
- ap = getenv("CLED");
- if (ap != (unchar *) 0 && (i = strlen(ap)) > 0)
- {
- if (ap[i - 1] != '/')
- {
- kp = malloc(strlen(ap) + 2);
- strcpy(kp,ap);
- strcat(kp,"/");
- ap = kp;
- }
- }
-
- pathptrs[1] = ap;
- ap = getenv("HOME");
- if (ap != (unchar *) 0 && (i = strlen(ap)) > 0)
- {
- if (ap[i - 1] != '/')
- {
- kp = malloc(strlen(ap) + 2);
- strcpy(kp,ap);
- strcat(kp,"/");
- ap = kp;
- }
- }
-
- pathptrs[2] = ap;
- ifn = get_pathname(pathptrs,inpfile,ACC_READ);
- if (ifn == (unchar *) 0)
- {
- if (buf != 0)
- free(buf);
- buf = (unchar *) 0;
- return;
- }
-
- ifp = fopen(ifn,"r");
- if (ifp == 0)
- {
- sprintf(inpbuf,"Unable to open input: %s\n\t",ifn);
- perror(inpbuf);
- exit(1);
- }
-
- tcap_defs[TCAP_CLREOL] = TCAP_CLREOL_STR;
- tcap_defs[TCAP_SETINV] = TCAP_SETINV_STR;
- tcap_defs[TCAP_SETNORM] = TCAP_SETNORM_STR;
- tcap_defs[TCAP_SAVE] = TCAP_SAVE_STR;
- tcap_defs[TCAP_RESTORE] = TCAP_RESTORE_STR;
- tcap_defs[TCAP_FLASH] = TCAP_FLASH_STR;
-
- i = 256 + sizeof (struct set_key) + CLEKEY_MAX * 2;
- buf = (unchar *) malloc(i * 2);
- if (buf == 0)
- {
- fprintf(stderr,"Unable to allocate %d bytes\n",i);
- exit(1);
- }
-
- skp = (struct set_key *) buf;
- skp->kdbuf_len = 0;
- skp->tcapbuf_len = 0;
- skp->modes = 0;
-
- kp = (unchar *) (skp + 1); /* point to key space */
- abp = ap = kp + CLEKEY_MAX * 2;
- while (fgets(inpbuf,sizeof (inpbuf),ifp) != NULL)
- {
- unchar *tok1,*tok2,c;
- extern unchar *strtok();
-
- ++line;
- tok1 = strtok(inpbuf,delim);
- if (tok1 == 0)
- continue;
-
- if (strcmp(tok1,"columns") == 0)
- {
- tok1 = strtok((unchar *) 0,delim);
- if (tok1 == 0)
- {
- show_error("mode",tok1);
- continue;
- }
-
- cols = atoi(tok1);
- if (cols >= 8 || cols <= MAXLINE)
- continue;
-
- cols = -1;
-
- show_error("mode",tok1);
- continue;
- }
-
- if (strcmp(tok1,"mode") == 0)
- {
- tok1 = strtok((unchar *) 0,delim);
- if (tok1 == 0)
- {
- show_error("mode",tok1);
- continue;
- }
-
- if (strcmp(tok1,"insert") == 0)
- {
- skp->modes |= CLEMODE_INSERT;
- continue;
- }
-
- if (strcmp(tok1,"overstrike") == 0)
- {
- skp->modes |= CLEMODE_OVER;
- continue;
- }
-
- show_error("mode",tok1);
- continue;
- }
-
- if (strcmp(tok1,"key") == 0)
- {
- int key,func;
-
- tok1 = strtok((unchar *) 0,delim);
- if (tok1 == 0)
- {
- show_error("keyname",tok1);
- continue;
- }
-
- if (tok1[0] == '^')
- key = (tok1[1] == '?') ? 0x7F : CLEKEY_CTL(tok1[1]);
- else if (tok1[0] == '_')
- key = CLEKEY_ESC(tok1[1]);
- else if (tok1[0] == 'M' && tok1[1] == '-')
- key = CLEKEY_ESC(tok1[2]);
- else
- {
- show_error("keyname",tok1);
- continue;
- }
-
- tok1 = strtok((unchar *) 0,delim);
- if (tok1 == 0)
- {
- show_error("function name",tok1);
- continue;
- }
-
- for (func = 0; func_names[func].numb > 0; ++func)
- if (strcmp(func_names[func].str,tok1) == 0)
- break;
-
- if (func_names[func].numb == 0)
- {
- show_error("function name",tok1);
- continue;
- }
-
- skp->kdbuf_len += 1;
- *kp++ = key;
- *kp++ = func_names[func].numb;
- continue;
- }
-
- if (strcmp(tok1,"string") == 0)
- {
- int ans;
- unchar *s;
-
- tok1 = strtok((unchar *) 0,delim);
- if (tok1 == 0)
- {
- show_error("string name",tok1);
- continue;
- }
-
- for (ans = 0; tcap_seq[ans].str != 0; ++ans)
- if (strcmp(tcap_seq[ans].str,tok1) == 0)
- break;
-
- if (tcap_seq[ans].str == 0)
- {
- show_error("string name",tok1);
- continue;
- }
-
- tok1 = strtok((unchar *) 0,"\"\r\n");
- if (set_tcapnames[ans] != (unchar *) 0)
- {
- anslen -= strlen(set_tcapnames[ans]) - 1;
- if (anslen < 0)
- anslen = 0;
- free(set_tcapnames[ans]);
- }
-
- if (tok1 != (unchar *) 0)
- {
- s = (unchar *) set_tcapnames[ans] = malloc(strlen(tok1) + 1);
- if (s == (unchar *) 0)
- {
- fprintf(stderr,"Unable to allocate %d bytes of mem\n",
- strlen(tok1) + 1);
- exit(1);
- }
-
- while (*tok1)
- {
- unchar c,*tp;
-
- c = *s++ = *tok1++;
- if (c == '\\')
- {
- int val;
-
- tp = tok1 - 1;
- switch ((c = *tok1++))
- {
- case 't': val = '\t'; break;
- case 'r': val = '\r'; break;
- case 'n': val = '\n'; break;
- case 'f': val = '\f'; break;
- case 'v': val = '\v'; break;
-
- case '0':
- if (*tok1 < '0' || *tok1 > '7')
- {
- val = 0;
- fprintf(stderr,"Warning: null in string on line %d\n",line);
- break;
- }
-
- case '1':
- case '2':
- case '3':
- val = (c - '0') << 6;
- if (*tok1 < '0' || *tok1 > '7')
- {
- show_error("string constant",tp);
- break;
- }
- val |= (*tok1++ - '0') << 3;
- if (*tok1 < '0' || *tok1 > '7')
- {
- show_error("string constant",tp);
- break;
- }
- val |= *tok1++ - '0';
- break;
-
-
- default:
- val = c;
- }
- *(s - 1) = val;
- }
- }
- *s++ = 0;
- anslen += s - set_tcapnames[ans];
- }
- else
- {
- s = set_tcapnames[ans] = malloc(1);
- if (s == (unchar *) 0)
- {
- fprintf(stderr,"Unable to allocate 1 byte");
- exit(1);
- }
- *s = 0;
- anslen += 1;
- }
- continue;
- }
- show_error("keyword",tok1);
- }
-
- if (anslen > stats.tcapsize)
- {
- fprintf(stderr,"Error: Total length of all strings is greater than %d\n",
- stats.tcapsize);
- exit(1);
- }
- if (anslen != 0)
- {
- unchar *bp;
-
- bp = buf + sizeof (struct set_key) + skp->kdbuf_len * 2;
- skp->tcapbuf_len = 0;
- for (i = 0; i < sizeof (set_tcapnames) / sizeof (unchar *); ++i)
- {
- if (set_tcapnames[i] != (unchar *) 0)
- {
- if (strcmp(tcap_defs[i],set_tcapnames[i]) != 0)
- {
- int sln;
-
- *bp++ = i;
- strcpy(bp,set_tcapnames[i]);
- sln = strlen(bp) + 1;
- bp += sln;
- skp->tcapbuf_len += sln + 1;
- }
- free(set_tcapnames[i]);
- set_tcapnames[i] = (unchar *) 0;
- }
- }
-
- #ifdef NOISY
- fprintf(stderr,"Found %d bytes of ascii defines:\n",skp->tcapbuf_len);
- bp = buf + sizeof (struct set_key) + skp->kdbuf_len * 2;
- dump_text(bp,skp->tcapbuf_len);
- #endif
- }
-
- #ifdef NOISY
- fprintf(stderr,"Found modes = %02X, %d key defines, %d bytes of tcap defines and %d errors\n",
- skp->modes,skp->kdbuf_len,skp->tcapbuf_len,errors);
- #endif
- }
-
- void make_output()
- {
- int i;
- unchar *bp,*kp,*ascp;
- FILE *ofp;
- struct set_key *kstr;
-
- ofp = fopen(outfile,"w");
- if (ofp == 0)
- {
- sprintf(inpbuf,"Unable to open %s for write\n\t",outfile);
- perror(inpbuf);
- exit(1);
- }
-
- if (ioctl(fileno(stderr),LDGETCOLS,&cols) < 0)
- {
- perror("error getting # of columns from cled\n\t");
- exit(1);
- }
-
- i = 256 + sizeof (struct set_key) + CLEKEY_MAX * 2;
- bp = malloc(i);
- if (ioctl(fileno(stderr),LDGETBF,bp) < 0)
- {
- perror("error getting key buf from cled\n\t");
- exit(1);
- }
-
- kstr = (struct set_key *) bp;
- kp = bp + sizeof (struct set_key);
- ascp = kp + kstr->kdbuf_len;
-
- #ifdef NOISY
- fprintf(stderr,"kstr=%08X, kp=%08X, ascp=%08X, key_len=%d, asc_len=%d\n",
- kstr,kp,ascp,kstr->kdbuf_len,kstr->tcapbuf_len);
- dump_text(ascp,kstr->tcapbuf_len);
- #endif
-
- fprintf(ofp,"columns %d\n",cols);
- fprintf(ofp,"mode %s\n",(kstr->modes & CLEMODE_INSERT) ? "insert" : "overstrike");
-
- for (i = 0; i < kstr->kdbuf_len; ++i)
- {
- int func,j;
-
- func = *kp++;
- if (func == 0)
- continue;
- if (func >= CLEFUN_MAX)
- {
- fprintf(stderr,"cled returned an unknown function of 0x%02X assigned to key 0x%02X\n",
- func,i);
- continue;
- }
- if (i >= CLEKEY_MAX)
- {
- fprintf(stderr,"cled returned unknown key 0x%02X assigned to function %s\n",
- i,rev_funcnames[func]);
- continue;
- }
- if (func != CLEFUN_BELL)
- fprintf(ofp,"key %s %s\n",rev_keyname(i),rev_funcnames[func]);
- }
-
- for (i = 0; i < kstr->tcapbuf_len;)
- {
- int j;
-
- j = *ascp++;
- if (j >= TCAP_COUNT)
- fprintf(stderr,"cled returned an unknown tcap_seq of {%s} assigned to 0x%02X\n",
- ascp,j);
- else
- {
- unchar *b,*s,c;
-
- s = inpbuf;
- *s = 0;
- b = ascp;
- while ((c = *b++) != 0)
- {
- if (c < ' ')
- {
- switch (c)
- {
- case '\t': strcat(s,"\\t"); break;
- case '\r': strcat(s,"\\r"); break;
- case '\n': strcat(s,"\\n"); break;
- case '\f': strcat(s,"\\f"); break;
- case '\v': strcat(s,"\\v"); break;
- default: sprintf(s,"\\%03o",c);
- }
-
- s += strlen(s);
- continue;
- }
- else if (c == '\\')
- {
- *s++ = '\\';
- *s++ = '\\';
- }
- else
- *s++ = c;
-
- *s = 0;
- }
- fprintf(ofp,"string %s \"%s\"\n",rev_tcapnames[j],inpbuf);
- }
- j = strlen(ascp) + 1;
- i += j + 1;
- ascp += j;
- }
- fclose(ofp);
- }
-
- #define OPT_OUTPUT 0x01
- #define OPT_ERROR 0x80
-
- main(argc,argv)
- int argc;
- unchar **argv;
- {
- int i,opts;
- unchar *kp,*ap,*abp;
- struct set_key *skp;
-
- for (opts = 0,i = 1; i < argc; ++i)
- {
- unchar *opt;
-
- opt = argv[i];
- if (*opt == '-')
- {
- if (i + 1 >= argc)
- {
- opts |= OPT_ERROR;
- fprintf(stderr,"%s option requires a parameter\n",opt);
- continue;
- }
- if (opt[1] == 'o')
- {
- opts |= OPT_OUTPUT;
- ++i;
- outfile = argv[i];
- continue;
- }
- opts |= OPT_ERROR;
- continue;
- }
- inpfile = argv[i];
- }
-
- if ((opts & OPT_ERROR) != 0)
- {
- fprintf(stderr,"Usage: %s [-o output_filename] [input_filename]\n",argv[0]);
- exit(1);
- }
-
- for (i = 0; i < CLEFUN_MAX; ++i)
- rev_funcnames[func_names[i].numb] = (unchar *) func_names[i].str;
- for (i = 0; i < TCAP_COUNT; ++i)
- rev_tcapnames[tcap_seq[i].numb] = (unchar *) tcap_seq[i].str;
-
- #ifdef NOISY
- fprintf(stderr,"stderr fildes = %d. isatty() = %d\n",fileno(stderr),
- isatty(fileno(stderr)));
- #endif
-
- if (!isatty(fileno(stderr)))
- {
- fprintf(stderr,"stderr is not a tty. Can't set discipline\n");
- exit(1);
- }
-
- if (ioctl(fileno(stderr),TCGETA,&tio) < 0)
- {
- perror("Error obtaining termio struct from stderr\n\t");
- exit(1);
- }
-
- cledp = open(cledfn,O_RDWR);
- if (cledp < 0)
- {
- fprintf(stderr,"cled not installed on the system\n");
- exit(1);
- }
-
- if (ioctl(cledp,LDGETS,&stats) < 0)
- {
- sprintf(inpbuf,"Error doing LDGETS ioctl to %s\n\t",cledfn);
- perror(inpbuf);
- exit(1);
- }
- close(cledp);
-
- if (stats.line == 0)
- {
- fprintf(stderr,"cled is not installed as a line discipline\n");
- exit(1);
- }
-
- #if 0
- if (stats.ledbufs <= stats.ledbufs_used ||
- stats.ttybufs <= stats.ttybufs_used)
- {
- fprintf(stderr,"No buffers available. ttybufs free = %d, ledbufs free = %d\n",
- stats.ttybufs - stats.ttybufs_used,stats.ledbufs - stats.ledbufs_used);
- exit(1);
- }
- #endif
-
- tio.c_line = stats.line;
- tio.c_lflag |= CLEDFLAGS;
- if (ioctl(fileno(stderr),TCSETA,&tio) < 0)
- {
- sprintf(inpbuf,"Error setting line discipline to %d\n\t",stats.line);
- perror(inpbuf);
- exit(1);
- }
-
- if ((opts & OPT_OUTPUT) != 0)
- make_output();
-
- read_setup();
- if (cols > 0)
- if (ioctl(fileno(stderr),LDSETCOLS,&cols) < 0)
- {
- perror("error setting # of columns in cled\n\t");
- fprintf(stderr,"columns %d\n",cols);
- exit(1);
- }
-
- if (buf != (unchar *) 0)
- {
- struct set_key old;
-
- old = *(struct set_key *) buf;
- if (ioctl(fileno(stderr),LDSETBF,buf) < 0)
- {
- perror("error setting key buf in cled\n\t");
- ioctl_error(&old);
- exit(1);
- }
- }
-
- return 0;
- }
-