]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - lib/hashtable.c
env: Refactor apply into change_ok
[people/ms/u-boot.git] / lib / hashtable.c
index f4d57950591366128b5c06c339bdec076970b61d..6861a42029cef8249972c149df424b088d95a18d 100644 (file)
  * Instead the interface of all functions is extended to take an argument
  * which describes the current status.
  */
+
 typedef struct _ENTRY {
        int used;
        ENTRY entry;
 } _ENTRY;
 
 
+static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep,
+       int idx);
+
 /*
  * hcreate()
  */
@@ -259,6 +263,17 @@ static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action,
            && strcmp(item.key, htab->table[idx].entry.key) == 0) {
                /* Overwrite existing value? */
                if ((action == ENTER) && (item.data != NULL)) {
+                       /* check for permission */
+                       if (htab->change_ok != NULL && htab->change_ok(
+                           &htab->table[idx].entry, item.data,
+                           env_op_overwrite, flag)) {
+                               debug("change_ok() rejected setting variable "
+                                       "%s, skipping it!\n", item.key);
+                               __set_errno(EPERM);
+                               *retval = NULL;
+                               return 0;
+                       }
+
                        free(htab->table[idx].entry.data);
                        htab->table[idx].entry.data = strdup(item.data);
                        if (!htab->table[idx].entry.data) {
@@ -383,6 +398,17 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
 
                ++htab->filled;
 
+               /* check for permission */
+               if (htab->change_ok != NULL && htab->change_ok(
+                   &htab->table[idx].entry, item.data, env_op_create, flag)) {
+                       debug("change_ok() rejected setting variable "
+                               "%s, skipping it!\n", item.key);
+                       _hdelete(item.key, htab, &htab->table[idx].entry, idx);
+                       __set_errno(EPERM);
+                       *retval = NULL;
+                       return 0;
+               }
+
                /* return new entry */
                *retval = &htab->table[idx].entry;
                return 1;
@@ -404,6 +430,18 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval,
  * do that.
  */
 
+static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep,
+       int idx)
+{
+       /* free used ENTRY */
+       debug("hdelete: DELETING key \"%s\"\n", key);
+       free((void *)ep->key);
+       free(ep->data);
+       htab->table[idx].used = -1;
+
+       --htab->filled;
+}
+
 int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
 {
        ENTRY e, *ep;
@@ -420,19 +458,15 @@ int hdelete_r(const char *key, struct hsearch_data *htab, int flag)
        }
 
        /* Check for permission */
-       if (htab->apply != NULL &&
-           htab->apply(ep->key, ep->data, NULL, flag)) {
+       if (htab->change_ok != NULL &&
+           htab->change_ok(ep, NULL, env_op_delete, flag)) {
+               debug("change_ok() rejected deleting variable "
+                       "%s, skipping it!\n", key);
                __set_errno(EPERM);
                return 0;
        }
 
-       /* free used ENTRY */
-       debug("hdelete: DELETING key \"%s\"\n", key);
-       free((void *)ep->key);
-       free(ep->data);
-       htab->table[idx].used = -1;
-
-       --htab->filled;
+       _hdelete(key, htab, ep, idx);
 
        return 1;
 }
@@ -800,24 +834,6 @@ int himport_r(struct hsearch_data *htab,
                e.key = name;
                e.data = value;
 
-               /* if there is an apply function, check what it has to say */
-               if (htab->apply != NULL) {
-                       debug("searching before calling cb function"
-                               " for  %s\n", name);
-                       /*
-                        * Search for variable in existing env, so to pass
-                        * its previous value to the apply callback
-                        */
-                       hsearch_r(e, FIND, &rv, htab, 0);
-                       debug("previous value was %s\n", rv ? rv->data : "");
-                       if (htab->apply(name, rv ? rv->data : NULL,
-                               value, flag)) {
-                               debug("callback function refused to set"
-                                       " variable %s, skipping it!\n", name);
-                               continue;
-                       }
-               }
-
                hsearch_r(e, ENTER, &rv, htab, flag);
                if (rv == NULL) {
                        printf("himport_r: can't insert \"%s=%s\" into hash table\n",