00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "mit-copyright.h"
00010
00011
00012
00013
00014
00015
00016
00017 #include "main.h"
00018 #include "exec.h"
00019 #include "eval.h"
00020 #include "node.h"
00021 #include "buffer.h"
00022 #include "port.h"
00023 #include "variables.h"
00024 #include "notice.h"
00025
00026 static int exec_subtree(), exec_fields();
00027
00028
00029
00030
00031
00032
00033
00034 static string
00035 eval_exprlist_to_string(exprlist)
00036 Node *exprlist;
00037 {
00038 string result = string_Copy("");
00039 string temp;
00040 int first_time = 1;
00041
00042 for (; exprlist; exprlist = exprlist->next) {
00043 if (!first_time)
00044 result = string_Concat2(result, " ");
00045 else
00046 first_time = 0;
00047
00048 temp = eval_expr(exprlist);
00049 result = string_Concat2(result, temp);
00050 free(temp);
00051 }
00052
00053 return (result);
00054 }
00055
00056 static char **
00057 eval_exprlist_to_args(exprlist)
00058 Node *exprlist;
00059 {
00060 char **result = (char **) malloc(sizeof(char *));
00061 int argc = 0;
00062
00063 for (; exprlist; exprlist = exprlist->next) {
00064 result[argc] = eval_expr(exprlist);
00065 argc++;
00066 result = (char **) realloc(result, (argc + 1) * sizeof(char *));
00067 }
00068
00069 result[argc] = NULL;
00070 return (result);
00071 }
00072
00073 static void
00074 free_args(args)
00075 char **args;
00076 {
00077 char **p;
00078
00079 for (p = args; *p; p++) {
00080 free(*p);
00081 }
00082
00083 free(args);
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 #define NOBREAK 0
00093 #define BREAK 1
00094 #define EXIT 2
00095
00096
00097 static int
00098 exec_noop(node)
00099 Node *node;
00100 {
00101 return (NOBREAK);
00102 }
00103
00104
00105 static int
00106 exec_break(node)
00107 Node *node;
00108 {
00109 return (BREAK);
00110 }
00111
00112
00113 static int
00114 exec_exit(node)
00115 Node *node;
00116 {
00117 return (EXIT);
00118 }
00119
00120 static int
00121 exec_set(node)
00122 Node *node;
00123 {
00124 var_set_variable_then_free_value(node->d.nodes.first->d.string_constant,
00125 eval_expr(node->d.nodes.second));
00126
00127 return (NOBREAK);
00128 }
00129
00130 static int
00131 exec_execport(node)
00132 Node *node;
00133 {
00134 string name = eval_expr(node->d.nodes.first);
00135 char **argv = eval_exprlist_to_args(node->d.nodes.second);
00136
00137 create_subprocess_port(name, argv);
00138
00139 free(name);
00140 free_args(argv);
00141 return (NOBREAK);
00142 }
00143
00144 static int
00145 exec_appendport(node)
00146 Node *node;
00147 {
00148 string name, filename;
00149
00150 name = eval_expr(node->d.nodes.first);
00151 filename = eval_expr(node->d.nodes.second);
00152
00153 create_file_append_port(name, filename);
00154
00155 free(name);
00156 free(filename);
00157 return (NOBREAK);
00158 }
00159
00160 static int
00161 exec_inputport(node)
00162 Node *node;
00163 {
00164 string name, filename;
00165
00166 name = eval_expr(node->d.nodes.first);
00167 filename = eval_expr(node->d.nodes.second);
00168
00169 create_file_input_port(name, filename);
00170
00171 free(name);
00172 free(filename);
00173 return (NOBREAK);
00174 }
00175
00176 static int
00177 exec_outputport(node)
00178 Node *node;
00179 {
00180 string name, filename;
00181
00182 name = eval_expr(node->d.nodes.first);
00183 filename = eval_expr(node->d.nodes.second);
00184
00185 create_file_output_port(name, filename);
00186
00187 free(name);
00188 free(filename);
00189 return (NOBREAK);
00190 }
00191
00192 static int
00193 exec_closeinput(node)
00194 Node *node;
00195 {
00196 string name;
00197
00198 name = eval_expr(node->d.nodes.first);
00199 close_port_input(name);
00200
00201 free(name);
00202 return (NOBREAK);
00203 }
00204
00205 static int
00206 exec_closeoutput(node)
00207 Node *node;
00208 {
00209 string name;
00210
00211 name = eval_expr(node->d.nodes.first);
00212 close_port_output(name);
00213
00214 free(name);
00215 return (NOBREAK);
00216 }
00217
00218 static int
00219 exec_closeport(node)
00220 Node *node;
00221 {
00222 string name;
00223
00224 name = eval_expr(node->d.nodes.first);
00225 close_port_input(name);
00226 close_port_output(name);
00227
00228 free(name);
00229 return (NOBREAK);
00230 }
00231
00232 static int
00233 exec_put(node)
00234 Node *node;
00235 {
00236 string name, temp;
00237
00238 if (node->d.nodes.second)
00239 temp = eval_exprlist_to_string(node->d.nodes.second);
00240 else
00241 temp = string_Copy(buffer_to_string());
00242
00243 if (node->d.nodes.first) {
00244 name = eval_expr(node->d.nodes.first);
00245
00246 write_on_port(name, temp, strlen(temp));
00247 free(name);
00248 }
00249 else
00250 write_on_port(var_get_variable("output_driver"), temp, strlen(temp));
00251
00252 free(temp);
00253 return (NOBREAK);
00254 }
00255
00256 static int
00257 exec_print(node)
00258 Node *node;
00259 {
00260 string temp;
00261
00262 temp = eval_exprlist_to_string(node->d.nodes.first);
00263 append_buffer(temp);
00264 free(temp);
00265
00266 return (NOBREAK);
00267 }
00268
00269
00270 static int
00271 exec_clearbuf(node)
00272 Node *node;
00273 {
00274 clear_buffer();
00275
00276 return (NOBREAK);
00277 }
00278
00279 static int
00280 exec_case(node)
00281 Node *node;
00282 {
00283 string constant, temp;
00284 Node *match, *cond;
00285 int equal_p;
00286
00287 constant = string_Downcase(eval_expr(node->d.nodes.first));
00288
00289 for (match = node->d.nodes.second; match; match = match->next) {
00290 cond = match->d.nodes.first;
00291 if (!cond) {
00292 free(constant);
00293 return (exec_subtree(match->d.nodes.second));
00294 }
00295 for (; cond; cond = cond->next) {
00296 temp = string_Downcase(eval_expr(cond));
00297 equal_p = string_Eq(constant, temp);
00298 free(temp);
00299 if (equal_p) {
00300 free(constant);
00301 return (exec_subtree(match->d.nodes.second));
00302 }
00303 }
00304 }
00305
00306 free(constant);
00307 return (NOBREAK);
00308 }
00309
00310 static int
00311 exec_while(node)
00312 Node *node;
00313 {
00314 int continue_code = NOBREAK;
00315
00316 while (eval_bool_expr(node->d.nodes.first)) {
00317 continue_code = exec_subtree(node->d.nodes.second);
00318 if (continue_code != NOBREAK)
00319 break;
00320 }
00321
00322 if (continue_code == BREAK)
00323 continue_code = NOBREAK;
00324
00325 return (continue_code);
00326 }
00327
00328 static int
00329 exec_if(node)
00330 Node *node;
00331 {
00332 Node *conds;
00333
00334 for (conds = node->d.nodes.first; conds; conds = conds->next)
00335 if (eval_bool_expr(conds->d.nodes.first))
00336 return (exec_subtree(conds->d.nodes.second));
00337
00338 return (NOBREAK);
00339 }
00340
00341 static int
00342 exec_exec(node)
00343 Node *node;
00344 {
00345 int pid;
00346 char **argv = eval_exprlist_to_args(node->d.nodes.first);
00347
00348 pid = fork();
00349 if (pid == -1) {
00350 fprintf(stderr, "jwgc: error while attempting to fork: ");
00351 perror("");
00352 }
00353 else if (pid == 0) {
00354 execvp(argv[0], argv);
00355 fprintf(stderr, "jwgc: unable to exec %s: ", argv[0]);
00356 perror("");
00357 _exit(errno);
00358 }
00359
00360 free_args(argv);
00361 return (NOBREAK);
00362 }
00363
00364 static struct _Opstuff {
00365 int (*exec) ();
00366 } const opstuff[] = {
00367 {exec_noop},
00368 {exec_noop},
00369 {exec_noop},
00370 {exec_noop},
00371 {exec_noop},
00372 {exec_noop},
00373 {exec_noop},
00374 {exec_noop},
00375 {exec_noop},
00376 {exec_noop},
00377 {exec_noop},
00378 {exec_noop},
00379 {exec_noop},
00380 {exec_noop},
00381 {exec_noop},
00382 {exec_noop},
00383 {exec_noop},
00384 {exec_noop},
00385 {exec_noop},
00386 {exec_noop},
00387 {exec_noop},
00388 {exec_noop},
00389 {exec_noop},
00390 {exec_noop},
00391 {exec_noop},
00392 {exec_noop},
00393 {exec_noop},
00394
00395 {exec_noop},
00396 {exec_set},
00397 {exec_fields},
00398
00399 {exec_print},
00400 {exec_clearbuf},
00401
00402 {exec_appendport},
00403 {exec_execport},
00404 {exec_inputport},
00405 {exec_outputport},
00406 {exec_put},
00407 {exec_closeinput},
00408 {exec_closeoutput},
00409 {exec_closeport},
00410
00411 {exec_exec},
00412
00413 {exec_if},
00414 {exec_case},
00415 {exec_while},
00416 {exec_break},
00417 {exec_exit},
00418
00419 {exec_noop},
00420 {exec_noop},
00421 {exec_noop},
00422 {exec_noop},
00423 {exec_noop},
00424 };
00425
00426 static int
00427 exec_subtree(node)
00428 Node *node;
00429 {
00430 int retval = NOBREAK;
00431
00432 for (; node; node = node->next) {
00433 retval = (opstuff[node->opcode].exec) (node);
00434 if (retval != NOBREAK)
00435 return (retval);
00436 }
00437
00438 return (NOBREAK);
00439 }
00440
00441
00442
00443 static char *notice_fields;
00444 static int notice_fields_length = 0;
00445 static int number_of_fields = 0;
00446
00447 static int
00448 exec_fields(node)
00449 Node *node;
00450 {
00451 for (node = node->d.nodes.first; node; node = node->next) {
00452 var_set_variable_then_free_value(node->d.string_constant,
00453 get_next_field(¬ice_fields,
00454 ¬ice_fields_length));
00455 if (number_of_fields)
00456 number_of_fields--;
00457 }
00458
00459 var_set_variable_to_number("number_of_fields", number_of_fields);
00460
00461 return (NOBREAK);
00462 }
00463
00464 void
00465 exec_process_packet(program, notice, body, body_sz)
00466 Node *program;
00467 struct jpacket_struct *notice;
00468 char *body;
00469 int body_sz;
00470 {
00471 notice_fields = body;
00472 notice_fields_length = body_sz;
00473
00474 var_set_number_variables_to_fields(notice_fields, notice_fields_length);
00475
00476 number_of_fields = count_nulls(notice_fields, notice_fields_length) + 1;
00477
00478 if (notice_fields[notice_fields_length - 1] == '\0')
00479 number_of_fields--;
00480 var_set_variable_to_number("number_of_fields", number_of_fields);
00481
00482 clear_buffer();
00483 (void) exec_subtree(program);
00484 }