/******************************************************************** * FUNCTION agt_ses_get_session_outNotifications * * <get> operation handler for the outNotifications counter * * INPUTS: * see ncx/getcb.h getcb_fn_t for details * * RETURNS: * status *********************************************************************/ status_t agt_ses_get_session_outNotifications (ses_cb_t *scb, getcb_mode_t cbmode, const val_value_t *virval, val_value_t *dstval) { ses_cb_t *testscb; ses_id_t sid; status_t res; (void)scb; if (cbmode != GETCB_GET_VALUE) { return ERR_NCX_OPERATION_NOT_SUPPORTED; } sid = 0; res = get_session_key(virval, &sid); if (res != NO_ERR) { return res; } testscb = agtses[sid]; VAL_UINT(dstval) = testscb->stats.outNotifications; return NO_ERR; } /* agt_ses_get_session_outNotifications */
/******************************************************************** * FUNCTION set_my_session_invoke * * set-my-session : invoke params callback * * INPUTS: * see rpc/agt_rpc.h * RETURNS: * status *********************************************************************/ static status_t set_my_session_invoke (ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { val_value_t *indentval, *linesizeval, *withdefval; (void)methnode; /* get the indent amount parameter */ indentval = val_find_child(msg->rpc_input, AGT_SES_MODULE, NCX_EL_INDENT); if (indentval && indentval->res == NO_ERR) { scb->indent = VAL_UINT(indentval); } /* get the line sizer parameter */ linesizeval = val_find_child(msg->rpc_input, AGT_SES_MODULE, NCX_EL_LINESIZE); if (linesizeval && linesizeval->res == NO_ERR) { scb->linesize = VAL_UINT(linesizeval); } /* get the with-defaults parameter */ withdefval = val_find_child(msg->rpc_input, AGT_SES_MODULE, NCX_EL_WITH_DEFAULTS); if (withdefval && withdefval->res == NO_ERR) { scb->withdef = ncx_get_withdefaults_enum(VAL_ENUM_NAME(withdefval)); } return NO_ERR; } /* set_my_session_invoke */
/******************************************************************** * FUNCTION y_ietf_netconf_partial_lock_partial_unlock_validate * * RPC validation phase * All YANG constraints have passed at this point. * Add description-stmt checks in this function. * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_ietf_netconf_partial_lock_partial_unlock_validate ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { val_value_t *lock_id_val; cfg_template_t *running; plock_cb_t *plcb; uint32 lock_id; status_t res; res = NO_ERR; lock_id_val = val_find_child( msg->rpc_input, y_ietf_netconf_partial_lock_M_ietf_netconf_partial_lock, y_ietf_netconf_partial_lock_N_lock_id); if (lock_id_val == NULL || lock_id_val->res != NO_ERR) { return ERR_NCX_INVALID_VALUE; } lock_id = VAL_UINT(lock_id_val); running = cfg_get_config_id(NCX_CFGID_RUNNING); plcb = cfg_find_partial_lock(running, lock_id); if (plcb == NULL || (plock_get_sid(plcb) != SES_MY_SID(scb))) { res = ERR_NCX_INVALID_VALUE; agt_record_error( scb, &msg->mhdr, NCX_LAYER_OPERATION, res, methnode, NCX_NT_NONE, NULL, NCX_NT_VAL, lock_id_val); } else { msg->rpc_user1 = plcb; } return res; } /* y_ietf_netconf_partial_lock_partial_unlock_validate */
/******************************************************************** * FUNCTION agt_ses_get_droppedSessions * * <get> operation handler for the droppedSessions counter * * INPUTS: * see ncx/getcb.h getcb_fn_t for details * * RETURNS: * status *********************************************************************/ status_t agt_ses_get_droppedSessions (ses_cb_t *scb, getcb_mode_t cbmode, const val_value_t *virval, val_value_t *dstval) { (void)scb; (void)virval; if (cbmode == GETCB_GET_VALUE) { VAL_UINT(dstval) = agttotals->droppedSessions; return NO_ERR; } else { return ERR_NCX_OPERATION_NOT_SUPPORTED; } } /* agt_ses_get_droppedSessions */
/******************************************************************** * FUNCTION get_session_idval * * Get the session ID number for the virtual * counter entry that was called from a <get> operation * * INPUTS: * virval == virtual value * retsid == address of return session ID number * * OUTPUTS: * *retsid == session ID for this <session> entry * RETURNS: * status *********************************************************************/ static status_t get_session_key (const val_value_t *virval, ses_id_t *retsid) { const val_value_t *parentval, *sidval; parentval = virval->parent; if (parentval == NULL) { return ERR_NCX_DEF_NOT_FOUND; } sidval = val_find_child(parentval, obj_get_mod_name(parentval->obj), (const xmlChar *)"session-id"); if (sidval == NULL) { return ERR_NCX_DEF_NOT_FOUND; } *retsid = VAL_UINT(sidval); return NO_ERR; } /* get_session_key */
/******************************************************************** * FUNCTION do_get_locks (local RPC) * * get all the locks on the server * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the history command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_get_locks (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { ses_cb_t *scb; val_value_t *valset, *parm; uint32 locks_timeout, retry_interval; boolean cleanup, done; status_t res; if (server_cb->locks_active) { log_error("\nError: locks are already active"); return ERR_NCX_OPERATION_FAILED; } if (server_cb->state != MGR_IO_ST_CONN_IDLE) { log_error("\nError: no active session to lock"); return ERR_NCX_OPERATION_FAILED; } scb = mgr_ses_get_scb(server_cb->mysid); if (scb == NULL) { log_error("\nError: active session dropped, cannot lock"); return ERR_NCX_OPERATION_FAILED; } locks_timeout = server_cb->locks_timeout; retry_interval = server_cb->locks_retry_interval; cleanup = TRUE; res = NO_ERR; valset = get_valset(server_cb, rpc, &line[len], &res); if (valset && res == NO_ERR) { /* get the overall lock timeout */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_LOCK_TIMEOUT); if (parm && parm->res == NO_ERR) { locks_timeout = VAL_UINT(parm); } /* get the retry interval between failed locks */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_RETRY_INTERVAL); if (parm && parm->res == NO_ERR) { retry_interval = VAL_UINT(parm); } /* get the auto-cleanup flag */ parm = val_find_child(valset, YANGCLI_MOD, YANGCLI_CLEANUP); if (parm && parm->res == NO_ERR) { cleanup = VAL_BOOL(parm); } } /* start the auto-lock procedure */ setup_lock_cbs(server_cb); server_cb->locks_timeout = locks_timeout; server_cb->locks_retry_interval = retry_interval; server_cb->locks_cleanup = cleanup; done = FALSE; if (LOGINFO) { log_info("\nSending <lock> operations for get-locks...\n"); } res = handle_get_locks_request_to_server(server_cb, TRUE, &done); if (res != NO_ERR && done) { /* need to undo the whole thing; whatever got done */ } if (valset != NULL) { val_free_value(valset); } return res; } /* do_get_locks */
/******************************************************************** * FUNCTION process_server_hello * * Process the NETCONF server <hello> contents * * 1) Protocol capabilities * 2) Module capabilities * 3) Unrecognized capabilities * * INPUTS: * scb == session control block to set * hello == value struct for the hello message to check * * OUTPUTS: * server caps in the scb->mgrcb is set * * RETURNS: * status *********************************************************************/ static status_t process_server_hello (ses_cb_t *scb, val_value_t *hello) { val_value_t *caps, *sidval, *cap; mgr_scb_t *mscb; boolean c1, c2; status_t res; mscb = mgr_ses_get_mscb(scb); /* make sure the capabilities element is present * This should not fail, since already parsed this far */ caps = val_find_child(hello, NC_MODULE, NCX_EL_CAPABILITIES); if (!caps || caps->res != NO_ERR) { log_error("\nError: no <capabilities> found in server <hello>"); return ERR_NCX_MISSING_VAL_INST; } /* make sure the session-id element is present * This should not fail, since already parsed this far */ sidval = val_find_child(hello, NC_MODULE, NCX_EL_SESSION_ID); if (!sidval || sidval->res != NO_ERR) { log_error("\nError: no <session-id> found in server <hello>"); return ERR_NCX_MISSING_VAL_INST; } else { mscb->agtsid = VAL_UINT(sidval); } /* go through the capability nodes and construct a caplist */ for (cap = val_find_child(caps, NC_MODULE, NCX_EL_CAPABILITY); cap != NULL; cap = val_find_next_child(caps, NC_MODULE, NCX_EL_CAPABILITY, cap)) { if (cap->res != NO_ERR) { continue; } res = cap_add_std_string(&mscb->caplist, VAL_STR(cap)); if (res == ERR_NCX_SKIPPED) { res = cap_add_module_string(&mscb->caplist, VAL_STR(cap)); if (res == ERR_NCX_SKIPPED) { /* * if (ncx_warning_enabled(ERR_NCX_RCV_UNKNOWN_CAP)) { * log_warn("\nWarning: received unknown capability '%s'", * VAL_STR(cap)); * } */ if (LOGDEBUG2) { log_debug2("\nmgr: Got enterprise capability %s", VAL_STR(cap)); } /* hack: check for juniper 1.0 server * change the useprefix mode to TRUE to get * <rpc> operations to work with this server */ if (!xml_strcmp(VAL_STR(cap), CAP_JUNOS)) { if (LOGDEBUG) { log_debug("\nUsing XML prefixes to work " "with Junos 1.0 server\n"); } ncx_set_useprefix(TRUE); } res = cap_add_ent(&mscb->caplist, VAL_STR(cap)); if (res != NO_ERR) { return res; } } } } /* check if the mandatory base protocol capability was set */ res = NO_ERR; c1 = cap_std_set(&mscb->caplist, CAP_STDID_V1); c2 = cap_std_set(&mscb->caplist, CAP_STDID_V11); if (c1 && c2) { if (LOGDEBUG2) { log_debug2("\nmgr_hello: server supports " "base:1.0 and base:1.1"); } if (ses_protocol_requested(scb, NCX_PROTO_NETCONF11)) { if (LOGDEBUG2) { log_debug2("\nmgr_hello: set protocol to base:1.1 " "for session '%d'", scb->sid); } ses_set_protocol(scb, NCX_PROTO_NETCONF11); } else if (ses_protocol_requested(scb, NCX_PROTO_NETCONF10)) { if (LOGDEBUG2) { log_debug2("\nmgr_hello: set protocol to base:1.0 " "for session '%d'", scb->sid); } ses_set_protocol(scb, NCX_PROTO_NETCONF10); } else { log_error("\nError: Internal: no protocols requested, " "dropping session '%d'", scb->sid); res = ERR_NCX_MISSING_VAL_INST; } } else if (c1) { if (LOGDEBUG2) { log_debug2("\nmgr_hello: server supports " "base:1.0 only"); } if (ses_protocol_requested(scb, NCX_PROTO_NETCONF10)) { if (LOGDEBUG2) { log_debug2("\nmgr_hello: set protocol to base:1.0 " "for session '%d'", scb->sid); } ses_set_protocol(scb, NCX_PROTO_NETCONF10); } else { log_error("\nError: Server supports base:1.0 only;" "\n Protocol 'netconf1.0' not enabled, " "dropping session '%d'", scb->sid); res = ERR_NCX_MISSING_VAL_INST; } } else if (c2) { if (LOGDEBUG2) { log_debug2("\nmgr_hello: server supports " "base:1.1 only"); } if (ses_protocol_requested(scb, NCX_PROTO_NETCONF11)) { if (LOGDEBUG2) { log_debug2("\nmgr_hello: set protocol to base:1.1 " "for session '%d'", scb->sid); } ses_set_protocol(scb, NCX_PROTO_NETCONF11); } else { log_error("\nError: Server supports base:1.1 only;" "\n Protocol 'netconf1.1' not enabled, " "dropping session '%d'", scb->sid); res = ERR_NCX_MISSING_VAL_INST; } } else { log_error("\nError: no support for base:1.0 " "or base:1.1 found in server <hello>;" "\n dropping session '%d'", scb->sid); return ERR_NCX_MISSING_VAL_INST; } /* set target type var in the manager session control block */ c1 = cap_std_set(&mscb->caplist, CAP_STDID_WRITE_RUNNING); c2 = cap_std_set(&mscb->caplist, CAP_STDID_CANDIDATE); if (c1 && c2) { mscb->targtyp = NCX_AGT_TARG_CAND_RUNNING; } else if (c1) { mscb->targtyp = NCX_AGT_TARG_RUNNING; } else if (c2) { mscb->targtyp = NCX_AGT_TARG_CANDIDATE; } else { mscb->targtyp = NCX_AGT_TARG_NONE; if (LOGINFO) { log_info("\nmgr_hello: no writable target found for" " session %u (a:%u)", scb->sid, mscb->agtsid); } } /* set the startup type in the mscb */ if (cap_std_set(&mscb->caplist, CAP_STDID_STARTUP)) { mscb->starttyp = NCX_AGT_START_DISTINCT; } else { mscb->starttyp = NCX_AGT_START_MIRROR; } return NO_ERR; } /* process_server_hello */
/*! * \brief SQL REPLACE implementation * \param _h structure representing database connection * \param _k key names * \param _v values of the keys * \param _n number of key=value pairs * \param _un number of keys to build the unique key, starting from first * \param _m mode - first update, then insert, or first insert, then update * \return 0 on success, negative on failure */ int db_postgres_replace(const db1_con_t* _h, const db_key_t* _k, const db_val_t* _v, const int _n, const int _un, const int _m) { unsigned int pos = 0; int i; if(_un > _n) { LM_ERR("number of columns for unique key is too high\n"); return -1; } if(_un > 0) { for(i=0; i<_un; i++) { if(!VAL_NULL(&_v[i])) { switch(VAL_TYPE(&_v[i])) { case DB1_INT: pos += VAL_UINT(&_v[i]); break; case DB1_STR: pos += get_hash1_raw((VAL_STR(&_v[i])).s, (VAL_STR(&_v[i])).len); break; case DB1_STRING: pos += get_hash1_raw(VAL_STRING(&_v[i]), strlen(VAL_STRING(&_v[i]))); break; default: break; } } } pos &= (_pg_lock_size-1); lock_set_get(_pg_lock_set, pos); if(db_postgres_update(_h, _k, 0, _v, _k + _un, _v + _un, _un, _n -_un)< 0) { LM_ERR("update failed\n"); lock_set_release(_pg_lock_set, pos); return -1; } if (db_postgres_affected_rows(_h) <= 0) { if(db_postgres_insert(_h, _k, _v, _n)< 0) { LM_ERR("insert failed\n"); lock_set_release(_pg_lock_set, pos); return -1; } LM_DBG("inserted new record in database table\n"); } else { LM_DBG("updated record in database table\n"); } lock_set_release(_pg_lock_set, pos); } else { if(db_postgres_insert(_h, _k, _v, _n)< 0) { LM_ERR("direct insert failed\n"); return -1; } LM_DBG("directly inserted new record in database table\n"); } return 0; }
/* * Reload addr table to new hash table and when done, make new hash table * current one. */ int reload_address_table(void) { db_key_t cols[5]; db1_res_t* res = NULL; db_row_t* row; db_val_t* val; struct addr_list **new_hash_table; struct subnet *new_subnet_table; struct domain_name_list **new_domain_name_table; int i; unsigned int gid; unsigned int port; unsigned int mask; str ips; ip_addr_t *ipa; char *tagv; cols[0] = &grp_col; cols[1] = &ip_addr_col; cols[2] = &mask_col; cols[3] = &port_col; cols[4] = &tag_col; if (perm_dbf.use_table(db_handle, &address_table) < 0) { LM_ERR("failed to use table\n"); return -1; } if (perm_dbf.query(db_handle, NULL, 0, NULL, cols, 0, 5, 0, &res) < 0) { LM_ERR("failed to query database\n"); return -1; } /* Choose new hash table and free its old contents */ if (*addr_hash_table == addr_hash_table_1) { empty_addr_hash_table(addr_hash_table_2); new_hash_table = addr_hash_table_2; } else { empty_addr_hash_table(addr_hash_table_1); new_hash_table = addr_hash_table_1; } /* Choose new subnet table */ if (*subnet_table == subnet_table_1) { empty_subnet_table(subnet_table_2); new_subnet_table = subnet_table_2; } else { empty_subnet_table(subnet_table_1); new_subnet_table = subnet_table_1; } /* Choose new domain name table */ if (*domain_list_table == domain_list_table_1) { empty_domain_name_table(domain_list_table_2); new_domain_name_table = domain_list_table_2; } else { empty_domain_name_table(domain_list_table_1); new_domain_name_table = domain_list_table_1; } row = RES_ROWS(res); LM_DBG("Number of rows in address table: %d\n", RES_ROW_N(res)); for (i = 0; i < RES_ROW_N(res); i++) { val = ROW_VALUES(row + i); /* basic checks to db values */ if (ROW_N(row + i) != 5) { LM_DBG("failure during checks of db address table: Colums %d - expected 5\n", ROW_N(row + i)); goto dberror; } if ((VAL_TYPE(val) != DB1_INT) || VAL_NULL(val) || (VAL_INT(val) <= 0)) { LM_DBG("failure during checks of database value 1 (group) in address table\n"); goto dberror; } if ((VAL_TYPE(val + 1) != DB1_STRING) && (VAL_TYPE(val + 1) != DB1_STR)) { LM_DBG("failure during checks of database value 2 (IP address) in address table - not a string value\n"); goto dberror; } if (VAL_NULL(val + 1)) { LM_DBG("failure during checks of database value 2 (IP address) in address table - NULL value not permitted\n"); goto dberror; } if ((VAL_TYPE(val + 2) != DB1_INT) || VAL_NULL(val + 2)) { LM_DBG("failure during checks of database value 3 (subnet size/CIDR) in address table\n"); goto dberror; } if ((VAL_TYPE(val + 3) != DB1_INT) || VAL_NULL(val + 3)) { LM_DBG("failure during checks of database value 4 (port) in address table\n"); goto dberror; } gid = VAL_UINT(val); ips.s = (char *)VAL_STRING(val + 1); ips.len = strlen(ips.s); mask = VAL_UINT(val + 2); port = VAL_UINT(val + 3); tagv = VAL_NULL(val + 4)?NULL:(char *)VAL_STRING(val + 4); ipa = strtoipX(&ips); if ( ipa==NULL ) { LM_DBG("Domain name: %.*s\n", ips.len, ips.s); // goto dberror; } else { if(ipa->af == AF_INET6) { if((int)mask<0 || mask>128) { LM_DBG("failure during IP mask check for v6\n"); goto dberror; } } else { if((int)mask<0 || mask>32) { LM_DBG("failure during IP mask check for v4\n"); goto dberror; } } } if ( ipa ) { if ( (ipa->af==AF_INET6 && mask==128) || (ipa->af==AF_INET && mask==32) ) { if (addr_hash_table_insert(new_hash_table, gid, ipa, port, tagv) == -1) { LM_ERR("hash table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u> inserted into address hash table\n", gid, ips.s, port); } else { if (subnet_table_insert(new_subnet_table, gid, ipa, mask, port, tagv) == -1) { LM_ERR("subnet table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u, %u> inserted into subnet table\n", gid, ips.s, port, mask); } } else { if (domain_name_table_insert(new_domain_name_table, gid, &ips, port, tagv) == -1) { LM_ERR("domain name table problem\n"); perm_dbf.free_result(db_handle, res); return -1; } LM_DBG("Tuple <%u, %s, %u> inserted into domain name table\n", gid, ips.s, port); } } perm_dbf.free_result(db_handle, res); *addr_hash_table = new_hash_table; *subnet_table = new_subnet_table; *domain_list_table = new_domain_name_table; LM_DBG("address table reloaded successfully.\n"); return 1; dberror: LM_ERR("database problem - invalid record\n"); perm_dbf.free_result(db_handle, res); return -1; }
/******************************************************************** * FUNCTION y_toaster_make_toast_invoke * * RPC invocation phase * All constraints have passed at this point. * Call device instrumentation code in this function. * * INPUTS: * see agt/agt_rpc.h for details * * RETURNS: * error status ********************************************************************/ static status_t y_toaster_make_toast_invoke ( ses_cb_t *scb, rpc_msg_t *msg, xml_node_t *methnode) { status_t res; val_value_t *toasterDoneness_val; val_value_t *toasterToastType_val; uint32 toasterDoneness; //val_idref_t *toasterToastType; res = NO_ERR; toasterDoneness = 0; toasterDoneness_val = val_find_child( msg->rpc_input, y_toaster_M_toaster, y_toaster_N_toasterDoneness); if (toasterDoneness_val != NULL && toasterDoneness_val->res == NO_ERR) { toasterDoneness = VAL_UINT(toasterDoneness_val); } toasterToastType_val = val_find_child( msg->rpc_input, y_toaster_M_toaster, y_toaster_N_toasterToastType); if (toasterToastType_val != NULL && toasterToastType_val->res == NO_ERR) { //toasterToastType = VAL_IDREF(toasterToastType_val); // invoke instrumentation with this toast type } /* invoke your device instrumentation code here */ /* make sure the toasterDoneness value is set */ if (toasterDoneness_val == NULL) { toasterDoneness = 5; /* set the default */ } /* arbitrary formula to convert toaster doneness to the * number of seconds the toaster should be on */ toaster_duration = toasterDoneness * 12; /* this is where the code would go to adjust the duration * based on the bread type */ if (LOGDEBUG) { log_debug("\ntoaster: starting toaster for %u seconds", toaster_duration); } /* this is where the code would go to start the toaster * heater element */ /* start a timer to toast for the specified time interval */ res = agt_timer_create(toaster_duration, FALSE, toaster_timer_fn, NULL, &toaster_timer_id); if (res == NO_ERR) { toaster_toasting = TRUE; } else { agt_record_error( scb, &msg->mhdr, NCX_LAYER_OPERATION, res, methnode, NCX_NT_NONE, NULL, NCX_NT_NONE, NULL); } /* added code ends here */ return res; } /* y_toaster_make_toast_invoke */
/******************************************************************** * FUNCTION set_server_profile * * Get the initial agent profile variables for now * Set the agt_profile data structure * * INPUTS: * valset == value set for CLI parsing or NULL if none * agt_profile == pointer to profile struct to fill in * * OUTPUTS: * *agt_profile is filled in with params of defaults * *********************************************************************/ static void set_server_profile (val_value_t *valset, agt_profile_t *agt_profile) { val_value_t *val; uint32 i; boolean done; /* check if there is any CLI data to read */ if (valset == NULL) { /* assumes agt_profile already has default values */ return; } /* check all the netconfd CLI parameters; * follow the order in netconfd.yang since * no action will be taken until all params are collected * * conf=filespec param checked externally */ /* get access-control param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_ACCESS_CONTROL); if (val && val->res == NO_ERR) { agt_profile->agt_accesscontrol = VAL_ENUM_NAME(val); } if (agt_profile->agt_accesscontrol) { if (!xml_strcmp(agt_profile->agt_accesscontrol, NCX_EL_ENFORCING)) { agt_profile->agt_accesscontrol_enum = AGT_ACMOD_ENFORCING; } else if (!xml_strcmp(agt_profile->agt_accesscontrol, NCX_EL_PERMISSIVE)) { agt_profile->agt_accesscontrol_enum = AGT_ACMOD_PERMISSIVE; } else if (!xml_strcmp(agt_profile->agt_accesscontrol, NCX_EL_DISABLED)) { agt_profile->agt_accesscontrol_enum = AGT_ACMOD_DISABLED; } else if (!xml_strcmp(agt_profile->agt_accesscontrol, NCX_EL_OFF)) { agt_profile->agt_accesscontrol_enum = AGT_ACMOD_OFF; } else { SET_ERROR(ERR_INTERNAL_VAL); agt_profile->agt_accesscontrol_enum = AGT_ACMOD_ENFORCING; } } else { agt_profile->agt_accesscontrol_enum = AGT_ACMOD_ENFORCING; } /* get default-style param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_DEFAULT_STYLE); if (val && val->res == NO_ERR) { agt_profile->agt_defaultStyle = VAL_ENUM_NAME(val); agt_profile->agt_defaultStyleEnum = ncx_get_withdefaults_enum(VAL_ENUM_NAME(val)); } /* help parameter checked externally */ /* the logging parameters might have already been * set in the bootstrap CLI (cli_parse_raw) * they may get reset here, if the conf file has * a different value selected */ /* get delete-empty-npcontainters param */ val = val_find_child(valset, AGT_CLI_MODULE, AGT_CLI_DELETE_EMPTY_NPCONTAINERS); if (val && val->res == NO_ERR) { agt_profile->agt_delete_empty_npcontainers = VAL_BOOL(val); } else { agt_profile->agt_delete_empty_npcontainers = AGT_DEF_DELETE_EMPTY_NP; } /* get indent param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_INDENT); if (val && val->res == NO_ERR) { agt_profile->agt_indent = (int32)VAL_UINT(val); } /* get log param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_LOG); if (val && val->res == NO_ERR) { agt_profile->agt_logfile = VAL_STR(val); } /* get log-append param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_LOGAPPEND); if (val && val->res == NO_ERR) { agt_profile->agt_logappend = TRUE; } /* get log-level param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_LOGLEVEL); if (val && val->res == NO_ERR) { agt_profile->agt_loglevel = log_get_debug_level_enum((const char *)VAL_STR(val)); } /* -------------------- LEVI -------------------------*/ /* port is now a leaf, and not leaf-list /* get leaf-list port parameter */ // val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_PORT); // if (val && val->res == NO_ERR) { // agt_profile->agt_ports[0] = VAL_UINT16(val); // // val = val_find_next_child(valset, AGT_CLI_MODULE, // NCX_EL_PORT, val); // while (val) { // done = FALSE; // for (i = 0; i < AGT_MAX_PORTS && !done; i++) { // if (agt_profile->agt_ports[i] == VAL_UINT16(val)) { // done = TRUE; // } else if (agt_profile->agt_ports[i] == 0) { // agt_profile->agt_ports[i] = VAL_UINT16(val); // done = TRUE; // } // } // val = val_find_next_child(valset, AGT_CLI_MODULE, // NCX_EL_PORT, val); // } // } /* getting the port params */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_PORT); if (val && val->res == NO_ERR) { agt_profile->agt_port = VAL_UINT(val); } /* ---------------- END LEVI -------------------------*/ /* eventlog-size param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_EVENTLOG_SIZE); if (val && val->res == NO_ERR) { agt_profile->agt_eventlog_size = VAL_UINT(val); } /* get hello-timeout param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_HELLO_TIMEOUT); if (val && val->res == NO_ERR) { agt_profile->agt_hello_timeout = VAL_UINT(val); } /* get idle-timeout param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_IDLE_TIMEOUT); if (val && val->res == NO_ERR) { agt_profile->agt_idle_timeout = VAL_UINT(val); } /* max-burst param */ val = val_find_child(valset, AGT_CLI_MODULE, AGT_CLI_MAX_BURST); if (val && val->res == NO_ERR) { agt_profile->agt_maxburst = VAL_UINT(val); } /* running-error param */ val = val_find_child(valset, AGT_CLI_MODULE, AGT_CLI_RUNNING_ERROR); if (val && val->res == NO_ERR) { if (!xml_strcmp(VAL_ENUM_NAME(val), AGT_CLI_STARTUP_STOP)) { agt_profile->agt_running_error = TRUE; } } /* start choice: * cli module will check that only 1 of the following 3 * parms are actually entered * start choice 1: get no-startup param */ val = val_find_child(valset, AGT_CLI_MODULE, AGT_CLI_NOSTARTUP); if (val && val->res == NO_ERR) { agt_profile->agt_usestartup = FALSE; } /* start choice 2: OR get startup param */ val = val_find_child(valset, AGT_CLI_MODULE, AGT_CLI_STARTUP); if (val && val->res == NO_ERR) { agt_profile->agt_startup = VAL_STR(val); } /* start choice 3: OR get factory-startup param */ val = val_find_child(valset, AGT_CLI_MODULE, AGT_CLI_FACTORY_STARTUP); if (val && val->res == NO_ERR) { agt_profile->agt_factorystartup = TRUE; } /* startup-error param */ val = val_find_child(valset, AGT_CLI_MODULE, AGT_CLI_STARTUP_ERROR); if (val && val->res == NO_ERR) { if (!xml_strcmp(VAL_ENUM_NAME(val), AGT_CLI_STARTUP_STOP)) { agt_profile->agt_startup_error = TRUE; } } /* superuser param */ val = val_find_child(valset, AGT_CLI_MODULE, AGT_CLI_SUPERUSER); if (val && val->res == NO_ERR) { agt_profile->agt_superuser = VAL_STR(val); } /* get target param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_TARGET); if (val && val->res == NO_ERR) { if (!xml_strcmp(VAL_ENUM_NAME(val), NCX_EL_RUNNING)) { agt_profile->agt_targ = NCX_AGT_TARG_RUNNING; } else if (!xml_strcmp(VAL_ENUM_NAME(val), NCX_EL_CANDIDATE)) { agt_profile->agt_targ = NCX_AGT_TARG_CANDIDATE; } } /* get the :startup capability setting */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_WITH_STARTUP); if (val && val->res == NO_ERR) { if (VAL_BOOL(val)) { agt_profile->agt_start = NCX_AGT_START_DISTINCT; agt_profile->agt_has_startup = TRUE; } else { agt_profile->agt_start = NCX_AGT_START_MIRROR; agt_profile->agt_has_startup = FALSE; } } /* check the subdirs parameter */ val_set_subdirs_parm(valset); /* version param handled externally */ /* get usexmlorder param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_USEXMLORDER); if (val && val->res == NO_ERR) { agt_profile->agt_xmlorder = TRUE; } /* get the :url capability setting */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_WITH_URL); if (val && val->res == NO_ERR) { agt_profile->agt_useurl = VAL_BOOL(val); } /* get with-validate param */ val = val_find_child(valset, AGT_CLI_MODULE, NCX_EL_WITH_VALIDATE); if (val && val->res == NO_ERR) { agt_profile->agt_usevalidate = VAL_BOOL(val); } } /* set_server_profile */
/******************************************************************** * FUNCTION do_while (local RPC) * * Handle the while command; start a new loopcb context * * while expr='xpath-str' [docroot=$foo] * * INPUTS: * server_cb == server control block to use * rpc == RPC method for the show command * line == CLI input in progress * len == offset into line buffer to start parsing * * RETURNS: * status *********************************************************************/ status_t do_while (server_cb_t *server_cb, obj_template_t *rpc, const xmlChar *line, uint32 len) { val_value_t *valset, *docroot, *expr, *dummydoc, *maxloops; xpath_pcb_t *pcb; status_t res; uint32 maxloopsval; docroot = NULL; expr = NULL; pcb = NULL; dummydoc = NULL; res = NO_ERR; maxloopsval = YANGCLI_DEF_MAXLOOPS; valset = get_valset(server_cb, rpc, &line[len], &res); if (valset == NULL) { return res; } if (res != NO_ERR) { val_free_value(valset); return res; } if (valset->res != NO_ERR) { res = valset->res; val_free_value(valset); return res; } /* get the expr parameter */ expr = val_find_child(valset, YANGCLI_MOD, YANGCLI_EXPR); if (expr == NULL) { res = ERR_NCX_MISSING_PARM; } else if (expr->res != NO_ERR) { res = expr->res; } if (res == NO_ERR) { /* get the optional docroot parameter */ docroot = val_find_child(valset, YANGCLI_MOD, YANGCLI_DOCROOT); if (docroot != NULL) { if (docroot->res != NO_ERR) { res = docroot->res; } else { val_remove_child(docroot); } } } if (res == NO_ERR && docroot == NULL) { dummydoc = xml_val_new_struct(NCX_EL_DATA, xmlns_nc_id()); if (dummydoc == NULL) { res = ERR_INTERNAL_MEM; } else { docroot = dummydoc; } } if (res == NO_ERR) { /* get the optional maxloops parameter */ maxloops = val_find_child(valset, YANGCLI_MOD, YANGCLI_MAXLOOPS); if (maxloops != NULL) { if (maxloops->res != NO_ERR) { res = maxloops->res; } else { maxloopsval = VAL_UINT(maxloops); } } } if (res == NO_ERR) { /* got all the parameters, and setup the XPath control block */ pcb = xpath_new_pcb_ex(VAL_STR(expr), xpath_getvar_fn, server_cb->runstack_context); if (pcb == NULL) { res = ERR_INTERNAL_MEM; } else { /* save these parameter and start a new while context block */ res = runstack_handle_while(server_cb->runstack_context, maxloopsval, pcb, /* hand off memory here */ docroot); /* hand off memory here */ if (res == NO_ERR) { /* hand off the pcb and docroot memory above */ pcb = NULL; docroot = NULL; } } } /* cleanup and exit */ if (valset) { val_free_value(valset); } if (pcb) { xpath_free_pcb(pcb); } if (docroot) { val_free_value(docroot); } return res; } /* do_while */
/*! * \brief Convert database values into ucontact_info * * Convert database values into ucontact_info, * expects 12 rows (contact, expirs, q, callid, cseq, flags, * ua, received, path, socket, methods, last_modified) * \param vals database values * \param contact contact * \return pointer to the ucontact_info on success, 0 on failure */ static inline ucontact_info_t* dbrow2info( db_val_t *vals, str *contact) { static ucontact_info_t ci; static str callid, ua, received, host, path; int port, proto; char *p; memset( &ci, 0, sizeof(ucontact_info_t)); contact->s = (char*)VAL_STRING(vals); if (VAL_NULL(vals) || contact->s==0 || contact->s[0]==0) { LM_CRIT("bad contact\n"); return 0; } contact->len = strlen(contact->s); if (VAL_NULL(vals+1)) { LM_CRIT("empty expire\n"); return 0; } ci.expires = VAL_TIME(vals+1); if (VAL_NULL(vals+2)) { LM_CRIT("empty q\n"); return 0; } ci.q = double2q(VAL_DOUBLE(vals+2)); if (VAL_NULL(vals+4)) { LM_CRIT("empty cseq_nr\n"); return 0; } ci.cseq = VAL_INT(vals+4); callid.s = (char*)VAL_STRING(vals+3); if (VAL_NULL(vals+3) || !callid.s || !callid.s[0]) { LM_CRIT("bad callid\n"); return 0; } callid.len = strlen(callid.s); ci.callid = &callid; if (VAL_NULL(vals+5)) { LM_CRIT("empty flag\n"); return 0; } ci.flags = VAL_BITMAP(vals+5); if (VAL_NULL(vals+6)) { LM_CRIT("empty cflag\n"); return 0; } ci.cflags = VAL_BITMAP(vals+6); ua.s = (char*)VAL_STRING(vals+7); if (VAL_NULL(vals+7) || !ua.s || !ua.s[0]) { ua.s = 0; ua.len = 0; } else { ua.len = strlen(ua.s); } ci.user_agent = &ua; received.s = (char*)VAL_STRING(vals+8); if (VAL_NULL(vals+8) || !received.s || !received.s[0]) { received.len = 0; received.s = 0; } else { received.len = strlen(received.s); } ci.received = received; path.s = (char*)VAL_STRING(vals+9); if (VAL_NULL(vals+9) || !path.s || !path.s[0]) { path.len = 0; path.s = 0; } else { path.len = strlen(path.s); } ci.path= &path; /* socket name */ p = (char*)VAL_STRING(vals+10); if (VAL_NULL(vals+10) || p==0 || p[0]==0) { ci.sock = 0; } else { if (parse_phostport( p, &host.s, &host.len, &port, &proto)!=0) { LM_ERR("bad socket <%s>\n", p); return 0; } ci.sock = grep_sock_info( &host, (unsigned short)port, proto); if (ci.sock==0) { LM_INFO("non-local socket <%s>...ignoring\n", p); } } /* supported methods */ if (VAL_NULL(vals+11)) { ci.methods = ALL_METHODS; } else { ci.methods = VAL_BITMAP(vals+11); } /* last modified time */ if (!VAL_NULL(vals+12)) { ci.last_modified = VAL_TIME(vals+12); } /* record internal uid */ if (!VAL_NULL(vals+13)) { ci.ruid.s = (char*)VAL_STRING(vals+13); ci.ruid.len = strlen(ci.ruid.s); } /* sip instance */ if (!VAL_NULL(vals+14)) { ci.instance.s = (char*)VAL_STRING(vals+14); ci.instance.len = strlen(ci.instance.s); } /* reg-id */ if (!VAL_NULL(vals+15)) { ci.reg_id = VAL_UINT(vals+15); } return &ci; }