+enum blob_match_loop_flags {
+ BM_NAME_LOOP = 1,
+ BM_REVERSE_LOOP = 2
+};
+
+struct blob_match_data {
+ struct osl_table *table;
+ const char *patterns;
+ size_t patterns_size;
+ int fnmatch_flags;
+ unsigned loop_flags;
+ void *data;
+ int (*action)(struct osl_table *table, struct osl_row *row, const char *name, void *data);
+};
+
+static int action_if_blob_matches(struct osl_row *row, void *data)
+{
+ struct blob_match_data *bmd = data;
+ struct osl_object name_obj;
+ const char *p, *name;
+ int ret = osl_get_object(bmd->table, row, BLOBCOL_NAME, &name_obj);
+
+ if (ret < 0) {
+ PARA_ERROR_LOG("%s\n", PARA_STRERROR(-ret));
+ return ret;
+ }
+ name = (char *)name_obj.data;
+ if (!*name) /* ignore dummy row */
+ return 1;
+ if (!bmd->patterns_size) /* match everything if no pattern was given */
+ return bmd->action(bmd->table, row, name, bmd->data);
+ for (p = bmd->patterns; p < bmd->patterns + bmd->patterns_size;
+ p += strlen(p) + 1) {
+ ret = fnmatch(p, name, bmd->fnmatch_flags);
+ if (ret == FNM_NOMATCH)
+ continue;
+ if (ret)
+ return -E_FNMATCH;
+ return bmd->action(bmd->table, row, name, bmd->data);
+ }
+ return 1;
+}
+
+static int for_each_matching_blob(struct blob_match_data *bmd)
+{
+ unsigned col = (bmd->loop_flags & BM_NAME_LOOP)?
+ BLOBCOL_NAME : BLOBCOL_ID;
+
+ if (bmd->loop_flags & BM_REVERSE_LOOP)
+ return osl_rbtree_loop_reverse(bmd->table, col, bmd, action_if_blob_matches);
+ return osl_rbtree_loop(bmd->table, col, bmd, action_if_blob_matches);
+}
+