00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
#include <jf/jf_config.h>
00021
00022
00023
00024
#ifdef HAVE_CTYPE_H
00025
# include <ctype.h>
00026
#endif
00027
#ifdef HAVE_ERRNO_H
00028
# include <errno.h>
00029
#endif
00030
#ifdef HAVE_STRING_H
00031
# include <string.h>
00032
#endif
00033
#ifdef HAVE_UNISTD_H
00034
# include <unistd.h>
00035
#endif
00036
#ifdef HAVE_LIBGEN_H
00037
# include <libgen.h>
00038
#endif
00039
00040
#include <jf_file.h>
00041
#include <jf/jf_journal_cold_recovery.h>
00042
#include <jf/jf_patches.h>
00043
00044
00045
00046
00047
#ifdef JF_TRACE_MODULE
00048
# undef JF_TRACE_MODULE
00049
#endif
00050 #define JF_TRACE_MODULE JF_TRACE_MOD_PRG_UTILS
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
void print_help(
char *arg);
00061
00062
00063
00064 int main(
int argc,
char *argv[])
00065 {
00066
int opt, ret_cod;
00067
char file_name[PATH_MAX + 1] =
"";
00068
int test_mode =
FALSE;
00069
int force_mode =
FALSE;
00070 uint32_t flags = 0;
00071
jf_journal_t journal;
00072
struct jf_journal_opts_s jopts;
00073
00074
if (argc < 2) {
00075
print_help(argv[0]);
00076
return 1;
00077 }
00078
00079
00080
while ((opt =
getopt(argc, argv,
"j:d:tfh")) != -1) {
00081
switch (opt) {
00082
case 'j':
00083 strncpy(file_name,
optarg,
sizeof(file_name));
00084 file_name[
sizeof(file_name) - 1] =
'\0';
00085
break;
00086
case 'd':
00087 flags |=
JF_JOURNAL_ANALYZE_TRACE;
00088
switch (tolower(
optarg[0])) {
00089
case 'n':
00090
break;
00091
case 'h':
00092 flags |=
JF_JOURNAL_ANALYZE_TRACE_HEX_DATA;
00093
break;
00094
case 't':
00095 flags |=
JF_JOURNAL_ANALYZE_TRACE_TEXT_DATA;
00096
break;
00097
case 'f':
00098 flags |=
JF_JOURNAL_ANALYZE_TRACE_HEX_DATA |
00099
JF_JOURNAL_ANALYZE_TRACE_TEXT_DATA;
00100
break;
00101
default:
00102
print_help(argv[0]);
00103
return 1;
00104 }
00105
break;
00106
case 't':
00107 test_mode =
TRUE;
00108
break;
00109
case 'f':
00110
00111 force_mode =
TRUE;
00112
break;
00113
case 'h':
00114
print_help(argv[0]);
00115
return 0;
00116
break;
00117
case '?':
00118
case ':':
00119
print_help(argv[0]);
00120
return 1;
00121
break;
00122
default:
00123 fprintf(stderr,
00124
"%s: internal error, option '-%c' not "
00125
"handled\n", argv[0], opt);
00126
return 1;
00127 }
00128 }
00129
00130
if (strlen(file_name) == 0) {
00131
print_help(argv[0]);
00132 fprintf(stderr,
00133
"%s: no journal file specified, leaving...\n",
00134 basename(argv[0]));
00135
return 1;
00136 }
00137
00138
jf_set_default_journal_opts(&jopts);
00139 jopts.
recovery_enabled =
TRUE;
00140 jopts.
recovery_damaged_journal =
FALSE;
00141 jopts.
recovery_analyze_flags = flags;
00142
if (force_mode)
00143 jopts.
recovery_damaged_journal =
TRUE;
00144
else if (test_mode)
00145 jopts.
recovery_enabled =
FALSE;
00146
00147
if (test_mode) {
00148 ret_cod =
jf_journal_cold_recovery_analyze(
00149 file_name, force_mode, NULL, flags);
00150
switch (ret_cod) {
00151
case JF_RC_COLD_RECOVERY_NEEDED:
00152
return 0;
00153
break;
00154
case JF_RC_DAMAGED_JOURNAL:
00155
return 1;
00156
break;
00157
case JF_RC_OK:
00158
return 3;
00159
break;
00160
default:
00161 fprintf(stderr,
00162
"%s/main/jf_journal_cold_recovery_analyze: "
00163
"%s (%d), system error: '%s' (errno = %d)\n",
00164 basename(argv[0]),
jf_strerror(ret_cod),
00165 ret_cod, strerror(errno), errno);
00166
return 2;
00167 }
00168 }
else {
00169 ret_cod =
jf_journal_open(&journal, file_name, 0, &jopts);
00170
if (
JF_RC_OK != ret_cod) {
00171 fprintf(stderr,
00172
"%s/main/jf_journal_open: %s (%d), system "
00173
"error: '%s' (errno = %d)\n",
00174 basename(argv[0]),
jf_strerror(ret_cod),
00175 ret_cod, strerror(errno), errno);
00176
return 1;
00177 }
00178 }
00179
00180 ret_cod =
jf_journal_close(&journal);
00181
if (
JF_RC_OK != ret_cod) {
00182 fprintf(stderr,
00183
"%s/main/jf_journal_close: %s (%d), system "
00184
"error: '%s' (errno = %d)\n",
00185 basename(argv[0]),
jf_strerror(ret_cod), ret_cod,
00186 strerror(errno), errno);
00187
return 1;
00188 }
00189
00190
return 0;
00191 }
00192
00193
00194
00195
void print_help(
char *arg)
00196 {
00197 printf(
"Usage: %s -j JOURNALFILENAME [-t [-d{n|h|t|f}] ] [-f]\n",
00198 basename(arg));
00199 printf(
"Recover all files journaled by JOURNALFILENAME\n\n");
00200 printf(
"\t-j : specify the name of the journal file must be "
00201
"host FILE\n");
00202 printf(
"\t-t : test only mode, useful to understand if recovery is necessary\n"
00203
"\t exit code values:\n"
00204
"\t\t0 - recovery is necessary\n"
00205
"\t\t1 - forced recovery is necessary\n"
00206
"\t\t2 - an error happened\n"
00207
"\t\t3 - recovery is not necessary\n"
00208
"\t-d : specifies which data must be dumped to output (test only mode)\n"
00209
"\t\t-dn no data are dumped (essential dump)\n"
00210
"\t\t-dh hexadecimal format data dump\n"
00211
"\t\t-dt text format data dump\n"
00212
"\t\t-df full (hexadecimal and text) data dump\n");
00213 printf(
"\t-f : forced recovery mode, useful to recover a damaged journal;\n"
00214
"\t use only as a LAST resource\n");
00215 printf(
"\t-h : print this help\n");
00216 }