Sophie

Sophie

distrib > Mandriva > 2009.0 > x86_64 > by-pkgid > 9186c28c138a52c8fdbb9adfb10afe10 > files > 1

cloop-utils-2.06-2mdv2008.1.src.rpm

diff -aurN cloop-1.02/create_compressed_fs.c cloop-1.02.jaco/create_compressed_fs.c
--- cloop-1.02/create_compressed_fs.c	2003-07-18 17:01:38.000000000 +0200
+++ cloop-1.02.jaco/create_compressed_fs.c	2003-10-31 11:54:12.000000000 +0200
@@ -38,6 +38,8 @@
  free(cbl);
 }
 
+static int out;
+
 /* Now using the goto style because it is quicker to read */
 static struct cb_list *create_compressed_blocks(int handle, unsigned long
                           blocksize, unsigned long *numblocks)
@@ -81,7 +83,15 @@
      fprintf(stderr, "*** Error %d compressing block %lu! (compressed=%p, len=%lu, uncompressed=%p, blocksize=%lu)\n", z_error, i, compressed,len,uncompressed,blocksize);
      goto error_free_cb_list;
     }
-   if((*cbp = malloc(sizeof(struct cb_list)+len))==NULL) /* get another block */
+
+   if (*numblocks)
+     if (write(out, compressed, len) != len)
+       {
+	 perror("writing block");
+	 exit (1);
+       }
+
+   if((*cbp = malloc(sizeof(struct cb_list)+ (*numblocks ? 0 : len)))==NULL) /* get another block */
     {
      fprintf(stderr, "*** Out of memory allocating block ptrs (virtual memory exhausted).\n");
      goto error_free_cb_list;
@@ -90,7 +100,7 @@
    /* Print status */
    fprintf(stderr, "Block# %5lu size %6lu -> %6lu [compression ratio %3lu%%, overall: %3Lu%%]\n", i, total, len, total>0?((len*100)/total):100,total_uncompressed>0?((total_compressed*100)/total_uncompressed):100);
    (*cbp)->size = len;
-   memcpy((*cbp)->data, compressed, len);
+   if (*numblocks == 0) memcpy((*cbp)->data, compressed, len);
    (*cbp)->next=NULL;
    cbp=&((*cbp)->next);
   } /* for */
@@ -111,17 +121,22 @@
 int main(int argc, char **argv)
 {
  int in;
- unsigned long blocksize;
+ unsigned long blocksize, estimated_size;
  struct cloop_head head;
- unsigned long numblocks;
+ unsigned long numblocks, estimated_numblocks;
  unsigned long long bytes_so_far;
  unsigned long i;
  struct cb_list *compressed_blocks,*cbp;
 
- if (argc != 3)
+ if (argc < 3 || argc > 5)
   {
-   fprintf(stderr, "Usage: %s filename blocksize(bytes).\n",argv[0]);
-   fprintf(stderr, "Use '-' as filename for stdin.\n");
+   fprintf(stderr, "Usage: %s <in_file> <blocksize> [<out_file> [<in_size>]]\n",argv[0]);
+   fprintf(stderr, "Options:\n");
+   fprintf(stderr, "   <in_file>    Input (uncompressed) filename. Use '-' for stdin.\n");
+   fprintf(stderr, "   <blocksize>  The number of bytes in a block (eg: 65536)\n");
+   fprintf(stderr, "   <out_file>   The output (compressed) file\n");
+   fprintf(stderr, "   <in_size>    The input filesize in MB. If you use stdin, you can\n");
+   fprintf(stderr, "                give a bigger estimated size (don't be conservative)\n");
    return 1;
   }
 
@@ -138,6 +153,8 @@
    sleep(2);
   }
 
+ estimated_size = argc > 4 ? (atoi(argv[4]) + 1) * 1024 * 1024 : 0;
+
  if (sizeof(CLOOP_PREAMBLE) > CLOOP_HEADROOM)
   {
    fprintf(stderr, "*** Preamble (%u chars) > headroom (%u)\n",
@@ -153,8 +170,55 @@
    return 1;
   }
 
+ out = argc > 3 ? open(argv[3], O_CREAT | O_TRUNC | O_WRONLY, 0644) : dup(STDOUT_FILENO);
+
+ if (out < 0)
+  {
+   perror("Opening output");
+   return 1;
+  }
+
+ if (argc > 3)
+   {
+     struct stat buf;
+     if (fstat(in, &buf) == 0 && buf.st_size)
+       {
+	 if (estimated_size != 0) fprintf(stderr, "replacing given size %lu with %lu\n", estimated_size, buf.st_size);
+	 estimated_size = buf.st_size;
+       }
+   }
+
+ estimated_numblocks = numblocks = (estimated_size + 1 + blocksize - 1) / blocksize;
+
+ if (estimated_size) 
+   {
+     size_t to_skip = sizeof(head) + sizeof(loff_t) * (estimated_numblocks + 1);
+     char *skip = alloca(to_skip);
+     memset(skip, 0xFF, to_skip);
+     if (write(out, skip, to_skip) != to_skip)
+       {
+	 perror("writing block");
+	 exit (1);
+       }
+   }
+ else
+   numblocks = 0;
+
  compressed_blocks = create_compressed_blocks(in, blocksize, &numblocks);
 
+ if (estimated_size) 
+   if (numblocks > estimated_numblocks)
+     {
+       fprintf(stderr, "estimated size is not good, it should be at least %f MB (%lu > %lu)\n", (numblocks / (1024. * 1024. / blocksize)), numblocks, estimated_numblocks);
+       exit (1);
+     }
+
+   if (lseek(out, 0, SEEK_SET) != 0)
+     {
+       perror("seeking to the beginning of output file");
+       exit (1);
+     }
+
  close(in);
 
  memset(head.preamble, 0, sizeof(head.preamble));
@@ -165,10 +229,10 @@
  fprintf(stderr, "Block size %lu, number of blocks %lu.\n",
          blocksize, numblocks);
 
- bytes_so_far = sizeof(head) + sizeof(loff_t) * (numblocks + 1);
+ bytes_so_far = sizeof(head) + sizeof(loff_t) * ((estimated_size ? estimated_numblocks : numblocks) + 1);
 
  /* Write out head... */
- write(STDOUT_FILENO, &head, sizeof(head));
+ write(out, &head, sizeof(head));
 
  if (!compressed_blocks) return 1;
 
@@ -177,14 +241,15 @@
   {
    loff_t tmp;
    tmp = __cpu_to_be64(bytes_so_far);
-   write(STDOUT_FILENO, &tmp, sizeof(tmp));
+   write(out, &tmp, sizeof(tmp));
    if(cbp) { bytes_so_far += cbp->size; cbp=cbp->next; }
   }
 
+ if (estimated_size == 0)
  /* Now write blocks and free them. */
  for (i = 0, cbp=compressed_blocks; cbp && i < numblocks; i++)
   {
-   if (write(STDOUT_FILENO, cbp->data, cbp->size) != cbp->size)
+   if (write(out, cbp->data, cbp->size) != cbp->size)
     {
      perror("writing block");
      free_cb_list(compressed_blocks);