/*-
***********************************************************************
*
* $Id: pad-make-binary-guts.c,v 1.6 2006/05/25 22:17:28 mavrik Exp $
*
***********************************************************************
*
* Copyright 2002-2006 The WebJob Project, All Rights Reserved.
*
***********************************************************************
*/
#include "pad-common.h"
#include "pad-make-binary-guts.h"
/*-
***********************************************************************
*
* Global Variables.
*
***********************************************************************
*/
void *gpvProperties;
PAD_CALL_TABLE gsCallTable[] =
{
{ PAD_VOID_CALL main, "PaDMain()" },
{ PAD_VOID_CALL PaDBootStrap, "PaDBootStrap()" },
{ PAD_VOID_CALL PaDGetBasename, "PaDGetBasename()" },
{ PAD_VOID_CALL PaDGetCallname, "PaDGetCallname()" },
{ PAD_VOID_CALL PaDGetEnvValue, "PaDGetEnvValue()" },
{ PAD_VOID_CALL PaDGetMyHandle, "PaDGetMyHandle()" },
{ PAD_VOID_CALL PaDGetPropertiesReference, "PaDGetPropertiesReference()" },
{ PAD_VOID_CALL PaDLocateDelimiter, "PaDLocateDelimiter()" },
{ PAD_VOID_CALL PaDNewDelimiter, "PaDNewDelimiter()" },
{ PAD_VOID_CALL PaDNewProperties, "PaDNewProperties()" },
{ PAD_VOID_CALL PaDProcessArguments, "PaDProcessArguments()" },
{ PAD_VOID_CALL PaDReadWrite, "PaDReadWrite()" },
{ PAD_VOID_CALL PaDSetPropertiesReference, "PaDSetPropertiesReference()" },
{ PAD_VOID_CALL PaDShutdown, "PaDShutdown()" },
{ PAD_VOID_CALL PaDUsage, "PaDUsage()" },
{ PAD_VOID_CALL PaDWorkHorse, "PaDWorkHorse()" }
};
int giNCalls = (sizeof(gsCallTable) / sizeof(gsCallTable[0]));
/*-
***********************************************************************
*
* PaDMain
*
***********************************************************************
*/
int
main(int iArgumentCount, char *ppcArgumentVector[])
{
void (*pvCall)() = PAD_VOID_CALL main;
char acLocalError[MESSAGE_SIZE];
int iError;
PAD_MAKE_PROPERTIES *psProperties;
/*-
*********************************************************************
*
* Punch in and go to work.
*
*********************************************************************
*/
iError = PaDBootStrap(acLocalError);
if (iError != ER_OK)
{
fprintf(stderr, "%s: %s\n", PaDGetCallname(pvCall), acLocalError);
PaDShutdown(XER_BootStrap);
}
psProperties = (PAD_MAKE_PROPERTIES *) PaDGetPropertiesReference();
/*-
*********************************************************************
*
* Process command line arguments.
*
*********************************************************************
*/
iError = PaDProcessArguments(iArgumentCount, ppcArgumentVector, psProperties, acLocalError);
if (iError != ER_OK)
{
fprintf(stderr, "%s: %s\n", PaDGetCallname(pvCall), acLocalError);
PaDShutdown(XER_ProcessArguments);
}
/*-
*********************************************************************
*
* Locate PaD guts.
*
*********************************************************************
*/
iError = PaDLocateDelimiter(psProperties->pFilePaD, psProperties->pcDelimiter, acLocalError);
if (iError != ER_OK)
{
fprintf(stderr, "%s: %s\n", PaDGetCallname(pvCall), acLocalError);
PaDShutdown(XER_Delimiter);
}
/*-
*********************************************************************
*
* Answer the mail.
*
*********************************************************************
*/
iError = PaDWorkHorse(psProperties, acLocalError);
if (iError != ER_OK)
{
fprintf(stderr, "%s: %s\n", PaDGetCallname(pvCall), acLocalError);
PaDShutdown(XER_WorkHorse);
}
/*-
*********************************************************************
*
* Shutdown and go home.
*
*********************************************************************
*/
PaDShutdown(XER_OK);
return XER_OK;
}
/*-
***********************************************************************
*
* PaDBootStrap
*
***********************************************************************
*/
int
PaDBootStrap(char *pcError)
{
void (*pvCall)() = PAD_VOID_CALL PaDBootStrap;
char acLocalError[MESSAGE_SIZE];
#ifdef WIN32
int iError;
#endif
PAD_MAKE_PROPERTIES *psProperties;
#ifdef WIN32
/*-
*********************************************************************
*
* Suppress critical-error-handler message boxes.
*
*********************************************************************
*/
SetErrorMode(SEM_FAILCRITICALERRORS);
/*-
*********************************************************************
*
* Put stdout in binary mode to prevent CRLF mappings.
*
*********************************************************************
*/
iError = _setmode(_fileno(stdout), _O_BINARY);
if (iError == -1)
{
snprintf(pcError, MESSAGE_SIZE, "%s: _setmode(): Stream='stdout' Error='%s'", PaDGetCallname(pvCall), strerror(errno));
return ER;
}
#endif
/*-
*********************************************************************
*
* Allocate and initialize the properties structure.
*
*********************************************************************
*/
psProperties = (PAD_MAKE_PROPERTIES *) PaDNewProperties(sizeof(PAD_MAKE_PROPERTIES), acLocalError);
if (psProperties == NULL)
{
snprintf(pcError, MESSAGE_SIZE, "%s: %s", PaDGetCallname(pvCall), acLocalError);
return ER;
}
PaDSetPropertiesReference((void *) psProperties);
/*-
*********************************************************************
*
* Allocate and initialize the delimiter.
*
*********************************************************************
*/
psProperties->pcDelimiter = PaDNewDelimiter(PAD_MAKE_TEMPLATE, 1, acLocalError);
if (psProperties->pcDelimiter == NULL)
{
snprintf(pcError, MESSAGE_SIZE, "%s: %s", PaDGetCallname(pvCall), acLocalError);
return ER;
}
return ER_OK;
}
/*-
***********************************************************************
*
* PaDProcessArguments
*
***********************************************************************
*/
int
PaDProcessArguments(int iArgumentCount, char *ppcArgumentVector[], PAD_MAKE_PROPERTIES *psProperties, char *pcError)
{
void (*pvCall)() = PAD_VOID_CALL PaDProcessArguments;
char acLocalError[MESSAGE_SIZE];
/*-
*********************************************************************
*
* Open a read handle for this program.
*
*********************************************************************
*/
psProperties->pFilePaD = PaDGetMyHandle(ppcArgumentVector[0], acLocalError);
if (psProperties->pFilePaD == NULL)
{
snprintf(pcError, MESSAGE_SIZE, "%s: %s", PaDGetCallname(pvCall), acLocalError);
return ER;
}
/*-
*********************************************************************
*
* Check remaining arguments.
*
*********************************************************************
*/
if (iArgumentCount == 2)
{
if (strcmp(ppcArgumentVector[1], "-e") == 0 || strcmp(ppcArgumentVector[1], "--export") == 0)
{
psProperties->iRunMode = EXPORT_MODE;
}
else
{
PaDUsage(ppcArgumentVector[0]);
}
}
else if (iArgumentCount == 3)
{
if (strcmp(ppcArgumentVector[1], "-c") == 0 || strcmp(ppcArgumentVector[1], "--create") == 0)
{
psProperties->iRunMode = CREATE_MODE;
psProperties->pcPayload = ppcArgumentVector[2];
if (strcmp(psProperties->pcPayload, "-") == 0)
{
psProperties->pFilePayload = stdin;
}
else
{
psProperties->pFilePayload = fopen(ppcArgumentVector[2], "rb");
if (psProperties->pFilePayload == NULL)
{
snprintf(pcError, MESSAGE_SIZE, "%s: fopen(): File='%s' Error='%s'", PaDGetCallname(pvCall), ppcArgumentVector[2], strerror(errno));
return ER;
}
}
}
else
{
PaDUsage(ppcArgumentVector[0]);
}
}
else
{
PaDUsage(ppcArgumentVector[0]);
}
return ER_OK;
}
/*-
***********************************************************************
*
* PaDShutdown
*
***********************************************************************
*/
void
PaDShutdown(int iError)
{
PAD_MAKE_PROPERTIES *psProperties;
psProperties = (PAD_MAKE_PROPERTIES *) PaDGetPropertiesReference();
if (psProperties != NULL)
{
if (psProperties->pFilePaD != NULL)
{
fclose(psProperties->pFilePaD);
}
if (psProperties->pFilePayload != NULL)
{
fclose(psProperties->pFilePayload);
}
if (psProperties->pcDelimiter != NULL)
{
free(psProperties->pcDelimiter);
}
free(psProperties);
}
exit(iError);
}
/*-
***********************************************************************
*
* PaDUsage
*
***********************************************************************
*/
void
PaDUsage(char *pcProgram)
{
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s {-c|--create} {payload|-}\n", PaDGetBasename(pcProgram));
fprintf(stderr, " %s {-e|--export}\n", PaDGetBasename(pcProgram));
fprintf(stderr, "\n");
exit(XER_Usage);
}
/*-
***********************************************************************
*
* PaDWorkHorse
*
***********************************************************************
*/
int
PaDWorkHorse(PAD_MAKE_PROPERTIES *psProperties, char *pcError)
{
void (*pvCall)() = PAD_VOID_CALL PaDWorkHorse;
char acLocalError[MESSAGE_SIZE];
char *pcDelimiter;
int iError;
/*-
*********************************************************************
*
* Export PaD guts.
*
*********************************************************************
*/
iError = PaDReadWrite(psProperties->pFilePaD, stdout, acLocalError);
if (iError != ER_OK)
{
snprintf(pcError, MESSAGE_SIZE, "%s: %s", PaDGetCallname(pvCall), acLocalError);
return ER;
}
/*-
*********************************************************************
*
* Conditionally output PaD delimiter and target payload.
*
*********************************************************************
*/
if (psProperties->iRunMode == CREATE_MODE)
{
pcDelimiter = PaDNewDelimiter(PAD_GUTS_TEMPLATE, 1, acLocalError);
if (pcDelimiter == NULL)
{
snprintf(pcError, MESSAGE_SIZE, "%s: %s", PaDGetCallname(pvCall), acLocalError);
return ER;
}
if (fwrite(pcDelimiter, 1, strlen(pcDelimiter), stdout) != (int) strlen(pcDelimiter))
{
snprintf(pcError, MESSAGE_SIZE, "%s: fwrite(): File='stdout' Error='%s'", PaDGetCallname(pvCall), strerror(errno));
free(pcDelimiter);
return ER;
}
iError = PaDReadWrite(psProperties->pFilePayload, stdout, acLocalError);
if (iError != ER_OK)
{
snprintf(pcError, MESSAGE_SIZE, "%s: %s", PaDGetCallname(pvCall), acLocalError);
free(pcDelimiter);
return ER;
}
free(pcDelimiter);
}
return ER_OK;
}
syntax highlighted by Code2HTML, v. 0.9.1