tw.help.c revision 59243
1148197Smarks/* $Header: /src/pub/tcsh/tw.help.c,v 3.16 1999/05/11 13:08:03 christos Exp $ */
2208291Suqs/* tw.help.c: actually look up and print documentation on a file.
3148197Smarks *	      Look down the path for an appropriate file, then print it.
4148197Smarks *	      Note that the printing is NOT PAGED.  This is because the
5148197Smarks *	      function is NOT meant to look at manual pages, it only does so
6148197Smarks *	      if there is no .help file to look in.
7148197Smarks */
8148197Smarks/*-
9148197Smarks * Copyright (c) 1980, 1991 The Regents of the University of California.
10148197Smarks * All rights reserved.
11148197Smarks *
12148197Smarks * Redistribution and use in source and binary forms, with or without
13148197Smarks * modification, are permitted provided that the following conditions
14148197Smarks * are met:
15148197Smarks * 1. Redistributions of source code must retain the above copyright
16148197Smarks *    notice, this list of conditions and the following disclaimer.
17148197Smarks * 2. Redistributions in binary form must reproduce the above copyright
18148197Smarks *    notice, this list of conditions and the following disclaimer in the
19148197Smarks *    documentation and/or other materials provided with the distribution.
20148197Smarks * 3. All advertising materials mentioning features or use of this software
21148197Smarks *    must display the following acknowledgement:
22148197Smarks *	This product includes software developed by the University of
23148197Smarks *	California, Berkeley and its contributors.
24148197Smarks * 4. Neither the name of the University nor the names of its contributors
25148197Smarks *    may be used to endorse or promote products derived from this software
26148197Smarks *    without specific prior written permission.
27148197Smarks *
28148197Smarks * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29148197Smarks * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30148197Smarks * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31148197Smarks * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32148197Smarks * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33148197Smarks * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34148197Smarks * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35148197Smarks * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36148197Smarks * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37148197Smarks * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38148197Smarks * SUCH DAMAGE.
39148197Smarks */
40148197Smarks#include "sh.h"
41148197Smarks
42148197SmarksRCSID("$Id: tw.help.c,v 3.16 1999/05/11 13:08:03 christos Exp $")
43148197Smarks
44148197Smarks#include "tw.h"
45148197Smarks#include "tc.h"
46148197Smarks
47148197Smarks
48148197Smarksstatic int f = -1;
49148197Smarksstatic	sigret_t	 cleanf		__P((int));
50148197Smarksstatic	Char    	*skipslist	__P((Char *));
51148197Smarksstatic	void		 nextslist 	__P((Char *, Char *));
52148197Smarks
53148197Smarksstatic char *h_ext[] = {
54148197Smarks    ".help", ".1", ".8", ".6", "", NULL
55148197Smarks};
56148197Smarks
57148197Smarksvoid
58148197Smarksdo_help(command)
59148197Smarks    Char   *command;
60148197Smarks{
61148197Smarks    Char    name[FILSIZ + 1];
62148197Smarks    Char   *cmd_p, *ep;
63148197Smarks    char  **sp;
64157036Shrs
65148197Smarks    signalfun_t orig_intr;
66267668Sbapt    Char    curdir[MAXPATHLEN];	/* Current directory being looked at */
67    register Char *hpath;	/* The environment parameter */
68    Char    full[MAXPATHLEN];
69    char    buf[512];		/* full path name and buffer for read */
70    int     len;		/* length of read buffer */
71    Char   *thpath;
72
73
74    /* trim off the whitespace at the beginning */
75    for (cmd_p = command; *cmd_p == ' ' || *cmd_p == '\t'; cmd_p++)
76	continue;
77
78    /* copy the string to a safe place */
79    copyn(name, cmd_p, FILSIZ + 1);
80
81    /* trim off the whitespace that may be at the end */
82    for (cmd_p = name;
83	 *cmd_p != ' ' && *cmd_p != '\t' && *cmd_p != '\0'; cmd_p++)
84	continue;
85    *cmd_p = '\0';
86
87    /* if nothing left, return */
88    if (*name == '\0')
89	return;
90
91    if (adrof1(STRhelpcommand, &aliases)) {	/* if we have an alias */
92	jmp_buf_t osetexit;
93
94	getexit(osetexit);	/* make sure to come back here */
95	if (setexit() == 0)
96	    aliasrun(2, STRhelpcommand, name);	/* then use it. */
97	resexit(osetexit);	/* and finish up */
98    }
99    else {			/* else cat something to them */
100	/* got is, now "cat" the file based on the path $HPATH */
101
102	hpath = str2short(getenv(SEARCHLIST));
103	if (hpath == NULL)
104	    hpath = str2short(DEFAULTLIST);
105	thpath = hpath = Strsave(hpath);
106
107	for (;;) {
108	    if (!*hpath) {
109		xprintf(CGETS(29, 1, "No help file for %S\n"), name);
110		break;
111	    }
112	    nextslist(hpath, curdir);
113	    hpath = skipslist(hpath);
114
115	    /*
116	     * now make the full path name - try first /bar/foo.help, then
117	     * /bar/foo.1, /bar/foo.8, then finally /bar/foo.6.  This is so
118	     * that you don't spit a binary at the tty when $HPATH == $PATH.
119	     */
120	    copyn(full, curdir, (int) (sizeof(full) / sizeof(Char)));
121	    catn(full, STRslash, (int) (sizeof(full) / sizeof(Char)));
122	    catn(full, name, (int) (sizeof(full) / sizeof(Char)));
123	    ep = &full[Strlen(full)];
124	    for (sp = h_ext; *sp; sp++) {
125		*ep = '\0';
126		catn(full, str2short(*sp), (int) (sizeof(full) / sizeof(Char)));
127		if ((f = open(short2str(full), O_RDONLY)) != -1)
128		    break;
129	    }
130	    if (f != -1) {
131		/* so cat it to the terminal */
132		orig_intr = (signalfun_t) sigset(SIGINT, cleanf);
133		while (f != -1 && (len = read(f, (char *) buf, 512)) > 0)
134		    (void) write(SHOUT, (char *) buf, (size_t) len);
135#ifdef convex
136		/* print error in case file is migrated */
137		if (len == -1)
138		    stderror(ERR_SYSTEM, progname, strerror(errno));
139#endif /* convex */
140		(void) sigset(SIGINT, orig_intr);
141		if (f != -1)
142		    (void) close(f);
143		break;
144	    }
145	}
146	xfree((ptr_t) thpath);
147    }
148}
149
150static  sigret_t
151/*ARGSUSED*/
152cleanf(snum)
153int snum;
154{
155#ifdef UNRELSIGS
156    if (snum)
157	(void) sigset(SIGINT, cleanf);
158#endif /* UNRELSIGS */
159    if (f != -1)
160	(void) close(f);
161    f = -1;
162#ifndef SIGVOID
163    return (snum);
164#endif
165}
166
167/* these next two are stolen from CMU's man(1) command for looking down
168 * paths.  they are prety straight forward. */
169
170/*
171 * nextslist takes a search list and copies the next path in it
172 * to np.  A null search list entry is expanded to ".".
173 * If there are no entries in the search list, then np will point
174 * to a null string.
175 */
176
177static void
178nextslist(sl, np)
179    register Char *sl;
180    register Char *np;
181{
182    if (!*sl)
183	*np = '\000';
184    else if (*sl == ':') {
185	*np++ = '.';
186	*np = '\000';
187    }
188    else {
189	while (*sl && *sl != ':')
190	    *np++ = *sl++;
191	*np = '\000';
192    }
193}
194
195/*
196 * skipslist returns the pointer to the next entry in the search list.
197 */
198
199static Char *
200skipslist(sl)
201    register Char *sl;
202{
203    while (*sl && *sl++ != ':')
204	continue;
205    return (sl);
206}
207