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