/******************************************************************** * FUNCTION agt_cap_set_modules * * Initialize the NETCONF agent capabilities modules list * MUST call after agt_cap_set_caps * * INPUTS: * profile == agent profile control block to use * * RETURNS: * status *********************************************************************/ status_t agt_cap_set_modules (agt_profile_t *profile) { if (!agt_caps || !my_agt_caps) { return SET_ERROR(ERR_INTERNAL_INIT_SEQ); } /* add the ietf-netconf module first */ status_t res = cap_add_netconf_modval(agt_caps); if (res != NO_ERR) { log_error("\nError: could not add ietf-netconf " "capability val (%s)\n", get_error_string(res)); return res; } ncx_module_t *mod = ncx_get_first_module(); /* add capability for each module loaded in ncxmod */ while (mod && res == NO_ERR) { /* keep internal modules out of the capabilities */ if (agt_advertise_module_needed(mod->name)) { res = cap_add_modval(agt_caps, mod); if (res == NO_ERR) { res = cap_add_mod(my_agt_caps, mod); } } mod = (ncx_module_t *)dlq_nextEntry(mod); } /* add capability for each deviation module, not already * listed in the module capabilities so far */ ncx_save_deviations_t *savedev; for (savedev = (ncx_save_deviations_t *) dlq_firstEntry(&profile->agt_savedevQ); savedev != NULL && res == NO_ERR; savedev = (ncx_save_deviations_t *) dlq_nextEntry(savedev)) { if (agt_advertise_module_needed(savedev->devmodule)) { /* make sure this is not a hard-wired internal module * or a duplicate already loaded as a regular module */ mod = ncx_find_module(savedev->devmodule, savedev->devrevision); if (mod == NULL) { /* not already announced in the capabilities */ res = cap_add_devmodval(agt_caps, savedev); } } } return res; } /* agt_cap_set_modules */
/******************************************************************** * FUNCTION do_show_modules (sub-mode of local RPC) * * show modules * * INPUTS: * server_cb == server control block to use * mode == requested help mode * * RETURNS: * status *********************************************************************/ static status_t do_show_modules (server_cb_t *server_cb, help_mode_t mode) { session_cb_t *session_cb = server_cb->cur_session_cb; ncx_module_t *mod; modptr_t *modptr; boolean imode = interactive_mode(); boolean anyout = FALSE; status_t res = NO_ERR; if (use_session_cb(session_cb)) { for (modptr = (modptr_t *)dlq_firstEntry(&session_cb->modptrQ); modptr != NULL && res == NO_ERR; modptr = (modptr_t *)dlq_nextEntry(modptr)) { res = do_show_one_module(modptr->mod, mode); anyout = TRUE; } for (modptr = (modptr_t *)dlq_firstEntry(get_mgrloadQ()); modptr != NULL && res == NO_ERR; modptr = (modptr_t *)dlq_nextEntry(modptr)) { res = do_show_one_module(modptr->mod, mode); anyout = TRUE; } } else { mod = ncx_get_first_module(); while (mod && res == NO_ERR) { res = do_show_one_module(mod, mode); anyout = TRUE; mod = ncx_get_next_module(mod); } } if (anyout) { if (imode) { log_stdout("\n"); } else { log_write("\n"); } } else { if (imode) { log_stdout("\nyangcli-pro: no modules loaded\n"); } else { log_error("\nyangcli-pro: no modules loaded\n"); } } return res; } /* do_show_modules */
/******************************************************************** * FUNCTION typedefQ_changed * * Check if a (nested) Q of typedefs changed * * INPUTS: * cp == parameter block to use * oldQ == Q of old typ_template_t to use * newQ == Q of new typ_template_t to use * * RETURNS: * 1 if field changed * 0 if field not changed *********************************************************************/ uint32 typedefQ_changed (yangdiff_diffparms_t *cp, dlq_hdr_t *oldQ, dlq_hdr_t *newQ) { typ_template_t *oldtyp, *newtyp; if (dlq_count(oldQ) != dlq_count(newQ)) { return 1; } /* borrowing the 'used' flag for marking matched typedefs * first set all these flags to FALSE */ for (newtyp = (typ_template_t *)dlq_firstEntry(oldQ); newtyp != NULL; newtyp = (typ_template_t *)dlq_nextEntry(newtyp)) { newtyp->used = FALSE; } /* look through the old type Q for matching types in the new type Q */ for (oldtyp = (typ_template_t *)dlq_firstEntry(oldQ); oldtyp != NULL; oldtyp = (typ_template_t *)dlq_nextEntry(oldtyp)) { /* find this revision in the new module */ newtyp = ncx_find_type_que(newQ, oldtyp->name); if (newtyp) { if (typedef_changed(cp, oldtyp, newtyp)) { return 1; } } else { return 1; } } /* look for typedefs that were added in the new module */ for (newtyp = (typ_template_t *)dlq_firstEntry(newQ); newtyp != NULL; newtyp = (typ_template_t *)dlq_nextEntry(newtyp)) { if (!newtyp->used) { return 1; } } return 0; } /* typedefQ_changed */
/******************************************************************** * FUNCTION find_feature_entry2 * * Find a feature_entry_t * * INPUTS: * modname == module name * feature == feature name * featQ == Q of feature_entry_t to use * * RETURNS: * pointer to found and removed entry or NULL if not found *********************************************************************/ static feature_entry_t * find_feature_entry2 (const xmlChar *modname, const xmlChar *feature, dlq_hdr_t *featQ) { feature_entry_t *feature_entry; for (feature_entry = (feature_entry_t *)dlq_firstEntry(featQ); feature_entry != NULL; feature_entry = (feature_entry_t *)dlq_nextEntry(feature_entry)) { /* match the module name */ if (feature_entry->modname && modname && xml_strcmp(feature_entry->modname, modname)) { continue; } /* match the feature name */ if (xml_strcmp(feature_entry->feature, feature)) { continue; } return feature_entry; } return NULL; } /* find_feature_entry2 */
/******************************************************************** * FUNCTION unQ_match * * Find the specified type in the unionnode Q * * INPUTS: * cp == comparison parameters to use * oldval == old typ_unionnode_t struct to check * newQ == Q of new typ_unionnode_t structs to check * idx == address of return index * * OUTPUTS: * *idx == index of the unionnode entry found [0..N-1 numbering] * * RETURNS: * pointer to the found entry * NULL if not found *********************************************************************/ static typ_unionnode_t * unQ_match (yangdiff_diffparms_t *cp, typ_unionnode_t *oldval, dlq_hdr_t *newQ, uint32 *idx) { typ_unionnode_t *newval; typ_def_t *olddef, *newdef; *idx = 0; olddef = typ_get_unionnode_ptr(oldval); for (newval = (typ_unionnode_t *)dlq_firstEntry(newQ); newval != NULL; newval = (typ_unionnode_t *)dlq_nextEntry(newval)) { if (!newval->seen) { newdef = typ_get_unionnode_ptr(newval); if (!type_changed(cp, olddef, newdef)) { return newval; } } (*idx)++; } return NULL; } /* unQ_match */
/******************************************************************** * FUNCTION add_alias * * Add the alias record * * INPUTS: * alias == alias to add * * RETURNS: * status *********************************************************************/ static status_t add_alias (alias_cb_t *alias) { dlq_hdr_t *aliasQ = get_aliasQ(); alias_cb_t *curalias; int ret; if (aliasQ == NULL) { SET_ERROR(ERR_INTERNAL_VAL); free_alias(alias); return ERR_INTERNAL_VAL; } for (curalias = (alias_cb_t *)dlq_firstEntry(aliasQ); curalias != NULL; curalias = (alias_cb_t *)dlq_nextEntry(curalias)) { ret = xml_strcmp(curalias->name, alias->name); if (ret == 0) { SET_ERROR(ERR_NCX_DUP_ENTRY); free_alias(alias); return ERR_NCX_DUP_ENTRY; } else if (ret > 0) { dlq_insertAhead(alias, curalias); return NO_ERR; } } /* new last entry */ dlq_enque(alias, aliasQ); return NO_ERR; } /* add_alias */
/******************************************************************** * FUNCTION find_alias * * Find the alias record * * INPUTS: * name == alias name to find (not assumed to be z-terminated * namelen == length of name string * RETURNS: * alias record; NULL if not found *********************************************************************/ static alias_cb_t * find_alias (const xmlChar *name, uint32 namelen) { dlq_hdr_t *aliasQ = get_aliasQ(); alias_cb_t *curalias; if (aliasQ == NULL) { SET_ERROR(ERR_INTERNAL_VAL); return NULL; } for (curalias = (alias_cb_t *)dlq_firstEntry(aliasQ); curalias != NULL; curalias = (alias_cb_t *)dlq_nextEntry(curalias)) { uint32 curlen = xml_strlen(curalias->name); int ret = xml_strncmp(curalias->name, name, namelen); if (ret == 0) { if (curlen == namelen) { return curalias; } } else if (ret > 0) { /* already past where this name should be sorted */ return NULL; } } return NULL; } /* find_alias */
/* callback intercepting all notifications. The registeration is done in y_interfaces_alarms_init */ status_t notification_cb(agt_not_msg_t *notif) { val_value_t *payload_val; char description_str[1024]; status_t res; int ret; if((0==strcmp(obj_get_name(notif->notobj),"link-up")) || (0==strcmp(obj_get_name(notif->notobj),"link-down"))) { int down; down = (0==strcmp(obj_get_name(notif->notobj),"link-down")); for (payload_val = (val_value_t *)dlq_firstEntry(¬if->payloadQ); payload_val != NULL; payload_val = (val_value_t *)dlq_nextEntry(payload_val)) { if(0==strcmp("if-name",obj_get_name(payload_val->obj))) { char* resource_str; sprintf(description_str,"Link down - %s",VAL_STRING(payload_val)); //alarm_event_w_type(description_str, "minor", "communications", down?1:0); resource_str=malloc(strlen("/interfaces/interface[name=\'%s\']")+strlen(VAL_STRING(payload_val))+1); sprintf(resource_str,"/interfaces/interface[name=\'%s\']",VAL_STRING(payload_val)); ret=alarmctrl_event(resource_str, "link-alarm"/*alarm_type_id_str*/, ""/*alarm_type_qualifier_str*/, "major", "Probably someone disconnected something?!", down?1:0); //assert(ret==0); free(resource_str); break; } } } return NO_ERR; }
/******************************************************************** * FUNCTION dump_appinfoQ (sub-mode of show RPC) * * show module=mod-name * * INPUTS: * hdr == appinfo Q to show (initialized but may be empty) * indent == start indent count *********************************************************************/ static void dump_appinfoQ (const dlq_hdr_t *hdr, uint32 indent) { const ncx_appinfo_t *appinfo; boolean first; first = TRUE; for (appinfo = (const ncx_appinfo_t *)dlq_firstEntry(hdr); appinfo != NULL; appinfo = (const ncx_appinfo_t *)dlq_nextEntry(appinfo)) { if (first) { help_write_lines((const xmlChar *)"Appinfo Queue:\n", indent, TRUE); first = FALSE; } help_write_lines(EMPTY_STRING, indent+2, TRUE); if (appinfo->value) { log_stdout("%s = %s", appinfo->name, appinfo->value); } else { log_stdout("%s", appinfo->name); } } if (!first) { log_stdout("\n"); } } /* dump_appinfoQ */
/******************************************************************** * FUNCTION grp_has_typedefs * * Check if the grouping contains any typedefs * * INPUTS: * grp == grp_template_t struct to check * * RETURNS: * TRUE if any embedded typedefs * FALSE if no embedded typedefs *********************************************************************/ boolean grp_has_typedefs (const grp_template_t *grp) { const grp_template_t *chgrp; #ifdef DEBUG if (!grp) { SET_ERROR(ERR_INTERNAL_PTR); return FALSE; } #endif if (!dlq_empty(&grp->typedefQ)) { return TRUE; } for (chgrp = (const grp_template_t *) dlq_firstEntry(&grp->groupingQ); chgrp != NULL; chgrp = (const grp_template_t *)dlq_nextEntry(chgrp)) { if (grp_has_typedefs(chgrp)) { return TRUE; } } return FALSE; } /* grp_has_typedefs */
/******************************************************************** * FUNCTION dump_rpcQ (sub-mode of show RPC) * * List all the RPC methods defined in the specified module * * INPUTS: * hdr == Queue header of RPC methods to show * mode == help mode requisted * HELP_MODE_FULL for full dump of each RPC * HELP_MODE_NORMAL for normal dump of each RPC * HELP_MODE_BRIEF for 1 line report on each RPC * indent == start indent count *********************************************************************/ static void dump_rpcQ (const dlq_hdr_t *hdr, help_mode_t mode, uint32 indent) { obj_template_t *rpc; boolean anyout; uint32 nestlevel; nestlevel = get_nestlevel(mode); anyout = FALSE; for (rpc = (obj_template_t *)dlq_firstEntry(hdr); rpc != NULL; rpc = (obj_template_t *)dlq_nextEntry(rpc)) { if (rpc->objtype == OBJ_TYP_RPC) { anyout = TRUE; obj_dump_template(rpc, mode, nestlevel, indent); } } if (anyout) { log_stdout("\n"); } } /* dump_rpcQ */
/******************************************************************** * FUNCTION dump_error * * Dump the error message * * INPUTS: * err == rpc_err_rec_t struct to dump * *********************************************************************/ static void dump_error (const rpc_err_rec_t *err) { const rpc_err_info_t *errinfo; log_write("\nrpc-error: (%u) %s L:%s S:%s ", err->error_res, (err->error_tag) ? (const char *)err->error_tag : "--", ncx_get_layer(err->error_type), rpc_err_get_severity(err->error_severity)); if (err->error_app_tag) { log_write("app-tag:%s ", err->error_app_tag); } if (err->error_path) { log_write("\n path:%s ", err->error_path); } if (err->error_message_lang) { log_write("lang:%s ", err->error_message_lang); } if (err->error_message) { log_write("\n msg:%s ", err->error_message); } for (errinfo = (const rpc_err_info_t *)dlq_firstEntry(&err->error_info); errinfo != NULL; errinfo = (const rpc_err_info_t *)dlq_nextEntry(errinfo)) { dump_error_info(errinfo); } log_write("\n"); } /* dump_error */
/******************************************************************** * FUNCTION xml_msg_check_xmlns_attr * * Check the default NS and the prefix map in the msg; * * INPUTS: * msg == message in progress * nsid == namespace ID to check * badns == namespace URI of the bad namespace * used if the nsid is the INVALID marker * attrs == Q to hold the xml_attr_t, if generated * * OUTPUTS: * msg->prefixQ will be populated as needed, * could be partially populated if some error returned * * XMLNS attr entry may be added to the attrs Q * * RETURNS: * status *********************************************************************/ status_t xml_msg_check_xmlns_attr (xml_msg_hdr_t *msg, xmlns_id_t nsid, const xmlChar *badns, xml_attrs_t *attrs) { const xmlChar *pfix; xmlChar *buff; xml_attr_t *attr; status_t res; #ifdef DEBUG if (!msg || !attrs) { return SET_ERROR(ERR_INTERNAL_PTR); } #endif /* no namespace is always ok, and if it is the same as the * current default, then nothing to do */ if (!nsid) { return NO_ERR; } /* not the default, see if prefix already set for this NS */ pfix = find_prefix(msg, nsid); if (pfix) { return NO_ERR; } /* check if this namespace ID already covered because the * xmlns decl is already present in the attrs list parameter */ for (attr = (xml_attr_t *)dlq_firstEntry(attrs); attr != NULL; attr = (xml_attr_t *)dlq_nextEntry(attr)) { if (attr->attr_xmlns_ns == nsid) { return NO_ERR; } } /* not already covered */ buff = NULL; res = xml_msg_gen_new_prefix(msg, nsid, &buff, 0); if (res == NO_ERR) { if (nsid == xmlns_inv_id()) { res = xml_add_inv_xmlns_attr(attrs, nsid, buff, badns); } else { res = xml_add_xmlns_attr(attrs, nsid, buff); } } if (buff) { m__free(buff); } return res; } /* xml_msg_check_xmlns_attr */
/******************************************************************** * FUNCTION get_next_alias * * Get the next alias record * * RETURNS: * pointer to alias record or NULL if none *********************************************************************/ alias_cb_t * get_next_alias (alias_cb_t *curalias) { if (curalias) { return (alias_cb_t *)dlq_nextEntry(curalias); } return NULL; } /* get_next_alias */
/******************************************************************** * FUNCTION output_typedefQ_diff * * Output the differences report for a Q of typedef definitions * Not always called for top-level typedefs; Can be called * for nested typedefs * * INPUTS: * cp == parameter block to use * oldQ == Q of old typ_template_t to use * newQ == Q of new typ_template_t to use * *********************************************************************/ void output_typedefQ_diff (yangdiff_diffparms_t *cp, dlq_hdr_t *oldQ, dlq_hdr_t *newQ) { typ_template_t *oldtyp, *newtyp; /* borrowing the 'used' flag for marking matched typedefs * first set all these flags to FALSE */ for (newtyp = (typ_template_t *)dlq_firstEntry(newQ); newtyp != NULL; newtyp = (typ_template_t *)dlq_nextEntry(newtyp)) { newtyp->used = FALSE; } /* look through the old type Q for matching types in the new type Q */ for (oldtyp = (typ_template_t *)dlq_firstEntry(oldQ); oldtyp != NULL; oldtyp = (typ_template_t *)dlq_nextEntry(oldtyp)) { /* find this revision in the new module */ newtyp = ncx_find_type_que(newQ, oldtyp->name); if (newtyp) { output_one_typedef_diff(cp, oldtyp, newtyp); newtyp->used = TRUE; } else { /* typedef was removed from the new module */ output_diff(cp, YANG_K_TYPEDEF, oldtyp->name, NULL, TRUE); } } /* look for typedefs that were added in the new module */ for (newtyp = (typ_template_t *)dlq_firstEntry(newQ); newtyp != NULL; newtyp = (typ_template_t *)dlq_nextEntry(newtyp)) { if (!newtyp->used) { /* this typedef was added in the new version */ output_diff(cp, YANG_K_TYPEDEF, NULL, newtyp->name, TRUE); } } } /* output_typedefQ_diff */
/******************************************************************** * FUNCTION ncx_find_feature * * Find a ncx_feature_t struct in the module and perhaps * any of its visible submodules * * INPUTS: * mod == module to search * name == feature name to find * * RETURNS: * pointer to found feature or NULL if not found *********************************************************************/ ncx_feature_t * ncx_find_feature (ncx_module_t *mod, const xmlChar *name) { ncx_feature_t *feature; dlq_hdr_t *que; yang_node_t *node; ncx_include_t *inc; #ifdef DEBUG if (!mod || !name) { SET_ERROR(ERR_INTERNAL_PTR); return NULL; } #endif feature = ncx_find_feature_que(&mod->featureQ, name); if (feature) { return feature; } que = ncx_get_allincQ(mod); /* check all the submodules, but only the ones visible * to this module or submodule */ for (inc = (ncx_include_t *)dlq_firstEntry(&mod->includeQ); inc != NULL; inc = (ncx_include_t *)dlq_nextEntry(inc)) { /* get the real submodule struct */ if (!inc->submod) { node = yang_find_node(que, inc->submodule, inc->revision); if (node) { inc->submod = node->submod; } if (!inc->submod) { /* include not found or errors in it */ continue; } } /* check the feature Q in this submodule */ feature = ncx_find_feature_que(&inc->submod->featureQ, name); if (feature) { return feature; } } return NULL; } /* ncx_find_feature */
/******************************************************************** * FUNCTION find_event_cb * * Find a specified event control block * * INPUTS: * modname == module name * event == eventname * curcb == current starting point; NULL to use start * RETURNS: * found record or NULL if not found *********************************************************************/ static event_cb_t * find_event_cb (const xmlChar *modname, const xmlChar *event, event_cb_t *curcb) { event_cb_t *cb = (curcb) ? (event_cb_t *)dlq_nextEntry(curcb) : (event_cb_t *)dlq_firstEntry(&event_cbQ); for (; cb; cb = (event_cb_t *)dlq_nextEntry(cb)) { int ret = xml_strcmp(modname, cb->modname); if (ret < 0) { return NULL; } else if (ret == 0) { int ret2 = xml_strcmp(event, cb->event); if (ret2 < 0) { return NULL; } else if (ret2 == 0) { return cb; } } } return NULL; } /* find_event_cb */
static agt_cb_queue_notification_set_t* find_callback_set( const xmlChar *modname ) { agt_cb_queue_notification_set_t* cbSet; for ( cbSet = ( agt_cb_queue_notification_set_t* )dlq_firstEntry( &callbackQ ); cbSet != NULL; cbSet = ( agt_cb_queue_notification_set_t* )dlq_nextEntry( cbSet ) ) { if ( 0==xml_strcmp( modname, cbSet->modname ) ) { return cbSet; } } return NULL; }
cfg_transaction_id_t agt_trans_id_get(rpc_msg_t *msg) { val_value_t* chval, *val = msg->rpc_input; //ncx_btype_t btyp; for (chval = (val_value_t *)dlq_firstEntry(&val->v.childQ); chval != NULL; chval = (val_value_t *)dlq_nextEntry(chval)) { if (!xml_strcmp(chval->name, "trans-id")) if (chval->btyp == NCX_BT_UINT64) { return (cfg_transaction_id_t)chval->v.num.ul; } } return 0; }
static agt_cb_commit_complete_set_t* find_callback_set( const xmlChar *modname ) { agt_cb_commit_complete_set_t* cbSet; for ( cbSet = ( agt_cb_commit_complete_set_t* )dlq_firstEntry( &callbackQ ); cbSet != NULL; cbSet = ( agt_cb_commit_complete_set_t* )dlq_nextEntry( cbSet ) ) { if ( xml_strcmp( modname, cbSet->modname ) ) { return cbSet; } } return NULL; }
/******************************************************************** * FUNCTION find_prefix_val * * Find the namespace prefix for the specified namespace ID * by the prefix value itself * * INPUTS: * msg == message to search * pfix == prefix to check for * * RETURNS: * namespace ID in the mapping or 0 if not found *********************************************************************/ static xmlns_id_t find_prefix_val (xml_msg_hdr_t *msg, const xmlChar *pfix) { const xmlns_pmap_t *pmap; for (pmap = (const xmlns_pmap_t *)dlq_firstEntry(&msg->prefixQ); pmap != NULL; pmap = (const xmlns_pmap_t *)dlq_nextEntry(pmap)) { if (!xml_strcmp(pmap->nm_pfix, pfix)) { return pmap->nm_id; } } return XMLNS_NULL_NS_ID; } /* find_prefix_val */
/******************************************************************** * FUNCTION add_pmap * * Add a prefix mapping entry * * INPUTS: * msg == message to search * newpmap == xmlns_pmap_t struct to add * * RETURNS: * none *********************************************************************/ static void add_pmap (xml_msg_hdr_t *msg, xmlns_pmap_t *newpmap) { xmlns_pmap_t *pmap; /* add the new prefix mapping */ for (pmap = (xmlns_pmap_t *)dlq_firstEntry(&msg->prefixQ); pmap != NULL; pmap = (xmlns_pmap_t *)dlq_nextEntry(pmap)) { if (newpmap->nm_id < pmap->nm_id) { dlq_insertAhead(newpmap, pmap); return; } } dlq_enque(newpmap, &msg->prefixQ); } /* add_pmap */
/******************************************************************** * FUNCTION find_feature_entry * * Find a feature_entry_t * * INPUTS: * featstr == feature string parm to use * featQ == Q of feature_entry_t to use * * RETURNS: * pointer to found entry or NULL if not found *********************************************************************/ static feature_entry_t * find_feature_entry (const xmlChar *featstr, dlq_hdr_t *featQ) { uint32 len = 0; boolean splitdone = FALSE; status_t res = split_feature_string(featstr, &len); if (res == NO_ERR) { splitdone = TRUE; } feature_entry_t *feature_entry = (feature_entry_t *)dlq_firstEntry(featQ); for (; feature_entry != NULL; feature_entry = (feature_entry_t *)dlq_nextEntry(feature_entry)) { if (splitdone && feature_entry->modname) { /* match the module name */ uint32 len2 = xml_strlen(feature_entry->modname); if (len != len2) { continue; } if (xml_strncmp(feature_entry->modname, featstr, len)) { continue; } } /* match the feature name */ if (splitdone) { if (xml_strcmp(feature_entry->feature, &featstr[len+1])) { continue; } } else { if (xml_strcmp(feature_entry->feature, featstr)) { continue; } } return feature_entry; } return NULL; } /* find_feature_entry */
/******************************************************************** * FUNCTION find_request * * Find an RPC request but do not remove it * * * The NETCONF protocol actually allows duplicates in * the message-id attribute, but if a message is cancelled * then only the first match is deleted * * INPUTS: * scb == session control block * msg_id == ID for the mgr_rpc_req_t to find * * RETURNS: * pointer to the request or NULL if not found *********************************************************************/ static mgr_rpc_req_t * find_request (ses_cb_t *scb, const xmlChar *msg_id) { mgr_scb_t *mscb; mgr_rpc_req_t *req; mscb = mgr_ses_get_mscb(scb); for (req = (mgr_rpc_req_t *)dlq_firstEntry(&mscb->reqQ); req != NULL; req = (mgr_rpc_req_t *)dlq_nextEntry(req)) { if (!xml_strcmp(msg_id, req->msg_id)) { return req; } } return NULL; } /* find_request */
/******************************************************************** * FUNCTION rpc_err_dump_errors * * Dump the error messages in the RPC message error Q * * INPUTS: * msg == rpc_msg_t struct to check for errors * *********************************************************************/ void rpc_err_dump_errors (const rpc_msg_t *msg) { const rpc_err_rec_t *err; #ifdef DEBUG if (!msg) { SET_ERROR(ERR_INTERNAL_PTR); return; } #endif for (err = (const rpc_err_rec_t *)dlq_firstEntry(&msg->mhdr.errQ); err != NULL; err = (const rpc_err_rec_t *)dlq_nextEntry(err)) { dump_error(err); } } /* rpc_err_dump_errors */
/******************************************************************** * FUNCTION find_pmap * * Find the pmap entry for the specified namespace ID * * INPUTS: * msg == message to search * nsid == namespace ID to find * * RETURNS: * pointer to prefix if found, else NULL if not found *********************************************************************/ static xmlns_pmap_t * find_pmap (xml_msg_hdr_t *msg, xmlns_id_t nsid) { xmlns_pmap_t *pmap; for (pmap = (xmlns_pmap_t *)dlq_firstEntry(&msg->prefixQ); pmap != NULL; pmap = (xmlns_pmap_t *)dlq_nextEntry(pmap)) { if (pmap->nm_id == nsid) { return pmap; } else if (pmap->nm_id > nsid) { return NULL; } } return NULL; } /* find_pmap */
/******************************************************************** * FUNCTION find_prefix * * Find the namespace prefix for the specified namespace ID * * INPUTS: * msg == message to search * nsid == namespace ID to find * * RETURNS: * pointer to prefix if found, else NULL if not found *********************************************************************/ static const xmlChar * find_prefix (xml_msg_hdr_t *msg, xmlns_id_t nsid) { const xmlns_pmap_t *pmap; for (pmap = (const xmlns_pmap_t *)dlq_firstEntry(&msg->prefixQ); pmap != NULL; pmap = (const xmlns_pmap_t *)dlq_nextEntry(pmap)) { if (pmap->nm_id == nsid) { return (const xmlChar *)pmap->nm_pfix; } else if (pmap->nm_id > nsid) { return NULL; } } return NULL; } /* find_prefix */
/******************************************************************** * FUNCTION mgr_rpc_timeout_requestQ * * Clean the request Q of mgr_rpc_req_t entries * Only remove the entries that have timed out * * returning number of msgs timed out * need a callback-based cleanup later on * to support N concurrent requests per agent * * INPUTS: * reqQ == Q of entries to check * * RETURNS: * number of request timed out *********************************************************************/ uint32 mgr_rpc_timeout_requestQ (dlq_hdr_t *reqQ) { mgr_rpc_req_t *req, *nextreq; time_t timenow; double timediff; uint32 deletecount; #ifdef DEBUG if (!reqQ) { SET_ERROR(ERR_INTERNAL_PTR); return 0; } #endif deletecount = 0; (void)uptime(&timenow); for (req = (mgr_rpc_req_t *)dlq_firstEntry(reqQ); req != NULL; req = nextreq) { nextreq = (mgr_rpc_req_t *)dlq_nextEntry(req); if (!req->timeout) { continue; } timediff = difftime(timenow, req->starttime); if (timediff >= (double)req->timeout) { log_info("\nmgr_rpc: deleting timed out request '%s'", req->msg_id); deletecount++; dlq_remove(req); mgr_rpc_free_request(req); } } return deletecount; } /* mgr_rpc_timeout_requestQ */
status_t agt_commit_complete( void ) { agt_cb_commit_complete_set_t* cbSet; for ( cbSet = ( agt_cb_commit_complete_set_t* )dlq_firstEntry( &callbackQ ); cbSet != NULL; cbSet = ( agt_cb_commit_complete_set_t* )dlq_nextEntry( cbSet ) ) { if ( cbSet->callback ) { status_t res = cbSet->callback(); if ( NO_ERR != res ) { return res; } } } return NO_ERR; }
status_t agt_not_queue_notification_cb( agt_not_msg_t *notif ) { agt_cb_queue_notification_set_t* cbSet; for ( cbSet = ( agt_cb_queue_notification_set_t* )dlq_firstEntry( &callbackQ ); cbSet != NULL; cbSet = ( agt_cb_queue_notification_set_t* )dlq_nextEntry( cbSet ) ) { if ( cbSet->callback ) { status_t res = cbSet->callback(notif); if ( NO_ERR != res ) { return res; } } } return NO_ERR; }