/*- *********************************************************************** * * $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; }