in src/utils/extension_utils/src/extension_utils.c [189:329]
static bool RegisterHandlerExtension(
const char* handlerId,
const char* handlerFilePath,
const char* handlerExtensionDir,
const char* handlerRegistrationFileName)
{
bool success = false;
STRING_HANDLE folderName = NULL;
STRING_HANDLE dir = NULL;
STRING_HANDLE content = NULL;
STRING_HANDLE outFilePath = NULL;
FILE* outFile = NULL;
char* hash = NULL;
Log_Debug("Registering handler for '%s', file: %s", handlerId, handlerFilePath);
if (IsNullOrEmpty(handlerId))
{
Log_Error("Invalid handler identifier.");
goto done;
}
if (IsNullOrEmpty(handlerFilePath))
{
Log_Error("Invalid handler extension file path.");
goto done;
}
folderName = PathUtils_SanitizePathSegment(handlerId);
if (folderName == NULL)
{
Log_Error("Cannot generate a folder name from an Update Type.");
goto done;
}
dir = STRING_construct_sprintf("%s/%s", handlerExtensionDir, STRING_c_str(folderName));
if (dir == NULL)
{
goto done;
}
// Note: the return value may point to a static area,
// and may be overwritten by subsequent calls to getpwent(3), getpwnam(), or getpwuid().
// (Do not pass the returned pointer to free(3).)
struct passwd* pwd = ADUCPAL_getpwnam(ADUC_FILE_USER);
if (pwd == NULL)
{
Log_Error("Cannot verify credential of 'adu' user.");
goto done;
}
uid_t aduUserId = pwd->pw_uid;
pwd = NULL;
// Note: The return value may point to a static area,
// and may be overwritten by subsequent calls to getgrent(3), getgrgid(), or getgrnam().
// (Do not pass the returned pointer to free(3).)
struct group* grp = ADUCPAL_getgrnam(ADUC_FILE_GROUP);
if (grp == NULL)
{
Log_Error("Cannot get 'adu' group info.");
goto done;
}
gid_t aduGroupId = grp->gr_gid;
grp = NULL;
Log_Debug("Creating the extension folder ('%s'), uid:%d, gid:%d", STRING_c_str(dir), aduUserId, aduGroupId);
int dir_result = ADUC_SystemUtils_MkDirRecursive(STRING_c_str(dir), aduUserId, aduGroupId, S_IRWXU | S_IRWXG);
if (dir_result != 0)
{
Log_Error("Cannot create a folder for registration file. ('%s')", STRING_c_str(dir));
goto done;
}
struct stat bS;
if (stat(handlerFilePath, &bS) != 0)
{
goto done;
}
long fileSize = bS.st_size;
if (!ADUC_HashUtils_GetFileHash(handlerFilePath, SHA256, &hash))
{
goto done;
}
content = STRING_construct_sprintf(
"{\n"
" \"fileName\":\"%s\",\n"
" \"sizeInBytes\":%lld,\n"
" \"hashes\": {\n"
" \"sha256\":\"%s\"\n"
" },\n"
" \"handlerId\":\"%s\"\n"
"}\n",
handlerFilePath,
fileSize,
hash,
handlerId);
if (content == NULL)
{
Log_Error("Cannot compose the handler registration information.");
goto done;
}
outFilePath = STRING_construct_sprintf("%s/%s", STRING_c_str(dir), handlerRegistrationFileName);
outFile = fopen(STRING_c_str(outFilePath), "w");
if (outFile == NULL)
{
Log_Error("Cannot open file: %s", STRING_c_str(outFilePath));
goto done;
}
int ref = fputs(STRING_c_str(content), outFile);
if (ref < 0)
{
Log_Error(
"Failed to write the handler registration information to file. File:%s, Content:%s",
STRING_c_str(dir),
STRING_c_str(content));
goto done;
}
// Print directly to stdout. Since this will be seen by customer,
// we don't want to show any 'log' info (e.g., time stamp, log level.)
printf(
"Successfully registered a handler for '%s'. Registration file: %s.\n", handlerId, STRING_c_str(outFilePath));
success = true;
done:
if (outFile != NULL)
{
fclose(outFile);
}
STRING_delete(outFilePath);
STRING_delete(dir);
free(hash);
return success;
}