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