/*                                              28 July 1994.  SMS.

      Simple file re-blocker, 512 byte to original, for
      Wollongong-processed (FTP) BACKUP save sets.  If no block size is
      specified on the command line, the program extracts the original
      block size from the original file.

      Arg1: input file (512-byte records)
      Arg2: output file (n-byte records, n = 2048 to 65534)
      Arg3: (optional) output file block size (2048 to 65534).

*/

	
#include  errno
#include  file
#include  stdio
#include  stdlib
#include  unixio

#define  IDENT  "\n ftb"

#define  MIN( a, b)  (((a) < (b)) ? (a) : (b))

#define  OUT_BUF_BYTES  65536+ 512

main( argc, argv)
int  argc;
char  **argv;
{

union
   {
   char  byte[ OUT_BUF_BYTES];
   short int  word[ OUT_BUF_BYTES/ 2];
   } out_buf;

char  *in_buf_ptr;
char  *out_buf_ptr;

char  not_done;

char  mrs_str[ 16];

int  mrs = -1;

int  in_bc;
int  in_file = -1;
int  out_bc;
int  out_file = -1;
int  xx_bc;


if (argc <= 2)
   {
   printf( "\n");
   printf( " Usage:\n");
   printf( "\n");
   printf( "    $ ftb == \"$ ''f$search( \"file_spec_of_ftb.exe\")'\"\n");
   printf( "    ftb  input_file_name  output_file_name  \
[ output_block_size ]\n");
   printf( "\n");
   printf( " Optional \"output_block_size\" overrides the value stored in\n");
   printf( " the input_file.\n");
   printf( "\n");
   return -1;
   }
else
   {
   if (argc > 3)
      {
      mrs = strtol( argv[ 3], (char**)NULL, 10);
      if ((mrs < 2048) || (mrs > 65536))
         {
         printf( " Bad command line block size (= %d).\n", mrs);
         mrs = 0;
         }
      }
   in_file = open( argv[ 1], O_RDONLY, 0);
   printf( " in_file: %s.\n", argv[ 1]);
   if (in_file <= 0)
      {
      printf( " Input file open failed.  errno = %d, vaxc$errno = %08x.\n",
       errno, vaxc$errno);
      perror( IDENT);
      return errno;
      }

   out_buf_ptr = & out_buf.byte[ 0];
   out_bc = 0;
   in_bc = read( in_file, out_buf_ptr, 512);
   if (in_bc < 0)
      {
      printf( " read error 1.  errno = %d, vaxc$errno = %08x.\n",
       errno, vaxc$errno);
      perror( IDENT);
      return errno;
      }
   else
      {
      out_buf_ptr += in_bc;
      out_bc += in_bc;
      if (mrs <= 0)
         {
         if (in_bc < 42)
            {
            printf( " Can not read block size from file.  Bytes read = %d.\n",
             in_bc);
            in_bc = -1;
            }
         else
            {
            if (mrs == 0)
               {
               printf( " Using block size from file.\n");
               }
            mrs = out_buf.word[ 20];
            }
         }
      }

   if ((mrs < 2048) || (mrs > 65536))
      {
      printf( " Bad block size from original file (= %d).\n", in_bc);
      in_bc = -1;
      }
   else
      {
      printf( " /BLOCK_SIZE = %d.\n", mrs);
      sprintf( mrs_str, "mrs = %d", mrs);
      out_file = open( argv[ 2],
       (O_CREAT| O_TRUNC| O_RDWR),
       0,
       mrs_str,
       "rfm = fix");

      printf( " out_file: %s.\n", argv[ 2]);
      if (out_file <= 0)
         {
         printf( " Output file open failed.  errno = %d, vaxc$errno = %08x.\n",
          errno, vaxc$errno);
         perror( IDENT);
         return  errno;
         }
      }
   }

while ((out_bc >= 0) && (in_bc > 0))
   {
   while ((out_bc < mrs) && (in_bc > 0))
      {
      in_bc = read( in_file, out_buf_ptr, 512);
      if (in_bc < 0)
         {
         printf( " read error 2.  errno = %d, vaxc$errno = %08x.\n",
          errno, vaxc$errno);
         perror( IDENT);
         return  errno;
         }
      else
         {
         out_buf_ptr += in_bc;
         out_bc += in_bc;
         if (in_bc == 0)
            {
/*
            Zero-fill not required.

            for ( ; out_bc < mrs ; out_bc++ )
               {
               *(out_buf_ptr++) = 0;
               }
*/
            }
         }

      }

   if ((in_bc >= 0) && (out_bc > 0))
      {
      xx_bc = write (out_file, &out_buf.byte[ 0], MIN( mrs, out_bc));
      if (xx_bc <= 0)
         {
         printf( " write 1 error.  errno = %d, vaxc$errno = %08x.\n",
          errno, vaxc$errno);
         perror( IDENT);
         return  errno;
         }
      out_buf_ptr = & out_buf.byte[ 0];
      }

   out_bc -= xx_bc;
   if (out_bc > 0)
      {
      xx_bc = out_bc;
      in_buf_ptr = & out_buf.byte[ mrs];
      for ( ; xx_bc > 0 ; xx_bc--)
         {
         *(out_buf_ptr++) = *(in_buf_ptr++);
         }
      }
   }

if ((in_bc >= 0) && (out_bc > 0))
   {
   xx_bc = write (out_file, &out_buf.byte[ 0], MIN( mrs, out_bc));
   if (xx_bc <= 0)
      {
      printf( " write 2 error.  errno = %d, vaxc$errno = %08x.\n",
       errno, vaxc$errno);
      perror( IDENT);
      return  errno;
      }
   out_buf_ptr = & out_buf.byte[ 0];
   }

if (in_file > 0)
   {
   close( in_file);
   }

if (out_file > 0)
   {
   close( out_file);
   }
}
