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