DSEXPORT.C

// --dsexport.c----------------------------------------------------------------- 
//
// Directory service export sample.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
// -----------------------------------------------------------------------------

#include "edk.h"
#include "dapi.h"

//
// Names of Command Line Arguments
//

#define ARG_FILE"FILE"
#define ARG_BASEPOINT"BASEPOINT"
#define ARG_CONTAINER"CONTAINER"
#define ARG_CLASSES "CLASSES"
#define ARG_DSA"DSA"
#define ARG_HELP1"?"
#define ARG_HELP2"HELP"
#define ARG_SERVER"SERVER"
#define ARG_ALL_RECIPIENTS"ALL_RECIPIENTS"
#define ARG_ONLY_BASEPOINT"ONLY_BASEPOINT"
#define ARG_DIST_LIST"DIST_LIST"
#define ARG_MAILBOX"MAILBOX"
#define ARG_REMOTE_ADDRESS"REMOTE_ADDRESS"
#define ARG_ALL_CLASSES"ALL_CLASSES"
#define ARG_HIDDEN"HIDDEN"
#define ARG_SUBTREE "SUBTREE"

//
// Table of Command Line Switches for _HrExpandCommandLineArgument()
//

static char * rgpszArgArray[] = {
ARG_FILE,
ARG_BASEPOINT,
ARG_CONTAINER,
ARG_CLASSES,
ARG_DSA,
ARG_HELP1,
ARG_HELP2,
ARG_SERVER,
ARG_ALL_RECIPIENTS,
ARG_ONLY_BASEPOINT,
ARG_DIST_LIST,
ARG_MAILBOX,
ARG_REMOTE_ADDRESS,
ARG_ALL_CLASSES,
ARG_HIDDEN,
ARG_SUBTREE,
};

//
// Variables For Command Line Arguments
//

char szExportFile[MAX_PATH+1]= {0};
char szDsaName[MAX_PATH+1]= {0};
char szServerName[MAX_PATH+1]= {0};
char szBasePoint[MAX_PATH+1] = {0};
char szParentContainer[MAX_PATH+1]= {0};
DWORD ControlFlags= 0;
ULONG cClasses = 0;
LPSTR* lppszClasses = NULL;

//
// Other Variables
//

BOOL fDisplayedHelp = FALSE;
DWORD cLoggedErrors = 0;

//
// Function Declarations
//

static HRESULT HrParseCommandLine(
IN int argc,
IN char *argv[]);

static VOID ShowUsage(
void);

static VOID ShowHelp(
void);

static HRESULT HrDoBatchExport(
void);

//
// Functions
//

//$--main-----------------------------------------------------------------------
// Main function that performs directory export.
// -----------------------------------------------------------------------------
int main(// RETURNS: exit code
IN int argc,// number of arguments on command line
IN char *argv[])// array of command line arguments
{
HRESULT hr = NOERROR;
BOOL IsMAPIInit = FALSE;

DEBUGPUBLIC("main()\n");

printf( "\n" );

hr = MAPIInitialize(NULL);

if(FAILED(hr))
{
goto cleanup;
}

IsMAPIInit = TRUE;

// Get export parameters from the command line.

hr = HrParseCommandLine(argc, argv);
if (FAILED(hr))
{
goto cleanup;
}

// Do batch export

hr = HrDoBatchExport();
if (FAILED(hr))
{
goto cleanup;
}

cleanup:

if(IsMAPIInit == TRUE)
{
MAPIUninitialize();
}

// Successful completion.

if (fDisplayedHelp)
{
hr = NOERROR;
}
else if (SUCCEEDED(hr))
{
fprintf(stderr, "Export operation completed successfully.\n");
}

// Error completion.

else if (cLoggedErrors == 1)
{
fprintf(stderr, "ERROR: 1 error written to NT Event Log.\n");
}
else if (cLoggedErrors > 1)
{
fprintf(stderr, "ERROR: %d errors written to NT Event Log.\n",
cLoggedErrors);
}

MAPIFREEBUFFER(lppszClasses);

return _nEcFromHr(hr);
}

//$--HrParseCommandLine---------------------------------------------------------
// Read export configuration from command line.
// -----------------------------------------------------------------------------
static HRESULT HrParseCommandLine(// RETURNS: HRESULT
IN int argc,// number of arguments on command line
IN char *argv[])// array of command line arguments
{
HRESULThr= NOERROR;
HRESULThrT= NOERROR;
char *pszArgument= NULL;
char *pszValue= NULL;
inti= 0;
LPTSTR lpszSep = "%\0";

DEBUGPRIVATE("HrParseCommandLine()\n");

// If there are no command line arguments then show a usage message.

if (argc < 2)
{
ShowUsage();
hr = E_FAIL;
goto cleanup;
}

// Do an initial check for /? or /HELP. If found, show a help message
// and don't do any other parsing.

for (i = 1; i < argc; i++)
{
hr = _HrExpandCommandLineArgument(
argv[i], rgpszArgArray, ARRAY_CNT(rgpszArgArray), NULL,
&pszArgument, &pszValue);

if (SUCCEEDED(hr) && pszArgument &&
(!_stricmp(pszArgument,ARG_HELP1) ||
!_stricmp(pszArgument,ARG_HELP2)))
{
ShowHelp();
hr = E_FAIL;
goto cleanup;
}
}

// Loop through and parse all the command line arguments.

for (i = 1; i < argc; i++)
{
hrT = _HrExpandCommandLineArgument(
argv[i], rgpszArgArray, ARRAY_CNT(rgpszArgArray), NULL,
&pszArgument, &pszValue);

if (FAILED(hrT))
{
hr = hrT;
if (hr == EDK_E_NOT_FOUND)
{
fprintf(stderr, "ERROR: unknown command line flag: %s\n",
argv[i]);
continue;
}
else
{
fprintf(stderr, "ERROR: unable to parse command line.\n");
goto cleanup;
}
}

// Parse flag arguments that don't take a value.

if (pszArgument != NULL && pszValue == NULL)
{
// ALL_RECIPIENTS

if (!_stricmp(pszArgument,ARG_ALL_RECIPIENTS))
{
ControlFlags |= DAPI_EXPORT_RECIPIENTS;
}

// ONLY_BASEPOINT

else if (!_stricmp(pszArgument,ARG_ONLY_BASEPOINT))
{
ControlFlags |= DAPI_EXPORT_BASEPOINT_ONLY;
}

// DIST_LIST

else if (!_stricmp(pszArgument,ARG_DIST_LIST))
{
ControlFlags |= DAPI_EXPORT_DIST_LIST;
}

// MAILBOX

else if (!_stricmp(pszArgument,ARG_MAILBOX))
{
ControlFlags |= DAPI_EXPORT_MAILBOX;
}

// REMOTE_ADDRESS

else if (!_stricmp(pszArgument,ARG_REMOTE_ADDRESS))
{
ControlFlags |= DAPI_EXPORT_CUSTOM;
}

// ALL_CLASSES

else if (!_stricmp(pszArgument,ARG_ALL_CLASSES))
{
ControlFlags |= DAPI_EXPORT_ALL_CLASSES;
}

// HIDDEN

else if (!_stricmp(pszArgument,ARG_HIDDEN))
{
ControlFlags |= DAPI_EXPORT_HIDDEN;
}

// SUBTREE

else if (!_stricmp(pszArgument,ARG_SUBTREE))
{
ControlFlags |= DAPI_EXPORT_SUBTREE;
}

// Other flag (must take a value).

else
{
fprintf(stderr, "ERROR: flag /%s requires a value\n",
pszArgument);
hr = HR_LOG(E_FAIL);
}
}

// Parse flag arguments that take a value.

else if (pszArgument != NULL && pszValue != NULL)
{
if (!_stricmp(pszArgument,ARG_DSA))
{
strncpy(szDsaName, pszValue, MAX_PATH);
szDsaName[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_SERVER))
{
strncpy(szServerName, pszValue, MAX_PATH);
szServerName[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_FILE))
{
strncpy(szExportFile, pszValue, MAX_PATH);
szExportFile[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_BASEPOINT))
{
strncpy(szBasePoint, pszValue, MAX_PATH);
szBasePoint[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_CONTAINER))
{
strncpy(szParentContainer, pszValue, MAX_PATH);
szParentContainer[MAX_PATH] = 0;
}
else if (!_stricmp(pszArgument,ARG_CLASSES))
{

hr = HrStrTokAll(
pszValue,
lpszSep,
&cClasses,
&lppszClasses);

if(FAILED(hr))
{
fprintf(stderr, "ERROR: syntax error in /%s\n",
pszArgument);
goto cleanup;
}
}

// Other flag (must not take a value).

else
{
fprintf(stderr, "ERROR: flag /%s does not take a value\n",
pszArgument);
hr = HR_LOG(E_FAIL);
}
}

// Catch unknown arguments.

else
{
fprintf(stderr, "ERROR: unknown argument %s\n", argv[i]);
hr = HR_LOG(E_FAIL);
}
}

// Make sure we have all the info we need.

if (SUCCEEDED(hr))
{
if (*szDsaName == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_DSA);
hr = HR_LOG(E_FAIL);
}
if (*szExportFile == 0)
{
fprintf(stderr, "ERROR: please specify /%s\n", ARG_FILE);
hr = HR_LOG(E_FAIL);
}
}

cleanup:
RETURN(hr);
}

//$--ShowUsage------------------------------------------------------------------
// Show usage information.
// -----------------------------------------------------------------------------
static VOID ShowUsage(void)// RETURNS: nothing
{
DEBUGPRIVATE("ShowUsage()\n");

printf("USAGE: DSEXPORT [Flags]\n\n");
printf(" [Flags] Enter DSEXPORT /? for details\n");

fDisplayedHelp = TRUE;
}

//$--ShowHelp-------------------------------------------------------------------
// Show help information.
// -----------------------------------------------------------------------------
static VOID ShowHelp(void)// RETURNS: nothing
{
DEBUGPRIVATE("ShowHelp()\n");

printf("Directory Service Export sample.\n\n");
printf("USAGE: DSEXPORT [Flags]\n\n");
printf(" /FILE= Name of export file\n");
printf(" /SERVER= Exchange server name\n");
printf(" /DSA= Directory Service Agent name\n");
printf(" /BASEPOINT= DN of Directory basepoint object\n");
printf(" /CONTAINER= RDN of Directory container beneath "
"BASEPOINT\n");
printf(" /CLASSES= Object classes (separated by '%%')\n");
printf(" /HELP or /? Display help screen\n");
printf(" /ONLY_BASEPOINT Export only the BASEPOINT object\n");
printf(" /ALL_RECIPIENTS Export all recipients\n");
printf(" /DIST_LIST Export distribution list recipients\n");
printf(" /MAILBOX Export mailbox recipients\n");
printf(" /REMOTE_ADDRESS Export remote address recipients\n");
printf(" /ALL_CLASSES Export all classes\n");
printf(" /HIDDEN Export hidden objects of the selected "
"classes\n");
printf(" /SUBTREE Export subtree\n");

fDisplayedHelp = TRUE;
}

//$--DoBatchExport--------------------------------------------------------------
// Do batch export of directory objects.
// -----------------------------------------------------------------------------
static HRESULT HrDoBatchExport(void)// RETURNS: HRESULT
{
HRESULT hr = NOERROR;
BEXPORT_PARMS BexportParms = {0};
LPBEXPORT_PARMS lpBexportParms = {0};

DEBUGPRIVATE("HrDoBatchExport()\n");

lpBexportParms = &BexportParms;
lpBexportParms->dwDAPISignature = DAPI_SIGNATURE;
lpBexportParms->dwFlags = ControlFlags | DAPI_EVENT_ALL;
lpBexportParms->pszExportFile = szExportFile;
lpBexportParms->pszBasePoint = szBasePoint;

if (*szParentContainer)
{
lpBexportParms->pszContainer = szParentContainer;
}

if (*szDsaName)
{
lpBexportParms->pszDSAName = szDsaName;
}

if (*szServerName)
{
lpBexportParms->pszHomeServer = szServerName;
}

if(lppszClasses != NULL)
{
lpBexportParms->rgpszClasses = lppszClasses;
}

lpBexportParms->chColSep = DAPI_DEFAULT_DELIM;
lpBexportParms->chQuote = DAPI_DEFAULT_QUOTE;
lpBexportParms->chMVSep = DAPI_DEFAULT_MV_SEP;

cLoggedErrors = BatchExport(lpBexportParms);
if (cLoggedErrors)
{
hr = HR_LOG(E_FAIL);
}

RETURN(hr);
}