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

Revision 22036, 5.9 KB checked in by ghudson, 19 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r22035, 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.3 2005-06-03 14:35:18 ghudson 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. 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.
23 *
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
34 * SUCH DAMAGE.
35 */
36#include "sh.h"
37
38RCSID("$Id: tw.help.c,v 1.1.1.3 2005-06-03 14:35:18 ghudson Exp $")
39
40#include "tw.h"
41#include "tc.h"
42
43
44static int f = -1;
45static  RETSIGTYPE       cleanf         __P((int));
46static  Char            *skipslist      __P((Char *));
47static  void             nextslist      __P((Char *, Char *));
48
49static const char *h_ext[] = {
50    ".help", ".1", ".8", ".6", "", NULL
51};
52
53void
54do_help(command)
55    Char   *command;
56{
57    Char    name[FILSIZ + 1];
58    Char   *cmd_p, *ep;
59    const char  **sp;
60
61    signalfun_t orig_intr;
62    Char    curdir[MAXPATHLEN]; /* Current directory being looked at */
63    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 */
67    Char   *thpath;
68
69
70    /* trim off the whitespace at the beginning */
71    for (cmd_p = command; *cmd_p == ' ' || *cmd_p == '\t'; cmd_p++)
72        continue;
73               
74    /* copy the string to a safe place */
75    copyn(name, cmd_p, FILSIZ + 1);
76
77    /* trim off the whitespace that may be at the end */
78    for (cmd_p = name;
79         *cmd_p != ' ' && *cmd_p != '\t' && *cmd_p != '\0'; cmd_p++)
80        continue;
81    *cmd_p = '\0';
82
83    /* if nothing left, return */
84    if (*name == '\0')
85        return;
86
87    if (adrof1(STRhelpcommand, &aliases)) {     /* if we have an alias */
88        jmp_buf_t osetexit;
89
90        getexit(osetexit);      /* make sure to come back here */
91        if (setexit() == 0)
92            aliasrun(2, STRhelpcommand, name);  /* then use it. */
93        resexit(osetexit);      /* and finish up */
94    }
95    else {                      /* else cat something to them */
96        /* got is, now "cat" the file based on the path $HPATH */
97
98        hpath = str2short(getenv(SEARCHLIST));
99        if (hpath == NULL)
100            hpath = str2short(DEFAULTLIST);
101        thpath = hpath = Strsave(hpath);
102
103        for (;;) {
104            if (!*hpath) {
105                xprintf(CGETS(29, 1, "No help file for %S\n"), name);
106                break;
107            }
108            nextslist(hpath, curdir);
109            hpath = skipslist(hpath);
110
111            /*
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.
115             */
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++) {
121                *ep = '\0';
122                catn(full, str2short(*sp), (int) (sizeof(full) / sizeof(Char)));
123                if ((f = open(short2str(full), O_RDONLY|O_LARGEFILE)) != -1)
124                    break;
125            }
126            if (f != -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);
131#ifdef convex
132                /* print error in case file is migrated */
133                if (len == -1)
134                    stderror(ERR_SYSTEM, progname, strerror(errno));
135#endif /* convex */
136                (void) sigset(SIGINT, orig_intr);
137                if (f != -1)
138                    (void) close(f);
139                break;
140            }
141        }
142        xfree((ptr_t) thpath);
143    }
144}
145
146static RETSIGTYPE
147/*ARGSUSED*/
148cleanf(snum)
149int snum;
150{
151    USE(snum);
152#ifdef UNRELSIGS
153    if (snum)
154        (void) sigset(SIGINT, cleanf);
155#endif /* UNRELSIGS */
156    if (f != -1)
157        (void) close(f);
158    f = -1;
159}
160
161/* these next two are stolen from CMU's man(1) command for looking down
162 * paths.  they are prety straight forward. */
163
164/*
165 * nextslist takes a search list and copies the next path in it
166 * to np.  A null search list entry is expanded to ".".
167 * If there are no entries in the search list, then np will point
168 * to a null string.
169 */
170
171static void
172nextslist(sl, np)
173    Char *sl;
174    Char *np;
175{
176    if (!*sl)
177        *np = '\000';
178    else if (*sl == ':') {
179        *np++ = '.';
180        *np = '\000';
181    }
182    else {
183        while (*sl && *sl != ':')
184            *np++ = *sl++;
185        *np = '\000';
186    }
187}
188
189/*
190 * skipslist returns the pointer to the next entry in the search list.
191 */
192
193static Char *
194skipslist(sl)
195    Char *sl;
196{
197    while (*sl && *sl++ != ':')
198        continue;
199    return (sl);
200}
Note: See TracBrowser for help on using the repository browser.