]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blob - zephyr/zwgc/exec.c
1bf8f724908fcfa5d7fbdbcc3ac0cfada63be623
[1ts-debian.git] / zephyr / zwgc / exec.c
1 /* This file is part of the Project Athena Zephyr Notification System.
2  * It is one of the source files comprising zwgc, the Zephyr WindowGram
3  * client.
4  *
5  *      Created by:     Marc Horowitz <marc@athena.mit.edu>
6  *
7  *      $Id$
8  *
9  *      Copyright (c) 1989 by the Massachusetts Institute of Technology.
10  *      For copying and distribution information, see the file
11  *      "mit-copyright.h".
12  */
13
14 #include <sysdep.h>
15
16 #if (!defined(lint) && !defined(SABER))
17 static const char rcsid_exec_c[] = "$Id$";
18 #endif
19
20 #include <zephyr/mit-copyright.h>
21
22 /****************************************************************************/
23 /*                                                                          */
24 /*               Module containing code to execute a program:               */
25 /*                                                                          */
26 /****************************************************************************/
27
28 #include <zephyr/zephyr.h>
29 #include "new_memory.h"
30 #include "exec.h"
31 #include "eval.h"
32 #include "node.h"
33 #include "buffer.h"
34 #include "port.h"
35 #include "variables.h"
36 #include "notice.h"
37
38 static int exec_subtree(), exec_fields();
39
40 /****************************************************************************/
41 /*                                                                          */
42 /*                           Utility subroutines:                          */
43 /*                                                                          */
44 /****************************************************************************/
45
46 static string eval_exprlist_to_string(exprlist)
47      Node *exprlist;
48 {
49     string result = string_Copy("");
50     string temp;
51     int first_time = 1;
52     
53     for (; exprlist; exprlist=exprlist->next) {
54         if (!first_time)
55           result = string_Concat2(result, " ");
56         else
57           first_time = 0;
58         
59         temp = eval_expr(exprlist);
60         result = string_Concat2(result, temp);
61         free(temp);
62     }
63     
64     return(result);
65 }
66
67 static char **eval_exprlist_to_args(exprlist)
68      Node *exprlist;
69 {
70     char **result = (char **)malloc(sizeof(char *));
71     int argc = 0;
72
73     for (; exprlist; exprlist=exprlist->next) {
74         result[argc] = eval_expr(exprlist);
75         argc++;
76         result = (char **)realloc(result, (argc+1)*sizeof(char *));
77     }
78     
79     result[argc] = NULL;
80     return(result);
81 }
82
83 static void free_args(args)
84      char **args;
85 {
86     char **p;
87
88     for (p=args; *p; p++) {
89       free(*p);
90   }
91         
92     free(args);
93 }
94
95 /****************************************************************************/
96 /*                                                                          */
97 /*          Subroutines to handle each particular statement type:           */
98 /*                                                                          */
99 /****************************************************************************/
100
101 #define  NOBREAK   0
102 #define  BREAK     1
103 #define  EXIT      2
104
105 /*ARGSUSED*/
106 static int exec_noop(node)
107      Node *node;
108 {
109     return(NOBREAK);
110 }
111
112 /*ARGSUSED*/
113 static int exec_break(node)
114      Node *node;
115 {
116     return(BREAK);
117 }
118
119 /*ARGSUSED*/
120 static int exec_exit(node)
121      Node *node;
122 {
123     return(EXIT);
124 }
125
126 static int exec_set(node)
127      Node *node;
128 {
129     var_set_variable_then_free_value(node->d.nodes.first->d.string_constant,
130                                      eval_expr(node->d.nodes.second));
131
132     return(NOBREAK);
133 }
134
135 static int exec_execport(node)
136      Node *node;
137 {
138     string name = eval_expr(node->d.nodes.first);
139     char **argv = eval_exprlist_to_args(node->d.nodes.second);
140
141     create_subprocess_port(name, argv);
142
143     free(name);
144     free_args(argv);
145     return(NOBREAK);
146 }
147
148 static int exec_appendport(node)
149      Node *node;
150 {
151     string name, filename;
152
153     name = eval_expr(node->d.nodes.first);
154     filename = eval_expr(node->d.nodes.second);
155
156     create_file_append_port(name, filename);
157
158     free(name);
159     free(filename);
160     return(NOBREAK);
161 }
162
163 static int exec_inputport(node)
164      Node *node;
165 {
166     string name, filename;
167
168     name = eval_expr(node->d.nodes.first);
169     filename = eval_expr(node->d.nodes.second);
170
171     create_file_input_port(name, filename);
172
173     free(name);
174     free(filename);
175     return(NOBREAK);
176 }
177
178 static int exec_outputport(node)
179      Node *node;
180 {
181     string name, filename;
182
183     name = eval_expr(node->d.nodes.first);
184     filename = eval_expr(node->d.nodes.second);
185
186     create_file_output_port(name, filename);
187
188     free(name);
189     free(filename);
190     return(NOBREAK);
191 }
192
193 static int exec_closeinput(node)
194      Node *node;
195 {
196     string name;
197
198     name = eval_expr(node->d.nodes.first);
199     close_port_input(name);
200
201     free(name);
202     return(NOBREAK);
203 }
204
205 static int exec_closeoutput(node)
206      Node *node;
207 {
208     string name;
209
210     name = eval_expr(node->d.nodes.first);
211     close_port_output(name);
212
213     free(name);
214     return(NOBREAK);
215 }
216
217 static int exec_closeport(node)
218      Node *node;
219 {
220     string name;
221
222     name = eval_expr(node->d.nodes.first);
223     close_port_input(name);
224     close_port_output(name);
225
226     free(name);
227     return(NOBREAK);
228 }
229
230 static int exec_put(node)
231      Node *node;
232 {
233     string name, temp;
234
235     if (node->d.nodes.second)
236       temp = eval_exprlist_to_string(node->d.nodes.second);
237     else
238       temp = string_Copy(buffer_to_string());
239
240     if (node->d.nodes.first) {
241         name = eval_expr(node->d.nodes.first);
242
243         write_on_port(name, temp, strlen(temp));
244         free(name);
245     } else
246       write_on_port(var_get_variable("output_driver"), temp, strlen(temp));
247
248     free(temp);
249     return(NOBREAK);
250 }
251
252 static int exec_print(node)
253      Node *node;
254 {
255     string temp;
256
257     temp = eval_exprlist_to_string(node->d.nodes.first);
258     append_buffer(temp);
259     free(temp);
260     
261     return(NOBREAK);
262 }
263
264 /*ARGSUSED*/
265 static int exec_clearbuf(node)
266      Node *node;
267 {
268     clear_buffer();
269
270     return(NOBREAK);
271 }
272
273 static int exec_case(node)
274      Node *node;
275 {
276     string constant,temp;
277     Node *match, *cond;
278     int equal_p;
279
280     constant = string_Downcase(eval_expr(node->d.nodes.first));
281    
282     for (match=node->d.nodes.second; match; match=match->next) {
283         cond = match->d.nodes.first;
284         if (!cond) {  /* default case */
285             free(constant);
286             return(exec_subtree(match->d.nodes.second));
287         }
288         for (; cond; cond=cond->next) {
289             temp = string_Downcase(eval_expr(cond));
290             equal_p = string_Eq(constant, temp);
291             free(temp);
292             if (equal_p) {
293                 free(constant);
294                 return(exec_subtree(match->d.nodes.second));
295             }
296         }
297     }
298
299     free(constant);
300     return(NOBREAK);
301 }
302
303 static int exec_while(node)
304      Node *node;
305 {
306     int continue_code = NOBREAK;
307
308     while (eval_bool_expr(node->d.nodes.first)) {
309         continue_code = exec_subtree(node->d.nodes.second);
310         if (continue_code != NOBREAK)
311           break;
312     }
313
314     if (continue_code == BREAK)
315       continue_code = NOBREAK;
316
317     return(continue_code);
318 }
319
320 static int exec_if(node)
321      Node *node;
322 {
323     Node *conds;
324
325     for (conds=node->d.nodes.first; conds; conds=conds->next)
326       if (eval_bool_expr(conds->d.nodes.first))
327         return(exec_subtree(conds->d.nodes.second));
328
329     return(NOBREAK);
330 }
331
332 static int exec_exec(node)
333      Node *node;
334 {
335     int pid;
336     char **argv = eval_exprlist_to_args(node->d.nodes.first);
337
338     pid = fork();
339     if (pid == -1) {
340         fprintf(stderr, "zwgc: error while attempting to fork: ");
341         perror("");
342     } else if (pid == 0) { /* in child */
343         execvp(argv[0], argv);
344         fprintf(stderr,"zwgc: unable to exec %s: ", argv[0]);
345         perror("");
346         _exit(errno);
347     }
348     
349     free_args(argv);
350     return(NOBREAK);
351 }
352
353 static struct _Opstuff {
354     int (*exec)();
355 } const opstuff[] = {
356     { exec_noop },                         /* string_constant */
357     { exec_noop },                         /* varref */
358     { exec_noop },                         /* varname */
359     { exec_noop },                         /* not */
360     { exec_noop },                         /* plus */
361     { exec_noop },                         /* and */
362     { exec_noop },                         /* or */
363     { exec_noop },                         /* eq */
364     { exec_noop },                         /* neq */
365     { exec_noop },                         /* regeq */
366     { exec_noop },                         /* regneq */
367     { exec_noop },                         /* buffer */
368     { exec_noop },                         /* substitute */
369     { exec_noop },                         /* protect */
370     { exec_noop },                         /* verbatim */
371     { exec_noop },                         /* stylestrip */
372     { exec_noop },                         /* getenv */
373     { exec_noop },                         /* upcase */
374     { exec_noop },                         /* downcase */
375     { exec_noop },                         /* zvar */
376     { exec_noop },                         /* get */
377     { exec_noop },                         /* lany */
378     { exec_noop },                         /* rany */
379     { exec_noop },                         /* lbreak */
380     { exec_noop },                         /* rbreak */
381     { exec_noop },                         /* lspan */
382     { exec_noop },                         /* rspan */
383
384     { exec_noop },                          /* noop statement */
385     { exec_set },
386     { exec_fields },
387
388     { exec_print },
389     { exec_clearbuf },
390
391     { exec_appendport },
392     { exec_execport },
393     { exec_inputport },
394     { exec_outputport },
395     { exec_put },
396     { exec_closeinput },
397     { exec_closeoutput },
398     { exec_closeport },
399
400     { exec_exec },
401
402     { exec_if },
403     { exec_case },
404     { exec_while },
405     { exec_break },
406     { exec_exit },
407
408     { exec_noop },                           /* if */
409     { exec_noop },                           /* elseif */
410     { exec_noop },                           /* else */
411     { exec_noop },                           /* matchlist */
412     { exec_noop },                           /* default */
413 };
414
415 static int exec_subtree(node)
416      Node *node;
417 {
418     int retval = NOBREAK;
419     
420     for (; node; node=node->next) {
421         retval = (opstuff[node->opcode].exec)(node);
422         if (retval != NOBREAK)
423           return(retval);
424     }
425
426     return(NOBREAK);
427 }
428
429 /***************************************************************************/
430
431 static char *notice_fields;
432 static int notice_fields_length = 0;
433 static int number_of_fields = 0;
434
435 static int exec_fields(node)
436      Node *node;
437 {
438     for (node=node->d.nodes.first; node; node=node->next) {
439         var_set_variable_then_free_value(node->d.string_constant,
440                                  get_next_field(&notice_fields,
441                                                 &notice_fields_length));
442         if (number_of_fields)
443           number_of_fields--;
444     }
445     
446     var_set_variable_to_number("number_of_fields", number_of_fields);
447
448     return(NOBREAK);
449 }
450
451 void exec_process_packet(program, notice)
452      Node *program;
453      ZNotice_t *notice;
454 {
455     notice_fields = notice->z_message;
456     notice_fields_length = notice->z_message_len;
457
458     var_set_number_variables_to_fields(notice_fields, notice_fields_length);
459
460     number_of_fields = count_nulls(notice_fields, notice_fields_length)+1;
461     /* workaround for bug in old zwrite */
462     if (notice_fields[notice_fields_length-1] == '\0')
463         number_of_fields--;
464     var_set_variable_to_number("number_of_fields", number_of_fields);
465
466     clear_buffer();
467     (void)exec_subtree(program);
468 }