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