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
5 * Created by: Marc Horowitz <marc@athena.mit.edu>
9 * Copyright (c) 1989 by the Massachusetts Institute of Technology.
10 * For copying and distribution information, see the file
16 #if (!defined(lint) && !defined(SABER))
17 static const char rcsid_exec_c[] = "$Id$";
20 #include <zephyr/mit-copyright.h>
22 /****************************************************************************/
24 /* Module containing code to execute a program: */
26 /****************************************************************************/
28 #include <zephyr/zephyr.h>
29 #include "new_memory.h"
35 #include "variables.h"
38 static int exec_subtree(Node *);
39 static int exec_fields(Node *);
41 /****************************************************************************/
43 /* Utility subroutines: */
45 /****************************************************************************/
48 eval_exprlist_to_string(Node *exprlist)
50 string result = string_Copy("");
54 for (; exprlist; exprlist=exprlist->next) {
56 result = string_Concat2(result, " ");
60 temp = eval_expr(exprlist);
61 result = string_Concat2(result, temp);
69 eval_exprlist_to_args(Node *exprlist)
71 char **result = (char **)malloc(sizeof(char *));
74 for (; exprlist; exprlist=exprlist->next) {
75 result[argc] = eval_expr(exprlist);
77 result = (char **)realloc(result, (argc+1)*sizeof(char *));
85 free_args(char **args)
89 for (p=args; *p; p++) {
96 /****************************************************************************/
98 /* Subroutines to handle each particular statement type: */
100 /****************************************************************************/
108 exec_noop(Node *node)
115 exec_break(Node *node)
122 exec_exit(Node *node)
130 var_set_variable_then_free_value(node->d.nodes.first->d.string_constant,
131 eval_expr(node->d.nodes.second));
137 exec_execport(Node *node)
139 string name = eval_expr(node->d.nodes.first);
140 char **argv = eval_exprlist_to_args(node->d.nodes.second);
142 create_subprocess_port(name, argv);
150 exec_appendport(Node *node)
152 string name, filename;
154 name = eval_expr(node->d.nodes.first);
155 filename = eval_expr(node->d.nodes.second);
157 create_file_append_port(name, filename);
165 exec_inputport(Node *node)
167 string name, filename;
169 name = eval_expr(node->d.nodes.first);
170 filename = eval_expr(node->d.nodes.second);
172 create_file_input_port(name, filename);
180 exec_outputport(Node *node)
182 string name, filename;
184 name = eval_expr(node->d.nodes.first);
185 filename = eval_expr(node->d.nodes.second);
187 create_file_output_port(name, filename);
195 exec_closeinput(Node *node)
199 name = eval_expr(node->d.nodes.first);
200 close_port_input(name);
207 exec_closeoutput(Node *node)
211 name = eval_expr(node->d.nodes.first);
212 close_port_output(name);
219 exec_closeport(Node *node)
223 name = eval_expr(node->d.nodes.first);
224 close_port_input(name);
225 close_port_output(name);
236 if (node->d.nodes.second)
237 temp = eval_exprlist_to_string(node->d.nodes.second);
239 temp = string_Copy(buffer_to_string());
241 if (node->d.nodes.first) {
242 name = eval_expr(node->d.nodes.first);
244 write_on_port(name, temp, strlen(temp));
247 write_on_port(var_get_variable("output_driver"), temp, strlen(temp));
254 exec_print(Node *node)
258 temp = eval_exprlist_to_string(node->d.nodes.first);
267 exec_clearbuf(Node *node)
275 exec_case(Node *node)
277 string constant,temp;
281 constant = string_Downcase(eval_expr(node->d.nodes.first));
283 for (match=node->d.nodes.second; match; match=match->next) {
284 cond = match->d.nodes.first;
285 if (!cond) { /* default case */
287 return(exec_subtree(match->d.nodes.second));
289 for (; cond; cond=cond->next) {
290 temp = string_Downcase(eval_expr(cond));
291 equal_p = string_Eq(constant, temp);
295 return(exec_subtree(match->d.nodes.second));
305 exec_while(Node *node)
307 int continue_code = NOBREAK;
309 while (eval_bool_expr(node->d.nodes.first)) {
310 continue_code = exec_subtree(node->d.nodes.second);
311 if (continue_code != NOBREAK)
315 if (continue_code == BREAK)
316 continue_code = NOBREAK;
318 return(continue_code);
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));
334 exec_exec(Node *node)
337 char **argv = eval_exprlist_to_args(node->d.nodes.first);
341 fprintf(stderr, "zwgc: error while attempting to fork: ");
343 } else if (pid == 0) { /* in child */
344 execvp(argv[0], argv);
345 fprintf(stderr,"zwgc: unable to exec %s: ", argv[0]);
354 static struct _Opstuff {
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 */
385 { exec_noop }, /* noop statement */
398 { exec_closeoutput },
409 { exec_noop }, /* if */
410 { exec_noop }, /* elseif */
411 { exec_noop }, /* else */
412 { exec_noop }, /* matchlist */
413 { exec_noop }, /* default */
417 exec_subtree(Node *node)
419 int retval = NOBREAK;
421 for (; node; node=node->next) {
422 retval = (opstuff[node->opcode].exec)(node);
423 if (retval != NOBREAK)
430 /***************************************************************************/
432 static char *notice_fields;
433 static int notice_fields_length = 0;
434 static int number_of_fields = 0;
437 exec_fields(Node *node)
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(¬ice_fields,
442 ¬ice_fields_length));
443 if (number_of_fields)
447 var_set_variable_to_number("number_of_fields", number_of_fields);
453 exec_process_packet(Node *program,
456 notice_fields = notice->z_message;
457 notice_fields_length = notice->z_message_len;
459 var_set_number_variables_to_fields(notice_fields, notice_fields_length);
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')
465 var_set_variable_to_number("number_of_fields", number_of_fields);
468 (void)exec_subtree(program);