5f77bc5cc3
Also, migrate to autosetup
314 lines
12 KiB
Diff
314 lines
12 KiB
Diff
From b9ce9b7ecd1db5afbfc1a51def601ec03e657f32 Mon Sep 17 00:00:00 2001
|
|
From: Alexander Scheel <ascheel@redhat.com>
|
|
Date: Wed, 12 Jul 2017 15:14:52 -0400
|
|
Subject: [PATCH] INI: Extend INI_MS_DETECT to be non-exclusive
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
This updates the INI_MS_DETECT flag such that it can be
|
|
used in combination with INI_MS_MERGE, INI_MS_OVERWRITE,
|
|
and INI_MS_PRESERVE. With the previous behavior, to detect
|
|
that duplicate sections exist in a config directory, two
|
|
separate calls to ini_augment would need to be made:
|
|
one with a copy baes_obj and INI_MS_DETECT, and one with
|
|
INI_MS_PRESERVE.
|
|
|
|
Resolves:
|
|
https://pagure.io/SSSD/ding-libs/issue/3167
|
|
|
|
Signed-off-by: Alexander Scheel <ascheel@redhat.com>
|
|
Reviewed-by: Michal Židek <mzidek@redhat.com>
|
|
|
|
Merges: https://pagure.io/SSSD/ding-libs/issue/3167
|
|
(cherry picked from commit 3163a969bbcd10c4d9e48e191f978c6991ac01cd)
|
|
---
|
|
ini/ini_augment.c | 4 +--
|
|
ini/ini_configobj.c | 71 ++++++++++++++++++++++++++++++++---------------------
|
|
ini/ini_configobj.h | 3 ++-
|
|
ini/ini_defines.h | 5 ++++
|
|
ini/ini_parse.c | 32 +++++++++++-------------
|
|
5 files changed, 67 insertions(+), 48 deletions(-)
|
|
|
|
diff --git a/ini/ini_augment.c b/ini/ini_augment.c
|
|
index 0855381..e4ac94b 100644
|
|
--- a/ini/ini_augment.c
|
|
+++ b/ini/ini_augment.c
|
|
@@ -808,9 +808,9 @@ static int ini_aug_apply(struct ini_cfgobj *cfg,
|
|
}
|
|
else if
|
|
((error == EEXIST) &&
|
|
- ((((merge_flags & INI_MS_MASK) == INI_MS_DETECT) &&
|
|
+ ((ini_flags_have(INI_MS_DETECT, merge_flags) &&
|
|
((merge_flags & INI_MV2S_MASK) != INI_MV2S_ERROR)) ||
|
|
- (((merge_flags & INI_MS_MASK) != INI_MS_ERROR) &&
|
|
+ ((!ini_flags_have(INI_MS_ERROR, merge_flags)) &&
|
|
((merge_flags & INI_MV2S_MASK) == INI_MV2S_DETECT)))) {
|
|
TRACE_ERROR_NUMBER("Got error in detect mode", error);
|
|
/* Fall through! */
|
|
diff --git a/ini/ini_configobj.c b/ini/ini_configobj.c
|
|
index 04e81ba..09bedc4 100644
|
|
--- a/ini/ini_configobj.c
|
|
+++ b/ini/ini_configobj.c
|
|
@@ -270,6 +270,23 @@ static int ini_copy_cb(struct collection_item *item,
|
|
return error;
|
|
}
|
|
|
|
+/* Check flags for flag */
|
|
+int ini_flags_have(uint32_t flag, uint32_t flags)
|
|
+{
|
|
+ switch (flag) {
|
|
+ case INI_MS_MERGE:
|
|
+ case INI_MS_ERROR:
|
|
+ case INI_MS_OVERWRITE:
|
|
+ case INI_MS_PRESERVE:
|
|
+ return flag == (flags & INI_MS_MODE_MASK);
|
|
+ case INI_MS_DETECT:
|
|
+ return flag == (flags & INI_MS_DETECT);
|
|
+ default:
|
|
+ TRACE_ERROR_NUMBER("Unsupported flag", flag);
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
/* Copy configuration */
|
|
int ini_config_copy(struct ini_cfgobj *ini_config,
|
|
struct ini_cfgobj **ini_new)
|
|
@@ -547,7 +564,12 @@ static int acceptor_handler(const char *property,
|
|
donor = passed_data->ci;
|
|
acceptor = *((struct collection_item **)(data));
|
|
|
|
- mergemode = passed_data->flags & INI_MS_MASK;
|
|
+ mergemode = passed_data->flags & INI_MS_MODE_MASK;
|
|
+
|
|
+ if (passed_data->flags & INI_MS_DETECT) {
|
|
+ TRACE_INFO_STRING("Detect mode", "");
|
|
+ passed_data->error = EEXIST;
|
|
+ }
|
|
|
|
switch (mergemode) {
|
|
case INI_MS_ERROR: /* Report error and return */
|
|
@@ -582,21 +604,6 @@ static int acceptor_handler(const char *property,
|
|
}
|
|
break;
|
|
|
|
- case INI_MS_DETECT: /* Detect mode */
|
|
- TRACE_INFO_STRING("Detect mode", "");
|
|
- passed_data->error = EEXIST;
|
|
- error = merge_two_sections(donor,
|
|
- acceptor,
|
|
- passed_data->flags);
|
|
- if (error) {
|
|
- if (error != EEXIST) {
|
|
- TRACE_ERROR_NUMBER("Failed to merge "
|
|
- "sections", error);
|
|
- return error;
|
|
- }
|
|
- }
|
|
- break;
|
|
-
|
|
case INI_MS_MERGE: /* Merge */
|
|
default: TRACE_INFO_STRING("Merge mode", "");
|
|
error = merge_two_sections(donor,
|
|
@@ -608,14 +615,22 @@ static int acceptor_handler(const char *property,
|
|
"sections", error);
|
|
return error;
|
|
}
|
|
- passed_data->error = error;
|
|
+
|
|
+ if (!(passed_data->flags & INI_MS_DETECT)) {
|
|
+ passed_data->error = error;
|
|
+ }
|
|
+
|
|
+ error = EOK;
|
|
}
|
|
break;
|
|
}
|
|
|
|
- *dummy = 1;
|
|
+ if (error == EOK) {
|
|
+ *dummy = 1;
|
|
+ }
|
|
+
|
|
TRACE_FLOW_EXIT();
|
|
- return EOK;
|
|
+ return error;
|
|
}
|
|
|
|
/* Callback to process the donating config */
|
|
@@ -671,8 +686,8 @@ static int donor_handler(const char *property,
|
|
/* Save error anyway */
|
|
passed_data->error = acceptor_data.error;
|
|
/* If it is section DETECT or MERGE+DETECT */
|
|
- if (((passed_data->flags & INI_MS_MASK) == INI_MS_DETECT) ||
|
|
- (((passed_data->flags & INI_MS_MASK) != INI_MS_ERROR) &&
|
|
+ if (ini_flags_have(INI_MS_DETECT, passed_data->flags) ||
|
|
+ (!ini_flags_have(INI_MS_ERROR, passed_data->flags) &&
|
|
((passed_data->flags & INI_MV2S_MASK) ==
|
|
INI_MV2S_DETECT))) {
|
|
TRACE_INFO_NUMBER("Non-critical error",
|
|
@@ -782,7 +797,7 @@ static int merge_configs(struct ini_cfgobj *donor,
|
|
|
|
/* Check if we got error */
|
|
if ((data.error) &&
|
|
- (((collision_flags & INI_MS_MASK) == INI_MS_ERROR) ||
|
|
+ (ini_flags_have(INI_MS_ERROR, collision_flags) ||
|
|
((collision_flags & INI_MV2S_MASK) == INI_MV2S_ERROR))) {
|
|
TRACE_ERROR_NUMBER("Got error in error mode", data.error);
|
|
return data.error;
|
|
@@ -806,7 +821,7 @@ static int merge_configs(struct ini_cfgobj *donor,
|
|
|
|
/* Check if we got error */
|
|
if ((data.error) &&
|
|
- (((collision_flags & INI_MS_MASK) == INI_MS_DETECT) ||
|
|
+ (ini_flags_have(INI_MS_DETECT, collision_flags) ||
|
|
((collision_flags & INI_MV2S_MASK) == INI_MV2S_DETECT))) {
|
|
TRACE_ERROR_NUMBER("Got error in error or detect mode", data.error);
|
|
error = data.error;
|
|
@@ -843,12 +858,12 @@ int valid_collision_flags(uint32_t collision_flags)
|
|
return 0;
|
|
}
|
|
|
|
- flag = collision_flags & INI_MS_MASK;
|
|
+ /* Any combination of DETECT and a MODE flag is valid. */
|
|
+ flag = collision_flags & INI_MS_MODE_MASK;
|
|
if ((flag != INI_MS_MERGE) &&
|
|
(flag != INI_MS_OVERWRITE) &&
|
|
(flag != INI_MS_ERROR) &&
|
|
- (flag != INI_MS_PRESERVE) &&
|
|
- (flag != INI_MS_DETECT)) {
|
|
+ (flag != INI_MS_PRESERVE)) {
|
|
TRACE_ERROR_STRING("Invalid section collision flag","");
|
|
return 0;
|
|
}
|
|
@@ -906,9 +921,9 @@ int ini_config_merge(struct ini_cfgobj *first,
|
|
if (error) {
|
|
TRACE_ERROR_NUMBER("Failed to merge configuration", error);
|
|
if ((error == EEXIST) &&
|
|
- ((((collision_flags & INI_MS_MASK) == INI_MS_DETECT) &&
|
|
+ ((ini_flags_have(INI_MS_DETECT, collision_flags) &&
|
|
((collision_flags & INI_MV2S_MASK) != INI_MV2S_ERROR)) ||
|
|
- (((collision_flags & INI_MS_MASK) != INI_MS_ERROR) &&
|
|
+ (!ini_flags_have(INI_MS_ERROR, collision_flags) &&
|
|
((collision_flags & INI_MV2S_MASK) == INI_MV2S_DETECT)))) {
|
|
TRACE_ERROR_NUMBER("Got error in detect mode", error);
|
|
/* Fall through! */
|
|
diff --git a/ini/ini_configobj.h b/ini/ini_configobj.h
|
|
index 093916a..ca1e5ff 100644
|
|
--- a/ini/ini_configobj.h
|
|
+++ b/ini/ini_configobj.h
|
|
@@ -344,7 +344,8 @@ enum ERR_PARSE {
|
|
#define INI_MS_OVERWRITE 0x0200
|
|
/** @brief Second section is discarded */
|
|
#define INI_MS_PRESERVE 0x0300
|
|
-/** @brief Merge but log errors if duplicate sections are detected */
|
|
+/** @brief Log errors if duplicate sections are detected; non-exclusive */
|
|
+/** This defaults to MERGE, but can be used with OVERWRITE and PRESERVE **/
|
|
#define INI_MS_DETECT 0x0400
|
|
|
|
/**
|
|
diff --git a/ini/ini_defines.h b/ini/ini_defines.h
|
|
index bb34510..d79019b 100644
|
|
--- a/ini/ini_defines.h
|
|
+++ b/ini/ini_defines.h
|
|
@@ -22,6 +22,8 @@
|
|
#ifndef INI_DEFINES_H
|
|
#define INI_DEFINES_H
|
|
|
|
+#include <stdint.h>
|
|
+
|
|
#define NAME_OVERHEAD 10
|
|
|
|
#define SLASH "/"
|
|
@@ -115,9 +117,12 @@
|
|
#define INI_MV2S_MASK 0x00F0 /* Merge values options mask
|
|
* for two sections. */
|
|
#define INI_MS_MASK 0x0F00 /* Merge section options mask */
|
|
+#define INI_MS_MODE_MASK 0x0300 /* Merge section merge mode mask */
|
|
|
|
|
|
/* Different error string functions can be passed as callbacks */
|
|
typedef const char * (*error_fn)(int error);
|
|
|
|
+int ini_flags_have(uint32_t flag, uint32_t flags);
|
|
+
|
|
#endif
|
|
diff --git a/ini/ini_parse.c b/ini/ini_parse.c
|
|
index e5baeca..3050223 100644
|
|
--- a/ini/ini_parse.c
|
|
+++ b/ini/ini_parse.c
|
|
@@ -580,7 +580,7 @@ static int parser_save_section(struct parser_obj *po)
|
|
|
|
TRACE_INFO_STRING("Merge collision detected", "");
|
|
|
|
- mergemode = po->collision_flags & INI_MS_MASK;
|
|
+ mergemode = po->collision_flags & INI_MS_MODE_MASK;
|
|
|
|
switch (mergemode) {
|
|
case INI_MS_ERROR:
|
|
@@ -623,9 +623,15 @@ static int parser_save_section(struct parser_obj *po)
|
|
merge = 1;
|
|
break;
|
|
|
|
- case INI_MS_DETECT:
|
|
- /* Detect mode */
|
|
- TRACE_INFO_STRING("Detect mode", "");
|
|
+ case INI_MS_MERGE:
|
|
+ /* Merge */
|
|
+ default:
|
|
+ TRACE_INFO_STRING("Merge mode", "");
|
|
+ merge = 1;
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (po->collision_flags & INI_MS_DETECT) {
|
|
po->merge_error = EEXIST;
|
|
error = save_error(po->el,
|
|
po->seclinenum,
|
|
@@ -637,15 +643,6 @@ static int parser_save_section(struct parser_obj *po)
|
|
error);
|
|
return error;
|
|
}
|
|
- merge = 1;
|
|
- break;
|
|
-
|
|
- case INI_MS_MERGE:
|
|
- /* Merge */
|
|
- default:
|
|
- TRACE_INFO_STRING("Merge mode", "");
|
|
- merge = 1;
|
|
- break;
|
|
}
|
|
|
|
if (merge) {
|
|
@@ -1599,9 +1596,9 @@ static int parser_error(struct parser_obj *po)
|
|
* We check for reverse condition and return error,
|
|
* otherwise fall through.
|
|
*/
|
|
- if (!((((po->collision_flags & INI_MS_MASK) == INI_MS_ERROR) &&
|
|
+ if (!(((ini_flags_have(INI_MS_ERROR, po->collision_flags)) &&
|
|
(error == EEXIST)) ||
|
|
- (((po->collision_flags & INI_MS_MASK) == INI_MS_MERGE) &&
|
|
+ (ini_flags_have(INI_MS_ERROR, po->collision_flags) &&
|
|
((po->collision_flags & INI_MV2S_MASK) == INI_MV2S_ERROR) &&
|
|
(error == EEXIST)))) {
|
|
return error;
|
|
@@ -1728,11 +1725,12 @@ int ini_config_parse(struct ini_cfgfile *file_ctx,
|
|
|
|
error = parser_run(po);
|
|
if (error) {
|
|
- fl1 = collision_flags & INI_MS_MASK;
|
|
+ fl1 = collision_flags & INI_MS_MODE_MASK;
|
|
fl2 = collision_flags & INI_MV1S_MASK;
|
|
fl3 = collision_flags & INI_MV2S_MASK;
|
|
if ((error == EEXIST) &&
|
|
- (((fl1 == INI_MS_DETECT) &&
|
|
+ ((ini_flags_have(INI_MS_DETECT, collision_flags) &&
|
|
+ (fl1 != INI_MS_ERROR) &&
|
|
(fl2 != INI_MV1S_ERROR) &&
|
|
(fl3 != INI_MV2S_ERROR)) ||
|
|
((fl2 == INI_MV1S_DETECT) &&
|
|
--
|
|
2.13.2
|
|
|