mark@ems.UUCP (Mark H. Colburn) (12/21/86)
Here is the source for untic, a terminfo definition disassembler. The source here is from the Unipress EMACS distribution tape and has been delcared Public Domain by Unipress. The original author of the source is Dave Regan. The shar file contains source, Makefile and manpage. Mark H. Colburn UUCP: ihnp4!meccts!ems!mark EMS/McGraw-Hill ATT: (612) 829-8200 9855 West 78th Street Eden Prairie, MN 55344 ---------------------------------- CUT HERE -------------------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting test in a file # 3. Execute the file with /bin/sh (not csh) to create the files: # # Makefile # README # untic.1 # untic.c # # Created by mark (Mark H. Colburn) on Sun Dec 21 01:13:19 CST 1986 # if test -f 'Makefile' then echo shar: will not over-write existing file "'Makefile'" else echo extracting "'Makefile'" sed 's/^X//' >Makefile <<'SHAR_EOF' XCFLAGS = -O -DHPUX5 XDESTDIR = /usr/local/bin XDOCDIR = /usr/man/man1 X Xuntic: untic.c X $(CC) $(CFLAGS) untic.c -o untic X Xlint: X lint untic.c X Xinstall: untic X cp untic $(DESTDIR)/untic X strip $(DESTDIR)/untic X cp untic.1 $(DOCDIR)/untic.1 X Xclean: X rm untic SHAR_EOF if test 254 -ne "`wc -c < 'Makefile'`" then echo shar: error transmitting "'Makefile'" '(should have been 254 characters)' fi fi if test -f 'README' then echo shar: will not over-write existing file "'README'" else echo extracting "'README'" sed 's/^X//' >README <<'SHAR_EOF' Xuntic -- Decompile a "terminfo" terminal description file for System V. X XI wrote the following program, "untic", because I needed to make a terminal Xdescription file which was just slightly different from one of the existing Xterminal descriptions. X XThis program looks up the description directly from the compiled description Xfile. Thus it produces a file, which when compiled, generated exactly the Xsame information as was in the original file. X XThis "shar" file contains the following files: X README This file X untic.1 A (very simple) manual page X Makefile A (very simple) make file X untic.c The program X XI hope this program is of some use to people. X X Dave Regan X 21 May 1986 X PO Box 601 X Corvallis OR 97339 X hplabs!hp-pcd!orstcs!regan (I think) SHAR_EOF if test 763 -ne "`wc -c < 'README'`" then echo shar: error transmitting "'README'" '(should have been 763 characters)' fi fi if test -f 'untic.1' then echo shar: will not over-write existing file "'untic.1'" else echo extracting "'untic.1'" sed 's/^X//' >untic.1 <<'SHAR_EOF' X.TH UNTIC 1 Public Domain X.SH NAME Xuntic \- Uncompile terminfo terminal description files X.SH SYNOPSIS X.B untic X.B terminal_name X[ X.B . . . X] X.SH DESCRIPTION X.B untic Xconvert the terminfo file which corresponds to the specified terminal name Xinto a file that can be processed by X.B tic. X.PP XIf multiple terminal names are given, a terminal description is generated Xfor each of the named terminals. XThe output is written on standard output. X.PP XIt is wise to backup the original terminal description X(from /usr/lib/terminfo) Xbefore compiling the generated file. X.SH EXAMPLES XTo uncompile the terminal description for a "vt100", type: X.RS Xuntic vt100 >vt100 X.RE XTo compile this generated file, you probably need root permissions and type: X.RS Xtic vt100 X.RE X.SH NOTES XIf new capabilities are added to the terminfo database, Xthe X.B untic Xprogram will need to be modified. XWith luck, the new entries will go at the end of the appropriate tables. X.PP XMost of the capabilities are in the tables in the order that the capabilites Xare documented. XThere are a few exceptions in the string variables. X.PP XThis program is placed into the public domain. XThat means that you can do anything you want to with it. X.SH BUGS XNone known, but . . . X.SH FILES XThe terminal descriptions are stored in X.B /usr/lib/terminfo/?/* SHAR_EOF if test 1304 -ne "`wc -c < 'untic.1'`" then echo shar: error transmitting "'untic.1'" '(should have been 1304 characters)' fi fi if test -f 'untic.c' then echo shar: will not over-write existing file "'untic.c'" else echo extracting "'untic.c'" sed 's/^X//' >untic.c <<'SHAR_EOF' X/* X * Untic.c -- Uncompile a terminfo file X * X * Usage: X * untic terminal_name . . . X * X * This program finds the terminal description in X * /usr/lib/terminfo/?/terminal_name X * It then converts the information into an ASCII file suitable for X * running into "tic". The resulting file is written to standard output. X * X * Compile by: X * cc -O -o untic untic.c X * X * It is probably a good idea to ensure that the file produced will compile X * to the original file before trusting "untic". X * X * Structure of terminfo file: X * short magic number X * short length of terminal names + NUL X * short length of booleans X * short length of numerics X * short length of strings X * short length of string table X * chars NUL terminated terminal name X * chars boolean flags for each of the possible booleans X * shorts values for each of the possible numerics X * shorts offsets (from start of strings) for each of the X * possible strings X * chars NUL terminated strings for each of the defined strings X * X * Most of the variables are in the order that the documentation lists X * them. This is important, as the information is stored in the file X * based upon the ordinal position of the variable. Some of the string X * variables are not in order. Presumably, if they add more variables, X * it will be to the end of the list, and not in the middle. X * X * This has been tested on X * Plexus P20 (M68010), System 5 Release 2 (I think) X * X * Bugs: X * The longest string capability is limited to 4096 bytes. If a longer X * string is encountered, the program will do unpredicatable things. X * (Who uses strings that long anyway?) The longest that the terminfo X * file can be is 4096 bytes anyway, so this isn't too big a problem. X * X * Credits: X * Written by Dave Regan X * orstcs!regan X * 16 May 86 X * X * I disclaim that this program does anything useful. It might also X * do accidental damage. Backup your original terminfo files. X * X * This program is public domain. That means you can do anything X * you want with it. X */ X X X#include <stdio.h> X#ifdef QC X#define OPEN_MODE "rb" /* Mode used to open terminfo files */ X#define void int /* Sigh . . . */ X#else /* QC */ X#include <ctype.h> X#define OPEN_MODE "r" /* Mode used to open terminfo files */ X#endif /* QC */ X#ifndef TRUE X#define TRUE 1 X#define FALSE 0 X#endif /* TRUE */ X X#define DEBUG FALSE /* TRUE/FALSE to enable debugging output */ X X#ifdef BSD X#define TERMINFO_DIR "/usr/static/sys5r2v2/usr/lib/terminfo" X#endif /* BSD */ X#ifndef TERMINFO_DIR X#define TERMINFO_DIR "/usr/lib/terminfo" X#endif /* TERMINFO_DIR */ X X X#define MAGIC 0x011A /* Terminfo magic number */ X#define MAXLINE 65 /* Longest emited line */ X#define MAX_CAP 4096 /* Longest single capability */ X Xextern char *strcpy(); X Xint line_len; /* Current length of line */ X Xmain(argc, argv) X int argc; /* Number of paramters */ X char *argv[]; /* The parameters themselves */ X { X char subdir[2]; /* Subdirectory name */ X FILE *file; X extern FILE *fopen(); X X#ifdef CPM X wildexp(&argc, &argv); X#endif /* CPM */ X X /* Change directory to the working directory */ X (void)chdir(TERMINFO_DIR); X X /* Go through the arguments */ X subdir[1] = '\0'; X if (argc == 1) X convert(stdin, "stdin"); X else X { X while (--argc) X { X ++argv; X subdir[0] = argv[0][0]; X (void)chdir(subdir); X if ((file = fopen(*argv, OPEN_MODE)) == NULL) X { X perror(*argv); X } X else X { X convert(file, *argv); X (void)fclose(file); X } X (void)chdir(".."); X } X } X } X X X/* X * Addchar -- Add a character X */ Xchar * Xaddchar(cptr, ch) X char *cptr; X int ch; X { X char *addstr(), *addoctal(); X X if (ch == 0x1B) X return (addstr(cptr, "\\E")); X if (ch == '\n') X return (addstr(cptr, "\\n")); X if (ch == '\r') X return (addstr(cptr, "\\r")); X if (ch == '\t') X return (addstr(cptr, "\\t")); X if (ch == '\b') X return (addstr(cptr, "\\b")); X if (ch == '\f') X return (addstr(cptr, "\\f")); X if (ch == ' ') X return (addstr(cptr, "\\s")); X if (ch == '^') X return (addstr(cptr, "\\^")); X if (ch == '\\') X return (addstr(cptr, "\\\\")); X if (ch == ',') X return (addstr(cptr, "\\,")); X if (ch == ':') X return (addstr(cptr, "\\:")); X if (ch >= ('A' - '@') && ch <= ('Z' - '@')) X { X *cptr++ = '^'; X *cptr++ = ch + '@'; X return (cptr); X } X#ifdef notdef X /* X * Did you know that \r \n \f \t are NOT control characters X * as defined by "iscntrl" under BSD 4.2? I find that X * rather odd. X */ X#endif /* notdef */ X if (iscntrl(ch) || isspace(ch) || ch > 0x7F) X return (addoctal(cptr, ch)); X *cptr++ = ch; X return (cptr); X } X X X/* X * Addoctal -- Add an octal character X * X * Use sprintf just in case "0" through "7" are not contiguous. Some X * machines are weird. X */ Xchar * Xaddoctal(cptr, ch) X char *cptr; X int ch; X { X char *addstr(); X X ch &= 0xFF; X X if (ch == 0x80) X return (addstr(cptr, "\\0")); X (void)sprintf(cptr, "\\%03o", ch); X while (*cptr != '\0') X cptr++; X return (cptr); X } X X X/* X * Addstr -- Add a string to the capability X */ Xchar * Xaddstr(cptr, str) X char *cptr, *str; X { X while (*str) X *cptr++ = *str++; X return (cptr); X } X X X/* X * Convert -- Do the actual conversion X */ Xconvert(file, name) X FILE *file; /* The file with the compiled information */ X char *name; /* Printable version of the filename */ X { X int ch, val, i, j, fail; X int name_length, bool_length, num_length, str_length, s_length; X char capability[MAX_CAP+1], *cptr, *addchar(); X X static char *booleans[] = /* Names of boolean variables, in order */ X { "bw", "am", "xsb", "xhp", "xenl", "eo", "gn", "hc", "km", X "hs", "in", "da", "db", "mir", "msgr", "os", "eslok", "xt", X "hz", "ul", "xon" }; X static char *numerics[] = /* Names of numeric variables, in order */ X { "cols", "it", "lines", "lm", "xmc", "pb", "vt", "wsl" }; X static char *strings[] = /* Names of string variables, not in strict X order. Makes things a little harder */ X { "cbt", "bel", "cr", "csr", "tbc", "clear", "el", "ed", "hpa", X "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup", X "cnorm", "cuf1", "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl", X "hd", "smacs", "blink", "bold", "smcup", "smdc", "dim", "smir", X "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", X "rmcup", "rmdc", "rmir", "rmso", "rmul", "flash", "ff", "fsl", X "is1", "is2", "is3", "if", "ich1", "il1", "ip", "kbs", "ktbc", X "kclr", "kctab", "kdch1", "kdl1", "kcud1", "krmir", "kel", "ked", X "kf0", "kf1", "kf10", "kf2", "kf3", "kf4", "kf5", "kf6", "kf7", X "kf8", "kf9", "khome", "kich1", "kil1", "kcub1", "kll", "knp", X "kpp", "kcuf1", "kind", "kri", "khts", "kcuu1", "rmkx", "smkx", X "lf0", "lf1", "lf10", "lf2", "lf3", "lf4", "lf5", "lf6", "lf7", X "lf8", "lf9", "rmm", "smm", "nel", "pad", "dch", "dl", "cud", X "ich", "indn", "il", "cub", "cuf", "rin", "cuu", "pfkey", "pfloc", X "pfx", "mc0", "mc4", "mc5", "rep", "rs1", "rs2", "rs3", "rf", X "rc", "vpa", "sc", "ind", "ri", "sgr", "hts", "wind", "ht", "tsl", X "uc", "hu", "iprog", "ka1", "ka3", "kb2", "kc1", "kc3", "mc5p" X#ifdef HPUX5 X , "meml", "memu" X#endif X }; X int str_cap[sizeof(strings) / sizeof(char *)]; X X /* Check the magic number out */ X if (get2(file) != MAGIC) X { X fprintf(stderr, "\"%s\" is not a terminfo file\n", name); X return; X } X X /* Get the rest of the header information */ X name_length = get2(file); /* Get the length of the terminal names */ X bool_length = get2(file); /* Get the length of the booleans */ X num_length = get2(file); /* Get the length of the numerics */ X str_length = get2(file); /* Get the length of the strings */ X s_length = get2(file); /* Get the length of the string tables */ X X /* Check for too many data items */ X fail = FALSE; X if (bool_length > (sizeof(booleans) / sizeof(char *))) X { X fprintf(stderr, "Boolean variables have been added to terminfo.\n"); X fail = TRUE; X } X if (num_length > (sizeof(numerics) / sizeof(char *))) X { X fprintf(stderr, "Numeric variables have been added to terminfo.\n"); X fail = TRUE; X } X if (str_length > (sizeof(strings) / sizeof(char *))) X { X fprintf(stderr, "String variables have been added to terminfo.\n"); X fail = TRUE; X } X if (fail) X { X fprintf(stderr, X"Update the \"untic\" program. Use \"xxx\" if needed. Good luck.\n"); X return; X } X X /* Time to get real information */ X while ((ch = getc(file)) != '\0' && ch != EOF) X putchar(ch); X printf(",\n\t"); X X /* Send out the non-null boolean variables */ X line_len = 0; X for (i = 0; i < bool_length; i++) X { X if ((ch = getc(file)) != 0) X emit(booleans[i]); X } X X /* The rest of the file is on a 16 bit boundary, so adjust the file */ X if ((name_length + bool_length) & 0x01) X (void)getc(file); X X /* Get the numeric variables */ X for (i = 0; i < num_length; i++) X { X if ((val = get2(file)) != 0xFFFF) X { X (void)sprintf(capability, "%s#%d", numerics[i], val); X emit(capability); X } X } X X /* Get the string variables offsets */ X for (i = 0; i < str_length; i++) X str_cap[i] = get2(file); X X /* Get the string variables themselves */ X for (i = 0; i < s_length; i++) X { X for (j = 0; j < str_length; j++) /* Find the name */ X if (str_cap[j] == i) X break; X#if DEBUG X if (j >= str_length) X fprintf(stderr, "Cannot find address %d\n", i); X#endif /* DEBUG */ X (void)strcpy(capability, strings[j]); X cptr = &capability[strlen(capability)]; X *cptr++ = '='; X for (; (ch = getc(file)) != '\0' && ch != EOF; i++) X cptr = addchar(cptr, ch); X *cptr = '\0'; X emit(capability); X } X X printf("\n\n"); X } X X X/* X * Emit -- Emit the string X * X * Emit the given string, and append a comma. If the line gets too long, X * send out a newline and a tab. X */ Xemit(str) X char *str; /* String to emit */ X { X if ((line_len += strlen(str) + 2) > MAXLINE) X { X line_len = strlen(str) + 2; X printf("\n\t"); X } X printf("%s, ", str); X } X X X/* X * Get2 -- Get a two byte number X */ Xget2(file) X FILE *file; /* The file with the compiled information */ X { X short temp; X X temp = getc(file) & 0xFF; X return (temp + (getc(file) << 8)); X } X X X#ifdef CPM Xchdir(str) X char *str; X { X } X Xperror(str) X char *str; X { X fprintf(stderr, "Cannot open \"%s\"\n", str); X } X#endif /* CPM */ SHAR_EOF if test 10385 -ne "`wc -c < 'untic.c'`" then echo shar: error transmitting "'untic.c'" '(should have been 10385 characters)' fi fi # end of shell archive exit 0 -- Mark H. Colburn UUCP: ihnp4!meccts!ems!mark EMS/McGraw-Hill ATT: (612) 829-8200 9855 West 78th Street Eden Prairie, MN 55344