struct pkg * pkg_jobs_universe_get_local(struct pkg_jobs_universe *universe, const char *uid, unsigned flag) { struct pkg *pkg = NULL; struct pkgdb_it *it; struct pkg_job_universe_item *unit, *cur, *found; if (flag == 0) { if (!IS_DELETE(universe->j)) flag = PKG_LOAD_BASIC|PKG_LOAD_DEPS|PKG_LOAD_RDEPS|PKG_LOAD_OPTIONS| PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES| PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|PKG_LOAD_ANNOTATIONS| PKG_LOAD_CONFLICTS; else flag = PKG_LOAD_BASIC|PKG_LOAD_RDEPS|PKG_LOAD_DEPS|PKG_LOAD_ANNOTATIONS; } HASH_FIND(hh, universe->items, uid, strlen(uid), unit); if (unit != NULL) { /* Search local in a universe chain */ cur = unit; found = NULL; do { if (cur->pkg->type == PKG_INSTALLED) { found = cur; break; } cur = cur->prev; } while (cur != unit); if (found) { pkgdb_ensure_loaded(universe->j->db, unit->pkg, flag); return (unit->pkg); } } if ((it = pkgdb_query(universe->j->db, uid, MATCH_EXACT)) == NULL) return (NULL); if (pkgdb_it_next(it, &pkg, flag) != EPKG_OK) pkg = NULL; pkgdb_it_free(it); return (pkg); }
gboolean sort_func_priority_extended(GNode *node, gpointer data) { struct VyattaNode *gp = (struct VyattaNode *) node->data; struct Config *gcfg = &(gp->_config); GNode *root_node = (GNode*)data; //WILL STOP AT DEPTH OF 10 REFERENCES //GET PARENT WORKING FIRST.... //change action state of node according to enclosing behavior if (gcfg->_priority_extended) { //only if priority is specified. GNode *new_node = g_node_copy(node); //NOW, we need to figure out where this node belongs in the priority chain if (strncmp(gcfg->_priority_extended, "PARENT", 6) == 0) { //needs to walk up parents until priority is found and insert there.... GNode *n = node; while (TRUE) { n = n->parent; if (n == NULL) { break; } gpointer nd = ((GNode*)n)->data; if (((struct VyattaNode*)nd)->_config._priority != LOWEST_PRIORITY) { //means we are done--found anchor in parent g_node_unlink(node); if (IS_DELETE(gp->_data._operation)) { g_node_insert_before(root_node,n,new_node); } else { g_node_insert_after(root_node,n,new_node); } break; } } } } return FALSE; }
gboolean sort_func(GNode *node, gpointer data, boolean priority_mode) { struct VyattaNode *gp = (struct VyattaNode *) node->data; struct Data *d = &(gp->_data); GNode *root_node = (GNode*)data; d_dplog("commit2::sort_func(): %s, node count: %d", (d->_name ? d->_name : "[n/a]"), g_node_n_children(root_node)); //change action state of node according to enclosing behavior /* XXX this is ugly. originally the condition for the if is the following: * (c1 && c2 || (c3 || c4) && c5) * * this causes compiler warning for mixing && and || without (). the * previous warning removal attempt changed the condition to the * following: * ((c1 && c2) || (c3 || (c4 && c5))) * * which was incorrect (c3 and c4 should be at the same "level") and * therefore was reverted. * * now changing the condition to the following to avoid compiler * warning: * ((c1 && c2) || ((c3 || c4) && c5)) * * note that since the current goal is simply cleanup, no attempt is * made to understand the logic here, and the change is purely based * on operator precendence to maintain the original logic. * * XXX now removing deactivate-handling code, which involves c2. * * note that c2 is (d->_disable_op != K_NO_DISABLE_OP), which means * the node is "deactivated" (in working or active config or both). * this in turn means that the (c1 && c2) part of the logic can only * be true if the node is deactivated. * * however, since activate/deactivate has not actually been exposed, * this means that in actual usage the (c1 && c2) part is never true. * therefore, we can simply remove the whole part, and the logic * becomes: * ((c3 || c4) && c5) */ NODE_OPERATION op = d->_operation; if (((/* c3 */ IS_SET_OR_CREATE(op)) || (/* c4 */ IS_DELETE(op))) && (/* c5 */ IS_NOOP(((struct VyattaNode*) (node->parent->data))->_data._operation))) { //first check if there is enclosing behavior boolean enclosing = FALSE; GNode *n = node; while (TRUE) { n = n->parent; vtw_def def = ((struct VyattaNode*)(n->data))->_config._def; if (def.actions[end_act].vtw_list_head || def.actions[begin_act].vtw_list_head) { enclosing = TRUE; break; } if (G_NODE_IS_ROOT(n) == TRUE) { break; } } //walk back up and flip operations until enclosing behavior if (enclosing == TRUE) { GNode *n = node; while (TRUE) { n = n->parent; vtw_def def = ((struct VyattaNode*)(n->data))->_config._def; if (((struct VyattaNode*)(n->data))->_data._operation == K_NO_OP) { /* XXX this is ugly. _operation is intended to be a bitmap, in which * case it doesn't make sense to make it an enum type (should * just be, e.g., int). this causes g++ to (rightly) complain. * work around it for now to avoid impacting other code since * the current goal is simply cleanup. */ int op = ((struct VyattaNode*)(n->data))->_data._operation; op |= K_ACTIVE_OP; ((struct VyattaNode*)(n->data))->_data._operation = (NODE_OPERATION) op; } if (def.actions[end_act].vtw_list_head || def.actions[begin_act].vtw_list_head) { break; } if (G_NODE_IS_ROOT(n) == TRUE) { break; } } } } if (priority_mode) { int gprio = gp->_config._priority; if (gprio < LOWEST_PRIORITY) { // only if priority is specified. //unlink from original tree g_node_unlink(node); GNode *new_node = g_node_copy(node); GNode *sibling = root_node->children; //now iterate through siblings of root_node and compare priority while (sibling && gprio > ((struct VyattaNode*)(sibling->data)) ->_config._priority) { sibling = sibling->next; if (!sibling || gprio < ((struct VyattaNode*)(sibling->data)) ->_config._priority) { // XXX isn't this redundant??? just cleaning up so not changing it break; } } d_dplog("commit2::sort_func(): inserting %s into transaction, " "priority: %d BEFORE %d", d->_name, gprio, (sibling ? ((struct VyattaNode*)(sibling->data))->_config._priority : LOWEST_PRIORITY)); g_node_insert_before(root_node,sibling,new_node); } } else { if (g_node_depth(node) == 2) { d_dplog("commit2::sort_func(): insert %s into transaction", d->_name); GNode *new_node = g_node_copy(node); g_node_insert(root_node,-1,new_node); //make a flat structure for now } } return FALSE; }
static gboolean process_func(GNode *node, gpointer data) { if (node == NULL) { return TRUE; } struct Result *result = (struct Result*)data; gpointer gp = ((GNode*)node)->data; struct Config *c = &((struct VyattaNode*)gp)->_config; struct Data *d = &((struct VyattaNode*)gp)->_data; struct Aux *a = &((struct VyattaNode*)gp)->_aux; NODE_OPERATION op = d->_operation; int status = 0; if (c->_def.actions && c->_def.actions[result->_action].vtw_list_head){ d_dplog("commit2::process_func(), calling process on : %s for action " "%d, type: %d, operation: %d, path: %s", (d->_name ? d->_name : "[n/a]"), result->_action, (d->_name ? c->_def.def_type : -1), op, d->_path); /* Needs to be cleaned up a bit such that this convoluted if clause * is easier to read. * (XXX original comment no longer correct and therefore is removed.) */ if ((IS_SET(op) && !IS_ACTIVE(op) && (result->_action != delete_act && result->_action != create_act)) || (IS_CREATE(op) && !IS_ACTIVE(op) && (result->_action == begin_act || result->_action == end_act || result->_action == create_act || (result->_action == update_act && !c->_def.actions[create_act].vtw_list_head))) || (IS_ACTIVE(op) && ((result->_action == begin_act) || (result->_action == end_act))) || (IS_DELETE(op) && ((result->_action == delete_act) || (result->_action == begin_act) || (result->_action == end_act)))) { //NEED TO ADD IF CREATE, THEN CREATE OR UPDATE //IF SET THEN UPDATE /* let's skip the case where this is active and it's a * delete--shouldn't be done, but needs to be include in the rule * set above */ if (IS_DELETE(op) && IS_ACTIVE(op) && result->_action == delete_act) { return FALSE; } /* let's skip any multi-node that does not have have a value * (an empty multi-node) */ if (c->_multi && node->children == NULL) { return FALSE; } //look at parent for multi tag if (d->_value && d->_name) { char *val = d->_name; if (c->_def.tag) { /* need to handle the embedded multinode as a special * case--should be fixed! */ val = (char*)clind_unescape(d->_name); } d_dplog("commit2::process_func(): @ value: %s", (char *) val); set_at_string(val); //embedded multinode value } else { if (g_debug) { dplog("commit2::process_func(): boolean value is: %d", d->_value); if (node->parent != NULL && ((struct VyattaNode*)(node->parent->data))->_data._name != NULL) { dplog("commit2::process_func(): parent has a name: %s", ((struct VyattaNode*)(node->parent->data))->_data._name); } dplog("commit2::process_func(): @ value: [NULL]"); } } common_set_context(c->_path,d->_path); d_dplog("Executing %s on this node", ActionNames[result->_action]); if (g_coverage) { struct timeval t; gettimeofday(&t,NULL); fprintf(out_stream, "[START] %lu:%lu, %s@%s", (unsigned long) t.tv_sec, (unsigned long) t.tv_usec, ActionNames[result->_action], d->_path); } if (result->_action == delete_act) { set_in_delete_action(TRUE); } //set location env setenv(ENV_DATA_PATH,d->_path,1); if (a->_first && a->_last) { setenv(ENV_SIBLING_POSITION,"FIRSTLAST",1); } else if (a->_first) { setenv(ENV_SIBLING_POSITION,"FIRST",1); } else if (a->_last) { setenv(ENV_SIBLING_POSITION,"LAST",1); } //do not set for promoted actions if (!IS_ACTIVE(op)) { if (IS_DELETE(op)) { setenv(ENV_ACTION_NAME,ENV_ACTION_DELETE,1); } else { setenv(ENV_ACTION_NAME,ENV_ACTION_SET,1); } } else { setenv(ENV_ACTION_NAME,ENV_ACTION_ACTIVE,1); } if (g_dump_actions == FALSE) { //need to add g_print_error_location_all, and processed location if (g_old_print_output == TRUE) { status = execute_list(c->_def.actions[result->_action].vtw_list_head, &c->_def, NULL); } else { char *p = process_script_path(d->_path); status = execute_list(c->_def.actions[result->_action].vtw_list_head, &c->_def, p); free(p); } } else { char buf[MAX_LENGTH_DIR_PATH*sizeof(char)]; sprintf(buf,"%s\t:\t%s",ActionNames[result->_action],d->_path); if (c->_def.multi) { /* need to handle the embedded multinode as a special * case--should be fixed! */ char *val = (char*)clind_unescape(d->_name); strcat(buf,val); free(val); } fprintf(out_stream,"%s\n",buf); status = 1; } if (result->_action == delete_act) { set_in_delete_action(FALSE); } unsetenv(ENV_ACTION_NAME); unsetenv(ENV_SIBLING_POSITION); unsetenv(ENV_DATA_PATH); if (g_coverage) { struct timeval t; gettimeofday(&t,NULL); fprintf(out_stream,"[END] %lu:%lu\n",t.tv_sec,t.tv_usec); } if (!status) { //EXECUTE_LIST RETURNS FALSE ON FAILURE.... syslog(LOG_ERR, "commit error for %s:[%s]", ActionNames[result->_action],d->_path); if (g_display_error_node) { fprintf(out_stream, "%s@_errloc_:[%s]\n", ActionNames[result->_action], d->_path); } result->_err_code = 1; d_dplog("commit2::process_func(): FAILURE: status: %d", status); return TRUE; //WILL STOP AT THIS POINT } } } return FALSE; }
/** * Execute syntax and commit checks **/ static gboolean validate_func(GNode *node, gpointer data) { if (node == NULL) { return TRUE; } struct VyattaNode *gp = (struct VyattaNode *) node->data; struct Config *c = &(gp->_config); struct Data *d = &(gp->_data); struct Aux *a = &(gp->_aux); struct Result *result = (struct Result*)data; /* let's mark first last nodes here for use later * do first/last/only sibling check, restrict to nodes with operations * defined */ GNode *n_last_op = NULL; GNode *n_first_op = NULL; GNode *sib = g_node_first_sibling(node); while (sib != NULL) { if (IS_DELETE(((struct VyattaNode*)(sib->data))->_data._operation)) { if (n_first_op == NULL) { n_first_op = sib; } n_last_op = sib; } sib = sib->next; } sib = g_node_first_sibling(node); while (sib != NULL) { if (IS_SET_OR_CREATE(((struct VyattaNode*)(sib->data)) ->_data._operation)) { if (n_first_op == NULL) { n_first_op = sib; } n_last_op = sib; } sib = sib->next; } a->_first = (node == n_first_op); a->_last = (node == n_last_op); /* since this visits all working nodes, let's maintain a set of nodes * to commit */ GSList *coll = (GSList*)result->_data; if (d->_path != NULL) { char buf[MAX_LENGTH_DIR_PATH*sizeof(char)]; if (IS_DELETE(d->_operation)) { sprintf(buf,"- %s",d->_path); if (c->_def.multi) { /* need to handle the embedded multinode as a special * case--should be fixed! */ char *val = (char*)clind_unescape(d->_name); strcat(buf,val); free(val); } char *tmp = (char *) malloc(strlen(buf)+1); strcpy(tmp,buf); coll = g_slist_append(coll,tmp); result->_data = (void*)coll; } else if (IS_SET_OR_CREATE(d->_operation)) { sprintf(buf,"+ %s",d->_path); if (c->_def.multi) { /* need to handle the embedded multinode as a special * case--should be fixed! */ char *val = (char*)clind_unescape(d->_name); strcat(buf,val); free(val); } char *tmp = (char *) malloc(strlen(buf)+1); strcpy(tmp,buf); coll = g_slist_append(coll,tmp); result->_data = (void*)coll; } } //don't run syntax check on this node if it is unchanged. if (IS_NOOP(d->_operation) && c->_def.actions[syntax_act].vtw_list_head && !c->_def.actions[syntax_act].vtw_list_head->vtw_node_aux) { return FALSE; } if (IS_DELETE(d->_operation) && !IS_ACTIVE(d->_operation)) { return FALSE; //will not perform validation checks on deleted nodes } if (!c->_def.actions || !c->_def.actions[result->_action].vtw_list_head){ return FALSE; } /* will not call term multi if it is a noop--shouldn't show up in tree * in the first place, but will require more rework of unionfs code * to fix this. */ if (c->_def.multi && IS_NOOP(d->_operation)) { return FALSE; } //look at parent for multi tag if (d->_value && d->_name) { char *val = d->_name; if (c->_def.tag) { /* need to handle the embedded multinode as a special * case--should be fixed! */ val = (char*)clind_unescape(d->_name); } d_dplog("commit2::process_func(): @ value: %s",(char *) val); set_at_string(val); //embedded multinode value } else { if (g_debug) { dplog("commit2::process_func(): boolean value is: %d", d->_value); if (node->parent && ((struct VyattaNode*)(node->parent->data))->_data._name) { dplog("commit2::process_func(): parent has a name: %s", ((struct VyattaNode*)(node->parent->data))->_data._name); } dplog("commit2::process_func(): @ value: [NULL]"); } } common_set_context(c->_path,d->_path); d_dplog("Executing %s on this node", ActionNames[result->_action]); if (g_coverage) { struct timeval t; gettimeofday(&t,NULL); fprintf(out_stream, "[START] %lu:%lu, %s@%s", (unsigned long) t.tv_sec, (unsigned long) t.tv_usec, ActionNames[result->_action], d->_path); } boolean status = 1; if (g_dump_actions == FALSE) { //set location env setenv(ENV_DATA_PATH,d->_path,1); if (g_old_print_output == TRUE) { status = execute_list(c->_def.actions[result->_action].vtw_list_head, &c->_def, NULL); } else { char *p = process_script_path(d->_path); status = execute_list(c->_def.actions[result->_action].vtw_list_head, &c->_def, p); free(p); } unsetenv(ENV_DATA_PATH); } else { char buf[MAX_LENGTH_DIR_PATH*sizeof(char)]; if (c->_def.actions[syntax_act].vtw_list_head) { if (c->_def.actions[syntax_act].vtw_list_head->vtw_node_aux == 0) { sprintf(buf,"syntax\t:\t%s",d->_path); } else { sprintf(buf,"commit\t:\t%s",d->_path); } } if (c->_def.multi) { /* need to handle the embedded multinode as a special * case--should be fixed! */ char *val = (char*)clind_unescape(d->_name); strcat(buf,val); free(val); } fprintf(out_stream,"%s\n",buf); status = 1; } if (g_coverage) { struct timeval t; gettimeofday(&t,NULL); fprintf(out_stream,"[END] %lu:%lu\n",t.tv_sec,t.tv_usec); } if (!status) { //EXECUTE_LIST RETURNS FALSE ON FAILURE.... syslog(LOG_ERR, "commit error for %s:[%s]", ActionNames[result->_action], d->_path); if (g_display_error_node) { fprintf(out_stream, "%s@_errloc_:[%s]\n", ActionNames[result->_action], d->_path); } result->_err_code = 1; d_dplog("commit2::validate_func(): FAILURE: status: %d", status); // WILL STOP AT THIS POINT if mode is not set for full syntax check return result->_mode ? FALSE: TRUE; } return FALSE; }
gboolean dump_func(GNode *node, gpointer data) { FILE *out; if (g_dump_trans) { out = out_stream; } else { out = stdout; } if (node != NULL) { guint depth = g_node_depth(node); if (depth == 2) { fprintf(out,"NEW TRANS\n"); } struct VyattaNode *gp = (struct VyattaNode *) node->data; struct Data *gdata = &(gp->_data); struct Config *gcfg = &(gp->_config); if (gdata->_name != NULL) { unsigned int i; NODE_OPERATION op = gdata->_operation; if (IS_ACTIVE(op)) { fprintf(out, "*"); } else if (IS_DELETE(op)) { fprintf(out, "-"); } else if (IS_CREATE(op)) { fprintf(out, "+"); } else if (IS_SET(op)) { fprintf(out, ">"); } else { fprintf(out, " "); } for (i = 0; i < depth; ++i) { fprintf(out," "); } if (gcfg->_def.def_type2 != ERROR_TYPE) { fprintf(out,"%s (t: %d-%d, ", gdata->_name, gcfg->_def.def_type, gcfg->_def.def_type2); } else { fprintf(out,"%s (t: %d, ", gdata->_name, gcfg->_def.def_type); } if (gcfg->_priority_extended) { fprintf(out, "p: %s)", gcfg->_priority_extended); } else { fprintf(out, "p: %d)", gcfg->_priority); } if (gdata->_value == TRUE) { fprintf(out," [VALUE]"); } if (gcfg->_multi == TRUE) { fprintf(out," [MULTI(%d)]",gcfg->_limit); } if (gcfg->_def.actions[syntax_act].vtw_list_head && !gcfg->_def.actions[syntax_act].vtw_list_head->vtw_node_aux) { fprintf(out," [SYNTAX]"); } if (gcfg->_def.actions[create_act].vtw_list_head) { fprintf(out," [CREATE]"); } if (gcfg->_def.actions[activate_act].vtw_list_head) { fprintf(out," [ACTIVATE]"); } if (gcfg->_def.actions[update_act].vtw_list_head) { fprintf(out," [UPDATE]"); } if (gcfg->_def.actions[delete_act].vtw_list_head) { fprintf(out," [DELETE]"); } if (gcfg->_def.actions[syntax_act].vtw_list_head && gcfg->_def.actions[syntax_act].vtw_list_head->vtw_node_aux) { fprintf(out," [COMMIT]"); } if (gcfg->_def.actions[begin_act].vtw_list_head) { fprintf(out," [BEGIN]"); } if (gcfg->_def.actions[end_act].vtw_list_head) { fprintf(out," [END]"); } fprintf(out,"\n"); } } return FALSE; }