mirror of https://github.com/vmware/tdnf.git
781 lines
17 KiB
C
781 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"
|
|
|
|
uint32_t
|
|
SolvLoadRepomd(
|
|
Repo* pRepo,
|
|
const char* pszRepomd
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
FILE *fp = NULL;
|
|
if( !pRepo || IsNullOrEmptyString(pszRepomd))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
fp = fopen(pszRepomd, "r");
|
|
if (fp == NULL)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
if (repo_add_repomdxml(pRepo, fp, 0))
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
cleanup:
|
|
if(fp != NULL)
|
|
{
|
|
fclose(fp);
|
|
}
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvLoadRepomdPrimary(
|
|
Repo* pRepo,
|
|
const char* pszPrimary
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
FILE *fp = NULL;
|
|
if( !pRepo || IsNullOrEmptyString(pszPrimary))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
fp = solv_xfopen(pszPrimary, "r");
|
|
if (fp == NULL)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
if (repo_add_rpmmd(pRepo, fp, 0, 0))
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
cleanup:
|
|
if(fp != NULL)
|
|
{
|
|
fclose(fp);
|
|
}
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
uint32_t
|
|
SolvLoadRepomdFilelists(
|
|
Repo* pRepo,
|
|
const char* pszFilelists
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
FILE *fp = NULL;
|
|
if(!pRepo || IsNullOrEmptyString(pszFilelists))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
fp = solv_xfopen(pszFilelists, "r");
|
|
if (fp == NULL)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
if (repo_add_rpmmd(pRepo, fp, "FL", REPO_EXTEND_SOLVABLES))
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_FAILED;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
cleanup:
|
|
if(fp != NULL)
|
|
fclose(fp);
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvLoadRepomdUpdateinfo(
|
|
Repo* pRepo,
|
|
const char* pszUpdateinfo
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
FILE *fp = NULL;
|
|
if( !pRepo || IsNullOrEmptyString(pszUpdateinfo))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
fp = solv_xfopen(pszUpdateinfo, "r");
|
|
if (fp == NULL)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
if (repo_add_updateinfoxml(pRepo, fp, 0))
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
cleanup:
|
|
if(fp != NULL)
|
|
{
|
|
fclose(fp);
|
|
}
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvLoadRepomdOther(
|
|
Repo* pRepo,
|
|
const char* pszOther
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
FILE *fp = NULL;
|
|
if( !pRepo || IsNullOrEmptyString(pszOther))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
fp = solv_xfopen(pszOther, "r");
|
|
if (fp == NULL)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
if (repo_add_rpmmd(pRepo, fp, 0, REPO_EXTEND_SOLVABLES))
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
cleanup:
|
|
if(fp != NULL)
|
|
{
|
|
fclose(fp);
|
|
}
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
uint32_t
|
|
SolvReadYumRepo(
|
|
Repo *pRepo,
|
|
const char *pszRepoName,
|
|
const char *pszRepomd,
|
|
const char *pszPrimary,
|
|
const char *pszFilelists,
|
|
const char *pszUpdateinfo,
|
|
const char *pszOther
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
if(!pRepo || !pszRepoName || !pszRepomd || !pszPrimary)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
dwError = SolvLoadRepomd(pRepo, pszRepomd);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
|
|
|
|
dwError = SolvLoadRepomdPrimary(pRepo, pszPrimary);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
|
|
if(pszFilelists)
|
|
{
|
|
dwError = SolvLoadRepomdFilelists(pRepo, pszFilelists);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
if(pszUpdateinfo)
|
|
{
|
|
dwError = SolvLoadRepomdUpdateinfo(pRepo, pszUpdateinfo);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
if(pszOther)
|
|
{
|
|
dwError = SolvLoadRepomdOther(pRepo, pszOther);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
|
|
cleanup:
|
|
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvCountPackages(
|
|
PSolvSack pSack,
|
|
uint32_t* pdwCount
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
uint32_t dwCount = 0;
|
|
const Pool* pool = 0;
|
|
Id p = 0;
|
|
if(!pSack || !pSack->pPool || !pdwCount)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
pool = pSack->pPool;
|
|
FOR_POOL_SOLVABLES(p)
|
|
{
|
|
dwCount++;
|
|
}
|
|
*pdwCount = dwCount;
|
|
cleanup:
|
|
return dwError;
|
|
error:
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
static
|
|
uint32_t
|
|
readRpmsFromDir(
|
|
Repo *pRepo,
|
|
const char *pszDir
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
DIR *pDir = NULL;
|
|
struct dirent *pEnt = NULL;
|
|
char *pszPath = NULL;
|
|
|
|
pDir = opendir(pszDir);
|
|
if(pDir == NULL) {
|
|
dwError = errno;
|
|
BAIL_ON_TDNF_SYSTEM_ERROR(dwError);
|
|
}
|
|
while ((pEnt = readdir (pDir)) != NULL ) {
|
|
int isDir;
|
|
|
|
if (pEnt->d_name[0] == '.') {
|
|
/* skip '.', '..', but also any dir name starting with '.' */
|
|
continue;
|
|
}
|
|
|
|
dwError = TDNFJoinPath(
|
|
&pszPath,
|
|
pszDir,
|
|
pEnt->d_name,
|
|
NULL);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
dwError = TDNFIsDir(pszPath, &isDir);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
if (isDir) {
|
|
dwError = readRpmsFromDir(pRepo, pszPath);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
} else if (strcmp(&pEnt->d_name[strlen(pEnt->d_name)-4], ".rpm") == 0) {
|
|
if(!repo_add_rpm(pRepo,
|
|
pszPath,
|
|
REPO_REUSE_REPODATA|REPO_NO_INTERNALIZE)) {
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
}
|
|
TDNF_SAFE_FREE_MEMORY(pszPath);
|
|
}
|
|
cleanup:
|
|
if(pDir) {
|
|
closedir(pDir);
|
|
}
|
|
TDNF_SAFE_FREE_MEMORY(pszPath);
|
|
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvReadRpmsFromDirectory(
|
|
Repo *pRepo,
|
|
const char *pszDir
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
|
|
if(!pRepo || IsNullOrEmptyString(pszDir))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
dwError = readRpmsFromDir(pRepo, pszDir);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
|
|
repo_internalize(pRepo);
|
|
|
|
cleanup:
|
|
return dwError;
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvReadInstalledRpms(
|
|
Repo* pRepo,
|
|
const char *pszCacheFileName
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
FILE *pCacheFile = NULL;
|
|
int dwFlags = 0;
|
|
|
|
if(!pRepo)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
if(pszCacheFileName && access(pszCacheFileName, F_OK) == 0)
|
|
{
|
|
/* coverity[toctou] */
|
|
pCacheFile = fopen(pszCacheFileName, "r");
|
|
|
|
if(!pCacheFile)
|
|
{
|
|
dwError = errno;
|
|
BAIL_ON_TDNF_SYSTEM_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
dwFlags = REPO_REUSE_REPODATA | RPM_ADD_WITH_HDRID | REPO_USE_ROOTDIR;
|
|
dwError = repo_add_rpmdb_reffp(pRepo, pCacheFile, dwFlags);
|
|
|
|
if (dwError)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
cleanup:
|
|
if (pCacheFile)
|
|
fclose(pCacheFile);
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvCalculateCookieForFile(
|
|
const char *pszFilePath,
|
|
unsigned char *pszCookie
|
|
)
|
|
{
|
|
FILE *fp = NULL;
|
|
int32_t nLen = 0;
|
|
uint32_t dwError = 0;
|
|
Chksum *pChkSum = NULL;
|
|
char buf[BUFSIZ] = {0};
|
|
|
|
if (!pszFilePath)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
fp = fopen(pszFilePath, "r");
|
|
if (!fp)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
pChkSum = solv_chksum_create(REPOKEY_TYPE_SHA256);
|
|
if (!pChkSum)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_CHKSUM;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
solv_chksum_add(pChkSum, SOLV_COOKIE_IDENT, strlen(SOLV_COOKIE_IDENT));
|
|
|
|
while ((nLen = fread(buf, 1, sizeof(buf) - 1, fp)) > 0)
|
|
{
|
|
solv_chksum_add(pChkSum, buf, nLen);
|
|
memset(buf, 0, sizeof(buf));
|
|
}
|
|
solv_chksum_free(pChkSum, pszCookie);
|
|
|
|
cleanup:
|
|
if (fp)
|
|
{
|
|
fclose(fp);
|
|
}
|
|
|
|
return dwError;
|
|
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
/* Create a name for the repo cache path based on repo name and
|
|
a hash of the url.
|
|
*/
|
|
uint32_t
|
|
SolvCreateRepoCacheName(
|
|
const char *pszName,
|
|
const char *pszUrl,
|
|
char **ppszCacheName
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
Chksum *pChkSum = NULL;
|
|
unsigned char pCookie[SOLV_COOKIE_LEN] = {0};
|
|
char pszCookie[9] = {0};
|
|
char *pszCacheName = NULL;
|
|
|
|
if (!pszName || !pszUrl || !ppszCacheName)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
pChkSum = solv_chksum_create(REPOKEY_TYPE_SHA256);
|
|
if (!pChkSum)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_CHKSUM;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
solv_chksum_add(pChkSum, pszUrl, strlen(pszUrl));
|
|
solv_chksum_free(pChkSum, pCookie);
|
|
|
|
snprintf(pszCookie, sizeof(pszCookie), "%.2x%.2x%.2x%.2x",
|
|
pCookie[0], pCookie[1], pCookie[2], pCookie[3]);
|
|
|
|
dwError = TDNFAllocateStringPrintf(&pszCacheName, "%s-%s", pszName, pszCookie);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
|
|
*ppszCacheName = pszCacheName;
|
|
cleanup:
|
|
return dwError;
|
|
|
|
error:
|
|
TDNF_SAFE_FREE_MEMORY(pszCacheName);
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvGetMetaDataCachePath(
|
|
PSOLV_REPO_INFO_INTERNAL pSolvRepoInfo,
|
|
char** ppszCachePath
|
|
)
|
|
{
|
|
char *pszCachePath = NULL;
|
|
uint32_t dwError = 0;
|
|
Repo *pRepo = NULL;
|
|
|
|
if (!pSolvRepoInfo || !pSolvRepoInfo->pRepo || !ppszCachePath)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
pRepo = pSolvRepoInfo->pRepo;
|
|
if (!IsNullOrEmptyString(pRepo->name))
|
|
{
|
|
dwError = TDNFAllocateStringPrintf(
|
|
&pszCachePath,
|
|
"%s/%s/%s.solv",
|
|
pSolvRepoInfo->pszRepoCacheDir,
|
|
TDNF_SOLVCACHE_DIR_NAME,
|
|
pRepo->name);
|
|
BAIL_ON_TDNF_ERROR(dwError);
|
|
}
|
|
*ppszCachePath = pszCachePath;
|
|
cleanup:
|
|
return dwError;
|
|
error:
|
|
TDNF_SAFE_FREE_MEMORY(pszCachePath);
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvAddSolvMetaData(
|
|
PSOLV_REPO_INFO_INTERNAL pSolvRepoInfo,
|
|
const char *pszTempSolvFile
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
Repo *pRepo = NULL;
|
|
FILE *fp = NULL;
|
|
int i = 0;
|
|
|
|
if (!pSolvRepoInfo || !pSolvRepoInfo->pRepo || !pszTempSolvFile)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
pRepo = pSolvRepoInfo->pRepo;
|
|
if (!pRepo->pool)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
for (i = pRepo->start; i < pRepo->end; i++)
|
|
{
|
|
if (pRepo->pool->solvables[i].repo != pRepo)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
if (i < pRepo->end)
|
|
{
|
|
goto cleanup;
|
|
}
|
|
fp = fopen (pszTempSolvFile, "r");
|
|
if (fp == NULL)
|
|
{
|
|
dwError = errno;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
repo_empty(pRepo, 1);
|
|
if (repo_add_solv(pRepo, fp, SOLV_ADD_NO_STUBS))
|
|
{
|
|
dwError = ERROR_TDNF_ADD_SOLV;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
cleanup:
|
|
if (fp != NULL)
|
|
{
|
|
fclose(fp);
|
|
}
|
|
return dwError;
|
|
error:
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvUseMetaDataCache(
|
|
const PSolvSack pSack,
|
|
PSOLV_REPO_INFO_INTERNAL pSolvRepoInfo,
|
|
int *nUseMetaDataCache
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
FILE *fp = NULL;
|
|
Repo *pRepo = NULL;
|
|
const unsigned char *pszCookie = NULL;
|
|
unsigned char pszTempCookie[32];
|
|
char *pszCacheFilePath = NULL;
|
|
|
|
if (!pSack || !pSolvRepoInfo || !pSolvRepoInfo->pRepo)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
pRepo = pSolvRepoInfo->pRepo;
|
|
pszCookie = pSolvRepoInfo->nCookieSet ? pSolvRepoInfo->cookie : NULL;
|
|
|
|
dwError = SolvGetMetaDataCachePath(pSolvRepoInfo, &pszCacheFilePath);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
|
|
if (IsNullOrEmptyString(pszCacheFilePath))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
fp = fopen(pszCacheFilePath, "r");
|
|
if (fp == NULL)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_CACHE_NOT_CREATED;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
// Reading the cookie from cached Solv File
|
|
if (fseek (fp, -sizeof(pszTempCookie), SEEK_END) || fread (pszTempCookie, sizeof(pszTempCookie), 1, fp) != 1)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
// compare the calculated cookie with the one read from Solv file
|
|
if (pszCookie && memcmp (pszCookie, pszTempCookie, sizeof(pszTempCookie)) != 0)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
rewind(fp);
|
|
if (repo_add_solv(pRepo, fp, 0))
|
|
{
|
|
dwError = ERROR_TDNF_ADD_SOLV;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
*nUseMetaDataCache = 1;
|
|
|
|
cleanup:
|
|
if (fp != NULL)
|
|
{
|
|
fclose(fp);
|
|
}
|
|
TDNF_SAFE_FREE_MEMORY(pszCacheFilePath);
|
|
return dwError;
|
|
error:
|
|
if (dwError == ERROR_TDNF_SOLV_CACHE_NOT_CREATED)
|
|
{
|
|
dwError = 0;
|
|
}
|
|
goto cleanup;
|
|
}
|
|
|
|
uint32_t
|
|
SolvCreateMetaDataCache(
|
|
const PSolvSack pSack,
|
|
PSOLV_REPO_INFO_INTERNAL pSolvRepoInfo
|
|
)
|
|
{
|
|
uint32_t dwError = 0;
|
|
Repo *pRepo = NULL;
|
|
FILE *fp = NULL;
|
|
int fd = 0;
|
|
char *pszSolvCacheDir = NULL;
|
|
char *pszTempSolvFile = NULL;
|
|
char *pszCacheFilePath = NULL;
|
|
mode_t mask = 0;
|
|
|
|
if (!pSack || !pSolvRepoInfo)
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
pRepo = pSolvRepoInfo->pRepo;
|
|
dwError = TDNFJoinPath(
|
|
&pszSolvCacheDir,
|
|
pSolvRepoInfo->pszRepoCacheDir,
|
|
TDNF_SOLVCACHE_DIR_NAME,
|
|
NULL);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
|
|
if (access(pszSolvCacheDir, W_OK | X_OK))
|
|
{
|
|
if(errno != ENOENT)
|
|
{
|
|
dwError = errno;
|
|
}
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
|
|
dwError = TDNFUtilsMakeDirs(pszSolvCacheDir);
|
|
if (dwError == ERROR_TDNF_ALREADY_EXISTS)
|
|
{
|
|
dwError = 0;
|
|
}
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
pszTempSolvFile = solv_dupjoin(pszSolvCacheDir, "/", ".newsolv-XXXXXX");
|
|
mask = umask(S_IRUSR | S_IWUSR | S_IRWXG);
|
|
umask(mask);
|
|
fd = mkstemp(pszTempSolvFile);
|
|
if (fd < 0)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
fchmod(fd, 0444);
|
|
fp = fdopen(fd, "w");
|
|
if (fp == NULL)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
if (repo_write(pRepo, fp))
|
|
{
|
|
dwError = ERROR_TDNF_REPO_WRITE;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
if (pSolvRepoInfo->nCookieSet)
|
|
{
|
|
if (fwrite(pSolvRepoInfo->cookie, SOLV_COOKIE_LEN, 1, fp) != 1)
|
|
{
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
}
|
|
|
|
if (fclose(fp))
|
|
{
|
|
fp = NULL;/* so that error branch will not attempt to close again */
|
|
dwError = ERROR_TDNF_SOLV_IO;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
fp = NULL;
|
|
dwError = SolvAddSolvMetaData(pSolvRepoInfo, pszTempSolvFile);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
|
|
dwError = SolvGetMetaDataCachePath(pSolvRepoInfo, &pszCacheFilePath);
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
|
|
if (IsNullOrEmptyString(pszCacheFilePath))
|
|
{
|
|
dwError = ERROR_TDNF_INVALID_PARAMETER;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
|
|
if (rename(pszTempSolvFile, pszCacheFilePath) == -1)
|
|
{
|
|
dwError = ERROR_TDNF_SYSTEM_BASE + errno;
|
|
BAIL_ON_TDNF_LIBSOLV_ERROR(dwError);
|
|
}
|
|
unlink(pszTempSolvFile);
|
|
cleanup:
|
|
TDNF_SAFE_FREE_MEMORY(pszTempSolvFile);
|
|
TDNF_SAFE_FREE_MEMORY(pszSolvCacheDir);
|
|
TDNF_SAFE_FREE_MEMORY(pszCacheFilePath);
|
|
return dwError;
|
|
error:
|
|
if (fp != NULL)
|
|
{
|
|
fclose(fp);
|
|
unlink(pszTempSolvFile);
|
|
}
|
|
else if (fd > 0)
|
|
{
|
|
close(fd);
|
|
unlink(pszTempSolvFile);
|
|
}
|
|
goto cleanup;
|
|
}
|