home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / unpost / part04 / segment.c < prev   
Encoding:
C/C++ Source or Header  |  1993-04-18  |  23.3 KB  |  748 lines

  1. /******************************************************************************
  2. * Module    :   Segment --- Find the segments of the posted file.
  3. *
  4. * Author    :   John W. M. Stevens
  5. ******************************************************************************/
  6.  
  7. #include    "compiler.h"
  8.  
  9. #include    "unpost.h"
  10. #include    "list.h"
  11. #include    "modflnm.h"
  12. #include    "parse.h"
  13. #include    "decode.h"
  14. #include    "uudec.h"
  15. #include    "segment.h"
  16. #include    "utils.h"
  17.  
  18. /*  Segment types.  */
  19. typedef enum    {
  20.     SEG_USED,           /*  Used in succesful decoding.                     */
  21.     SEG_TEXT,           /*  Pure text segment.                              */
  22.     SEG_INCOMP,         /*  Segment that is part of incomplete posting.     */
  23.     SEG_DESC            /*  Segment is a description.                       */
  24. } SEG_TYPE;
  25.  
  26. /*  Segment list structure. */
  27. typedef struct  {
  28.     long    LnOfs;          /*  Byte offset to start of SEGMENT.        */
  29.     int     CopyFlag;       /*  Copy out flag.                          */
  30. } SEG_LIST;
  31.  
  32. /*  Line and string buffers.    */
  33. char    SegLine[BFR_SIZE];
  34. char    IDLine[BFR_SIZE];
  35. char    UULine[BFR_SIZE];
  36. char    InBfr[BFR_SIZE];
  37. BYTE    OutBfr[BFR_SIZE];
  38.  
  39. /*-----------------------------------------------------------------------------
  40. | Routine   :   UUDecode() --- Decode a UU encoded file.
  41. |
  42. | Inputs    :   FlName  - Name of input file.
  43. -----------------------------------------------------------------------------*/
  44.  
  45. void    UUDecode(char   *InFlNm)
  46. {
  47.     auto        FILE    *InFlPtr;
  48.     auto        FILE    *OutFlPtr;
  49.     auto        int     OutLen;
  50.     auto        char    **RetStrs;
  51.     auto        char    FlName[FL_NM_SZ];
  52.  
  53.     /*  Externals used by this function.    */
  54.     extern      FILE            *ErrFile;
  55.  
  56.     /*  Open file.  */
  57.     if ((InFlPtr = fopen(InFlNm, BIN_READ)) == NULL)
  58.     {
  59.         fprintf(ErrFile,
  60.                 "%s %d : Error - could not open file '%s' for reading.\n",
  61.                 __FILE__,
  62.                 __LINE__,
  63.                 InFlNm);
  64.         return;
  65.     }
  66.  
  67.     /*  Get all uuencoded files from single file.   */
  68.     while (! feof( InFlPtr ))
  69.     {
  70.         /*  Search forwards through the file for the first
  71.         *   UU encoded line.
  72.         */
  73.         do
  74.         {
  75.             /*  Get a line from the file.   */
  76.             if (ReadLine(InFlPtr, InBfr, BFR_SIZE) == EOF)
  77.             {
  78.                 fclose( InFlPtr );
  79.                 return;
  80.             }
  81.         } while (! MatchBegin(InBfr, &RetStrs));
  82.  
  83.         /*  Get the binary file name.   */
  84.         GetBinFlNm(InFlPtr, RetStrs, FlName);
  85.  
  86.         /*  Check to make sure that file does not already exist.    */
  87.         if ( FileExists( FlName ) )
  88.         {
  89.             fprintf(ErrFile,
  90.                     "%s %d : Error - file '%s' already exists.\n",
  91.                     __FILE__,
  92.                     __LINE__,
  93.                     FlName);
  94.             fclose( InFlPtr );
  95.             return;
  96.         }
  97.  
  98.         /*  Open the file.  */
  99.         if ((OutFlPtr = fopen(FlName, BIN_WRITE)) == NULL)
  100.         {
  101.             fprintf(ErrFile,
  102.                     "%s %d : Error - %s\n\t'%s'\n",
  103.                     __FILE__,
  104.                     __LINE__,
  105.                     sys_errlist[errno],
  106.                     FlName);
  107.             fclose( InFlPtr );
  108.             return;
  109.         }
  110.  
  111.         /*  It exists, is open, and ready to roll.  Now decode to
  112.         *   end line.
  113.         */
  114.         while (ReadLine(InFlPtr, InBfr, BFR_SIZE) != EOF)
  115.         {
  116.             /*  Test for end line.  */
  117.             if ( MatchEnd( InBfr ) )
  118.                 break;
  119.  
  120.             /*  Space pad line, if necesary.    */
  121.             DecTruncUULn(InBfr, &OutLen, OutBfr);
  122.  
  123.             /*  Are there any bytes to write?   */
  124.             if (OutLen < 1)
  125.                 continue;
  126.  
  127.             /*  Write the buffer to the output file.    */
  128.             if (fwrite(OutBfr, 1, OutLen, OutFlPtr) != OutLen)
  129.             {
  130.                 fprintf(ErrFile,
  131.                         "\t%s %d : Error - Bad write to binary file.\n",
  132.                         __FILE__,
  133.                         __LINE__);
  134.                 exit( 1 );
  135.             }
  136.         }
  137.  
  138.         /*  Close output file.  */
  139.         fclose( OutFlPtr );
  140.     }
  141.  
  142.     /*  Close input file.   */
  143.     fclose( InFlPtr );
  144. }
  145.  
  146. /*-----------------------------------------------------------------------------
  147. | Routine   :   Single() --- Decode binarys, assumed to be in sorted order.
  148. |               already.
  149. |
  150. | Inputs    :   FileNm  - Name of file that contains single binary.
  151. -----------------------------------------------------------------------------*/
  152.  
  153. void    Single(char     *FileNm)
  154. {
  155.     auto        long            LnOfs;
  156.     auto        CHK_UU_ENC      UULnType;
  157.     auto        char            **RetStrs;
  158.     auto        int             OutLen;
  159.     auto        FILE            *InFlPtr;
  160.     auto        FILE            *OutFlPtr;
  161.     auto        char            FlName[FL_NM_SZ];
  162.  
  163.     /*  Externals used by this function.    */
  164.     extern      FILE            *ErrFile;
  165.  
  166.     /*  Open file.  */
  167.     if ((InFlPtr = fopen(FileNm, BIN_READ)) == NULL)
  168.     {
  169.         fprintf(ErrFile,
  170.                 "%s %d : Error - could not open file '%s' for reading.\n",
  171.                 __FILE__,
  172.                 __LINE__,
  173.                 FileNm);
  174.         return;
  175.     }
  176.  
  177.  
  178.     /*  Get all uuencoded files from single file.   */
  179.     while (! feof( InFlPtr ))
  180.     {
  181.         /*  Search forwards through the file for the first UU encoded line. */
  182.         do
  183.         {
  184.             /*  Get the current file offset.    */
  185.             LnOfs = ftell( InFlPtr );
  186.  
  187.             /*  Get a line from the file.   */
  188.             if (ReadLine(InFlPtr, InBfr, BFR_SIZE) == EOF)
  189.              {
  190.                 fclose( InFlPtr );
  191.                 return;
  192.             }
  193.  
  194.             /*  Check to see if this is a UUencoded line.   */
  195.             UULnType = ChkUULine(InBfr, &RetStrs, &OutLen);
  196.  
  197.         } while (UULnType != UU_BEGIN);
  198.  
  199.         /*  Get the binary file name.   */
  200. UnExpectedBegin:
  201.         GetBinFlNm(InFlPtr, RetStrs, FlName);
  202.  
  203.         /*  Check to make sure that file does not already exist.    */
  204.         if ( FileExists( FlName ) )
  205.         {
  206.             fprintf(ErrFile,
  207.                     "%s %d : Error - file '%s' already exists.\n",
  208.                     __FILE__,
  209.                     __LINE__,
  210.                     FlName);
  211.             continue;
  212.         }
  213.  
  214.         /*  Open the file.  */
  215.         if ((OutFlPtr = fopen(FlName, BIN_WRITE)) == NULL)
  216.         {
  217.             fprintf(ErrFile,
  218.                     "%s %d : Error - %s\n\t'%s'\n",
  219.                     __FILE__,
  220.                     __LINE__,
  221.                     sys_errlist[errno],
  222.                     FlName);
  223.             continue;
  224.         }
  225.  
  226.         /*  Now munch and crunch until done with file.  */
  227.         do
  228.         {
  229.             /*  Decode a segment.   */
  230.             DecSeg(InFlPtr, OutFlPtr, &UULnType);
  231.  
  232.             /*  Check for proper exit conditions.   */
  233.             if (UULnType == UU_BEGIN ||
  234.                 UULnType == UU_END)
  235.                 break;
  236.  
  237.             /*  Scan to next UU encoded line.   */
  238.             do
  239.             {
  240.                 /*  Get the current file offset.    */
  241.                 LnOfs = ftell( InFlPtr );
  242.  
  243.                 /*  Get next line.  */
  244.                 if (ReadLine(InFlPtr, InBfr, BFR_SIZE) == EOF)
  245.                 {
  246.                     fprintf(ErrFile,
  247.                             "%s %d : Error - Unexpected end of file.\n",
  248.                             __FILE__,
  249.                             __LINE__);
  250.                     fclose( InFlPtr );
  251.                     fclose( OutFlPtr );
  252.                     return;
  253.                 }
  254.  
  255.                  /*  Check to see if this is a UUencoded line.   */
  256.                 UULnType = ChkUULine(InBfr, &RetStrs, &OutLen);
  257.  
  258.             } while (UULnType == NOT_UU_LINE || UULnType == UU_SPACE);
  259.  
  260.             /*  Reset file pointer to begining of UU line.  */
  261.             if (fseek(InFlPtr, LnOfs, SEEK_SET) != 0)
  262.             {
  263.                 fprintf(ErrFile,
  264.                         "%s %d : Error - %s\n",
  265.                         __FILE__,
  266.                         __LINE__,
  267.                         sys_errlist[errno]);
  268.                 exit( 1 );
  269.             }
  270.  
  271.         } while (UULnType == IS_UU_LINE);
  272.  
  273.         /*  Close the output file pointer.  */
  274.         fclose( OutFlPtr );
  275.  
  276.         /*  Check the various types.    */
  277.         if (UULnType == UU_BEGIN)
  278.         {
  279.             fprintf(ErrFile,
  280.                     "%s %d : Error - Unexpected UU begin line.\n",
  281.                     __FILE__,
  282.                     __LINE__);
  283.             goto UnExpectedBegin;
  284.         }
  285.     }
  286.  
  287.     /*  Close the files.    */
  288.     fclose( InFlPtr );
  289. }
  290.  
  291. /*-----------------------------------------------------------------------------
  292. | Routine   :   CmpFl() --- Compare two file list entries.
  293. |
  294. | Inputs    :   File1   - File entry one.
  295. |               File2   - File entry two.
  296. -----------------------------------------------------------------------------*/
  297.  
  298. static
  299. int     CmpFl(void  *File1,
  300.               void  *File2)
  301. {
  302.     return( strcmp(((FL_LIST *) File1)->IDString,
  303.                    ((FL_LIST *) File2)->IDString) );
  304. }
  305.  
  306. /*-----------------------------------------------------------------------------
  307. | Routine   :   DumpSeg() --- Dump a segment to a file.
  308. |
  309. | Inputs    :   InFlPtr     - File to read segment from (source file).
  310. |               OutFlPtr    - File to write segment to.
  311. |               NextSeg     - Start of next segment.
  312. -----------------------------------------------------------------------------*/
  313.  
  314. static
  315. void    DumpSeg(FILE    *InFlPtr,
  316.                 FILE    *OutFlPtr,
  317.                 long    NextSeg)
  318. {
  319.     /*  Dump segment to output file.    */
  320.     while (ReadLine(InFlPtr, SegLine, BFR_SIZE) != EOF)
  321.     {
  322.         /*  Print line. */
  323.         fprintf(OutFlPtr, "%s\n", SegLine);
  324.  
  325.         /*  Get next line offset.   */
  326.         if (ftell( InFlPtr ) == NextSeg)
  327.             break;
  328.     }
  329. }
  330.  
  331. /*-----------------------------------------------------------------------------
  332. | Routine   :   Multiple() --- Extract multiple postings from one file.
  333. |
  334. | Inputs    :   FileNm  - Name of file to unpost.
  335. -----------------------------------------------------------------------------*/
  336.  
  337. void    Multiple(char       *FileNm)
  338. {
  339.     register    int             i;
  340.     register    int             j;
  341.     auto        FILE            *InFlPtr;
  342.     auto        FILE            *OutFlPtr;
  343.     auto        long            LnOfs;
  344.     auto        int             InsPt;
  345.     auto        SEG_INFO        SegInfo;
  346.     auto        FL_LIST         *FlPtr;
  347.     auto        FL_LIST         NewFile;
  348.     auto        SEG_LIST        *SegPtr;
  349.     auto        SEG_LIST        NewSeg;
  350.  
  351.     /*  Buffers for input and output.   */
  352.     static      LIST            *FileList;
  353.     static      LIST            *SegList;
  354.     extern      int             MsDosFileNms;
  355.     extern      int             DumpDesc;
  356.     extern      int             SepIncomps;
  357.     extern      FILE            *ErrFile;
  358.     extern      FILE            *TextFile;
  359.     extern      FILE            *IncompFile;
  360.  
  361.     /*  Open file.  */
  362.     if ((InFlPtr = fopen(FileNm, BIN_READ)) == NULL)
  363.     {
  364.         fprintf(ErrFile,
  365.                 "%s %d : Error - could not open file '%s' for reading.\n",
  366.                 __FILE__,
  367.                 __LINE__,
  368.                 FileNm);
  369.         return;
  370.     }
  371.  
  372.     /*  Allocate a file and a segment list.    */
  373.     FileList = CrtList( sizeof( FL_LIST ) );
  374.     SegList = CrtList( sizeof( SEG_LIST ) );
  375.  
  376.     /*  Search for all ID lines, building a list of all
  377.     *   files and their segments as we go.
  378.     */
  379.     while (! feof( InFlPtr ))
  380.     {
  381.         /*  Parse article information out of the file.  */
  382.         memset(&SegInfo, 0, sizeof( SEG_INFO ));
  383.         LnOfs = Parse(InFlPtr,
  384.                       SegLine,
  385.                       IDLine,
  386.                       &SegInfo);
  387.  
  388. #if defined(UNPOST_DEBUG)
  389. printf("\n\tSegInfo:\n");
  390. printf("\t--------\n");
  391. printf("\tNumber of Segments: %d\n", SegInfo.NoSegs);
  392. printf("\tSegment Number    : %d\n", SegInfo.SegNo);
  393. printf("\tSegment Offset    : %ld\n", SegInfo.SegOfs);
  394. printf("\tUUencode Offset   : %ld\n", SegInfo.UUOfs);
  395. printf("\tBinary ID String  : '%s'\n",
  396.        (SegInfo.IDString == NULL) ? "NULL POINTER"
  397.                                   : SegInfo.IDString);
  398. printf("\tBinary File Name  : '%s'\n\n",
  399.        (SegInfo.FlName == NULL) ? "NULL POINTER"
  400.                                 : SegInfo.FlName);
  401.  
  402. switch ( LnOfs )
  403. {
  404. case -1L:
  405.     printf("\tPRS_NO_SEGMENT\n");
  406.     break;
  407. case -2L:
  408.     printf("\tPRS_NO_ID_STR\n");
  409.     break;
  410. case -3L:
  411.     printf("\tPRS_NO_UU_LN\n");
  412.     break;
  413. case -4L:
  414.     printf("\tPRS_NO_BEGIN\n");
  415.     break;
  416. case -5L:
  417.     printf("\tPRS_NO_SEG_NUM\n");
  418.     break;
  419. case -6L:
  420.     printf("\tPRS_NO_NUM_SEGS\n");
  421.     break;
  422. case -7L:
  423.     printf("\tPRS_UNX_END_SEG\n");
  424.     break;
  425. }
  426. #endif
  427.  
  428.         /*  Save the segment data.  */
  429.         NewSeg.LnOfs = SegInfo.SegOfs;
  430.  
  431.         /*  Check for errors.   */
  432.         if (LnOfs == PRS_NO_SEGMENT)
  433.             break;
  434.         else if (LnOfs == PRS_NO_UU_LN)
  435.         {
  436.             /*  Check to see if this is a description segment.  */
  437.             if (SegInfo.IDString &&
  438.                 *SegInfo.IDString  &&
  439.                 SegInfo.SegNo == 0 &&
  440.                 SegInfo.NoSegs > 0)
  441.             {
  442.                 /*  This has part numbering info, and the part number
  443.                 *   is zero, but it has no uuencoded data, so this
  444.                 *   must be a description segement.
  445.                 */
  446.                 NewSeg.CopyFlag = SEG_DESC;
  447.             }
  448.             else
  449.             {
  450.                 /*  Save as text segment.   */
  451.                 NewSeg.CopyFlag = SEG_TEXT;
  452.                 SegList = AppList(SegList, &NewSeg);
  453.  
  454.                 /*  If the file name or ID string exist, deallocate.    */
  455.                 if ( SegInfo.IDString )
  456.                     free( SegInfo.IDString );
  457.                 continue;
  458.             }
  459.         }
  460.         else if (LnOfs == PRS_NO_SEG_NUM  ||
  461.                  LnOfs == PRS_NO_NUM_SEGS ||
  462.                  SegInfo.IDString == NULL ||
  463.                  *SegInfo.IDString == '\0')
  464.         {
  465.             /*  Something important is missing.  Do NOT attempt to
  466.             *   put one of these in the file list.
  467.             */
  468.             NewSeg.CopyFlag = SEG_INCOMP;
  469.             SegList = AppList(SegList, &NewSeg);
  470.  
  471.             /*  If the file name or ID string exist, deallocate.    */
  472.             if ( SegInfo.IDString )
  473.                 free( SegInfo.IDString );
  474.             continue;
  475.         }
  476.         else
  477.             NewSeg.CopyFlag = SEG_INCOMP;
  478.  
  479.         /*  Add segment to list.  */
  480.         SegList = AppList(SegList, &NewSeg);
  481.  
  482.         /*  Search file list for ID string. */
  483.         NewFile.IDString = SegInfo.IDString;
  484.         if (SrchList(FileList, &NewFile, CmpFl, &InsPt) == FALSE)
  485.         {
  486.             /*  Did not find file in list, add a new file.  First,
  487.             *   allocate segments buffer.
  488.             */
  489.             if ((NewFile.Segs = (SEGS *)
  490.                  calloc(SegInfo.NoSegs + 1, sizeof( SEGS ))) == NULL)
  491.             {
  492.                 fprintf(ErrFile,
  493.                         "%s %d : Error - out of memory.\n",
  494.                         __FILE__,
  495.                         __LINE__);
  496.                 exit( 1 );
  497.             }
  498.  
  499.             /*  We have a valid ID line, and at least one UUencoded
  500.             *   line, so add this segment to the list.
  501.             */
  502.             NewFile.NoSegs = SegInfo.NoSegs;
  503.             NewFile.FlName = NULL;
  504.             NewFile.Success = 0;
  505.             FileList = AddList(FileList, &NewFile, InsPt);
  506.         }
  507.         else
  508.             free( SegInfo.IDString );
  509.         FlPtr = ListIdx(FileList, InsPt);
  510.  
  511.         /*  Check for irreconcilable differences.   */
  512.         if (FlPtr->NoSegs < SegInfo.SegNo)
  513.         {
  514.             fprintf(ErrFile,
  515.                     "%s %d : Error - Segment number #%d greater than number",
  516.                     __FILE__,
  517.                     __LINE__,
  518.                     SegInfo.SegNo);
  519.             fprintf(ErrFile,
  520.                     " of segments in:\n\tSegment: '%s'\n",
  521.                     SegLine);
  522.         }
  523.         else
  524.         {
  525.             /*  Save the offset in the proper segment location. */
  526.             if (FlPtr->Segs[SegInfo.SegNo].SegNo != 0)
  527.             {
  528.                 fprintf(ErrFile,
  529.                         "%s %d : Warning - duplicate segment #%d in:\n",
  530.                         __FILE__,
  531.                         __LINE__,
  532.                         SegInfo.SegNo);
  533.                 fprintf(ErrFile,
  534.                         "\tBinary ID: '%s'\n",
  535.                         FlPtr->IDString);
  536.             }
  537.  
  538.             /*  Set up file descriptor segment. */
  539.             FlPtr->Segs[SegInfo.SegNo].Exists = 1;
  540.             FlPtr->Segs[SegInfo.SegNo].SegNo = SegInfo.SegNo;
  541.             FlPtr->Segs[SegInfo.SegNo].SegOfs = SegInfo.SegOfs;
  542.             FlPtr->Segs[SegInfo.SegNo].UUOfs  = SegInfo.UUOfs;
  543.             FlPtr->Segs[SegInfo.SegNo].SegLstOrd = SegList->NoElems - 1;
  544.         }
  545.  
  546.         /*  Add the file name string, if it isn't already present.  */
  547.         if ( FlPtr->FlName )
  548.             free( SegInfo.FlName );
  549.         else if ( SegInfo.FlName )
  550.             FlPtr->FlName = SegInfo.FlName;
  551.     }
  552.  
  553.     /*  Dump Table. */
  554.     fprintf(ErrFile, "File ID                         Segments\n");
  555.     fprintf(ErrFile, "----------------------------------------\n");
  556.     for (i = 0; i < FileList->NoElems; i++)
  557.     {
  558.         FlPtr = ListIdx(FileList, i);
  559.         fprintf(ErrFile,
  560.                 "%-30.30s  %d\n",
  561.                 FlPtr->IDString,
  562.                 FlPtr->NoSegs);
  563.         for (j = 1; j <= FlPtr->NoSegs; j++)
  564.             fprintf(ErrFile, "\t%d  %ld\n",
  565.                     FlPtr->Segs[j].SegNo,
  566.                     FlPtr->Segs[j].SegOfs);
  567.     }
  568.     fprintf(ErrFile, "\n");
  569.  
  570.     /*  Decode the files.   */
  571.     for (i = 0; i < FileList->NoElems; i++)
  572.     {
  573.         /*  Get pointer to file list entry. */
  574.         FlPtr = ListIdx(FileList, i);
  575.  
  576.         /*  Report binary id you are attempting to decode.  */
  577.         fprintf(ErrFile,
  578.                 "Decoding Binary ID: '%s'\n",
  579.                 FlPtr->IDString);
  580.  
  581.         /*  Attempt to decode the file. */
  582.         if (DeCode(InFlPtr, FlPtr) == OK)
  583.         {
  584.             /*  Scan segment list, marking all segments as having been
  585.             *   successfully used.
  586.             */
  587.             FlPtr->Success = 1;
  588.             for (j = 1; j <= FlPtr->NoSegs; j++)
  589.             {
  590.                 SegPtr = ListIdx(SegList, FlPtr->Segs[j].SegLstOrd);
  591.                 SegPtr->CopyFlag = SEG_USED;
  592.             }
  593.         }
  594.     }
  595.  
  596.     /*  Do we want to save incomplete pieces?   */
  597.     if (IncompFile || SepIncomps)
  598.     {
  599.         /*  Write incomplete binaries to uuencoded file in sorted
  600.         *   order.
  601.         */
  602.         for (i = 0; i < FileList->NoElems; i++)
  603.         {
  604.             auto    long    EndOfs;
  605.  
  606.             /*  Get pointer to file.    */
  607.             FlPtr = ListIdx(FileList, i);
  608.             if ( FlPtr->Success )
  609.                 continue;
  610.  
  611.             /*  Open file to write segments to, or use incompletes
  612.             *   file.
  613.             */
  614.             if (SepIncomps && FlPtr->IDString && *FlPtr->IDString)
  615.             {
  616.                 /*  Use the binary ID string to create a .uue file name.
  617.                 */
  618.                 if ( MsDosFileNms )
  619.                     ModifyFlNm(FlPtr->IDString, ".uue", InBfr);
  620.                 else
  621.                     ModExten(FlPtr->IDString, ".uue", InBfr);
  622.  
  623.                 /*  Open incompletes file.  */
  624.                 if ((OutFlPtr = fopen(InBfr, TXT_APPEND)) == NULL)
  625.                 {
  626.                     fprintf(ErrFile,
  627.                             "%s %d : Error - File '%s' cannot be opened ",
  628.                             __FILE__,
  629.                             __LINE__,
  630.                             InBfr);
  631.                     fprintf(ErrFile,
  632.                             "for appending.\n");
  633.                     continue;
  634.                 }
  635.             }
  636.             else
  637.                 OutFlPtr = IncompFile;
  638.  
  639.             /*  This file was NOT successfully converted, write it's
  640.             *   segments out to the incomplete file.
  641.             */
  642.             for (j = 0; j <= FlPtr->NoSegs; j++)
  643.             {
  644.                 /*  If this segment does not exist, do not copy it. */
  645.                 if (! FlPtr->Segs[j].Exists)
  646.                     continue;
  647.                 else if (j == 0 && ! DumpDesc)
  648.                     continue;
  649.  
  650.                 /*  Position file pointer to first line of segment. */
  651.                 if (fseek(InFlPtr, FlPtr->Segs[j].SegOfs, SEEK_SET) != 0)
  652.                 {
  653.                     fprintf(ErrFile,
  654.                             "%s %d : Error - %s\n",
  655.                             __FILE__,
  656.                             __LINE__,
  657.                             sys_errlist[errno]);
  658.                     exit( 1 );
  659.                 }
  660.  
  661.                 /*  Mark this segment as having been dumped out.    */
  662.                 SegPtr = ListIdx(SegList, FlPtr->Segs[j].SegLstOrd);
  663.                 SegPtr->CopyFlag = SEG_USED;
  664.  
  665.                 /*  Get offset for end of segment.  */
  666.                 if (FlPtr->Segs[j].SegLstOrd + 1 < SegList->NoElems)
  667.                     EndOfs = SegPtr[1].LnOfs;
  668.                 else
  669.                     EndOfs = -1L;
  670.  
  671.                 /*  Write all of segment to file.   */
  672.                 DumpSeg(InFlPtr, OutFlPtr, EndOfs);
  673.             }
  674.  
  675.             /*  Check to see if we need to close the file.  */
  676.             if (OutFlPtr != IncompFile)
  677.                 fclose( OutFlPtr );
  678.         }
  679.     }
  680.  
  681.     /*  Check to make sure that the user has requested that unused
  682.     *   segments be dumped out to ANY file.
  683.     */
  684.     if (TextFile || IncompFile)
  685.     {
  686.         /*  Dump unused segments to file.   */
  687.         for (i = 0, SegPtr = ListIdx(SegList, 0);
  688.              i < SegList->NoElems;
  689.              i++, SegPtr++)
  690.         {
  691.             /*  If this segment was successfully converted, do not
  692.             *   copy it.
  693.             */
  694.             if (SegPtr->CopyFlag == SEG_USED)
  695.                 continue;
  696.  
  697.             /*  Position file pointer to first UUencoded
  698.             *   line of segment.
  699.             */
  700.             if (fseek(InFlPtr, SegPtr->LnOfs, SEEK_SET) != 0)
  701.             {
  702.                 fprintf(ErrFile,
  703.                         "%s %d : Error - %s\n",
  704.                         __FILE__,
  705.                         __LINE__,
  706.                         sys_errlist[errno]);
  707.                 exit( 1 );
  708.             }
  709.  
  710.             /*  Read and write lines.   */
  711.             if (SegPtr->CopyFlag == SEG_TEXT && TextFile)
  712.             {
  713.                 /*  Dump the segment out to the text file.  */
  714.                 DumpSeg(InFlPtr,
  715.                         TextFile,
  716.                         (i < SegList->NoElems - 1)
  717.                             ? SegPtr[1].LnOfs
  718.                             : -1L);
  719.             }
  720.             else if (SegPtr->CopyFlag == SEG_INCOMP && IncompFile)
  721.             {
  722.                 /*  Dump the segment out to the text file.  */
  723.                 DumpSeg(InFlPtr,
  724.                         IncompFile,
  725.                         (i < SegList->NoElems - 1)
  726.                             ? SegPtr[1].LnOfs
  727.                             : -1L);
  728.             }
  729.         }
  730.     }
  731.  
  732.     /*  Deallocate file descriptor list.    */
  733.     for (i = 0; i < FileList->NoElems; i++)
  734.     {
  735.         /*  Get pointer to file list entry. */
  736.         FlPtr = ListIdx(FileList, i);
  737.  
  738.         /*  Deallocate the heap memory. */
  739.         free( FlPtr->Segs );
  740.         free( FlPtr->FlName );
  741.         free( FlPtr->IDString );
  742.     }
  743.  
  744.     /*  Free the list.  */
  745.     free( FileList );
  746.     free( SegList );
  747. }
  748.