1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
/* Clzip - LZMA lossless data compressor
Copyright (C) 2010-2026 Antonio Diaz Diaz.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _FILE_OFFSET_BITS 64
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include "lzip.h"
#include "lzip_index.h"
static void list_line( const unsigned long long uncomp_size,
const unsigned long long comp_size,
const char * const input_filename )
{
if( uncomp_size > 0 )
printf( "%14s %14s %6.2f%% %s\n",
format_num3( uncomp_size ), format_num3( comp_size ),
100.0 - ( ( 100.0 * comp_size ) / uncomp_size ),
input_filename );
else
printf( "%14llu %14llu -INF%% %s\n", uncomp_size, comp_size,
input_filename );
}
int list_files( const char * const filenames[], const int num_filenames,
const Cl_options * const cl_opts )
{
unsigned long long total_comp = 0, total_uncomp = 0;
unsigned files = 0;
int retval = 0;
int i;
bool first_post = true;
bool stdin_used = false;
for( i = 0; i < num_filenames; ++i )
{
const bool from_stdin = strcmp( filenames[i], "-" ) == 0;
if( from_stdin ) { if( stdin_used ) continue; else stdin_used = true; }
const char * const input_filename = from_stdin ? "(stdin)" : filenames[i];
struct stat in_stats; /* not used */
const int infd = from_stdin ? STDIN_FILENO :
open_instream( input_filename, &in_stats, false, true );
if( infd < 0 ) { set_retval( &retval, 1 ); continue; }
Lzip_index lzip_index;
Li_init( &lzip_index, infd, cl_opts );
close( infd );
if( lzip_index.retval != 0 )
{
show_file_error( input_filename, lzip_index.error, 0 );
set_retval( &retval, lzip_index.retval );
Li_free( &lzip_index ); continue;
}
const bool multi_empty = !from_stdin && Li_multi_empty( &lzip_index );
if( multi_empty ) set_retval( &retval, 2 );
if( verbosity < 0 ) { Li_free( &lzip_index ); continue; }
const unsigned long long udata_size = Li_udata_size( &lzip_index );
const unsigned long long cdata_size = Li_cdata_size( &lzip_index );
const unsigned long long tdata_size = Li_file_size( &lzip_index ) - cdata_size;
total_comp += cdata_size; total_uncomp += udata_size; ++files;
const long members = lzip_index.members;
if( first_post )
{
first_post = false;
if( verbosity >= 1 ) fputs( " dict memb ", stdout );
fputs( " uncompressed compressed saved name\n", stdout );
}
if( multi_empty ) { fflush( stdout );
show_file_error( input_filename, empty_member_msg, 0 ); }
if( verbosity >= 1 )
printf( "%s %5lu%s ", format_ds( lzip_index.dictionary_size ),
members, tdata_size ? "+t" : " " );
list_line( udata_size, cdata_size, input_filename );
if( verbosity >= 2 && ( members > 1 || tdata_size > 0 ) )
{
long j;
fputs( " member data_pos data_size member_pos member_size\n", stdout );
for( j = 0; j < members; ++j )
{
const Block * db = Li_dblock( &lzip_index, j );
const Block * mb = Li_mblock( &lzip_index, j );
printf( "%6s %14s %14s %14s %14s\n", format_num3( j + 1 ),
format_num3( db->pos ), format_num3( db->size ),
format_num3( mb->pos ), format_num3( mb->size ) );
}
if( tdata_size > 0 ) printf( " tdata %44s %14s\n",
format_num3( cdata_size ), format_num3( tdata_size ) );
if( i + 1 < num_filenames || files > 1 ) fputc( '\n', stdout );
first_post = true; /* reprint heading after list of members */
}
fflush( stdout );
Li_free( &lzip_index );
if( ferror( stdout ) ) break;
}
if( verbosity >= 0 && files > 1 && !ferror( stdout ) )
{
if( verbosity >= 2 && first_post )
fputs( " uncompressed compressed saved\n", stdout );
if( verbosity >= 1 ) fputs( " ", stdout );
list_line( total_uncomp, total_comp, "(totals)" );
fflush( stdout );
}
if( verbosity >= 0 && ( ferror( stdout ) || fclose( stdout ) != 0 ) )
{ show_file_error( "(stdout)", wr_err_msg, errno );
set_retval( &retval, 1 ); }
return retval;
}
|