1: /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tw.help.c,v 3.0 1991/07/04 21:49:28 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 "config.h" 41: #if !defined(lint) && !defined(pdp11) 42: static char *rcsid() 43: { return "$Id: tw.help.c,v 3.0 1991/07/04 21:49:28 christos Exp $"; } 44: #endif 45: 46: #include "sh.h" 47: #include "tw.h" 48: 49: 50: static int f = -1; 51: static sigret_t cleanf __P((int)); 52: static Char *skipslist __P((Char *)); 53: static void nextslist __P((Char *, Char *)); 54: 55: static char *h_ext[] = { 56: ".help", ".1", ".8", ".6", NULL 57: }; 58: 59: void 60: do_help(command) 61: Char *command; 62: { 63: Char name[FILSIZ + 1]; 64: Char *cmd_p, *ep; 65: char **sp; 66: 67: sigret_t(*orig_intr) (); 68: Char curdir[MAXPATHLEN]; /* Cur_ directory being looked at */ 69: register Char *hpath; /* The environment parameter */ 70: Char full[MAXPATHLEN]; 71: char buf[512]; /* full path name and buffer for read */ 72: int len; /* length of read buffer */ 73: Char *thpath; 74: 75: 76: /* copy the string to a safe place */ 77: copyn(name, command, FILSIZ + 1); 78: 79: /* trim off the garbage that may be at the end */ 80: for (cmd_p = name; *cmd_p != '\0'; cmd_p++) 81: if (*cmd_p == ' ' || *cmd_p == '\t') 82: *cmd_p = '\0'; 83: 84: /* if nothing left, return */ 85: if (*name == '\0') 86: return; 87: 88: if (adrof1(STRhelpcommand, &aliases)) { /* if we have an alias */ 89: jmp_buf osetexit; 90: 91: getexit(osetexit); /* make sure to come back here */ 92: if (setexit() == 0) 93: aliasrun(2, STRhelpcommand, name); /* then use it. */ 94: resexit(osetexit); /* and finish up */ 95: } 96: else { /* else cat something to them */ 97: /* got is, now "cat" the file based on the path $HPATH */ 98: 99: hpath = str2short(getenv(SEARCHLIST)); 100: if (hpath == NULL) 101: hpath = str2short(DEFAULTLIST); 102: thpath = hpath = Strsave(hpath); 103: 104: while (1) { 105: if (!*hpath) { 106: xprintf("No help file for %s\n", short2str(name)); 107: break; 108: } 109: nextslist(hpath, curdir); 110: hpath = skipslist(hpath); 111: 112: /* 113: * now make the full path name - try first /bar/foo.help, then 114: * /bar/foo.1, /bar/foo.8, then finally /bar/foo.6. This is so 115: * that you don't spit a binary at the tty when $HPATH == $PATH. 116: */ 117: copyn(full, curdir, sizeof(full) / sizeof(Char)); 118: catn(full, STRslash, sizeof(full) / sizeof(Char)); 119: catn(full, name, sizeof(full) / sizeof(Char)); 120: ep = &full[Strlen(full)]; 121: for (sp = h_ext; *sp; sp++) { 122: *ep = '\0'; 123: catn(full, str2short(*sp), sizeof(full) / sizeof(Char)); 124: if ((f = open(short2str(full), O_RDONLY)) != -1) 125: break; 126: } 127: if (f != -1) { 128: /* so cat it to the terminal */ 129: orig_intr = sigset(SIGINT, cleanf); 130: while (f != -1 && (len = read(f, (char *) buf, 512)) != 0) 131: (void) write(SHOUT, (char *) buf, (size_t) len); 132: (void) sigset(SIGINT, orig_intr); 133: if (f != -1) 134: (void) close(f); 135: break; 136: } 137: } 138: xfree((ptr_t) thpath); 139: } 140: } 141: 142: static sigret_t 143: /*ARGSUSED*/ 144: cleanf(snum) 145: int snum; 146: { 147: if (f != -1) 148: (void) close(f); 149: f = -1; 150: #ifndef SIGVOID 151: return (snum); 152: #endif 153: } 154: 155: /* these next two are stolen from CMU's man(1) command for looking down 156: * paths. they are prety straight forward. */ 157: 158: /* 159: * nextslist takes a search list and copies the next path in it 160: * to np. A null search list entry is expanded to ".". 161: * If there are no entries in the search list, then np will point 162: * to a null string. 163: */ 164: 165: static void 166: nextslist(sl, np) 167: register Char *sl; 168: register Char *np; 169: { 170: if (!*sl) 171: *np = '\000'; 172: else if (*sl == ':') { 173: *np++ = '.'; 174: *np = '\000'; 175: } 176: else { 177: while (*sl && *sl != ':') 178: *np++ = *sl++; 179: *np = '\000'; 180: } 181: } 182: 183: /* 184: * skipslist returns the pointer to the next entry in the search list. 185: */ 186: 187: static Char * 188: skipslist(sl) 189: register Char *sl; 190: { 191: while (*sl && *sl++ != ':'); 192: return (sl); 193: }