Using the ndbm library

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.
walkermAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

dhmCommented:
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 );


0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
walkermAuthor Commented:
Thanks. Now I need to use dbm_fetch to retrieve the data (assuming the same structure).

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

Thanks again
0
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

dhmCommented:
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 );
0
walkermAuthor Commented:
I'm getting a segmentation fault on the call to dbm_fetch. I have Digital UNIX V4.0B  (Rev. 564).

Any ideas?
0
dhmCommented:
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 );
}

0
walkermAuthor Commented:
Thank you!!!  That really help me out.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.