1 /* $Header: /src/pub/tcsh/tw.help.c,v 3.18 2002/03/08 17:36:47 christos Exp $ */
2 /* tw.help.c: actually look up and print documentation on a file.
3 * Look down the path for an appropriate file, then print it.
4 * Note that the printing is NOT PAGED. This is because the
5 * function is NOT meant to look at manual pages, it only does so
6 * if there is no .help file to look in.
9 * Copyright (c) 1980, 1991 The Regents of the University of California.
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 RCSID("$Id: tw.help.c,v 3.18 2002/03/08 17:36:47 christos Exp $")
45 static sigret_t cleanf __P((int));
46 static Char *skipslist __P((Char *));
47 static void nextslist __P((Char *, Char *));
49 static char *h_ext[] = {
50 ".help", ".1", ".8", ".6", "", NULL
57 Char name[FILSIZ + 1];
61 signalfun_t orig_intr;
62 Char curdir[MAXPATHLEN]; /* Current directory being looked at */
63 register Char *hpath; /* The environment parameter */
64 Char full[MAXPATHLEN];
65 char buf[512]; /* full path name and buffer for read */
66 int len; /* length of read buffer */
70 /* trim off the whitespace at the beginning */
71 for (cmd_p = command; *cmd_p == ' ' || *cmd_p == '\t'; cmd_p++)
74 /* copy the string to a safe place */
75 copyn(name, cmd_p, FILSIZ + 1);
77 /* trim off the whitespace that may be at the end */
79 *cmd_p != ' ' && *cmd_p != '\t' && *cmd_p != '\0'; cmd_p++)
83 /* if nothing left, return */
87 if (adrof1(STRhelpcommand, &aliases)) { /* if we have an alias */
90 getexit(osetexit); /* make sure to come back here */
92 aliasrun(2, STRhelpcommand, name); /* then use it. */
93 resexit(osetexit); /* and finish up */
95 else { /* else cat something to them */
96 /* got is, now "cat" the file based on the path $HPATH */
98 hpath = str2short(getenv(SEARCHLIST));
100 hpath = str2short(DEFAULTLIST);
101 thpath = hpath = Strsave(hpath);
105 xprintf(CGETS(29, 1, "No help file for %S\n"), name);
108 nextslist(hpath, curdir);
109 hpath = skipslist(hpath);
112 * now make the full path name - try first /bar/foo.help, then
113 * /bar/foo.1, /bar/foo.8, then finally /bar/foo.6. This is so
114 * that you don't spit a binary at the tty when $HPATH == $PATH.
116 copyn(full, curdir, (int) (sizeof(full) / sizeof(Char)));
117 catn(full, STRslash, (int) (sizeof(full) / sizeof(Char)));
118 catn(full, name, (int) (sizeof(full) / sizeof(Char)));
119 ep = &full[Strlen(full)];
120 for (sp = h_ext; *sp; sp++) {
122 catn(full, str2short(*sp), (int) (sizeof(full) / sizeof(Char)));
123 if ((f = open(short2str(full), O_RDONLY)) != -1)
127 /* so cat it to the terminal */
128 orig_intr = (signalfun_t) sigset(SIGINT, cleanf);
129 while (f != -1 && (len = read(f, (char *) buf, 512)) > 0)
130 (void) write(SHOUT, (char *) buf, (size_t) len);
132 /* print error in case file is migrated */
134 stderror(ERR_SYSTEM, progname, strerror(errno));
136 (void) sigset(SIGINT, orig_intr);
142 xfree((ptr_t) thpath);
154 (void) sigset(SIGINT, cleanf);
155 #endif /* UNRELSIGS */
164 /* these next two are stolen from CMU's man(1) command for looking down
165 * paths. they are prety straight forward. */
168 * nextslist takes a search list and copies the next path in it
169 * to np. A null search list entry is expanded to ".".
170 * If there are no entries in the search list, then np will point
181 else if (*sl == ':') {
186 while (*sl && *sl != ':')
193 * skipslist returns the pointer to the next entry in the search list.
200 while (*sl && *sl++ != ':')