1 /* $OpenBSD: hist.c,v 1.7 2003/06/11 21:09:50 deraadt Exp $ */ 2 /* $NetBSD: hist.c,v 1.7 1995/03/21 18:35:44 mycroft Exp $ */ 3 4 /*- 5 * Copyright (c) 1980, 1991, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef lint 34 #if 0 35 static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 5/31/93"; 36 #else 37 static char rcsid[] = "$OpenBSD: hist.c,v 1.7 2003/06/11 21:09:50 deraadt Exp $"; 38 #endif 39 #endif /* not lint */ 40 41 #include <sys/types.h> 42 #include <stdlib.h> 43 #include <stdarg.h> 44 45 #include "csh.h" 46 #include "extern.h" 47 48 static void hfree(struct Hist *); 49 static void dohist1(struct Hist *, int *, int, int); 50 static void phist(struct Hist *, int); 51 52 void 53 savehist(struct wordent *sp) 54 { 55 struct Hist *hp, *np; 56 int histlen = 0; 57 Char *cp; 58 59 /* throw away null lines */ 60 if (sp->next->word[0] == '\n') 61 return; 62 cp = value(STRhistory); 63 if (*cp) { 64 Char *p = cp; 65 66 while (*p) { 67 if (!Isdigit(*p)) { 68 histlen = 0; 69 break; 70 } 71 histlen = histlen * 10 + *p++ - '0'; 72 } 73 } 74 for (hp = &Histlist; (np = hp->Hnext) != NULL;) 75 if (eventno - np->Href >= histlen || histlen == 0) 76 hp->Hnext = np->Hnext, hfree(np); 77 else 78 hp = np; 79 (void) enthist(++eventno, sp, 1); 80 } 81 82 struct Hist * 83 enthist(int event, struct wordent *lp, bool docopy) 84 { 85 struct Hist *np; 86 87 np = (struct Hist *) xmalloc((size_t) sizeof(*np)); 88 np->Hnum = np->Href = event; 89 if (docopy) { 90 copylex(&np->Hlex, lp); 91 } 92 else { 93 np->Hlex.next = lp->next; 94 lp->next->prev = &np->Hlex; 95 np->Hlex.prev = lp->prev; 96 lp->prev->next = &np->Hlex; 97 } 98 np->Hnext = Histlist.Hnext; 99 Histlist.Hnext = np; 100 return (np); 101 } 102 103 static void 104 hfree(struct Hist *hp) 105 { 106 107 freelex(&hp->Hlex); 108 xfree((ptr_t) hp); 109 } 110 111 void 112 /*ARGSUSED*/ 113 dohist(Char **v, struct command *t) 114 { 115 int n, rflg = 0, hflg = 0; 116 sigset_t sigset; 117 118 if (getn(value(STRhistory)) == 0) 119 return; 120 if (setintr) { 121 sigemptyset(&sigset); 122 sigaddset(&sigset, SIGINT); 123 sigprocmask(SIG_UNBLOCK, &sigset, NULL); 124 } 125 while (*++v && **v == '-') { 126 Char *vp = *v; 127 128 while (*++vp) 129 switch (*vp) { 130 case 'h': 131 hflg++; 132 break; 133 case 'r': 134 rflg++; 135 break; 136 case '-': /* ignore multiple '-'s */ 137 break; 138 default: 139 stderror(ERR_HISTUS); 140 break; 141 } 142 } 143 if (*v) 144 n = getn(*v); 145 else { 146 n = getn(value(STRhistory)); 147 } 148 dohist1(Histlist.Hnext, &n, rflg, hflg); 149 } 150 151 static void 152 dohist1(struct Hist *hp, int *np, int rflg, int hflg) 153 { 154 bool print = (*np) > 0; 155 156 for (; hp != 0; hp = hp->Hnext) { 157 (*np)--; 158 hp->Href++; 159 if (rflg == 0) { 160 dohist1(hp->Hnext, np, rflg, hflg); 161 if (print) 162 phist(hp, hflg); 163 return; 164 } 165 if (*np >= 0) 166 phist(hp, hflg); 167 } 168 } 169 170 static void 171 phist(struct Hist *hp, int hflg) 172 { 173 if (hflg == 0) 174 (void) fprintf(cshout, "%6d\t", hp->Hnum); 175 prlex(cshout, &hp->Hlex); 176 } 177