Beispiel #1
0
/*
 * Locate an object in an object set.
 *
 * Arguments:
 * set: the object set to search
 * compare_fn: a caller-provided function used to compare the
 *             name against an object. This function should return
 *             a negtive value, zero, or a positive value if the
 *             object's name is, respectively, less that, equal
 *             to, or greater than the provided name.
 * name: the name (value) to find.
 * 
 * The returned object, if any, is referenced. The caller must
 * call object_release() when finished with the object.
 *
 * Returns the object, if found. Otherwise, returns NULL.
 * Implementation note: since we store objects in an unordered
 * linked list, all that's really important is that the compare_fn
 * return 0 when a match is found, and non-zero otherwise.
 * Other types of implementations might try to optimize the
 * storage, e.g. binary search.
 */
Object *
objset_find(Objset *set, CMPFn compare_fn, const void *name)
{
	objset_object *found = NULL;

	PR_ASSERT(NULL != set);
	PR_ASSERT(NULL != name);
	PR_ASSERT(NULL != compare_fn);

	PR_Lock(set->lock);
	found = set->head;
	while (NULL != found)
	{
		if (compare_fn(found->obj, name) == 0)
		{
			break;
		}
		found = found->next;
	}
	if (NULL != found)
	{
		/* acquire object */
		object_acquire(found->obj);
	}
	PR_Unlock(set->lock);
	return found == NULL ? NULL : found->obj;
}
Beispiel #2
0
static void * ListFindValue( char *node, unsigned limit, unsigned elsize,
                             void *target, bool (*compare_fn)(void *, void *) )
/*****************************************************************************/
{
    unsigned            index;

    for( index = 0; index < limit; index++ ) {
        if( compare_fn( node, target ) ) return node;
        node += elsize;
    }
    return NULL;
}
Beispiel #3
0
/* Helper for FUNC_NAME.  */
static int
iterate_device (const char *name, void *data)
{
  struct search_ctx *ctx = data;
  int found = 0;

  /* Skip floppy drives when requested.  */
  if (ctx->no_floppy &&
      name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9')
    return 0;

#ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp
#else
#define compare_fn grub_strcmp
#endif

#ifdef DO_SEARCH_FILE
    {
      char *buf;
      grub_file_t file;

      buf = grub_xasprintf ("(%s)%s", name, ctx->key);
      if (! buf)
	return 1;

      grub_file_filter_disable_compression ();
      file = grub_file_open (buf);
      if (file)
	{
	  found = 1;
	  grub_file_close (file);
	}
      grub_free (buf);
    }
#elif defined(DO_SEARCH_PART_UUID)
    {
      grub_device_t dev;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  if (grub_gpt_part_uuid (dev, &quid) == GRUB_ERR_NONE)
	    {
	      if (grub_strcasecmp (quid, ctx->key) == 0)
		    found = 1;

	      grub_free (quid);
	    }

	  grub_device_close (dev);
	}
    }
#elif defined(DO_SEARCH_PART_LABEL)
    {
      grub_device_t dev;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  if (grub_gpt_part_label (dev, &quid) == GRUB_ERR_NONE)
	    {
	      if (grub_strcmp (quid, ctx->key) == 0)
		    found = 1;

	      grub_free (quid);
	    }

	  grub_device_close (dev);
	}
    }
#else
    {
      /* SEARCH_FS_UUID or SEARCH_LABEL */
      grub_device_t dev;
      grub_fs_t fs;
      char *quid;

      dev = grub_device_open (name);
      if (dev)
	{
	  fs = grub_fs_probe (dev);

#ifdef DO_SEARCH_FS_UUID
#define read_fn uuid
#else
#define read_fn label
#endif

	  if (fs && fs->read_fn)
	    {
	      fs->read_fn (dev, &quid);

	      if (grub_errno == GRUB_ERR_NONE && quid)
		{
		  if (compare_fn (quid, ctx->key) == 0)
		    found = 1;

		  grub_free (quid);
		}
	    }

	  grub_device_close (dev);
	}
    }
#endif

  if (!ctx->is_cache && found && ctx->count == 0)
    {
      struct cache_entry *cache_ent;
      cache_ent = grub_malloc (sizeof (*cache_ent));
      if (cache_ent)
	{
	  cache_ent->key = grub_strdup (ctx->key);
	  cache_ent->value = grub_strdup (name);
	  if (cache_ent->value && cache_ent->key)
	    {
	      cache_ent->next = cache;
	      cache = cache_ent;
	    }
	  else
	    {
	      grub_free (cache_ent->value);
	      grub_free (cache_ent->key);
	      grub_free (cache_ent);
	      grub_errno = GRUB_ERR_NONE;
	    }
	}
      else
	grub_errno = GRUB_ERR_NONE;
    }

  if (found)
    {
      ctx->count++;
      if (ctx->var)
	grub_env_set (ctx->var, name);
      else
	grub_printf (" %s", name);
    }

  grub_errno = GRUB_ERR_NONE;
  return (found && ctx->var);
}