mirror of https://github.com/vmware/tdnf.git
613 lines
17 KiB
C
613 lines
17 KiB
C
/*
|
|
* Copyright (C) 2015-2023 VMware, Inc. All Rights Reserved.
|
|
*
|
|
* Licensed under the GNU Lesser General Public License v2.1 (the "License");
|
|
* you may not use this file except in compliance with the License. The terms
|
|
* of the License are located in the COPYING file of this distribution.
|
|
*/
|
|
|
|
#include "includes.h"
|
|
|
|
#include "../llconf/nodes.h"
|
|
#include "../llconf/modules.h"
|
|
#include "../llconf/entry.h"
|
|
#include "../llconf/ini.h"
|
|
|
|
#define USERAGENT_HEADER_MAX_LENGTH 256
|
|
#define OS_CONF_FILE "/etc/os-release"
|
|
|
|
int
|
|
TDNFConfGetRpmVerbosity(
|
|
PTDNF pTdnf
|
|
)
|
|
{
|
|
rpmlogLvl nLogLevel = RPMLOG_INFO;
|
|
if(pTdnf && pTdnf->pArgs->nRpmVerbosity >= 0)
|
|
{
|
|
nLogLevel = pTdnf->pArgs->nRpmVerbosity;
|
|
}
|
|
return nLogLevel;
|
|
}
|
|
|
|
static uint32_t TDNFParseOSInfo(PTDNF_CONF pConf)
|
|
{
|
|
char buf[USERAGENT_HEADER_MAX_LENGTH];
|
|
char *name = NULL;
|
|
char *version = NULL;
|
|
uint32_t dwError = 0;
|
|
FILE *file = NULL;
|
|
|
|
file = fopen(OS_CONF_FILE, "r");
|
|
|
|
if (!file) {
|
|
pr_info("Warning: %s file is not present in the system\n", OS_CONF_FILE);
|
|
return 0;
|
|
}
|
|
|
|
while (fgets(buf, USERAGENT_HEADER_MAX_LENGTH, file))
|
|
{
|
|
if (strncmp("ID=", buf, sizeof("ID=")-1) == 0)
|
|
{
|
|
if (sscanf(buf, "ID=\"%[^\"]\"", buf) == 1) {
|
|
dwError = TDNFAllocateString(buf, &name);
|
|
} else if (sscanf(buf, "ID=%s", buf) == 1) {
|
|
dwError = TDNFAllocateString(buf, &name);
|
|
}
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
else if (strncmp("VERSION_ID=", buf, sizeof("VERSION_ID=")-1) == 0)
|
|
{
|
|
if (sscanf(buf, "VERSION_ID=\"%[^\"]\"", buf) == 1) {
|
|
dwError = TDNFAllocateString(buf, &version);
|
|
} else if (sscanf(buf, "VERSION_ID=%s", buf) == 1) {
|
|
dwError = TDNFAllocateString(buf, &version);
|
|
}
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
pConf->pszOSName = name;
|
|
pConf->pszOSVersion = version;
|
|
|
|
cleanup:
|
|
if(file)
|
|
{
|
|
fclose(file);
|
|
}
|
|
return dwError;
|
|
|
|
error:
|
|
TDNF_SAFE_FREE_MEMORY(name);
|
|
TDNF_SAFE_FREE_MEMORY(version);
|
|
goto cleanup;
|
|
}
|
|
|
|
static
|
|
uint32_t
|
|
TDNFConfigFromCnfTree(PTDNF_CONF pConf, struct cnfnode *cn_top)
|
|
{
|
|
uint32_t dwError = 0;
|
|
struct cnfnode *cn;
|
|
const char *pszProxyUser = NULL;
|
|
const char *pszProxyPass = NULL;
|
|
|
|
for(cn = cn_top->first_child; cn; cn = cn->next)
|
|
{
|
|
if ((cn->name[0] == '.') || (cn->value == NULL))
|
|
continue;
|
|
|
|
if (strcmp(cn->name, TDNF_CONF_KEY_INSTALLONLY_LIMIT) == 0)
|
|
{
|
|
pConf->nInstallOnlyLimit = strtoi(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_CLEAN_REQ_ON_REMOVE) == 0)
|
|
{
|
|
pConf->nCleanRequirementsOnRemove = isTrue(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_GPGCHECK) == 0)
|
|
{
|
|
pConf->nGPGCheck = isTrue(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_SSL_VERIFY) == 0)
|
|
{
|
|
pConf->nSSLVerify = isTrue(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_KEEP_CACHE) == 0)
|
|
{
|
|
pConf->nKeepCache = isTrue(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_REPOSDIR) == 0 ||
|
|
strcmp(cn->name, TDNF_CONF_KEY_REPODIR) == 0)
|
|
{
|
|
SET_STRING(pConf->pszRepoDir, cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_CACHEDIR) == 0)
|
|
{
|
|
SET_STRING(pConf->pszCacheDir, cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_PERSISTDIR) == 0)
|
|
{
|
|
SET_STRING(pConf->pszPersistDir, cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_DISTROVERPKGS) == 0)
|
|
{
|
|
dwError = TDNFSplitStringToArray(cn->value,
|
|
" ", &pConf->ppszDistroVerPkgs);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_EXCLUDE) == 0)
|
|
{
|
|
dwError = TDNFSplitStringToArray(cn->value,
|
|
" ", &pConf->ppszExcludes);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_MINVERSIONS) == 0)
|
|
{
|
|
dwError = TDNFSplitStringToArray(cn->value,
|
|
" ", &pConf->ppszMinVersions);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_OPENMAX) == 0)
|
|
{
|
|
pConf->nOpenMax = strtoi(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_CHECK_UPDATE_COMPAT) == 0)
|
|
{
|
|
pConf->nCheckUpdateCompat = isTrue(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_DISTROSYNC_REINSTALL_CHANGED) == 0)
|
|
{
|
|
pConf->nDistroSyncReinstallChanged = isTrue(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_PROXY) == 0)
|
|
{
|
|
SET_STRING(pConf->pszProxy, cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_PROXY_USER) == 0)
|
|
{
|
|
pszProxyUser = cn->value;
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_PROXY_PASS) == 0)
|
|
{
|
|
pszProxyPass = cn->value;
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_INSTALLONLYPKGS) == 0)
|
|
{
|
|
dwError = TDNFSplitStringToArray(cn->value,
|
|
" ", &pConf->ppszInstallOnlyPkgs);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_VARS_DIRS) == 0)
|
|
{
|
|
dwError = TDNFSplitStringToArray(cn->value,
|
|
" ", &pConf->ppszVarsDirs);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_PLUGINS) == 0)
|
|
{
|
|
pConf->nPluginsEnabled = isTrue(cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_PLUGIN_CONF_PATH) == 0)
|
|
{
|
|
SET_STRING(pConf->pszPluginConfPath, cn->value);
|
|
}
|
|
else if (strcmp(cn->name, TDNF_CONF_KEY_PLUGIN_PATH) == 0)
|
|
{
|
|
SET_STRING(pConf->pszPluginPath, cn->value);
|
|
}
|
|
}
|
|
|
|
if (pszProxyUser && pszProxyPass)
|
|
{
|
|
dwError = TDNFAllocateStringPrintf(
|
|
&pConf->pszProxyUserPass,
|
|
"%s:%s",
|
|
pszProxyUser,
|
|
pszProxyPass);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
cleanup:
|
|
return dwError;
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
|
|
uint32_t
|
|
TDNFReadConfig(
|
|
PTDNF pTdnf,
|
|
const char* pszConfFile,
|
|
const char* pszGroup
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
PTDNF_CONF pConf = NULL;
|
|
char *pszConfDir = NULL;
|
|
char *pszMinVersionsDir = NULL;
|
|
char *pszPkgLocksDir = NULL;
|
|
char *pszProtectedDir = NULL;
|
|
|
|
const char *pszTdnfVersion = NULL;
|
|
|
|
struct cnfnode *cn_conf = NULL;
|
|
struct cnfmodule *mod_ini;
|
|
|
|
if(!pTdnf ||
|
|
IsNullOrEmptyString(pszConfFile) ||
|
|
IsNullOrEmptyString(pszGroup))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
dwError = TDNFAllocateMemory(
|
|
1,
|
|
sizeof(TDNF_CONF),
|
|
(void**)&pConf);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
/* defaults */
|
|
pConf->nGPGCheck = 0;
|
|
pConf->nInstallOnlyLimit = 1;
|
|
pConf->nCleanRequirementsOnRemove = 0;
|
|
pConf->nKeepCache = 0;
|
|
pConf->nOpenMax = TDNF_CONF_DEFAULT_OPENMAX;
|
|
pConf->nInstallOnlyLimit = TDNF_CONF_DEFAULT_INSTALLONLY_LIMIT;
|
|
pConf->nSSLVerify = TDNF_CONF_DEFAULT_SSLVERIFY;
|
|
|
|
register_ini(NULL);
|
|
mod_ini = find_cnfmodule("ini");
|
|
if (mod_ini == NULL) {
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
cn_conf = cnfmodule_parse_file(mod_ini, pszConfFile);
|
|
if (cn_conf == NULL)
|
|
{
|
|
if (errno != 0)
|
|
{
|
|
dwError = errno;
|
|
BAIL_ON_TDNF_SYSTEM_ERROR(dwError);
|
|
}
|
|
else
|
|
{
|
|
dwError = ERROR_TDNF_CONF_FILE_LOAD;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
dwError = TDNFParseOSInfo(pConf);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
/* cn_conf == NULL => we will not reach here */
|
|
/* coverity[var_deref_op] */
|
|
dwError = TDNFConfigFromCnfTree(pConf, cn_conf->first_child);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
pszTdnfVersion = TDNFGetVersion();
|
|
|
|
if (pConf->pszOSName == NULL)
|
|
TDNFAllocateString("UNKNOWN", &pConf->pszOSName);
|
|
|
|
if (pConf->pszOSVersion == NULL)
|
|
TDNFAllocateString("UNKNOWN", &pConf->pszOSVersion);
|
|
|
|
dwError = TDNFAllocateStringPrintf(&pConf->pszUserAgentHeader, "tdnf/%s %s/%s", pszTdnfVersion, pConf->pszOSName, pConf->pszOSVersion);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
if (pConf->pszRepoDir == NULL)
|
|
pConf->pszRepoDir = strdup(TDNF_DEFAULT_REPO_LOCATION);
|
|
if (pConf->pszCacheDir == NULL)
|
|
pConf->pszCacheDir = strdup(TDNF_DEFAULT_CACHE_LOCATION);
|
|
if (pConf->ppszDistroVerPkgs == NULL) {
|
|
dwError = TDNFSplitStringToArray(TDNF_DEFAULT_DISTROVERPKGS,
|
|
" ", &pConf->ppszDistroVerPkgs);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
if (pConf->pszPersistDir == NULL)
|
|
pConf->pszPersistDir = strdup(TDNF_DEFAULT_DB_LOCATION);
|
|
|
|
if (pConf->ppszVarsDirs == NULL) {
|
|
dwError = TDNFSplitStringToArray(TDNF_DEFAULT_VARS_DIRS,
|
|
" ", &pConf->ppszVarsDirs);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
if (pConf->pszPluginPath == NULL)
|
|
pConf->pszPluginPath = strdup(TDNF_DEFAULT_PLUGIN_PATH);
|
|
if (pConf->pszPluginConfPath == NULL)
|
|
pConf->pszPluginConfPath = strdup(TDNF_DEFAULT_PLUGIN_CONF_PATH);
|
|
|
|
dwError = TDNFDirName(pszConfFile, &pszConfDir);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
dwError = TDNFJoinPath(&pszMinVersionsDir, pszConfDir, "minversions.d", NULL);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
dwError = TDNFReadConfFilesFromDir(pszMinVersionsDir, &pConf->ppszMinVersions);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
dwError = TDNFJoinPath(&pszPkgLocksDir, pszConfDir, "locks.d", NULL);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
dwError = TDNFReadConfFilesFromDir(pszPkgLocksDir, &pConf->ppszPkgLocks);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
dwError = TDNFJoinPath(&pszProtectedDir, pszConfDir, "protected.d", NULL);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
dwError = TDNFReadConfFilesFromDir(pszProtectedDir, &pConf->ppszProtectedPkgs);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
pTdnf->pConf = pConf;
|
|
|
|
cleanup:
|
|
destroy_cnftree(cn_conf);
|
|
TDNF_SAFE_FREE_MEMORY(pszConfDir);
|
|
TDNF_SAFE_FREE_MEMORY(pszMinVersionsDir);
|
|
TDNF_SAFE_FREE_MEMORY(pszPkgLocksDir);
|
|
TDNF_SAFE_FREE_MEMORY(pszProtectedDir);
|
|
return dwError;
|
|
|
|
error:
|
|
if(pTdnf)
|
|
{
|
|
pTdnf->pConf = NULL;
|
|
}
|
|
if(pConf)
|
|
{
|
|
TDNFFreeConfig(pConf);
|
|
}
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
TDNFConfigExpandVars(
|
|
PTDNF pTdnf
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
PTDNF_CONF pConf = NULL;
|
|
|
|
if(!pTdnf || !pTdnf->pConf)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
pConf = pTdnf->pConf;
|
|
|
|
//Allow --releasever overrides
|
|
if(!pConf->pszVarReleaseVer &&
|
|
!IsNullOrEmptyString(pTdnf->pArgs->pszReleaseVer))
|
|
{
|
|
dwError = TDNFAllocateString(pTdnf->pArgs->pszReleaseVer,
|
|
&pConf->pszVarReleaseVer);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
if(!pConf->pszVarReleaseVer)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; pConf->ppszDistroVerPkgs[i]; i++) {
|
|
dwError = TDNFGetReleaseVersion(
|
|
pTdnf->pArgs->pszInstallRoot,
|
|
pConf->ppszDistroVerPkgs[i],
|
|
&pConf->pszVarReleaseVer);
|
|
|
|
if (dwError == 0)
|
|
break;
|
|
else if (dwError != ERROR_TDNF_NO_DISTROVERPKG)
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
if(!pConf->pszVarBaseArch)
|
|
{
|
|
dwError = TDNFGetKernelArch(&pConf->pszVarBaseArch);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
cleanup:
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
void
|
|
TDNFFreeConfig(
|
|
PTDNF_CONF pConf
|
|
)
|
|
{
|
|
if(pConf)
|
|
{
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszProxy);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszProxyUserPass);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszRepoDir);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszCacheDir);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszPersistDir);
|
|
TDNF_SAFE_FREE_STRINGARRAY(pConf->ppszDistroVerPkgs);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszVarReleaseVer);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszVarBaseArch);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszBaseArch);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszUserAgentHeader);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszOSName);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszOSVersion);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszPluginPath);
|
|
TDNF_SAFE_FREE_MEMORY(pConf->pszPluginConfPath);
|
|
TDNF_SAFE_FREE_STRINGARRAY(pConf->ppszExcludes);
|
|
TDNF_SAFE_FREE_STRINGARRAY(pConf->ppszMinVersions);
|
|
TDNF_SAFE_FREE_STRINGARRAY(pConf->ppszPkgLocks);
|
|
TDNF_SAFE_FREE_STRINGARRAY(pConf->ppszProtectedPkgs);
|
|
TDNF_SAFE_FREE_STRINGARRAY(pConf->ppszInstallOnlyPkgs);
|
|
TDNF_SAFE_FREE_STRINGARRAY(pConf->ppszVarsDirs);
|
|
TDNFFreeMemory(pConf);
|
|
}
|
|
}
|
|
|
|
uint32_t
|
|
TDNFConfigReplaceVars(
|
|
PTDNF pTdnf,
|
|
char** ppszString
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
char* pszDst = NULL;
|
|
struct cnfnode * cn_vars = NULL, *cn;
|
|
|
|
if(!pTdnf || !ppszString || IsNullOrEmptyString(*ppszString))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
cn_vars = parse_varsdirs(pTdnf->pConf->ppszVarsDirs);
|
|
if (cn_vars == NULL) {
|
|
pr_err("parsing vars failed: %s (%d)\n", strerror(errno), errno);
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
cn = create_cnfnode(TDNF_VAR_RELEASEVER);
|
|
cnfnode_setval(cn, pTdnf->pConf->pszVarReleaseVer);
|
|
append_node(cn_vars, cn);
|
|
|
|
cn = create_cnfnode(TDNF_VAR_BASEARCH);
|
|
cnfnode_setval(cn, pTdnf->pConf->pszVarBaseArch);
|
|
append_node(cn_vars, cn);
|
|
|
|
pszDst = replace_vars(cn_vars, *ppszString);
|
|
if (pszDst == NULL) {
|
|
pr_err("replacing vars in %s failed\n", *ppszString);
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
TDNFFreeMemory(*ppszString);
|
|
*ppszString = pszDst;
|
|
|
|
cleanup:
|
|
destroy_cnftree(cn_vars);
|
|
return dwError;
|
|
|
|
error:
|
|
TDNF_SAFE_FREE_MEMORY(pszDst);
|
|
goto cleanup;
|
|
}
|
|
|
|
/*
|
|
* Read all minimal versions files from pszDir, and store results into
|
|
* string array pointed to by pppszLines. pppszLines may already
|
|
* have values set from the config file, which are preserved.
|
|
*/
|
|
uint32_t
|
|
TDNFReadConfFilesFromDir(
|
|
char *pszDir,
|
|
char ***pppszLines
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
DIR *pDir = NULL;
|
|
struct dirent *pEnt = NULL;
|
|
char *pszFile = NULL;
|
|
char **ppszNewLines = NULL;
|
|
char ***pppszArrayList = NULL;
|
|
int nFileCount = 0;
|
|
int i, j, k;
|
|
int nLineCount = 0;
|
|
int nTmp = 0;
|
|
|
|
if(IsNullOrEmptyString(pszDir) || !pppszLines)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
|
|
/* first, open directory and count all files match *.conf,
|
|
* so we know how much memory we need */
|
|
pDir = opendir(pszDir);
|
|
if (pDir == NULL)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
|
|
while((pEnt = readdir(pDir)) != NULL)
|
|
{
|
|
if (fnmatch("*.conf", pEnt->d_name, 0) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
nFileCount++;
|
|
}
|
|
closedir(pDir);
|
|
pDir = NULL;
|
|
|
|
/* allocate memory for our string array */
|
|
dwError = TDNFAllocateMemory(nFileCount + 1, sizeof(char **), (void **)&pppszArrayList);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
/* read directory again and the files, store content of each file
|
|
* temporarily in pppszArrayList[i] */
|
|
i = 0;
|
|
pDir = opendir(pszDir);
|
|
while((pEnt = readdir(pDir)) != NULL && i < nFileCount)
|
|
{
|
|
if (fnmatch("*.conf", pEnt->d_name, 0) != 0)
|
|
{
|
|
continue;
|
|
}
|
|
dwError = TDNFJoinPath(&pszFile, pszDir, pEnt->d_name, NULL);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
dwError = TDNFReadFileToStringArray(pszFile, &pppszArrayList[i]);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
TDNF_SAFE_FREE_MEMORY(pszFile);
|
|
|
|
i++;
|
|
}
|
|
closedir(pDir);
|
|
pDir = NULL;
|
|
|
|
/* append values that are already set */
|
|
pppszArrayList[i] = *pppszLines;
|
|
|
|
/* each file can have multiple lines, count them */
|
|
for (i = 0; pppszArrayList[i]; i++)
|
|
{
|
|
dwError = TDNFStringArrayCount(pppszArrayList[i], &nTmp);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
nLineCount += nTmp;
|
|
}
|
|
|
|
/* move the lines from 2 dimensional pppszArrayList to
|
|
* flat pointer list ppszLines */
|
|
dwError = TDNFAllocateMemory(nLineCount+1, sizeof(char *), (void **)&ppszNewLines);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
for (i = 0, k = 0; pppszArrayList[i]; i++)
|
|
{
|
|
for (j = 0; pppszArrayList[i][j]; j++)
|
|
{
|
|
ppszNewLines[k++] = pppszArrayList[i][j];
|
|
}
|
|
TDNF_SAFE_FREE_MEMORY(pppszArrayList[i]);
|
|
}
|
|
|
|
*pppszLines = ppszNewLines;
|
|
|
|
cleanup:
|
|
if (pDir)
|
|
{
|
|
closedir(pDir);
|
|
}
|
|
TDNF_SAFE_FREE_MEMORY(pppszArrayList);
|
|
TDNF_SAFE_FREE_MEMORY(pszFile);
|
|
return dwError;
|
|
error:
|
|
goto cleanup;
|
|
}
|