src/utils/system_utils/src/system_utils.c
int ADUC_SystemUtils_MkDirRecursive(const char* path, uid_t userId, gid_t groupId, mode_t mode)
{
    if (path == NULL)
    {
        return EINVAL;
    }

    char mkdirPath[PATH_MAX + 1];
    const size_t mkdirPath_cch = strnlen(path, PATH_MAX);

    // Create writable copy of path to iterate over.
    if (mkdirPath_cch + 1 > ARRAY_SIZE(mkdirPath))
    {
        return ENAMETOOLONG;
    }

    strncpy(mkdirPath, path, mkdirPath_cch);
    mkdirPath[mkdirPath_cch] = '\0';

    // Remove any trailing slash.
    if (mkdirPath[mkdirPath_cch - 1] == '/')
    {
        mkdirPath[mkdirPath_cch - 1] = '\0';
    }

    for (char* current = (mkdirPath[0] == '/') ? (mkdirPath + 1) : mkdirPath; *current != '\0'; ++current)
    {
        if (*current == '/')
        {
            *current = '\0';

            const int ret = ADUC_SystemUtils_MkDir(mkdirPath, userId, groupId, mode);
            if (ret != 0)
            {
                return ret;
            }

            *current = '/';
        }
    }

    const int ret = ADUC_SystemUtils_MkDir(mkdirPath, userId, groupId, mode);
    if (ret != 0)
    {
        return ret;
    }

    // Let's make sure that we set this correct permission on the leaf folder.
    struct stat st = {};
    if (stat(path, &st) == 0)
    {
        int perms = st.st_mode & ~S_IFMT;
        if (perms != mode)
        {
            // Fix the permissions.
            if (0 != chmod(path, mode))
            {
                stat(path, &st);
                Log_Warn(
                    "Failed to set '%s' folder permissions (expected:%d, actual: %d)",
                    mkdirPath,
                    mode,
                    st.st_mode & ~S_IFMT);
            }
        }
    }

    return 0;
}
/**
 * @brief Create a directory tree.
 *
 * On error, none of the partially created tree is cleaned up.
 *
 * @param path Path to create.
 * @param userId The uid_t of the user owner any new directory. -1 to indicate the system default behavior.
 * @param groupId The gid_t of the group owner any new directory. -1 to indicate the system default behavior.
 * @param mode The mode_t of the desired permissions any new directory.
 *
 * @return errno, zero on success.
 */
@brief Create a directory tree.
On error, none of the partially created tree is cleaned up.

@param path Path to create.
@param userId The uid_t of the user owner any new directory. -1 to indicate the system default behavior.
@param groupId The gid_t of the group owner any new directory. -1 to indicate the system default behavior.
@param mode The mode_t of the desired permissions any new directory.

@return errno, zero on success.
@brief Create a directory tree . On error none of the partially created tree is cleaned up . @param path Path to create . @param userId The uid_t of the user owner any new directory . - 1 to indicate the system default behavior . @param groupId The gid_t of the group owner any new directory . - 1 to indicate the system default behavior . @param mode The mode_t of the desired permissions any new directory . @return errno zero on success .
int ADUC_SystemUtils_MkDirRecursive(const char* path, uid_t userId, gid_t groupId, mode_t mode)
{
    if (path == NULL)
    {
        return EINVAL;
    }
    char mkdirPath[PATH_MAX + 1];
    const size_t mkdirPath_cch = strnlen(path, PATH_MAX);
    if (mkdirPath_cch + 1 > ARRAY_SIZE(mkdirPath))
    {
        return ENAMETOOLONG;
    }
    strncpy(mkdirPath, path, mkdirPath_cch);
    mkdirPath[mkdirPath_cch] = '\0';
    if (mkdirPath[mkdirPath_cch - 1] == '/')
    {
        mkdirPath[mkdirPath_cch - 1] = '\0';
    }
    for (char* current = (mkdirPath[0] == '/') ? (mkdirPath + 1) : mkdirPath; *current != '\0'; ++current)
    {
        if (*current == '/')
        {
            *current = '\0';
            const int ret = ADUC_SystemUtils_MkDir(mkdirPath, userId, groupId, mode);
            if (ret != 0)
            {
                return ret;
            }
            *current = '/';
        }
    }
    const int ret = ADUC_SystemUtils_MkDir(mkdirPath, userId, groupId, mode);
    if (ret != 0)
    {
        return ret;
    }
    struct stat st = {};
    if (stat(path, &st) == 0)
    {
        int perms = st.st_mode & ~S_IFMT;
        if (perms != mode)
        {
            if (0 != chmod(path, mode))
            {
                stat(path, &st);
                Log_Warn(
                    "Failed to set '%s' folder permissions (expected:%d, actual: %d)",
                    mkdirPath,
                    mode,
                    st.st_mode & ~S_IFMT);
            }
        }
    }
    return 0;
}
int ADUC_SystemUtils_MkDirRecursive ( const char * path , uid_t userId , gid_t groupId , mode_t mode ) { if ( path == NULL ) { return EINVAL ; } char mkdirPath [ PATH_MAX + 1 ] ; const size_t mkdirPath_cch = strnlen ( path , PATH_MAX ) ; if ( mkdirPath_cch + 1 > ARRAY_SIZE ( mkdirPath ) ) { return ENAMETOOLONG ; } strncpy ( mkdirPath , path , mkdirPath_cch ) ; mkdirPath [ mkdirPath_cch ] = ' \0 ' ; if ( mkdirPath [ mkdirPath_cch - 1 ] == ' ' ) { mkdirPath [ mkdirPath_cch - 1 ] = ' \0 ' ; } for ( char * current = ( mkdirPath [ 0 ] == ' ' ) ? ( mkdirPath + 1 ) : mkdirPath ; * current != ' \0 ' ; ++ current ) { if ( * current == ' ' ) { * current = ' \0 ' ; const int ret = ADUC_SystemUtils_MkDir ( mkdirPath , userId , groupId , mode ) ; if ( ret != 0 ) { return ret ; } * current = ' ' ; } } const int ret = ADUC_SystemUtils_MkDir ( mkdirPath , userId , groupId , mode ) ; if ( ret != 0 ) { return ret ; } struct stat st = { } ; if ( stat ( path , & st ) == 0 ) { int perms = st . st_mode & ~ S_IFMT ; if ( perms != mode ) { if ( 0 != chmod ( path , mode ) ) { stat ( path , & st ) ; Log_Warn ( " " , mkdirPath , mode , st . st_mode & ~ S_IFMT ) ; } } } return 0 ; }
@brief Create a directory tree.
@brief Create a directory tree .
// Create writable copy of path to iterate over. // Remove any trailing slash. // Let's make sure that we set this correct permission on the leaf folder. // Fix the permissions.