Code Examples

Here are two related code examples. The first one is a C file used to read and write an RMS index file that was used to do session management for a website. The second one is the H file that defines the data scructures used by the C file.

SESDB.C

    
/*                                                                         */
/* Routines to handle SESDB (session tracking DB) functions                */
/*                                                                         */
#include "sesdb_proto.h"
#include "ttdb_db.h"
#include "ttdb_db_proto.h"
#include "ttdb_msg.h"
#include 
#include 
#include 

struct DGS_SESDB_REC Sesdb_rec;

/*                                                                         */
/*  Create a new sesdb rec.  Check to see if the passed in id is in use    */
/*  if not, then create one.  If the id is in use, then this routine does  */
/*  nothing but a successful get.                                          */
/*                                                                         */
ulong sesdb_create_new
   (
   char *new_id
   )
   {
   time_t now;
   ulong  status;

   if ( new_id == NULL) return( TTDB__SESNULLINP);
   if ( strlen( new_id) > SESDB_K_MAXIDLEN) return( TTDB__SESTOOLONG);

   status = tt_db_lookup( DBF_K_SESDB_IDX, DBF_K_DB_KEY_PRI, 
                          new_id, DBF_K_DB_MAT_EQ);
   if LSB_CLR( status)
      {
      if ( status != TTDB__DBRNF) 
         return( status);
      now = time( 0);
      status = tt_db_set_sesdb_rec( new_id, NULL, NULL, 
                                    &now, &now, NULL, TRUE);
      if LSB_CLR( status) return( status);
      status = tt_db_put( DBF_K_SESDB_IDX);
      }
   return( status);
   }

/*                                                                         */
/* Update the user_id associated with this session.  Also, since they are  */
/* changing something in the sesdb rec for this session update last_time   */
/*                                                                         */
ulong sesdb_update_user_id
   (
   char *id,          /* session id to update  */
   ulong new_user_id  /* new value for user_id */
   )
   {
   time_t now;
   ulong  status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   now = time( 0);
   status = tt_db_set_sesdb_rec( id, &new_user_id, NULL, 
                                 NULL, (ulong *) &now, NULL, FALSE);
   if LSB_CLR( status) return( status);
   status = tt_db_update( DBF_K_SESDB_IDX);
   return( status);
   }

/*                                                                         */
/* Update the logged_in field for this session record.  Also, since they   */
/* updating the record, update the last_time field, too.                   */
/*                                                                         */
ulong sesdb_update_logged_in
   (
   char *id,            /* session id to update    */
   ulong new_logged_in  /* new value for logged_in */
   )
   {
   time_t now;
   ulong  status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   now = time( 0);
   status = tt_db_set_sesdb_rec( id, NULL, &new_logged_in,
                                 NULL, (ulong *) &now, NULL, FALSE);
   if LSB_CLR( status) return( status);
   status = tt_db_update( DBF_K_SESDB_IDX);
   return( status);
   }

/*                                                                         */
/* Update the init_time field for this session record.  In this case we    */
/* will also update the last_time to match to keep from having a situation */
/* where last_time is less than init_time.                                 */
/*                                                                         */
ulong sesdb_update_init_time
   (
   char *id,            /* session id to update    */
   ulong new_init_time  /* new value for init_time */
   )
   {
   ulong status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   status = tt_db_set_sesdb_rec( id, NULL, NULL, 
                                 &new_init_time, &new_init_time, NULL, FALSE);
   if LSB_CLR( status) return( status);
   status = tt_db_update( DBF_K_SESDB_IDX);
   return( status);
   }

/*                                                                         */
/* Update the last_time field for the sesdb record.  We'll ignore the      */
/* SESEXPIRED error, since we're updating the last_time field anyway,      */
/* which may cause the session to be unexpired.                            */
/*                                                                         */
ulong sesdb_update_last_time
   (
   char *id,            /* session id to update    */
   ulong new_last_time  /* new value for last_time */
   )
   {
   ulong status;

   status = sesdb_find( id);
   if ( LSB_CLR( status) && ( status != TTDB__SESEXPIRED)) return( status);
   status = tt_db_set_sesdb_rec( id, NULL, NULL, 
                                 NULL, &new_last_time, NULL, FALSE);
   if LSB_CLR( status) return( status);
   status = tt_db_update( DBF_K_SESDB_IDX);
   return( status);
   }

/*                                                                         */
/* Update the iter field for the session record, as well as the last_time  */
/* field.                                                                  */
/*                                                                         */
ulong sesdb_update_iter
   (
   char *id,       /* session id to update */
   ulong new_iter  /* new value for iter   */
   )
   {
   time_t now;
   ulong  status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   now = time( 0);
   status = tt_db_set_sesdb_rec( id, NULL, NULL, 
                                 NULL, (ulong *) &now, &new_iter, FALSE);
   if LSB_CLR( status) return( status);
   status = tt_db_update( DBF_K_SESDB_IDX);
   return( status);
   }

/*                                                                         */
/*                                                                         */
/*                                                                         */
ulong sesdb_get_user_id
   (
   char  *id,      /* session id to find       */
   ulong *user_id  /* return value for user_id */
   )
   {
   ulong status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   status = tt_db_get_sesdb_rec( &Sesdb_rec);
   if LSB_CLR( status) return( status);
   *user_id = Sesdb_rec.user_id;
   return( status);
   }

/*                                                                         */
/*                                                                         */
/*                                                                         */
ulong sesdb_get_logged_in
   (
   char  *id,        /* session id to find         */
   ulong *logged_in  /* return value for logged_in */
   )
   {
   ulong status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   status = tt_db_get_sesdb_rec( &Sesdb_rec);
   if LSB_CLR( status) return( status);
   *logged_in = Sesdb_rec.logged_in;
   return( status);
   }

/*                                                                         */
/*                                                                         */
/*                                                                         */
ulong sesdb_get_init_time
   (
   char  *id,        /* session id to find         */
   ulong *init_time  /* return value for init_time */
   )
   {
   ulong status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   status = tt_db_get_sesdb_rec( &Sesdb_rec);
   if LSB_CLR( status) return( status);
   *init_time = Sesdb_rec.init_time;
   return( status);
   }

/*                                                                         */
/*                                                                         */
/*                                                                         */
ulong sesdb_get_last_time
   (
   char  *id,        /* session id to find         */
   ulong *last_time  /* return value for last_time */
   )
   {
   ulong status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   status = tt_db_get_sesdb_rec( &Sesdb_rec);
   if LSB_CLR( status) return( status);
   *last_time = Sesdb_rec.last_time;
   return( status);
   }

/*                                                                         */
/*                                                                         */
/*                                                                         */
ulong sesdb_get_iter
   (
   char  *id,   /* session id to find    */
   ulong *iter  /* return value for iter */
   )
   {
   ulong status;

   status = sesdb_find( id);
   if LSB_CLR( status) return( status);
   status = tt_db_get_sesdb_rec( &Sesdb_rec);
   if LSB_CLR( status) return( status);
   *iter = Sesdb_rec.iter;
   return( status);
   }

/*                                                                         */
/*  Lookup the record for this session based on the id passed in.  Since   */
/*  the protocol is stateless, we can't count on having a global variable  */
/*  to play with to maintain information.  If the record isn't there       */
/*  return SESNOTFOUND.  Is there, then check for a timeout.               */
/*                                                                         */
ulong sesdb_find
   (
   char *id
   )
   {
   time_t now;
   ulong  status;
   long   elapsed;

   if ( id == NULL) return( TTDB__SESNULLINP);
   if ( strlen( id) > SESDB_K_MAXIDLEN) return( TTDB__SESTOOLONG);

   status = tt_db_lookup( DBF_K_SESDB_IDX, DBF_K_DB_KEY_PRI,
                          id, DBF_K_DB_MAT_EQ);
   if ( status == TTDB__DBRNF) return( TTDB__SESNOTFOUND);
   if LSB_CLR( status) return( status);
   status = tt_db_get_sesdb_rec( &Sesdb_rec);
   if LSB_CLR( status) return( status);
   now = time( 0);
   elapsed = now - Sesdb_rec.last_time;
   if ( elapsed > SESDB_K_TIMEOUTS) return( TTDB__SESEXPIRED);
   return( SUCCESS);
   }

    
    

TTDB_DB.H

    
#ifndef __TTDB_DB
#define __TTDB_DB 1

#include 
#include "general_c_defs.h"
/*                                                                          */
/*                                                                          */
/* Define constants for the database files                                  */
/*                                                                          */
#define DBF_K_DB_IDX_MIN  0               /* min index for the _DBF array   */

#define DBF_K_MATDB_IDX   0               /* mail addr track idx in _DBF    */
#define DBF_K_MATDB_KEY   2               /* 2 keys: db_id, email           */
#define DBF_K_MATDB_NAM   "MTS_MATDB"     /* matdb logical name for dbf     */
#define DBF_K_MATDB_MRS   128             /* record size                    */
#define DBF_K_MATDB_SIG   "*MATDB V1*"    /* sig in email field, size=56    */

#define DBF_K_MAUIDB_IDX  1               /* mail unique id in _DBF array   */
#define DBF_K_MAUIDB_KEY  1               /* number of keys in name db      */
#define DBF_K_MAUIDB_NAM  "MTS_MAUIDB"    /* mail addr unique id db         */
#define DBF_K_MAUIDB_MRS  512             /* record size                    */
#define DBF_K_MAUIDB_SIG  "*MAUIDB V1*"   /* sig goes in signature, size=11 */

#define DBF_K_UIDB_IDX    2               /* uidb db index in _DBF array    */
#define DBF_K_UIDB_KEY    1               /* number of keys in uidb db      */
#define DBF_K_UIDB_NAM    "MTS_UIDB"      /* uidb db name                   */
#define DBF_K_UIDB_MRS    64              /* record size                    */
#define DBF_K_UIDB_SIG    "*UIDBV1*"      /* sig goes in fill, size=8       */

#define DBF_K_UCTDB_IDX   3               /* uct db index in _DBF array     */
#define DBF_K_UCTDB_KEY   1               /* number of keys in uct db       */
#define DBF_K_UCTDB_NAM   "MTS_UCTDB"     /* uct db name                    */
#define DBF_K_UCTDB_MRS   64              /* record size                    */
#define DBF_K_UCTDB_SIG   "*UCTDB V1*"    /* sig is in fill field           */

#define DBF_K_SRCDB_IDX   4               /* src db index in _DBF array     */
#define DBF_K_SRCDB_KEY   1               /* number of keys in src db       */
#define DBF_K_SRCDB_NAM   "MTS_SRCDB"     /* src db name                    */
#define DBF_K_SRCDB_MRS   64              /* record size                    */
#define DBF_K_SRCDB_SIG   "*SRCDB V1*"    /* sig is in description field    */

#define DBF_K_UPIDB_IDX   5               /* upi db index in _DBF array     */
#define DBF_K_UPIDB_KEY   1               /* number of keys in upi db       */
#define DBF_K_UPIDB_NAM   "MTS_UPIDB"     /* upi db name                    */
#define DBF_K_UPIDB_MRS   640             /* record size                    */
#define DBF_K_UPIDB_SIG   "*UPIDB V1*"    /* sig is in fill field           */

#define DBF_K_LPSDB_IDX   6               /* lps db index in _DBF array     */
#define DBF_K_LPSDB_KEY   1               /* number of keys in lps db       */
#define DBF_K_LPSDB_NAM   "MTS_LPSDB"     /* lps db name                    */
#define DBF_K_LPSDB_MRS   32              /* record size                    */
#define DBF_K_LPSDB_SIG   "*LPSDB V1*"    /* sig is in fill field           */

#define DBF_K_SESDB_IDX   7               /* ses db index in _DBF array     */
#define DBF_K_SESDB_KEY   1               /* number of keys in ses db       */
#define DBF_K_SESDB_NAM   "MTS_SESDB"     /* ses db name                    */
#define DBF_K_SESDB_MRS   64              /* record size                    */
#define DBF_K_SESDB_SIG   "*SESDB V1*"    /* sig is in sessid field         */

#define DBF_K_CCIDB_IDX   8               /* cci db index in _DBF array     */
#define DBF_K_CCIDB_KEY   1               /* number of keys in cci db       */
#define DBF_K_CCIDB_NAM   "MTS_CCIDB"     /* cci db name                    */
#define DBF_K_CCIDB_MRS   256             /* record size                    */
#define DBF_K_CCIDB_SIG   "*CCIDB V1*"    /* sig is in the fill field       */

#define DBF_K_DB_IDX_MAX  8               /* max index for the _DBF array   */

#define DBF_K_DB_MAT_MIN  0               /* min match type for keyed get   */
#define DBF_K_DB_MAT_EQ   0               /* key value should be equal      */
#define DBF_K_DB_MAT_GTE  1               /* key value should be >=         */
#define DBF_K_DB_MAT_GT   2               /* key value should be >          */
#define DBF_K_DB_MAT_MAX  2               /* max match type for keyed get   */

#define DBF_K_DB_KEY_PRI  0               /* handy constant for key index   */
#define DBF_K_DB_KEY_SEC  1               /* secondary key                  */
#define DBF_K_DB_KEY_TER  2               /* tertiary key                   */

#pragma __member_alignment __save
#pragma __nomember_alignment
/*                                                                          */
/*  Database File Def Struct                                                */
/*                                                                          */
static struct DBF
   {
   ushort  dbf_idx;                    /* file index number                 */
   ushort  dbf_key_cnt;                /* number of keys                    */
   ushort  dbf_open;                   /* is it open?                       */
   ushort  dbf_opencnt;                /* how many times has it been opened?*/
   ushort  dbf_recset;                 /* is the record ready for put/upd?  */
   char   *dbf_name;                   /* database logical name             */
   char   *dbf_signature;              /* signature string to match in db   */
   void   *dbf_rec;                    /* ptr to current record struct      */
   } ;
/*                                                                          */
/*  Database Global Struct                                                  */
/*                                                                          */
struct DGS
   {
   ulong  dgs_inited;                       /* has dgs struct been inited?  */
   ulong  dgs_prev_db_id;                   /* last get db_id used          */
   struct DBF dgs_dbf[DBF_K_DB_IDX_MAX+1];  /* database file array          */
   } ;

/*                                                                          */
/* Mail Address Tracking Database layout.  Main database of email addresses */
/* The db_id is kept in the MAUIDB (see below).  Since we expect to have >  */
/* than 100M email addresses, the aim is to keep this small.  If email lens */
/* >= 88 are encountered, split them into another file.                     */
/*                                                                          */
#define  MATDB_K_MAXELEN  88  /* maximum acceptable email address length    */
struct DGS_MATDB_REC
   {
   ulong db_id;               /* key 0, no dup, insert cnt                  */
   ulong init_status;         /* initial delivery status                    */
   ulong last_status;         /* last delivery status, see values below     */
   ulong source;              /* where'd we get this email address?         */
   uquad init_time;           /* when was the initial send done?            */
   uquad last_time;           /* when was last_status updated?              */
   ulong flag;                /* handy flag that might be used later        */
   ulong back_link;           /* set to the db_id of previous email rec if  */
                              /* this is a changed email address            */
   char  email[MATDB_K_MAXELEN]; /* key 1, nodup, len > max rejected        */
   } ;
/*                                                                          */
/* Mail Address Tracking delivery status values                             */
/*                                                                          */
#define  MATDB_K_NOACTION       0  /* no attempt has been made to this addr */
#define  MATDB_K_SENT_OK        1  /* no error occured during initial send  */
#define  MATDB_K_RELAY_REJECT   2  /* rejected for relay reasons            */
#define  MATDB_K_SPAM_REJECT    3  /* rejected for spam reasons             */
#define  MATDB_K_NOHOST_REJECT  4  /* host name invalid                     */
#define  MATDB_K_INVADDR_REJECT 5  /* user address invalid, host OK         */
#define  MATDB_K_TIMEOUT_REJECT 6  /* connection to host timed out          */
#define  MATDB_K_REMOVE_REQ     7  /* explicit remove request received      */
#define  MATDB_K_RESTART_REQ    8  /* explicit restart req rcvd (unremove)  */
#define  MATDB_K_UNSOLICITED    9  /* added by request, set init_status to  */
                                   /* this so sender pgm will skip them     */
#define  MATDB_K_UNKNOWN_ERROR  10 /* There was an error sending that didn't*/
                                   /* fit 2 through 6, above.               */
#define  MATDB_K_MAX_STATUS_VAL 10 /* maximum status value                  */

#define  MATDB_K_FLAG_HOLD      1  /* on hold for what ever reason          */
#define  MATDB_K_FLAG_MGMT      2  /* this email is a tinseltrash manager   */
#define  MATDB_K_FLAG_ISALIAS   4  /* this is an alias use backlink info    */
#define  MATDB_K_MAX_FLAG_VAL   4  /* maximum flag value                    */

/*                                                                          */
/* Mail Address Unique ID Tracking Database layout.  Instead of flailing    */
/* the MATDB to figure out what the next db_id is, we'll just keep it in    */
/* this file.  This file only has the one record, no key, just read and upd */
/* Mass updates can be done by putting an exclusive lock on this file so    */
/* that other programs can't do updates.  That way the mass update only has */
/* to update the MAUIDB at the end of the update.                           */
/*                                                                          */
struct DGS_MAUIDB_REC
   {
   ulong db_id;           /* Next unique matdb id number                    */
   char  signature[12];   /* signature                                      */
   char  fill[496];       /* fill                                           */
   } ;
/*                                                                          */
/* User Information Database layout.  The "username" so to speak is the     */
/* email address for the user.  That is kept in the matdb file, so all we   */
/* need to do is copy the db_id in the matdb file into user_id for keying   */
/* purposes.                                                                */
/*                                                                          */
#define  UIDB_K_MAXPWD  32      /* maximum acceptable password length       */
#define  UIDB_K_MINPWD  4       /* minimum acceptable password length       */
struct DGS_UIDB_REC
   {
   ulong user_id;               /* key 0, no dup, unique user identifier    */
   char  pwd[UIDB_K_MAXPWD];    /* password associated with the user        */
   uquad add_date;              /* when the record was added                */
   uword mail_pref;             /* mail preference (currently unused)       */
   uword gender;                /* male/female/unknown                      */
   uword age_group;             /* age range (see below)                    */
   uword confirmed;             /* did they confirm their email address?    */
   ulong conf_number;           /* conf number generated when record is     */
   char  fill[8];               /* fill to 64                               */
   } ;
#define  UIDB_K_MP_UNKN    0    /* mail preference is unknown               */
#define  UIDB_K_MP_TEXT    1    /* mail preference is plain text            */
#define  UIDB_K_MP_HTML    2    /* mail preference is HTML                  */
#define  UIDB_K_MP_WORD    3    /* mail preference is WORD attachement      */
#define  UIDB_K_MP_MAX     3    /* max mail preference value                */

#define  UIDB_K_GE_UNKN    0    /* Gender field not specified               */
#define  UIDB_K_GE_MALE    1    /* gender set to male                       */
#define  UIDB_K_GE_FEMALE  2    /* gender set to female                     */
#define  UIDB_K_GE_MAX     2    /* gender MAX setting                       */

#define  UIDB_K_AG_UNKN    0    /* Age group unknown                        */
#define  UIDB_K_AG_UN18    1    /* Age group under 18                       */
#define  UIDB_K_AG_1824    2    /* Age group 18-24                          */
#define  UIDB_K_AG_2530    3    /* Age group 25-30                          */
#define  UIDB_K_AG_3140    4    /* Age group 31-40                          */
#define  UIDB_K_AG_4150    5    /* Age group 41-50                          */
#define  UIDB_K_AG_OV50    6    /* Age group over 50                        */
#define  UIDB_K_AG_MAX     6    /* max age group                            */

/*                                                                          */
/* User Chapter Tracking Database layout.  Primary key is a segmented key   */
/* of sorts, it is the user_id combined with the req number.  The req_date  */
/* will track when the chapter was requested, and we'll calc the rel_date   */
/* from that (only one chapter per weekday, ya know).                       */
/*                                                                          */
struct DGS_UCTDB_REC
   {
   union uctdb_key0_union
      {
      uquad key0;
      struct 
         {
         ulong req;       /* chapter requested, second half of pri key      */
         ulong user_id;   /* pri key is UIDB id plus the chapter requested  */
         } usr_req;
      } ku;
   uquad req_date;        /* requested date, when we received the request   */
   uquad rel_date;        /* release date, when we can release the chapter  */
   uquad pay_date;        /* when this chapter was run through pay system   */
   ulong send_flag;       /* send chapter, need to pay msg, or what?        */
   ulong dstatus;         /* status of delivery, see MATDB values above     */
   char  fill[24];        /* fill to 64.                                    */
   } ;
#define  uctdb_key0    ku.key0
#define  uctdb_user_id ku.usr_req.user_id
#define  uctdb_req     ku.usr_req.req
                                        /* Send flag values                 */
#define  UCTDB_K_SF_OK        1         /* Billing OK; send this chapter    */
#define  UCTDB_K_SF_NEEDPAY   2         /* needpay; card isn't there, or bad*/
#define  UCTDB_K_SF_MAX       2         /* max value for the send flag      */

#define  UCTDB_K_LAST_FREE_CHAPTER  5   /* Last free chapter (11/16/01 2->5)*/
/*                                                                          */
/* Source Description Database layout.  Where'd we get this email address?  */
/*                                                                          */
#define  SRCDB_K_MAXSRCDSC  48   /* maximum acceptable description length   */
#define  SRCDB_K_INCOMING   1    /* requested via incoming email source     */
struct DGS_SRCDB_REC
   {
   ulong src_id;                 /* pri key, no dup, unique source code     */
   uquad add_date;               /* when this src code was added            */
   ulong referrer;               /* if not 0, then matdb.db_id of referrer  */
   char  dsc[SRCDB_K_MAXSRCDSC]; /* source description                      */
   } ;
/*                                                                          */
/* User Payment Info layout.  Keeping track of user payment information.    */
/* This tracks the fields that BofA payment services are passing back to us */
/* when we pass them an order.  We'll be passing them info from the ccidb,  */
/* along with other info.  It may be that all these fields are not filled   */
/* as some are exclusively based on transaction status.                     */
/*                                                                          */
#define  UPIDB_K_SIDLEN   42
#define  UPIDB_K_ACLEN     6
#define  UPIDB_K_AVRLEN   10 
#define  UPIDB_K_INVLEN  200
#define  UPIDB_K_REJLEN  100
#define  UPIDB_K_CVVLEN    1
struct DGS_UPIDB_REC
   {
   union upidb_key0_union
      {
      uquad key0;
      struct 
         {
         ulong order;     /* order number is generated by us                */
         ulong user_id;   /* pri key is UIDB id plus the order number       */
         } usr_ord;
      } ku;
   ulong amount;                      /* amount, in cents, of the order     */
   char  shopper_id[UPIDB_K_SIDLEN];  /* ioc_shopper_id                     */
   ulong auth_amount;                 /* ioc_authorization_amount           */
   char  auth_code[UPIDB_K_ACLEN];    /* ioc_authorization_code             */
   char  avs_result[UPIDB_K_AVRLEN];  /* ioc_avs_result                     */
   char  order_id[UPIDB_K_AVRLEN];    /* ioc_order_id                       */
   ulong resp_code;                   /* ioc_response_code                  */
   ulong cvv_indicator;               /* ioc_cvv_indicator = 1,2 or 9       */
   char  cvv_resp_code[UPIDB_K_CVVLEN]; /* ecom_payment_card_verification_rc */
   char  inv_fields[UPIDB_K_INVLEN];  /* ioc_invalid_fields                 */
   char  mis_fields[UPIDB_K_INVLEN];  /* ioc_missing_fields                 */
   char  reject_desc[UPIDB_K_REJLEN]; /* ioc_reject_description             */
   char  fill[48];                    /* fill to 640                        */
   } ;
#define  upidb_key0    ku.key0
#define  upidb_user_id ku.usr_ord.user_id
#define  upidb_order   ku.usr_ord.order
/*                                                                          */
/* Last Paid Status Info layout.  Last time we asked for payment, what was  */
/* the response?                                                            */
/*                                                                          */
struct DGS_LPSDB_REC
   {
   ulong user_id;         /* user id from matdb                             */
   uword ptype;           /* payment type; comp, card, ?                    */
   uword pstatus;         /* payment status last time we checked            */
   uquad cdate;           /* when did we check?                             */
   char  fill[16];        /* fill to 32                                     */
   } ;
#define  LPSDB_K_PT_UNK      0  /* unknown payment type                     */
#define  LPSDB_K_PT_COMP     1  /* payment type complimentary, free for them*/
#define  LPSDB_K_PT_CARD     2  /* paying with a credit card                */
#define  LPSDB_K_PT_MAX      2  /* maximum payment type                     */

#define  LPSDB_K_PS_UNK      0  /* Pay status not set yet                   */
#define  LPSDB_K_PS_OK       1  /* Last payment status was OK               */
#define  LPSDB_K_PS_BAD_CARD 2  /* Invalid credit card info                 */
#define  LPSDB_K_PS_CANCEL   3  /* card deleted or cancelled                */
#define  LPSDB_K_PS_COMPCAN  4  /* comp status cancelled                    */
#define  LPSDB_K_PS_MAX      4  /* maximum pay status                       */
/*                                                                          */
/* Session tracking DB.  Keep track of who is online at the moment.         */
/*                                                                          */
#define  SESDB_K_MAXIDLEN  20    /* maximum acceptable session id length    */
#define  SESDB_K_TIMEOUTS  600   /* seconds until a session times out       */
struct DGS_SESDB_REC
   {
   char  sessid[SESDB_K_MAXIDLEN];  /* unique id from server at first hit   */
   ulong user_id;         /* user id looked up in matdb via email address   */
   ulong logged_in;       /* logged in or not                               */
   ulong init_time;       /* when did they start (time_t not vms uquad time)*/
   ulong last_time;       /* when was the last time they hit the site       */
   ulong iter;            /* handy counter                                  */
   char  fill[24];        /* fill to 64                                     */
   } ;
/*                                                                          */
/* Credit Card Information DB.  This is the minimum information needed for  */
/* a users credit card as defined by BofA.                                  */
/*                                                                          */
/*                                                                          */
#define  CCIDB_K_NAMELEN 50
#define  CCIDB_K_NUMLEN  19
#define  CCIDB_K_PCLEN   20 
#define  CCIDB_K_CCLEN    2
#define  CCIDB_K_CVVLEN   3
struct DGS_CCIDB_REC
   {
   ulong user_id;                      /* primary key is the user id        */
   char  card_name[CCIDB_K_NAMELEN];   /* ecom_payment_card_name            */
                                       /* name as it is on credit card      */
   char  card_number[CCIDB_K_NUMLEN];  /* ecom_payment_card_number          */
   char  street1[CCIDB_K_NAMELEN];     /* ecom_billto_postal_street_line1   */
   char  street2[CCIDB_K_NUMLEN];      /* optional street addr 2            */
   char  city[CCIDB_K_NUMLEN];         /* optional city info                */
   char  state[CCIDB_K_CCLEN];         /* optional state info               */
   char  postcode[CCIDB_K_PCLEN];      /* ecom_billto_postal_postalcode     */
   char  countrycode[CCIDB_K_CCLEN];   /* ecom_billto_postal_countrycode    */
   char  card_CVV2[CCIDB_K_CVVLEN];    /* ecom_payment_card_verification    */
   ulong card_type;                    /* Visa, MC, ?                       */
   ulong expdate_mo;                   /* ecom_payment_card_expdate_month   */
   ulong expdate_yr;                   /* ecom_payment_card_expdate_year    */
   ulong bill_ok;                      /* set if ok to bill checked         */
   ulong age_confirm;                  /* did they check the age ok button? */
   ulong deleted;                      /* set when user "deletes" info      */
   char  fill[44];                     /* fill to 256                       */
   } ;
#define  CCIDB_K_CT_UNKN  0   /* Credit card type is Unknown                */
#define  CCIDB_K_CT_VISA  1   /* Credit card type is Visa                   */
#define  CCIDB_K_CT_MC    2   /* Credit card type is MC                     */
#define  CCIDB_K_CT_MAX   2   /* Maximum value for credit card type field   */

#define  CCIDB_K_EM_UNKN  0   /* Expiration Date, Month,                    */
#define  CCIDB_K_EM_JAN   1   /* Expiration Date, Month, January            */
#define  CCIDB_K_EM_FEB   2   /* Expiration Date, Month, February           */
#define  CCIDB_K_EM_MAR   3   /* Expiration Date, Month, March              */
#define  CCIDB_K_EM_APR   4   /* Expiration Date, Month, April              */
#define  CCIDB_K_EM_MAY   5   /* Expiration Date, Month, May                */
#define  CCIDB_K_EM_JUN   6   /* Expiration Date, Month, June               */
#define  CCIDB_K_EM_JUL   7   /* Expiration Date, Month, July               */
#define  CCIDB_K_EM_AUG   8   /* Expiration Date, Month, August             */
#define  CCIDB_K_EM_SEP   9   /* Expiration Date, Month, September          */
#define  CCIDB_K_EM_OCT  10   /* Expiration Date, Month, October            */
#define  CCIDB_K_EM_NOV  11   /* Expiration Date, Month, November           */
#define  CCIDB_K_EM_DEC  12   /* Expiration Date, Month, December           */
#define  CCIDB_K_EM_MAX  12

#define  CCIDB_K_EY_UNKN  0   /* Expiration Date, Year, Unknown             */
#define  CCIDB_K_EY_2001  1   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2002  2   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2003  3   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2004  4   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2005  5   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2006  6   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2007  7   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2008  8   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2009  9   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_2010 10   /* Expiration Date, Year                      */
#define  CCIDB_K_EY_MAX  10

#pragma __member_alignment __restore

#endif /* __TTDB_DB */