uint32_t TDNFRemoveCachedRpms( GArray* pCachedRpmsArray ) { uint32_t dwError = 0; uint32_t dwIndex = 0; char* pszCachedRpm = NULL; if(!pCachedRpmsArray) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } for(dwIndex = 0; dwIndex < pCachedRpmsArray->len; ++dwIndex) { pszCachedRpm = g_array_index(pCachedRpmsArray, char*, dwIndex); if(access(pszCachedRpm, F_OK) != -1) { if(unlink(pszCachedRpm)) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } } } cleanup: return dwError; error: goto cleanup; }
uint32_t ReadAllBytes( const char* pszFile, char** ppszData ) { uint32_t dwError = 0; size_t fsize = 0; char* pszData = NULL; FILE* fp = NULL; if(IsNullOrEmptyString(pszFile) || !ppszData) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } fp = fopen(pszFile, "r"); if(!fp) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } if(fseek(fp, 0, SEEK_END)) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } fsize = ftell(fp); if(fseek(fp, 0, SEEK_SET)) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } dwError = TDNFAllocateMemory(fsize+1, (void**)&pszData); BAIL_ON_TDNF_ERROR(dwError); if(!fread(pszData, fsize, 1, fp)) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } *ppszData = pszData; cleanup: if(fp) { fclose(fp); } return dwError; error: if(!ppszData) { *ppszData = NULL; } TDNF_SAFE_FREE_MEMORY(pszData); goto cleanup; }
uint32_t VerifyRpmSig( rpmKeyring pKeyring, const char* pszPkgFile ) { uint32_t dwError = 0; FD_t pFD_t = NULL; rpmts pTS = NULL; rpmtd pTD = NULL; Header pPkgHeader = NULL; pgpDig pDigest = NULL; if(!pKeyring || IsNullOrEmptyString(pszPkgFile)) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } pFD_t = Fopen(pszPkgFile, "r.fdio"); if(!pFD_t) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } pTS = rpmtsCreate(); if(!pTS) { dwError = ERROR_TDNF_RPMTS_CREATE_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } rpmtsSetVSFlags (pTS, _RPMVSF_NOSIGNATURES); pTD = rpmtdNew(); if(!pTD) { dwError = ERROR_TDNF_RPMTD_CREATE_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } dwError = rpmReadPackageFile(pTS, pFD_t, pszPkgFile, &pPkgHeader); BAIL_ON_TDNF_RPM_ERROR(dwError); if(!headerConvert(pPkgHeader, HEADERCONV_RETROFIT_V3)) { dwError = ERROR_TDNF_RPM_HEADER_CONVERT_FAILED; BAIL_ON_TDNF_RPM_ERROR(dwError); } if(!headerGet(pPkgHeader, RPMTAG_RSAHEADER, pTD, HEADERGET_MINMEM)) { dwError = ERROR_TDNF_RPM_GET_RSAHEADER_FAILED; BAIL_ON_TDNF_ERROR(dwError); } pDigest = pgpNewDig(); if(pgpPrtPkts(pTD->data, pTD->count, pDigest, 0)) { dwError = ERROR_TDNF_RPM_GPG_PARSE_FAILED; BAIL_ON_TDNF_ERROR(dwError); } if(rpmKeyringLookup(pKeyring, pDigest) != RPMRC_OK) { dwError = ERROR_TDNF_RPM_GPG_NO_MATCH; BAIL_ON_TDNF_ERROR(dwError); } cleanup: if(pFD_t) { Fclose(pFD_t); } if(pDigest) { pgpFreeDig(pDigest); } if(pPkgHeader) { headerFree(pPkgHeader); } if(pTD) { rpmtdFree(pTD); } if(pTS) { rpmtsFree(pTS); } return dwError; error: goto cleanup; }
//Download repo metadata and initialize uint32_t TDNFInitRepo( PTDNF pTdnf, PTDNF_REPO_DATA pRepoData, HyRepo* phRepo ) { uint32_t dwError = 0; gboolean bRet = 0; LrHandle* hLibRepo = NULL; LrResult* pResult = NULL; LrYumRepo* pRepo = NULL; int nLocalOnly = 0; char* pszRepoCacheDir = NULL; char* pszRepoDataDir = NULL; char* pszUserPass = NULL; char* ppszRepoUrls[] = {NULL, NULL}; char* ppszLocalUrls[] = {NULL, NULL}; char* ppszDownloadList[] = {"primary", "filelists", "updateinfo", NULL}; PTDNF_CONF pConf = NULL; HyRepo hRepo = NULL; if(!pTdnf || !pTdnf->pConf || !pRepoData || !phRepo) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } pConf = pTdnf->pConf; pszRepoCacheDir = g_build_path( G_DIR_SEPARATOR_S, pConf->pszCacheDir, pRepoData->pszId, NULL); if(!pszRepoCacheDir) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } pszRepoDataDir = g_build_path( G_DIR_SEPARATOR_S, pszRepoCacheDir, TDNF_REPODATA_DIR_NAME, NULL); if(!pszRepoDataDir) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } ppszRepoUrls[0] = pRepoData->pszBaseUrl; ppszLocalUrls[0] = pszRepoCacheDir; hLibRepo = lr_handle_init(); if(!hLibRepo) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } pResult = lr_result_init(); if(!pResult) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } //Look for repodata dir - this is auto created //during last refresh so skip download if present if(!access(pszRepoDataDir, F_OK)) { nLocalOnly = 1; lr_handle_setopt(hLibRepo, NULL, LRO_URLS, ppszLocalUrls); lr_handle_setopt(hLibRepo, NULL, LRO_IGNOREMISSING, 1); } else { //Look for the repo root cache dir. If not there, //try to create and download into it. if(access(pszRepoCacheDir, F_OK)) { if(errno != ENOENT) { dwError = errno; } BAIL_ON_TDNF_SYSTEM_ERROR(dwError); if(mkdir(pszRepoCacheDir, 755)) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } } lr_handle_setopt(hLibRepo, NULL, LRO_URLS, ppszRepoUrls); lr_handle_setopt(hLibRepo, NULL, LRO_SSLVERIFYPEER, 1); lr_handle_setopt(hLibRepo, NULL, LRO_SSLVERIFYHOST, 2); lr_handle_setopt(hLibRepo, NULL, LRO_DESTDIR, pszRepoCacheDir); lr_handle_setopt(hLibRepo, NULL, LRO_YUMDLIST, ppszDownloadList); if(!IsNullOrEmptyString(pRepoData->pszUser) && !IsNullOrEmptyString(pRepoData->pszPass)) { dwError = TDNFAllocateStringPrintf( &pszUserPass, "%s:%s", pRepoData->pszUser, pRepoData->pszPass); BAIL_ON_TDNF_ERROR(dwError); lr_handle_setopt( hLibRepo, NULL, LRO_USERPWD, pszUserPass); } } lr_handle_setopt(hLibRepo, NULL, LRO_REPOTYPE, LR_YUMREPO); lr_handle_setopt(hLibRepo, NULL, LRO_LOCAL, nLocalOnly); bRet = lr_handle_perform(hLibRepo, pResult, NULL); if(!bRet) { dwError = ERROR_TDNF_REPO_PERFORM; BAIL_ON_TDNF_ERROR(dwError); } bRet = lr_result_getinfo(pResult, NULL, LRR_YUM_REPO, &pRepo); if(!bRet) { dwError = ERROR_TDNF_REPO_GETINFO; BAIL_ON_TDNF_ERROR(dwError); } //Create and set repo properties hRepo = hy_repo_create(pRepoData->pszId); if(!hRepo) { dwError = ERROR_TDNF_HAWKEY_FAILED; BAIL_ON_TDNF_ERROR(dwError); } dwError = TDNFInitRepoFromMetaData(hRepo, pRepo); BAIL_ON_TDNF_ERROR(dwError); *phRepo = hRepo; cleanup: if(pszRepoDataDir) { g_free(pszRepoDataDir); } if(pszRepoCacheDir) { g_free(pszRepoCacheDir); } if(pResult) { lr_result_free(pResult); } if(hLibRepo) { lr_handle_free(hLibRepo); } return dwError; error: //If there is an error during init, log the error //remove any cache data that could be potentially corrupt. if(pRepoData) { fprintf( stderr, "Error: Failed to synchronize cache for repo '%s' from '%s'\n", pRepoData->pszName, pRepoData->pszBaseUrl); if(pTdnf) { TDNFRepoRemoveCache(pTdnf, pRepoData->pszId); } } if(phRepo) { *phRepo = NULL; } if(hRepo) { hy_repo_free(hRepo); } goto cleanup; }
//check a local rpm folder for dependency issues. uint32_t TDNFCheckLocalPackages( PTDNF pTdnf, const char* pszLocalPath ) { uint32_t dwError = 0; int i = 0; char* pszRPMPath = NULL; const char* pszFile = NULL; GDir* pDir = NULL; HySack hSack = NULL; HyPackage hPkg = NULL; HyGoal hGoal = NULL; HyPackageList hPkgList = NULL; if(!pTdnf || !pszLocalPath) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } pDir = g_dir_open(pszLocalPath, 0, NULL); if(!pDir) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } fprintf(stdout, "Checking all packages from: %s\n", pszLocalPath); hSack = hy_sack_create(NULL, NULL, NULL, 0); if(!hSack) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } hy_sack_create_cmdline_repo(hSack); hPkgList = hy_packagelist_create(); if(!hPkgList) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } while ((pszFile = g_dir_read_name (pDir)) != NULL) { if (!g_str_has_suffix (pszFile, TDNF_RPM_EXT)) { continue; } pszRPMPath = g_build_filename(pszLocalPath, pszFile, NULL); hPkg = hy_sack_add_cmdline_package(hSack, pszRPMPath); g_free(pszRPMPath); pszRPMPath = NULL; if(!hPkg) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } hy_packagelist_push(hPkgList, hPkg); hPkg = NULL; } fprintf(stdout, "Found %d packages\n", hy_packagelist_count(hPkgList)); hGoal = hy_goal_create(hSack); if(!hGoal) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_TDNF_ERROR(dwError); } FOR_PACKAGELIST(hPkg, hPkgList, i) { dwError = hy_goal_install(hGoal, hPkg); BAIL_ON_TDNF_HAWKEY_ERROR(dwError); }
uint32_t TDNFTransAddInstallPkg( PTDNFRPMTS pTS, PTDNF pTdnf, HyPackage hPkg, int nUpgrade ) { uint32_t dwError = 0; int nGPGCheck = 0; char* pszRpmCacheDir = NULL; char* pszFilePath = NULL; const char* pszRepoName = NULL; char* pszHyName = NULL; Header rpmHeader = NULL; FD_t fp = NULL; char* pszDownloadCacheDir = NULL; char* pszUrlGPGKey = NULL; pszRepoName = hy_package_get_reponame(hPkg); pszHyName = hy_package_get_location(hPkg); pszRpmCacheDir = g_build_filename( G_DIR_SEPARATOR_S, pTdnf->pConf->pszCacheDir, pszRepoName, "rpms", G_DIR_SEPARATOR_S, NULL); pszFilePath = g_build_filename(pszRpmCacheDir, pszHyName, NULL); if(pTS->pCachedRpmsArray) { if(!g_array_append_val(pTS->pCachedRpmsArray, pszFilePath)) { dwError = ERROR_TDNF_OUT_OF_MEMORY; BAIL_ON_TDNF_ERROR(dwError); } } pszDownloadCacheDir = g_path_get_dirname(pszFilePath); if(!pszDownloadCacheDir) { dwError = ENOENT; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } if(access(pszDownloadCacheDir, F_OK)) { if(errno != ENOENT) { dwError = errno; } BAIL_ON_TDNF_SYSTEM_ERROR(dwError); dwError = TDNFUtilsMakeDirs(pszDownloadCacheDir); BAIL_ON_TDNF_ERROR(dwError); } if(access(pszFilePath, F_OK)) { if(errno != ENOENT) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } dwError = TDNFDownloadPackage(pTdnf, hPkg, pszDownloadCacheDir); BAIL_ON_TDNF_ERROR(dwError); } //A download could have been triggered. //So check access and bail if not available if(access(pszFilePath, F_OK)) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } //Check override, then repo config and launch //gpg check if needed dwError = TDNFGetGPGCheck(pTdnf, pszRepoName, &nGPGCheck, &pszUrlGPGKey); BAIL_ON_TDNF_ERROR(dwError); if(nGPGCheck) { dwError = TDNFGPGCheck(pTS->pKeyring, pszUrlGPGKey, pszFilePath); BAIL_ON_TDNF_ERROR(dwError); } fp = Fopen (pszFilePath, "r.ufdio"); if(!fp) { dwError = errno; BAIL_ON_TDNF_SYSTEM_ERROR(dwError); } dwError = rpmReadPackageFile( pTS->pTS, fp, pszFilePath, &rpmHeader); //If not checking gpg sigs, ignore signature errors if(!nGPGCheck && (dwError == RPMRC_NOTTRUSTED || dwError == RPMRC_NOKEY)) { dwError = 0; } BAIL_ON_TDNF_RPM_ERROR(dwError); dwError = rpmtsAddInstallElement( pTS->pTS, rpmHeader, (fnpyKey)pszFilePath, nUpgrade, NULL); BAIL_ON_TDNF_RPM_ERROR(dwError); cleanup: TDNF_SAFE_FREE_MEMORY(pszUrlGPGKey); if(pszHyName) { hy_free(pszHyName); } if(pszDownloadCacheDir) { g_free(pszDownloadCacheDir); } if(pszRpmCacheDir) { g_free(pszRpmCacheDir); } if(fp) { Fclose(fp); } if(rpmHeader) { headerFree(rpmHeader); } return dwError; error: goto cleanup; }