int Dbc::pget(Dbt* key, Dbt *pkey, Dbt *data, u_int32_t _flags)
{
    int ret;
    DBC *dbc = this;

    ret = dbc->c_pget(dbc, key, pkey, data, _flags);

    /* Logic is the same as for Dbc::get - reusing macro. */
    if (!DB_RETOK_DBCGET(ret)) {
        if (ret == ENOMEM && DB_OVERFLOWED_DBT(key))
            DB_ERROR_DBT("Dbc::pget", key, ON_ERROR_UNKNOWN);
        else if (ret == ENOMEM && DB_OVERFLOWED_DBT(data))
            DB_ERROR_DBT("Dbc::pget", data, ON_ERROR_UNKNOWN);
        else
            DB_ERROR("Dbc::pget", ret, ON_ERROR_UNKNOWN);
    }

    return (ret);
}
Example #2
0
/*
 * DbRecord_search_field --
 *	Search, looking for a record by field.
 */
static int
DbRecord_search_field(DbField *f, char *value, OPERATOR op)
{
#ifdef HAVE_WILDCARD_SUPPORT
	regex_t preq;
#endif
	DBC *dbc;
	DbRecord record;
	DBT key, data, pkey;
	double value_double;
	u_long value_ulong;
	u_int32_t cursor_flags;
	int ret, t_ret;
	int (*cmp)(void *, void *, OPERATOR);
	void *faddr, *valuep;

	dbc = NULL;
	memset(&key, 0, sizeof(key));
	memset(&pkey, 0, sizeof(pkey));
	memset(&data, 0, sizeof(data));

	/*
	 * Initialize the comparison function, crack the value.  Wild cards
	 * are always strings, otherwise we follow the field type.
	 */
	if (op == WC || op == NWC) {
#ifdef HAVE_WILDCARD_SUPPORT
		if (f->type != STRING) {
			dbenv->errx(dbenv,
		    "wildcard operator only supported for string fields");
			return (1);
		}
		if (regcomp(&preq, value, 0) != 0) {
			dbenv->errx(dbenv, "regcomp of pattern failed");
			return (1);
		}
		valuep = &preq;
		cmp = field_cmp_re;
#else
		dbenv->errx(dbenv,
		    "wildcard operators not supported in this build");
		return (1);
#endif
	} else
		switch (f->type) {
		case DOUBLE:
			if (strtod_err(value, &value_double) != 0)
				return (1);
			cmp = field_cmp_double;
			valuep = &value_double;
			key.size = sizeof(double);
			break;
		case STRING:
			valuep = value;
			cmp = field_cmp_string;
			key.size = (u_int32_t)strlen(value);
			break;
		case UNSIGNED_LONG:
			if (strtoul_err(value, &value_ulong) != 0)
				return (1);
			cmp = field_cmp_ulong;
			valuep = &value_ulong;
			key.size = sizeof(u_long);
			break;
		default:
		case NOTSET:
			abort();
			/* NOTREACHED */
		}

	/*
	 * Retrieve the first record that interests us.  The range depends on
	 * the operator:
	 *
	 *	~		beginning to end
	 *	!=		beginning to end
	 *	<		beginning to first match
	 *	<=		beginning to last match
	 *	=		first match to last match
	 *	>		record after last match to end
	 *	>=		first match to end
	 *
	 * If we have a secondary, set a cursor in the secondary, else set the
	 * cursor to the beginning of the primary.
	 *
	 * XXX
	 * If the wildcard string has a leading non-magic character we should
	 * be able to do a range search instead of a full-database search.
	 *
	 * Step through records to the first non-match or to the end of the
	 * database, depending on the operation.  If the comparison function
	 * returns success for a key/data pair, print the pair.
	 */
	if (f->secondary == NULL || op == NEQ || op == WC || op == NWC) {
		if ((ret = db->cursor(db, NULL, &dbc, 0)) != 0)
			goto err;
		while ((ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) == 0) {
			if ((ret = DbRecord_init(&key, &data, &record)) != 0)
				break;
			faddr = (u_int8_t *)&record + f->offset;
			if (cmp(faddr, valuep, op))
				DbRecord_print(&record, NULL);
			else
				if (op == EQ || op == LT || op == LTEQ)
					break;
		}
	} else {
		if ((ret =
		    f->secondary->cursor(f->secondary, NULL, &dbc, 0)) != 0)
			goto err;
		key.data = valuep;
		cursor_flags = op == LT || op == LTEQ ? DB_FIRST : DB_SET_RANGE;
		if ((ret =
		    dbc->c_pget(dbc, &key, &pkey, &data, cursor_flags)) != 0)
			goto done;
		if (op == GT) {
			while ((ret = dbc->c_pget(
			    dbc, &key, &pkey, &data, DB_NEXT)) == 0) {
				if ((ret =
				    DbRecord_init(&pkey, &data, &record)) != 0)
					break;
				faddr = (u_int8_t *)&record + f->offset;
				if (cmp(faddr, valuep, op) != 0)
					break;
			}
			if (ret != 0)
				goto done;
		}
		do {
			if ((ret = DbRecord_init(&pkey, &data, &record)) != 0)
				break;
			faddr = (u_int8_t *)&record + f->offset;
			if (cmp(faddr, valuep, op))
				DbRecord_print(&record, NULL);
			else
				if (op == EQ || op == LT || op == LTEQ)
					break;
		} while ((ret =
		    dbc->c_pget(dbc, &key, &pkey, &data, DB_NEXT)) == 0);
	}

done:	if (ret == DB_NOTFOUND)
		ret = 0;

err:	if (dbc != NULL && (t_ret = dbc->c_close(dbc)) != 0 && ret == 0)
		ret = t_ret;

#ifdef HAVE_WILDCARD_SUPPORT
	if (op == WC || op == NWC)
		regfree(&preq);
#endif

	return (ret);
}
Example #3
0
enum jaldb_status jaldb_iterate_by_timestamp(jaldb_context *ctx,
        enum jaldb_rec_type type,
        const char *timestamp,
        jaldb_iter_cb cb, void *up)
{
    enum jaldb_status ret = JALDB_E_INVAL;
    struct tm target_time, record_time;
    memset(&target_time, 0, sizeof(target_time));
    memset(&record_time, 0, sizeof(record_time));
    int target_ms = 0;
    int record_ms = 0;
    char *tmp_time = NULL;
    struct jaldb_record *rec = NULL;
    int byte_swap = 0;
    struct jaldb_record_dbs *rdbs = NULL;
    int db_ret = 0;
    DBT key;
    DBT pkey;
    DBT val;
    DBC *cursor = NULL;
    memset(&key, 0, sizeof(key));
    memset(&pkey, 0, sizeof(pkey));
    memset(&val, 0, sizeof(val));
    key.flags = DB_DBT_REALLOC;
    val.flags = DB_DBT_REALLOC;
    time_t target_secs = 0;

    tmp_time = strptime(timestamp, "%Y-%m-%dT%H:%M:%S", &target_time);
    if (!tmp_time) {
        fprintf(stderr, "ERROR: Invalid time format specified.\n");
        ret = JALDB_E_INVAL_TIMESTAMP;
        goto out;
    }

    if (!sscanf(tmp_time,".%d-%*d:%*d", &target_ms)) {
        fprintf(stderr, "ERROR: Invalid time format specified.\n");
        ret = JALDB_E_INVAL_TIMESTAMP;
        goto out;
    }
    // Calculate the target time in secs once before we start looping
    target_secs = mktime(&target_time);

    if (!ctx || !cb) {
        ret = JALDB_E_UNINITIALIZED;
        goto out;
    }

    switch(type) {
    case JALDB_RTYPE_JOURNAL:
        rdbs = ctx->journal_dbs;
        break;
    case JALDB_RTYPE_AUDIT:
        rdbs = ctx->audit_dbs;
        break;
    case JALDB_RTYPE_LOG:
        rdbs = ctx->log_dbs;
        break;
    default:
        ret = JALDB_E_INVAL_RECORD_TYPE;
        goto out;
    }

    if (!rdbs) {
        ret = JALDB_E_UNINITIALIZED;
        goto out;
    }

    // Use the record creation time database
    db_ret = rdbs->timestamp_idx_db->get_byteswapped(rdbs->timestamp_idx_db, &byte_swap);
    if (0 != db_ret) {
        ret = JALDB_E_INVAL;
        goto out;
    }

    db_ret = rdbs->timestamp_idx_db->cursor(rdbs->timestamp_idx_db, NULL, &cursor, DB_DEGREE_2);
    if (0 != db_ret) {
        JALDB_DB_ERR(rdbs->timestamp_idx_db, db_ret);
        ret = JALDB_E_INVAL;
        goto out;
    }

    while(0 == db_ret) {
        db_ret = cursor->c_pget(cursor, &key, &pkey, &val, DB_NEXT);
        if (0 != db_ret) {
            if (DB_NOTFOUND == db_ret) {
                ret = JALDB_OK;
            } else {
                JALDB_DB_ERR(rdbs->timestamp_idx_db, db_ret);
                ret = JALDB_E_INVAL;
            }
            goto out;
        }

        // mktime() like to set things like timezone to system timezone - need to clean out the tm struct before each call
        memset(&record_time, 0, sizeof(record_time));

        tmp_time = strptime((char*) key.data, "%Y-%m-%dT%H:%M:%S", &record_time);
        if (!tmp_time) {
            fprintf(stderr, "ERROR: Cannot get strptime from record\n");
            ret = JALDB_E_INVAL_TIMESTAMP;
            goto out;
        }

        if (!sscanf(tmp_time,".%d-%*d:%*d", &record_ms)) {
            ret = JALDB_E_INVAL_TIMESTAMP;
            goto out;
        }

        double delta = difftime(target_secs,mktime(&record_time));
        if (delta < 0) {
            // record_time is > target_time, so break out
            goto out;
        }

        if (delta == 0) {
            if (record_ms > target_ms) {
                goto out;
            }
        }

        ret = jaldb_deserialize_record(byte_swap, (uint8_t*) val.data, val.size, &rec);
        if (ret != JALDB_OK) {
            goto out;
        }

        switch (cb((char*) pkey.data, rec, up)) {
        case JALDB_ITER_CONT:
            break;
        case JALDB_ITER_REM:
            // Need to close cursor before removing record
            cursor->c_close(cursor);
            cursor = NULL;

            ret = jaldb_remove_record(ctx, type, (char*) pkey.data);
            if (JALDB_OK == ret) {
                ret = jaldb_remove_segments_from_disk(ctx, rec);
            }
            if (ret != JALDB_OK) {
                // something went wrong...
                goto out;
            }

            db_ret = rdbs->timestamp_idx_db->cursor(rdbs->timestamp_idx_db, NULL, &cursor, DB_DEGREE_2);
            if (0 != db_ret) {
                JALDB_DB_ERR(rdbs->timestamp_idx_db, db_ret);
                ret = JALDB_E_INVAL;
                goto out;
            }
            break;
        default:
            goto out;
        }

        jaldb_destroy_record(&rec);
    }

out:
    if (cursor) {
        cursor->c_close(cursor);
    }

    jaldb_destroy_record(&rec);

    free(key.data);
    free(val.data);
    return ret;
}
Example #4
0
File: dbdump.C Project: Amit-DU/dht
// }}}
// {{{ dumpall: Dump all db key metadata
static int
dumpall (bool bytime)
{
  adb_master_metadata_t mmd;
  bzero (&mmd, sizeof (mmd));

  DBT begin_time, key, data;
  u_int64_t totalsz = 0;
  unsigned keys = 0;

  int r = 0;

  DBC *cursor;
  if (bytime) 
    r = byexpiredb->cursor (byexpiredb, NULL, &cursor, 0);
  else 
    r = metadatadb->cursor (metadatadb, NULL, &cursor, 0);
  if (r) {
    warn << "cursor error: " << r << " " << db_strerror (r) << "\n";
    return r;
  }

  for (int i = 0; ; i++) {
    bzero (&begin_time, sizeof (begin_time));
    bzero (&key, sizeof (key));
    bzero (&data, sizeof (data));
    if (bytime)
      r = cursor->c_pget (cursor, &begin_time, &key, &data, DB_NEXT);
    else 
      r = cursor->c_get (cursor, &key, &data, DB_NEXT);
    if (r == DB_NOTFOUND) {
      aout << "EOF.\n";
      r = 0;
      break;
    } else if (r) {
      warn << "error: " << r << " " << db_strerror (r) << "\n";
      break;
    }
    if (key.size != sha1::hashsize) {
      buf2xdr (mmd, data.data, data.size);
      continue;
    }

    chordID k;
    mpz_set_rawmag_be (&k, static_cast<char *> (key.data), key.size);

    adb_metadata_t md;
    buf2xdr (md, data.data, data.size);

    aout << "key[" << i << "] " << k << " " << md.size << " " << md.expiration << "\n";

    keys++;
    totalsz += md.size;
    
    aout->flush ();
  }
  cursor->c_close (cursor);

  aout << "total keys: " << keys << "\n";
  aout << "total bytes: " << totalsz << "\n";
  if (totalsz != mmd.size)
    warn << "Master metadata total bytes error: " << mmd.size << "\n";

  return r;
}