1 /*
2  * $Id: shellux.c,v 1.4 2003/02/16 12:42:14 isizaka Exp isizaka $
3  *
4  * This file is part of "Ngraph for X11".
5  *
6  * Copyright (C) 2002, Satoshi ISHIZAKA. isizaka@msa.biglobe.ne.jp
7  *
8  * "Ngraph for X11" is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * "Ngraph for X11" is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
21  *
22  */
23 
24 /**
25  *
26  * $Log: shellux.c,v $
27  * Revision 1.4  2003/02/16 12:42:14  isizaka
28  * for release 6.13.18
29  *
30  * Revision 1.3  2002/07/06 08:51:42  isizaka
31  * change to GPL.
32  *
33  * Revision 1.2  1999/04/11 06:08:10  isizaka
34  * *** empty log message ***
35  *
36  * Revision 1.1  1999/03/17 13:46:09  isizaka
37  * Initial revision
38  *
39  *
40  **/
41 
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #ifndef WINDOWS
46 #include <unistd.h>
47 #include <signal.h>
48 #include <time.h>
49 #else
50 #include <windows.h>
51 #include <dos.h>
52 #endif
53 #include "ngraph.h"
54 #include "nstring.h"
55 #include "object.h"
56 #include "ioutil.h"
57 #include "shell.h"
58 #include "shellux.h"
59 
60 #define TRUE  1
61 #define FALSE 0
62 
cmtrue(struct nshell * nshell,int argc,char ** argv)63 int cmtrue(struct nshell *nshell,int argc,char **argv)
64 {
65   return 0;
66 }
67 
cmfalse(struct nshell * nshell,int argc,char ** argv)68 int cmfalse(struct nshell *nshell,int argc,char **argv)
69 {
70   return 1;
71 }
72 
73 #ifndef WINDOWS
74 
75 int timeout;
76 
cmsleeptimeout(int sig)77 void cmsleeptimeout(int sig)
78 {
79   signal(sig,SIG_IGN);
80   timeout=TRUE;
81   signal(SIGALRM,cmsleeptimeout);
82 }
83 
cmsleep(struct nshell * nshell,int argc,char ** argv)84 int cmsleep(struct nshell *nshell,int argc,char **argv)
85 {
86   int a;
87   char *arg,*endptr;
88 
89   if (argc<2) {
90     sherror4(argv[0],ERRSMLARG);
91     return ERRSMLARG;
92   }
93   arg=argv[1];
94   a=strtol(arg,&endptr,10);
95   if (endptr[0]!='\0') {
96     sherror3(argv[0],ERRNUMERIC,arg);
97     return ERRNUMERIC;
98   }
99   timeout=FALSE;
100   signal(SIGALRM,cmsleeptimeout);
101   alarm(a);
102   while (!timeout) eventloop();
103   alarm(0);
104   return 0;
105 }
106 
107 #else
108 
109 typedef struct {
110   int Sleep;
111   int Second;
112 } ThreadParam;
113 
SleepThread(LPVOID lpvThreadParam)114 DWORD WINAPI SleepThread(LPVOID lpvThreadParam)
115 {
116   ThreadParam *pTH;
117 
118   pTH=(ThreadParam *)lpvThreadParam;
119   sleep(pTH->Second);
120   pTH->Sleep=FALSE;
121   return 0;
122 }
123 
cmsleep(struct nshell * nshell,int argc,char ** argv)124 int cmsleep(struct nshell *nshell,int argc,char **argv)
125 {
126   int a;
127   char *arg,*endptr;
128   ThreadParam TH;
129   DWORD IDThread;
130 
131   if (argc<2) {
132     sherror4(argv[0],ERRSMLARG);
133     return ERRSMLARG;
134   }
135   arg=argv[1];
136   a=strtol(arg,&endptr,10);
137   if (endptr[0]!='\0') {
138     sherror3(argv[0],ERRNUMERIC,arg);
139     return ERRNUMERIC;
140   }
141   TH.Sleep=TRUE;
142   TH.Second=a;
143   CreateThread(NULL,0,SleepThread,&TH,0,&IDThread);
144   while (TH.Sleep) eventloop();
145   return 0;
146 }
147 
148 #endif
149 
testexpand(int pre,int * oppo,int * numpo,int numbuf[],char * numbufc[],char opbuf[],int prebuf[])150 int testexpand(int pre,int *oppo,int *numpo,
151                int numbuf[],char *numbufc[],char opbuf[],int prebuf[])
152 {
153   int argnum;
154   int d1,d2;
155   char *endptr1,*endptr2;
156   struct stat buf;
157 
158   while ((*oppo>=0) && (pre<=prebuf[*oppo])) {
159     if (strchr("!nzdefrswx",opbuf[*oppo])!=NULL) argnum=1;
160     else argnum=2;
161     switch (opbuf[*oppo]) {
162     case 'n':
163       if (numbufc[*numpo]==NULL) return FALSE;
164       numbuf[*numpo]=(numbufc[*numpo][0]=='\0')?FALSE:TRUE;
165       numbufc[*numpo]=NULL;
166       break;
167     case 'z':
168       if (numbufc[*numpo]==NULL) return FALSE;
169       numbuf[*numpo]=(numbufc[*numpo][0]=='\0')?TRUE:FALSE;
170       numbufc[*numpo]=NULL;
171       break;
172     case 'd':
173     case 'f':
174     case 'e':
175     case 'r':
176     case 'w':
177     case 'x':
178     case 's':
179       if (numbufc[*numpo]==NULL) return FALSE;
180       if (stat(numbufc[*numpo],&buf)!=0) {
181         numbuf[*numpo]=FALSE;
182         numbufc[*numpo]=NULL;
183         break;
184       }
185       switch (opbuf[*oppo]) {
186       case 'd':
187         numbuf[*numpo]=((buf.st_mode & S_IFMT)==S_IFDIR)?TRUE:FALSE;
188         break;
189       case 'f':
190         numbuf[*numpo]=((buf.st_mode & S_IFMT)==S_IFREG)?TRUE:FALSE;
191         break;
192       case 'e':
193         numbuf[*numpo]=TRUE;
194         break;
195       case 'r':
196         numbuf[*numpo]=((buf.st_mode & S_IREAD)!=0)?TRUE:FALSE;
197         break;
198       case 'w':
199         numbuf[*numpo]=((buf.st_mode & S_IWRITE)!=0)?TRUE:FALSE;
200         break;
201       case 'x':
202         numbuf[*numpo]=((buf.st_mode & S_IEXEC)!=0)?TRUE:FALSE;
203         break;
204       case 's':
205         numbuf[*numpo]=(buf.st_size>0)?TRUE:FALSE;
206         break;
207       }
208       numbufc[*numpo]=NULL;
209       break;
210     case '!':
211       numbuf[*numpo]=(numbuf[*numpo])?FALSE:TRUE;
212       numbufc[*numpo]=NULL;
213       break;
214     case 'o':
215       numbuf[*numpo-1]=numbuf[*numpo-1] || numbuf[*numpo];
216       numbufc[*numpo]=NULL;
217       break;
218     case 'a':
219       numbuf[*numpo-1]=numbuf[*numpo-1] && numbuf[*numpo];
220       numbufc[*numpo]=NULL;
221       break;
222     case '?':
223     case '*':
224     case '>':
225     case '}':
226     case '<':
227     case '{':
228       if ((numbufc[*numpo-1]==NULL) || (numbufc[*numpo]==NULL)) return FALSE;
229       d1=strtol(numbufc[*numpo-1],&endptr1,10);
230       d2=strtol(numbufc[*numpo],&endptr2,10);
231       if ((endptr1[0]!='\0') || (endptr2[0]!='\0')) return FALSE;
232       switch (opbuf[*oppo]) {
233       case '?':
234         numbuf[*numpo-1]=(d1==d2)?TRUE:FALSE;
235         break;
236       case '*':
237         numbuf[*numpo-1]=(d1!=d2)?TRUE:FALSE;
238         break;
239       case '>':
240         numbuf[*numpo-1]=(d1>d2)?TRUE:FALSE;
241         break;
242       case '}':
243         numbuf[*numpo-1]=(d1>=d2)?TRUE:FALSE;
244         break;
245       case '<':
246         numbuf[*numpo-1]=(d1<d2)?TRUE:FALSE;
247         break;
248       case '{':
249         numbuf[*numpo-1]=(d1<=d2)?TRUE:FALSE;
250         break;
251       }
252       numbufc[*numpo-1]=NULL;
253       break;
254     case '=':
255       if ((numbufc[*numpo-1]==NULL) || (numbufc[*numpo]==NULL)) return FALSE;
256       numbuf[*numpo-1]
257       =(strcmp2(numbufc[*numpo-1],numbufc[*numpo])==0)?TRUE:FALSE;
258       numbufc[*numpo-1]=NULL;
259       break;
260     case '+':
261       if ((numbufc[*numpo-1]==NULL) || (numbufc[*numpo]==NULL)) return FALSE;
262       numbuf[*numpo-1]
263       =(strcmp2(numbufc[*numpo-1],numbufc[*numpo])==0)?FALSE:TRUE;
264       numbufc[*numpo-1]=NULL;
265       break;
266     }
267     (*numpo)+=-argnum+1;
268     (*oppo)--;
269   }
270   return TRUE;
271 }
272 
cmtest(struct nshell * nshell,int argc,char ** argv)273 int cmtest(struct nshell *nshell,int argc,char **argv)
274 {
275   int prebuf[20];
276   int numbuf[20];
277   char *numbufc[20];
278   char opbuf[20];
279   int oppo,numpo,numeric;
280   int i;
281 
282   if (argc<2) return 0;
283   numpo=-1;
284   oppo=-1;
285   numeric=FALSE;
286   if (strcmp2(argv[argc-1],"]")==0) argc--;
287   i=1;
288   while (i<argc) {
289     if (!numeric) {
290       if ((strcmp2(argv[i],"!")==0) && ((i+1)<argc)) {
291         if (!testexpand(4,&oppo,&numpo,numbuf,numbufc,opbuf,prebuf)) {
292           sherror4(argv[0],ERRTESTSYNTAX);
293           return 1;
294         }
295         oppo++;
296         if (oppo>=20) {
297           sherror4(argv[0],ERRTESTNEST);
298           return 1;
299         }
300         opbuf[oppo]='!';
301         prebuf[oppo]=4;
302         i++;
303       } else if (((strcmp2(argv[i],"-d")==0) || (strcmp2(argv[i],"-e")==0)
304       || (strcmp2(argv[i],"-f")==0) || (strcmp2(argv[i],"-r")==0)
305       || (strcmp2(argv[i],"-s")==0) || (strcmp2(argv[i],"-w")==0)
306       || (strcmp2(argv[i],"-x")==0) || (strcmp2(argv[i],"-z")==0)
307       || (strcmp2(argv[i],"-n")==0))
308       && ((i+1)<argc)
309       && (strcmp2(argv[i+1],"=")!=0) && (strcmp2(argv[i+1],"!=")!=0)) {
310         if (!testexpand(6,&oppo,&numpo,numbuf,numbufc,opbuf,prebuf)) {
311           sherror4(argv[0],ERRTESTSYNTAX);
312           return 1;
313         }
314         oppo++;
315         if (oppo>=20) {
316           sherror4(argv[0],ERRTESTNEST);
317           return 1;
318         }
319         opbuf[oppo]=argv[i][1];
320         prebuf[oppo]=6;
321         i++;
322       } else if ((strcmp2(argv[i],"(")==0) && ((i+1)<argc)) {
323         oppo++;
324         if (oppo>=20) {
325           sherror4(argv[0],ERRTESTNEST);
326           return 1;
327         }
328         opbuf[oppo]='(';
329         prebuf[oppo]=0;
330         i++;
331       } else {
332         numpo++;
333         if (numpo>=20) {
334           sherror4(argv[0],ERRTESTNEST);
335           return 1;
336         }
337         numbuf[numpo]=strlen(argv[i]);
338         numbufc[numpo]=argv[i];
339         numeric=TRUE;
340         i++;
341       }
342     } else {
343       if (((strcmp2(argv[i],"-eq")==0) || (strcmp2(argv[i],"-ne")==0)
344       || (strcmp2(argv[i],"-gt")==0)  || (strcmp2(argv[i],"-ge")==0)
345       || (strcmp2(argv[i],"-lt")==0)  || (strcmp2(argv[i],"-le")==0)
346       || (strcmp2(argv[i],"=")==0)  || (strcmp2(argv[i],"!=")==0))
347       && ((i+1)<argc)) {
348         if (!testexpand(5,&oppo,&numpo,numbuf,numbufc,opbuf,prebuf)) {
349           sherror4(argv[0],ERRTESTSYNTAX);
350           return 1;
351         }
352         oppo++;
353         if (oppo>=20) {
354           sherror4(argv[0],ERRTESTNEST);
355           return 1;
356         }
357         if (strcmp2(argv[i],"-eq")==0) opbuf[oppo]='?';
358         else if (strcmp2(argv[i],"-ne")==0) opbuf[oppo]='*';
359         else if (strcmp2(argv[i],"-gt")==0) opbuf[oppo]='>';
360         else if (strcmp2(argv[i],"-ge")==0) opbuf[oppo]='}';
361         else if (strcmp2(argv[i],"-lt")==0) opbuf[oppo]='<';
362         else if (strcmp2(argv[i],"-le")==0) opbuf[oppo]='{';
363         else if (strcmp2(argv[i],"=")==0) opbuf[oppo]='=';
364         else if (strcmp2(argv[i],"!=")==0) opbuf[oppo]='+';
365         prebuf[oppo]=5;
366         numeric=FALSE;
367         i++;
368       } else if (strcmp2(argv[i],")")==0) {
369         if (!testexpand(1,&oppo,&numpo,numbuf,numbufc,opbuf,prebuf)) {
370           sherror4(argv[0],ERRTESTSYNTAX);
371           return 1;
372         }
373         if ((oppo!=-1) && (opbuf[oppo]=='(')) oppo--;
374         numeric=TRUE;
375         i++;
376       } else if ((strcmp2(argv[i],"-a")==0) && ((i+1)<argc)) {
377         if (!testexpand(3,&oppo,&numpo,numbuf,numbufc,opbuf,prebuf)) {
378           sherror4(argv[0],ERRTESTSYNTAX);
379           return 1;
380         }
381         oppo++;
382         if (oppo>=20) {
383           sherror4(argv[0],ERRTESTNEST);
384           return 1;
385         }
386         opbuf[oppo]=argv[i][1];
387         prebuf[oppo]=3;
388         numeric=FALSE;
389         i++;
390       } else if ((strcmp2(argv[i],"-o")==0) && ((i+1)<argc)) {
391         if (!testexpand(2,&oppo,&numpo,numbuf,numbufc,opbuf,prebuf)) {
392           sherror4(argv[0],ERRTESTSYNTAX);
393           return 1;
394         }
395         oppo++;
396         if (oppo>=20) {
397           sherror4(argv[0],ERRTESTNEST);
398           return 1;
399         }
400         opbuf[oppo]=argv[i][1];
401         prebuf[oppo]=2;
402         numeric=FALSE;
403         i++;
404       } else if (strcmp2(argv[i],"]")==0) {
405         i++;
406       } else {
407         sherror4(argv[0],ERRTESTSYNTAX);
408         return 1;
409       }
410     }
411   }
412   if (!numeric || !testexpand(1,&oppo,&numpo,numbuf,numbufc,opbuf,prebuf)) {
413     sherror4(argv[0],ERRTESTSYNTAX);
414     return 1;
415   }
416   if ((oppo>-1) || (numpo!=0)) {
417     sherror4(argv[0],ERRTESTSYNTAX);
418     return 1;
419   }
420   if (numbuf[0]) return 0;
421   else return 1;
422 }
423