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(), exec_fields();
40 /****************************************************************************/
42 /* Utility subroutines: */
44 /****************************************************************************/
46 static string eval_exprlist_to_string(exprlist)
49 string result = string_Copy("");
53 for (; exprlist; exprlist=exprlist->next) {
55 result = string_Concat2(result, " ");
59 temp = eval_expr(exprlist);
60 result = string_Concat2(result, temp);
67 static char **eval_exprlist_to_args(exprlist)
70 char **result = (char **)malloc(sizeof(char *));
73 for (; exprlist; exprlist=exprlist->next) {
74 result[argc] = eval_expr(exprlist);
76 result = (char **)realloc(result, (argc+1)*sizeof(char *));
83 static void free_args(args)
88 for (p=args; *p; p++) {
95 /****************************************************************************/
97 /* Subroutines to handle each particular statement type: */
99 /****************************************************************************/
106 static int exec_noop(node)
113 static int exec_break(node)
120 static int exec_exit(node)
126 static int exec_set(node)
129 var_set_variable_then_free_value(node->d.nodes.first->d.string_constant,
130 eval_expr(node->d.nodes.second));
135 static int exec_execport(node)
138 string name = eval_expr(node->d.nodes.first);
139 char **argv = eval_exprlist_to_args(node->d.nodes.second);
141 create_subprocess_port(name, argv);
148 static int exec_appendport(node)
151 string name, filename;
153 name = eval_expr(node->d.nodes.first);
154 filename = eval_expr(node->d.nodes.second);
156 create_file_append_port(name, filename);
163 static int exec_inputport(node)
166 string name, filename;
168 name = eval_expr(node->d.nodes.first);
169 filename = eval_expr(node->d.nodes.second);
171 create_file_input_port(name, filename);
178 static int exec_outputport(node)
181 string name, filename;
183 name = eval_expr(node->d.nodes.first);
184 filename = eval_expr(node->d.nodes.second);
186 create_file_output_port(name, filename);
193 static int exec_closeinput(node)
198 name = eval_expr(node->d.nodes.first);
199 close_port_input(name);
205 static int exec_closeoutput(node)
210 name = eval_expr(node->d.nodes.first);
211 close_port_output(name);
217 static int exec_closeport(node)
222 name = eval_expr(node->d.nodes.first);
223 close_port_input(name);
224 close_port_output(name);
230 static int exec_put(node)
235 if (node->d.nodes.second)
236 temp = eval_exprlist_to_string(node->d.nodes.second);
238 temp = string_Copy(buffer_to_string());
240 if (node->d.nodes.first) {
241 name = eval_expr(node->d.nodes.first);
243 write_on_port(name, temp, strlen(temp));
246 write_on_port(var_get_variable("output_driver"), temp, strlen(temp));
252 static int exec_print(node)
257 temp = eval_exprlist_to_string(node->d.nodes.first);
265 static int exec_clearbuf(node)
273 static int exec_case(node)
276 string constant,temp;
280 constant = string_Downcase(eval_expr(node->d.nodes.first));
282 for (match=node->d.nodes.second; match; match=match->next) {
283 cond = match->d.nodes.first;
284 if (!cond) { /* default case */
286 return(exec_subtree(match->d.nodes.second));
288 for (; cond; cond=cond->next) {
289 temp = string_Downcase(eval_expr(cond));
290 equal_p = string_Eq(constant, temp);
294 return(exec_subtree(match->d.nodes.second));
303 static int exec_while(node)
306 int continue_code = NOBREAK;
308 while (eval_bool_expr(node->d.nodes.first)) {
309 continue_code = exec_subtree(node->d.nodes.second);
310 if (continue_code != NOBREAK)
314 if (continue_code == BREAK)
315 continue_code = NOBREAK;
317 return(continue_code);
320 static int exec_if(node)
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));
332 static int exec_exec(node)
336 char **argv = eval_exprlist_to_args(node->d.nodes.first);
340 fprintf(stderr, "zwgc: error while attempting to fork: ");
342 } else if (pid == 0) { /* in child */
343 execvp(argv[0], argv);
344 fprintf(stderr,"zwgc: unable to exec %s: ", argv[0]);
353 static struct _Opstuff {
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 */
384 { exec_noop }, /* noop statement */
397 { exec_closeoutput },
408 { exec_noop }, /* if */
409 { exec_noop }, /* elseif */
410 { exec_noop }, /* else */
411 { exec_noop }, /* matchlist */
412 { exec_noop }, /* default */
415 static int exec_subtree(node)
418 int retval = NOBREAK;
420 for (; node; node=node->next) {
421 retval = (opstuff[node->opcode].exec)(node);
422 if (retval != NOBREAK)
429 /***************************************************************************/
431 static char *notice_fields;
432 static int notice_fields_length = 0;
433 static int number_of_fields = 0;
435 static int exec_fields(node)
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(¬ice_fields,
441 ¬ice_fields_length));
442 if (number_of_fields)
446 var_set_variable_to_number("number_of_fields", number_of_fields);
451 void exec_process_packet(program, notice)
455 notice_fields = notice->z_message;
456 notice_fields_length = notice->z_message_len;
458 var_set_number_variables_to_fields(notice_fields, notice_fields_length);
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')
464 var_set_variable_to_number("number_of_fields", number_of_fields);
467 (void)exec_subtree(program);