source: trunk/third/tcsh/tw.help.c @ 12039

Revision 12039, 6.2 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r12038, which included commits to RCS files with non-trunk default branches.
Line 
1/* $Header: /afs/dev.mit.edu/source/repository/third/tcsh/tw.help.c,v 1.1.1.2 1998-10-03 21:10:21 danw 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.
7 */
8/*-
9 * Copyright (c) 1980, 1991 The Regents of the University of California.
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
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. All advertising materials mentioning features or use of this software
21 *    must display the following acknowledgement:
22 *      This product includes software developed by the University of
23 *      California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 *    may be used to endorse or promote products derived from this software
26 *    without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 */
40#include "sh.h"
41
42RCSID("$Id: tw.help.c,v 1.1.1.2 1998-10-03 21:10:21 danw Exp $")
43
44#include "tw.h"
45#include "tc.h"
46
47
48static int f = -1;
49static  sigret_t         cleanf         __P((int));
50static  Char            *skipslist      __P((Char *));
51static  void             nextslist      __P((Char *, Char *));
52
53static char *h_ext[] = {
54    ".help", ".1", ".8", ".6", "", NULL
55};
56
57void
58do_help(command)
59    Char   *command;
60{
61    Char    name[FILSIZ + 1];
62    Char   *cmd_p, *ep;
63    char  **sp;
64
65    signalfun_t orig_intr;
66    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(28, 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}
Note: See TracBrowser for help on using the repository browser.