home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Module : Parse --- Search for a particular line.
- *
- * Author : John W. M. Stevens
- ******************************************************************************/
-
- #include "compiler.h"
-
- #include "unpost.h"
- #include "regexp.h"
- #include "uudec.h"
- #include "modflnm.h"
- #include "ident.h"
- #include "parse.h"
- #include "config.h"
- #include "utils.h"
-
- /* These are the elements we have to parse out of either the header or
- * the body of the message BEFORE we find the first UUencoded line.
- */
- typedef enum {
- ID_STRING,
- SEGMENT_NO,
- NO_SEGMENTS
- } PARSE_ELS;
-
- /*
- * Regular expression source strings.
- *
- * To configure the program for different systems, these are the
- * strings to change.
- */
- static PART_RE Parts1[] =
- {
- { "^Subject:(.*)[[({]Part[_ \t]*([0-9]+)[^0-9]+([0-9]+)[)\\]}](.*)",
- 1, 2, 3, 4, IGN_CASE, NULL
- },
- { "^Subject:(.*)Part[_ \t]*[[({]([0-9]+)[^0-9]+([0-9]+)[)\\]}](.*)",
- 1, 2, 3, 4, IGN_CASE, NULL
- },
- { "^Subject:(.*)Part[_ \t]+([0-9]+)[^0-9]+([0-9]+)(.*)",
- 1, 2, 3, 4, IGN_CASE, NULL
- },
- { "^Subject:(.*)[([{]([0-9]+)[^0-9]+([0-9]+)[)\\]}](.*)",
- 1, 2, 3, 4, IGN_CASE, NULL
- },
- { "^Subject:(.*)([0-9]+)([/|]|[ \t]+of[ \t]+)([0-9]+)(.*)",
- 1, 2, 4, 5, IGN_CASE, NULL
- },
- { "^Subject:(.*)",
- 1, 0, 0, 0, IGN_CASE, NULL
- },
- { NULL,
- 0, 0, 0, 0, IGN_CASE, NULL
- }
- };
-
- static PART_RE Parts3[] =
- {
- { "^X-File-Name:[ \t]+(.*)",
- 1, 0, 0, 0, CASE_SENSITIVE, NULL
- },
- { NULL,
- 0, 0, 0, 0, IGN_CASE, NULL
- }
- };
-
- static PART_RE Parts4[] =
- {
- { "^X-Part:[ \t]+([0-9]+)",
- 0, 1, 0, 0, CASE_SENSITIVE, NULL
- },
- { NULL,
- 0, 0, 0, 0, IGN_CASE, NULL
- }
- };
-
- static PART_RE Parts5[] =
- {
- { "^X-Part-Total:[ \t]+([0-9]+)",
- 0, 0, 1, 0, CASE_SENSITIVE, NULL
- },
- { NULL,
- 0, 0, 0, 0, IGN_CASE, NULL
- }
- };
-
- static PART_RE Parts6[] =
- {
- { "^Uusplit-part:[ \t]+([0-9]+)",
- 0, 1, 0, 0, CASE_SENSITIVE, NULL
- },
- { NULL,
- 0, 0, 0, 0, IGN_CASE, NULL
- }
- };
-
- static PART_RE Parts7[] =
- {
- { "^Uusplit-parts:[ \t]+([0-9]+)",
- 0, 0, 1, 0, CASE_SENSITIVE, NULL
- },
- { NULL,
- 0, 0, 0, 0, IGN_CASE, NULL
- }
- };
-
- static PART_RE Parts8[] =
- {
- { "^section ([0-9]+) of uuencode [0-9]+\\.[0-9]+ of file ([^ \t]+)[ \t]+by R.E.M.",
- 2, 1, 0, 0, CASE_SENSITIVE, NULL
- },
- { NULL,
- 0, 0, 0, 0, IGN_CASE, NULL
- }
- };
-
- static PART_RE Parts9[] =
- {
- { "^([^ \t]+)[ \t]+section[ \t]+([0-9]+)/([0-9]+)[ \t]+UUXFER ver ",
- 1, 2, 3, 0, CASE_SENSITIVE, NULL
- },
- { NULL,
- 0, 0, 0, 0, IGN_CASE, NULL
- }
- };
-
- static IDENT Hdr1[] =
- {
- { "^Subject:", Parts1, NULL },
- { "^X-File-Name:", Parts3, NULL },
- { "^X-Part:", Parts4, NULL },
- { "^X-Part-Total:", Parts5, NULL },
- { "^Uusplit-part:", Parts6, NULL },
- { "^Uusplit-parts:", Parts7, NULL },
- { NULL, NULL, NULL }
- };
-
- static IDENT Body1[] =
- {
- { "^Subject:", Parts1, NULL },
- { "^section [0-9]+ of uuencode [0-9]+\\.[0-9]+ of file [^ \t]+ by R.E.M.",
- Parts8, NULL },
- { "^[^ \t]+[ \t]+section[ \t]+[0-9]+/[0-9]+[ \t]+UUXFER ver ",
- Parts9, NULL },
- { NULL, NULL, NULL }
- };
-
- /*=============================================================================
- || SEGMENT begin line regular expressions are defined below.
- ||
- || These can be set by command line switch.
- =============================================================================*/
-
- static SEGMENT RnSegs[] =
- {
- { "^(Article[:]?|X-NEWS:) ", Hdr1, Body1, NULL },
- { NULL, NULL, NULL, NULL }
- };
-
- static SEGMENT NnSegs[] =
- {
- { "^From[:]? ", Hdr1, Body1, NULL },
- { NULL, NULL, NULL, NULL }
- };
-
- static SEGMENT EmailSegs[] =
- {
- { "^From ", Hdr1, Body1, NULL },
- { NULL, NULL, NULL, NULL }
- };
-
- static SEGMENT GroupsSegs[] =
- {
- { "^Newsgroups: ", Hdr1, Body1, NULL },
- { NULL, NULL, NULL, NULL }
- };
-
- static SEGMENT *Segments = RnSegs;
- static REG_EXP_NODE *Begin = NULL;
- static REG_EXP_NODE *End = NULL;
- static char *BeginStr = "^begin[ \t]+([0-7]+)[ \t]+([^ \t]+)";
- static char *EndStr = "^end[ \t]*$";
-
- /*-----------------------------------------------------------------------------
- | Routine : GetBinFlNm() --- Get the binary file name.
- |
- | Inputs : InFlPtr - Pointer to source file.
- | Outputs : FlName - Pointer to file name buffer.
- -----------------------------------------------------------------------------*/
-
- void GetBinFlNm(FILE *InFlPtr,
- char **RetStrs,
- char *FlName)
- {
- auto long LnOfs;
- auto char *tp;
- auto char *sp;
- auto int OutLen;
- auto char Exten[5];
- auto char BeginName[FL_NM_SZ];
-
- /* Externals used by this function. */
- extern BYTE OutBfr[];
- extern char SegLine[];
- extern char InBfr[];
- extern char UULine[];
- extern FILE *ErrFile;
- extern int MsDosFileNms;
-
- /* Extract the file name. */
- for (tp = BeginName, sp = RetStrs[2];
- *sp && *sp != '\n' && *sp != ' ' && *sp != '\t';
- )
- *tp++ = *sp++;
- *tp = '\0';
-
- /* Munge file name? */
- if ( MsDosFileNms )
- {
- /* Get the current file offset. */
- LnOfs = ftell( InFlPtr );
-
- /* Get next line and identify file type. */
- *Exten = '\0';
- if (ReadLine(InFlPtr, InBfr, BFR_SIZE) == EOF)
- {
- fprintf(ErrFile,
- "%s %d : Warning - Unexpected end of file in segment:\n",
- __FILE__,
- __LINE__);
- fprintf(ErrFile,
- "\tSegment: '%s'\n",
- SegLine);
- }
- else if (DecUULine(InBfr, &OutLen, OutBfr) == NOT_UU_LINE)
- {
- fprintf(ErrFile,
- "%s %d : Warning - No UU line after begin.\n",
- __FILE__,
- __LINE__);
- fprintf(ErrFile,
- "\tSegment: '%s'\n",
- SegLine);
- }
- else
- {
- /* Attempt to ID the file. */
- IdUUFile(OutBfr, OutLen, Exten);
-
- /* Modify the file name to be MS-DOS compatible? */
- ModifyFlNm(BeginName, Exten, FlName);
- }
-
- /* Position file pointer to start of line. */
- if (fseek(InFlPtr, LnOfs, SEEK_SET) != 0)
- {
- fprintf(ErrFile,
- "%s %d : Error - %s\n",
- __FILE__,
- __LINE__,
- sys_errlist[errno]);
- exit( 1 );
- }
- }
- else
- strcpy(FlName, BeginName);
-
- #if defined(UNPOST_DEBUG)
- printf("\tBinary File Name: '%s'\n", FlName);
- #endif
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : MatchEnd() --- Match a uuencode end line.
- |
- | Inputs : Line - The line to attempt to match against.
- -----------------------------------------------------------------------------*/
-
- int MatchEnd(char *Line)
- {
- auto char **RetStrs;
-
- /* Attempt to match the line. */
- return( ReMatch(Line, CASE_SENSITIVE, End, &RetStrs) );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : MatchBegin() --- Match a uuencode begin line.
- |
- | Inputs : Line - The line to attempt to match against.
- | Outputs : RetStrs - Returned sub-strings.
- -----------------------------------------------------------------------------*/
-
- int MatchBegin(char *Line,
- char ***RetStrs)
- {
- /* Attempt to match the line. */
- return( ReMatch(Line, CASE_SENSITIVE, Begin, RetStrs) );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : MatchSegment() --- Match a SEGMENT begin line.
- |
- | Inputs : Line - The line to attempt to match against.
- | Outputs : Hdr - Pointer to header ID line RE's.
- | Body - Pointer to body ID line RE's.
- -----------------------------------------------------------------------------*/
-
- int MatchSegment(char *Line,
- IDENT **Hdr,
- IDENT **Body)
- {
- register int i;
- auto char **RetStrs;
-
- /* Attempt to match the line. */
- for (i = 0; Segments[i].ReExprStr; i++)
- {
- /* Attempt to match one of the segment begin lines. */
- if (ReMatch(Line,
- CASE_SENSITIVE,
- Segments[i].ReExpr,
- &RetStrs) != 0)
- {
- *Hdr = Segments[i].Header;
- *Body = Segments[i].Body;
- return( 1 );
- }
- }
-
- /* Return not matched. */
- Hdr = NULL;
- Body = NULL;
- return( 0 );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : GetBinID() --- Get binary ID string.
- |
- | Inputs : SubStr - Pointer to possible ID sub-string.
- | Outputs : IDStr - Pointer to ID string buffer.
- -----------------------------------------------------------------------------*/
-
- static
- void GetBinID(char *SubStr,
- char *IDStr)
- {
- register int i;
- auto int ExtSep;
- auto int MaxLen;
- auto char *WordPtr;
- auto char *DestPtr;
- auto char *MaxPtr;
- auto char *tp;
-
- extern int MsDosFileNms;
-
- /* Filter string. */
- FlNmFilter( SubStr );
-
- /* Attempt to guess at a file name. */
- for (tp = SubStr; *tp; )
- {
- /* Skip white space. */
- while (*tp == ' ' || *tp == '\t')
- tp++;
-
- /* Get word. */
- for (DestPtr = IDStr, ExtSep = 0;
- *tp && *tp != ' ' && *tp != '\t';
- tp++)
- {
- /* Check to see if this is and extension separator
- * character, and if so, count how many.
- */
- if (*tp == EXT_SEP_CHAR)
- ExtSep++;
-
- /* Copy character. */
- *DestPtr++ = *tp;
- }
- *DestPtr = '\0';
-
- /* Does this look like a file name? */
- if ( ExtSep )
- {
- #if defined(UNPOST_DEBUG)
- printf("\tBinary ID: '%s'\n", IDStr);
- #endif
- return;
- }
- }
-
- /* OK, we didn't find anything that looks like it could possibly
- * be a file name, so get the longest word and use it.
- */
- MaxLen = 0;
- MaxPtr = NULL;
- for (tp = SubStr; *tp; )
- {
- /* Skip white space. */
- while (*tp == ' ' || *tp == '\t')
- tp++;
-
- /* Copy string. */
- for (i = 0, WordPtr = tp;
- *tp && *tp != ' ' && *tp != '\t';
- i++)
- IDStr[i] = *tp++;
- IDStr[i] = '\0';
-
- /* Is this the longest so far? */
- if (i > MaxLen)
- {
- MaxPtr = WordPtr;
- MaxLen = i;
- }
- }
-
- /* OK, check for no non-white space characters in sub
- * string.
- */
- if (MaxPtr == NULL || MaxLen == 0)
- {
- *IDStr = '\0';
- return;
- }
-
- /* Get word. */
- for (DestPtr = IDStr, tp = MaxPtr;
- *tp && *tp != ' ' && *tp != '\t';
- tp++)
- *DestPtr++ = *tp;
- *DestPtr = '\0';
-
- #if defined(UNPOST_DEBUG)
- printf("\tBinary ID: '%s'\n", IDStr);
- #endif
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : ParseIDLine() --- Extract the ID string, part number and
- | total number of parts from the ID line.
- |
- | Inputs : IDLine - Pointer to ID line.
- | PartREs - Array of part number parsing RE's.
- | Outputs : Elements - Aqquisition flags for the three items to
- | parse out, ID string, Segment number and
- | total number of segments.
- | SegInfo - Pointer to segment information buffer.
- -----------------------------------------------------------------------------*/
-
- static
- void ParseIDLine(char *IDLine,
- PART_RE *PartREs,
- int *Elements,
- SEG_INFO *SegInfo)
- {
- register int i;
- auto char **RetStrs;
- auto PART_RE *PartRec;
- auto char IDBfr[FL_NM_SZ];
-
- /* Externals used in this function. */
- extern FILE *ErrFile;
-
- /* Seach for a matching part number parsing regular expression. */
- for (PartRec = NULL, i = 0;
- PartREs[i].ReExpStr;
- i++)
- {
- /* Does this RE match the ID line? */
- if (ReMatch(IDLine,
- PartREs[i].Case,
- PartREs[i].ReExpr,
- &RetStrs) != 0)
- {
- #if defined(UNPOST_DEBUG)
- printf("\tExtract RE: /%s/\n", PartREs[i].ReExpStr);
- #endif
- PartRec = PartREs + i;
- break;
- }
- }
-
- /* If no match found, return. */
- if (PartRec == NULL)
- return;
-
- /* Get what elements we do not yet have. */
- for (i = ID_STRING; i <= NO_SEGMENTS; i++)
- {
- /* Get this element, if it is available. */
- switch ( i )
- {
- case 0: /* Get ID string. */
- /* Check for no ID string. */
- if (PartRec->IDStr == 0)
- break;
-
- /* Extract ID string from sub string. */
- GetBinID(RetStrs[ PartRec->IDStr ], IDBfr);
-
- /* Check to see if there was an ID string or not. */
- if (*IDBfr == '\0')
- {
- /* Is there an alternate regular expression for
- * extracting the binary ID string?
- */
- if (PartRec->AltIDStr > 0)
- {
- /* OK, try other side. */
- GetBinID(RetStrs[ PartRec->AltIDStr ], IDBfr);
- if (*IDBfr == '\0')
- break;
- }
- else
- break;
- }
-
- /* Duplicate the ID string. */
- if (SegInfo->IDString != NULL)
- free( SegInfo->IDString );
- SegInfo->IDString = StrDup( IDBfr );
- Elements[i] = 1;
- break;
- case 1: /* Get the segment number. */
- /* Check for no segment number. */
- if (PartRec->SegNo == 0)
- break;
-
- /* Get the segment number. */
- if ((SegInfo->SegNo = atoi( RetStrs[ PartRec->SegNo ] )) < 0)
- break;
- Elements[i] = 1;
- break;
- case 2: /* Get total number of segments. */
- /* Check for no total number of segments. */
- if (PartRec->NoSegs == 0)
- break;
-
- /* Get the total number of segments. */
- if ((SegInfo->NoSegs = atoi( RetStrs[ PartRec->NoSegs ] )) <= 0)
- break;
- Elements[i] = 1;
- break;
- }
- }
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : IdSearch() --- Search for an ID line.
- |
- | Inputs : InFlPtr - Input file pointer.
- | IdPtr - Pointer to ID RE hierarchy for this SEGMENT.
- | Outputs : Elements - Check list for data elements.
- | IDLine - Contains ID line.
- | UULnType - Type of UU encoded line found.
- | RetStrs - Returned sub strings from RE match.
- | SegInfo - Pointer to segment information buffer.
- |
- | Returns : Returns one of:
- -----------------------------------------------------------------------------*/
-
- static
- long IdSearch(FILE *InFlPtr,
- IDENT *IdPtr,
- int *Elements,
- char *IDLine,
- CHK_UU_ENC *UULnType,
- char ***RetStrs,
- SEG_INFO *SegInfo)
- {
- register int i;
- auto long LnOfs;
- auto int EncLen;
- auto IDENT *Hdr;
- auto IDENT *Body;
- extern FILE *ErrFile;
-
- /* Search forwards through the file for the first ID line. */
- for ( ; ; )
- {
- /* Get the current file offset. */
- LnOfs = ftell( InFlPtr );
-
- /* Get a line from the file. */
- if (ReadLine(InFlPtr, IDLine, BFR_SIZE) == EOF)
- {
- LnOfs = PRS_NO_UU_LN;
- break;
- }
-
- /* Is this a SEGMENT begin line? */
- if ( MatchSegment(IDLine, &Hdr, &Body) )
- {
- /* Position file pointer to start of line. */
- if (fseek(InFlPtr, LnOfs, SEEK_SET) != 0)
- {
- fprintf(ErrFile,
- "%s %d : Error - %s\n",
- __FILE__,
- __LINE__,
- sys_errlist[errno]);
- exit( 1 );
- }
-
- /* Return that no UU encoded line was found. */
- LnOfs = PRS_NO_UU_LN;
- break;
- }
-
- /* Is this a UUencoded line? */
- *UULnType = ChkUULine(IDLine, RetStrs, &EncLen);
- if (*UULnType == IS_UU_LINE ||
- *UULnType == UU_BEGIN ||
- *UULnType == UU_END)
- {
- /* Did we miss getting a piece of data we would like to
- * have?
- */
- if (Elements[SEGMENT_NO] == 0 && Elements[NO_SEGMENTS])
- {
- /* Error message. */
- fprintf(ErrFile,
- "%s %d : Error - Got number of segments but not ",
- __FILE__,
- __LINE__);
- fprintf(ErrFile,
- "segment number.\n");
-
- /* Check for totally idiotic mess. */
- if (SegInfo->NoSegs == 1)
- {
- /* Attempt assumption. */
- fprintf(ErrFile,
- "\tNumber of Segments: %d\n",
- SegInfo->NoSegs);
- fprintf(ErrFile,
- "\tAssuming Part 1 of 1\n");
- SegInfo->SegNo = SegInfo->NoSegs = 1;
- }
- else
- LnOfs = PRS_NO_SEG_NUM;
- }
- else if (Elements[SEGMENT_NO] && Elements[NO_SEGMENTS] == 0)
- {
- /* Error message. */
- fprintf(ErrFile,
- "%s %d : Error - Got segment number but not number ",
- __FILE__,
- __LINE__);
- fprintf(ErrFile,
- "of segments.\n");
-
- /* Check segment number. */
- if (SegInfo->SegNo == 1)
- {
- /* Attempt assumption. */
- fprintf(ErrFile,
- "Segment Number: %d\n\tAssuming Part 1 of 1\n",
- SegInfo->SegNo);
- SegInfo->SegNo = SegInfo->NoSegs = 1;
- }
- else
- LnOfs = PRS_NO_NUM_SEGS;
- }
- else if (Elements[SEGMENT_NO] == 0 && Elements[NO_SEGMENTS] == 0)
- SegInfo->SegNo = SegInfo->NoSegs = 1;
- break;
- }
-
- /* Is this an ID line? */
- for (i = 0; IdPtr[i].ReExprStr; i++)
- {
- /* Does this line match? */
- if (ReMatch(IDLine,
- CASE_SENSITIVE,
- IdPtr[i].ReExpr,
- RetStrs) != 0)
- {
- #if defined(UNPOST_DEBUG)
- printf("\n\tID Line: '%s'\n", IDLine);
- printf("\tBody RE: /%s/\n", IdPtr[i].ReExprStr);
- #endif
- /* Attempt to parse out one or more elements. */
- ParseIDLine(IDLine, IdPtr[i].IdParts, Elements, SegInfo);
- break;
- }
- }
- }
-
- /* Return status. */
- return( LnOfs );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : Header() --- Search for legal header ID lines.
- |
- | Inputs : InFlPtr - Input file pointer.
- | IdPtr - Pointer to ID RE hierarchy for this SEGMENT.
- | Outputs : Elements - Checklist for needed pieces of information.
- | IDLine - Contains ID line.
- | SegInfo - Pointer to segment information buffer.
- |
- | Returns : Returns one of:
- | PRS_NO_UU_LN - For no uuencoded line found in segment.
- | 1L - OK.
- -----------------------------------------------------------------------------*/
-
- static
- long Header(FILE *InFlPtr,
- IDENT *IdPtr,
- int *Elements,
- char *IDLine,
- SEG_INFO *SegInfo)
- {
- register int i;
- auto char **RetStrs;
- auto char *tp;
- extern FILE *ErrFile;
-
- /* Search forwards through the file for the first ID line. */
- for ( ; ; )
- {
- /* Is this an ID line? */
- for (i = 0; IdPtr[i].ReExprStr; i++)
- {
- /* Does this line match? */
- if (ReMatch(IDLine,
- CASE_SENSITIVE,
- IdPtr[i].ReExpr,
- &RetStrs) != 0)
- {
- #if defined(UNPOST_DEBUG)
- printf("\n\tID Line: '%s'\n", IDLine);
- printf("\tHeader RE: /%s/\n", IdPtr[i].ReExprStr);
- #endif
- /* Attempt to parse out one or more elements. */
- ParseIDLine(IDLine, IdPtr[i].IdParts, Elements, SegInfo);
- break;
- }
- }
-
- /* Get a line from the file. */
- if (ReadLine(InFlPtr, IDLine, BFR_SIZE) == EOF)
- return( PRS_NO_UU_LN );
-
- /* Check for a blank line, which is the header delimiter. */
- for (tp = IDLine; *tp == ' ' || *tp == '\t'; tp++)
- ;
- if (*tp == '\0' || *tp == '\n')
- break;
- }
-
- /* Return that no errors occured. */
- return( 1L );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : Parse() --- Parse out a SEGMENT and ID line.
- |
- | Inputs : InFlPtr - Input file pointer.
- | Outputs : SegLine - Contains the segment line.
- | IDLine - Contains ID line.
- | UULine - Contains the first UU encoded line.
- | SegInfo - Pointer to segment information buffer.
- |
- | Returns : Returns one of:
- | PRS_NO_SEGMENT - End of file found.
- | PRS_NO_UU_LN - No uuencoded line found in article.
- | PRS_NO_ID_STR - No ID string found at all.
- | PRS_NO_BEGIN - No uuencode begin line found in first
- | segment.
- -----------------------------------------------------------------------------*/
-
- long Parse(FILE *InFlPtr,
- char *SegLine,
- char *IDLine,
- SEG_INFO *SegInfo)
- {
- register int i;
- auto long LnOfs;
- auto char **RetStrs;
- auto IDENT *Hdr;
- auto IDENT *Body;
- auto CHK_UU_ENC UULnType;
- auto int Elements[NO_SEGMENTS + 1];
- auto char FlName[FL_NM_SZ];
-
- /* Externals used by this function. */
- extern FILE *ErrFile;
- extern int MsDosFileNms;
-
- /* Initialize the elements array to show that we have none of the
- * elements.
- */
- for (i = ID_STRING; i <= NO_SEGMENTS; i++)
- Elements[i] = 0;
-
- /* Search forwards through the file for the first SEGMENT
- * begin line.
- */
- for ( ; ; )
- {
- /* Get the current file offset. */
- LnOfs = ftell( InFlPtr );
-
- /* Get a line from the file. */
- if (ReadLine(InFlPtr, SegLine, BFR_SIZE) == EOF)
- return( PRS_NO_SEGMENT );
-
- /* Is this a SEGMENT begin line? */
- if ( MatchSegment(SegLine, &Hdr, &Body) )
- {
- #if defined(UNPOST_DEBUG)
- printf("Segment Begin: '%s'\n", SegLine);
- #endif
- strcpy(IDLine, SegLine);
- break;
- }
- }
-
- /* Initialize new segment. */
- SegInfo->SegOfs = LnOfs;
-
- /* Process header block. */
- LnOfs = Header(InFlPtr,
- Hdr,
- Elements,
- IDLine,
- SegInfo);
- if (LnOfs < 0L)
- return( LnOfs );
-
- /* Process body to end of segment or first UU line. */
- LnOfs = IdSearch(InFlPtr,
- Body,
- Elements,
- IDLine,
- &UULnType,
- &RetStrs,
- SegInfo);
- if (LnOfs < 0L)
- return( LnOfs );
-
- /* Is this the begin line? */
- SegInfo->UUOfs = LnOfs;
- if (UULnType != UU_BEGIN)
- {
- /* If this is segment number 1 and we did not find a begin line,
- * that is BIG trouble, so report an error.
- */
- if (SegInfo->SegNo == 1)
- {
- fprintf(ErrFile,
- "%s %d : Error - No begin line in first segment:\n",
- __FILE__,
- __LINE__);
- fprintf(ErrFile,
- "\tSegment: '%s'\n",
- SegLine);
- return( PRS_NO_BEGIN );
- }
- return( 0L );
- }
-
- /* Get file name from begin line. */
- GetBinFlNm(InFlPtr, RetStrs, FlName);
- #if defined(UNPOST_DEBUG)
- printf("\tFile Name: '%s'\n", FlName);
- #endif
-
- /* Return no errors occurred. */
- if ( *FlName )
- SegInfo->FlName = StrDup( FlName );
- return( 0L );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : FreeCfg() --- Free a configuration that was created by
- | reading a configuration file.
- -----------------------------------------------------------------------------*/
-
- static
- void FreeCfg(void)
- {
- register int i;
- register int j;
- register int k;
-
- /* If the default configuration is in place, do nothing, else
- * free the old configuration.
- */
- if (Segments != NnSegs && Segments != RnSegs &&
- Segments != GroupsSegs && Segments != EmailSegs)
- {
- /* Free all ID prefix lists in SEGMENT list. */
- for (i = 0; Segments[i].ReExprStr; i++)
- {
- /* Free all ID part lists in ID prefix list. */
- for (j = 0;
- Segments[i].Header[j].ReExprStr;
- j++)
- {
- /* Free all part extraction RE's, etc. */
- for (k = 0;
- Segments[i].Header[j].IdParts[k].ReExpStr;
- k++)
- {
- free( Segments[i].Header[j].IdParts[k].ReExpStr );
- FreeReExpr( Segments[i].Header[j].IdParts[k].ReExpr );
- }
-
- /* Free list memory and regular expression. */
- free( Segments[i].Header[j].IdParts );
- free( Segments[i].Header[j].ReExprStr );
- (void) FreeReExpr( Segments[i].Header[j].ReExpr );
- }
- free( Segments[i].Header );
-
- /* Free all ID part lists in ID prefix list. */
- for (j = 0;
- Segments[i].Body[j].ReExprStr;
- j++)
- {
- /* Free all part extraction RE's, etc. */
- for (k = 0;
- Segments[i].Body[j].IdParts[k].ReExpStr;
- k++)
- {
- free( Segments[i].Body[j].IdParts[k].ReExpStr );
- FreeReExpr( Segments[i].Body[j].IdParts[k].ReExpr );
- }
-
- /* Free list memory and regular expression. */
- free( Segments[i].Body[j].IdParts );
- free( Segments[i].Body[j].ReExprStr );
- (void) FreeReExpr( Segments[i].Body[j].ReExpr );
- }
- free( Segments[i].Body );
-
- /* Free the regular expression graph for the segment. */
- free( Segments[i].ReExprStr );
- (void) FreeReExpr( Segments[i].ReExpr );
- }
-
- /* Free SEGMENT list. */
- free( Segments );
- }
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : SetSegBegin() --- Set the segment begin line regular
- | expression.
- |
- | Inputs : SegType - Either 'e', 'g', 'n', 'm', 'r'.
- -----------------------------------------------------------------------------*/
-
- void SetSegBegin(char *SegType)
- {
- register int i;
-
- /* Free any previously allocated configurations (configurations
- * read in from a config file only.
- */
- FreeCfg();
-
- /* Determine which type, based on input string. */
- switch ( tolower( *SegType ) )
- {
- case 'e':
- Segments = EmailSegs;
- break;
- case 'g':
- Segments = GroupsSegs;
- break;
- case 'n':
- Segments = NnSegs;
- break;
- case 'r':
- default:
- Segments = RnSegs;
- break;
- }
-
- /* Compile SEGMENT begin RE's. */
- for (i = 0; Segments[i].ReExprStr; i++)
- if (Segments[i].ReExpr == NULL)
- Segments[i].ReExpr = ReCompile( Segments[i].ReExprStr );
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : CompCfg() --- Compile a configuration.
- -----------------------------------------------------------------------------*/
-
- static
- void CompCfg(void)
- {
- register int i;
- register int j;
- register int k;
- auto PART_RE *PartPtr;
- auto IDENT *IdPtr;
- auto SEGMENT *SegPtr;
-
- /* Compile the regular expressions. */
- for (i = 0; Segments[i].ReExprStr; i++)
- {
- /* Compile the unique SEGMENT line prefix. */
- SegPtr = Segments + i;
- if (SegPtr->ReExpr == NULL)
- SegPtr->ReExpr = ReCompile( SegPtr->ReExprStr );
-
- /* Compile all Header ID line information. */
- for (j = 0; SegPtr->Header[j].ReExprStr; j++)
- {
- /* Compile the unique ID line prefix. */
- IdPtr = SegPtr->Header + j;
- IdPtr->ReExpr = ReCompile( IdPtr->ReExprStr );
-
- /* Compile the part number parsing RE's. */
- for (k = 0; IdPtr->IdParts[k].ReExpStr; k++)
- {
- PartPtr = IdPtr->IdParts + k;
- PartPtr->ReExpr = ReCompile( PartPtr->ReExpStr );
- }
- }
-
- /* Compile all Body ID line information. */
- for (j = 0; SegPtr->Body[j].ReExprStr; j++)
- {
- /* Compile the unique Body ID line prefix. */
- IdPtr = SegPtr->Body + j;
- IdPtr->ReExpr = ReCompile( IdPtr->ReExprStr );
-
- /* Compile the part number parsing RE's. */
- for (k = 0; IdPtr->IdParts[k].ReExpStr; k++)
- {
- PartPtr = IdPtr->IdParts + k;
- PartPtr->ReExpr = ReCompile( PartPtr->ReExpStr );
- }
- }
- }
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : LoadCfg() --- Load a configuration file.
- |
- | Inputs : CfgFlNm - Configuration file name.
- -----------------------------------------------------------------------------*/
-
- void LoadCfg(char *CfgFlNm)
- {
- extern FILE *ErrFile;
-
- /* Check for reading a configuration file. */
- if (CfgFlNm == NULL || *CfgFlNm == '\0')
- {
- fprintf(ErrFile,
- "%s %d : Error - Missing configuraiton file name.\n",
- __FILE__,
- __LINE__);
- return;
- }
-
- /* Free any previously allocated configuration trees. */
- FreeCfg();
-
- /* Parse configuration file. */
- Segments = ReadConfig( CfgFlNm );
-
- /* Compile the configuration. */
- CompCfg();
- }
-
- /*-----------------------------------------------------------------------------
- | Routine : ParseInit() --- Compile regular expressions here that will
- | not change during run time, and compile the default
- | configuration.
- -----------------------------------------------------------------------------*/
-
- void ParseInit(void)
- {
- /* Compile the RN default configuration. */
- CompCfg();
-
- /* Compile the UU encoding RE's. */
- Begin = ReCompile( BeginStr );
- End = ReCompile( EndStr );
- }
-