home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Module : Unpost --- Extract a binary file from a multi-part, uuencoded
- * USENET News posting.
- *
- * Author : John W. M. Stevens
- *
- * Notes : See the file unpost.doc for information.
- ******************************************************************************/
-
- #include "compiler.h"
-
- #include "unpost.h"
- #include "parse.h"
- #include "segment.h"
-
- /*********************************** Globals *********************************/
- char *Version = "UNPOST V2.1.2";
- int LineNumber = 0;
-
- /* Binary switches. See file compiler.h to change default settings. */
- int MsDosFileNms = MUNGE_FILE_NMS;
- int DumpDesc = DUMP_DESC_FILES;
- int SepIncomps = SEP_INCOMPLETES;
-
- /* File pointers. */
- FILE *ErrFile = NULL; /* Error file. */
- FILE *TextFile = NULL; /* Write non-binary to file. */
- FILE *IncompFile = NULL; /* Incompletes file. */
- /*****************************************************************************/
-
- /*-----------------------------------------------------------------------------
- | Routine : ReadLine() --- Get a line from the file.
- |
- | Inputs : FlPtr - Pointer to file to read from.
- | InBfr - Pointer to buffer to read into.
- | BfrMax - Max buffer size.
- |
- | Returns : Returns EOF or OK.
- -----------------------------------------------------------------------------*/
-
- int ReadLine(FILE *FlPtr,
- char *InBfr,
- int BfrMax)
- {
- register int i;
- extern FILE *ErrFile;
-
- /* Get a line from the file. */
- if (fgets(InBfr, BfrMax, FlPtr) == NULL)
- {
- /* Check for end of file. */
- if ( feof( FlPtr ) )
- return( EOF );
- else if ( ferror( FlPtr ) )
- {
- fprintf(ErrFile,
- "%s %d : Error - reading source file.\n",
- __FILE__,
- __LINE__);
- exit( 1 );
- }
- }
-
- /* Remove trailing '\n' character.
- *
- * Maybe THIS time I got it right. . .
- */
- LineNumber++;
- for (i = strlen( InBfr );
- i > 0 && (InBfr[i - 1] == '\n' || InBfr[i - 1] == '\r');
- i--
- )
- ;
- InBfr[i] = '\0';
-
- /* Return OK. */
- return( OK );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : ShowSynopsis() --- Show a summary of the command line
- | syntax.
- -----------------------------------------------------------------------------*/
-
- static char *Synopsis[] =
- {
- "Options:\n",
- " -b[-] Break incompletes into separate files.\n",
- " -d[-] Dump descriptions flag.\n",
- " -e <file> File for errors (default standard error).\n",
- " -f[-] Modify file names to be MS-DOS compatible.\n",
- " -h Interpret headers in source files.\n",
- " -i <file> File to write incomplete binaries to.\n",
- " -r <e|g|n|r> Set news reader type (SEGMENT begin line RE).\n",
- " -s Assume segments in order in file.\n",
- " -t <file> File for text only segments.\n",
- " -u UU decoder, pure and simple.\n",
- " -v Print the version number and quit.\n",
- " -? Show this help summary.\n\n",
- "Example:\n",
- " unpost -d -e errors -t text -i multiple.1 multiple.uue\n",
- " Save errors, text segments, descriptions and incompletes.\n\n",
- NULL
- };
-
- static
- void ShowSynopsis(void)
- {
- register int i;
-
- /* Show header and version number. */
- printf("%s --- Extract a uuencoded binary from a multi-part posting.\n\n",
- Version);
-
- /* Show synopsis. */
- for (i = 0; Synopsis[i]; i++)
- printf( Synopsis[i] );
-
- /* Show current state of binary flags. */
- printf("File Name Modifying (-f) : %-3.3s\n",
- (MsDosFileNms) ? "On" : "Off");
- printf("Create Description Files (-d) : %-3.3s\n",
- (DumpDesc) ? "On" : "Off");
- printf("Separate Incomplete Files (-b) : %-3.3s\n",
- (SepIncomps) ? "On" : "Off");
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : CmdLineParse() --- Parse the command line.
- |
- | Inputs : argc - Number of command line arguments.
- | argv - List of command line argument strings.
- | SwList - Switch list.
- -----------------------------------------------------------------------------*/
-
- static
- void CmdLineParse(int argc,
- char **argv,
- char *SwList)
- {
- register int i;
- auto char *ArgPtr;
- auto char *SwPtr;
- auto char SwChar;
- auto char ModeFlag;
-
- /* Check for no arguments. */
- if (argc < 2)
- {
- /* Give synopsis and quit. */
- ShowSynopsis();
- exit( 1 );
- }
-
- /* Scan entire command line. */
- ErrFile = stderr;
- ModeFlag = 'h';
- for (i = 1; i < argc; i++)
- {
- /* Get a pointer to the argument. */
- ArgPtr = argv[i];
-
- /* Is this a switch? */
- if (*ArgPtr == '-')
- {
- /* Get switch character. */
- if ((SwChar = *++ArgPtr) == '\0')
- {
- /* There is no character after the switch marker,
- * so declare an error.
- */
- ShowSynopsis();
- exit( 1 );
- }
- else if ((SwPtr = strchr(SwList, SwChar)) == NULL)
- {
- /* Error, this is evidently an illegal switch
- * character.
- */
- ShowSynopsis();
- exit( 1 );
- }
- else if (SwPtr[1] == '>')
- {
- /* Get parameter string. Parameter string can
- * follow immediately after the switch character,
- * or it can be the next command line string.
- */
- if (*++ArgPtr == '\0')
- {
- /* Next command line parameter is switch
- * parameter string.
- */
- if (i + 1 < argc)
- ArgPtr = argv[++i];
- else
- {
- ShowSynopsis();
- exit( 1 );
- }
- }
- }
- else
- ArgPtr++;
- }
- else
- SwChar = ' ';
-
- /* Have argument processed. */
- switch ( SwChar )
- {
- case 'b':
- /* Set or reset flag that tells UNPOST to separate incompletes
- * into their own files.
- */
- if (*ArgPtr == '-')
- SepIncomps = 0;
- else
- SepIncomps = 1;
- break;
- case 'c':
- /* Initialize the parser, using the default configuration OR
- * the configuration file.
- */
- LoadCfg( ArgPtr );
- break;
- case 'd':
- if (*ArgPtr == '-')
- DumpDesc = 0;
- else
- DumpDesc = 1;
- break;
- case 'e':
- /* Close a file that is already open. */
- if ( ErrFile )
- fclose( ErrFile );
-
- /* Open a new error file. */
- if ((ErrFile = fopen(ArgPtr, TXT_WRITE)) == NULL)
- {
- fprintf(stderr,
- "%s %d : Error - Could not open file '%s' ",
- __FILE__,
- __LINE__,
- ArgPtr);
- fprintf(stderr, "for output.\n");
- exit( 1 );
- }
- break;
- case 'f':
- if (*ArgPtr == '-')
- MsDosFileNms = 0;
- else
- MsDosFileNms = 1;
- break;
- case 'i':
- /* Close a file that is already open. */
- if ( IncompFile )
- fclose( IncompFile );
-
- /* Open an incompletes file. */
- if ((IncompFile = fopen(ArgPtr, TXT_APPEND)) == NULL)
- {
- fprintf(stderr,
- "%s %d : Error - Could not open file '%s' ",
- __FILE__,
- __LINE__,
- ArgPtr);
- fprintf(stderr, "for output.\n");
- exit( 1 );
- }
- break;
- case 'r':
- SetSegBegin( ArgPtr );
- break;
- case 't':
- /* Close a file that is already open. */
- if ( TextFile )
- fclose( TextFile );
-
- /* Open file for saving text only segments. */
- if ((TextFile = fopen(ArgPtr, TXT_WRITE)) == NULL)
- {
- fprintf(stderr,
- "%s %d : Error - Could not open file '%s' ",
- __FILE__,
- __LINE__,
- ArgPtr);
- fprintf(stderr, "for output.\n");
- exit( 1 );
- }
- break;
- case 'h':
- case 'u':
- case 's':
- ModeFlag = SwChar;
- break;
- case 'v':
- printf("%s\n", Version);
- exit( 0 );
- case ' ':
- /* Select mode. */
- switch ( ModeFlag )
- {
- case 'h':
- Multiple( ArgPtr );
- break;
- case 's':
- Single( ArgPtr );
- break;
- case 'u':
- UUDecode( ArgPtr );
- break;
- }
- break;
- default:
- ShowSynopsis();
- exit( 1 );
- }
- }
- }
-
- #if defined(MUNGE_FILE_NAMES_PER_FS) && defined(SYSTEM_OS_2)
-
- /*-----------------------------------------------------------------------------
- | Routine : IsHpfs() --- Is this an HPFS?
- |
- | Returns : Returns 0 for not a HPFS, or non zero for is.
- -----------------------------------------------------------------------------*/
-
- #if defined(EMX_GCC_COMPILER)
-
- int IsHpfs(void)
- {
- auto unsigned long ulDrive;
- auto unsigned long ulLogical;
- auto char drive[3];
- auto char name[16];
-
- /* Check operating system mode. */
- if (_osmode == DOS_MODE)
- return( 0 );
-
- /* Get current disk drive. */
- DosQueryCurrentDisk(&ulDrive, &ulLogical);
-
- /* Set up drive name string. */
- drive[0] = (char) (ulDrive + '@');
- drive[1] = ':';
- drive[2] = '\0';
-
- /* Get file system name string. */
- if (_filesys(drive, name, 16) == -1)
- return( 0 );
-
- /* Is this an HPFS? */
- if (strcmp(name, "HPFS") == 0)
- return( 1 );
- return( 0 );
- }
-
- #elif defined(OS_2_MSC_COMPILER)
-
- int IsHpfs(void)
- {
- auto USHORT nDrive;
- auto ULONG lMap;
- auto BYTE bData[64];
- auto BYTE bName[3];
- auto USHORT cbData;
-
- /* MS-DOS does not have HPFS. */
- if (_osmode == DOS_MODE)
- return( 0 );
-
- /* Get the default drive. */
- DosQCurDisk(&nDrive, &lMap);
-
- /* Set up the drive name. */
- bName[0] = (char) (nDrive + '@');
- bName[1] = ':';
- bName[2] = 0;
- cbData = sizeof( bData );
-
- /* Read the info, if we fail - assume non-HPFS. */
- if ( DosQFSAttach(bName, 0, FSAIL_QUERYNAME, bData, &cbData, 0L) )
- return( 0 );
- else if (strcmp(bData + (*((USHORT *) (bData + 2)) + 7), "HPFS") == 0)
- return( 1 );
- return( 0 );
- }
-
- #endif
-
- #endif
-
- int main(int argc,
- char **argv)
- {
- /* If the user wants different file name munging on different
- * systems, set -f flag accordingly, otherwise, leave alone.
- */
- #if defined(MUNGE_FILE_NAMES_PER_FS) && defined(SYSTEM_OS_2)
- MsDosFileNms = ! IsHpfs();
- #endif
-
- /* Parse command line parameters. */
- ParseInit();
- CmdLineParse(argc, argv, "bc>de>fhi>r>st>uv");
- return( 0 );
- }
-