Previous | Next | Contents | Index |
The popstore provides an application program interface (API). With this interface, sites can write their own code to directly create, manipulate, and delete user accounts as well as interface the popstore to billing utilities and other management interfaces.
12.1 Fundamentals
The popstore API is a re-entrant, thread-safe API. User and message
contexts are shared between API client code and the API so as to
facilitate the handling of multiple accounts and messages
simultaneously from either single or multi-threaded programs. Note that
writers of multi-threaded API client code should read Section 12.9.
Access to the underlying profile and message files is controlled and coordinated by the API subroutines. Programs must not attempt to access those files directly. The contexts used by the API are not opaque: clients of the API are provided with structure definitions for those contexts and can view the individual data fields in them. However, these fields must be treated as read only data and must not be changed. Indeed, changes to them generally will not affect the actual on-disk data. To change the actual, underlying on-disk data, call the appropriate API subroutines to effect the desired change.
For C programmers, a C header file declaring basic constants, data
types, structures, and API subroutines in provided. This header file is
the popstore.h
header file and is, on UNIX and NT
platforms, located in the /pmdf/include/
directory. On
OpenVMS platforms, it is located in the PMDF_COM:
directory.
In order to use the popstore API, you must first call the
POPSTORE_init
subroutine so as to initialize the API. When
finished with the API, be sure to call POPSTORE_end
. The
sections 12.2--12.8 provide information and code
examples for performing common tasks. Section 12.12 provides complete
descriptions for each API subroutine. See Section 12.10 for information
on linking programs against the API.
12.2 Creating Accounts
There are two approaches to creating accounts: either create an account
from scratch with no default settings for fields in the account's
profile, or create the account by copying fields from another account
profile and then subsequently changing desired fields in the new
account. Either approach is acceptable; both methods are described
below. The advantage to the latter approach is that by copying the
default
account, the site's default account settings are
used as an initial basis for the new account.
12.2.1 From Scratch
The subroutines POPSTORE_user_create_set
and
POPSTORE_user_create
are used to create an account from
scratch. With a variable of type
POPSTORE_user_context *user_context |
NULL
, make successive calls to
POPSTORE_user_create_set
to set values for the account to
be created. The username field must be set, and it is always a good
idea to set a password too unless you genuinely want the account to
require no password to access it. After setting the desired fields,
call POPSTORE_user_create
to actually create the account
and dispose of the context created by the first call to
POPSTORE_user_create_set
. That call will write to disk the
profile file for the account and create an entry in the user database.
If the username for the account conflicts with another existing
account, the account will not be created and a
POPSTORE_USEREXISTS
error will be returned.
Note that the POPSTORE_user_create_set
subroutine will not
allow the MANAGE
usage flag to be set or cleared without
first calling POPSTORE_manage
to explicitly authorize such
actions. (cleared). Note further that regardless of any value set for
the last billing field, that field will be set to the current date and
time when POPSTORE_user_create
is called.
An example program which creates the profile
# pmdf popstore show joe Username: joe Owner: Joe User Group: staff Store Type: popstore Usage flags: Site-defined: Last pwd change: No time recorded Last connect: No time recorded Last disconnect: No time recorded Total connect time: 0 00:00:00 Total connections: 0 Past block days: 0 Last billing: Tue Nov 19 10:25:18 2012 Message count: 0 (0 total messages received) Quota used: 0.00 Kbytes Primary quota: 90.00 Kbytes Overdraft quota: 10.00 Kbytes |
POPSTORE_initialize
.
POPSTORE_user_add
.
Example 12-1 Creating a New Account from Scratch |
---|
/****************************************************************** * * * create_sample.c * * Sample subroutine to create a popstore account from scratch. * * * ******************************************************************/ #include <stdio.h> #include <stdlib.h> #ifdef __VMS # include "pmdf_com:popstore.h" #else # include "/pmdf/include/popstore.h" #endif void check (int stat) (1) { if (stat == POPSTORE_SUCCESS) return; fprintf (stderr, "Error %d: %s\n", stat, POPSTORE_error_to_text (stat)); (void) POPSTORE_end (); exit (1); } main () { POPSTORE_user_context *ctx; /* * Initialize the popstore */ check (POPSTORE_init (1, NULL, "create_sample", 13)); (2) /* * Set values for various fields */ ctx = NULL; check (POPSTORE_user_create_set (&ctx, POPSTORE_SET_USERNAME, 3, "joe")); (3) check (POPSTORE_user_create_set (&ctx, POPSTORE_SET_GROUP_NAME, 5, "staff")); check (POPSTORE_user_create_set (&ctx, POPSTORE_SET_OWNER, 10, "Joe User")); check (POPSTORE_user_create_set (&ctx, POPSTORE_SET_PASSWORD, 6, "secret")); check (POPSTORE_user_create_set (&ctx, POPSTORE_SET_QUOTA, 1024*90)); check (POPSTORE_user_create_set (&ctx, POPSTORE_SET_OVERDRAFT, 1024*10)); /* * Create the account */ check (POPSTORE_user_create (&ctx)); (4) /* * All done */ (void) POPSTORE_end (); (5) } |
12.2.2 By Copying
New accounts can also be created by copying an old account with the
POPSTORE_user_copy_d
subroutine and then changing the
value of fields with POPSTORE_user_update
. For instance,
both of the popstore management interfaces create new accounts by
copying the default
account to the new account and then
changing the requested fields in the new account.
Note that the POPSTORE_user_update
subroutine will not
allow the MANAGE
usage flag can not be set or cleared
without first calling POPSTORE_manage
to explicitly
authorize such actions.
The code in Example 12-2 creates the account joe
by first
copying the default
account and then changing fields in
the newly created joe
account with
POPSTORE_user_update
. The account so created is identical
to that created from scratch in Example 12-1. The following items of
note are identified with callouts in the example program:
POPSTORE_initialize
.
default
account except for the username and
password fields.
Example 12-2 Creating a New Account by
Copying the default Account |
---|
/****************************************************************
* *
* copy_sample.c *
* Sample subroutine to create a popstore account by copying *
* the default account. *
* *
****************************************************************/
#include <stdio.h>
#include <stdlib.h>
#ifdef __VMS
# include "pmdf_com:popstore.h"
#else
# include "/pmdf/include/popstore.h"
#endif
static POPSTORE_user_context *user_context = NULL;
void check (int stat) (1)
{
if (stat == POPSTORE_SUCCESS) return;
fprintf (stderr, "Error %d: %s\n", stat, POPSTORE_error_to_text (stat));
if (user_context) (void) POPSTORE_user_end (user_context);
(void) POPSTORE_end ();
exit (1);
}
#define PUSH(list,code,addr,len) \ (2)
list[item_index].item_code = (code); \
list[item_index].
|
12.3 Modifying Accounts
Fields in an existing account can be modified using the
POPSTORE_user_update
subroutine. This subroutine accepts
as input a user context created by POPSTORE_user_begin_d
and an item list describing the fields to change and the new values to
use for those fields. Before making any changes, the validity of the
entries in the item list is first determined. Only if the entries are
all correct, are any changes then made. The changes are made
atomically: the profile is locked, read, all changes made, written back
to disk, and then unlocked. In the event of an unexpected error, the
old profile data is restored if possible.
An example of using POPSTORE_user_update
is given in
Example 12-2. When modifying accounts, keep the following notes in
mind:
POPSTORE_user_update
. To change that field, use
POPSTORE_user_copy_d
specifying a non-zero value for the
do_rename argument of that subroutine.
MANAGE
flag can only be set or cleared if a prior
call to POPSTORE_manage
has been made which enables the
ability to set that bit.
M
to the value N
, then the oldest M-N
messages are deleted (e.g., when M=N
, all
messages are deleted). Note that unread deleted messages are simply
deleted: they are not returned to their originator. If they should
instead be returned, use POPSTORE_message_return
.
POPSTORE_user_pw_change_d
.
12.4 Deleting Accounts
Accounts are deleted with POPSTORE_user_delete_d
. When an
account is deleted, any unread messages for that account can optionally
be returned to their originators. Shown below is the call which would
be made to delete the account jdoe
, returning any unread
messages to their originators:
stat = POPSTORE_user_delete_d ("jdoe", 4, 1); |
12.5 Listing Accounts
Formatted listings of accounts can be generated with the
POPSTORE_format_profiles_d
procedure. Note that this same
functionality is provided at the command line with the
POPSTORE
utility; see Chapter 9 for details. In order
to use POPSTORE_format_profiles_d
, you must first decide
upon a layout for the listing and then implement that layout with a
formatting file. See the description of the
POPSTORE_format_profiles_d
subroutine for further details.
Once a formatting file has been developed, it can then be used to
format listings of user accounts. In the example code shown in
Example 12-4, an actual formatting file used by the
POPSTORE
utility is used. That formatting file, as can be
seen in Example 12-3, lists for each account the username, stored
message count, and used quota.
Example 12-3 Formatting File for Account Listings |
---|
%first{ Message Quota used} %first{ Username Count (kbytes)} %first{ ------------------------------------------------------} %flags_manage{ |*}%username{%-32s} %message_count{%7u} %quota_used_k{%8.2f} %last{ ----------------------------------------------------------------} %last{*Note: privileged users are flagged with an asterisk} |
Example 12-4 Generating Account Listings |
---|
/*************************************************************** * * * format_sample.c * * Sample subroutine to generate an account listing. * * * ***************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef __VMS # include "PMDF_COM:popstore.h" #else # include "/pmdf/include/popstore.h" #endif void check (int stat) { if (stat == POPSTORE_SUCCESS) return; fprintf (stderr, "Error %d: %s\n", stat, POPSTORE_error_to_text (stat)); (void) POPSTORE_end (); exit (1); } int output (void *ctx, char *line, int len, int eol, int literal) { if (!eol) printf ("%.*s", len, line); else printf ("%.*s\n", len, line); return (POPSTORE_SUCCESS); } main () { POPSTORE_format_element *format; /* * Initialize the popstore */ check (POPSTORE_init (0, NULL, "format_sample", 13)); /* * Read in the formatting file and get a formatting context */ check (POPSTORE_format_read (&format, "popmgr_profile_brief.txt", 24, #ifdef __VMS "PMDF_HTTP_POPSTORE:[000000]", 27)); #else "/pmdf/www/popstore/", 19)); #endif /* * Display the profiles */ check (POPSTORE_format_profiles_d (format, NULL, 0, NULL, 0, NULL, 0, NULL, NULL, output)); /* * Dispose of the formatting context */ check (POPSTORE_format_dispose (format)); /* * All done */ (void) POPSTORE_end (); } |
To generate a simple listing of accounts, the
POPSTORE_user_list_d
subroutine can prove sufficient. That
subroutine is primarily intended for cases where a program needs to
obtain one-by-one the usernames for each account. Sample code using
POPSTORE_user_list_d
to list all accounts and then the
first account with a username starting with the letter "z" is
given in Example 12-5.
Example 12-5 Simple Account Listing |
---|
/*************************************************************** * * * list_sample.c * * Sample subroutine to generate an account listing. * * * ***************************************************************/ #include <stdio.h> #ifdef __VMS # include "PMDF_COM:popstore.h" #else # include "/pmdf/include/popstore.h" #endif main () { POPSTORE_list_context *list_context; int stat, userlen; char user[POPSTORE_MAX_USER_LEN+1]; /* * Initialize the popstore */ stat = POPSTORE_init (1, NULL, "list_sample", 11); if (stat != POPSTORE_SUCCESS) exit (1); /* * List all accounts */ printf ("---- Listing of all accounts ----\n"); list_context = NULL; stat = POPSTORE_SUCCESS; while (stat == POPSTORE_SUCCESS) { stat = POPSTORE_user_list_d (&list_context, "*", 1, NULL, 0, NULL, 0, user, &userlen, POPSTORE_MAX_USER_LEN + 1); if (stat == POPSTORE_SUCCESS) printf ("%s\n", user); } printf ("\n---- The first account starting with the letter \"z\" ----\n"); list_context = NULL; stat = POPSTORE_user_list_d (&list_context, "z*", 2, NULL, 0, NULL, 0, user, &userlen, POPSTORE_MAX_USER_LEN + 1); if (stat == POPSTORE_SUCCESS) { printf ("%s\n", user); /* Done with this context; dispose of it now */ (void) POPSTORE_user_list_abort (&list_context); } else printf ("**** No accounts begin with the letter \"z\" ****\n"); /* * All done */ (void) POPSTORE_end (); } |
12.6 Billing Accounts
Sites who want to bill users for usage should use the
POPSTORE_user_billing_d
subroutine to perform
"atomic" billing operations. That subroutine locks a user
profile, extracts billing information, resets accounting fields, writes
the user profile back to disk, unlocks the profile, and then returns
the extracted billing information to the caller.
The billing period is the intervening time between when
POPSTORE_user_billing_d
was last called and the current
billing time supplied to POPSTORE_user_billing_d
. The time
when POPSTORE_user_billing_d was last called is stored in each
account's last billing profile field.1
The extracted billing information includes the total connect time and
past block days of message storage used during the billing period.
After that information is extracted, those two fields are set to the
value zero. In addition, the last billing time fields in the profile
and message list are set to the new billing time supplied to
POPSTORE_user_billing_d
, and this data is then written out
to the on-disk profile file.
Example 12-6 shows sample code which uses
POPSTORE_user_billing_d
in conjunction with
POPSTORE_user_list_d to bill each account whose associated username
starts with the letter "a" and is in the
students
management group.
Example 12-6 Account Billing Operations |
---|
/*************************************************************** * * * bill_sample.c * * Sample subroutine to bill each popstore account. * * * ***************************************************************/ #include <stdio.h> #include <times.h> #ifdef __VMS # include "PMDF_COM:popstore.h" #else # include "/pmdf/include/popstore.h" #endif main () { time_t billing_time; POPSTORE_user_data data; POPSTORE_list_context *list_context; int stat, stat2, userlen; char user[POPSTORE_MAX_USER_LEN + 1]; /* * Initialize the popstore */ stat = POPSTORE_init (1, NULL, "list_sample", 11); if (stat != POPSTORE_SUCCESS) exit (1); /* * Output a heading */ printf (" Connect Block\n"); printf ("Username Time Days\n"); printf ("-------------------------------- ------- -------\n"); /* * Now, loop over each account and bill it */ billing_time = time (NULL); list_context = NULL; do { stat = POPSTORE_user_list_d (&list_context, "a", 1, NULL, 0, "students", 8, user, &userlen, POPSTORE_MAX_USER_LEN + 1); if (stat == POPSTORE_SUCCESS) { stat2 = POPSTORE_user_billing_d (NULL, 0, user, userlen, billing_time, &data); if (stat2 == POPSTORE_SUCCESS) { printf ("%-32s %7u %7u\n", user, data.total_connect, data.past_block_days); } else { fprintf (stderr, "Unable to bill %.*s; error = %d\n", userlen, user, stat2); fprintf (stderr, "%s\n", POPSTORE_error_to_text (stat2)); } } } while (stat == POPSTORE_SUCCESS); if (stat != POPSTORE_EOM) { fprintf (stderr, "POPSTORE_user_list_d returned the error %d\n", stat); fprintf (stderr, "%s\n", POPSTORE_error_to_text (stat)); } /* * All done */ (void) POPSTORE_end (); } |
1 For new accounts, that field is initialized to the time at which the account was created. |
To store a message into the message store, enqueue it as a mail message to PMDF with the desired popstore recipients given as the message's envelope To: recipients. See the PMDF Programmer's Reference Manual for information on using the PMDF API to enqueue messages to PMDF.
12.8 Accessing Messages
A user's messages are accessed by first obtaining a user context,
user_context
, with POPSTORE_user_begin_d
. The
list of stored messages is the array of
POPSTORE_message_ref
structures which start at the address
user_context->messages |
user_context->profile->message_count |
sue
:
Example 12-7 Message Lists |
---|
int i, new_count, stat; POPSTORE_message_ref *msg_ptr; POPSTORE_user_context *user_context; ... stat = POPSTORE_user_begin_d (&user_context, "sue", 3, POPSTORE_NOACCOUNTING, "new message count", 17); new_count = 0; for (i = 0, msg_ptr = user_context->messages; i < user_context->profile->message_count; i++, msg_ptr++) if (!(msg_ptr->flags & POPSTORE_MFLAGS_READ)) new_count++; stat = POPSTORE_user_end (user_context); printf ("Sue has %d new messages\n", new_count); ... |
Individual messages are accessed and manipulated with the
POPSTORE_message
subroutines. When accessing or
manipulating a message, the message is referenced using its
"message index". The first message stored for a user has
message index value 1
, the second index value
2
, the third index value 3
, and so on.
The code shown in Example 12-8 displays each new message for the user
sue
, marking each message as read after displaying it.
Example 12-8 Displaying New Messages |
---|
/*************************************************************** * * * read_sample.c * * Sample subroutine to display new messages for an account. * * * ***************************************************************/ #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef __VMS # include "pmdf_com:popstore.h" #else # include "/pmdf/include/popstore.h" #endif void check (int stat) { if (stat == POPSTORE_SUCCESS) return; fprintf (stderr, "Error %d: %s\n", stat, POPSTORE_error_to_text (stat)); (void) POPSTORE_end (); exit (1); } void display_message (POPSTORE_user_context *user_context, int msg_index) { char buffer[1024+1]; int len, message_context, stat; printf ("=========================================================\n"); printf ("Message %d\n", msg_index); printf ("=========================================================\n"); if (POPSTORE_SUCCESS != POPSTORE_message_begin (user_context, msg_index, &message_context, NULL, 0, NULL, 0)) return; do { stat = POPSTORE_message_read (message_context, buffer, 1024, &len); if (stat != POPSTORE_READERROR) { buffer[len] = '\0'; printf ("%s", buffer); } } while (stat == POPSTORE_SUCCESS); (void) POPSTORE_message_end (message_context); printf ("=========================================================\n"); } main () { POPSTORE_message_ref *msg_ptr; int i, stat; POPSTORE_user_context *user_context; /* * Initialize the popstore */ check (POPSTORE_init (1, NULL, "read_sample", 11)); /* * Access the popstore account */ check (POPSTORE_user_begin_d (NULL, 0, &user_context, "sue", 3, POPSTORE_ACCOUNTING, "read_sample", 11)); /* * Display the new messages */ msg_ptr = user_context->messages; for (i = 0, msg_ptr = user_context->messages; i < user_context->profile->message_count; i++, msg_ptr++) if (!(msg_ptr->flags & POPSTORE_MFLAGS_READ)) { display_message (user_context, i+1); (void) POPSTORE_message_mark_read (user_context, i+1); } /* * Deaccess the account */ (void) POPSTORE_user_end (user_context); /* * And shut down the popstore */ (void) POPSTORE_end (); } |
12.9 Using the API from Multi-threaded Programs
Multi-threaded programs need to register mutex handling subroutines
with the PMDF API subroutine PMDF_set_mutex
prior to
initializing either the PMDF or popstore APIs. In addition, when
calling POPSTORE_initialize
, supply the address of the
sleep subroutine provided to PMDF_set_mutex
.
12.10 Compiling and Linking Programs
OpenVMS Systems
To declare the API subroutines, data structures, and constants, C
programs should use the PMDF_COM:popstore.h
header file.
Linking programs to the popstore API is accomplished with a link command of the form
$ LINK program,PMDF_EXE:pmdfshr_link.opt/OPT |
program
is the name of the object file to
link.
To declare the API subroutines, data structures, and constants, C
programs should use the /pmdf/include/popstore.h
header
file.
Linking a C program to the API is accomplished with a link command of the form
% cc -R/pmdf/lib/ -L/pmdf/lib/ -o program program.c \ -lpmdf -lsocket -lintl -lnsl -lm -ldb -lldapv3 |
program
is the name of your program.
To declare the API subroutines, data structures, and constants, C
programs should use the C:\pmdf\include\popstore.h
header
file.
When linking programs to the API with the Microsoft C/C++ compiler, use the switches
-mD -D_WIN32_WINNT=0x0400 C:\pmdf\lib\libpmdf.lib |
12.11 Basic Constants, Types, and Data Structures
Basic constants and data types used by the popstore are listed in
Tables 12-1 and 12-2. The data structures describing
a user profile, POPSTORE_user_data
, and a message list,
POPSTORE_message_list
, are shown in Sections 12.11.1
and Section 12.11.2. A user context as obtained from the
POPSTORE_user_begin_d subroutine, is a pointer to a
POPSTORE_user_context
structure and is described in
Section 12.11.3. Fields in that structure point to data structures
containing the user's profile and message list. All of these constants,
data types, and structures are declared in the popstore.h
header file located in the /pmdf/include/
directory on
UNIX and NT platforms and the PMDF_COM:
directory on
OpenVMS.
Constant | Value | Description |
---|---|---|
ALFA_SIZE | 252 | A basic PMDF string size |
BIGALFA_SIZE | 1024 | A basic PMDF string size |
POPSTORE_FLAGS_DELETE | 16 | Bit mask for the DELETE usage flag bit |
POPSTORE_FLAGS_DISMAIL | 2 | Bit mask for the DISMAIL usage flag bit |
POPSTORE_FLAGS_DISUSER | 1 | Bit mask for the DISUSER usage flag bit |
POPSTORE_FLAGS_LOCKPWD | 4 | Bit mask for the LOCKPWD usage flag bit |
POPSTORE_FLAGS_MANAGE | 8 | Bit mask for the MANAGE usage flag bit |
POPSTORE_FULL_UIDL_LEN | 23 | Length in bytes of a full message UIDL derived |
POPSTORE_MAX_DOMAIN_LEN | 40 | Maximum length in bytes of a user domain name |
POPSTORE_MAX_FILE_LEN | 1024 | Maximum length in bytes for full file paths |
POPSTORE_MAX_GROUP_LEN | 16 | Maximum length in bytes of a management group name |
POPSTORE_MAX_OWN_LEN | 40 | Maximum length in bytes for the profile owner field |
POPSTORE_MAX_PRIV_LEN | 64 | Maximum length in bytes for the profile site-defined private data field |
POPSTORE_MAX_PWD_LEN | 32 | Maximum length in bytes for the profile password field |
POPSTORE_MAX_USER_LEN | 32 | Maximum length in bytes for the profile username field |
POPSTORE_MFLAGS_READ | 1 | Bit mask for the READ message flag bit |
POPSTORE_MSG_FILE_FORMAT_VERSION | 0 | Current value for message file format version |
POPSTORE_MSG_NAME_LEN | 19 | Length in bytes of a message file name |
POPSTORE_USERDATA_VERSION | 2 | Current value for the profile file format version |
Type | Size (bytes) | Underlying data type |
---|---|---|
int32 | 4 | int |
ubyte | 1 | unsigned char |
uint32 | 4 | unsigned int |
ushort | 2 | unsigned short int |
12.11.1 POPSTORE_user_data Structure
User profile information is stored in a POPSTORE_user_data
structure of the form shown below. To change user profile information,
the POPSTORE_user_set
or POPSTORE_user_update
subroutines should be used. The former is used when creating an
account---an account which does not yet exist. The latter is used to
modify an existing account. The profile information for an existing
account is obtained with the POPSTORE_user_begin_d
subroutine. That subroutine returns a pointer to a
POPSTORE_user_context
structure; the profile data is
pointed at by the profile
field in that structure.
The layout of the POPSTORE_user_data
structure is shown
below:
typedef struct { ubyte version; ubyte store_type; ushort flags; ubyte ulen; ubyte plen; ubyte olen; ubyte slen; char username[POPSTORE_MAX_USER_LEN]; char password[POPSTORE_MAX_PWD_LEN]; char owner[POPSTORE_MAX_OWN_LEN]; ubyte private[POPSTORE_MAX_PRIV_LEN]; uint32 quota; uint32 return_after; uint32 overdraft; time_t last_billing; uint32 total_conntections; time_t last_connect; time_t last_pwd_change; time_t last_disconnect; uint32 total_connect; uint32 past_block_days; uint32 past_block_days_remainder; uint32 message_count; uint32 quota_used; uint32 received_messages; uint32 received_bytes; ubyte reserved5[3]; ubyte glen; char group[POPSTORE_MAX_GROUP_LEN]; } POPSTORE_user_data; |
Data structure version number. The current version number for the data structure is given by the
version
POPSTORE_USERDATA_VERSION
constant.Type of message store used for this profile. Value will typically be zero
store_type
POPSTORE_STORE_TYPE_POP
.Bit masked field containing usage flag settings. The bits in this field can be tested with the
flags
POPSTORE_FLAGS_
constants.Length in bytes of the value stored in the username field.
ulen
Length in bytes of the value stored in the password field. The value of this field is encrypted.
plen
Length in bytes of the value stored in the owner field.
olen
Length in bytes of the value stored in the private field.
slen
The account username. This field is not null terminated; the length of the value stored in this field is given by the value of the ulen field.
username
The account password. The value stored in this field is encrypted and is not null terminated. The encrypted value of the plen field gives the length of the value stored in this field.
password
Account owner information. This field is not null terminated; the length of the value stored in this field is given by the value of the olen field.
owner
Site-defined private data field. The length of the value stored in this field is given by the value of the slen field. This field is not null terminated.
private
Primary message storage quota measured in units of bytes. A value of zero for this field conveys unlimited storage quota.
quota
Field reserved for future use.
return_after
Message overdraft storage quota.
overdraft
Time of last billing as measured in seconds since 1 January 1970. This field is set to the current time when the account is first created.
last_billing
Cumulative count of connections made to the account since either the account was created or this field last cleared.
total_connections
Time of last connection attempt as measured in seconds since 1 January 1970. This field is set for both successful and unsuccessful login attempts. The time is recorded when the user context is created with
last_connect
POPSTORE_user_begin_d
and written to the profile when the context is disposed of withPOPSTORE_user_end
.Time of last password change as measured in seconds since 1 January 1970. If the value is 0, then the account is pre-expired. This field is set whenever the password is successfully changed, or when the account is set to pre-expired or not pre-expired through the web-based management interface or the command line management utility.
last_pwd_change
Time of last disconnect as measured in seconds since 1 January 1970. This field is set for both successful and unsuccessful login attempts. The time is recorded when the user context is disposed of with
last_disconnect
POPSTORE_user_end
.Total number of seconds spent connected since the account was created or this field last cleared.
total_connect
Cumulative block days for previously stored and since deleted or returned messages since the account was created or this field last cleared. The value of this field does not take into account messages currently held in the store.
past_block_days
Remainder field used in computation of block days. This field is measured in units of byte seconds.
past_block_days_remainder
Count of messages currently stored for the account.
message_count
Number of bytes currently being consumed to store messages for the account. This value only takes into consideration the size of the underlying messages themselves and not the size of the actual container files.
quota_used
Cumulative count of messages received and stored for the account since either the account was created or this field last cleared.
received_messages
Cumulative count of message bytes received and stored for the account since either the account was created or this field last cleared.
received_bytes
Field reserved for future use.
reserved5
Length in bytes of the value stored in the
glen
group
field.Name of the management group to which this account belongs.
group
12.11.2 POPSTORE_message_ref Structure
A user's list of stored messages is stored as an array of zero or more
array elements each of type POPSTORE_message_ref
. To
change information in the list (e.g., mark messages for
deletion), use the appropriate POPSTORE_message_ subroutine. The list
of an account's stored messages is obtained with the
POPSTORE_user_begin_d subroutine. That subroutine returns a pointer to
a POPSTORE_user_context
structure; the message list is
pointed at by the messages
field in that structure. The
count of stored messages, and hence the count of array elements in the
message list, is given by the user profile information also available
from the user context structure. See, for instance, Example 12-7.
The layout of the POPSTORE_message_ref
structure is shown
below:
typedef struct { uint32 size; uint32 last_billing; time_t created; uint32 flags; char uidl[4]; char filename[POPSTORE_MSG_NAME_LEN]; ubyte pad; } POPSTORE_message_ref; |
Size in bytes of the message. This size includes CRLF terminators but does not include any dots used for dot stuffing.
size
Time at which usage billing was last done for the storage of this message. Measured as the count of seconds since 1 January 1970.
last_billing
Time at which the message file was created. Measured as the count of seconds since 1 January 1970.
created
Bit masked field containing message status flag bits. The bits in this field can be tested with the
flags
POPSTORE_MFLAGS_
constants. Currently, only one flag bit is stored in the message list: the read/unread bit accessed with thePOPSTORE_MFLAGS_READ
bit mask.The message UIDL begins with this field and includes the
uidl
filename
field. The length in bytes of the UIDL is given byPOPSTORE_FULL_UIDL_LEN
. This portion of the UIDL is unique for each recipient of the underlying message file.This field forms part of the message UIDL and is the same for all popstore recipients of this particular message. This field also is the name of the underlying file containing the message.
filename
A padding byte. The value of this byte is set to zero thus making the full UIDL accessible as a null terminated string.
pad
12.11.3 POPSTORE_user_context Structure
Information about a popstore account is returned to callers of
POPSTORE_user_begin_d
in the form of a pointer to a
structure of type POPSTORE_user_context
---a "user
context". Fields in this structure must not be changed; use the
appropriate API subroutines to effect the needed changes. When through
with a user context, call POPSTORE_user_end
to dispose of
the context. Note that it is important that that call be made: not only
does it dispose of allocated resources, it also updates accounting
information for the account and performs any requested message deletion
operations.
The layout of the POPSTORE_user_context
structure is shown
below:
typedef struct { time_t connect; uint32 log_subid; int do_accounting; uint32 block_days; uint32 block_days_remainder; POPSTORE_user_data *profile; POPSTORE_message_ref *messages; POPSTORE_string filespec; char pad[3]; POPSTORE_userdb_data *userdb_data; void *reserved0; char domain[POPSTORE_MAX_DOMAIN_LEN]; int dlen; } POPSTORE_user_context; |
Time at which this context was established.
connect
Sub-identifier used for logging purposes.
log_subid
Flag indicating whether or not accounting should be done for this context.
do_accounting
Accumulated block days for messages deleted with this context.
block_days
Accumulated block days roundoff for messages deleted with this context.
block_days_remainder
The user's profile data. The value of this field is a pointer to the profile information for this user account.
profile
The user's list of stored messages. The value of this field is a pointer to an array of
messages
POPSTORE_message_ref
elements. This array containsprofile->message_count
elements.File specification for the underlying profile file.
filespec
Alignment padding bytes.
pad
This field will usually be
userdb_data
NULL
. It is a pointer to the account's user database record. That record is only obtained when the popstore is performing management operations and even then only seldom.Field reserved for future use.
reserved0
User domain associated with this account.
domain
Length in bytes of the user domain associated with this account. A length of zero indicates the
dlen
default
domain.
12.12 Subroutine Descriptions
This section documents the individual popstore API subroutines. A brief
description of each subroutine is given in Table 12-3 below.
Subroutine name | Description |
---|---|
POPSTORE_command | Obsolete: use the POPSTORE_command_d subroutine |
POPSTORE_command_d | Process a management command |
POPSTORE_end | End usage of the API |
POPSTORE_error_to_text | Convert a numerical error to a textual error message |
POPSTORE_format_counters | Format PMDF channel counter information |
POPSTORE_format_dispose | Dispose of a formatting context |
POPSTORE_format_forwarding | Obsolete: use the POPSTORE_format_forwarding_d subroutine |
POPSTORE_format_forwarding_d | Format forwarding information |
POPSTORE_format_message | Format a stored message |
POPSTORE_format_messages | Format a user's list of stored messages |
POPSTORE_format_profile | Format a user profile |
POPSTORE_format_profiles | Obsolete: use the POPSTORE_format_profiles_d subroutine |
POPSTORE_format_profiles_d | Format a list of user profiles |
POPSTORE_format_read | Read and parse a formatting file |
POPSTORE_init | Initialize the API |
POPSTORE_manage | Allow changing of the MANAGE usage flag |
POPSTORE_message_begin | Access a stored message |
POPSTORE_message_end | Deaccess a stored message |
POPSTORE_message_mark_delete | Mark a user's message copy for deletion |
POPSTORE_message_mark_nodelete | Mark a user's message to be retained |
POPSTORE_message_mark_noread | Mark a user's message as being unread |
POPSTORE_message_mark_read | Mark a user's message as read |
POPSTORE_message_read | Sequentially read a message |
POPSTORE_message_return | Return a message to its originator |
POPSTORE_user_begin | Obsolete: use the POPSTORE_user_begin_d subroutine |
POPSTORE_user_begin_d | Access a user account |
POPSTORE_user_billing | Obsolete: use the POPSTORE_user_billing_d subroutine |
POPSTORE_user_billing_d | Perform billing operations |
POPSTORE_user_copy | Obsolete: use the POPSTORE_user_copy_d subroutine |
POPSTORE_user_copy_d | Copy or rename an existing account |
POPSTORE_user_create | Create a new account |
POPSTORE_user_create_dispose | Abort creating a new account |
POPSTORE_user_create_set | Set the value of a field for an account to be created with POPSTORE_user_create |
POPSTORE_user_delete | Obsolete: use the POPSTORE_user_delete_d subroutine |
POPSTORE_user_delete_d | Delete a user account |
POPSTORE_user_end | Deaccess a user account |
POPSTORE_user_exists | Obsolete: use the POPOPSTORE_user_exists_d subroutine |
POPSTORE_user_exists_d | See if a username specifies a valid account |
POPSTORE_user_list | Obsolete: use the POPSTORE_user_list_d subroutine |
POPSTORE_user_list_abort | Prematurely dispose of a list |
POPSTORE_user_list_d | Return the usernames associated with each account within an accounting group |
POPSTORE_user_pw_change | Obsolete: use the POPSTORE_user_pw_change_d subroutine |
POPSTORE_user_pw_change_d | Change a user's password |
POPSTORE_user_pw_check | Perform an authentication check |
POPSTORE_user_update | Update a field in an existing account |
Previous | Next | Contents | Index |