Commit | Line | Data |
---|---|---|
977b5828 | 1 | #ifndef LINT |
2d9f9d8c | 2 | static char *sccsid="@(#)showtc.c 1.7 (Berkeley) %G%"; |
977b5828 KL |
3 | #endif |
4 | ||
551db654 KL |
5 | /* |
6 | ** show termcap entries | |
7 | ** | |
8 | ** where: | |
ba9c0f2e | 9 | ** -D look for duplicate names and print termcap file |
551db654 | 10 | ** -S sort entries before display |
ba9c0f2e | 11 | ** -T trace (-DDEBUG only) |
322eb279 | 12 | ** -U print unknown capabilities |
551db654 | 13 | ** -b show bare entries |
ba9c0f2e | 14 | ** -d -D and stop |
551db654 | 15 | ** -f following arg is FULL PATHNAME of termcap file |
977b5828 | 16 | ** -g sort on generic names |
977b5828 KL |
17 | ** -s don't print two char name at the front of every line |
18 | ** -x expand tc= capabilities | |
551db654 KL |
19 | ** [ent] display specific entry. tc= will be expanded. |
20 | ** | |
21 | ** David L. Wasley, U.C.Berkeley | |
0b733427 KL |
22 | ** Kevin Layer: modified for 4.1c and misc changes. |
23 | ** Kevin Layer: added the printing of terminal capabilities | |
24 | ** in `human' readable form (like that in "man 5 termcap"). | |
551db654 KL |
25 | */ |
26 | ||
551db654 KL |
27 | #include <stdio.h> |
28 | #include <sys/file.h> | |
29 | #include <ctype.h> | |
30 | #include <sys/types.h> | |
31 | #include <sys/stat.h> | |
32 | ||
33 | #define NO 0 | |
34 | #define YES 1 | |
35 | #define CNULL '\0' | |
36 | #define NOENTRIES 1024 | |
977b5828 | 37 | #define USAGE "usage: %s [-Sxdngb] [-f termcapfile] [entry] ...\n" |
551db654 KL |
38 | |
39 | struct TcName { | |
40 | char name_buf[124]; | |
41 | long file_pos; | |
42 | } tcNames[NOENTRIES]; | |
43 | ||
322eb279 | 44 | #define NOCAPS 105 |
0b733427 KL |
45 | |
46 | struct Caps { | |
47 | char *cap; | |
48 | char *desc; | |
49 | } capList[NOCAPS] = | |
50 | { | |
51 | "ae", "End alternate character set", | |
52 | "al", "Add new blank line", | |
53 | "am", "Has automatic margins", | |
54 | "as", "Start alternate character set", | |
55 | "bc", "Backspace if not ^H", | |
322eb279 | 56 | "bl", "Audible Bell", |
0b733427 KL |
57 | "bs", "Can backspace with ^H", |
58 | "bt", "Back tab", | |
59 | "bw", "Backspace wraps from col 0 to last col", | |
60 | "CC", "Command char in prototype if settable", | |
61 | "cd", "Clear to end of display", | |
62 | "ce", "Clear to end of line", | |
63 | "ch", "Like cm, but horizontal motion only", | |
64 | "cl", "Clear screen", | |
65 | "cm", "Cursor motion", | |
66 | "co", "Number of columns in a line", | |
67 | "cr", "Carriage return, (default ^M)", | |
68 | "cs", "Change scrolling region (vt100), like cm", | |
69 | "cv", "Like ch but vertical only.", | |
70 | "da", "Display may be retained above", | |
71 | "dB", "Number of millisec of bs delay needed", | |
72 | "db", "Display may be retained below", | |
73 | "dC", "Number of millisec of cr delay needed", | |
74 | "dc", "Delete character", | |
75 | "dF", "Number of millisec of ff delay needed", | |
76 | "dl", "Delete line", | |
77 | "dm", "Start Delete mode", | |
78 | "dN", "Number of millisec of nl delay needed", | |
79 | "do", "Down one line", | |
180b3e99 | 80 | "ds", "Disable status display", |
0b733427 KL |
81 | "dT", "Number of millisec of tab delay needed", |
82 | "ed", "End delete mode", | |
83 | "ei", "End insert mode;give \":ei=:\" if ic", | |
84 | "eo", "Can erase overstrikes with a blank", | |
180b3e99 | 85 | "es", "Escape seq's ok on status line", |
0b733427 KL |
86 | "ff", "Hardcopy page eject (default ^L)", |
87 | "fs", "From status line sequence", | |
88 | "hc", "Hardcopy terminal", | |
89 | "hd", "Half-line down (forward 1/2 lf)", | |
90 | "ho", "Home cursor (if no cm)", | |
91 | "hs", "Has 25th status line", | |
92 | "hu", "Half-line up (reverse 1/2 lf)", | |
93 | "hz", "Hazeltine; can't print ~'s", | |
94 | "ic", "Insert character", | |
95 | "if", "Name of file containing is", | |
96 | "im", "Start insert mode;give \":im=:\" if ic", | |
97 | "in", "Insert mode distinguishes nulls on display", | |
98 | "ip", "Insert pad after character inserted", | |
99 | "is", "Initialization string", | |
180b3e99 | 100 | "i2", "Initialization string (used by sysline(1))", |
0b733427 KL |
101 | "kb", "Sent by backspace key", |
102 | "kd", "Sent down arrow key", | |
103 | "ke", "Out of \"keypad transmit\" mode", | |
104 | "kh", "Sent by home key", | |
105 | "kl", "Sent by left arrow key", | |
106 | "kn", "Number of \"other\" keys", | |
107 | "ko", "Tc entries for other non-function keys", | |
108 | "kr", "Sent by right arrow key", | |
109 | "ks", "Put in \"keypad transmit\" mode", | |
110 | "ku", "Sent by up arrow key", | |
322eb279 | 111 | "le", "Move left", |
0b733427 KL |
112 | "li", "Number of lines on screen or page", |
113 | "ll", "Last line, first column (if no cm)", | |
114 | "ma", "Arrow key map, used by vi V2 only", | |
322eb279 KL |
115 | "mb", "Enter blinking mode", |
116 | "md", "Enter bold mode", | |
117 | "me", "Reset video attributes", | |
118 | "mh", "Enter halfbright mode", | |
0b733427 | 119 | "mi", "Safe to move while in insert mode", |
322eb279 | 120 | "mk", "Enter protected mode", |
0b733427 | 121 | "ml", "Memory lock on above cursor.", |
322eb279 | 122 | "mr", "Enter reverse video mode", |
0b733427 KL |
123 | "ms", "Ok to move while in standout/underline mode", |
124 | "mu", "Memory unlock (turn off memory lock).", | |
125 | "nc", "No working CR (DM2500,H2000)", | |
126 | "nd", "Non-destructive space (cursor right)", | |
127 | "nl", "Newline character (default \\n)", | |
128 | "ns", "Is a CRT but doesn't scroll.", | |
129 | "os", "Terminal overstrikes", | |
130 | "pc", "Pad character (rather than null)", | |
131 | "pt", "Has hardware tabs (may need to use is)", | |
132 | "se", "End stand out mode", | |
133 | "sf", "Scroll forwards", | |
134 | "sg", "Number of blank chars left by so/se", | |
135 | "so", "Begin stand out mode", | |
136 | "sr", "Scroll reverse (backwards)", | |
137 | "ta", "Tab (other than ^I or with padding)", | |
138 | "tc", "Entry of similar terminal - must be last", | |
139 | "te", "String to end programs that use cm", | |
140 | "ti", "String to begin programs that use cm", | |
141 | "ts", "To status line sequence", | |
142 | "uc", "Underscore one char and move past it", | |
143 | "ue", "End underscore mode", | |
144 | "ug", "Number of blank chars left by us or ue", | |
145 | "ul", "Underlines, though no overstrike", | |
146 | "up", "Upline (cursor up)", | |
147 | "us", "Start underscore mode", | |
148 | "vb", "Visible bell (may not move cursor)", | |
149 | "ve", "Sequence to end open/visual mode", | |
150 | "vs", "Sequence to start open/visual mode", | |
151 | "xb", "Beehive (f1=escape, f2=ctrl C)", | |
152 | "xn", "A newline is ignored after a wrap (Concept)", | |
153 | "xr", "Return acts like ce \\r \\n (Delta Data)", | |
154 | "xs", "Standout not erased by writing over it (HP 264?)", | |
155 | "xt", "Destructive tabs, magic so char (Teleray 1061)" | |
156 | }; | |
157 | ||
551db654 KL |
158 | #ifdef DEBUG |
159 | int Dflag = NO; | |
160 | #endif | |
161 | int xflag = NO; | |
977b5828 KL |
162 | int Sflag = YES; |
163 | int sflag = NO; | |
551db654 KL |
164 | int dflag = NO; |
165 | int nflag = NO; | |
166 | int gflag = NO; | |
167 | int bflag = NO; | |
322eb279 | 168 | int Uflag = NO; |
551db654 KL |
169 | int tc_loopc; /* loop counter */ |
170 | char *tcfile; /* termcap database pathname */ | |
2d9f9d8c | 171 | char tcbuf[2048]; /* buffer for termcap description */ |
551db654 KL |
172 | char *lastchar(); |
173 | int name_cmp(); | |
174 | int ent_cmp(); | |
175 | struct TcName *find_name(); | |
176 | char *getenv(); | |
177 | char *ctime(); | |
178 | char *strncpy(); | |
179 | long ftell(); | |
180 | ||
181 | main(argc, argv, envp) | |
182 | int argc; | |
183 | char **argv; | |
184 | char **envp; | |
185 | { | |
186 | char *av; | |
187 | struct TcName *tn; | |
188 | register char *bp; | |
189 | long pos; | |
190 | int n; | |
191 | struct stat st; | |
192 | char envbuf[256]; | |
193 | FILE *tcfp; | |
194 | ||
195 | if ((bp = getenv("TERMCAP")) && *bp == '/') | |
196 | tcfile = bp; | |
197 | else | |
198 | tcfile = "/etc/termcap"; | |
199 | ||
200 | while (--argc > 0) | |
201 | { | |
202 | if (*(av = *++argv) == '-') | |
203 | { | |
204 | while (*++av) | |
205 | { | |
206 | switch (*av) | |
207 | { | |
208 | /* use alternate termcap file */ | |
209 | case 'f': | |
210 | if (argc-- <= 0) | |
211 | { | |
212 | fprintf(stderr, | |
213 | "-f needs a filename\n"); | |
214 | exit(1); | |
215 | } | |
216 | tcfile = *++argv; | |
217 | break; | |
218 | ||
219 | /* only check for dup names */ | |
ba9c0f2e | 220 | case 'd': |
551db654 KL |
221 | nflag = YES; |
222 | /* fall thru */ | |
223 | ||
224 | /* look for duplicated names */ | |
ba9c0f2e | 225 | case 'D': |
551db654 KL |
226 | dflag = YES; |
227 | continue; | |
228 | ||
322eb279 KL |
229 | case 'U': |
230 | Uflag = YES; | |
231 | continue; | |
232 | ||
977b5828 KL |
233 | /* strip the two name off */ |
234 | case 's': | |
235 | sflag = YES; | |
236 | continue; | |
237 | ||
551db654 KL |
238 | /* sort the name array */ |
239 | case 'S': | |
977b5828 | 240 | Sflag = NO; |
551db654 KL |
241 | continue; |
242 | ||
243 | #ifdef DEBUG | |
ba9c0f2e | 244 | case 'T': |
551db654 KL |
245 | Dflag = YES; |
246 | continue; | |
247 | #endif | |
248 | ||
249 | /* sort on generic names */ | |
250 | case 'g': | |
251 | gflag = YES; | |
252 | continue; | |
253 | ||
254 | /* expand entries in 'full mode' */ | |
255 | case 'x': | |
256 | xflag = YES; | |
257 | continue; | |
258 | ||
259 | /* show bare entry */ | |
260 | case 'b': | |
261 | bflag = YES; | |
262 | continue; | |
263 | ||
264 | default: | |
265 | fprintf(stderr, "showtc: unknown flag: -%c\n", *av); | |
266 | fprintf(stderr, USAGE, argv[0]); | |
267 | exit(1); | |
268 | } | |
269 | } | |
270 | } | |
271 | else | |
272 | break; | |
273 | } | |
274 | ||
275 | /* | |
276 | * insert the specified TERMCAP file into the environment | |
277 | */ | |
278 | (void) sprintf(envbuf, "TERMCAP=%s", tcfile); | |
279 | while (*envp) | |
280 | { | |
281 | if (strncmp(*envp, "TERMCAP=", 8) == 0) | |
282 | { | |
283 | *envp = envbuf; | |
284 | break; | |
285 | } | |
286 | envp++; | |
287 | } | |
288 | if (! *envp) | |
289 | *envp = envbuf; /* this may be dangerous */ | |
290 | ||
291 | /* | |
292 | ** if user specified type(s), do only those | |
293 | */ | |
294 | if (argc > 0) | |
295 | { | |
296 | /* | |
297 | ** look for the users specified term types | |
298 | */ | |
299 | while (argc > 0) | |
300 | { | |
301 | switch (n = tgetent(tcbuf, *argv)) | |
302 | { | |
303 | case 1: | |
304 | if (bflag) | |
305 | (void) prnt_raw(tcbuf); | |
306 | else | |
307 | (void) prnt_ent(tcbuf); | |
308 | break; | |
309 | ||
310 | case 0: | |
311 | fprintf(stderr, | |
312 | "showtc: bad entry: %s\n", *argv); | |
313 | break; | |
314 | ||
315 | case -1: | |
316 | fputs("showtc: ", stderr); | |
317 | perror(tcfile); | |
318 | exit(1); | |
319 | ||
320 | default: | |
321 | fprintf(stderr, "bad return from tgetent: %d\n", n); | |
322 | exit(1); | |
323 | } | |
324 | argc--; | |
325 | argv++; | |
326 | } | |
327 | exit(0); | |
328 | } | |
329 | ||
330 | if (bflag) | |
331 | { | |
332 | fprintf(stderr, "showtc: -b flag with no entries makes no sense.\n"); | |
333 | exit(1); | |
334 | } | |
335 | ||
336 | ||
337 | /* | |
338 | ** if no type was specified, do the whole file | |
339 | */ | |
340 | if ((tcfp = fopen(tcfile, "r")) == NULL) | |
341 | { | |
342 | perror(tcfile); | |
343 | exit(1); | |
344 | } | |
345 | ||
346 | /* | |
347 | ** identify database, for the record | |
348 | */ | |
349 | if (stat(tcfile, &st)) | |
350 | { | |
351 | perror(tcfile); | |
352 | exit(1); | |
353 | } | |
354 | printf("File: %s, last modified: %s\n", tcfile, ctime(&st.st_mtime)); | |
355 | ||
356 | ||
357 | /* | |
358 | ** build termcap entry table | |
359 | */ | |
360 | tn = tcNames; | |
361 | pos = ftell(tcfp); | |
362 | bp = tcbuf; | |
363 | while (fgets(bp, sizeof (tcbuf), tcfp) != NULL) | |
364 | { | |
365 | if (tcbuf[0] == '#') | |
366 | { | |
367 | pos = ftell(tcfp); | |
368 | bp = tcbuf; | |
369 | continue; | |
370 | } | |
371 | ||
372 | tn->file_pos = pos; | |
373 | ||
374 | /* | |
375 | ** get full entry | |
376 | */ | |
377 | while (*(bp = lastchar(bp)) == '\\' && fgets(bp, (sizeof tcbuf) - (bp - tcbuf), tcfp)) | |
378 | ; | |
379 | /* | |
380 | ** save the names | |
381 | */ | |
382 | for (bp = tcbuf; *bp && *bp != ':'; bp++) | |
383 | ; | |
384 | *bp = '\0'; | |
385 | (void) strncpy(tn->name_buf, tcbuf, | |
386 | sizeof tcNames[0].name_buf); | |
387 | ||
388 | pos = ftell(tcfp); | |
389 | bp = tcbuf; | |
390 | tn++; | |
391 | } | |
392 | tn->file_pos = -1; | |
393 | ||
394 | /* | |
395 | ** Look for duplicate names | |
396 | */ | |
397 | if (dflag) | |
398 | check_dup(); | |
399 | if (nflag) | |
400 | exit(0); | |
401 | ||
402 | #ifdef DEBUG | |
403 | if (Dflag) | |
404 | { | |
405 | for (tn = tcNames; tn->file_pos >= 0; tn++) | |
406 | { | |
407 | printf("Entry #%d:\n\t%s\n\tfile_pos = %ld\n", | |
408 | tn - tcNames, tn->name_buf, tn->file_pos); | |
409 | } | |
410 | exit(0); | |
411 | } | |
412 | #endif | |
413 | ||
414 | /* | |
415 | ** Order the list | |
416 | */ | |
977b5828 | 417 | if (Sflag) |
551db654 KL |
418 | qsort((char *)tcNames, tn - tcNames, |
419 | sizeof (struct TcName), name_cmp); | |
420 | ||
421 | /* | |
422 | ** List termcap entry for each name in table | |
423 | */ | |
424 | for (tn = tcNames; tn->file_pos >= 0; tn++) | |
425 | { | |
426 | tc_loopc = 0; | |
427 | /*** working toward this ... | |
428 | (void) prnt_ent(tn); | |
429 | ***/ | |
430 | (void) fseek(tcfp, tn->file_pos, 0); | |
431 | bp = tcbuf; | |
432 | while (fgets(bp, (sizeof tcbuf) - (bp - tcbuf), tcfp) | |
433 | && *(bp = lastchar(bp)) == '\\') | |
434 | ; | |
435 | (void) prnt_ent(tcbuf); | |
436 | } | |
437 | } | |
438 | ||
439 | char * | |
440 | lastchar(b) | |
441 | char *b; | |
442 | { | |
443 | register char *p; | |
444 | ||
445 | p = b + strlen(b) - 1; | |
446 | while (*p == '\n' || *p == ' ') | |
447 | p--; | |
448 | return(p); | |
449 | } | |
450 | ||
451 | name_cmp(a, b) | |
452 | char *a, *b; | |
453 | { | |
454 | if (gflag) /* sort on generic names */ | |
455 | { | |
456 | a += 3; | |
457 | b += 3; | |
458 | while (*a && *b && *a != '|' && *a == *b) | |
459 | { | |
460 | a++; | |
461 | b++; | |
462 | } | |
463 | if (*a == '|' || *a == CNULL) | |
464 | return((*b == '|' || *b == CNULL)? 0:-1); | |
465 | if (*b == '|' || *b == CNULL) | |
466 | return(1); | |
467 | return(*a - *b); | |
468 | } | |
469 | return(strncmp(a, b, 2)); | |
470 | } | |
471 | ||
472 | prnt_ent(buf) | |
473 | register char *buf; | |
474 | { | |
475 | register char *name; | |
0b733427 | 476 | char *getdesc(); |
551db654 KL |
477 | char *caps[256]; |
478 | register char **cp; | |
479 | register char **tp; | |
480 | char tname[3]; | |
481 | ||
482 | cp = caps; | |
483 | name = buf; | |
484 | tname[3] = '\0'; | |
485 | ||
486 | while (*buf) | |
487 | { | |
488 | switch (*buf) | |
489 | { | |
490 | case ':': | |
491 | *buf++ = '\0'; | |
492 | while (*buf && !isalnum(*buf)) | |
493 | buf++; | |
494 | if (*buf) | |
495 | { | |
496 | /* | |
497 | * ignore duplicate cap entries | |
498 | */ | |
499 | for (tp = caps; tp < cp; tp++) | |
500 | if (strncmp(buf, *tp, 2) == 0) | |
501 | goto skip; | |
502 | *cp++ = buf; | |
503 | skip: | |
504 | /* | |
505 | * does user want tc= expanded? | |
506 | */ | |
507 | if (xflag && strncmp(buf, "tc=", 3) == 0) | |
508 | { | |
509 | /* | |
510 | * find end of tc= | |
511 | */ | |
512 | while (*buf != ':') | |
513 | buf++; | |
514 | *buf = '\0'; | |
515 | /* | |
516 | * save term name | |
517 | */ | |
518 | tname[0] = name[0]; | |
519 | tname[1] = name[1]; | |
520 | printf("%s: expanding %s\n", | |
521 | tname, cp[-1]); | |
522 | /* | |
523 | * let tgetent do the work | |
524 | */ | |
525 | tgetent(tcbuf, tname); | |
526 | prnt_ent(tcbuf); | |
527 | return; | |
528 | } | |
529 | } | |
530 | continue; | |
531 | ||
532 | case '|': | |
533 | *buf++ = ','; | |
534 | continue; | |
535 | ||
536 | default: | |
537 | buf++; | |
538 | } | |
539 | } | |
540 | *cp = CNULL; /* was (char *)0 */ | |
541 | ||
977b5828 | 542 | if (Sflag) |
551db654 KL |
543 | qsort((char *) caps, cp - caps, sizeof (char *), ent_cmp); |
544 | ||
545 | printf("%s\n", name); | |
546 | for (cp = caps; *cp; cp++) | |
322eb279 KL |
547 | if (Uflag) { |
548 | if (unknowncap(*cp)) { | |
549 | printf("%3.3s\n", *cp); | |
550 | } | |
551 | } else if (sflag) { | |
0b733427 | 552 | printf("%-45s %s\n", getdesc(*cp), *cp); |
322eb279 | 553 | } else { |
0b733427 KL |
554 | printf("%2.2s %-45s %s\n", name, getdesc(*cp), *cp); |
555 | } | |
551db654 KL |
556 | (void) putchar('\n'); |
557 | } | |
558 | ||
559 | prnt_raw(buf) | |
560 | char *buf; | |
561 | { | |
562 | register char *b; | |
563 | register int len; | |
564 | register int n; | |
565 | char *index(); | |
566 | ||
567 | len = 0; | |
568 | b = buf; | |
569 | while (*b) | |
570 | { | |
571 | if ((n = index(b, ':') - b + 1) <= 0) | |
572 | n = strlen(b); | |
573 | if (len == 0) /* first part */ | |
574 | { | |
575 | printf("%.*s\\\n\t:", n, b); | |
576 | len = 9 - n; | |
577 | } | |
578 | else | |
579 | { | |
580 | if ((len + n) >= 75) | |
581 | { | |
582 | printf("\\\n\t:"); | |
583 | len = 9; | |
584 | } | |
585 | printf("%.*s", n, b); | |
586 | } | |
587 | len += n; | |
588 | b += n; | |
589 | while (*b && index(" \t:\n", *b)) | |
590 | b++; | |
591 | } | |
592 | if (b[-1] != ':') | |
593 | (void) putchar(':'); | |
594 | (void) putchar('\n'); | |
595 | } | |
596 | ||
597 | ent_cmp(a, b) | |
598 | char **a, **b; | |
599 | { | |
600 | return(strncmp(*a, *b, 2)); | |
601 | } | |
602 | ||
603 | check_dup() | |
604 | { | |
605 | /* | |
606 | ** Look for duplicated names | |
607 | */ | |
608 | register char *p; | |
609 | register char *q; | |
610 | register struct TcName *tn; | |
611 | register struct TcName *tm; | |
612 | ||
613 | tn = tcNames; | |
614 | while (tn->file_pos >= 0) | |
615 | { | |
616 | p = q = tn->name_buf; | |
617 | while (*q) | |
618 | { | |
619 | while (*p && *p != '|') | |
620 | p++; | |
621 | if (p != q && (tm = find_name(q, tn + 1, p - q))) | |
622 | { | |
623 | fputs("Duplicate name: ", stdout); | |
624 | while (q != p) | |
625 | (void) putchar(*q++); | |
626 | (void) putchar('\n'); | |
627 | puts(tn->name_buf); | |
628 | puts(tm->name_buf); | |
629 | puts("---\n"); | |
630 | } | |
631 | if (*p == '|') | |
632 | p++; | |
633 | q = p; | |
634 | } | |
635 | tn++; | |
636 | } | |
637 | } | |
638 | ||
639 | struct TcName * | |
640 | find_name(name, tn, len) | |
641 | register char *name; | |
642 | register struct TcName *tn; | |
643 | register int len; | |
644 | { | |
645 | /* | |
646 | ** find name of length len in tcname structure buffers. | |
647 | */ | |
648 | register char *p; | |
649 | register char *buf; | |
650 | register int n; | |
651 | ||
652 | while (tn->file_pos >= 0) | |
653 | { | |
654 | buf = tn->name_buf; | |
655 | while (*buf) | |
656 | { | |
657 | p = name; | |
658 | n = len; | |
659 | if (*buf == '|') | |
660 | buf++; | |
661 | ||
662 | while (*buf && *buf != '|') | |
663 | { | |
664 | if (*p != *buf) | |
665 | { | |
666 | while (*buf && *buf != '|') | |
667 | buf++; | |
668 | break; | |
669 | } | |
670 | ||
671 | if (--n <= 0) | |
672 | { | |
673 | buf++; | |
674 | if (*buf == '|' || *buf == '\0') | |
675 | return(tn); | |
676 | while (*buf && *buf != '|') | |
677 | buf++; | |
678 | break; | |
679 | } | |
680 | buf++; | |
681 | p++; | |
682 | } | |
683 | } | |
684 | tn++; | |
685 | } | |
686 | return((struct TcName *)0); | |
687 | } | |
0b733427 KL |
688 | |
689 | char * | |
690 | getdesc(key) | |
691 | char *key; | |
692 | { | |
693 | register int i; | |
694 | ||
695 | for (i = 0; i <= NOCAPS; i++) | |
696 | if (strncmp(key, capList[i].cap, 2) == 0) | |
697 | return (capList[i].desc); | |
ba9c0f2e | 698 | return(""); |
0b733427 | 699 | } |
322eb279 KL |
700 | |
701 | unknowncap(key) | |
702 | char *key; | |
703 | { | |
704 | register int i; | |
705 | ||
706 | for (i = 0; i <= NOCAPS; i++) | |
707 | if (strncmp(key, capList[i].cap, 2) == 0) | |
708 | return (0); | |
709 | return(1); | |
710 | } |