// ------------------------------------------------------------------------------------------------- static void DumpTreeJSON ( le_cfg_IteratorRef_t iterRef, ///< Read the tree data from this iterator. json_t* jsonObject ///< JSON object to hold the tree data. ) // ------------------------------------------------------------------------------------------------- { // Note that because this is a recursive function, the buffer here is static in order to save on // stack space. The implication here is that we then have to be careful how it is later // accessed. Also, this makes the function not thread safe. But this trade off was made as // this was not intended to be a multi-threaded program. static char strBuffer[LE_CFG_STR_LEN_BYTES] = ""; // Build up the child array. json_t* childArrayPtr = json_array(); do { // Simply grab the name and the type of the current node. le_cfg_GetNodeName(iterRef, "", strBuffer, sizeof(strBuffer)); le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); switch (type) { // It's a stem object, so mark this item as being a stem and recurse into the stem's // sub-items. case LE_CFG_TYPE_STEM: { json_t* nodePtr = CreateJsonNode(strBuffer, NodeTypeStr(type)); le_cfg_GoToFirstChild(iterRef); DumpTreeJSON(iterRef, nodePtr); le_cfg_GoToParent(iterRef); json_array_append(childArrayPtr, nodePtr); } break; default: { json_t* nodePtr = CreateJsonNodeFromIterator(iterRef); if (nodePtr != NULL) { json_array_append(childArrayPtr, nodePtr); } } break; } } while (le_cfg_GoToNextSibling(iterRef) == LE_OK); // Set children into the JSON document. json_object_set_new(jsonObject, JSON_FIELD_CHILDREN, childArrayPtr); }
//-------------------------------------------------------------------------------------------------- static le_result_t GetEnvironmentVariables ( proc_Ref_t procRef, ///< [IN] The process to get the environment variables for. EnvVar_t envVars[], ///< [IN] The list of environment variables. size_t maxNumEnvVars ///< [IN] The maximum number of items envVars can hold. ) { le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot); le_cfg_GoToNode(procCfg, CFG_NODE_ENV_VARS); if (le_cfg_GoToFirstChild(procCfg) != LE_OK) { LE_WARN("No environment variables for process '%s'.", procRef->name); le_cfg_CancelTxn(procCfg); return LE_NOT_FOUND; } int i; for (i = 0; i < maxNumEnvVars; i++) { if ( (le_cfg_GetNodeName(procCfg, "", envVars[i].name, LIMIT_MAX_ENV_VAR_NAME_BYTES) != LE_OK) || (le_cfg_GetString(procCfg, "", envVars[i].value, LIMIT_MAX_PATH_BYTES, "") != LE_OK) ) { LE_ERROR("Error reading environment variables for process '%s'.", procRef->name); le_cfg_CancelTxn(procCfg); return LE_FAULT; } if (le_cfg_GoToNextSibling(procCfg) != LE_OK) { break; } else if (i >= maxNumEnvVars-1) { LE_ERROR("There were too many environment variables for process '%s'.", procRef->name); le_cfg_CancelTxn(procCfg); return LE_FAULT; } } le_cfg_CancelTxn(procCfg); return i + 1; }
static void DumpTree(le_cfg_IteratorRef_t iterRef, size_t indent) { if (le_arg_NumArgs() == 1) { return; } static char strBuffer[STR_SIZE] = { 0 }; do { size_t i; for (i = 0; i < indent; i++) { printf(" "); } le_cfg_GetNodeName(iterRef, "", strBuffer, STR_SIZE); le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); switch (type) { case LE_CFG_TYPE_STEM: printf("%s/\n", strBuffer); le_cfg_GoToFirstChild(iterRef); DumpTree(iterRef, indent + 2); le_cfg_GoToParent(iterRef); break; case LE_CFG_TYPE_EMPTY: printf("%s~~\n", strBuffer); break; default: printf("%s<%s> == ", strBuffer, NodeTypeStr(iterRef)); le_cfg_GetString(iterRef, "", strBuffer, STR_SIZE, ""); printf("%s\n", strBuffer); break; } } while (le_cfg_GoToNextSibling(iterRef) == LE_OK); }
//-------------------------------------------------------------------------------------------------- LE_SHARED le_result_t appCfg_GetNextItem ( appCfg_Iter_t iter ///< [IN] Apps iterator ) { le_result_t result; if (iter->atFirst) { result = le_cfg_GoToFirstChild(iter->cfgIter); iter->atFirst = false; } else { result = le_cfg_GoToNextSibling(iter->cfgIter); } if (result != LE_OK) { return LE_NOT_FOUND; } return LE_OK; }
//-------------------------------------------------------------------------------------------------- static void Load ( void ) //-------------------------------------------------------------------------------------------------- { le_result_t result; // Connect to the Configuration API server. le_cfg_ConnectService(); // Initialize the "User API". user_Init(); // Start a read transaction on the root of the "system" configuration tree. le_cfg_IteratorRef_t i = le_cfg_CreateReadTxn("system:"); // Tell the Service Directory to delete all existing bindings. SendUnbindAllRequest(); // Iterate over the users collection. le_cfg_GoToNode(i, "/users"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { uid_t uid; if (GetUserUid(i, &uid) == LE_OK) { // For each user, iterate over the bindings collection, sending the binding to // the Service Directory. le_cfg_GoToNode(i, "bindings"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { SendBindRequest(uid, i); result = le_cfg_GoToNextSibling(i); } // Go back up to the user name node. le_cfg_GoToNode(i, "../.."); } // Move on to the next user. result = le_cfg_GoToNextSibling(i); } // Iterate over the apps collection. le_cfg_GoToNode(i, "/apps"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { uid_t uid; if (GetAppUid(i, &uid) == LE_OK) { // For each app, iterate over the bindings collection, sending the binding to // the Service Directory. le_cfg_GoToNode(i, "bindings"); result = le_cfg_GoToFirstChild(i); while (result == LE_OK) { SendBindRequest(uid, i); result = le_cfg_GoToNextSibling(i); } // Go back up to the app's node. le_cfg_GoToNode(i, "../.."); } // Move on to the next app. result = le_cfg_GoToNextSibling(i); } exit(EXIT_SUCCESS); }
//-------------------------------------------------------------------------------------------------- static le_result_t GetArgs ( proc_Ref_t procRef, ///< [IN] The process to get the args for. char argsBuffers[LIMIT_MAX_NUM_CMD_LINE_ARGS][LIMIT_MAX_ARGS_STR_BYTES], ///< [OUT] A pointer to /// an array of buffers /// used to store /// arguments. char* argsPtr[NUM_ARGS_PTRS] ///< [OUT] An array of pointers that will point to the valid /// arguments list. The list is terminated by NULL. ) { // Get a config iterator to the arguments list. le_cfg_IteratorRef_t procCfg = le_cfg_CreateReadTxn(procRef->cfgPathRoot); le_cfg_GoToNode(procCfg, CFG_NODE_ARGS); if (le_cfg_GoToFirstChild(procCfg) != LE_OK) { LE_ERROR("No arguments for process '%s'.", procRef->name); le_cfg_CancelTxn(procCfg); return LE_FAULT; } size_t ptrIndex = 0; size_t bufIndex = 0; // Record the executable path. if (le_cfg_GetString(procCfg, "", argsBuffers[bufIndex], LIMIT_MAX_ARGS_STR_BYTES, "") != LE_OK) { LE_ERROR("Error reading argument '%s...' for process '%s'.", argsBuffers[bufIndex], procRef->name); le_cfg_CancelTxn(procCfg); return LE_FAULT; } argsPtr[ptrIndex++] = argsBuffers[bufIndex++]; // Record the process name in the list. argsPtr[ptrIndex++] = procRef->name; // Record the arguments in the caller's list of buffers. while(1) { if (le_cfg_GoToNextSibling(procCfg) != LE_OK) { // Terminate the list. argsPtr[ptrIndex] = NULL; break; } else if (bufIndex >= LIMIT_MAX_NUM_CMD_LINE_ARGS) { LE_ERROR("Too many arguments for process '%s'.", procRef->name); le_cfg_CancelTxn(procCfg); return LE_FAULT; } if (le_cfg_IsEmpty(procCfg, "")) { LE_ERROR("Empty node in argument list for process '%s'.", procRef->name); le_cfg_CancelTxn(procCfg); return LE_FAULT; } if (le_cfg_GetString(procCfg, "", argsBuffers[bufIndex], LIMIT_MAX_ARGS_STR_BYTES, "") != LE_OK) { LE_ERROR("Argument too long '%s...' for process '%s'.", argsBuffers[bufIndex], procRef->name); le_cfg_CancelTxn(procCfg); return LE_FAULT; } // Point to the string. argsPtr[ptrIndex++] = argsBuffers[bufIndex++]; } le_cfg_CancelTxn(procCfg); return LE_OK; }
// ------------------------------------------------------------------------------------------------- static void DumpTree ( le_cfg_IteratorRef_t iterRef, ///< Write out the tree pointed to by this iterator. size_t indent ///< The amount of indentation to use for this item. ) // ------------------------------------------------------------------------------------------------- { // Note that because this is a recursive function, the buffer here is static in order to save on // stack space. The implication here is that we then have to be careful how it is later // accessed. Also, this makes the function not thread safe. But this trade off was made as // this was not intended to be a multi-threaded program. static char strBuffer[LE_CFG_STR_LEN_BYTES] = ""; do { // Quick and dirty way to indent the tree item. size_t i; for (i = 0; i < indent; i++) { printf(" "); } // Simply grab the name and the type of the current node. le_cfg_GetNodeName(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES); le_cfg_nodeType_t type = le_cfg_GetNodeType(iterRef, ""); switch (type) { // It's a stem object, so mark this item as being a stem and recurse into the stem's // sub-items. case LE_CFG_TYPE_STEM: printf("%s/\n", strBuffer); le_cfg_GoToFirstChild(iterRef); DumpTree(iterRef, indent + 2); le_cfg_GoToParent(iterRef); // If we got back up to where we started then don't iterate the "root" node's // siblings. if (indent == 0) { return; } break; // The node is empty, so simply mark it as such. case LE_CFG_TYPE_EMPTY: printf("%s<empty>\n", strBuffer); break; case LE_CFG_TYPE_BOOL: { char* value = NULL; if (le_cfg_GetBool(iterRef, "", false)) { value = "true"; } else { value = "false"; } printf("%s<bool> == %s\n", strBuffer, value); } break; // The node has a different type. So write out the name and the type. Then print the // value. default: printf("%s<%s> == ", strBuffer, NodeTypeStr(le_cfg_GetNodeType(iterRef, ""))); le_cfg_GetString(iterRef, "", strBuffer, LE_CFG_STR_LEN_BYTES, ""); printf("%s\n", strBuffer); break; } } while (le_cfg_GoToNextSibling(iterRef) == LE_OK); }