112044Slayer #ifndef LINT 2*12461Slayer static char *sccsid="@(#)showtc.c 1.5 (Berkeley) 05/15/83"; 312044Slayer #endif 412044Slayer 512031Slayer /* 612031Slayer ** show termcap entries 712031Slayer ** 812031Slayer ** where: 912458Slayer ** -D look for duplicate names and print termcap file 1012031Slayer ** -S sort entries before display 1112458Slayer ** -T trace (-DDEBUG only) 1212044Slayer ** -b show bare entries 1312458Slayer ** -d -D and stop 1412044Slayer ** -f following arg is FULL PATHNAME of termcap file 1512044Slayer ** -g sort on generic names 1612044Slayer ** -s don't print two char name at the front of every line 1712044Slayer ** -x expand tc= capabilities 1812031Slayer ** [ent] display specific entry. tc= will be expanded. 1912031Slayer ** 2012031Slayer ** David L. Wasley, U.C.Berkeley 2112446Slayer ** Kevin Layer: modified for 4.1c and misc changes. 2212446Slayer ** Kevin Layer: added the printing of terminal capabilities 2312446Slayer ** in `human' readable form (like that in "man 5 termcap"). 2412031Slayer */ 2512031Slayer 2612031Slayer #include <stdio.h> 2712031Slayer #include <sys/file.h> 2812031Slayer #include <ctype.h> 2912031Slayer #include <sys/types.h> 3012031Slayer #include <sys/stat.h> 3112031Slayer 3212031Slayer #define NO 0 3312031Slayer #define YES 1 3412031Slayer #define CNULL '\0' 3512031Slayer #define NOENTRIES 1024 3612044Slayer #define USAGE "usage: %s [-Sxdngb] [-f termcapfile] [entry] ...\n" 3712031Slayer 3812031Slayer struct TcName { 3912031Slayer char name_buf[124]; 4012031Slayer long file_pos; 4112031Slayer } tcNames[NOENTRIES]; 4212031Slayer 43*12461Slayer #define NOCAPS 97 4412446Slayer 4512446Slayer struct Caps { 4612446Slayer char *cap; 4712446Slayer char *desc; 4812446Slayer } capList[NOCAPS] = 4912446Slayer { 5012446Slayer "ae", "End alternate character set", 5112446Slayer "al", "Add new blank line", 5212446Slayer "am", "Has automatic margins", 5312446Slayer "as", "Start alternate character set", 5412446Slayer "bc", "Backspace if not ^H", 5512446Slayer "bs", "Can backspace with ^H", 5612446Slayer "bt", "Back tab", 5712446Slayer "bw", "Backspace wraps from col 0 to last col", 5812446Slayer "CC", "Command char in prototype if settable", 5912446Slayer "cd", "Clear to end of display", 6012446Slayer "ce", "Clear to end of line", 6112446Slayer "ch", "Like cm, but horizontal motion only", 6212446Slayer "cl", "Clear screen", 6312446Slayer "cm", "Cursor motion", 6412446Slayer "co", "Number of columns in a line", 6512446Slayer "cr", "Carriage return, (default ^M)", 6612446Slayer "cs", "Change scrolling region (vt100), like cm", 6712446Slayer "cv", "Like ch but vertical only.", 6812446Slayer "da", "Display may be retained above", 6912446Slayer "dB", "Number of millisec of bs delay needed", 7012446Slayer "db", "Display may be retained below", 7112446Slayer "dC", "Number of millisec of cr delay needed", 7212446Slayer "dc", "Delete character", 7312446Slayer "dF", "Number of millisec of ff delay needed", 7412446Slayer "dl", "Delete line", 7512446Slayer "dm", "Start Delete mode", 7612446Slayer "dN", "Number of millisec of nl delay needed", 7712446Slayer "do", "Down one line", 78*12461Slayer "ds", "Disable status display", 7912446Slayer "dT", "Number of millisec of tab delay needed", 8012446Slayer "ed", "End delete mode", 8112446Slayer "ei", "End insert mode;give \":ei=:\" if ic", 8212446Slayer "eo", "Can erase overstrikes with a blank", 83*12461Slayer "es", "Escape seq's ok on status line", 8412446Slayer "ff", "Hardcopy page eject (default ^L)", 8512446Slayer "fs", "From status line sequence", 8612446Slayer "hc", "Hardcopy terminal", 8712446Slayer "hd", "Half-line down (forward 1/2 lf)", 8812446Slayer "ho", "Home cursor (if no cm)", 8912446Slayer "hs", "Has 25th status line", 9012446Slayer "hu", "Half-line up (reverse 1/2 lf)", 9112446Slayer "hz", "Hazeltine; can't print ~'s", 9212446Slayer "ic", "Insert character", 9312446Slayer "if", "Name of file containing is", 9412446Slayer "im", "Start insert mode;give \":im=:\" if ic", 9512446Slayer "in", "Insert mode distinguishes nulls on display", 9612446Slayer "ip", "Insert pad after character inserted", 9712446Slayer "is", "Initialization string", 98*12461Slayer "i2", "Initialization string (used by sysline(1))", 9912446Slayer "kb", "Sent by backspace key", 10012446Slayer "kd", "Sent down arrow key", 10112446Slayer "ke", "Out of \"keypad transmit\" mode", 10212446Slayer "kh", "Sent by home key", 10312446Slayer "kl", "Sent by left arrow key", 10412446Slayer "kn", "Number of \"other\" keys", 10512446Slayer "ko", "Tc entries for other non-function keys", 10612446Slayer "kr", "Sent by right arrow key", 10712446Slayer "ks", "Put in \"keypad transmit\" mode", 10812446Slayer "ku", "Sent by up arrow key", 10912446Slayer "li", "Number of lines on screen or page", 11012446Slayer "ll", "Last line, first column (if no cm)", 11112446Slayer "ma", "Arrow key map, used by vi V2 only", 11212446Slayer "mi", "Safe to move while in insert mode", 11312446Slayer "ml", "Memory lock on above cursor.", 11412446Slayer "ms", "Ok to move while in standout/underline mode", 11512446Slayer "mu", "Memory unlock (turn off memory lock).", 11612446Slayer "nc", "No working CR (DM2500,H2000)", 11712446Slayer "nd", "Non-destructive space (cursor right)", 11812446Slayer "nl", "Newline character (default \\n)", 11912446Slayer "ns", "Is a CRT but doesn't scroll.", 12012446Slayer "os", "Terminal overstrikes", 12112446Slayer "pc", "Pad character (rather than null)", 12212446Slayer "pt", "Has hardware tabs (may need to use is)", 12312446Slayer "se", "End stand out mode", 12412446Slayer "sf", "Scroll forwards", 12512446Slayer "sg", "Number of blank chars left by so/se", 12612446Slayer "so", "Begin stand out mode", 12712446Slayer "sr", "Scroll reverse (backwards)", 12812446Slayer "ta", "Tab (other than ^I or with padding)", 12912446Slayer "tc", "Entry of similar terminal - must be last", 13012446Slayer "te", "String to end programs that use cm", 13112446Slayer "ti", "String to begin programs that use cm", 13212446Slayer "ts", "To status line sequence", 13312446Slayer "uc", "Underscore one char and move past it", 13412446Slayer "ue", "End underscore mode", 13512446Slayer "ug", "Number of blank chars left by us or ue", 13612446Slayer "ul", "Underlines, though no overstrike", 13712446Slayer "up", "Upline (cursor up)", 13812446Slayer "us", "Start underscore mode", 13912446Slayer "vb", "Visible bell (may not move cursor)", 14012446Slayer "ve", "Sequence to end open/visual mode", 14112446Slayer "vs", "Sequence to start open/visual mode", 14212446Slayer "xb", "Beehive (f1=escape, f2=ctrl C)", 14312446Slayer "xn", "A newline is ignored after a wrap (Concept)", 14412446Slayer "xr", "Return acts like ce \\r \\n (Delta Data)", 14512446Slayer "xs", "Standout not erased by writing over it (HP 264?)", 14612446Slayer "xt", "Destructive tabs, magic so char (Teleray 1061)" 14712446Slayer }; 14812446Slayer 14912031Slayer #ifdef DEBUG 15012031Slayer int Dflag = NO; 15112031Slayer #endif 15212031Slayer int xflag = NO; 15312044Slayer int Sflag = YES; 15412044Slayer int sflag = NO; 15512031Slayer int dflag = NO; 15612031Slayer int nflag = NO; 15712031Slayer int gflag = NO; 15812031Slayer int bflag = NO; 15912031Slayer int tc_loopc; /* loop counter */ 16012031Slayer char *tcfile; /* termcap database pathname */ 16112031Slayer char tcbuf[1024]; /* buffer for termcap description */ 16212031Slayer char *lastchar(); 16312031Slayer int name_cmp(); 16412031Slayer int ent_cmp(); 16512031Slayer struct TcName *find_name(); 16612031Slayer char *getenv(); 16712031Slayer char *ctime(); 16812031Slayer char *strncpy(); 16912031Slayer long ftell(); 17012031Slayer 17112031Slayer main(argc, argv, envp) 17212031Slayer int argc; 17312031Slayer char **argv; 17412031Slayer char **envp; 17512031Slayer { 17612031Slayer char *av; 17712031Slayer struct TcName *tn; 17812031Slayer register char *bp; 17912031Slayer long pos; 18012031Slayer int n; 18112031Slayer struct stat st; 18212031Slayer char envbuf[256]; 18312031Slayer FILE *tcfp; 18412031Slayer 18512031Slayer if ((bp = getenv("TERMCAP")) && *bp == '/') 18612031Slayer tcfile = bp; 18712031Slayer else 18812031Slayer tcfile = "/etc/termcap"; 18912031Slayer 19012031Slayer while (--argc > 0) 19112031Slayer { 19212031Slayer if (*(av = *++argv) == '-') 19312031Slayer { 19412031Slayer while (*++av) 19512031Slayer { 19612031Slayer switch (*av) 19712031Slayer { 19812031Slayer /* use alternate termcap file */ 19912031Slayer case 'f': 20012031Slayer if (argc-- <= 0) 20112031Slayer { 20212031Slayer fprintf(stderr, 20312031Slayer "-f needs a filename\n"); 20412031Slayer exit(1); 20512031Slayer } 20612031Slayer tcfile = *++argv; 20712031Slayer break; 20812031Slayer 20912031Slayer /* only check for dup names */ 21012458Slayer case 'd': 21112031Slayer nflag = YES; 21212031Slayer /* fall thru */ 21312031Slayer 21412031Slayer /* look for duplicated names */ 21512458Slayer case 'D': 21612031Slayer dflag = YES; 21712031Slayer continue; 21812031Slayer 21912044Slayer /* strip the two name off */ 22012044Slayer case 's': 22112044Slayer sflag = YES; 22212044Slayer continue; 22312044Slayer 22412031Slayer /* sort the name array */ 22512031Slayer case 'S': 22612044Slayer Sflag = NO; 22712031Slayer continue; 22812031Slayer 22912031Slayer #ifdef DEBUG 23012458Slayer case 'T': 23112031Slayer Dflag = YES; 23212031Slayer continue; 23312031Slayer #endif 23412031Slayer 23512031Slayer /* sort on generic names */ 23612031Slayer case 'g': 23712031Slayer gflag = YES; 23812031Slayer continue; 23912031Slayer 24012031Slayer /* expand entries in 'full mode' */ 24112031Slayer case 'x': 24212031Slayer xflag = YES; 24312031Slayer continue; 24412031Slayer 24512031Slayer /* show bare entry */ 24612031Slayer case 'b': 24712031Slayer bflag = YES; 24812031Slayer continue; 24912031Slayer 25012031Slayer default: 25112031Slayer fprintf(stderr, "showtc: unknown flag: -%c\n", *av); 25212031Slayer fprintf(stderr, USAGE, argv[0]); 25312031Slayer exit(1); 25412031Slayer } 25512031Slayer } 25612031Slayer } 25712031Slayer else 25812031Slayer break; 25912031Slayer } 26012031Slayer 26112031Slayer /* 26212031Slayer * insert the specified TERMCAP file into the environment 26312031Slayer */ 26412031Slayer (void) sprintf(envbuf, "TERMCAP=%s", tcfile); 26512031Slayer while (*envp) 26612031Slayer { 26712031Slayer if (strncmp(*envp, "TERMCAP=", 8) == 0) 26812031Slayer { 26912031Slayer *envp = envbuf; 27012031Slayer break; 27112031Slayer } 27212031Slayer envp++; 27312031Slayer } 27412031Slayer if (! *envp) 27512031Slayer *envp = envbuf; /* this may be dangerous */ 27612031Slayer 27712031Slayer /* 27812031Slayer ** if user specified type(s), do only those 27912031Slayer */ 28012031Slayer if (argc > 0) 28112031Slayer { 28212031Slayer /* 28312031Slayer ** look for the users specified term types 28412031Slayer */ 28512031Slayer while (argc > 0) 28612031Slayer { 28712031Slayer switch (n = tgetent(tcbuf, *argv)) 28812031Slayer { 28912031Slayer case 1: 29012031Slayer if (bflag) 29112031Slayer (void) prnt_raw(tcbuf); 29212031Slayer else 29312031Slayer (void) prnt_ent(tcbuf); 29412031Slayer break; 29512031Slayer 29612031Slayer case 0: 29712031Slayer fprintf(stderr, 29812031Slayer "showtc: bad entry: %s\n", *argv); 29912031Slayer break; 30012031Slayer 30112031Slayer case -1: 30212031Slayer fputs("showtc: ", stderr); 30312031Slayer perror(tcfile); 30412031Slayer exit(1); 30512031Slayer 30612031Slayer default: 30712031Slayer fprintf(stderr, "bad return from tgetent: %d\n", n); 30812031Slayer exit(1); 30912031Slayer } 31012031Slayer argc--; 31112031Slayer argv++; 31212031Slayer } 31312031Slayer exit(0); 31412031Slayer } 31512031Slayer 31612031Slayer if (bflag) 31712031Slayer { 31812031Slayer fprintf(stderr, "showtc: -b flag with no entries makes no sense.\n"); 31912031Slayer exit(1); 32012031Slayer } 32112031Slayer 32212031Slayer 32312031Slayer /* 32412031Slayer ** if no type was specified, do the whole file 32512031Slayer */ 32612031Slayer if ((tcfp = fopen(tcfile, "r")) == NULL) 32712031Slayer { 32812031Slayer perror(tcfile); 32912031Slayer exit(1); 33012031Slayer } 33112031Slayer 33212031Slayer /* 33312031Slayer ** identify database, for the record 33412031Slayer */ 33512031Slayer if (stat(tcfile, &st)) 33612031Slayer { 33712031Slayer perror(tcfile); 33812031Slayer exit(1); 33912031Slayer } 34012031Slayer printf("File: %s, last modified: %s\n", tcfile, ctime(&st.st_mtime)); 34112031Slayer 34212031Slayer 34312031Slayer /* 34412031Slayer ** build termcap entry table 34512031Slayer */ 34612031Slayer tn = tcNames; 34712031Slayer pos = ftell(tcfp); 34812031Slayer bp = tcbuf; 34912031Slayer while (fgets(bp, sizeof (tcbuf), tcfp) != NULL) 35012031Slayer { 35112031Slayer if (tcbuf[0] == '#') 35212031Slayer { 35312031Slayer pos = ftell(tcfp); 35412031Slayer bp = tcbuf; 35512031Slayer continue; 35612031Slayer } 35712031Slayer 35812031Slayer tn->file_pos = pos; 35912031Slayer 36012031Slayer /* 36112031Slayer ** get full entry 36212031Slayer */ 36312031Slayer while (*(bp = lastchar(bp)) == '\\' && fgets(bp, (sizeof tcbuf) - (bp - tcbuf), tcfp)) 36412031Slayer ; 36512031Slayer /* 36612031Slayer ** save the names 36712031Slayer */ 36812031Slayer for (bp = tcbuf; *bp && *bp != ':'; bp++) 36912031Slayer ; 37012031Slayer *bp = '\0'; 37112031Slayer (void) strncpy(tn->name_buf, tcbuf, 37212031Slayer sizeof tcNames[0].name_buf); 37312031Slayer 37412031Slayer pos = ftell(tcfp); 37512031Slayer bp = tcbuf; 37612031Slayer tn++; 37712031Slayer } 37812031Slayer tn->file_pos = -1; 37912031Slayer 38012031Slayer /* 38112031Slayer ** Look for duplicate names 38212031Slayer */ 38312031Slayer if (dflag) 38412031Slayer check_dup(); 38512031Slayer if (nflag) 38612031Slayer exit(0); 38712031Slayer 38812031Slayer #ifdef DEBUG 38912031Slayer if (Dflag) 39012031Slayer { 39112031Slayer for (tn = tcNames; tn->file_pos >= 0; tn++) 39212031Slayer { 39312031Slayer printf("Entry #%d:\n\t%s\n\tfile_pos = %ld\n", 39412031Slayer tn - tcNames, tn->name_buf, tn->file_pos); 39512031Slayer } 39612031Slayer exit(0); 39712031Slayer } 39812031Slayer #endif 39912031Slayer 40012031Slayer /* 40112031Slayer ** Order the list 40212031Slayer */ 40312044Slayer if (Sflag) 40412031Slayer qsort((char *)tcNames, tn - tcNames, 40512031Slayer sizeof (struct TcName), name_cmp); 40612031Slayer 40712031Slayer /* 40812031Slayer ** List termcap entry for each name in table 40912031Slayer */ 41012031Slayer for (tn = tcNames; tn->file_pos >= 0; tn++) 41112031Slayer { 41212031Slayer tc_loopc = 0; 41312031Slayer /*** working toward this ... 41412031Slayer (void) prnt_ent(tn); 41512031Slayer ***/ 41612031Slayer (void) fseek(tcfp, tn->file_pos, 0); 41712031Slayer bp = tcbuf; 41812031Slayer while (fgets(bp, (sizeof tcbuf) - (bp - tcbuf), tcfp) 41912031Slayer && *(bp = lastchar(bp)) == '\\') 42012031Slayer ; 42112031Slayer (void) prnt_ent(tcbuf); 42212031Slayer } 42312031Slayer } 42412031Slayer 42512031Slayer char * 42612031Slayer lastchar(b) 42712031Slayer char *b; 42812031Slayer { 42912031Slayer register char *p; 43012031Slayer 43112031Slayer p = b + strlen(b) - 1; 43212031Slayer while (*p == '\n' || *p == ' ') 43312031Slayer p--; 43412031Slayer return(p); 43512031Slayer } 43612031Slayer 43712031Slayer name_cmp(a, b) 43812031Slayer char *a, *b; 43912031Slayer { 44012031Slayer if (gflag) /* sort on generic names */ 44112031Slayer { 44212031Slayer a += 3; 44312031Slayer b += 3; 44412031Slayer while (*a && *b && *a != '|' && *a == *b) 44512031Slayer { 44612031Slayer a++; 44712031Slayer b++; 44812031Slayer } 44912031Slayer if (*a == '|' || *a == CNULL) 45012031Slayer return((*b == '|' || *b == CNULL)? 0:-1); 45112031Slayer if (*b == '|' || *b == CNULL) 45212031Slayer return(1); 45312031Slayer return(*a - *b); 45412031Slayer } 45512031Slayer return(strncmp(a, b, 2)); 45612031Slayer } 45712031Slayer 45812031Slayer prnt_ent(buf) 45912031Slayer register char *buf; 46012031Slayer { 46112031Slayer register char *name; 46212446Slayer char *getdesc(); 46312031Slayer char *caps[256]; 46412031Slayer register char **cp; 46512031Slayer register char **tp; 46612031Slayer char tname[3]; 46712031Slayer 46812031Slayer cp = caps; 46912031Slayer name = buf; 47012031Slayer tname[3] = '\0'; 47112031Slayer 47212031Slayer while (*buf) 47312031Slayer { 47412031Slayer switch (*buf) 47512031Slayer { 47612031Slayer case ':': 47712031Slayer *buf++ = '\0'; 47812031Slayer while (*buf && !isalnum(*buf)) 47912031Slayer buf++; 48012031Slayer if (*buf) 48112031Slayer { 48212031Slayer /* 48312031Slayer * ignore duplicate cap entries 48412031Slayer */ 48512031Slayer for (tp = caps; tp < cp; tp++) 48612031Slayer if (strncmp(buf, *tp, 2) == 0) 48712031Slayer goto skip; 48812031Slayer *cp++ = buf; 48912031Slayer skip: 49012031Slayer /* 49112031Slayer * does user want tc= expanded? 49212031Slayer */ 49312031Slayer if (xflag && strncmp(buf, "tc=", 3) == 0) 49412031Slayer { 49512031Slayer /* 49612031Slayer * find end of tc= 49712031Slayer */ 49812031Slayer while (*buf != ':') 49912031Slayer buf++; 50012031Slayer *buf = '\0'; 50112031Slayer /* 50212031Slayer * save term name 50312031Slayer */ 50412031Slayer tname[0] = name[0]; 50512031Slayer tname[1] = name[1]; 50612031Slayer printf("%s: expanding %s\n", 50712031Slayer tname, cp[-1]); 50812031Slayer /* 50912031Slayer * let tgetent do the work 51012031Slayer */ 51112031Slayer tgetent(tcbuf, tname); 51212031Slayer prnt_ent(tcbuf); 51312031Slayer return; 51412031Slayer } 51512031Slayer } 51612031Slayer continue; 51712031Slayer 51812031Slayer case '|': 51912031Slayer *buf++ = ','; 52012031Slayer continue; 52112031Slayer 52212031Slayer default: 52312031Slayer buf++; 52412031Slayer } 52512031Slayer } 52612031Slayer *cp = CNULL; /* was (char *)0 */ 52712031Slayer 52812044Slayer if (Sflag) 52912031Slayer qsort((char *) caps, cp - caps, sizeof (char *), ent_cmp); 53012031Slayer 53112031Slayer printf("%s\n", name); 53212031Slayer for (cp = caps; *cp; cp++) 53312044Slayer if (sflag) 53412446Slayer printf("%-45s %s\n", getdesc(*cp), *cp); 53512044Slayer else 53612446Slayer { 53712446Slayer printf("%2.2s %-45s %s\n", name, getdesc(*cp), *cp); 53812446Slayer } 53912031Slayer (void) putchar('\n'); 54012031Slayer } 54112031Slayer 54212031Slayer prnt_raw(buf) 54312031Slayer char *buf; 54412031Slayer { 54512031Slayer register char *b; 54612031Slayer register int len; 54712031Slayer register int n; 54812031Slayer char *index(); 54912031Slayer 55012031Slayer len = 0; 55112031Slayer b = buf; 55212031Slayer while (*b) 55312031Slayer { 55412031Slayer if ((n = index(b, ':') - b + 1) <= 0) 55512031Slayer n = strlen(b); 55612031Slayer if (len == 0) /* first part */ 55712031Slayer { 55812031Slayer printf("%.*s\\\n\t:", n, b); 55912031Slayer len = 9 - n; 56012031Slayer } 56112031Slayer else 56212031Slayer { 56312031Slayer if ((len + n) >= 75) 56412031Slayer { 56512031Slayer printf("\\\n\t:"); 56612031Slayer len = 9; 56712031Slayer } 56812031Slayer printf("%.*s", n, b); 56912031Slayer } 57012031Slayer len += n; 57112031Slayer b += n; 57212031Slayer while (*b && index(" \t:\n", *b)) 57312031Slayer b++; 57412031Slayer } 57512031Slayer if (b[-1] != ':') 57612031Slayer (void) putchar(':'); 57712031Slayer (void) putchar('\n'); 57812031Slayer } 57912031Slayer 58012031Slayer ent_cmp(a, b) 58112031Slayer char **a, **b; 58212031Slayer { 58312031Slayer return(strncmp(*a, *b, 2)); 58412031Slayer } 58512031Slayer 58612031Slayer check_dup() 58712031Slayer { 58812031Slayer /* 58912031Slayer ** Look for duplicated names 59012031Slayer */ 59112031Slayer register char *p; 59212031Slayer register char *q; 59312031Slayer register struct TcName *tn; 59412031Slayer register struct TcName *tm; 59512031Slayer 59612031Slayer tn = tcNames; 59712031Slayer while (tn->file_pos >= 0) 59812031Slayer { 59912031Slayer p = q = tn->name_buf; 60012031Slayer while (*q) 60112031Slayer { 60212031Slayer while (*p && *p != '|') 60312031Slayer p++; 60412031Slayer if (p != q && (tm = find_name(q, tn + 1, p - q))) 60512031Slayer { 60612031Slayer fputs("Duplicate name: ", stdout); 60712031Slayer while (q != p) 60812031Slayer (void) putchar(*q++); 60912031Slayer (void) putchar('\n'); 61012031Slayer puts(tn->name_buf); 61112031Slayer puts(tm->name_buf); 61212031Slayer puts("---\n"); 61312031Slayer } 61412031Slayer if (*p == '|') 61512031Slayer p++; 61612031Slayer q = p; 61712031Slayer } 61812031Slayer tn++; 61912031Slayer } 62012031Slayer } 62112031Slayer 62212031Slayer struct TcName * 62312031Slayer find_name(name, tn, len) 62412031Slayer register char *name; 62512031Slayer register struct TcName *tn; 62612031Slayer register int len; 62712031Slayer { 62812031Slayer /* 62912031Slayer ** find name of length len in tcname structure buffers. 63012031Slayer */ 63112031Slayer register char *p; 63212031Slayer register char *buf; 63312031Slayer register int n; 63412031Slayer 63512031Slayer while (tn->file_pos >= 0) 63612031Slayer { 63712031Slayer buf = tn->name_buf; 63812031Slayer while (*buf) 63912031Slayer { 64012031Slayer p = name; 64112031Slayer n = len; 64212031Slayer if (*buf == '|') 64312031Slayer buf++; 64412031Slayer 64512031Slayer while (*buf && *buf != '|') 64612031Slayer { 64712031Slayer if (*p != *buf) 64812031Slayer { 64912031Slayer while (*buf && *buf != '|') 65012031Slayer buf++; 65112031Slayer break; 65212031Slayer } 65312031Slayer 65412031Slayer if (--n <= 0) 65512031Slayer { 65612031Slayer buf++; 65712031Slayer if (*buf == '|' || *buf == '\0') 65812031Slayer return(tn); 65912031Slayer while (*buf && *buf != '|') 66012031Slayer buf++; 66112031Slayer break; 66212031Slayer } 66312031Slayer buf++; 66412031Slayer p++; 66512031Slayer } 66612031Slayer } 66712031Slayer tn++; 66812031Slayer } 66912031Slayer return((struct TcName *)0); 67012031Slayer } 67112446Slayer 67212446Slayer char * 67312446Slayer getdesc(key) 67412446Slayer char *key; 67512446Slayer { 67612446Slayer register int i; 67712446Slayer 67812446Slayer for (i = 0; i <= NOCAPS; i++) 67912446Slayer if (strncmp(key, capList[i].cap, 2) == 0) 68012446Slayer return (capList[i].desc); 68112458Slayer return(""); 68212446Slayer } 683