home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / unpost / part05 / decode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-18  |  12.1 KB  |  401 lines

  1. /******************************************************************************
  2. * Module    :   UUdecode --- Test for and decode a uuencoded text.
  3. *
  4. * Author    :   John W. M. Stevens
  5. ******************************************************************************/
  6.  
  7. #include    "compiler.h"
  8.  
  9. #include    "unpost.h"
  10. #include    "regexp.h"
  11. #include    "parse.h"
  12. #include    "uudec.h"
  13. #include    "decode.h"
  14. #include    "modflnm.h"
  15. #include    "utils.h"
  16.  
  17. /*-----------------------------------------------------------------------------
  18. | Routine   :   OpenBinFile() --- Find the begin line, and open the output
  19. |               binary file.
  20. |
  21. | Inputs    :   InFlPtr - Pointer to input source file.
  22. |               InBfr   - Buffer to read lines into when searching for
  23. |                         begin line.
  24. |
  25. | Returns   :   Pointer to the binary file to write to.
  26. -----------------------------------------------------------------------------*/
  27.  
  28. static
  29. FILE        *OpenBinFile(FILE   *InFlPtr,
  30.                          char   *FlName,
  31.                          char   *InBfr)
  32. {
  33.     auto        FILE            *OutFlPtr;
  34.     auto        char            **RetStrs;
  35.  
  36.     extern      FILE            *ErrFile;
  37.  
  38.     /*  Get begin line. */
  39.     if (ReadLine(InFlPtr, InBfr, BFR_SIZE) != EOF)
  40.     {
  41.         /*  Is this the begin line? */
  42.         if ( MatchBegin(InBfr, &RetStrs) )
  43.         {
  44.             /*  Check to make sure that file does not already exist.    */
  45.             if ( FileExists( FlName ) )
  46.             {
  47.                 fprintf(ErrFile,
  48.                         "\t%s %d : Error - file '%s' already exists.\n",
  49.                         __FILE__,
  50.                         __LINE__,
  51.                         FlName);
  52.                 return( NULL );
  53.             }
  54.  
  55.             /*  Open the file.  */
  56.             if ((OutFlPtr = fopen(FlName, BIN_WRITE)) == NULL)
  57.             {
  58.                 fprintf(ErrFile,
  59.                         "\t%s %d : Error - %s\n\t'%s'\n",
  60.                         __FILE__,
  61.                         __LINE__,
  62.                         sys_errlist[errno],
  63.                         FlName);
  64.                 return( NULL );
  65.             }
  66.  
  67.             /*  Return the file pointer.    */
  68.             return( OutFlPtr );
  69.         }
  70.         else
  71.         {
  72.             /*  Missing begin line. */
  73.             fprintf(ErrFile,
  74.                     "\t%s %d : Error - missing begin line.\n",
  75.                     __FILE__,
  76.                     __LINE__);
  77.             fprintf(ErrFile,
  78.                     "\t'%s'\n",
  79.                     InBfr);
  80.         }
  81.     }
  82.     else
  83.     {
  84.         /*  Missing begin line. */
  85.         fprintf(ErrFile,
  86.                 "\t%s %d : Error - missing begin line.\n",
  87.                 __FILE__,
  88.                 __LINE__);
  89.     }
  90.  
  91.     /*  Return NULL file pointer.   */
  92.     return( NULL );
  93. }
  94.  
  95. /*-----------------------------------------------------------------------------
  96. | Routine   :   WriteDesc() --- Write descriptions to a separate file.
  97. |
  98. | Inputs    :   InFlPtr     - Pointer to source file.
  99. |               DescFlName  - Name of description file.
  100. |               FlDesc      - Pointer to file descriptor structure.
  101. |               InBfr       - Pointer to buffer to read lines into.
  102. -----------------------------------------------------------------------------*/
  103.  
  104. static
  105. int     WriteDesc(FILE      *InFlPtr,
  106.                   char      *DescFlName,
  107.                   FL_LIST   *FlDesc,
  108.                   char      *InBfr)
  109. {
  110.     auto        CHK_UU_ENC      UULnType;
  111.     auto        char            **RetStrs;
  112.     auto        int             EncLen;
  113.     auto        IDENT           *Hdr;
  114.     auto        IDENT           *Body;
  115.     auto        FILE            *DescFile;
  116.  
  117.     extern      FILE            *ErrFile;
  118.  
  119.     /*  Open the description file.  */
  120.     if ((DescFile = fopen(DescFlName, TXT_WRITE)) == NULL)
  121.     {
  122.         fprintf(ErrFile,
  123.                 "\t%s %d : Error - Could not open description file ",
  124.                 __FILE__,
  125.                 __LINE__);
  126.         fprintf(ErrFile,
  127.                 "'%s' for writing.\n",
  128.                 DescFlName);
  129.         return( ERROR );
  130.     }
  131.  
  132.     /*  Check to see which one of the segments exist.   */
  133.     if ( FlDesc->Segs[0].Exists )
  134.     {
  135.         /*  Position file pointer to start of segment.  */
  136.         if (fseek(InFlPtr, FlDesc->Segs[0].SegOfs, SEEK_SET) != 0)
  137.         {
  138.             fprintf(ErrFile,
  139.                     "\t%s %d : Error - %s\n",
  140.                     __FILE__,
  141.                     __LINE__,
  142.                     sys_errlist[errno]);
  143.             fclose( DescFile );
  144.             return( ERROR );
  145.         }
  146.  
  147.         /*  Dump lines until the start of the next segment is seen. */
  148.         if (ReadLine(InFlPtr, InBfr, BFR_SIZE) != EOF)
  149.         {
  150.             /*  Print the line. */
  151.             fprintf(DescFile, "%s\n", InBfr);
  152.  
  153.             /*  Print description.  */
  154.             while (ReadLine(InFlPtr, InBfr, BFR_SIZE) != EOF)
  155.             {
  156.                 /*  Is this a SEGMENT begin line?    */
  157.                 if ( MatchSegment(InBfr, &Hdr, &Body) )
  158.                     break;
  159.  
  160.                 /*  Print the line. */
  161.                 fprintf(DescFile, "%s\n", InBfr);
  162.             }
  163.         }
  164.     }
  165.  
  166.     /*  Position file pointer to start of segment.  */
  167.     if (fseek(InFlPtr, FlDesc->Segs[1].SegOfs, SEEK_SET) != 0)
  168.     {
  169.         fprintf(ErrFile,
  170.                 "\t%s %d : Error - %s\n",
  171.                 __FILE__,
  172.                 __LINE__,
  173.                 sys_errlist[errno]);
  174.         fclose( DescFile );
  175.         return( ERROR );
  176.     }
  177.  
  178.     /*  Dump lines until first UU encoded line is seen. */
  179.     while (ReadLine(InFlPtr, InBfr, BFR_SIZE) != EOF)
  180.     {
  181.         /*  Print the line. */
  182.         fprintf(DescFile, "%s\n", InBfr);
  183.  
  184.         /*  Check to see if this line is a UU encoded line. */
  185.         UULnType = ChkUULine(InBfr, &RetStrs, &EncLen);
  186.         if (UULnType == UU_BEGIN ||
  187.             UULnType == UU_END   ||
  188.             UULnType == IS_UU_LINE)
  189.             break;
  190.     }
  191.  
  192.     /*  Return no error.    */
  193.     fprintf(DescFile, "\n");
  194.     fclose( DescFile );
  195.     return( OK );
  196. }
  197.  
  198. /*-----------------------------------------------------------------------------
  199. | Routine   :   DecSeg() --- Decode a single segment.
  200. |
  201. | Inputs    :   InFlPtr     - Pointer to source file.
  202. |               OutFlPtr    - Pointer to output binary file.
  203. | Outputs   :   UULnType    - Returns UU line type.
  204. |
  205. | Returns   :   EOF     - For end of file.
  206. |               ERROR   - For a binary file write error.
  207. -----------------------------------------------------------------------------*/
  208.  
  209. int     DecSeg(FILE         *InFlPtr,
  210.                FILE         *OutFlPtr,
  211.                CHK_UU_ENC   *UULnType)
  212. {
  213.     auto        int     OutLen;
  214.  
  215.     /*  Externals used by this function.    */
  216.     extern      char    InBfr[];
  217.     extern      BYTE    OutBfr[];
  218.     extern      FILE    *ErrFile;
  219.  
  220.     /*  Decode lines until end of segment.  */
  221.     for ( ; ; )
  222.     {
  223.         /*  Get a line from the file.   */
  224.         if (ReadLine(InFlPtr, InBfr, BFR_SIZE) == EOF)
  225.             return( EOF );
  226.  
  227.         /*  Check the line to make sure that it is a UUENCODE
  228.         *   line, and if it is, decode it.
  229.         */
  230.         *UULnType = DecUULine(InBfr, &OutLen, OutBfr);
  231.         if (*UULnType == NOT_UU_LINE ||
  232.             *UULnType == UU_BEGIN    ||
  233.             *UULnType == UU_END)
  234.             break;
  235.         else if (*UULnType == UU_SPACE)
  236.             continue;
  237.  
  238.         /*  Are there any bytes to write?   */
  239.         if ( OutLen )
  240.         {
  241.             /*  Write the buffer to the output file.    */
  242.             if (fwrite(OutBfr, 1, OutLen, OutFlPtr) != OutLen)
  243.             {
  244.                 fprintf(ErrFile,
  245.                         "\t%s %d : Error - Bad write to binary file.\n",
  246.                         __FILE__,
  247.                         __LINE__);
  248.                 return( ERROR );
  249.             }
  250.         }
  251.     }
  252.  
  253.     /*  No errors, all is cool. */
  254.     return( OK );
  255. }
  256.  
  257. /*-----------------------------------------------------------------------------
  258. | Routine   :   DeCode() --- Decode the file.
  259. |
  260. | Inputs    :   InFlPtr - Pointer to source file.
  261. |               FlDesc  - Pointer to file descriptor.
  262. -----------------------------------------------------------------------------*/
  263.  
  264. int         DeCode(FILE     *InFlPtr,
  265.                    FL_LIST  *FlDesc)
  266. {
  267.     register    int         i;
  268.     auto        FILE        *OutFlPtr;
  269.     auto        int         ret;
  270.     auto        CHK_UU_ENC  UULnType;
  271.     auto        char        OutFlNm[FL_NM_SZ];
  272.  
  273.     /*  Externals used by this function.    */
  274.     extern      int     DumpDesc;
  275.     extern      char    InBfr[];
  276.     extern      FILE    *ErrFile;
  277.  
  278.     /*  Check to make sure that all segments are present before we
  279.     *   decode.
  280.     */
  281.     for (i = 1; i <= FlDesc->NoSegs; i++)
  282.     {
  283.         /*  Check for missing segments. */
  284.         if (FlDesc->Segs[i].SegNo == 0)
  285.         {
  286.             fprintf(ErrFile,
  287.                     "\t%s %d : Error - missing segment #%d.\n",
  288.                     __FILE__,
  289.                     __LINE__,
  290.                     i);
  291.             fprintf(ErrFile,
  292.                     "\tBinary ID: '%s'\n",
  293.                     FlDesc->IDString);
  294.             return( ERROR );
  295.         }
  296.     }
  297.  
  298.     /*  Check for file name.  If none, report error.    */
  299.     if (! FlDesc->FlName)
  300.     {
  301.         fprintf(ErrFile,
  302.                 "\t%s %d : Error - missing file name.\n",
  303.                 __FILE__,
  304.                 __LINE__);
  305.         fprintf(ErrFile,
  306.                 "\tBinary ID: '%s'\n",
  307.                 FlDesc->IDString);
  308.         return( ERROR );
  309.     }
  310.  
  311.     /*  If we want descriptions, dump the first part of segment one.    */
  312.     if ( DumpDesc )
  313.     {
  314.         /*  Dump description for zero segment, if one exists, and
  315.         *   dump the first part of segment one (up to and including
  316.         *   the begin line.
  317.         */
  318.         ModExten(FlDesc->FlName, ".inf", OutFlNm);
  319.         WriteDesc(InFlPtr, OutFlNm, FlDesc, InBfr);
  320.     }
  321.  
  322.     /*  Now that we have scanned all lines, decode file.    */
  323.     for (i = 1; i <= FlDesc->NoSegs; i++)
  324.     {
  325.         /*  Position file pointer to first UUencoded
  326.         *   line of segment.
  327.         */
  328.         if (fseek(InFlPtr, FlDesc->Segs[i].UUOfs, SEEK_SET) != 0)
  329.         {
  330.             fprintf(ErrFile,
  331.                     "\t%s %d : Error - %s\n",
  332.                     __FILE__,
  333.                     __LINE__,
  334.                     sys_errlist[errno]);
  335.             return( ERROR );
  336.         }
  337.  
  338.         /*  Open the binary file.   */
  339.         if (i == 1)
  340.         {
  341.             /*  Open the binary file.   */
  342.             if ((OutFlPtr = OpenBinFile(InFlPtr,
  343.                                         FlDesc->FlName,
  344.                                         InBfr)) == NULL)
  345.                 return( ERROR );
  346.         }
  347.  
  348.         /*  Decode lines until end of segment.  */
  349.         if ((ret = DecSeg(InFlPtr, OutFlPtr, &UULnType)) == EOF ||
  350.             ret == ERROR)
  351.         {
  352.             /*  Close output file, return error.    */
  353.             fclose( OutFlPtr );
  354.             return( ret );
  355.         }
  356.  
  357.         /*  Check for various errors.   */
  358.         if (UULnType == NOT_UU_LINE)
  359.         {
  360.             /*  Is there supposed to be a end line in this segment? */
  361.             if (i == FlDesc->NoSegs)
  362.             {
  363.                 fprintf(ErrFile,
  364.                         "\t%s %d : Error - Missing UU end line.\n",
  365.                         __FILE__,
  366.                         __LINE__);
  367.                 fprintf(ErrFile,
  368.                         "\t'%s'\n",
  369.                         InBfr);
  370.                 fclose( OutFlPtr );
  371.                 return( ERROR );
  372.             }
  373.         }
  374.         else if (UULnType == UU_END)
  375.         {
  376.             /*  Is this supposed to be the end? */
  377.             if (i < FlDesc->NoSegs)
  378.             {
  379.                 fprintf(ErrFile,
  380.                         "\t%s %d : Warning - Early uuencode end line.\n",
  381.                         __FILE__,
  382.                         __LINE__);
  383.             }
  384.             break;
  385.         }
  386.         else if (UULnType == UU_BEGIN)
  387.         {
  388.             /*  What the HELL is this doing here?!  */
  389.             fprintf(ErrFile,
  390.                     "\t%s %d : Error - Unexpected UU begin line.\n",
  391.                     __FILE__,
  392.                     __LINE__);
  393.             return( ERROR );
  394.         }
  395.     }
  396.  
  397.     /*  Close the output file.  */
  398.     fclose( OutFlPtr );
  399.     return( OK );
  400. }
  401.