From 4e74ec9594f5a5b10627b6ef1d85e5b6f5c00ed1 Mon Sep 17 00:00:00 2001 From: Oliver Kurth Date: Thu, 11 Jan 2024 11:29:56 -0800 Subject: [PATCH] implement setopt=.foo=bar now to override repo settings --- client/repolist.c | 236 +++++++++++++++++++++----------------- common/utils.c | 1 + include/tdnftypes.h | 1 + tools/cli/lib/parseargs.c | 29 ++++- 4 files changed, 157 insertions(+), 110 deletions(-) diff --git a/client/repolist.c b/client/repolist.c index bbf9d7d0..fcc5f453 100644 --- a/client/repolist.c +++ b/client/repolist.c @@ -48,6 +48,121 @@ TDNFCreateRepo( ); +TDNFRepoConfigFromCnfTree(PTDNF_REPO_DATA pRepo, struct cnfnode *cn_top) +{ + uint32_t dwError = 0; + struct cnfnode *cn; + + for(cn = cn_top->first_child; cn; cn = cn->next) + { + if ((cn->name[0] == '.') || (cn->value == NULL)) + continue; + + if (strcmp(cn->name, TDNF_REPO_KEY_ENABLED) == 0) + { + pRepo->nEnabled = isTrue(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_NAME) == 0) + { + SET_STRING(pRepo->pszName, cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_BASEURL) == 0) + { + dwError = TDNFAddStringArray(&pRepo->ppszBaseUrls, cn->value); + BAIL_ON_TDNF_ERROR(dwError); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_METALINK) == 0) + { + SET_STRING(pRepo->pszMetaLink, cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_MIRRORLIST) == 0) + { + pRepo->pszMirrorList = strdup(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_SKIP) == 0) + { + pRepo->nSkipIfUnavailable = isTrue(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_GPGCHECK) == 0) + { + pRepo->nGPGCheck = isTrue(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_GPGKEY) == 0) + { + dwError = TDNFAddStringArray(&pRepo->ppszUrlGPGKeys, cn->value); + BAIL_ON_TDNF_ERROR(dwError); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_USERNAME) == 0) + { + SET_STRING(pRepo->pszUser, cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_PASSWORD) == 0) + { + SET_STRING(pRepo->pszPass, cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_PRIORITY) == 0) + { + pRepo->nPriority = strtoi(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_TIMEOUT) == 0) + { + pRepo->nTimeout = strtoi(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_RETRIES) == 0) + { + pRepo->nRetries = strtoi(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_MINRATE) == 0) + { + pRepo->nMinrate = strtoi(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_THROTTLE) == 0) + { + pRepo->nThrottle = strtoi(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_SSL_VERIFY) == 0) + { + pRepo->nSSLVerify = isTrue(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_SSL_CA_CERT) == 0) + { + SET_STRING(pRepo->pszSSLCaCert, cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_SSL_CLI_CERT) == 0) + { + SET_STRING(pRepo->pszSSLClientCert, cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_SSL_CLI_KEY) == 0) + { + SET_STRING(pRepo->pszSSLClientKey, cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_METADATA_EXPIRE) == 0) + { + dwError = TDNFParseMetadataExpire( + cn->value, + &pRepo->lMetadataExpire); + BAIL_ON_TDNF_ERROR(dwError); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_SKIP_MD_FILELISTS) == 0) + { + pRepo->nSkipMDFileLists = isTrue(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_SKIP_MD_UPDATEINFO) == 0) + { + pRepo->nSkipMDUpdateInfo = isTrue(cn->value); + } + else if (strcmp(cn->name, TDNF_REPO_KEY_SKIP_MD_OTHER) == 0) + { + pRepo->nSkipMDOther = isTrue(cn->value); + } + } + + +cleanup: + return dwError; +error: + goto cleanup; +} uint32_t TDNFLoadRepoData( @@ -66,6 +181,8 @@ TDNFLoadRepoData( char **ppszUrlIdTuple = NULL; PTDNF_REPO_DATA pRepoParsePre = NULL; PTDNF_REPO_DATA pRepoParseNext = NULL; + PTDNF_REPO_DATA pRepo = NULL; + struct cnfnode *cn_repo; if(!pTdnf || !pTdnf->pConf || !pTdnf->pArgs || !ppReposAll) { @@ -159,7 +276,6 @@ TDNFLoadRepoData( } for (pRepoParsePre = pReposAll; pRepoParsePre; pRepoParsePre = pRepoParsePre->pNext) { - for (pRepoParseNext = pRepoParsePre->pNext; pRepoParseNext; pRepoParseNext = pRepoParseNext->pNext) { if (!strcmp(pRepoParsePre->pszId, pRepoParseNext->pszId)) { pr_err("ERROR: duplicate repo id: %s\n", pRepoParsePre->pszId); @@ -169,6 +285,16 @@ TDNFLoadRepoData( } } + /* look for setopt settings */ + if (pTdnf->pArgs->cn_repoopts != NULL) { + for (pRepo = pReposAll; pRepo; pRepo = pRepo->pNext) { + if ((cn_repo = find_child(pTdnf->pArgs->cn_repoopts, pRepo->pszId)) != NULL) { + dwError = TDNFRepoConfigFromCnfTree(pRepo, cn_repo); + BAIL_ON_TDNF_ERROR(dwError); + } + } + } + *ppReposAll = pReposAll; cleanup: if(pDir) @@ -490,7 +616,7 @@ TDNFLoadReposFromFile( PTDNF_REPO_DATA pRepos = NULL; PTDNF_REPO_DATA pRepo = NULL; - struct cnfnode *cn_conf = NULL, *cn_section, *cn; + struct cnfnode *cn_conf = NULL, *cn_section; struct cnfmodule *mod_ini; mod_ini = find_cnfmodule("ini"); @@ -528,111 +654,9 @@ TDNFLoadReposFromFile( dwError = TDNFEventRepoReadConfigStart(pTdnf, cn_section); BAIL_ON_TDNF_ERROR(dwError); - for(cn = cn_section->first_child; cn; cn = cn->next) - { - if ((cn->name[0] == '.') || (cn->value == NULL)) - continue; + dwError = TDNFRepoConfigFromCnfTree(pRepo, cn_section); + BAIL_ON_TDNF_ERROR(dwError); - if (strcmp(cn->name, TDNF_REPO_KEY_ENABLED) == 0) - { - pRepo->nEnabled = isTrue(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_NAME) == 0) - { - SET_STRING(pRepo->pszName, cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_BASEURL) == 0) - { - dwError = TDNFSplitStringToArray(cn->value, - " ", &pRepo->ppszBaseUrls); - BAIL_ON_TDNF_ERROR(dwError); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_METALINK) == 0) - { - SET_STRING(pRepo->pszMetaLink, cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_MIRRORLIST) == 0) - { - pRepo->pszMirrorList = strdup(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_SKIP) == 0) - { - pRepo->nSkipIfUnavailable = isTrue(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_GPGCHECK) == 0) - { - pRepo->nGPGCheck = isTrue(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_GPGKEY) == 0) - { - dwError = TDNFSplitStringToArray(cn->value, - " ", &pRepo->ppszUrlGPGKeys); - BAIL_ON_TDNF_ERROR(dwError); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_USERNAME) == 0) - { - SET_STRING(pRepo->pszUser, cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_PASSWORD) == 0) - { - SET_STRING(pRepo->pszPass, cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_PRIORITY) == 0) - { - pRepo->nPriority = strtoi(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_TIMEOUT) == 0) - { - pRepo->nTimeout = strtoi(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_RETRIES) == 0) - { - pRepo->nRetries = strtoi(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_MINRATE) == 0) - { - pRepo->nMinrate = strtoi(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_THROTTLE) == 0) - { - pRepo->nThrottle = strtoi(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_SSL_VERIFY) == 0) - { - pRepo->nSSLVerify = isTrue(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_SSL_CA_CERT) == 0) - { - SET_STRING(pRepo->pszSSLCaCert, cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_SSL_CLI_CERT) == 0) - { - SET_STRING(pRepo->pszSSLClientCert, cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_SSL_CLI_KEY) == 0) - { - SET_STRING(pRepo->pszSSLClientKey, cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_METADATA_EXPIRE) == 0) - { - dwError = TDNFParseMetadataExpire( - cn->value, - &pRepo->lMetadataExpire); - BAIL_ON_TDNF_ERROR(dwError); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_SKIP_MD_FILELISTS) == 0) - { - pRepo->nSkipMDFileLists = isTrue(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_SKIP_MD_UPDATEINFO) == 0) - { - pRepo->nSkipMDUpdateInfo = isTrue(cn->value); - } - else if (strcmp(cn->name, TDNF_REPO_KEY_SKIP_MD_OTHER) == 0) - { - pRepo->nSkipMDOther = isTrue(cn->value); - } - } /* plugin event repo readconfig end */ dwError = TDNFEventRepoReadConfigEnd(pTdnf, cn_section); BAIL_ON_TDNF_ERROR(dwError); diff --git a/common/utils.c b/common/utils.c index 7852fc9d..542fec41 100644 --- a/common/utils.c +++ b/common/utils.c @@ -422,6 +422,7 @@ TDNFFreeCmdArgs( TDNFFreeCmdOpt(pCmdArgs->pSetOpt); } destroy_cnftree(pCmdArgs->cn_setopts); + destroy_cnftree(pCmdArgs->cn_repoopts); TDNF_SAFE_FREE_MEMORY(pCmdArgs); } diff --git a/include/tdnftypes.h b/include/tdnftypes.h index 8a0f811a..0028ffea 100644 --- a/include/tdnftypes.h +++ b/include/tdnftypes.h @@ -244,6 +244,7 @@ typedef struct _TDNF_CMD_ARGS int nCmdCount; PTDNF_CMD_OPT pSetOpt; struct cnfnode *cn_setopts; + struct cnfnode *cn_repoopts; int nArgc; char **ppszArgv; diff --git a/tools/cli/lib/parseargs.c b/tools/cli/lib/parseargs.c index 27a0fa7e..578e4c28 100644 --- a/tools/cli/lib/parseargs.c +++ b/tools/cli/lib/parseargs.c @@ -146,6 +146,7 @@ TDNFCliParseArgs( BAIL_ON_CLI_ERROR(dwError); pCmdArgs->cn_setopts = create_cnfnode("(setopts)"); + pCmdArgs->cn_repoopts = create_cnfnode("(repoopts)"); /* * when invoked as 'tdnfj', act as if invoked with with '-j' and '-y' @@ -402,6 +403,7 @@ ParseOption( else if (!strcasecmp(pszName, "setopt")) { struct cnfnode *cn; + char *psep_eq, *pseq_dot; if (!optarg) { @@ -409,11 +411,30 @@ ParseOption( BAIL_ON_CLI_ERROR(dwError); } - cn = create_cnfnode_keyval(optarg); - if (!cn) { - dwError = ERROR_TDNF_CLI_SETOPT_NO_EQUALS; + psep_eq = strstr(optarg, "="); + if (psep_eq) { + *psep_eq = 0; + + pseq_dot = strstr(optarg, "."); + if (pseq_dot == NULL) { + cn = create_cnfnode(optarg); + cnfnode_setval(cn, psep_eq + 1); + append_node(pCmdArgs->cn_setopts, cn); + } else { + struct cnfnode *cn_repo; + *pseq_dot = 0; + cn_repo = find_child(pCmdArgs->cn_repoopts, optarg); + if (!cn_repo) { + cn_repo = create_cnfnode(optarg); + append_node(pCmdArgs->cn_repoopts, cn_repo); + } + cn = create_cnfnode(pseq_dot+1); + cnfnode_setval(cn, psep_eq + 1); + append_node(cn_repo, cn); + } } else { - append_node(pCmdArgs->cn_setopts, cn); + dwError = ERROR_TDNF_CLI_SETOPT_NO_EQUALS; + BAIL_ON_CLI_ERROR(dwError); } } else if (!strcasecmp(pszName, "exclude"))