1 /*
2 * affstats.cpp:
3 *
4 * print specific statistics about one or more AFF files.
5 * Ideally, we can get the stats from the metadata, but this program will
6 * calculate it if necessary.
7 */
8
9 /*
10 * Copyright (c) 2005-2006
11 * Simson L. Garfinkel and Basis Technology, Inc.
12 * All rights reserved.
13 *
14 * This code is derrived from software contributed by
15 * Simson L. Garfinkel
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. [omitted]
26 * 4. Neither the name of Simson Garfinkel, Basis Technology, or other
27 * contributors to this program may be used to endorse or promote
28 * products derived from this software without specific prior written
29 * permission.
30 *
31 * THIS SOFTWARE IS PROVIDED BY SIMSON GARFINKEL, BASIS TECHNOLOGY,
32 * AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
33 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
34 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL SIMSON GARFINKEL, BAIS TECHNOLOGy,
36 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
37 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
38 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
39 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
40 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
41 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
42 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43 * SUCH DAMAGE.
44 */
45
46
47 #include "affconfig.h"
48 #include "afflib.h"
49 #include "afflib_i.h"
50
51 #include <openssl/md5.h>
52 #include <openssl/sha.h>
53 #include <zlib.h>
54 #include <assert.h>
55
56 #ifdef HAVE_ERR_H
57 #include <err.h>
58 #endif
59
60 #ifdef HAVE_UNISTD_H
61 #include <unistd.h>
62 #endif
63
64 #ifdef HAVE_UNISTD_H
65 #include <unistd.h>
66 #endif
67
68 #ifdef WIN32
69 #include "unix4win32.h"
70 #include <malloc.h>
71 #endif
72
73 const char *progname = "affstats";
74 int opt_m = 0;
75
usage()76 void usage()
77 {
78 printf("%s version %s\n\n",progname,PACKAGE_VERSION);
79 printf("usage: %s [options] infile(s)\n",progname);
80 printf(" -m = print all output in megabytes\n");
81 printf(" -v = Just print the version number and exit.\n");
82 exit(0);
83 }
84
85
title()86 void title()
87 {
88 printf("fname\tbytes\tcompressed\n");
89 }
90
print_size(uint64_t s)91 void print_size(uint64_t s)
92 {
93 if(opt_m){
94 printf("%u",(unsigned int)(s/(1024*1024)));
95 return;
96 }
97 printf("%" I64u,s);
98 }
99
affstats_title()100 void affstats_title()
101 {
102 printf("Name\tAF_IMAGESIZE\tCompressed\tUncompressed\tBlank\tBad\n");
103 }
104
affstats(const char * fname)105 void affstats(const char *fname)
106 {
107 AFFILE *af = af_open(fname,O_RDONLY,0);
108 if(!af) af_err(1,"af_open(%s)",fname);
109
110 printf("%s\t",fname);
111
112 uint32_t segsize=0;
113
114 int64_t imagesize=0;
115 int64_t blanksectors=0;
116 int64_t badsectors=0;
117 af_get_segq(af,AF_IMAGESIZE,&imagesize);
118 if(af_get_seg(af,AF_PAGESIZE,&segsize,0,0)){
119 af_get_seg(af,AF_SEGSIZE_D,&segsize,0,0); // check for oldstype
120 }
121 af_get_segq(af,AF_BADSECTORS,&badsectors);
122 af_get_segq(af,AF_BLANKSECTORS,&blanksectors);
123
124 print_size(imagesize);
125 printf("\t");
126 fflush(stdout);
127
128 int64_t compressed_bytes = 0;
129 int64_t uncompressed_bytes = 0;
130
131 /* Now read through all of the segments and count the number of
132 * data segments. We know the uncompressed size...
133 */
134 af_rewind_seg(af);
135 char segname[AF_MAX_NAME_LEN+1];
136 size_t datalen;
137 while(af_get_next_seg(af,segname,sizeof(segname),0,0,&datalen)==0){
138 int64_t page_num = af_segname_page_number(segname);
139 if(page_num>=0){
140 compressed_bytes += datalen;
141 uncompressed_bytes += segsize;
142 }
143 }
144 if(uncompressed_bytes > imagesize) uncompressed_bytes = imagesize;
145
146 print_size(compressed_bytes);
147 printf("\t");
148 print_size(uncompressed_bytes);
149 printf(" %" I64d " %" I64d,blanksectors,badsectors);
150 putchar('\n');
151
152
153 }
154
155
156
157
main(int argc,char ** argv)158 int main(int argc,char **argv)
159 {
160 int ch;
161 while ((ch = getopt(argc, argv, "mh?V")) != -1) {
162 switch (ch) {
163 case 'm':
164 opt_m = 1;
165 break;
166 case 'h':
167 case '?':
168 default:
169 usage();
170 break;
171 case 'V':
172 printf("%s version %s\n",progname,PACKAGE_VERSION);
173 exit(0);
174 }
175 }
176 argc -= optind;
177 argv += optind;
178
179 if(argc<1){
180 usage();
181 }
182
183 /* Each argument is now a file. Process each one */
184 affstats_title();
185 while(*argv){
186 affstats(*argv++);
187 argc--;
188 }
189 exit(0);
190 }
191
192
193