Advertisement
Guest User

BatchDrake

a guest
Mar 22nd, 2009
589
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.66 KB | None | 0 0
  1. /*
  2.  *     hacha.c: Une archivos con el Hacha de Windows en Linux.
  3.  * Copyright  (c) BatchDrake 2006 <BatchDrake@gmail.com>
  4.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19.  *
  20.  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  21.  */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27.  
  28. inline char *xstrdup (char *str)
  29. {
  30.   register char *r;
  31.  
  32.   if ((r = strdup (str)) == NULL)
  33.     abort ();
  34.  
  35.   return r;
  36. }
  37.  
  38. inline void *xmalloc (int size)
  39. {
  40.   register void *r;
  41.  
  42.   if ((r = malloc (size)) == NULL)
  43.     abort ();
  44.  
  45.   return r;
  46. }
  47.  
  48. static int __expect_hacha_boundary (FILE *fp)
  49. {
  50.   char buf [5];
  51.  
  52.   if (fread (buf, 5, 1, fp) < 1)
  53.     return -1;
  54.  
  55.   if (memcmp (buf, "?????", 5) == 0)
  56.     return 1;
  57.  
  58.   return 0;
  59. }
  60.  
  61. void expect_hacha_marker (char *file, FILE *fp)
  62. {
  63.   int i;
  64.  
  65.   if ((i = __expect_hacha_boundary (fp)) == -1)
  66.   {
  67.     fprintf (stderr, "%s: Final de fichero inesperado. Archivo incompleto.\n", file);
  68.     exit (1);
  69.   }
  70.   else if (i == 0)
  71.   {
  72.     fprintf (stderr, "%s: Separador interno no encontrado (¿formato no reconocido?). Se aborta.\n", file);
  73.     exit (1);
  74.   }
  75. }
  76.  
  77. int string_end (FILE *fp)
  78. {
  79.   int r;
  80.  
  81.   r = __expect_hacha_boundary (fp);
  82.  
  83.   fseek (fp, -5, SEEK_CUR);
  84.  
  85.   return r;
  86. }
  87.  
  88. char *get_hacha_string (FILE *fp)
  89. {
  90.   char buffer [256];
  91.   char *result;
  92.   int i;
  93.  
  94.   for (i = 0; i < 256 && !string_end (fp); i++)
  95.     fread (&buffer[i], 1, 1, fp);
  96.  
  97.   buffer[i] = '\0';
  98.  
  99.   return xstrdup (buffer);
  100. }
  101.  
  102. int main (int argc, char **argv)
  103. {
  104.   FILE *fp;
  105.   FILE *out;
  106.   FILE *this_input;
  107.  
  108.   char b;
  109.   char *out_file, *tmp;
  110.   char *in_files, *template;
  111.  
  112.   char buffer [4096];
  113.   int size;
  114.   int frag_size;
  115.   int chunk_size;
  116.   int version;
  117.  
  118.   register int frsize;
  119.   register int i, p;
  120.   register int total_amount;
  121.  
  122.   if (argc != 2)
  123.   {
  124.     fprintf (stderr, "Forma de uso: %s archivo.0\n", argv[0]);
  125.     return 0;
  126.   }
  127.  
  128.   fp = fopen (argv[1], "rb");
  129.   if (fp == NULL)
  130.   {
  131.     perror (argv[1]);
  132.     exit (2);
  133.   }
  134.  
  135.   expect_hacha_marker (argv[1], fp);
  136.  
  137.   printf ("\n");
  138.  
  139.   fread (&version, sizeof (int), 1, fp);
  140.   printf ("\tHacha version 0.%d\n", version);
  141.   expect_hacha_marker (argv[1], fp);
  142.   out_file = get_hacha_string (fp);
  143.   expect_hacha_marker (argv[1], fp);
  144.   printf ("\tArchivo de salida: %s\n", out_file);
  145.   tmp = get_hacha_string (fp);
  146.  
  147.   if (!sscanf (tmp, "%i", &size))
  148.   {
  149.     fprintf (stderr, "%s: Error en formato de tamaño total.\n", argv[1]);
  150.     exit (3);
  151.   }
  152.  
  153.   free (tmp);
  154.  
  155.   expect_hacha_marker (argv[1], fp);
  156.  
  157.   tmp = get_hacha_string (fp);
  158.  
  159.   if (!sscanf (tmp, "%i", &frag_size))
  160.   {
  161.     fprintf (stderr, "%s: Error en formato de tamaño total.\n", argv[1]);
  162.     exit (3);
  163.   }
  164.  
  165.   free (tmp);
  166.  
  167.   expect_hacha_marker (argv[1], fp);
  168.  
  169.  
  170.   printf ("\tTamaño total: %g MiB\n", (float) size / (1024.0 * 1024.0));
  171.   printf ("\tTamaño por fragmento: %g MiB\n", (float) frag_size / (1024.0 * 1024.0));
  172.   printf ("\nSe espera que el archivo se haya dividido en %d partes.\n\n", size / frag_size + ((size % frag_size) ? 1 : 0));
  173.  
  174.  
  175.  
  176.   frsize = frag_size;
  177.   out = fopen (out_file, "wb");
  178.   if (out == NULL)
  179.   {
  180.     perror (out_file);
  181.     exit (4);
  182.   }
  183.  
  184.   template = xstrdup (argv[1]);
  185.   in_files = xmalloc (strlen (argv[1]) + 5);
  186.  
  187.   strcpy (in_files, argv[1]);
  188.   template [strlen (template) - 1] = '\0';
  189.  
  190.   for (i = 0, total_amount = 0; total_amount < size; i++)
  191.   {
  192.     printf ("Ligando fichero nº %d... ", i + 1);
  193.     fflush (stdout);
  194.    
  195.     if (i)
  196.     {
  197.       sprintf (in_files, "%s%d", template, i);
  198.       this_input = fopen (in_files, "rb");
  199.       if (this_input == NULL)
  200.       {
  201.         perror (in_files);
  202.         fprintf (stderr, "El archivo es necesario para la recomposición pero no se ha podido abrir. Se aborta.\n");
  203.         unlink (out_file);
  204.        
  205.         exit (1);
  206.       }
  207.     }
  208.     else
  209.       this_input = fp;
  210.    
  211.     if (total_amount + frsize > size)
  212.       frsize = size - total_amount;
  213.    
  214.     for (p = 0; p < frsize; )
  215.     {
  216.       chunk_size = ((p + 4096) <= frsize) ? 4096 : frsize - p;
  217.      
  218.       if ((p % 4096) == 0 || chunk_size < 4096)
  219.         fprintf (stderr, "%3d%%\033[4D", ((p + chunk_size)) / (frsize / 100));
  220.       if (fread (buffer, chunk_size, 1, this_input) < 1)
  221.       {
  222.         fprintf (stderr, "%s: fatal: El fichero está incompleto (¿descarga interrumpida?). Se aborta.\n", in_files);
  223.         unlink (out_file);
  224.        
  225.         exit (1);
  226.       }
  227.      
  228.       if (fwrite (buffer, chunk_size, 1, out) < 1)
  229.       {
  230.         perror (out_file);
  231.        
  232.         fprintf (stderr, "%s: fatal: Ha ocurrido un problema al escribir el fichero resultante. Se aborta.\n", in_files);
  233.         unlink (out_file);
  234.       }
  235.      
  236.       p += chunk_size;
  237.     }
  238.    
  239.     total_amount += p;
  240.    
  241.     printf ("Ok  \n");
  242.   }
  243.  
  244.  
  245.   printf ("\nTodo bien.\n");
  246.  
  247.   return 0;
  248. }
  249.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement