RSA BSAFE Cert-C

Certificate Components for C

Crypto-C 6.2.1 Developer's Guide
Search

rsadbm.c

Creates, lists, and deletes databases for use with the default RSA Database Service Provider

/* $Id: rsadbm.c,v 1.5 2004/03/02 05:18:39 gsingh Exp $ */
/* rsadbm.c
** Copyright (c) 1999-2003, RSA Security Inc.
**
** This file is used to demonstrate how to interface to an RSA Security
** licensed development product.  You have a royalty-free right to use,
** modify, reproduce and distribute this demonstration file (including
** any modified version), provided that you agree that RSA Security has
** no warranty, implied or otherwise, or liability for this demonstration
** file or any modified version.
**
** This stand-alone sample program can be used to create, list, and delete
** databases for use with the default database service provider.  If neither
** the -c nor the -d options are specified, the utility prints a list of the
** database names defined in the specified directory to stdout.
**
** Usage:  rsadbm [-c name | -d name] [-p path] [-l log]
** Options:  -c name    Used to specify the name of a database to be created.
**           -d name    Used to specify the name of a database to be deleted.
**           -p path    Used to specify the file system path (or directory)
**                      where the database files are stored.  If this option
**                      is omitted, the current working directory is assumed.
**           -l log     Used to specify the file where the error log entries
**                      should be recorded.  If this option is omitted, error
**                      log entries are printed to stderr.
**
** Note that we will not be manipulating the contents of the local database,
** therefore we do not need to register a crypto provider or the default
** database provider.
*/

#include "certc.h"
#include "filelog.h"
#include "rsadb.h"
#include <stdio.h>

#ifdef _MSC_VER
# pragma warning (disable: 171) /* invalid type conversion (often of very similar ptrs) */
#endif

/*  Note that this program expects the certc.msg in the current directory
 *  for the default file log provider.
 */

/*  The number of service providers used in this example.  Here, we must
 *  register a status log provider.
 */
#define SP_COUNT 1

/*  This structure is used to hold information gathered from the command-line
 *  arguments provided by the user.
 */
typedef struct {
  char *dbToCreateName;
  char *dbToDeleteName;
  char *path;
  char *errLogfileName;
} RSADBM_ARGS;

/*  Reads in command line arguments and sets RSADBM_ARGS appropriately.
 *  Any errors that occur during SetOptions needs to go to stderr, since
 *  the log provider won't be registered until after this procedure is called.
 */
static int SetOptions (int argc, char *argv[], RSADBM_ARGS *params);

/*  PrintDBList iterates through the list specified by dbList and prints
 *  out a string corresponding to each member of the list.  A properly
 *  initialized CERTC_CTX must be passed in.
 */
static int PrintDBList (CERTC_CTX ctx, LIST_OBJ dbList);

int main (int argc, char *argv[])
{
  int status = 0;

  RSADBM_ARGS params = {NULL, NULL, NULL, NULL};
  
  CERTC_CTX ctx = NULL;
  
  SERVICE_HANDLER spTable[SP_COUNT];
  POINTER spParams[SP_COUNT];
  FILE_LOG_PARAMS fileLogParams;

  DEFAULT_DB_PARAMS defaultDBParams;
  LIST_OBJ dbList = NULL;
  
  status = SetOptions (argc, argv, &params);
  if (status != 0)
    goto CLEANUP;

  /*  Set up file logging  */
  spTable[0].type = SPT_LOG;
  spTable[0].name = "Default file log";
  spTable[0].Initialize = S_InitializeFileLog;

  /* if this is NULL, the provider uses stderr */
  fileLogParams.logName = params.errLogfileName;
  
  /* format control string file for now assumed to be ./certc.msg */
  fileLogParams.formatName = NULL;

  spParams[0] = (POINTER)&fileLogParams;

  status = C_InitializeCertC (spTable, spParams, SP_COUNT, &ctx);
  if (status != 0)
    goto CLEANUP;

  /* only one of params.dbToCreateName and params.dbToDeleteName should be set
   */
  if (params.dbToCreateName && params.dbToDeleteName) {
    status = C_Log (ctx, E_INVALID_PARAMETER, ST_ERROR, __FILE__, __LINE__,
                    "command line [only one of -c and -d may be specified]");
    goto CLEANUP;
  }

  defaultDBParams.path = params.path;
  defaultDBParams.name = NULL;               /* fill in name later... */
  defaultDBParams.password.data = NULL;      /* password ignored since we're */
  defaultDBParams.password.len = 0;          /* not doing manipulating data  */

  if (params.dbToCreateName) {  /* create a database */
    defaultDBParams.name = params.dbToCreateName;
    status = S_CreateDefaultDB (ctx, &defaultDBParams);
  }
  else if (params.dbToDeleteName) {  /* delete a database */
    defaultDBParams.name = params.dbToDeleteName;
    status = S_DeleteDefaultDB (ctx, &defaultDBParams);
  }
  else {  /* print a list of the database names in a directory */
    status = C_CreateListObject (&dbList);
    if (status != 0)
      goto CLEANUP;
    status = S_GetDefaultDBList (ctx, params.path, dbList);
    if (status != 0)
      goto CLEANUP;
    status = PrintDBList (ctx, dbList);
  }
  if (status != 0)
    goto CLEANUP;
  
CLEANUP:
  /*  If ctx has not been initialized properly, file logging has not been
   *  enabled.
   */
  if (ctx == NULL)
    fprintf (stderr, "rsadbm exiting with status = 0x%x\n", status);

  C_DestroyListObject (&dbList);
  C_FinalizeCertC (&ctx);
  
  return (C_Log (ctx, status, ST_ERROR, __FILE__, __LINE__));
}  /* end main */

/* See function declaration at the top for a description */
int SetOptions (int argc, char *argv[], RSADBM_ARGS *params)
{
  unsigned int c, status = 0;
  
  /* discard the name of the procedure being called (argv[0]) */
  --argc;
  ++argv;

  /*  If the user does not specify a particular option, the appropriate field
   *  in params will be NULL.
   */
  params->dbToCreateName = NULL;
  params->dbToDeleteName = NULL;
  params->path = NULL;
  params->errLogfileName = NULL;
  
  /*  Process command-line arguments  */
  while (argc > 0) {
    /* all arguments must begin with a '-' */
    if (argv[0][0] != '-') {
      fprintf (stderr, "unrecognized option: %s\n", argv[0]);
      status = E_INVALID_PARAMETER;
      break;
    }

    /* get the first character following a '-' */
    c = *++argv[0];
    /* argv[0] is now a string without the '-' */
    if (T_strlen(argv[0]) == 1)
      /* case where exactly one character follows a '-' */
      switch (c) {
        case 'c':  /* name of database to be created */
          --argc;
          ++argv;
          params->dbToCreateName = argv[0];
          --argc;
          ++argv;
          break;
        case 'd':  /* name of database to be deleted */
          --argc;
          ++argv;
          params->dbToDeleteName = argv[0];
          --argc;
          ++argv;
          break;
        case 'p':  /* path to directory where database files are stored */
          --argc;
          ++argv;
          params->path = argv[0];
          --argc;
          ++argv;
          break;
        case 'l':  /* specify file where error log entries should be stored */
          --argc;
          ++argv;
          params->errLogfileName = argv[0];
          --argc;
          ++argv;
          break;
        default:
          status = E_INVALID_PARAMETER;
          fprintf (stderr, "unrecognized option: %s\n", argv[0]);
      }
    else {
      status = E_INVALID_PARAMETER;
      fprintf (stderr, "illegal option: %s\n", argv[0]);
    }
    if (status != 0)
      break;
  }  /* end of while loop for retrieving command-line args */

  /*  If we get an apparently invalid argument  */
  if (status != 0) {
    fprintf (stderr, "Usage:  rsadbm [-c name | -d name] [-p path] ");
    fprintf (stderr, "[-l log]\nOptions\n-c name    Used to specify the ");
    fprintf (stderr, "name of a database to be created.\n-d name    Used ");
    fprintf (stderr, "to specify the name of a database to be deleted.\n-p ");
    fprintf (stderr, "path    Used to specify the file system path (or ");
    fprintf (stderr, "directory)\n           where the database files are ");
    fprintf (stderr, "stored.  If this option\n           is omitted, the ");
    fprintf (stderr, "current working directory is assumed.\n-l log     ");
    fprintf (stderr, "Used to specify the file where the error log entries");
    fprintf (stderr, "\n           should be recorded.  If this option is ");
    fprintf (stderr, "omitted,\n           log entries are printed to ");
    fprintf (stderr, "stderr.\n");
  }

  return status;
}  /* end SetOptions */

/* See function declaration at the top for a description */
int PrintDBList (CERTC_CTX ctx, LIST_OBJ dbList)
{
  int status = 0;

  unsigned int dbListEntries = 0, index = 0;
  POINTER listEntry;

  status = C_GetListObjectCount (dbList, &dbListEntries);
  if (status != 0)
    goto CLEANUP;

  /*  According to the documentation for S_GetDefaultDBList(), which we used
   *  to fill dbList, the LIST_OBJ is filled with null-terminated character
   *  strings.
   */

  for (index = 0; index < dbListEntries; index++) {
    status = C_GetListObjectEntry (dbList, index, &listEntry);
    if (status != 0)
      goto CLEANUP;

    puts ((char *)listEntry);
  }

CLEANUP:
  return (C_Log (ctx, status, ST_ERROR, __FILE__, __LINE__));
}  /* end PrintDBList */

Copyright (c) 1999-2005 RSA Security Inc. All rights reserved. 067-001001-2720-001-000 - 2.7.2