remove OSF1 support
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / cmd / ksh93 / bltins / hist.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: hist.c /main/3 1995/11/01 16:28:36 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF        *
29 *                    AT&T BELL LABORATORIES                    *
30 *         AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN         *
31 *            ACCORDANCE WITH APPLICABLE AGREEMENTS             *
32 *                                                              *
33 *                Copyright (c) 1995 AT&T Corp.                 *
34 *              Unpublished & Not for Publication               *
35 *                     All Rights Reserved                      *
36 *                                                              *
37 *       The copyright notice above does not evidence any       *
38 *      actual or intended publication of such source code      *
39 *                                                              *
40 *               This software was created by the               *
41 *           Advanced Software Technology Department            *
42 *                    AT&T Bell Laboratories                    *
43 *                                                              *
44 *               For further information contact                *
45 *                    {research,attmail}!dgk                    *
46 *                                                              *
47 ***************************************************************/
48
49 /* : : generated by proto : : */
50
51 #if !defined(__PROTO__)
52 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
53 #if defined(__cplusplus)
54 #define __MANGLE__      "C"
55 #else
56 #define __MANGLE__
57 #endif
58 #define __STDARG__
59 #define __PROTO__(x)    x
60 #define __OTORP__(x)
61 #define __PARAM__(n,o)  n
62 #if !defined(__STDC__) && !defined(__cplusplus)
63 #if !defined(c_plusplus)
64 #define const
65 #endif
66 #define signed
67 #define void            int
68 #define volatile
69 #define __V_            char
70 #else
71 #define __V_            void
72 #endif
73 #else
74 #define __PROTO__(x)    ()
75 #define __OTORP__(x)    x
76 #define __PARAM__(n,o)  o
77 #define __MANGLE__
78 #define __V_            char
79 #define const
80 #define signed
81 #define void            int
82 #define volatile
83 #endif
84 #if defined(__cplusplus) || defined(c_plusplus)
85 #define __VARARG__      ...
86 #else
87 #define __VARARG__
88 #endif
89 #if defined(__STDARG__)
90 #define __VA_START__(p,a)       va_start(p,a)
91 #else
92 #define __VA_START__(p,a)       va_start(p)
93 #endif
94 #endif
95 #include        "defs.h"
96 #include        <stak.h>
97 #include        <ls.h>
98 #include        <error.h>
99 #include        <ctype.h>
100 #include        "variables.h"
101 #include        "io.h"
102 #include        "name.h"
103 #include        "history.h"
104 #include        "builtins.h"
105
106 static void hist_subst __PROTO__((const char*, int fd, char*));
107
108 int     b_hist __PARAM__((int argc,char *argv[], __V_ *extra), (argc, argv, extra)) __OTORP__(int argc;char *argv[]; __V_ *extra;){
109         register History_t *hp;
110         register char *arg;
111         register int flag,fdo;
112         struct stat statb;
113         time_t before;
114         Sfio_t *outfile;
115         char *fname;
116         int range[2], incr, index2, indx= -1;
117         char *edit = 0;         /* name of editor */
118         char *replace = 0;              /* replace old=new */
119         int lflag = 0, nflag = 0, rflag = 0;
120         Histloc_t location;
121         NOT_USED(argc);
122         NOT_USED(extra);
123         if(!sh_histinit())
124                 error(ERROR_system(1),e_histopen);
125         hp = sh.hist_ptr;
126         while((flag = optget(argv,sh_opthist))) switch(flag)
127         {
128             case 'e':
129                 edit = opt_arg;
130                 break;
131             case 'n':
132                 nflag++;
133                 break;
134             case 'l':
135                 lflag++;
136                 break;
137             case 'r':
138                 rflag++;
139                 break;
140             case 's':
141                 edit = "-";
142                 break;
143             case 'N':
144                 if(indx<=0)
145                 {
146                         if((flag = hist_max(hp) - opt_num-1) < 0)
147                                 flag = 1;
148                         range[++indx] = flag;
149                         break;
150                 }
151             case ':':
152                 error(2, opt_arg);
153                 break;
154             case '?':
155                 error(ERROR_usage(2), opt_arg);
156                 break;
157         }
158         if(error_info.errors)
159                 error(ERROR_usage(2),optusage((char*)0));
160         argv += (opt_index-1);
161         flag = indx;
162         while(flag<1 && (arg=argv[1]))
163         {
164                 /* look for old=new argument */
165                 if(!replace && strchr(arg+1,'='))
166                 {
167                         replace = arg;
168                         argv++;
169                         continue;
170                 }
171                 else if(isdigit(*arg) || *arg == '-')
172                 {
173                         /* see if completely numeric */
174                         do      arg++;
175                         while(isdigit(*arg));
176                         if(*arg==0)
177                         {
178                                 arg = argv[1];
179                                 range[++flag] = atoi(arg);
180                                 if(*arg == '-')
181                                         range[flag] += (hist_max(hp)-1);
182                                 argv++;
183                                 continue;
184                         }
185                 }
186                 /* search for last line starting with string */
187                 location = hist_find(hp,argv[1],hist_max(hp)-1,0,-1);
188                 if((range[++flag] = location.hist_command) < 0)
189                         error(ERROR_exit(1),e_found,argv[1]);
190                 argv++;
191         }
192         if(flag <0)
193         {
194                 /* set default starting range */
195                 if(lflag)
196                 {
197                         flag = hist_max(hp)-17;
198                         if(flag<1)
199                                 flag = 1;
200                 }
201                 else
202                         flag = hist_max(hp)-2;
203                 range[0] = flag;
204                 flag = 0;
205         }
206         index2 = hist_min(hp);
207         if(range[0]<index2)
208                 range[0] = index2;
209         if(flag==0)
210                 /* set default termination range */
211                 range[1] = (lflag?hist_max(hp)-2:range[0]);
212         if(range[1]>=(flag=(hist_max(hp) - 1)))
213                 range[1] = flag;
214         /* check for valid ranges */
215         if(range[1]<index2 || range[0]>=flag)
216                 error(ERROR_exit(1),e_badrange,range[0],range[1]);
217         if(edit && *edit=='-' && range[0]!=range[1])
218                 error(ERROR_exit(1),e_eneedsarg);
219         /* now list commands from range[rflag] to range[1-rflag] */
220         incr = 1;
221         flag = rflag>0;
222         if(range[1-flag] < range[flag])
223                 incr = -1;
224         if(lflag)
225         {
226                 outfile = sfstdout;
227                 arg = "\n\t";
228         }
229         else
230         {
231                 if(!(fname=pathtemp(NIL(char*),0,0)))
232                         error(ERROR_exit(1),e_create,"");
233                 if((fdo=open(fname,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR)) < 0)
234                         error(ERROR_system(1),e_create,fname);
235                 outfile= sfnew(NIL(Sfio_t*),sh.outbuff,IOBSIZE,fdo,SF_WRITE);
236                 arg = "\n";
237                 nflag++;
238         }
239         while(1)
240         {
241                 if(nflag==0)
242                         sfprintf(outfile,"%d\t",range[flag]);
243                 else if(lflag)
244                         sfputc(outfile,'\t');
245                 hist_list(sh.hist_ptr,outfile,hist_tell(sh.hist_ptr,range[flag]),0,arg);
246                 if(lflag)
247                         sh_sigcheck();
248                 if(range[flag] == range[1-flag])
249                         break;
250                 range[flag] += incr;
251         }
252         if(lflag)
253                 return(0);
254         if(fstat(sffileno(outfile),&statb)>=0)
255                 before = statb.st_mtime;
256         sfclose(outfile);
257         hist_eof(hp);
258         arg = edit;
259         if(!arg && !(arg=nv_getval(nv_scoped(HISTEDIT))) && !(arg=nv_getval(nv_scoped(FCEDNOD))))
260                 arg = (char*)e_defedit;
261 #ifdef apollo
262         /*
263          * Code to support the FC using the pad editor.
264          * Exampled of how to use: HISTEDIT=pad
265          */
266         if (strcmp (arg, "pad") == 0)
267         {
268                 extern __MANGLE__ int pad_create __PROTO__((char*));
269                 sh_close(fdo);
270                 fdo = pad_create(fname);
271                 pad_wait(fdo);
272                 unlink(fname);
273                 strcat(fname, ".bak");
274                 unlink(fname);
275                 lseek(fdo,(off_t)0,SEEK_SET);
276         }
277         else
278         {
279 #endif /* apollo */
280         if(*arg != '-')
281         {
282                 char *com[3];
283                 com[0] =  arg;
284                 com[1] =  fname;
285                 com[2] = 0;
286                 error_info.errors = sh_eval(sh_sfeval(com),0);
287         }
288         fdo = sh_chkopen(fname);
289         unlink(fname);
290         free((__V_*)fname);
291 #ifdef apollo
292         }
293 #endif /* apollo */
294         /* don't history fc itself unless forked */
295         error_info.flags |= ERROR_SILENT;
296         if(!sh_isstate(SH_FORKED))
297                 hist_cancel(hp);
298         sh_onstate(SH_VERBOSE|SH_HISTORY);      /* echo lines as read */
299         if(replace)
300                 hist_subst(error_info.id,fdo,replace);
301         else if(error_info.errors == 0)
302         {
303                 char buff[IOBSIZE+1];
304                 Sfio_t *iop = sfnew(NIL(Sfio_t*),buff,IOBSIZE,fdo,SF_READ);
305                 /* read in and run the command */
306                 sh_eval(iop,1);
307         }
308         else
309         {
310                 sh_close(fdo);
311                 if(!sh_isoption(SH_VERBOSE))
312                         sh_offstate(SH_VERBOSE|SH_HISTORY);
313         }
314         return(sh.exitval);
315 }
316
317
318 /*
319  * given a file containing a command and a string of the form old=new,
320  * execute the command with the string old replaced by new
321  */
322
323 static void hist_subst __PARAM__((const char *command,int fd,char *replace), (command, fd, replace)) __OTORP__(const char *command;int fd;char *replace;){
324         register char *newp=replace;
325         register char *sp;
326         register int c;
327         off_t size;
328         char *string;
329         while(*++newp != '='); /* skip to '=' */
330         if((size = lseek(fd,(off_t)0,SEEK_END)) < 0)
331                 return;
332         lseek(fd,(off_t)0,SEEK_SET);
333         c =  (int)size;
334         string = stakalloc(c+1);
335         if(read(fd,string,c)!=c)
336                 return;
337         string[c] = 0;
338         *newp++ =  0;
339         if((sp=sh_substitute(string,replace,newp))==0)
340                 error(ERROR_exit(1),e_subst,command);
341         *(newp-1) =  '=';
342         sh_eval(sfopen(NIL(Sfio_t*),sp,"s"),1);
343 }
344