コード例 #1
0
ファイル: gdbCfg.c プロジェクト: mbaglin/legato-af
//--------------------------------------------------------------------------------------------------
static void ResetApp
(
    void
)
{
    le_cfg_ConnectService();
    le_cfgAdmin_ConnectService();

    // Get a write iterator to the application node.
    le_cfg_IteratorRef_t cfgIter = le_cfg_CreateWriteTxn("/apps");
    le_cfg_GoToNode(cfgIter, AppName);

    // Check if this is a temporary configuration that was previously created by this or a similar
    // tool.
    if (le_cfg_IsEmpty(cfgIter, CFG_DEBUG_TOOL))
    {
        fprintf(stderr, "This application already has its original configuration.\n");
        exit(EXIT_FAILURE);
    }

    // Blow away what's in there now.
    le_cfg_GoToNode(cfgIter, "/apps");
    le_cfg_DeleteNode(cfgIter, AppName);

    le_cfg_CommitTxn(cfgIter);

    // NOTE: Currently there is a bug in the config DB where deletions and imports cannot be done in
    //       the same transaction so we must do it in two transactions.
    cfgInstall_Add(AppName);
}
コード例 #2
0
ファイル: avcObject.c プロジェクト: legatoproject/legato-af
//--------------------------------------------------------------------------------------------------
static void SetObject9InstanceForApp
(
    const char* appName,                     ///< The name of the application in question.
    assetData_InstanceDataRef_t instanceRef  ///< The instance of object 9 to link to.  Pass NULL if
                                             ///<   the link is to be cleared.
)
//--------------------------------------------------------------------------------------------------
{
    le_cfg_IteratorRef_t iterRef = le_cfg_CreateWriteTxn(CFG_OBJECT_INFO_PATH);

    if (instanceRef != NULL)
    {
        int instanceId;
        LE_ASSERT(assetData_GetInstanceId(instanceRef, &instanceId) == LE_OK);

        le_cfg_GoToNode(iterRef, appName);
        le_cfg_SetInt(iterRef, "oiid", instanceId);

        LE_DEBUG("Application '%s' mapped to instance %d.", appName, instanceId);
    }
    else
    {
        le_cfg_DeleteNode(iterRef, appName);
    }

    le_cfg_CommitTxn(iterRef);
}
コード例 #3
0
//--------------------------------------------------------------------------------------------------
void userAddRemove_Add
(
    const char* appName
)
//--------------------------------------------------------------------------------------------------
{
    le_result_t result;
    uid_t uid;
    gid_t gid;

    char userName[256] = "app";

    result = le_utf8_Append(userName, appName, sizeof(userName), NULL);
    LE_FATAL_IF(result != LE_OK, "App name '%s' is too long.", appName);

    LE_INFO("Creating user '%s' for application '%s'.", userName, appName);

    // Start a read transaction and go to node /apps/app-name
    le_cfg_ConnectService();
    le_cfg_IteratorRef_t i = le_cfg_CreateReadTxn("/apps");
    le_cfg_GoToNode(i, appName);

    // If the node doesn't exist, bail out.
    if (!le_cfg_NodeExists(i, ""))
    {
        fprintf(stderr, "** ERROR: App '%s' doesn't exist in the system configuration.\n", appName);
    }
    else
    {
        result = user_Create(userName, &uid, &gid);

        if (result == LE_OK)
        {
            printf("Created user '%s' (uid %u, gid %u).\n", userName, uid, gid);

            // TODO: Groups configuration.

            le_cfg_CancelTxn(i);

            exit(EXIT_SUCCESS);
        }
        else if (result == LE_DUPLICATE)
        {
            // TODO: Verify correct groups configuration.

            printf("User '%s' already exists (uid %u, gid %u).\n", userName, uid, gid);

            le_cfg_CancelTxn(i);

            exit(EXIT_SUCCESS);
        }
        else
        {
            fprintf(stderr, "** ERROR: user_Create() failed for user '%s'.\n", userName);
        }
    }

    le_cfg_CancelTxn(i);
    exit(EXIT_FAILURE);
}
コード例 #4
0
ファイル: appCfg.c プロジェクト: mbaglin/legato-af
//--------------------------------------------------------------------------------------------------
LE_SHARED appCfg_Iter_t appCfg_FindApp
(
    const char* appName         ///< [IN] Name of the app to find.
)
{
    AppsIter_t* iterPtr = appCfg_CreateAppsIter();

    le_cfg_GoToNode(iterPtr->cfgIter, appName);

    if (le_cfg_NodeExists(iterPtr->cfgIter, "") == false)
    {
        appCfg_DeleteIter(iterPtr);
        return NULL;
    }

    return iterPtr;
}
コード例 #5
0
ファイル: proc.c プロジェクト: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
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;
}
コード例 #6
0
ファイル: appCfg.c プロジェクト: mbaglin/legato-af
//--------------------------------------------------------------------------------------------------
LE_SHARED appCfg_Iter_t appCfg_CreateAppProcIter
(
    appCfg_Iter_t appIterRef    ///< [IN] Apps iterator
)
{
    CheckFor(appIterRef, ITER_TYPE_APP);

    char pathStr[LE_CFG_STR_LEN_BYTES] = "";
    le_cfg_GetPath(appIterRef->cfgIter, "", pathStr, sizeof(pathStr));

    AppsIter_t* iterPtr = le_mem_ForceAlloc(AppIterPool);

    iterPtr->type = ITER_TYPE_PROC;
    iterPtr->cfgIter = le_cfg_CreateReadTxn(pathStr);
    le_cfg_GoToNode(iterPtr->cfgIter, CFG_PROCS_LIST);
    iterPtr->atFirst = true;

    return iterPtr;
}
コード例 #7
0
ファイル: resourceLimits.c プロジェクト: hakanernam/legato-af
//--------------------------------------------------------------------------------------------------
static void SetRLimit
(
    pid_t pid,                      // The pid of the process to set the limit for.
    le_cfg_IteratorRef_t procCfg,   // The iterator for the process.  This is a iterator is owned by
                                    // the caller and should not be deleted in this function.
    const char* resourceName,       // The resource name in the config tree.
    int resourceID,                 // The resource ID that setrlimit() expects.
    rlim_t defaultValue             // The default value for this resource limit.
)
{
    // Initialize the limit to the defaults.
    struct rlimit lim = {defaultValue, defaultValue};

    // Move the iterator to the resource limit to read.
    le_cfg_GoToNode(procCfg, resourceName);
    if (le_cfg_NodeExists(procCfg, "") == false)
    {
        LE_WARN("No resource limit %s.  Using the default value %lu.", resourceName, defaultValue);
    }
    else
    {
        // Try reading the resource limit from the config tree.
        if (GetCfgResourceLimit(procCfg, &(lim.rlim_max)) != LE_OK)
        {
            LE_ERROR("Configured resource limit %s is invalid.  Using the default value %lu.",
                     resourceName, defaultValue);
        }
        else
        {
            // Check that the limit does not exceed the maximum.
            if ( (resourceID == RLIMIT_NOFILE) && (lim.rlim_max > MAX_LIMIT_NUM_FD) )
            {
                LE_ERROR("Resource limit %s is greater than the maximum allowed limit (%d).  Using the \
    maximum allowed value.", resourceName, MAX_LIMIT_NUM_FD);

                lim.rlim_max = MAX_LIMIT_NUM_FD;
            }
        }

        // Move the iterator back to where it was.
        LE_ASSERT(le_cfg_GoToParent(procCfg) == LE_OK);
    }
コード例 #8
0
ファイル: resourceLimits.c プロジェクト: hakanernam/legato-af
//--------------------------------------------------------------------------------------------------
rlim_t resLim_GetSandboxedAppTmpfsLimit
(
    app_Ref_t appRef                ///< [IN] The application to set resource limits for.
)
{
    // Get the resource limit from the config tree.  Zero means unlimited for tmpfs mounts and is
    // not allowed.

    // Determine the file system limit to set.
    rlim_t fileSysLimit = DEFAULT_LIMIT_FILE_SYSTEM_SIZE;

    // Create a config iterator to get the file system limit from the config tree.
    le_cfg_IteratorRef_t appCfg = le_cfg_CreateReadTxn(app_GetConfigPath(appRef));
    le_cfg_GoToNode(appCfg, CFG_NODE_LIMIT_FILE_SYSTEM_SIZE);

    if (le_cfg_NodeExists(appCfg, "") == false)
    {
        LE_WARN("No resource limit %s.  Assuming the default value %d.",
                CFG_NODE_LIMIT_FILE_SYSTEM_SIZE,
                DEFAULT_LIMIT_FILE_SYSTEM_SIZE);
    }
    else if ( (GetCfgResourceLimit(appCfg, &fileSysLimit) != LE_OK) ||
              (fileSysLimit == 0) )
    {
        // Use the default limit.
        LE_ERROR("Configured resource limit %s is invalid.  Assuming the default value %d.",
                 CFG_NODE_LIMIT_FILE_SYSTEM_SIZE,
                 DEFAULT_LIMIT_FILE_SYSTEM_SIZE);

        fileSysLimit = DEFAULT_LIMIT_FILE_SYSTEM_SIZE;
    }

    le_cfg_CancelTxn(appCfg);

    return fileSysLimit;
}
コード例 #9
0
ファイル: avcObject.c プロジェクト: legatoproject/legato-af
//--------------------------------------------------------------------------------------------------
static assetData_InstanceDataRef_t GetObject9InstanceForApp
(
    const char* appName,  ///< Name of the application in question.
    bool mapIfNotFound    ///< If an instance was created, should a mapping be created for it?
)
//--------------------------------------------------------------------------------------------------
{
    LE_DEBUG("Getting object 9 instance for application '%s'.", appName);

    // Attempt to read the mapping from the configuration.
    assetData_InstanceDataRef_t instanceRef = NULL;
    le_cfg_IteratorRef_t iterRef = le_cfg_CreateReadTxn(CFG_OBJECT_INFO_PATH);

    le_cfg_GoToNode(iterRef, appName);
    int instanceId = le_cfg_GetInt(iterRef, "oiid", -1);
    le_cfg_CancelTxn(iterRef);

    if (instanceId != -1)
    {
        LE_DEBUG("Was mapped to instance, %d.", instanceId);

        // Looks like there was a mapping.  Try to get that instance and make sure it's not taken
        // by another application.  If the instance was taken by another application, remap this
        // application to a new instance and update the mapping.
        if (LE_OK == assetData_GetInstanceRefById(LWM2M_NAME,
                                                  LWM2M_SOFTWARE_UPDATE,
                                                  instanceId,
                                                  &instanceRef))
        {
            char newName[MAX_APP_NAME_BYTES] = "";
            LE_ASSERT(assetData_client_GetString(instanceRef,
                                                 O9F_PKG_NAME,
                                                 newName,
                                                 sizeof(newName)) == LE_OK);

            if (strcmp(newName, appName) != 0)
            {
                LE_DEBUG("Instance has been taken by '%s', creating new.", newName);

                LE_ASSERT(assetData_CreateInstanceById(LWM2M_NAME, 9, -1, &instanceRef) == LE_OK);
                LE_ASSERT(assetData_client_SetString(instanceRef, O9F_PKG_NAME, appName) == LE_OK);

                if (mapIfNotFound)
                {
                    LE_DEBUG("Recording new instance id.");
                    SetObject9InstanceForApp(appName, instanceRef);
                }
            }
            else
            {
                LE_DEBUG("Instance is existing and has been reused.");
            }
        }
        else
        {
            LE_DEBUG("No instance found, creating new as mapped.");

            LE_ASSERT(assetData_CreateInstanceById(LWM2M_NAME,
                                                   9,
                                                   instanceId,
                                                   &instanceRef) == LE_OK);

            LE_ASSERT(assetData_client_SetString(instanceRef, O9F_PKG_NAME, appName) == LE_OK);
        }
    }
    else
    {
        LE_DEBUG("No instance mapping found, creating new.");

        // A mapping was not found.  So create a new object, and let the data store assign an
        // instance Id.  If desired, at this point record the instance mapping for later use.
        LE_ASSERT(assetData_CreateInstanceById(LWM2M_NAME, 9, -1, &instanceRef) == LE_OK);
        LE_ASSERT(assetData_client_SetString(instanceRef, O9F_PKG_NAME, appName) == LE_OK);

        if (mapIfNotFound)
        {
            LE_DEBUG("Recording new instance id.");
            SetObject9InstanceForApp(appName, instanceRef);
        }
    }

    return instanceRef;
}
コード例 #10
0
ファイル: sdirTool.c プロジェクト: mbaglin/legato-af
//--------------------------------------------------------------------------------------------------
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);
}
コード例 #11
0
ファイル: gdbCfg.c プロジェクト: mbaglin/legato-af
//--------------------------------------------------------------------------------------------------
static void ConfigureGdb
(
    void
)
{
    le_cfg_ConnectService();
    le_cfgAdmin_ConnectService();

    // Get a write iterator to the application node.
    le_cfg_IteratorRef_t cfgIter = le_cfg_CreateWriteTxn("/apps");
    le_cfg_GoToNode(cfgIter, AppName);

    // Check if this is a temporary configuration that was previously created by this or a similar
    // tool.
    if (!le_cfg_IsEmpty(cfgIter, CFG_DEBUG_TOOL))
    {
        char debugTool[LIMIT_MAX_PATH_BYTES];

        // Don't need to check return code because the value is just informative and does not matter
        // if it is truncated.
        le_cfg_GetString(cfgIter, CFG_DEBUG_TOOL, debugTool, sizeof(debugTool), "");

        fprintf(stderr, "This application has already been configured for %s debug mode.\n", debugTool);
        exit(EXIT_FAILURE);
    }

    // Write into the config's debug tool node to indicate that this configuration has been modified.
    le_cfg_SetString(cfgIter, CFG_DEBUG_TOOL, "gdb");

    // Add 512K to the maxFileSytemBytes so that we can debug this app in sandboxed mode
    uint32_t maxBytes;

    maxBytes = le_cfg_GetInt(cfgIter, "maxFileSystemBytes", DEFAULT_LIMIT_MAX_FILE_SYSTEM_BYTES);
    maxBytes += ADD_FILE_SYSTEM_BYTES;  // add an additional 512KBytes
    LE_INFO("Resetting maxFileSystemBytes to %d bytes", maxBytes);
    le_cfg_SetInt(cfgIter, "maxFileSystemBytes", maxBytes);

    // Add gdbserver and libs to the app's 'requires/files' section.
    le_cfg_GoToNode(cfgIter, "requires/files");
    AddImportFiles(cfgIter, &GdbFilesImports, NUM_ARRAY_MEMBERS(GdbFilesImports));

    // Add /proc to the app's dirs section.
    le_cfg_GoToParent(cfgIter);
    le_cfg_GoToNode(cfgIter, "dirs");
    AddImportFiles(cfgIter, &GdbDirsImports, NUM_ARRAY_MEMBERS(GdbDirsImports));

    // Delete the list of processes.
    le_cfg_GoToParent(cfgIter);
    le_cfg_GoToParent(cfgIter);
    int i;
    for (i = 0; i < NumProcs; i++)
    {
        char nodePath[LIMIT_MAX_PATH_BYTES];

        int n = snprintf(nodePath, sizeof(nodePath), "procs/%s", ProcNames[i]);

        INTERNAL_ERR_IF(n >= sizeof(nodePath), "Node name is too long.");
        INTERNAL_ERR_IF(n < 0, "Format error.  %m");

        le_cfg_DeleteNode(cfgIter, nodePath);
    }

    le_cfg_CommitTxn(cfgIter);
}
コード例 #12
0
ファイル: proc.c プロジェクト: tegoo/legato-af
//--------------------------------------------------------------------------------------------------
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;
}
コード例 #13
0
ファイル: config.c プロジェクト: ekral85/legato-af
// -------------------------------------------------------------------------------------------------
static le_result_t HandleImportJSONIteration
(
    le_cfg_IteratorRef_t iterRef,  ///< Dump the JSON data into this iterator.
    json_t* nodePtr                ///< From this JSON object.
)
// -------------------------------------------------------------------------------------------------
{
    // Get value
    json_t* value = json_object_get(nodePtr, JSON_FIELD_VALUE);

    // Check type
    const char* typeStr = json_string_value(json_object_get(nodePtr, JSON_FIELD_TYPE));
    le_cfg_nodeType_t type = GetNodeTypeFromString(typeStr);

    switch (type)
    {
        case LE_CFG_TYPE_BOOL:
            le_cfg_SetBool(iterRef, "", json_is_true(value));
            break;

        case LE_CFG_TYPE_STRING:
            le_cfg_SetString(iterRef, "", json_string_value(value));
            break;

        case LE_CFG_TYPE_INT:
            le_cfg_SetInt(iterRef, "", json_integer_value(value));
            break;

        case LE_CFG_TYPE_FLOAT:
            le_cfg_SetFloat(iterRef, "", json_real_value(value));
            break;

        case LE_CFG_TYPE_STEM:
            {
                // Iterate on children
                json_t* childrenPtr = json_object_get(nodePtr, JSON_FIELD_CHILDREN);
                json_t* childPtr;
                int i;

                json_array_foreach(childrenPtr, i, childPtr)
                {
                    // Get name
                    const char* name = json_string_value(json_object_get(childPtr,
                                                                         JSON_FIELD_NAME));

                    // Is node exist with this name?
                    le_cfg_nodeType_t existingType = le_cfg_GetNodeType(iterRef, name);
                    switch (existingType)
                    {
                        case LE_CFG_TYPE_DOESNT_EXIST:
                        case LE_CFG_TYPE_STEM:
                        case LE_CFG_TYPE_EMPTY:
                            // Not existing, already a stem or empty node, nothing to do
                        break;

                        default:
                            // Issue with node creation
                            fprintf(stderr, "Node conflict when importing, at node %s", name);
                            return LE_NOT_POSSIBLE;
                        break;
                    }

                    // Iterate to this child
                    le_cfg_GoToNode(iterRef, name);

                    // Iterate
                    le_result_t subResult = HandleImportJSONIteration(iterRef, childPtr);
                    if (subResult != LE_OK)
                    {
                        // Something went wrong
                        return subResult;
                    }

                    // Go back to parent
                    le_cfg_GoToParent(iterRef);
                }
            }
            break;

        default:
            return LE_FAULT;
    }

    return LE_OK;
}
コード例 #14
0
ファイル: config.c プロジェクト: ekral85/legato-af
// -------------------------------------------------------------------------------------------------
static int HandleCopy
(
    void
)
// -------------------------------------------------------------------------------------------------
{
    // Create a temp file to export the tree to.
    char tempFilePath[] = "/tmp/configExport-XXXXXX";
    int tempFd;

    do
    {
        tempFd = mkstemp(tempFilePath);
    }
    while ((tempFd == -1) && (errno == EINTR));

    if (tempFd == -1)
    {
        fprintf(stderr, "Could not create temp file. Reason, %s (%d).", strerror(errno), errno);
        return 1;
    }

    // Unlink the file now so that we can make sure that it will end up being deleted, no matter how
    // we exit.
    if (unlink(tempFilePath) == -1)
    {
        printf("Could not unlink temporary file. Reason, %s (%d).", strerror(errno), errno);
    }

    // Create a transaction and export the data from the config tree.
    le_cfg_IteratorRef_t iterRef = le_cfg_CreateWriteTxn(NodePath);
    le_result_t result = le_cfgAdmin_ExportTree(iterRef, tempFilePath, "");

    if (result != LE_OK)
    {
        fprintf(stderr,
                "An I/O error occurred while updating the config tree.  "
                "Tree has been left untouched.\n");
        goto txnDone;
    }

    if (DeleteAfterCopy != false)
    {
        // Since this is a rename, then delete the node at the original location.
        le_cfg_DeleteNode(iterRef, "");
    }

    // Now, move the iterator to the node's new name, then attempt to reload the data.
    le_cfg_GoToNode(iterRef, "..");
    result = le_cfgAdmin_ImportTree(iterRef, tempFilePath, NodeDestPath);

    if (result != LE_OK)
    {
        switch (result)
        {
            case LE_FAULT:
                fprintf(stderr,
                        "An I/O error occurred while updating the config tree.  "
                        "Tree has been left untouched.\n");
                break;

            case LE_FORMAT_ERROR:
                fprintf(stderr,
                        "Import/export corruption detected.  Tree has been left untouched.\n");
                break;

            default:
                fprintf(stderr,
                        "An unexpected error has occurred: %s, (%d).\n",
                        LE_RESULT_TXT(result),
                        result);
                break;
        }
    }

 txnDone:
    // Make sure that the change was successful, and either commit or discard any changes that were
    // made.
    if (result == LE_OK)
    {
        le_cfg_CommitTxn(iterRef);
    }
    else
    {
        le_cfg_CancelTxn(iterRef);
    }

    // Was the operation successful?
    int exitResult = (result == LE_OK) ? EXIT_SUCCESS : EXIT_FAILURE;

    // Finally, clean up our temp file and report our results.
    int closeRetVal;

    do
    {
        closeRetVal = close(tempFd);
    }
    while ((closeRetVal == -1) && (errno == EINTR));

    if (closeRetVal == -1)
    {
        fprintf(stderr, "Could not close temp file. Reason, %s (%d).", strerror(errno), errno);
        exitResult = EXIT_FAILURE;
    }

    return exitResult;
}