mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / archive / archive_reader.c
blob2a426966e73278408180444b559bcecfab020412
1 /* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16 #include "azlib.h"
17 #include <string.h>
18 #include <assert.h>
19 #include <stdio.h>
20 #include <stdarg.h>
21 #include <m_ctype.h>
22 #include <m_string.h>
23 #include <my_getopt.h>
24 #include <mysql_version.h>
26 #define BUFFER_LEN 1024
27 #define ARCHIVE_ROW_HEADER_SIZE 4
29 #define SHOW_VERSION "0.1"
31 static void get_options(int *argc,char * * *argv);
32 static void print_version(void);
33 static void usage(void);
34 static const char *opt_tmpdir;
35 static const char *new_auto_increment;
36 unsigned long long new_auto_increment_value;
37 static const char *load_default_groups[]= { "archive_reader", 0 };
38 static char **default_argv;
39 int opt_check, opt_force, opt_quiet, opt_backup= 0, opt_extract_frm;
40 int opt_autoincrement;
42 int main(int argc, char *argv[])
44 unsigned int ret;
45 azio_stream reader_handle;
47 MY_INIT(argv[0]);
48 get_options(&argc, &argv);
50 if (argc < 1)
52 printf("No file specified. \n");
53 return 0;
56 if (!(ret= azopen(&reader_handle, argv[0], O_RDONLY|O_BINARY)))
58 printf("Could not open Archive file\n");
59 return 0;
62 if (opt_autoincrement)
64 azio_stream writer_handle;
66 if (new_auto_increment_value)
68 if (reader_handle.auto_increment >= new_auto_increment_value)
70 printf("Value is lower then current value\n");
71 goto end;
74 else
76 new_auto_increment_value= reader_handle.auto_increment + 1;
79 if (!(ret= azopen(&writer_handle, argv[0], O_CREAT|O_RDWR|O_BINARY)))
81 printf("Could not open file for update: %s\n", argv[0]);
82 goto end;
85 writer_handle.auto_increment= new_auto_increment_value;
87 azclose(&writer_handle);
88 azflush(&reader_handle, Z_SYNC_FLUSH);
91 printf("Version %u\n", reader_handle.version);
92 if (reader_handle.version > 2)
94 printf("\tMinor version %u\n", reader_handle.minor_version);
95 printf("\tStart position %llu\n", (unsigned long long)reader_handle.start);
96 printf("\tBlock size %u\n", reader_handle.block_size);
97 printf("\tRows %llu\n", reader_handle.rows);
98 printf("\tAutoincrement %llu\n", reader_handle.auto_increment);
99 printf("\tCheck Point %llu\n", reader_handle.check_point);
100 printf("\tForced Flushes %llu\n", reader_handle.forced_flushes);
101 printf("\tLongest Row %u\n", reader_handle.longest_row);
102 printf("\tShortest Row %u\n", reader_handle.shortest_row);
103 printf("\tState %s\n", ( reader_handle.dirty ? "dirty" : "clean"));
104 printf("\tFRM stored at %u\n", reader_handle.frm_start_pos);
105 printf("\tComment stored at %u\n", reader_handle.comment_start_pos);
106 printf("\tData starts at %u\n", (unsigned int)reader_handle.start);
107 if (reader_handle.frm_start_pos)
108 printf("\tFRM length %u\n", reader_handle.frm_length);
109 if (reader_handle.comment_start_pos)
111 char *comment =
112 (char *) malloc(sizeof(char) * reader_handle.comment_length);
113 azread_comment(&reader_handle, comment);
114 printf("\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length,
115 reader_handle.comment_length, comment);
116 free(comment);
119 else
121 goto end;
124 printf("\n");
126 if (opt_check)
128 uchar size_buffer[ARCHIVE_ROW_HEADER_SIZE];
129 int error;
130 unsigned int x;
131 unsigned int read;
132 unsigned int row_len;
133 unsigned long long row_count= 0;
134 char buffer;
136 while ((read= azread(&reader_handle, (uchar *)size_buffer,
137 ARCHIVE_ROW_HEADER_SIZE, &error)))
139 if (error == Z_STREAM_ERROR || (read && read < ARCHIVE_ROW_HEADER_SIZE))
141 printf("Table is damaged\n");
142 goto end;
145 /* If we read nothing we are at the end of the file */
146 if (read == 0 || read != ARCHIVE_ROW_HEADER_SIZE)
147 break;
149 row_len= uint4korr(size_buffer);
150 row_count++;
152 if (row_len > reader_handle.longest_row)
154 printf("Table is damaged, row %llu is invalid\n",
155 row_count);
156 goto end;
160 for (read= x= 0; x < row_len ; x++)
162 read+= (unsigned int)azread(&reader_handle, &buffer, sizeof(char), &error);
163 if (!read)
164 break;
168 if (row_len != read)
170 printf("Row length did not match row (at %llu). %u != %u \n",
171 row_count, row_len, read);
172 goto end;
176 if (0)
178 printf("Table is damaged\n");
179 goto end;
181 else
183 printf("Found %llu rows\n", row_count);
187 if (opt_backup)
189 uchar size_buffer[ARCHIVE_ROW_HEADER_SIZE];
190 int error;
191 unsigned int read;
192 unsigned int row_len;
193 unsigned long long row_count= 0;
194 char *buffer;
196 azio_stream writer_handle;
198 buffer= (char *)malloc(reader_handle.longest_row);
199 if (buffer == NULL)
201 printf("Could not allocate memory for row %llu\n", row_count);
202 goto end;
206 if (!(ret= azopen(&writer_handle, argv[1], O_CREAT|O_RDWR|O_BINARY)))
208 printf("Could not open file for backup: %s\n", argv[1]);
209 goto end;
212 writer_handle.auto_increment= reader_handle.auto_increment;
213 if (reader_handle.frm_length)
215 char *ptr;
216 ptr= (char *)my_malloc(sizeof(char) * reader_handle.frm_length, MYF(0));
217 azread_frm(&reader_handle, ptr);
218 azwrite_frm(&writer_handle, ptr, reader_handle.frm_length);
219 my_free(ptr, MYF(0));
222 if (reader_handle.comment_length)
224 char *ptr;
225 ptr= (char *)my_malloc(sizeof(char) * reader_handle.comment_length, MYF(0));
226 azread_comment(&reader_handle, ptr);
227 azwrite_comment(&writer_handle, ptr, reader_handle.comment_length);
228 my_free(ptr, MYF(0));
231 while ((read= azread(&reader_handle, (uchar *)size_buffer,
232 ARCHIVE_ROW_HEADER_SIZE, &error)))
234 if (error == Z_STREAM_ERROR || (read && read < ARCHIVE_ROW_HEADER_SIZE))
236 printf("Table is damaged\n");
237 goto end;
240 /* If we read nothing we are at the end of the file */
241 if (read == 0 || read != ARCHIVE_ROW_HEADER_SIZE)
242 break;
244 row_len= uint4korr(size_buffer);
246 row_count++;
248 memcpy(buffer, size_buffer, ARCHIVE_ROW_HEADER_SIZE);
250 read= (unsigned int)azread(&reader_handle, buffer + ARCHIVE_ROW_HEADER_SIZE,
251 row_len, &error);
253 DBUG_ASSERT(read == row_len);
255 azwrite(&writer_handle, buffer, row_len + ARCHIVE_ROW_HEADER_SIZE);
258 if (row_len != read)
260 printf("Row length did not match row (at %llu). %u != %u \n",
261 row_count, row_len, read);
262 goto end;
265 if (reader_handle.rows == writer_handle.rows)
266 break;
269 free(buffer);
271 azclose(&writer_handle);
274 if (opt_extract_frm)
276 File frm_file;
277 char *ptr;
278 frm_file= my_open(argv[1], O_CREAT|O_RDWR|O_BINARY, MYF(0));
279 ptr= (char *)my_malloc(sizeof(char) * reader_handle.frm_length, MYF(0));
280 azread_frm(&reader_handle, ptr);
281 my_write(frm_file, (uchar*) ptr, reader_handle.frm_length, MYF(0));
282 my_close(frm_file, MYF(0));
283 my_free(ptr, MYF(0));
286 end:
287 printf("\n");
288 azclose(&reader_handle);
290 return 0;
293 static my_bool
294 get_one_option(int optid,
295 const struct my_option *opt __attribute__((unused)),
296 char *argument)
298 switch (optid) {
299 case 'b':
300 opt_backup= 1;
301 break;
302 case 'c':
303 opt_check= 1;
304 break;
305 case 'e':
306 opt_extract_frm= 1;
307 break;
308 case 'f':
309 opt_force= 1;
310 printf("Not implemented yet\n");
311 break;
312 case 'q':
313 opt_quiet= 1;
314 printf("Not implemented yet\n");
315 break;
316 case 'V':
317 print_version();
318 exit(0);
319 case 't':
320 printf("Not implemented yet\n");
321 break;
322 case 'A':
323 opt_autoincrement= 1;
324 if (argument)
325 new_auto_increment_value= strtoull(argument, NULL, 0);
326 else
327 new_auto_increment_value= 0;
328 break;
329 case '?':
330 usage();
331 exit(0);
332 case '#':
333 if (argument == disabled_my_option)
335 DBUG_POP();
337 else
339 DBUG_PUSH(argument ? argument : "d:t:o,/tmp/archive_reader.trace");
341 break;
343 return 0;
346 static struct my_option my_long_options[] =
348 {"backup", 'b',
349 "Make a backup of an archive table.",
350 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
351 {"check", 'c', "Check table for errors.",
352 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
353 #ifndef DBUG_OFF
354 {"debug", '#',
355 "Output debug log. Often this is 'd:t:o,filename'.",
356 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
357 #endif
358 {"extract-frm", 'e',
359 "Extract the frm file.",
360 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
361 {"force", 'f',
362 "Restart with -r if there are any errors in the table.",
363 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
364 {"help", '?',
365 "Display this help and exit.",
366 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
367 {"quick", 'q', "Faster repair by not modifying the data file.",
368 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
369 {"repair", 'r', "Repair a damaged Archive version 3 or above file.",
370 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
371 {"set-auto-increment", 'A',
372 "Force auto_increment to start at this or higher value. If no value is given, then sets the next auto_increment value to the highest used value for the auto key + 1.",
373 &new_auto_increment, &new_auto_increment,
374 0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0},
375 {"silent", 's',
376 "Only print errors. One can use two -s to make archive_reader very silent.",
377 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
378 {"tmpdir", 't',
379 "Path for temporary files.",
380 &opt_tmpdir,
381 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
382 {"version", 'V',
383 "Print version and exit.",
384 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
385 { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
388 static void usage(void)
390 print_version();
391 puts("Copyright 2007-2008 MySQL AB, 2008 Sun Microsystems, Inc.");
392 puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\nand you are welcome to modify and redistribute it under the GPL license\n");
393 puts("Read and modify Archive files directly\n");
394 printf("Usage: %s [OPTIONS] file_to_be_looked_at [file_for_backup]\n", my_progname);
395 print_defaults("my", load_default_groups);
396 my_print_help(my_long_options);
399 static void print_version(void)
401 printf("%s Ver %s Distrib %s, for %s (%s)\n", my_progname, SHOW_VERSION,
402 MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
405 static void get_options(int *argc, char ***argv)
407 load_defaults("my", load_default_groups, argc, argv);
408 default_argv= *argv;
410 handle_options(argc, argv, my_long_options, get_one_option);
412 if (*argc == 0)
414 usage();
415 exit(-1);
418 return;
419 } /* get options */