uint32_t TDNFCliCheckLocalCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; if(!pTdnf || !pCmdArgs) { dwError = ERROR_TDNF_CLI_INVALID_ARGUMENT; BAIL_ON_CLI_ERROR(dwError); } if(pCmdArgs->nCmdCount < 2) { dwError = ERROR_TDNF_CLI_CHECKLOCAL_EXPECT_DIR; BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFCheckLocalPackages(pTdnf, pCmdArgs->ppszCmds[1]); BAIL_ON_CLI_ERROR(dwError); fprintf(stdout, "Check completed without issues\n"); cleanup: return dwError; error: goto cleanup; }
uint32_t TDNFCliParseRepoListArgs( PTDNF_CMD_ARGS pCmdArgs, TDNF_REPOLISTFILTER* pnFilter ) { uint32_t dwError = 0; TDNF_REPOLISTFILTER nFilter = REPOLISTFILTER_ENABLED; if(!pCmdArgs) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_CLI_ERROR(dwError); } //Could have filter argument (tdnf repolist <filter>) //assume REPOLISTFILTER_ENABLED if not specified. if(pCmdArgs->nCmdCount > 1) { dwError = ParseFilter(pCmdArgs->ppszCmds[1], &nFilter); BAIL_ON_CLI_ERROR(dwError); } *pnFilter = nFilter; cleanup: return dwError; error: if(pnFilter) { *pnFilter = REPOLISTFILTER_ENABLED; } goto cleanup; }
uint32_t TDNFCliCheckUpdateCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; PTDNF_PKG_INFO pPkgInfo = NULL; PTDNF_PKG_INFO pPkg = NULL; uint32_t unCount = 0; uint32_t dwIndex = 0; char** ppszPackageArgs = NULL; int nPackageCount = 0; if(!pTdnf || !pCmdArgs) { dwError = ERROR_TDNF_CLI_INVALID_ARGUMENT; BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFCliParsePackageArgs( pCmdArgs, &ppszPackageArgs, &nPackageCount); BAIL_ON_CLI_ERROR(dwError); dwError = TDNFCheckUpdates( pTdnf, ppszPackageArgs, &pPkgInfo, &unCount); BAIL_ON_CLI_ERROR(dwError); for(dwIndex = 0; dwIndex < unCount; ++dwIndex) { pPkg = &pPkgInfo[dwIndex]; printf("%*s\r", 80, pPkg->pszRepoName); printf("%*s-%s\r", 50, pPkg->pszVersion, pPkg->pszRelease); printf("%s.%s", pPkg->pszName, pPkg->pszArch); printf("\n"); } cleanup: TDNF_CLI_SAFE_FREE_STRINGARRAY(ppszPackageArgs); if(pPkgInfo) { TDNFFreePackageInfoArray(pPkgInfo, unCount); } return dwError; error: goto cleanup; }
uint32_t GetOptionAndValue( const char* pszOptArg, PTDNF_CMD_OPT* ppCmdOpt ) { uint32_t dwError = 0; const char* EQUAL_SIGN = "="; const char* pszIndex = NULL; PTDNF_CMD_OPT pCmdOpt = NULL; int nEqualsPos = -1; if(IsNullOrEmptyString(pszOptArg) || !ppCmdOpt) { dwError = ERROR_TDNF_CLI_INVALID_ARGUMENT; BAIL_ON_CLI_ERROR(dwError); } pszIndex = strstr(pszOptArg, EQUAL_SIGN); if(!pszIndex) { dwError = ERROR_TDNF_CLI_SETOPT_NO_EQUALS; BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFAllocateMemory(1, sizeof(TDNF_CMD_OPT), (void**)&pCmdOpt); BAIL_ON_CLI_ERROR(dwError); dwError = TDNFAllocateString(pszOptArg, &pCmdOpt->pszOptName); BAIL_ON_CLI_ERROR(dwError); nEqualsPos = pszIndex - pszOptArg; pCmdOpt->pszOptName[nEqualsPos] = '\0'; dwError = TDNFAllocateString(pszOptArg+nEqualsPos+1, &pCmdOpt->pszOptValue); BAIL_ON_CLI_ERROR(dwError); *ppCmdOpt = pCmdOpt; cleanup: return dwError; error: if(ppCmdOpt) { *ppCmdOpt = NULL; } if(pCmdOpt) { TDNFFreeCmdOpt(pCmdOpt); } goto cleanup; }
uint32_t TDNFCliParsePackageArgs( PTDNF_CMD_ARGS pCmdArgs, char*** pppszPackageArgs, int* pnPackageCount ) { uint32_t dwError = 0; char** ppszPackageArgs = NULL; int nPackageCount = 0; int nIndex = 0; if(!pCmdArgs || !pppszPackageArgs || !pnPackageCount) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_CLI_ERROR(dwError); } nPackageCount = pCmdArgs->nCmdCount - 1; if(nPackageCount < 0) { dwError = ERROR_TDNF_CLI_NOT_ENOUGH_ARGS; BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFAllocateMemory( nPackageCount + 1, sizeof(char*), (void**)&ppszPackageArgs); BAIL_ON_CLI_ERROR(dwError); for(nIndex = 0; nIndex < nPackageCount; ++nIndex) { dwError = TDNFAllocateString( pCmdArgs->ppszCmds[nIndex+1], &ppszPackageArgs[nIndex]); BAIL_ON_CLI_ERROR(dwError); } *pppszPackageArgs = ppszPackageArgs; cleanup: return dwError; error: if(pppszPackageArgs) { *pppszPackageArgs = NULL; } TDNF_CLI_SAFE_FREE_STRINGARRAY(ppszPackageArgs); goto cleanup; }
uint32_t TDNFCliProvidesCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; PTDNF_PKG_INFO pPkgInfo = NULL; PTDNF_PKG_INFO pPkgInfos = NULL; if(!pTdnf || !pCmdArgs) { dwError = ERROR_TDNF_CLI_INVALID_ARGUMENT; BAIL_ON_CLI_ERROR(dwError); } if(pCmdArgs->nCmdCount < 2) { dwError = ERROR_TDNF_CLI_PROVIDES_EXPECT_ARG; BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFProvides(pTdnf, pCmdArgs->ppszCmds[1], &pPkgInfos); BAIL_ON_CLI_ERROR(dwError); pPkgInfo = pPkgInfos; while(pPkgInfo) { fprintf( stdout, "%s-%s-%s.%s : %s\n", pPkgInfo->pszName, pPkgInfo->pszVersion, pPkgInfo->pszRelease, pPkgInfo->pszArch, pPkgInfo->pszSummary); fprintf(stdout, "Repo\t : %s\n", pPkgInfo->pszRepoName); pPkgInfo = pPkgInfo->pNext; } cleanup: if(pPkgInfos) { TDNFFreePackageInfo(pPkgInfos); } return dwError; error: goto cleanup; }
uint32_t TDNFCopyOptions( PTDNF_CMD_ARGS pOptionArgs, PTDNF_CMD_ARGS pArgs ) { uint32_t dwError = 0; if(!pOptionArgs || !pArgs) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_CLI_ERROR(dwError); } pArgs->nAllowErasing = pOptionArgs->nAllowErasing; pArgs->nAssumeNo = pOptionArgs->nAssumeNo; pArgs->nAssumeYes = pOptionArgs->nAssumeYes; pArgs->nBest = pOptionArgs->nBest; pArgs->nCacheOnly = pOptionArgs->nCacheOnly; pArgs->nDebugSolver = pOptionArgs->nDebugSolver; pArgs->nNoGPGCheck = pOptionArgs->nNoGPGCheck; pArgs->nRefresh = pOptionArgs->nRefresh; pArgs->nShowDuplicates= pOptionArgs->nShowDuplicates; pArgs->nShowHelp = pOptionArgs->nShowHelp; pArgs->nShowVersion = pOptionArgs->nShowVersion; pArgs->nVerbose = pOptionArgs->nVerbose; pArgs->nIPv4 = pOptionArgs->nIPv4; pArgs->nIPv6 = pOptionArgs->nIPv6; cleanup: return dwError; error: goto cleanup; }
uint32_t TDNFCliGetErrorString( uint32_t dwErrorCode, char** ppszError ) { uint32_t dwError = 0; char* pszError = NULL; int i = 0; int nCount = 0; TDNF_ERROR_DESC arErrorDesc[] = TDNF_CLI_ERROR_TABLE; nCount = sizeof(arErrorDesc)/sizeof(arErrorDesc[0]); for(i = 0; i < nCount; i++) { if (dwErrorCode == arErrorDesc[i].nCode) { dwError = TDNFAllocateString(arErrorDesc[i].pszDesc, &pszError); BAIL_ON_CLI_ERROR(dwError); break; } } *ppszError = pszError; cleanup: return dwError; error: TDNF_CLI_SAFE_FREE_MEMORY(pszError); goto cleanup; }
uint32_t TDNFCliSearchCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t unError = 0; PTDNF_PKG_INFO pPkgInfo = NULL; PTDNF_PKG_INFO pPkg = NULL; uint32_t unCount = 0; uint32_t unIndex = 0; unError = TDNFSearchCommand(pTdnf, pCmdArgs, &pPkgInfo, &unCount); BAIL_ON_CLI_ERROR(unError); for(unIndex = 0; unIndex < unCount; ++unIndex) { pPkg = &pPkgInfo[unIndex]; printf("%s : %s\n", pPkg->pszName, pPkg->pszSummary); } cleanup: TDNFFreePackageInfoArray(pPkgInfo, unCount); return unError; error: goto cleanup; }
uint32_t TDNFCliCleanCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; TDNF_CLEANTYPE nCleanType = CLEANTYPE_NONE; PTDNF_CLEAN_INFO pTDNFCleanInfo = NULL; char** ppszReposUsed = NULL; dwError = TDNFCliParseCleanArgs(pCmdArgs, &nCleanType); BAIL_ON_CLI_ERROR(dwError); dwError = TDNFClean(pTdnf, nCleanType, &pTDNFCleanInfo); BAIL_ON_CLI_ERROR(dwError); //Print clean info printf("Cleaning repos:"); ppszReposUsed = pTDNFCleanInfo->ppszReposUsed; while(*ppszReposUsed) { printf(" %s", *ppszReposUsed); ++ppszReposUsed; } printf("\n"); if(pTDNFCleanInfo->nCleanAll) { printf("Cleaning up everything\n"); } cleanup: if(pTDNFCleanInfo) { TDNFFreeCleanInfo(pTDNFCleanInfo); } return dwError; error: goto cleanup; }
uint32_t PrintError( uint32_t dwErrorCode ) { uint32_t dwError = 0; char* pszError = NULL; if(dwErrorCode < ERROR_TDNF_BASE) { dwError = TDNFCliGetErrorString(dwErrorCode, &pszError); BAIL_ON_CLI_ERROR(dwError); } else { dwError = TDNFGetErrorString(dwErrorCode, &pszError); BAIL_ON_CLI_ERROR(dwError); } if(dwErrorCode == ERROR_TDNF_CLI_NOTHING_TO_DO) { dwErrorCode = 0; } if(dwErrorCode) { printf("Error(%d) : %s\n", dwErrorCode, pszError); } else { printf("%s\n", pszError); } cleanup: TDNF_CLI_SAFE_FREE_MEMORY(pszError); return dwError; error: printf( "Retrieving error string for %d failed with %d\n", dwErrorCode, dwError); goto cleanup; }
uint32_t TDNFCliRepoListCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; PTDNF_REPO_DATA pRepos = NULL; PTDNF_REPO_DATA pReposTemp = NULL; TDNF_REPOLISTFILTER nFilter = REPOLISTFILTER_ENABLED; dwError = TDNFCliParseRepoListArgs(pCmdArgs, &nFilter); BAIL_ON_CLI_ERROR(dwError); dwError = TDNFRepoList(pTdnf, nFilter, &pRepos); BAIL_ON_CLI_ERROR(dwError); pReposTemp = pRepos; if(pReposTemp) { printf("%-20s%-40s%-10s\n", "repo id", "repo name", "status"); } while(pReposTemp) { printf( "%-20s%-40s%-10s\n", pReposTemp->pszId, pReposTemp->pszName, pReposTemp->nEnabled ? "enabled" : "disabled"); pReposTemp = pReposTemp->pNext; } cleanup: TDNFFreeRepos(pRepos); return dwError; error: goto cleanup; }
uint32_t AddSetOpt( PTDNF_CMD_ARGS pCmdArgs, const char* pszOptArg ) { uint32_t dwError = 0; PTDNF_CMD_OPT pCmdOpt = NULL; if(!pCmdArgs || IsNullOrEmptyString(pszOptArg)) { dwError = ERROR_TDNF_CLI_INVALID_ARGUMENT; BAIL_ON_CLI_ERROR(dwError); } dwError = GetOptionAndValue(pszOptArg, &pCmdOpt); BAIL_ON_CLI_ERROR(dwError); if(!strcmp(pCmdOpt->pszOptName, "tdnf.conf")) { TDNF_CLI_SAFE_FREE_MEMORY(pCmdArgs->pszConfFile); dwError = TDNFAllocateString( pCmdOpt->pszOptValue, &pCmdArgs->pszConfFile); BAIL_ON_CLI_ERROR(dwError); } cleanup: if(pCmdOpt) { TDNFFreeCmdOpt(pCmdOpt); } return dwError; error: TDNF_CLI_SAFE_FREE_MEMORY(pCmdArgs->pszConfFile); goto cleanup; }
uint32_t ParseFilter( const char* pszFilter, TDNF_REPOLISTFILTER* pnFilter ) { uint32_t dwError = 0; int nIndex = 0; TDNF_REPOLISTFILTER nFilter = REPOLISTFILTER_ENABLED; struct stTemp { char* pszTypeName; int nType; }; struct stTemp stFilterTypes[] = { {"all", REPOLISTFILTER_ALL}, {"enabled", REPOLISTFILTER_ENABLED}, {"disabled", REPOLISTFILTER_DISABLED} }; int nCount = sizeof(stFilterTypes)/sizeof(stFilterTypes[0]); for(nIndex = 0; nIndex < nCount; ++nIndex) { if(!strcasecmp(stFilterTypes[nIndex].pszTypeName, pszFilter)) { nFilter = stFilterTypes[nIndex].nType; break; } } if(nIndex >= nCount) { dwError = ERROR_TDNF_CLI_NO_MATCH; } BAIL_ON_CLI_ERROR(dwError); *pnFilter = nFilter; cleanup: return dwError; error: if(pnFilter) { *pnFilter = REPOLISTFILTER_ENABLED; } goto cleanup; }
uint32_t TDNFCliCountCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; uint32_t unCount = 0; dwError = TDNFCountCommand(pTdnf, &unCount); BAIL_ON_CLI_ERROR(dwError); printf("Package count = %d\n", unCount); cleanup: return dwError; error: goto cleanup; }
uint32_t GetColumnWidths( int nCount, int* pnColPercents, int* pnColWidths ) { uint32_t dwError = 0; struct winsize stWinSize = {0}; int nConsoleWidth = 0; int nIndex = 0; if(!pnColPercents || !pnColWidths) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_CLI_ERROR(dwError); } dwError = ioctl(STDOUT_FILENO, TIOCGWINSZ, &stWinSize); if(dwError > 0) { nConsoleWidth = 80; dwError = 0; } else { nConsoleWidth = stWinSize.ws_col; } for(nIndex = 0; nIndex < nCount; nIndex++) { pnColWidths[nIndex] = (nConsoleWidth * pnColPercents[nIndex]) / 100; } cleanup: return dwError; error: goto cleanup; }
uint32_t TDNFCliMakeCacheCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; if(!pTdnf || !pCmdArgs) { dwError = ERROR_TDNF_CLI_INVALID_ARGUMENT; BAIL_ON_CLI_ERROR(dwError); } //Empty as refresh flag is set for makecache command //and will execute refresh on all enabled repos fprintf(stdout, "Metadata cache created.\n"); cleanup: return dwError; error: goto cleanup; }
uint32_t ParseOption( const char* pszName, const char* pszArg, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; if(!pszName || !pCmdArgs) { dwError = ERROR_TDNF_CLI_INVALID_ARGUMENT; BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFCliValidateOptions(pszName, pszArg, pstOptions); BAIL_ON_CLI_ERROR(dwError); if(!strcasecmp(pszName, "rpmverbosity")) { if(!optarg) { dwError = ERROR_TDNF_CLI_OPTION_ARG_REQUIRED; BAIL_ON_CLI_ERROR(dwError); } dwError = ParseRpmVerbosity( optarg, &pCmdArgs->nRpmVerbosity); BAIL_ON_CLI_ERROR(dwError); } else if(!strcasecmp(pszName, "enablerepo")) { if(!optarg) { dwError = ERROR_TDNF_CLI_OPTION_ARG_REQUIRED; BAIL_ON_CLI_ERROR(dwError); } fprintf(stdout, "EnableRepo: %s\n", optarg); } else if(!strcasecmp(pszName, "disablerepo")) { if(!optarg) { dwError = ERROR_TDNF_CLI_OPTION_ARG_REQUIRED; BAIL_ON_CLI_ERROR(dwError); } fprintf(stdout, "DisableRepo: %s\n", optarg); } else if(!strcasecmp(pszName, "installroot")) { if(!optarg) { dwError = ERROR_TDNF_CLI_OPTION_ARG_REQUIRED; BAIL_ON_CLI_ERROR(dwError); } fprintf(stdout, "InstallRoot: %s\n", optarg); } else if(!strcasecmp(pszName, "setopt")) { if(!optarg) { dwError = ERROR_TDNF_CLI_OPTION_ARG_REQUIRED; BAIL_ON_CLI_ERROR(dwError); } dwError = AddSetOpt(pCmdArgs, optarg); BAIL_ON_CLI_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
uint32_t TDNFCliListCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; PTDNF_PKG_INFO pPkgInfo = NULL; PTDNF_PKG_INFO pPkg = NULL; uint32_t unCount = 0; uint32_t dwIndex = 0; PTDNF_LIST_ARGS pListArgs = NULL; #define MAX_COL_LEN 256 char szNameAndArch[MAX_COL_LEN] = {0}; char szVersionAndRelease[MAX_COL_LEN] = {0}; #define COL_COUNT 3 //Name.Arch | Version-Release | Repo int nColPercents[COL_COUNT] = {55, 25, 15}; int nColWidths[COL_COUNT] = {0}; dwError = TDNFCliParseListArgs(pCmdArgs, &pListArgs); BAIL_ON_CLI_ERROR(dwError); dwError = TDNFList( pTdnf, pListArgs->nScope, pListArgs->ppszPackageNameSpecs, &pPkgInfo, &unCount); BAIL_ON_CLI_ERROR(dwError); dwError = GetColumnWidths(COL_COUNT, nColPercents, nColWidths); BAIL_ON_CLI_ERROR(dwError); for(dwIndex = 0; dwIndex < unCount; ++dwIndex) { pPkg = &pPkgInfo[dwIndex]; memset(szNameAndArch, 0, MAX_COL_LEN); if(snprintf( szNameAndArch, MAX_COL_LEN, "%s.%s", pPkg->pszName, pPkg->pszArch) < 0) { dwError = errno; BAIL_ON_CLI_ERROR(dwError); } memset(szVersionAndRelease, 0, MAX_COL_LEN); if(snprintf( szVersionAndRelease, MAX_COL_LEN, "%s-%s", pPkg->pszVersion, pPkg->pszRelease) < 0) { dwError = errno; BAIL_ON_CLI_ERROR(dwError); } printf( "%-*s%-*s%*s\n", nColWidths[0], szNameAndArch, nColWidths[1], szVersionAndRelease, nColWidths[2], pPkg->pszRepoName); } cleanup: if(pListArgs) { TDNFFreeListArgs(pListArgs); } if(pPkgInfo) { TDNFFreePackageInfoArray(pPkgInfo, unCount); } return dwError; error: goto cleanup; }
int main(int argc, char* argv[]) { uint32_t dwError = 0; PTDNF_CMD_ARGS pCmdArgs = NULL; TDNF_CLI_CMD_MAP arCmdMap[] = { {"autoerase", TDNFCliAutoEraseCommand}, {"autoremove", TDNFCliAutoEraseCommand}, {"check-local", TDNFCliCheckLocalCommand}, {"check-update", TDNFCliCheckUpdateCommand}, {"clean", TDNFCliCleanCommand}, {"count", TDNFCliCountCommand}, {"distro-sync", TDNFCliDistroSyncCommand}, {"downgrade", TDNFCliDowngradeCommand}, {"erase", TDNFCliEraseCommand}, {"help", TDNFCliHelpCommand}, {"info", TDNFCliInfoCommand}, {"install", TDNFCliInstallCommand}, {"list", TDNFCliListCommand}, {"makecache", TDNFCliMakeCacheCommand}, {"provides", TDNFCliProvidesCommand}, {"whatprovides", TDNFCliProvidesCommand}, {"reinstall", TDNFCliReinstallCommand}, {"remove", TDNFCliEraseCommand}, {"repolist", TDNFCliRepoListCommand}, {"search", TDNFCliSearchCommand}, {"update", TDNFCliUpgradeCommand}, {"update-to", TDNFCliUpgradeCommand}, {"upgrade", TDNFCliUpgradeCommand}, {"upgrade-to", TDNFCliUpgradeCommand}, {"updateinfo", TDNFCliUpdateInfoCommand}, }; int nCommandCount = sizeof(arCmdMap)/sizeof(TDNF_CLI_CMD_MAP); const char* pszCmd = NULL; PTDNF pTdnf = NULL; int nFound = 0; dwError = TDNFCliParseArgs(argc, argv, &pCmdArgs); BAIL_ON_CLI_ERROR(dwError); //If --version, show version and exit if(pCmdArgs->nShowVersion) { TDNFCliShowVersion(); } else if(pCmdArgs->nShowHelp) { TDNFCliShowHelp(); } else if(pCmdArgs->nCmdCount > 0) { pszCmd = pCmdArgs->ppszCmds[0]; while(nCommandCount > 0) { --nCommandCount; if(!strcmp(pszCmd, arCmdMap[nCommandCount].pszCmdName)) { nFound = 1; if(!strcmp(pszCmd, "makecache")) { pCmdArgs->nRefresh = 1; } dwError = TDNFOpenHandle(pCmdArgs, &pTdnf); BAIL_ON_CLI_ERROR(dwError); dwError = arCmdMap[nCommandCount].pFnCmd(pTdnf, pCmdArgs); BAIL_ON_CLI_ERROR(dwError); break; } }; if(!nFound) { TDNFCliShowNoSuchCommand(pszCmd); } } else { TDNFCliShowUsage(); } cleanup: if(pTdnf) { TDNFCloseHandle(pTdnf); } if(pCmdArgs) { TDNFFreeCmdArgs(pCmdArgs); } return dwError; error: PrintError(dwError); goto cleanup; }
uint32_t TDNFCliInfoCommand( PTDNF pTdnf, PTDNF_CMD_ARGS pCmdArgs ) { uint32_t dwError = 0; char* pszFormattedSize = NULL; PTDNF_PKG_INFO pPkgInfo = NULL; PTDNF_PKG_INFO pPkg = NULL; PTDNF_LIST_ARGS pInfoArgs = NULL; uint32_t unCount = 0; uint32_t dwIndex = 0; uint32_t unTotalSize = 0; dwError = TDNFCliParseInfoArgs(pCmdArgs, &pInfoArgs); BAIL_ON_CLI_ERROR(dwError); dwError = TDNFInfo( pTdnf, pInfoArgs->nScope, pInfoArgs->ppszPackageNameSpecs, &pPkgInfo, &unCount); BAIL_ON_CLI_ERROR(dwError); for(dwIndex = 0; dwIndex < unCount; ++dwIndex) { pPkg = &pPkgInfo[dwIndex]; printf("Name : %s\n", pPkg->pszName); printf("Arch : %s\n", pPkg->pszArch); printf("Epoch : %d\n", pPkg->dwEpoch); printf("Version : %s\n", pPkg->pszVersion); printf("Release : %s\n", pPkg->pszRelease); printf("Install Size : %s (%u)\n", pPkg->pszFormattedSize, pPkg->dwInstallSizeBytes); printf("Repo : %s\n", pPkg->pszRepoName); printf("Summary : %s\n", pPkg->pszSummary); printf("URL : %s\n", pPkg->pszURL); printf("License : %s\n", pPkg->pszLicense); printf("Description : %s\n", pPkg->pszDescription); printf("\n"); unTotalSize += pPkg->dwInstallSizeBytes; } dwError = TDNFUtilsFormatSize(unTotalSize, &pszFormattedSize); BAIL_ON_CLI_ERROR(dwError); printf("\nTotal Size: %s (%u)\n", pszFormattedSize, unTotalSize); cleanup: if(pInfoArgs) { TDNFFreeListArgs(pInfoArgs); } if(pPkgInfo) { TDNFFreePackageInfoArray(pPkgInfo, unCount); } TDNF_CLI_SAFE_FREE_MEMORY(pszFormattedSize); return dwError; error: goto cleanup; }
uint32_t TDNFCliParseArgs( int argc, char* const* argv, PTDNF_CMD_ARGS* ppCmdArgs ) { uint32_t dwError = 0; PTDNF_CMD_ARGS pCmdArgs = NULL; int nOptionIndex = 0; int nOption = 0; int nIndex = 0; char* pszDefaultInstallRoot = "/"; if(!ppCmdArgs) { dwError = ERROR_TDNF_INVALID_PARAMETER; BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFAllocateMemory( 1, sizeof(TDNF_CMD_ARGS), (void**)&pCmdArgs); BAIL_ON_CLI_ERROR(dwError); opterr = 0;//tell getopt to not print errors while (1) { nOption = getopt_long ( argc, argv, "46bCc:d:e:hiqvxy", pstOptions, &nOptionIndex); if (nOption == -1) break; switch (nOption) { case 0: dwError = ParseOption( pstOptions[nOptionIndex].name, optarg, pCmdArgs); BAIL_ON_CLI_ERROR(dwError); break; case 'b': _opt.nBest = 1; break; case 'e': break; case 'C': _opt.nCacheOnly = 1; break; case 'h': _opt.nShowHelp = 1; break; case 'i': dwError = TDNFAllocateString( optarg, &pCmdArgs->pszInstallRoot); BAIL_ON_CLI_ERROR(dwError); break; case 'r': break; case 'y': _opt.nAssumeYes = 1; break; case '4': _opt.nIPv4 = 1; break; case '6': _opt.nIPv6 = 1; break; case 'v': _opt.nVerbose = 1; break; case '?': dwError = HandleOptionsError(argv[optind-1], optarg, pstOptions); BAIL_ON_CLI_ERROR(dwError); //TODO: Handle unknown option, incomplete options break; } } if(pCmdArgs->pszInstallRoot == NULL) { dwError = TDNFAllocateString( pszDefaultInstallRoot, &pCmdArgs->pszInstallRoot); BAIL_ON_CLI_ERROR(dwError); } dwError = TDNFCopyOptions(&_opt, pCmdArgs); BAIL_ON_CLI_ERROR(dwError); //Collect extra args if (optind < argc) { pCmdArgs->nCmdCount = argc-optind; dwError = TDNFAllocateMemory( pCmdArgs->nCmdCount, sizeof(char*), (void**)&pCmdArgs->ppszCmds); BAIL_ON_CLI_ERROR(dwError); while (optind < argc) { dwError = TDNFAllocateString( argv[optind++], &pCmdArgs->ppszCmds[nIndex++]); BAIL_ON_CLI_ERROR(dwError); } } *ppCmdArgs = pCmdArgs; cleanup: return dwError; error: if(ppCmdArgs) { *ppCmdArgs = NULL; } if(pCmdArgs) { TDNFFreeCmdArgs(pCmdArgs); } goto cleanup; }