We help IT Professionals succeed at work.

Using the ndbm library

walkerm
walkerm asked
on
Medium Priority
237 Views
Last Modified: 2013-12-26
Does anyone have any experience using the old ndbm library in UNIX?  I have a structure defined something like:
      char key[12];
      typedef struct {
            char name[50];
            char addr[50];
            char phone[12];
      } data;
How do I store and retrieve the data?  I've only used the library for singular strings.

Quick replies will be greatly appreciated.
Comment
Watch Question

Commented:
ndbm uses a structure called a datum to describe both keys and values.  The structure looks like this:

struct datum {
    char *dptr;
    int   dlen;
} ;

When you work with strings, you usually set dptr to point to the string, and dlen is strlen(dptr).  In this case, however, you just set dptr to point to your data structure, and dlen will be sizeof(data).  (Assuming the typedef you gave in the question.  The sizeof will probably be 112.)

So, here's some sample code:

DBM *database = dbm_open( /* filename, flags, etc */ );

char key[12];
data my_data;
datum K;
datum V;

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

strcpy( key, "billgates" );
strcpy( my_data.name, "Bill Gates" );
strcpy( my_data.addr, "Redmond, WA" );
strcpy( my_data.phone, "800-WINDOZE" );

K.dptr = key;
K.dlen = strlen(key);
V.dptr = (char *)(&my_data);
V.dlen = sizeof(my_data);

db_store( database, K, V, DBM_REPLACE );


Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts

Author

Commented:
Thanks. Now I need to use dbm_fetch to retrieve the data (assuming the same structure).

Thanks again

Author

Commented:
Thanks. Now I need to use dbm_fetch to retrieve the data (assuming the same structure).  Please help

Thanks again
dhm

Commented:
Continuing from the db_store() in my example:

V = db_fetch( database, K );

if (V.dptr == 0) { printf( "Not found!\n" ); exit( 0 ); }
if (V.dlen != sizeof(my_data)) { printf( "Wrong data size!\n"; }
memcpy( &my_data, V.dptr, sizeof(my_data) );

printf( "Phone number for %s is %s\n", my_data.name, my_data.phone );

Author

Commented:
I'm getting a segmentation fault on the call to dbm_fetch. I have Digital UNIX V4.0B  (Rev. 564).

Any ideas?
dhm

Commented:
Here's a complete, working program that I compiled on Digital Unix 4.0, using both gcc-2.7.2 and the DEC C compiler.

#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <ndbm.h>
#include <errno.h>
#include <fcntl.h>

typedef struct data {
  char       name[50];
  char       addr[50];
  char       phone[12];
} data;

int
main( int argc, char **argv )
{
  DBM      *database;
  datum       K;
  datum       V;
  char       key[12];
  data       my_data;
  int       result;

  database = dbm_open( "/tmp/test-db", O_RDWR | O_CREAT, 0666 );
  if (database == 0) {
    printf( "Can't open/create database: %d\n", errno );
    exit( errno );
  }

  strcpy( key, "billgates" );
  strcpy( my_data.name, "Bill Gates" );
  strcpy( my_data.addr, "Redmond, WA" );
  strcpy( my_data.phone, "800-WINDOZE" );

  K.dptr = key;
  K.dsize = strlen( key );
  V.dptr = &my_data;
  V.dsize = sizeof(my_data);

  result = dbm_store( database, K, V, DBM_REPLACE );
  printf( "dbm_store result = %d\n", result );

  V.dptr = 0;
  V.dsize = 0;
  V = dbm_fetch( database, K );

  if (V.dptr == 0) {
    printf( "I can't find the key I just inserted!\n" );
  } else {
    if (V.dsize != sizeof(my_data)) {
      printf( "Expected the value for this key to be %d bytes long, not %d\n",
            sizeof(my_data), V.dsize );
    } else {
      memcpy( &my_data, V.dptr, sizeof(my_data) );
      printf( "Name: %s Address %s Phone %s\n",
            my_data.name, my_data.addr, my_data.phone );
    }
  }

  printf( "Now, look for username \"marca\" (expect NOT FOUND)\n" );

  strcpy( key, "marca" );
  K.dptr = key;
  K.dsize = strlen( key );

  V.dptr = 0;
  V.dsize = 0;
  V = dbm_fetch( database, K );

  if (V.dptr == 0) {
    printf( "I can't find the key. (That's good!)\n" );
  } else {
    if (V.dsize != sizeof(my_data)) {
      printf( "Expected the value for this key to be %d bytes long, not %d\n",
            sizeof(my_data), V.dsize );
    } else {
      memcpy( &my_data, V.dptr, sizeof(my_data) );
      printf( "Name: %s Address %s Phone %s\n",
            my_data.name, my_data.addr, my_data.phone );
    }
  }

  dbm_close( database );

  exit( 0 );
}

Author

Commented:
Thank you!!!  That really help me out.
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.