예제 #1
0
int mail_cache_db_clean_up(struct mail_cache_db * cache_db,
    chash * exist)
{
  DB * dbp;
  int r;
  DBT db_key;
  DBT db_data;
  
  dbp = cache_db->internal_database;
  
  r = dbp->seq(dbp, &db_key, &db_data, R_FIRST);
  if (r == -1)
    return -1;
  
  while (r == 0) {
    chashdatum hash_key;
    chashdatum hash_data;
    
    hash_key.data = db_key.data;
    hash_key.len = db_key.size;

    r = chash_get(exist, &hash_key, &hash_data);
    if (r < 0) {
      r = dbp->del(dbp, &db_key, 0);
      if (r != 0)
        return -1;
    }
    
    r = dbp->seq(dbp, &db_key, &db_data, R_NEXT);
    if (r < 0)
      return -1;
  }
  
  return 0;
}
예제 #2
0
int mail_cache_db_get_keys(struct mail_cache_db * cache_db,
    chash * keys)
{
  DB * dbp;
  int r;
  DBT db_key;
  DBT db_data;
  
  dbp = cache_db->internal_database;
  
  r = dbp->seq(dbp, &db_key, &db_data, R_FIRST);
  if (r == -1)
    return -1;
  
  while (r == 0) {
    chashdatum hash_key;
    chashdatum hash_data;
    
    hash_key.data = db_key.data;
    hash_key.len = db_key.size;
    hash_data.data = NULL;
    hash_data.len = 0;
    
    r = chash_set(keys, &hash_key, &hash_data, NULL);
    if (r < 0) {
      return -1;
    }
    
    r = dbp->seq(dbp, &db_key, &db_data, R_NEXT);
    if (r < 0)
      return -1;
  }
  
  return 0;
}
예제 #3
0
파일: map_db.c 프로젝트: jcarnat/OpenSMTPD
static int
map_db_compare(void *hdl, char *key, enum map_kind kind,
    int (*func)(char *, char *))
{
	int ret = 0;
	DB *db = hdl;
	DBT dbk;
	DBT dbd;
	int r;
	char *buf = NULL;

	for (r = db->seq(db, &dbk, &dbd, R_FIRST); !r;
	     r = db->seq(db, &dbk, &dbd, R_NEXT)) {
		buf = calloc(dbk.size+1, 1);
		if (buf == NULL)
			fatalx("calloc");
		strlcpy(buf, dbk.data, dbk.size+1);
		log_debug("key: %s, buf: %s", key, buf);
		if (func(key, buf))
			ret = 1;
		free(buf);
		if (ret)
			break;
	}
	return ret;
}
예제 #4
0
static krb5_error_code
ctx_iterate(krb5_context context, krb5_db2_context *dbc,
            krb5_error_code (*func)(krb5_pointer, krb5_db_entry *),
            krb5_pointer func_arg)
{
    DB *db;
    DBT key, contents;
    krb5_data contdata;
    krb5_db_entry *entry;
    krb5_error_code retval, retval2;
    int dbret;

    retval = ctx_lock(context, dbc, KRB5_LOCKMODE_SHARED);
    if (retval)
        return retval;

    db = dbc->db;
    dbret = db->seq(db, &key, &contents, R_FIRST);
    while (dbret == 0) {
        contdata.data = contents.data;
        contdata.length = contents.size;
        retval = krb5_decode_princ_entry(context, &contdata, &entry);
        if (retval)
            break;
        retval = k5_mutex_unlock(krb5_db2_mutex);
        if (retval)
            break;
        retval = (*func)(func_arg, entry);
        krb5_dbe_free(context, entry);
        retval2 = k5_mutex_lock(krb5_db2_mutex);
        /* Note: If re-locking fails, the wrapper in db2_exp.c will
           still try to unlock it again.  That would be a bug.  Fix
           when integrating the locking better.  */
        if (retval)
            break;
        if (retval2) {
            retval = retval2;
            break;
        }
        dbret = db->seq(db, &key, &contents, R_NEXT);
    }
    switch (dbret) {
    case 1:
    case 0:
        break;
    case -1:
    default:
        retval = errno;
    }
    (void) ctx_unlock(context, dbc);
    return retval;
}
예제 #5
0
파일: kdb_db2.c 프로젝트: DirectXMan12/krb5
/* Get initial entry. */
static int
curs_start(iter_curs *curs)
{
    DB *db = curs->dbc->db;

    return db->seq(db, &curs->key, &curs->data, curs->startflag);
}
예제 #6
0
int findoffset(char *dbname)
{
    DB *db;
    DBT dkey, dvalue;
    int result;
    int offset = 0;
    char *p;
    int ptag = 0, pclass, plen;
    X509 *mycert;

    if((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL)
    {
        fprintf(stderr, "Failed to open DB file '%s': %s\n", dbname, strerror(errno));
        exit(1);
    }
    while((result = (db->seq(db, &dkey, &dvalue, R_NEXT))) == 0)
    {
        if((dvalue.size) > 520)
        {
            while(offset < dvalue.size)
            {
                p = (char *)dvalue.data + offset - 1;
                ASN1_get_object((unsigned char **)&p, (long *)&plen, &ptag, &pclass, dvalue.size);
                if(ptag == V_ASN1_SEQUENCE)
                { /* ok, it might be a cert then. */
                    /* include length of object header junk */
                    plen += p - ((char *)dvalue.data + offset - 1);
                    mycert = NULL;
                    p = (char *)dvalue.data + offset - 1;
                    d2i_X509(&mycert, (unsigned char **)&p, plen);
                    if(mycert == NULL)
                    { /* must be garbage after all */
                        offset++;
                        continue;
                    }
                    break;
                }
                else
                    offset++;
            }
            if(offset > 0)
                break; /* found it, let's quit */
        }
    }
    db->close(db);
    return (offset);
}
예제 #7
0
int 
next_rule()
{
	DB *db;
	DBT dbt;
	DBT key;
	int i = 0;

	db = dbopen(RULESCRIPT, O_CREAT | O_RDWR, 0600, DB_BTREE, NULL);

	while (db->seq(db, &key, &dbt, R_NEXT)== 0){
		i += 1;
	}

	db->close(db);

	return i;
}
예제 #8
0
static int dict_db_sequence(DICT *dict, int function,
			            const char **key, const char **value)
{
    const char *myname = "dict_db_sequence";
    DICT_DB *dict_db = (DICT_DB *) dict;
    DB     *db = dict_db->db;
    DBT     db_key;
    DBT     db_value;
    int     status = 0;
    int     db_function;

    dict->error = 0;

#if DB_VERSION_MAJOR > 1

    /*
     * Initialize.
     */
    memset(&db_key, 0, sizeof(db_key));
    memset(&db_value, 0, sizeof(db_value));

    /*
     * Determine the function.
     */
    switch (function) {
    case DICT_SEQ_FUN_FIRST:
	if (dict_db->cursor == 0)
	    DICT_DB_CURSOR(db, &(dict_db->cursor));
	db_function = DB_FIRST;
	break;
    case DICT_SEQ_FUN_NEXT:
	if (dict_db->cursor == 0)
	    msg_panic("%s: no cursor", myname);
	db_function = DB_NEXT;
	break;
    default:
	msg_panic("%s: invalid function %d", myname, function);
    }

    /*
     * Acquire a shared lock.
     */
    if ((dict->flags & DICT_FLAG_LOCK)
	&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
	msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);

    /*
     * Database lookup.
     */
    status =
	dict_db->cursor->c_get(dict_db->cursor, &db_key, &db_value, db_function);
    if (status != 0 && status != DB_NOTFOUND)
	msg_fatal("error [%d] seeking %s: %m", status, dict_db->dict.name);

    /*
     * Release the shared lock.
     */
    if ((dict->flags & DICT_FLAG_LOCK)
	&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
	msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);

    if (status == 0) {

	/*
	 * Copy the result so it is guaranteed null terminated.
	 */
	*key = SCOPY(dict_db->key_buf, db_key.data, db_key.size);
	*value = SCOPY(dict_db->val_buf, db_value.data, db_value.size);
    }
    return (status);
#else

    /*
     * determine the function
     */
    switch (function) {
    case DICT_SEQ_FUN_FIRST:
	db_function = R_FIRST;
	break;
    case DICT_SEQ_FUN_NEXT:
	db_function = R_NEXT;
	break;
    default:
	msg_panic("%s: invalid function %d", myname, function);
    }

    /*
     * Acquire a shared lock.
     */
    if ((dict->flags & DICT_FLAG_LOCK)
	&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_SHARED) < 0)
	msg_fatal("%s: lock dictionary: %m", dict_db->dict.name);

    if ((status = db->seq(db, &db_key, &db_value, db_function)) < 0)
	msg_fatal("error seeking %s: %m", dict_db->dict.name);

    /*
     * Release the shared lock.
     */
    if ((dict->flags & DICT_FLAG_LOCK)
	&& myflock(dict->lock_fd, INTERNAL_LOCK, MYFLOCK_OP_NONE) < 0)
	msg_fatal("%s: unlock dictionary: %m", dict_db->dict.name);

    if (status == 0) {

	/*
	 * Copy the result so that it is guaranteed null terminated.
	 */
	*key = SCOPY(dict_db->key_buf, db_key.data, db_key.size);
	*value = SCOPY(dict_db->val_buf, db_value.data, db_value.size);
    }
    return status;
#endif
}
예제 #9
0
/**
 * librdf_hash_bdb_cursor_get - Retrieve a hash value for the given key
 * @context: BerkeleyDB hash cursor context
 * @key: pointer to key to use
 * @value: pointer to value to use
 * @flags: flags
 * 
 * Return value: non 0 on failure
 **/
static int
librdf_hash_bdb_cursor_get(void* context, 
                           librdf_hash_datum *key, librdf_hash_datum *value,
                           unsigned int flags)
{
  librdf_hash_bdb_cursor_context *cursor=(librdf_hash_bdb_cursor_context*)context;
#ifdef HAVE_BDB_CURSOR
  DBC *bdb_cursor=cursor->cursor;
#else
  /* For BDB V1 */
  DB* db;
#endif
  DBT bdb_key;
  DBT bdb_value;
  int ret;

  /* docs say you must zero DBT's before use */
  memset(&bdb_key, 0, sizeof(DBT));
  memset(&bdb_value, 0, sizeof(DBT));

  /* Always initialise BDB version of key */
  bdb_key.data = (char*)key->data;
  bdb_key.size = key->size;
  
#ifdef DB_DBT_MALLOC
  /* BDB V2 or later? */
  bdb_key.flags=DB_DBT_MALLOC;   /* Return in malloc() allocated memory */
  bdb_value.flags=DB_DBT_MALLOC;
#endif

#ifndef HAVE_BDB_CURSOR
  /* For BDB V1 */
  db=cursor->hash->db;
#endif
  
  switch(flags) {
    case LIBRDF_HASH_CURSOR_SET:

#ifdef HAVE_BDB_CURSOR
      /* V2/V3 prototype:
       * int DBcursor->c_get(DBC *cursor, DBT *key, DBT *data, u_int32_t flags);
       */
      ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, DB_SET);
#else
      /* V1 */
      ret=db->seq(db, &bdb_key, &bdb_value, 0);
#endif
      break;
      
    case LIBRDF_HASH_CURSOR_FIRST:
#ifdef HAVE_BDB_CURSOR
      /* V2/V3 prototype:
       * int DBcursor->c_get(DBC *cursor, DBT *key, DBT *data, u_int32_t flags);
       */
      ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, DB_FIRST);
#else
      /* V1 */
      ret=db->seq(db, &bdb_key, &bdb_value, R_FIRST);
#endif
      break;
      
    case LIBRDF_HASH_CURSOR_NEXT_VALUE:
#ifdef HAVE_BDB_CURSOR
      /* V2/V3 */
      ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, DB_NEXT);
#else
      /* V1 */
      ret=db->seq(db, &bdb_key, &bdb_value, R_NEXT);
#endif
      
      /* If succeeded and key has changed, end */
      if(!ret && cursor->last_key &&
         memcmp(cursor->last_key, bdb_key.data, bdb_key.size)) {
        
        /* always allocated by BDB using system malloc */
        SYSTEM_FREE(bdb_key.data);
        SYSTEM_FREE(bdb_value.data);

#ifdef DB_NOTFOUND
        /* V2 and V3 */
        ret=DB_NOTFOUND;
#else
        ret=1;
#endif
      }
      
      break;
      
    case LIBRDF_HASH_CURSOR_NEXT:
#ifdef HAVE_BDB_CURSOR
#ifdef DB_NEXT_NODUP
      /* V3 */

      /* Get next key, or next key/value (when value defined) */
      ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value,
                            (value) ? DB_NEXT : DB_NEXT_NODUP);
#else
      /* V2 */

      /* Must mess about finding next key - note this relies on
       * the bdb btree having the keys in sorted order
       */
      while(1) {
        ret=bdb_cursor->c_get(bdb_cursor, &bdb_key, &bdb_value, DB_NEXT);
        /* finish on error, want all values or no previous key */
        if(ret || value || !cursor->last_key)
          break;
        /* else have previous key and want unique keys, so keep
         * going until the key changes
         */
        if(memcmp(cursor->last_key, bdb_key.data, bdb_key.size))
          break;
        
        /* always allocated by BDB using system malloc */
        SYSTEM_FREE(bdb_key.data);
        SYSTEM_FREE(bdb_value.data);
      }
#endif
#else
      /* V1 */
      ret=db->seq(db, &bdb_key, &bdb_value, R_NEXT);
#endif
      break;
      
    default:
      LIBRDF_ERROR2(cursor->hash->hash->world, "Unknown hash method flag %d\n", flags);
      return 1;
  }


  /* Free previous key and values */
  if(cursor->last_key) {
    LIBRDF_FREE(cstring, cursor->last_key);
    cursor->last_key=NULL;
  }
    
  if(cursor->last_value) {
    LIBRDF_FREE(cstring, cursor->last_value);
    cursor->last_value=NULL;
  }

  

  if(ret) {
#ifdef DB_NOTFOUND
    /* V2 and V3 */
    if(ret != DB_NOTFOUND)
      LIBRDF_DEBUG2("BDB cursor error - %d\n", ret);
#endif
    key->data=NULL;
    return ret;
  }
  
  cursor->last_key = key->data = LIBRDF_MALLOC(cstring, bdb_key.size);
  if(!key->data) {
    /* always allocated by BDB using system malloc */
    if(flags != LIBRDF_HASH_CURSOR_SET)
      SYSTEM_FREE(bdb_key.data);
    SYSTEM_FREE(bdb_value.data);
    return 1;
  }
  
  memcpy(key->data, bdb_key.data, bdb_key.size);
  key->size = bdb_key.size;

  if(value) {
    cursor->last_value = value->data = LIBRDF_MALLOC(cstring, bdb_value.size);
    if(!value->data) {
      /* always allocated by BDB using system malloc */
      if(flags != LIBRDF_HASH_CURSOR_SET)
        SYSTEM_FREE(bdb_key.data);
      SYSTEM_FREE(bdb_value.data);
      return 1;
    }
    
    memcpy(value->data, bdb_value.data, bdb_value.size);
    value->size = bdb_value.size;
  }

  /* always allocated by BDB using system malloc */
  if(flags != LIBRDF_HASH_CURSOR_SET)
    SYSTEM_FREE(bdb_key.data);
  SYSTEM_FREE(bdb_value.data);

  return 0;
}
예제 #10
0
int main(int argc, char **argv)
{
    char *dbname;
    DB *db;
    int j;
    int offset;
    DBT dkey, dvalue;
    int result;
    char oname[40];
    int fout;
    int find;
    char *p;
    int ptag = 0, pclass, plen;
    X509 *mycert;
    char *shortname;
    char byte1, byte2;

    if(argc != 2)
    {
        fprintf(stderr, "usage: %s /path/to/netscape/cert.db\n", argv[0]);
        exit(1);
    }

    dbname = argv[1];
    offset = findoffset(dbname);
    if(offset == 0)
    {
        fprintf(stderr, "Couldn't determine cert offset in DB file '%s'\n", dbname);
        exit(1);
    }
    else
    {
        fprintf(stderr, "Ok: certificates are at offset %d\n", offset);
    }

    if((db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL)) == NULL)
    {
        fprintf(stderr, "Failed to open DB file '%s': %s\n", dbname, strerror(errno));
        exit(1);
    }
    if((find = open("cert.index", O_WRONLY | O_CREAT | O_TRUNC, 0755)) == -1)
    {
        fprintf(stderr, "Failed to open Index file '%s': %s\n", "cert-index", strerror(errno));
        exit(1);
    }
    j = 0;
    byte1 = -1;
    byte2 = -1;
    while((result = (db->seq(db, &dkey, &dvalue, R_NEXT))) == 0)
    {
        if(dvalue.size > offset && ((dvalue.size) - offset) > 500)
        {
            p = (char *)dvalue.data + offset - 1;
            if(byte1 != -1 && byte2 != -1)
                if(byte1 != p[0] || byte2 != p[1])
                    continue;
            ASN1_get_object((unsigned char **)&p, (long *)&plen, &ptag, &pclass, dvalue.size);
            if(ptag == V_ASN1_SEQUENCE)
            { /* ok, it might be a cert then. */
                if(byte1 == -1 && byte2 == -1)
                {
                    byte1 = p[0];
                    byte2 = p[1];
                }
                /* include length of object header junk */
                plen += p - ((char *)dvalue.data + offset - 1);
                mycert = NULL;
                p = (char *)dvalue.data + offset - 1;
                d2i_X509(&mycert, (unsigned char **)&p, plen);
                if(mycert == NULL)
                { /* must be garbage after all */
                    continue;
                }
                j++;
                sprintf(oname, "cert.%02d.der", j);
                if((fout = open(oname, O_WRONLY | O_CREAT | O_TRUNC, 0755)) == -1)
                {
                    fprintf(stderr, "couldn't open %s\n", oname);
                    continue;
                }
                write(fout, (char *)dvalue.data + offset - 1, plen);
                close(fout);
                write(find, oname, strlen(oname));
                write(find, ": ", 2);
                shortname = (char *)dvalue.data + offset - 1 + plen;
                write(find, shortname, dvalue.size - plen - offset);
                write(find, "\n", 1);
                fprintf(stderr, "Extracted: %s (", oname);
                write(fileno(stderr), shortname, dvalue.size - plen - offset);
                fprintf(stderr, ")\n");
            }
            else
            {
                /* fprintf(stderr, "Hmmm... ptag is %d, plen is %d\n", ptag, plen); */
            }
        }
    }
    close(find);
    db->close(db);

    return (0);
}
예제 #11
0
파일: bigtest.c 프로젝트: Akasurde/krb5
int
main(void)
{
	HASHINFO info;
	DB *db;
	DBT key, value, returned;
	int *data;
	int n, i;

	info.bsize = 512;
	info.cachesize = 500;
	info.lorder = 0;
	info.ffactor = 4;
	info.nelem = 0;
	info.hash = NULL;

	db = dbopen("big2.db", O_RDWR|O_CREAT|O_TRUNC|O_BINARY, 0664, DB_HASH, &info);
	data = malloc(800 * sizeof(int));
	for (n = 0; n < 800; n++)
		data[n] = 0xDEADBEEF;
	key.size = sizeof(int);
	key.data = &n;
	value.size = 800 * sizeof(int);
	value.data = (void *)data;

	for (n = 0; n < 200000; n++) {
		returned.data = NULL;
		if (n == 4627)
			printf("");
		if (n % 50 == 0)
			printf("put n = %d\n", n);
		if (db->put(db, &key, &value, 0) != 0)
			printf("put error, n = %d\n", n);
		if (db->get(db, &key, &returned, 0) != 0)
			printf("Immediate get error, n = %d\n", n);
		assert (returned.size == 3200);
		for (i = 0; i < 800; i++)
			if (((int *)returned.data)[i] != 0xDEADBEEF)
				printf("ERRORRRRRR!!!\n");

	}

	for (n = 0; n < 200000; n++) {
		if (n % 50 == 0)
			printf("seq n = %d\n", n);
		if ((db->seq(db, &key, &returned, 0)) != 0)
			printf("Seq error, n = %d\n", n);

		assert(returned.size == 3200);

		for (i = 0; i < 800; i++)
			if (((int *)returned.data)[i] != 0xDEADBEEF)
				printf("ERRORRRRRR!!! seq %d\n", n);
	}

	for (n = 0; n < 2000; n++) {
		if (n % 50 == 0)
			printf("get n = %d\n", n);
		if (db->get(db, &key, &returned, 0) != 0)
			printf("Late get error, n = %d\n", n);
		assert(returned.size == 1200);
		for (i = 0; i < 300; i++)
			if (((int *)returned.data)[i] != 0xDEADBEEF)
				printf("ERRORRRRRR!!!, get %d\n", n);
	}
   	db->close(db);
	free(value.data);
	return(0);
}
예제 #12
0
파일: vsdb.c 프로젝트: lembacon/VSDataStore
vsdb_ret_t vsdb_glob(vsdb_t vsdb, const char *glob, size_t glob_length,
                                  const char ***keys, size_t **key_lengths,
                                  const void ***values, size_t **value_sizes,
                                  size_t *count)
{
  DB *db;
  DBT kt, dt;
  vsdb_ret_t vsdb_ret;
  int ret;
  size_t i;
  struct {
    DBT *kts, *dts;
    size_t count;
    size_t capacity;
  } buf;

  vsdb_ret = vsdb_okay;
  bzero(&buf, sizeof(buf));
  lockdb(vsdb);

  if ((db = getdb(vsdb)) == NULL)
    goto failed;
  if (glob == NULL)
    goto failed;
  if (glob_length == SIZE_T_MAX)
    glob_length = strlen(glob);
  if (glob_length == 0)
    goto failed;
  if (keys == NULL || key_lengths == NULL || values == NULL || value_sizes == NULL)
    goto failed;
  if (count == NULL)
    goto failed;

  if (glob_length == 1 && glob[0] == '*') {
    if ((ret = db->seq(db, &kt, &dt, R_FIRST)) < 0) {
      goto failed;
    }
    else if (ret == 0) {
      do {
        if (buf.count == buf.capacity) {
          if (buf.capacity == 0) {
            buf.capacity = 16;
            buf.kts = (DBT *)malloc(sizeof(DBT) * buf.capacity);
            buf.dts = (DBT *)malloc(sizeof(DBT) * buf.capacity);
          }
          else {
            buf.capacity <<= 1;
            buf.kts = (DBT *)realloc(buf.kts, sizeof(DBT) * buf.capacity);
            buf.dts = (DBT *)realloc(buf.dts, sizeof(DBT) * buf.capacity);
          }
        }

        dup_dbt(&buf.kts[buf.count], &kt);
        dup_dbt(&buf.dts[buf.count], &dt);
        buf.count++;
      } while ((ret = db->seq(db, &kt, &dt, R_NEXT)) == 0);

      if (ret < 0) {
        goto failed;
      }
    }
  }
  else if (glob_length > 0 && glob[glob_length - 1] == '*') {
    kt.data = (void *)glob;
    kt.size = glob_length - 1;

    if ((ret = db->seq(db, &kt, &dt, R_CURSOR)) < 0) {
      goto failed;
    }
    else if (ret == 0) {
      do {
        if (buf.count == buf.capacity) {
          if (buf.capacity == 0) {
            buf.capacity = 16;
            buf.kts = (DBT *)malloc(sizeof(DBT) * buf.capacity);
            buf.dts = (DBT *)malloc(sizeof(DBT) * buf.capacity);
          }
          else {
            buf.capacity <<= 1;
            buf.kts = (DBT *)realloc(buf.kts, sizeof(DBT) * buf.capacity);
            buf.dts = (DBT *)realloc(buf.dts, sizeof(DBT) * buf.capacity);
          }
        }

        if (strncmp((const char *)kt.data, glob, ((glob_length - 1) < kt.size) ? (glob_length - 1) : kt.size) != 0) {
          break;
        }

        dup_dbt(&buf.kts[buf.count], &kt);
        dup_dbt(&buf.dts[buf.count], &dt);
        buf.count++;
      } while ((ret = db->seq(db, &kt, &dt, R_NEXT)) == 0);

      if (ret < 0) {
        goto failed;
      }
    }
  }
  else {
    goto failed;
  }

  if (buf.count > 0) {
    *keys = (const char **)malloc(sizeof(const char *) * buf.count);
    *key_lengths = (size_t *)malloc(sizeof(size_t) * buf.count);
    *values = (const void **)malloc(sizeof(const void *) * buf.count);
    *value_sizes = (size_t *)malloc(sizeof(size_t) * buf.count);
    *count = buf.count;
    
    for (i = 0; i < buf.count; i++) {
      (*keys)[i] = (const char *)buf.kts[i].data;
      (*key_lengths)[i] = buf.kts[i].size;
      (*values)[i] = buf.dts[i].data;
      (*value_sizes)[i] = buf.dts[i].size;
    }

    goto cleanup;
  }
  else {
    goto reset;
  }

failed:
  vsdb_ret = vsdb_failed;
reset:
  if (keys != NULL)
    *keys = NULL;
  if (key_lengths != NULL)
    *key_lengths = NULL;
  if (values != NULL)
    *values = NULL;
  if (value_sizes != NULL)
    *value_sizes = NULL;
  if (count != NULL)
    *count = 0;
cleanup:
  unlockdb(vsdb);
  if (buf.capacity > 0) {
    free(buf.kts);
    free(buf.dts);
  }
  return vsdb_ret;
}
예제 #13
0
파일: cc_db.c 프로젝트: PADL/pam_ccreds
int pam_cc_db_seq(void *_db, void **cookie,
		  const char **key_p, size_t *keylength_p,
		  const char **data_p, size_t *datalength_p)
{
	DB *db = (DB *)_db;
	DBT key;
	DBT val;
	int rc;
#if DB_VERSION_MAJOR >= 2
	DBC *cursor = (DBC *)*cookie;
	int first = 0;
#endif

	memset(&key, 0, sizeof(key));
	memset(&val, 0, sizeof(val));

#if DB_VERSION_MAJOR < 2
	rc = db->seq(db, &key, &val, (*cookie == NULL ? R_FIRST : R_NEXT));
	if (*cookie == NULL) {
		*cookie = (void *)1;
	}
#else
	if (cursor == NULL) {
# if DB_VERSION_MAJOR > 2 || (DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR > 5)
		rc = db->cursor(db, NULL, &cursor, 0);
# else
		rc = db->cursor(db, NULL, &cursor);
# endif
		if (rc != 0) {
			errno = rc;
			return PAM_SERVICE_ERR;
		}

		*cookie = cursor;
		first++;
	}

	rc = cursor->c_get(cursor, &key, &val,
			   first ? DB_FIRST : DB_NEXT);
#endif /* DB_VERSION_MAJOR <= 2 */

	switch (rc) {
	case DB_NOTFOUND:
		rc = PAM_SUCCESS;
		break;
	case 0:
		rc = PAM_INCOMPLETE;
		break;
	default:
		errno = rc;
		rc = PAM_SERVICE_ERR;
		return rc;
		break;
	}

	*key_p = key.data;
	*keylength_p = key.size;

	*data_p = val.data;
	*datalength_p = val.size;

	return rc;
}