1 /* ldc2 preliminary main program */
12 #include "tape_block.hh"
13 #include "data_block_0.hh"
15 #include "configuration_manager.hh"
19 static int in_fd
, out_fd
;
22 int dump_vector(vector
<string
> arguments
){
24 for (vector
<string
>::iterator iter
=arguments
.begin();iter
<arguments
.end();iter
++){
26 snprintf(buffer
,2000,"%s\n",(*iter
).c_str());
27 write (out_fd
,buffer
,strlen(buffer
));
35 *\brief The main routine.
37 * Here we do the configuration management and process the data.
40 int main(int argc
, char ** args
){
42 /* Configuration data */
44 string infile
, outfile
;
45 int infile_set
=0, outfile_set
=0, config_file_set
=0;
54 split_objects_numbered
=0,
55 ignore_block_errors
=0,
56 ignore_checksum_errors
=0,
57 pause_on_checksum_error
=0,
58 ignore_unknown_block_errors
=0,
59 ignore_object_integrity_errors
=0,
63 in_fd
=0; /* stdin {O _ \ */
64 out_fd
=1; /* stdout {O ^ / */
66 configuration_manager
ar("ldc2");
68 /* Here come the configuration switches */
69 ar
.add_option_switch("h","help",
70 "Output this help text and exit.",
73 ar
.add_option_switch("a","output_info",
74 "Print tape data information (default)",
75 &output_info
,true,true);
77 ar
.add_option_switch("c","output_called",
78 "Print all called symbols from the object(s).",
79 &output_called
,true,true);
81 ar
.add_option_switch("e","output_exported",
82 "Print all exported symbols from the object(s).",
83 &output_exported
,true,true);
85 ar
.add_option_switch("u","output_unsatisfied",
86 "List all unsatisfied symbols.",
87 &output_unsatisfied
,true,true);
89 ar
.add_option_switch("S","split_objects_numbered",
90 "Split input data into distinct numbered files",
91 &split_objects_numbered
,true,true);
93 ar
.add_option_switch("s","split_objects",
94 "Split input data into distinct object files.",
95 &split_objects
,true,true);
97 ar
.add_option_switch("b","ignore_block_errors",
98 "Ignore block integrity errors. This will output broken blocks,too",
99 &ignore_block_errors
,true,true);
101 ar
.add_option_switch("k","ignore_checksum_errors",
102 "Ignore block checksum errors. Errors will be converted to warnings.",
103 &ignore_checksum_errors
,true,true);
105 ar
.add_option_switch("p","pause_on_checksum_error",
106 "Wait for user input on checksum error.",
107 &pause_on_checksum_error
,true,true);
109 ar
.add_option_switch("n","ignore_unknown_block_errors",
110 "Ignore errors caused by unknown block types. Errors will be converted to warnings.",
111 &ignore_unknown_block_errors
,true,true);
113 ar
.add_option_switch("g","ignore_object_integrity_errors",
114 "Ignore errors caused by objects without proper end block. \
115 Errors will be converted to warnings.",
116 &ignore_object_integrity_errors
,true,true);
118 ar
.add_option_switch("v","verbose",
119 "Be a bit more verbose.",
122 ar
.add_option_value("i","in_file",
123 "specify input file",
125 "<input-file>",true,false);
127 ar
.add_option_value("o","out_file",
128 "Specify output file.",
129 &outfile_set
,&outfile
,
130 "<output_file>",true,true);
132 ar
.add_argument("File from where data is read",
136 ar
.add_argument("File to where output is redirected",
137 &outfile_set
,&outfile
,
140 ar
.add_option_value("F","config_file",
141 "Use the specified configuration file.",
142 &config_file_set
,&config_file
,
143 "<file-name>",false,true);
146 // If there's a config file mentioned in the environment, take it!
147 char * env_ldc_config
=getenv("LDC_CONFIG");
149 fprintf(stderr
,"Using config file:\"%s\"\n",env_ldc_config
);
150 if(dump_vector(ar
.read_file(env_ldc_config
))){
151 dump_vector(ar
.get_help());
156 // Process command line first time
157 if(dump_vector(ar
.read_args(argc
,args
))){
158 dump_vector(ar
.get_help());
163 dump_vector(ar
.get_help());
167 // If user has a config file, use it.
168 if (config_file_set
){
169 fprintf(stderr
,"Using config file:\"%s\"\n",config_file
.c_str());
170 if(dump_vector(ar
.read_file(config_file
))){
171 dump_vector(ar
.get_help());
175 // Process command line a second time to override values from config file.
176 if(dump_vector(ar
.read_args(argc
,args
))||do_help
){
177 dump_vector(ar
.get_help());
183 fprintf(stderr
,"Opening file for input:%s\n",infile
.c_str());
184 in_fd
=open(infile
.c_str(),O_RDONLY
);
186 fprintf(stderr
,"Error: could not open file \"%s\" for reading!\n",infile
.c_str());
192 fprintf(stderr
,"Opening file for output:%s\n",outfile
.c_str());
193 out_fd
=open(outfile
.c_str(),O_WRONLY
|O_TRUNC
);
195 fprintf(stderr
,"Error: could not open file \"%s\" for writing!\n",outfile
.c_str());
200 // The configuration implications according to /cfg007/
201 if (in_fd
==0) pause_on_checksum_error
=0;
202 if (pause_on_checksum_error
==1) ignore_checksum_errors
=1;
203 if (output_info
||output_called
||output_exported
||output_unsatisfied
)
207 // Now we go to read the data!
209 vector
<tape_block
*> tape
;
210 vector
<vector
<tape_block
*> > objects
;
211 vector
<tape_block
*> current_object
;
213 tape_block
* block
=0;
214 bool read_ahead
=true;
219 bool in_object
=false;
225 block
=tape_block::gen_from_fd(in_fd
);
227 block_start
=read_pointer
+block
->get_discarded_bytes();
228 block_end
=block_start
+block
->get_raw_size()-1;
229 read_pointer
=block_end
+1;
230 //printf("Discarded:%2x, Raw Size:%2x\n",block->get_discarded_bytes(),block->get_raw_size());
231 switch(block
->get_state()){ // switchy
232 case tape_block::TBS_EOF_LEGAL
:
235 fprintf(stderr
,"File successfully read.\n");
237 if (ignore_object_integrity_errors
){
238 fprintf(stderr
,"Warning: Object integrity check failed!\n");
241 fprintf(stderr
,"Error: Object integrity check failed!\n");
248 case tape_block::TBS_EOF_ILLEGAL
:
250 if (ignore_block_errors
){
251 fprintf(stderr
,"Warning: Block integrity check failed!\n");
254 fprintf(stderr
,"Error: Block integrity check failed!\n");
260 case tape_block::TBS_CHECKSUM
:
262 if (ignore_checksum_errors
){
263 fprintf(stderr
,"Warning: Block checksum wrong!\n");
266 fprintf(stderr
,"Error: Block checksum wrong!\n");
272 case tape_block::TBS_DEFAULT
:
274 fprintf(stderr
,"TBS_DEFAULT encountered ->> SEVERE INTERNAL ERROR!\n");
279 case tape_block::TBS_IOERR
:
282 fprintf(stderr
,"Error: Could not read from \"%s\"!\n",infile
.c_str());
284 fprintf(stderr
,"Error: Could not read from stdin!\n");
289 case tape_block::TBS_OK
:
290 tape
.insert(tape
.end(),block
);
295 snprintf(buffer
,200,"Block No. %3i: Start(hex):%5x End(hex):%5x Size(hex):%3x\n",
299 block
->get_raw_size());
300 write (out_fd
,buffer
,strlen(buffer
));
304 dump_vector(block
->get_description());
306 if (block
->get_type()==0x10){ // Unknown data block!
307 if (ignore_unknown_block_errors
){
308 fprintf(stderr
,"Warning: Unknown block type!\n");
311 fprintf(stderr
,"Error: Unknown block type!\n");
318 current_object
.insert(current_object
.end(),block
);
320 if ((block
->get_type()==data_block::TBT_EOT
)
321 ||((block
->get_type()==0)&&(block
->get_subtype()==3))
322 ||((block
->get_type()==4)||(block
->get_type()==3))
323 ||((block
->get_type()==0)&&(block
->get_subtype()==014))){
325 objects
.insert(objects
.end(),current_object
);
326 current_object
.clear();
336 // Now we have our blocks, tell the user about that!
338 sprintf(buffer
,"Bytes read:%i Blocks read:%i\nErrors:%i Warnings:%i\n",
339 read_pointer
,blocks_read
,errors
,warnings
);
341 write (out_fd
,buffer
,strlen(buffer
));
343 fprintf(stderr
,buffer
);
347 fprintf(stderr
,"Errors make me sick. Goodbye!\n");