Kernel part of bluetooth stack ported by Dmitry Komissaroff. Very much work
[dragonfly.git] / contrib / tcsh / tw.help.c
blob1cdf7e3c0b3ffe3b781e2a9edd607159279f1387
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.
7 */
8 /*-
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
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.
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.
36 #include "sh.h"
38 RCSID("$Id: tw.help.c,v 3.18 2002/03/08 17:36:47 christos Exp $")
40 #include "tw.h"
41 #include "tc.h"
44 static int f = -1;
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
53 void
54 do_help(command)
55 Char *command;
57 Char name[FILSIZ + 1];
58 Char *cmd_p, *ep;
59 char **sp;
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 */
67 Char *thpath;
70 /* trim off the whitespace at the beginning */
71 for (cmd_p = command; *cmd_p == ' ' || *cmd_p == '\t'; cmd_p++)
72 continue;
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 */
78 for (cmd_p = name;
79 *cmd_p != ' ' && *cmd_p != '\t' && *cmd_p != '\0'; cmd_p++)
80 continue;
81 *cmd_p = '\0';
83 /* if nothing left, return */
84 if (*name == '\0')
85 return;
87 if (adrof1(STRhelpcommand, &aliases)) { /* if we have an alias */
88 jmp_buf_t osetexit;
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 */
95 else { /* else cat something to them */
96 /* got is, now "cat" the file based on the path $HPATH */
98 hpath = str2short(getenv(SEARCHLIST));
99 if (hpath == NULL)
100 hpath = str2short(DEFAULTLIST);
101 thpath = hpath = Strsave(hpath);
103 for (;;) {
104 if (!*hpath) {
105 xprintf(CGETS(29, 1, "No help file for %S\n"), name);
106 break;
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++) {
121 *ep = '\0';
122 catn(full, str2short(*sp), (int) (sizeof(full) / sizeof(Char)));
123 if ((f = open(short2str(full), O_RDONLY)) != -1)
124 break;
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;
142 xfree((ptr_t) thpath);
146 static sigret_t
147 /*ARGSUSED*/
148 cleanf(snum)
149 int snum;
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 #ifndef SIGVOID
160 return (snum);
161 #endif
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
171 * to a null string.
174 static void
175 nextslist(sl, np)
176 register Char *sl;
177 register Char *np;
179 if (!*sl)
180 *np = '\000';
181 else if (*sl == ':') {
182 *np++ = '.';
183 *np = '\000';
185 else {
186 while (*sl && *sl != ':')
187 *np++ = *sl++;
188 *np = '\000';
193 * skipslist returns the pointer to the next entry in the search list.
196 static Char *
197 skipslist(sl)
198 register Char *sl;
200 while (*sl && *sl++ != ':')
201 continue;
202 return (sl);