/*-
***********************************************************************
*
* $Id: pad-join.c,v 1.5 2006/05/25 22:17:28 mavrik Exp $
*
***********************************************************************
*
* Copyright 2002-2006 The WebJob Project, All Rights Reserved.
*
***********************************************************************
*/
#include "pad-common.h"
#include "pad-join.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_JOIN_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_JOIN_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);
}
/*-
*********************************************************************
*
* 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_JOIN_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_JOIN_PROPERTIES *) PaDNewProperties(sizeof(PAD_JOIN_PROPERTIES), acLocalError);
if (psProperties == NULL)
{
snprintf(pcError, MESSAGE_SIZE, "%s: %s", PaDGetCallname(pvCall), acLocalError);
return ER;
}
PaDSetPropertiesReference((void *)psProperties);
return ER_OK;
}
/*-
***********************************************************************
*
* PaDProcessArguments
*
***********************************************************************
*/
int
PaDProcessArguments(int iArgumentCount, char *ppcArgumentVector[], PAD_JOIN_PROPERTIES *psProperties, char *pcError)
{
if (iArgumentCount == 3)
{
psProperties->pcPaDGuts = ppcArgumentVector[1];
psProperties->pcPayload = ppcArgumentVector[2];
}
else if (iArgumentCount == 5)
{
if (strcmp(ppcArgumentVector[1], "-d") == 0 || strcmp(ppcArgumentVector[1], "--delimiter") == 0)
{
psProperties->pcDelimiter = ppcArgumentVector[2];
psProperties->pcPaDGuts = ppcArgumentVector[3];
psProperties->pcPayload = ppcArgumentVector[4];
}
else
{
PaDUsage(ppcArgumentVector[0]);
}
}
else
{
PaDUsage(ppcArgumentVector[0]);
}
return ER_OK;
}
/*-
***********************************************************************
*
* PaDShutdown
*
***********************************************************************
*/
void
PaDShutdown(int iError)
{
PAD_JOIN_PROPERTIES *psProperties;
psProperties = (PAD_JOIN_PROPERTIES *) PaDGetPropertiesReference();
if (psProperties != NULL)
{
free(psProperties);
}
exit(iError);
}
/*-
***********************************************************************
*
* PaDUsage
*
***********************************************************************
*/
void
PaDUsage(char *pcProgram)
{
fprintf(stderr, "\n");
fprintf(stderr, "Usage: %s [{-d|--delimiter} string] pad-guts payload\n", PaDGetBasename(pcProgram));
fprintf(stderr, "\n");
exit(XER_Usage);
}
/*-
***********************************************************************
*
* PaDWorkHorse
*
***********************************************************************
*/
int
PaDWorkHorse(PAD_JOIN_PROPERTIES *psProperties, char *pcError)
{
void (*pvCall)() = PAD_VOID_CALL PaDWorkHorse;
char acData[PAD_READ_SIZE];
char acLocalError[MESSAGE_SIZE];
char *pcDelimiter;
char *pcFilename[2];
FILE *pFile[2];
int i;
int iInUse;
int iNRead;
int iNWritten;
/*-
*********************************************************************
*
* Allocate and initialize the PaD delimiter.
*
*********************************************************************
*/
if (psProperties->pcDelimiter == NULL)
{
pcDelimiter = PaDNewDelimiter(PAD_GUTS_TEMPLATE, 1, acLocalError);
}
else
{
pcDelimiter = PaDNewDelimiter(psProperties->pcDelimiter, 0, acLocalError);
}
if (pcDelimiter == NULL)
{
snprintf(pcError, MESSAGE_SIZE, "%s: %s", PaDGetCallname(pvCall), acLocalError);
return ER;
}
/*-
*********************************************************************
*
* Open input files.
*
*********************************************************************
*/
pcFilename[0] = psProperties->pcPaDGuts;
pcFilename[1] = psProperties->pcPayload;
for (i = iInUse = 0, pFile[0] = pFile[1] = NULL; i < 2; i++)
{
if (strcmp(pcFilename[i], "-") == 0 && iInUse == 0)
{
pFile[i] = stdin;
iInUse = 1;
}
else
{
pFile[i] = fopen(pcFilename[i], "rb");
if (pFile[i] == NULL)
{
snprintf(pcError, MESSAGE_SIZE, "%s: fopen(): File='%s' Error='%s'", PaDGetCallname(pvCall), pcFilename[i], strerror(errno));
while (i >= 0)
{
if (pFile[i] != NULL && pFile[i] != stdin)
{
fclose(pFile[i]);
}
i--;
}
return ER;
}
}
}
/*-
*********************************************************************
*
* Read input files and write PaD output to stdout.
*
*********************************************************************
*/
for (i = 0; i < 2; i++)
{
while ((iNRead = fread(acData, 1, PAD_READ_SIZE, pFile[i])))
{
iNWritten = fwrite(acData, 1, iNRead, stdout);
if (iNWritten != iNRead)
{
snprintf(pcError, MESSAGE_SIZE, "%s: fwrite(): File='stdout' Error='%s'", PaDGetCallname(pvCall), strerror(errno));
return ER;
}
}
if (ferror(pFile[i]))
{
snprintf(pcError, MESSAGE_SIZE, "%s: fread(): File='%s' Error='%s'", PaDGetCallname(pvCall), pcFilename[i], strerror(errno));
return ER;
}
fclose(pFile[i]);
if (i == 0)
{
iNWritten = fwrite(pcDelimiter, 1, strlen(pcDelimiter), stdout);
if (iNWritten != strlen(pcDelimiter))
{
snprintf(pcError, MESSAGE_SIZE, "%s: fwrite(): File='stdout' Error='%s'", PaDGetCallname(pvCall), strerror(errno));
return ER;
}
}
}
free(pcDelimiter);
return ER_OK;
}
syntax highlighted by Code2HTML, v. 0.9.1