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
++ != ':')