00001 00005 #include <malloc.h> 00006 #include <string.h> 00007 00008 #include "libmgk.h" 00009 #include "allocate.h" 00010 00011 DEFINE_ALLOCATOR(mgk_mask_trigger, 50, next); 00012 DEFINE_ALLOCATOR(mgk_remnode, 50, next); 00013 00014 mgk_node **__mgk_local_nodes = NULL; 00015 int __mgk_num_local_nodes = 0; 00016 static int max_table_size = 0; 00017 static mgk_remnode *stub_list = NULL; 00018 00019 static int 00020 grow_table(void) 00021 { 00022 static int table_alloc = 250; 00023 static int table_alloc_inc = 256; 00024 mgk_node **ntab = malloc(sizeof(mgk_node *) * table_alloc); 00025 if (ntab) { 00026 if (__mgk_num_local_nodes > 0) { 00027 memcpy(ntab, 00028 __mgk_local_nodes, 00029 (sizeof(mgk_node *) * __mgk_num_local_nodes)); 00030 } 00031 if (__mgk_local_nodes) { 00032 free(__mgk_local_nodes); 00033 } 00034 __mgk_local_nodes = ntab; 00035 max_table_size = table_alloc; 00036 table_alloc += table_alloc_inc; 00037 table_alloc_inc *= 2; 00038 return (TRUE); 00039 } 00040 return (FALSE); 00041 } 00042 00043 mgk_nodep 00044 mgk_create_node(mgk_script fn, unsigned int nin, unsigned int nout, 00045 unsigned int priority, 00046 mgk_trigger_mode tmode) 00047 { 00048 mgk_node *node; 00049 char *memptr; 00050 int i, crcbyte; 00051 long crc; 00052 00053 if (fn == NULL) { 00054 mgk_errno = E_SCRIPTNOTFOUND; 00055 return (NULL); 00056 } 00057 if ((nin >= MGK_MAX_PORT_COUNT) || (nout >= MGK_MAX_PORT_COUNT)) { 00058 mgk_errno = E_BADPORTIX; 00059 return (NULL); 00060 } 00061 if ((tmode != AT_IFALL) && (tmode != AT_IFANY) && (tmode != AT_SPEC)) { 00062 mgk_errno = E_BADTRIGGER; 00063 return (NULL); 00064 } 00065 if (__mgk_num_local_nodes == max_table_size) { 00066 if (!grow_table()) { 00067 mgk_errno = E_NOMEM; 00068 return (NULL); 00069 } 00070 } 00071 node = malloc((sizeof(mgk_node)) + 00072 (sizeof(mgk_inport) * nin) + 00073 (sizeof(mgk_outport) * nout)); 00074 if (!node) { 00075 mgk_errno = E_NOMEM; 00076 return (NULL); 00077 } 00078 memptr = (char *)node; 00079 memset(node, 0, sizeof(mgk_node)); 00080 node->tag = OBJ_NODE; 00081 node->script = fn; 00082 node->ins = (mgk_inport *) (memptr += sizeof(mgk_node)); 00083 node->outs = (mgk_outport *) (memptr += (sizeof(mgk_inport) * nin)); 00084 node->nin = nin; 00085 node->nout = nout; 00086 if (nin > 0) { 00087 int i; 00088 memset(node->ins, 0, (sizeof(mgk_inport) * nin)); 00089 for(i = 0; i < (int)nin; i++) { 00090 mgk_set_portmask_bit(node->input_mask,i,1); 00091 } 00092 } 00093 if (nout > 0) { 00094 memset(node->outs, 0, (sizeof(mgk_outport) * nout)); 00095 } 00096 node->priority = max(min(priority, MGK_MAX_NODE_PRIORITY), 00097 MGK_NODE_STOP_PRIORITY); 00098 node->tmode = tmode; 00099 __mgk_update(node); 00100 crc = (long)node ^ (long)node->script ^ 00101 node->nin ^ node->nout ^ 00102 __mgk_num_local_nodes; 00103 for (memptr = (char *)(&crc), i = crcbyte = 0; i < sizeof(crc); i++) { 00104 crcbyte ^= memptr[i]; 00105 } 00106 node->ID = __mgk_num_local_nodes | ((long)crcbyte << 24); 00107 __mgk_local_nodes[__mgk_num_local_nodes++] = node; 00108 return (node); 00109 } 00110 00111 mgk_nodep 00112 mgk_create_node_indirect(char *scriptname, 00113 unsigned int nin, unsigned int nout, 00114 unsigned int priority, 00115 mgk_trigger_mode tmode, mgk_hostp host) 00116 { 00117 if ((host == MGK_LOCALHOST) || (host == __mgk_local_host)) { 00118 return (mgk_create_node(__mgk_lookup_script(scriptname), 00119 nin, nout, priority, tmode)); 00120 } 00121 if (__mgk_check_host(host)) { 00122 mgk_value *args[5], *rargs[2]; 00123 args[0] = __mgk_build_value(scriptname, T_STRING); 00124 args[1] = __mgk_build_value(&nin, T_INTEGER); 00125 args[2] = __mgk_build_value(&nout, T_INTEGER); 00126 args[3] = __mgk_build_value(&priority, T_INTEGER); 00127 args[4] = __mgk_build_value(&tmode, T_INTEGER); 00128 if (__mgk_remote_call(host, 00129 cmd_create_node_indirect, 00130 5, args, 00131 2, rargs)) { 00132 mgk_data_type t1, t2; 00133 mgk_scalar s1, s2; 00134 long *idp = __mgk_extract_value(rargs[0], &t1, &s1); 00135 int *errp = __mgk_extract_value(rargs[1], &t2, &s2); 00136 if ((t1 == T_LONGINT) && 00137 (t2 == T_INTEGER) && 00138 ((mgk_errno = *errp) == E_SUCCESS)) { 00139 return ((mgk_node *) __mgk_remnode_stub(host, *idp)); 00140 } 00141 return (NULL); 00142 } 00143 mgk_errno = E_COMM; 00144 return (NULL); 00145 } 00146 mgk_errno = E_NOTHOST; 00147 return (NULL); 00148 } 00149 00150 DEFSVC(create_node_indirect) 00151 { 00152 if ((argc == 5) && (rargc == 2)) { 00153 mgk_data_type t1, t2, t3, t4, t5; 00154 char *sname = __mgk_parse_value(argv[0], &t1); 00155 int *ninp = __mgk_parse_value(argv[1], &t2); 00156 int *noutp = __mgk_parse_value(argv[2], &t3); 00157 int *priop = __mgk_parse_value(argv[3], &t4); 00158 int *tmodep = __mgk_parse_value(argv[4], &t5); 00159 if ((t1 == (T_CHAR | T_BUFFER)) && 00160 (t2 == T_INTEGER) && 00161 (t3 == T_INTEGER) && 00162 (t4 == T_INTEGER) && 00163 (t5 == T_INTEGER)) { 00164 mgk_node *res = mgk_create_node_indirect(sname, 00165 *ninp, *noutp, *priop, 00166 (mgk_trigger_mode) (*tmodep), 00167 MGK_LOCALHOST); 00168 long ID = res ? res->ID : 0; 00169 rargv[0] = __mgk_build_value(&ID, T_LONGINT); 00170 rargv[1] = __mgk_build_value(&mgk_errno, T_INTEGER); 00171 return (TRUE); 00172 } 00173 } 00174 return (FALSE); 00175 } 00176 00177 mgk_error_code 00178 mgk_add_node_trigger_mask_disp(mgk_nodep node, 00179 mgk_portmask mask, 00180 mgk_script fn) 00181 { 00182 mgk_mask_trigger *tm; 00183 if (!__mgk_check_node(node)) { 00184 return (E_NOTNODE); 00185 } 00186 if (!fn) { 00187 return (E_SCRIPTNOTFOUND); 00188 } 00189 if (node->tmode != AT_SPEC) { 00190 return (E_BADTRIGGER); 00191 } 00192 if (!(tm = ALLOC_mgk_mask_trigger())) { 00193 return (E_NOMEM); 00194 } 00195 memcpy(tm->mask, mask, sizeof(mgk_portmask)); 00196 tm->script = fn; 00197 tm->next = node->trigger_list; 00198 node->trigger_list = tm; 00199 __mgk_update(node); 00200 return (E_SUCCESS); 00201 } 00202 00203 mgk_error_code 00204 mgk_add_node_trigger_mask(mgk_nodep node, mgk_portmask mask) 00205 { 00206 if (__mgk_check_remnode(node)) { 00207 mgk_remnode *rn = (mgk_remnode *) node; 00208 mgk_value *args[2]; 00209 mgk_value *rargs[1]; 00210 args[0] = __mgk_build_value(&rn->ID, T_LONGINT); 00211 args[1] = __mgk_build_value(mask, (T_INTEGER | T_ARRAY(itemsof(mask)))); 00212 if (__mgk_remote_call(rn->host, 00213 cmd_add_node_trigger_mask, 00214 2, args, 00215 1, rargs)) { 00216 mgk_data_type t; 00217 mgk_scalar s; 00218 int *errp = __mgk_extract_value(rargs[0], &t, &s); 00219 if (t == T_INTEGER) { 00220 return (mgk_errno = *errp); 00221 } 00222 } 00223 return (mgk_errno = E_COMM); 00224 } 00225 if (!__mgk_check_node(node)) { 00226 return (E_NOTNODE); 00227 } 00228 return (mgk_add_node_trigger_mask_disp(node, mask, node->script)); 00229 } 00230 00231 DEFSVC(add_node_trigger_mask) 00232 { 00233 if ((argc == 2) && (rargc == 1)) { 00234 mgk_data_type t1, t2; 00235 long *idp = __mgk_parse_value(argv[0], &t1); 00236 int *maskp = __mgk_parse_value(argv[1], &t2); 00237 if ((t1 == T_LONGINT) && 00238 (t2 == (T_INTEGER | T_BUFFER)) && 00239 (mgk_buffer_size(maskp) == sizeof(mgk_portmask))) { 00240 mgk_node *np = __mgk_retrieve_node_by_ID(*idp); 00241 mgk_add_node_trigger_mask(np, maskp); 00242 rargv[0] = __mgk_build_value(&mgk_errno, T_INTEGER); 00243 return (TRUE); 00244 } 00245 } 00246 return (FALSE); 00247 } 00248 00249 mgk_error_code 00250 mgk_add_node_trigger_mask_disp_indirect(mgk_nodep node, 00251 mgk_portmask mask, 00252 char *scriptname) 00253 { 00254 if (__mgk_check_remnode(node)) { 00255 mgk_remnode *rn = (mgk_remnode *) node; 00256 mgk_value *args[3]; 00257 mgk_value *rargs[1]; 00258 args[0] = __mgk_build_value(&rn->ID, T_LONGINT); 00259 args[1] = __mgk_build_value(mask, (T_INTEGER | T_ARRAY(itemsof(mask)))); 00260 args[2] = __mgk_build_value(scriptname, T_STRING); 00261 if (__mgk_remote_call(rn->host, 00262 cmd_add_node_trigger_mask_disp_indirect, 00263 3, args, 00264 1, rargs)) { 00265 mgk_data_type t; 00266 mgk_scalar s; 00267 int *errp = __mgk_extract_value(rargs[0], &t, &s); 00268 if (t == T_INTEGER) { 00269 return (mgk_errno = *errp); 00270 } 00271 } 00272 return (mgk_errno = E_COMM); 00273 } 00274 return (mgk_add_node_trigger_mask_disp(node, mask, 00275 __mgk_lookup_script(scriptname))); 00276 } 00277 00278 DEFSVC(add_node_trigger_mask_disp_indirect) 00279 { 00280 if ((argc == 3) && (rargc == 1)) { 00281 mgk_data_type t1, t2, t3; 00282 long *idp = __mgk_parse_value(argv[0], &t1); 00283 int *maskp = __mgk_parse_value(argv[1], &t2); 00284 char *sc = __mgk_parse_value(argv[2], &t3); 00285 if ((t1 == T_LONGINT) && 00286 (t2 == (T_INTEGER | T_BUFFER)) && 00287 (t3 == (T_CHAR | T_BUFFER)) && 00288 (mgk_buffer_size(maskp) == sizeof(mgk_portmask))) { 00289 mgk_node *np = __mgk_retrieve_node_by_ID(*idp); 00290 mgk_add_node_trigger_mask_disp_indirect(np, maskp, sc); 00291 rargv[0] = __mgk_build_value(&mgk_errno, T_INTEGER); 00292 return (TRUE); 00293 } 00294 } 00295 return (FALSE); 00296 } 00297 00298 mgk_error_code 00299 mgk_set_node_priority(mgk_nodep node, unsigned int priority) 00300 { 00301 if (__mgk_check_remnode(node)) { 00302 mgk_remnode *rn = (mgk_remnode *) node; 00303 mgk_value *args[2]; 00304 mgk_value *rargs[1]; 00305 args[0] = __mgk_build_value(&rn->ID, T_LONGINT); 00306 args[1] = __mgk_build_value(&priority, T_INTEGER); 00307 if (__mgk_remote_call(rn->host, 00308 cmd_set_node_priority, 00309 2, args, 00310 1, rargs)) { 00311 mgk_data_type t; 00312 mgk_scalar s; 00313 int *errp = __mgk_extract_value(rargs[0], &t, &s); 00314 if (t == T_INTEGER) { 00315 return (mgk_errno = *errp); 00316 } 00317 } 00318 return (mgk_errno = E_COMM); 00319 } 00320 if (!__mgk_check_node(node)) { 00321 return (E_NOTNODE); 00322 } 00323 priority = max(min(priority, MGK_MAX_NODE_PRIORITY), MGK_NODE_STOP_PRIORITY); 00324 if (node->priority != priority) { 00325 if (node->status == READY) { 00326 __mgk_dequeue(node); 00327 } 00328 node->priority = priority; 00329 if (node->status == READY) { 00330 __mgk_enqueue(node); 00331 } 00332 } 00333 return (E_SUCCESS); 00334 } 00335 00336 DEFSVC(set_node_priority) 00337 { 00338 if ((argc == 2) && (rargc == 1)) { 00339 mgk_data_type t1, t2; 00340 long *idp = __mgk_parse_value(argv[0], &t1); 00341 int *prip = __mgk_parse_value(argv[1], &t2); 00342 if ((t1 == T_LONGINT) && (t2 == T_INTEGER)) { 00343 mgk_node *np = __mgk_retrieve_node_by_ID(*idp); 00344 mgk_set_node_priority(np, *prip); 00345 rargv[0] = __mgk_build_value(&mgk_errno, T_INTEGER); 00346 return (TRUE); 00347 } 00348 } 00349 return (FALSE); 00350 } 00351 00352 unsigned int 00353 mgk_node_priority(mgk_nodep node) 00354 { 00355 if (__mgk_check_remnode(node)) { 00356 mgk_remnode *rn = (mgk_remnode *) node; 00357 mgk_value *args[1]; 00358 mgk_value *rargs[2]; 00359 args[0] = __mgk_build_value(&rn->ID, T_LONGINT); 00360 if (__mgk_remote_call(rn->host, 00361 cmd_node_priority, 00362 1, args, 00363 2, rargs)) { 00364 mgk_data_type t1, t2; 00365 mgk_scalar s1, s2; 00366 int *prip = __mgk_extract_value(rargs[0], &t1, &s1); 00367 int *errp = __mgk_extract_value(rargs[1], &t2, &s2); 00368 if ((t1 == T_INTEGER) && (t2 == T_INTEGER)) { 00369 mgk_errno = *errp; 00370 return (*prip); 00371 } 00372 } 00373 mgk_errno = E_COMM; 00374 return (MGK_U_BADVAL); 00375 } 00376 if (!__mgk_check_node(node)) { 00377 mgk_errno = E_NOTNODE; 00378 return (MGK_U_BADVAL); 00379 } 00380 mgk_errno = E_SUCCESS; 00381 return (node->priority); 00382 } 00383 00384 DEFSVC(node_priority) 00385 { 00386 if ((argc == 1) && (rargc == 2)) { 00387 mgk_data_type t; 00388 long *idp = __mgk_parse_value(argv[0], &t); 00389 if (t == T_LONGINT) { 00390 mgk_node *np = __mgk_retrieve_node_by_ID(*idp); 00391 int pri = mgk_node_priority(np); 00392 rargv[0] = __mgk_build_value(&pri, T_INTEGER); 00393 rargv[1] = __mgk_build_value(&mgk_errno, T_INTEGER); 00394 return (TRUE); 00395 } 00396 } 00397 return (FALSE); 00398 } 00399 00400 mgk_error_code 00401 mgk_set_node_context(mgk_nodep node, 00402 void *context, mgk_data_type type) 00403 { 00404 mgk_value *val; 00405 if (__mgk_check_remnode(node)) { 00406 mgk_remnode *rn = (mgk_remnode *) node; 00407 mgk_value *args[2]; 00408 mgk_value *rargs[1]; 00409 if ((context == NULL) || (type == T_NODATA)) { 00410 int dummy = 0; 00411 val = __mgk_build_value(&dummy, T_INTEGER); 00412 val->type = T_NODATA; 00413 } 00414 else if (!(val = __mgk_build_value(context, type))) { 00415 return (E_BADDATA); 00416 } 00417 args[0] = __mgk_build_value(&rn->ID, T_LONGINT); 00418 args[1] = val; 00419 if (__mgk_remote_call(rn->host, 00420 cmd_set_node_context, 00421 2, args, 00422 1, rargs)) { 00423 mgk_data_type t; 00424 mgk_scalar s; 00425 int *errp = __mgk_extract_value(rargs[0], &t, &s); 00426 if (t == T_INTEGER) { 00427 return (mgk_errno = *errp); 00428 } 00429 } 00430 return (mgk_errno = E_COMM); 00431 } 00432 if (!__mgk_check_node(node)) { 00433 return (E_NOTNODE); 00434 } 00435 if ((context == NULL) || (type == T_NODATA)) { 00436 val = NULL; 00437 } 00438 else if (!(val = __mgk_build_value(context, type))) { 00439 return (E_BADDATA); 00440 } 00441 if (node->context) { 00442 __mgk_free_value(node->context); 00443 } 00444 node->context = val; 00445 return (E_SUCCESS); 00446 } 00447 00448 DEFSVC(set_node_context) 00449 { 00450 if ((argc == 2) && (rargc == 1)) { 00451 mgk_data_type t; 00452 long *idp = __mgk_parse_value(argv[0], &t); 00453 if (t == T_LONGINT) { 00454 mgk_node *np = __mgk_retrieve_node_by_ID(*idp); 00455 if (np) { 00456 if (np->context) { 00457 __mgk_free_value(np->context); 00458 } 00459 if (argv[1]->type == T_NODATA) { 00460 np->context = NULL; 00461 } 00462 else { 00463 np->context = argv[1]; 00464 argv[1] = NULL; 00465 } 00466 mgk_errno = E_SUCCESS; 00467 } 00468 else { 00469 mgk_errno = E_NOTNODE; 00470 } 00471 rargv[0] = __mgk_build_value(&mgk_errno, T_INTEGER); 00472 return (TRUE); 00473 } 00474 } 00475 return (FALSE); 00476 } 00477 00478 void * 00479 mgk_node_context(mgk_nodep node, mgk_data_type * typep) 00480 { 00481 if (__mgk_check_remnode(node)) { 00482 mgk_remnode *rn = (mgk_remnode *) node; 00483 mgk_value *args[1]; 00484 mgk_value *rargs[2]; 00485 args[0] = __mgk_build_value(&rn->ID, T_LONGINT); 00486 if (__mgk_remote_call(rn->host, 00487 cmd_node_priority, 00488 1, args, 00489 2, rargs)) { 00490 mgk_data_type t; 00491 mgk_scalar s; 00492 int *errp = __mgk_extract_value(rargs[1], &t, &s); 00493 if (t == T_INTEGER) { 00494 static mgk_scalar cxts[16]; 00495 static int ncxt = 0; 00496 mgk_errno = *errp; 00497 return (__mgk_extract_value(rargs[0], typep, &cxts[++ncxt & 15])); 00498 } 00499 __mgk_free_value(rargs[0]); 00500 } 00501 mgk_errno = E_COMM; 00502 return (NULL); 00503 } 00504 if (!__mgk_check_node(node)) { 00505 mgk_errno = E_NOTNODE; 00506 return (NULL); 00507 } 00508 mgk_errno = E_SUCCESS; 00509 return (node->context ? 00510 __mgk_parse_value(node->context, typep) : 00511 (void*) ((*typep = T_NODATA), NULL)); 00512 } 00513 00514 DEFSVC(node_context) 00515 { 00516 if ((argc == 1) && (rargc == 2)) { 00517 mgk_data_type t; 00518 long *idp = __mgk_parse_value(argv[0], &t); 00519 if (t == T_LONGINT) { 00520 mgk_node *np = __mgk_retrieve_node_by_ID(*idp); 00521 if (np && np->context) { 00522 rargv[0] = __mgk_alias_value(np->context); 00523 } 00524 else { 00525 int dummy = 0; 00526 rargv[0] = __mgk_build_value(&dummy, T_INTEGER); 00527 rargv[0]->type = T_NODATA; 00528 } 00529 mgk_errno = np ? E_SUCCESS : E_NOTNODE; 00530 rargv[1] = __mgk_build_value(&mgk_errno, T_INTEGER); 00531 return (TRUE); 00532 } 00533 } 00534 return (FALSE); 00535 } 00536 00537 mgk_node * 00538 __mgk_retrieve_node_by_ID(unsigned long ID) 00539 { 00540 mgk_node *np; 00541 int idx; 00542 return (((__mgk_local_nodes) && 00543 ((idx = (int)(ID & 0x0ffffffL)) < __mgk_num_local_nodes) && 00544 ((np = __mgk_local_nodes[idx])) && 00545 (__mgk_check_node(np)) && 00546 (np->ID == ID)) ? 00547 np : 00548 NULL); 00549 } 00550 00551 mgk_remnode * 00552 __mgk_remnode_stub(mgk_host * h, unsigned long ID) 00553 { 00554 mgk_remnode *rp; 00555 for (rp = stub_list; rp; rp = rp->next) { 00556 if ((rp->host == h) && (rp->ID == ID)) { 00557 return (rp); 00558 } 00559 } 00560 rp = ALLOC_mgk_remnode(); 00561 if (!rp) { 00562 mgk_errno = E_NOMEM; 00563 return (NULL); 00564 } 00565 rp->tag = OBJ_REMNODE; 00566 rp->host = h; 00567 rp->ID = ID; 00568 rp->next = stub_list; 00569 stub_list = rp; 00570 return (rp); 00571 } 00572 00573 mgk_node * 00574 __mgk_locate_node(unsigned int hostidx, unsigned long ID) 00575 { 00576 if (hostidx == (unsigned int)__mgk_local_host->index) { 00577 return (__mgk_retrieve_node_by_ID(ID)); 00578 } 00579 if (hostidx < (unsigned int)__mgk_num_hosts) { 00580 return ((mgk_node *) __mgk_remnode_stub(&__mgk_host_table[hostidx], ID)); 00581 } 00582 return (NULL); 00583 }