~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

Viewing changes to storage/archive/archive_reader.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "azio.h"
 
2
#include <string.h>
 
3
#include <assert.h>
 
4
#include <stdio.h>
 
5
#include <stdarg.h>
 
6
#include <m_ctype.h>
 
7
#include <m_string.h>
 
8
#include <my_getopt.h>
 
9
#include <mysql_version.h>
 
10
 
 
11
#define BUFFER_LEN 1024
 
12
#define ARCHIVE_ROW_HEADER_SIZE 4
 
13
 
 
14
#define SHOW_VERSION "0.1"
 
15
 
 
16
static void get_options(int *argc,char * * *argv);
 
17
static void print_version(void);
 
18
static void usage(void);
 
19
static const char *opt_tmpdir;
 
20
static const char *new_auto_increment;
 
21
unsigned long long new_auto_increment_value;
 
22
static const char *load_default_groups[]= { "archive_reader", 0 };
 
23
static char **default_argv;
 
24
int opt_check, opt_force, opt_quiet, opt_backup= 0, opt_extract_frm;
 
25
int opt_autoincrement;
 
26
 
 
27
int main(int argc, char *argv[])
 
28
{
 
29
  unsigned int ret;
 
30
  azio_stream reader_handle;
 
31
 
 
32
  my_init();
 
33
  MY_INIT(argv[0]);
 
34
  get_options(&argc, &argv);
 
35
 
 
36
  if (argc < 1)
 
37
  {
 
38
    printf("No file specified. \n");
 
39
    return 0;
 
40
  }
 
41
 
 
42
  if (!(ret= azopen(&reader_handle, argv[0], O_RDONLY|O_BINARY, AZ_METHOD_BLOCK)))
 
43
  {
 
44
    printf("Could not open Archive file\n");
 
45
    return 0;
 
46
  }
 
47
 
 
48
  if (opt_autoincrement)
 
49
  {
 
50
    azio_stream writer_handle;
 
51
 
 
52
    if (new_auto_increment_value)
 
53
    {
 
54
      if (reader_handle.auto_increment >= new_auto_increment_value)
 
55
      {
 
56
        printf("Value is lower then current value\n");
 
57
        goto end;
 
58
      }
 
59
    }
 
60
    else
 
61
    {
 
62
      new_auto_increment_value= reader_handle.auto_increment + 1;
 
63
    }
 
64
 
 
65
    if (!(ret= azopen(&writer_handle, argv[0], O_CREAT|O_RDWR|O_BINARY, 
 
66
                      AZ_METHOD_BLOCK)))
 
67
    {
 
68
      printf("Could not open file for update: %s\n", argv[0]);
 
69
      goto end;
 
70
    }
 
71
 
 
72
    writer_handle.auto_increment= new_auto_increment_value;
 
73
 
 
74
    azclose(&writer_handle);
 
75
    azflush(&reader_handle, Z_SYNC_FLUSH);
 
76
  }
 
77
 
 
78
  printf("Version %u\n", reader_handle.version);
 
79
  if (reader_handle.version > 2)
 
80
  {
 
81
    printf("\tMinor version %u\n", reader_handle.minor_version);
 
82
    printf("\tStart position %llu\n", (unsigned long long)reader_handle.start);
 
83
    printf("\tBlock size %u\n", reader_handle.block_size);
 
84
    printf("\tRows %llu\n", reader_handle.rows);
 
85
    printf("\tAutoincrement %llu\n", reader_handle.auto_increment);
 
86
    printf("\tCheck Point %llu\n", reader_handle.check_point);
 
87
    printf("\tForced Flushes %llu\n", reader_handle.forced_flushes);
 
88
    printf("\tLongest Row %u\n", reader_handle.longest_row);
 
89
    printf("\tShortest Row %u\n", reader_handle.shortest_row);
 
90
    printf("\tState %s\n", ( reader_handle.dirty ? "dirty" : "clean"));
 
91
    printf("\tFRM stored at %u\n", reader_handle.frm_start_pos);
 
92
    printf("\tComment stored at %u\n", reader_handle.comment_start_pos);
 
93
    printf("\tData starts at %u\n", (unsigned int)reader_handle.start);
 
94
    if (reader_handle.frm_start_pos)
 
95
      printf("\tFRM length %u\n", reader_handle.frm_length);
 
96
    if (reader_handle.comment_start_pos)
 
97
    {
 
98
      char *comment =
 
99
        (char *) malloc(sizeof(char) * reader_handle.comment_length);
 
100
      azread_comment(&reader_handle, comment);
 
101
      printf("\tComment length %u\n\t\t%.*s\n", reader_handle.comment_length, 
 
102
             reader_handle.comment_length, comment);
 
103
      free(comment);
 
104
    }
 
105
  }
 
106
  else
 
107
  {
 
108
    goto end;
 
109
  }
 
110
 
 
111
  printf("\n");
 
112
 
 
113
  if (opt_check)
 
114
  {
 
115
    int error;
 
116
    unsigned int read;
 
117
    unsigned long long row_count= 0;
 
118
 
 
119
    while ((read= azread_row(&reader_handle, &error)))
 
120
    {
 
121
      if (error == Z_STREAM_ERROR || &error)
 
122
      {
 
123
        printf("Table is damaged\n");
 
124
        goto end;
 
125
      }
 
126
 
 
127
      row_count++;
 
128
 
 
129
      if (read > reader_handle.longest_row)
 
130
      {
 
131
        printf("Table is damaged, row %llu is invalid\n", row_count);
 
132
        goto end;
 
133
      }
 
134
    }
 
135
 
 
136
    printf("Found %llu rows\n", row_count);
 
137
  }
 
138
 
 
139
  if (opt_backup)
 
140
  {
 
141
    int error;
 
142
    unsigned int read;
 
143
    unsigned long long row_count= 0;
 
144
    char *buffer;
 
145
 
 
146
    azio_stream writer_handle;
 
147
 
 
148
    buffer= (char *)malloc(reader_handle.longest_row);
 
149
    if (buffer == NULL)
 
150
    {
 
151
      printf("Could not allocate memory for row %llu\n", row_count);
 
152
      goto end;
 
153
    }
 
154
 
 
155
 
 
156
    if (!(ret= azopen(&writer_handle, argv[1], O_CREAT|O_RDWR|O_BINARY,
 
157
                      AZ_METHOD_BLOCK)))
 
158
    {
 
159
      printf("Could not open file for backup: %s\n", argv[1]);
 
160
      goto end;
 
161
    }
 
162
 
 
163
    writer_handle.auto_increment= reader_handle.auto_increment;
 
164
    if (reader_handle.frm_length)
 
165
    {
 
166
      char *ptr;
 
167
      ptr= (char *)my_malloc(sizeof(char) * reader_handle.frm_length, MYF(0));
 
168
      azread_frm(&reader_handle, ptr);
 
169
      azwrite_frm(&writer_handle, ptr, reader_handle.frm_length);
 
170
      my_free(ptr, MYF(0));
 
171
    }
 
172
 
 
173
    if (reader_handle.comment_length)
 
174
    {
 
175
      char *ptr;
 
176
      ptr= (char *)my_malloc(sizeof(char) * reader_handle.comment_length, MYF(0));
 
177
      azread_comment(&reader_handle, ptr);
 
178
      azwrite_comment(&writer_handle, ptr, reader_handle.comment_length);
 
179
      my_free(ptr, MYF(0));
 
180
    }
 
181
 
 
182
    while ((read= azread_row(&reader_handle, &error)))
 
183
    {
 
184
      if (error == Z_STREAM_ERROR || error)
 
185
      {
 
186
        printf("Table is damaged\n");
 
187
        goto end;
 
188
      }
 
189
 
 
190
      /* If we read nothing we are at the end of the file */
 
191
      if (read == 0)
 
192
        break;
 
193
 
 
194
      row_count++;
 
195
 
 
196
      azwrite_row(&writer_handle, reader_handle.row_ptr, read);
 
197
 
 
198
      if (reader_handle.rows == writer_handle.rows)
 
199
        break;
 
200
    }
 
201
 
 
202
    free(buffer);
 
203
 
 
204
    azclose(&writer_handle);
 
205
  }
 
206
 
 
207
  if (opt_extract_frm)
 
208
  {
 
209
    File frm_file;
 
210
    char *ptr;
 
211
    frm_file= my_open(argv[1], O_CREAT|O_RDWR|O_BINARY, MYF(0));
 
212
    ptr= (char *)my_malloc(sizeof(char) * reader_handle.frm_length, MYF(0));
 
213
    azread_frm(&reader_handle, ptr);
 
214
    my_write(frm_file, (uchar*) ptr, reader_handle.frm_length, MYF(0));
 
215
    my_close(frm_file, MYF(0));
 
216
    my_free(ptr, MYF(0));
 
217
  }
 
218
 
 
219
end:
 
220
  printf("\n");
 
221
  azclose(&reader_handle);
 
222
 
 
223
  my_end(0);
 
224
  return 0;
 
225
}
 
226
 
 
227
static my_bool
 
228
get_one_option(int optid,
 
229
               const struct my_option *opt __attribute__((unused)),
 
230
               char *argument)
 
231
{
 
232
  switch (optid) {
 
233
  case 'b':
 
234
    opt_backup= 1;
 
235
    break;
 
236
  case 'c':
 
237
    opt_check= 1;
 
238
    break;
 
239
  case 'e':
 
240
    opt_extract_frm= 1;
 
241
    break;
 
242
  case 'f':
 
243
    opt_force= 1;
 
244
    printf("Not implemented yet\n");
 
245
    break;
 
246
  case 'q':
 
247
    opt_quiet= 1;
 
248
    printf("Not implemented yet\n");
 
249
    break;
 
250
  case 'V':
 
251
    print_version();
 
252
    exit(0);
 
253
  case 't':
 
254
    printf("Not implemented yet\n");
 
255
    break;
 
256
  case 'A':
 
257
    opt_autoincrement= 1;
 
258
    if (argument)
 
259
      new_auto_increment_value= strtoull(argument, NULL, 0);
 
260
    else
 
261
      new_auto_increment_value= 0;
 
262
    break;
 
263
  case '?':
 
264
    usage();
 
265
    exit(0);
 
266
  case '#':
 
267
    if (argument == disabled_my_option)
 
268
    {
 
269
      DBUG_POP();
 
270
    }
 
271
    else
 
272
    {
 
273
      DBUG_PUSH(argument ? argument : "d:t:o,/tmp/archive_reader.trace");
 
274
    }
 
275
    break;
 
276
  }
 
277
  return 0;
 
278
}
 
279
 
 
280
static struct my_option my_long_options[] =
 
281
{
 
282
  {"backup", 'b',
 
283
   "Make a backup of an archive table.",
 
284
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
285
  {"check", 'c', "Check table for errors.",
 
286
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
287
#ifndef DBUG_OFF
 
288
  {"debug", '#',
 
289
   "Output debug log. Often this is 'd:t:o,filename'.",
 
290
   0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
291
#endif
 
292
  {"extract-frm", 'e',
 
293
   "Extract the frm file.",
 
294
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
295
  {"force", 'f',
 
296
   "Restart with -r if there are any errors in the table.",
 
297
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
298
  {"help", '?',
 
299
   "Display this help and exit.",
 
300
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
301
  {"quick", 'q', "Faster repair by not modifying the data file.",
 
302
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
303
  {"repair", 'r', "Repair a damaged Archive version 3 or above file.",
 
304
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
305
  {"set-auto-increment", 'A',
 
306
   "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.",
 
307
   (uchar**) &new_auto_increment,
 
308
   (uchar**) &new_auto_increment,
 
309
   0, GET_ULL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 
310
  {"silent", 's',
 
311
   "Only print errors. One can use two -s to make archive_reader very silent.",
 
312
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
313
  {"tmpdir", 't',
 
314
   "Path for temporary files.",
 
315
   (uchar**) &opt_tmpdir,
 
316
   0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 
317
  {"version", 'V',
 
318
   "Print version and exit.",
 
319
   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
 
320
  { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 
321
};
 
322
 
 
323
static void usage(void)
 
324
{
 
325
  print_version();
 
326
  puts("Copyright (C) 2007 MySQL AB");
 
327
  puts("This software comes with ABSOLUTELY NO WARRANTY. This is free software,\
 
328
       \nand you are welcome to modify and redistribute it under the GPL \
 
329
       license\n");
 
330
  puts("Read and modify Archive files directly\n");
 
331
  printf("Usage: %s [OPTIONS] file_to_be_looked_at [file_for_backup]\n", my_progname);
 
332
  print_defaults("my", load_default_groups);
 
333
  my_print_help(my_long_options);
 
334
}
 
335
 
 
336
static void print_version(void)
 
337
{
 
338
  printf("%s  Ver %s Distrib %s, for %s (%s)\n", my_progname, SHOW_VERSION,
 
339
         MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
 
340
}
 
341
 
 
342
static void get_options(int *argc, char ***argv)
 
343
{
 
344
  load_defaults("my", load_default_groups, argc, argv);
 
345
  default_argv= *argv;
 
346
 
 
347
  handle_options(argc, argv, my_long_options, get_one_option);
 
348
 
 
349
  if (*argc == 0)
 
350
  {
 
351
    usage();
 
352
    exit(-1);
 
353
  }
 
354
 
 
355
  return;
 
356
} /* get options */