tw.help.c revision 59243
1/* $Header: /src/pub/tcsh/tw.help.c,v 3.16 1999/05/11 13:08:03 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. 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 3.16 1999/05/11 13:08:03 christos 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(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