00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00034 #include "libdrc.h"
00035
00036 #if HAVE_ERRNO_H
00037 #include <errno.h>
00038 #endif
00039
00040 #if HAVE_STDLIB_H
00041 #include <stdlib.h>
00042 #endif
00043
00044
00045 #include <libxml/parser.h>
00046 #include <libxml/tree.h>
00047
00048
00049
00050
00051 static char* bool_to_string( bool val );
00052 static bool string_to_bool( char* str, bool* val );
00053 static char* allocate_copy_string( const char* source );
00054
00055
00056
00057 struct _dar_drc
00058 {
00059 enum { read_file, read_memory } read_mode;
00060
00061 char* xml_buffer;
00062 char* xml_filename;
00063
00064 int xml_buffer_size;
00065
00066 char* dtd_filename;
00067 int dtd_version;
00068
00069 xmlDocPtr doc;
00070
00071
00072 dar_sup_spec* spec;
00073 dar_sup_storage* storage;
00074 dar_sup_flags* flags;
00075
00076 bool has_reference;
00077
00078 dar_sup_spec* ref_spec;
00079 dar_sup_storage* ref_storage;
00080 dar_sup_flags* ref_flags;
00081
00082
00083 };
00084
00085
00086
00087
00088
00089
00090
00091
00092 static char* get_dtd_location(const char* dtdfilepath, const char* version);
00093 static void validate_drc(dar_drc* ref, dar_sup_exception* exception);
00094 static void interpret_drc(dar_drc* ref, dar_sup_exception* exception);
00095 static bool dar_drc_prep(dar_drc* ref);
00096 static xmlNodePtr get_next_element_node(xmlNodePtr node);
00097
00098
00099
00100
00101 static void interpret_drc_1_0(dar_drc* ref, dar_sup_exception* exception);
00102
00103
00104
00105
00106 char* dar_drc_get_passphrase( dar_drc* ref )
00107 {
00108 DEBUG("Function: dar_drc_get_passphrase: Retrieving passphrase.\n");
00109 if (ref->storage->crypto_pass == NULL)
00110 return NULL;
00111 char* ret = (char*)malloc(strlen(ref->storage->crypto_pass) + 1);
00112 if (ret == NULL) { return NULL; }
00113 strcpy( ret, ref->storage->crypto_pass );
00114 return ret;
00115 }
00116
00117 bool dar_drc_set_passphrase( dar_drc* ref, char* passphrase )
00118 {
00119 DEBUG("Function: dar_drc_set_passphrase: Replacing passphrase.\n");
00120 char* tmp = ref->storage->crypto_pass;
00121 ref->storage->crypto_pass = (char*)malloc(strlen(passphrase) + 1);
00122 if (ref->storage->crypto_pass == NULL)
00123 {
00124 ref->storage->crypto_pass = tmp;
00125 return false;
00126 }
00127 strcpy( ref->storage->crypto_pass, passphrase );
00128 if (tmp != NULL)
00129 free(tmp);
00130 return true;
00131 }
00132
00133 char* dar_drc_get_reference_passphrase( dar_drc* ref )
00134 {
00135 DEBUG("Function: dar_drc_get_reference_passphrase: Retrieving reference archive passphrase.\n");
00136 if (ref->ref_storage->crypto_pass == NULL)
00137 return NULL;
00138 char* ret = (char*)malloc(strlen(ref->ref_storage->crypto_pass) + 1);
00139 if (ret == NULL) { return NULL; }
00140 strcpy( ret, ref->ref_storage->crypto_pass );
00141 return ret;
00142 }
00143
00144 bool dar_drc_set_reference_passphrase( dar_drc* ref, char* passphrase )
00145 {
00146 DEBUG("Function: dar_drc_set_reference_passphrase: Replacing reference archive passphrase.\n");
00147 char* tmp = ref->ref_storage->crypto_pass;
00148 ref->ref_storage->crypto_pass = (char*)malloc(strlen(passphrase) + 1);
00149 if (ref->ref_storage->crypto_pass == NULL)
00150 {
00151 ref->ref_storage->crypto_pass = tmp;
00152 return false;
00153 }
00154 strcpy( ref->ref_storage->crypto_pass, passphrase );
00155 if (tmp != NULL)
00156 free(tmp);
00157 return true;
00158 }
00159
00160 bool dar_drc_has_reference(dar_drc* ref)
00161 {
00162 DEBUG("Function: dar_drc_has_reference: Querying if drc contains reference archive specs.\n");
00163 return ref->has_reference;
00164 }
00165
00166 dar_archive* dar_drc_open_reference( dar_user_interaction_struct dialog,
00167 dar_drc* ref, dar_sup_exception* exception )
00168 {
00169 DEBUG("Function: dar_drc_open_reference: Opening reference archive.\n");
00170
00171 if (ref->has_reference)
00172 {
00173 DEBUG("Reference archive exists, opening.\n");
00174 dar_archive* ret = dar_op_archive_open( dialog, *(ref->ref_spec),
00175 *(ref->ref_storage), exception );
00176
00177 if ( exception->type != LIBDAR_NOEXCEPT )
00178 {
00179 DEBUG("Exception caught, throwing.\n");
00180 return NULL;
00181 }
00182 return ret;
00183 } else {
00184 DEBUG("No reference archive exists, returning null.\n");
00185 return NULL;
00186 }
00187 }
00188
00189
00190 dar_sup_spec *dar_drc_get_spec( dar_drc* ref )
00191 {
00192 DEBUG("Function: dar_drc_get_spec: Retrieving archive spec struct.\n");
00193 return ref->spec;
00194 }
00195
00196 dar_sup_storage *dar_drc_get_storage( dar_drc* ref )
00197 {
00198 DEBUG("Function: dar_drc_get_storage: Retrieving archive storage struct.\n");
00199 return ref->storage;
00200 }
00201
00202 dar_sup_flags *dar_drc_get_flags( dar_drc* ref )
00203 {
00204 DEBUG("Function: dar_drc_get_flags: Retrieving archive flags struct.\n");
00205 return ref->flags;
00206 }
00207
00208 void dar_drc_destroy( dar_drc *ref )
00209 {
00210 DEBUG("Function: dar_drc_destroy: Freeing drc context object.\n");
00211 if ( ref->doc != NULL )
00212 xmlFreeDoc(ref->doc);
00213 if ( ref->dtd_filename != NULL )
00214 free(ref->dtd_filename);
00215 if ( ref->xml_buffer != NULL )
00216 {
00217 free(ref->xml_buffer);
00218 }
00219 if ( ref->xml_filename != NULL )
00220 {
00221 free(ref->xml_filename);
00222 }
00223 if ( ref->flags != NULL )
00224 {
00225 free(ref->flags);
00226 }
00227 if ( ref->spec != NULL )
00228 {
00229 dar_sup_spec_destroy(ref->spec);
00230 free(ref->spec);
00231 }
00232 if ( ref->storage != NULL )
00233 {
00234 dar_sup_storage_destroy(ref->storage);
00235 free(ref->storage);
00236 }
00237 if ( ref->ref_spec != NULL )
00238 {
00239 dar_sup_spec_destroy(ref->ref_spec);
00240 free(ref->ref_spec);
00241 }
00242 if ( ref->ref_storage != NULL )
00243 {
00244 dar_sup_storage_destroy(ref->ref_storage);
00245 free(ref->ref_storage);
00246 }
00247 if ( ref->ref_flags != NULL )
00248 {
00249 free(ref->ref_flags);
00250 }
00251
00252 free(ref);
00253
00254 return;
00255 }
00256
00257 dar_drc *dar_drc_create( dar_drc* reference,
00258 dar_sup_spec* spec, dar_sup_storage* storage,
00259 dar_sup_flags* flags )
00260 {
00261 DEBUG("Function: dar_drc_create: Creating drc from archive spec structures.\n");
00262 dar_drc* ret = (dar_drc*)malloc(sizeof(dar_drc));
00263 if (ret == NULL)
00264 {
00265 DEBUG("Memory exhausted, could not allocate drc context object.\n");
00266 return NULL;
00267 }
00268
00269 DEBUG("Preping drc context.\n");
00270
00271 if ( !dar_drc_prep(ret) )
00272 {
00273 DEBUG("Memory exhausted, could not allocate drc internal storage.\n");
00274 free(ret);
00275 return NULL;
00276 }
00277
00278 DEBUG("Copying reference archive specification if applicable.\n");
00279
00280 if (reference != NULL)
00281 {
00282 DEBUG("Copying reference archive elements: spec structure.\n");
00283
00284 if (reference->spec->arc_path != NULL)
00285 {
00286 ret->ref_spec->arc_path =
00287 allocate_copy_string(reference->spec->arc_path);
00288 if ( ret->ref_spec->arc_path == NULL )
00289 {
00290 DEBUG("Memory exhausted, could not allocate archive path copy.\n");
00291 dar_drc_destroy(ret);
00292 return NULL;
00293 }
00294 }
00295
00296 if (reference->spec->arc_name != NULL)
00297 {
00298 ret->ref_spec->arc_name =
00299 allocate_copy_string(reference->spec->arc_name);
00300 if ( ret->ref_spec->arc_name == NULL )
00301 {
00302 DEBUG("Memory exhausted, could not allocate archive name copy.\n");
00303 dar_drc_destroy(ret);
00304 return NULL;
00305 }
00306 }
00307
00308 if (reference->spec->arc_ext != NULL)
00309 {
00310 ret->ref_spec->arc_ext =
00311 allocate_copy_string(reference->spec->arc_ext);
00312 if ( ret->ref_spec->arc_ext == NULL )
00313 {
00314 DEBUG("Memory exhausted, could not allocate archive extension copy.\n");
00315 dar_drc_destroy(ret);
00316 return NULL;
00317 }
00318 }
00319
00320 if (reference->spec->input_pipe != NULL)
00321 {
00322 ret->ref_spec->input_pipe =
00323 allocate_copy_string(reference->spec->input_pipe);
00324 if ( ret->ref_spec->input_pipe == NULL )
00325 {
00326 DEBUG("Memory exhausted, could not allocate input pipe name copy.\n");
00327 dar_drc_destroy(ret);
00328 return NULL;
00329 }
00330 }
00331
00332 if (reference->spec->output_pipe != NULL)
00333 {
00334 ret->ref_spec->output_pipe =
00335 allocate_copy_string(reference->spec->output_pipe);
00336 if ( ret->ref_spec->output_pipe == NULL )
00337 {
00338 DEBUG("Memory exhausted, could not allocate output pipe name copy.\n");
00339 dar_drc_destroy(ret);
00340 return NULL;
00341 }
00342 }
00343
00344 DEBUG("Copying reference archive elements: storage structure.\n");
00345
00346 ret->ref_storage->crypto_algo =
00347 reference->storage->crypto_algo;
00348
00349 ret->ref_storage->crypto_size =
00350 reference->storage->crypto_size;
00351
00352 if (reference->storage->crypto_pass != NULL)
00353 {
00354 ret->ref_storage->crypto_pass =
00355 allocate_copy_string(reference->storage->crypto_pass);
00356 if ( ret->ref_storage->crypto_pass == NULL )
00357 {
00358 DEBUG("Memory exhausted, could not allocate passphrase copy.\n");
00359 dar_drc_destroy(ret);
00360 return NULL;
00361 }
00362 }
00363
00364 if (reference->storage->slice_execute != NULL)
00365 {
00366 ret->ref_storage->slice_execute =
00367 allocate_copy_string(reference->storage->slice_execute);
00368 if ( ret->ref_storage->slice_execute == NULL )
00369 {
00370 DEBUG("Memory exhausted, could not allocate interslice command copy.\n");
00371 dar_drc_destroy(ret);
00372 return NULL;
00373 }
00374 }
00375
00376 DEBUG("Finished copying reference archive elements.\n");
00377 }
00378
00379 DEBUG("Inserting archive specification structures.\n");
00380
00381 ret->spec = spec;
00382 ret->storage = storage;
00383 ret->flags = flags;
00384
00385 return ret;
00386 }
00387
00388 bool dar_drc_write_xml_file( const char* filename,
00389 dar_sup_exception* exception )
00390 {
00391 DEBUG("Function: dar_drc_write_xml_file: Writing drc to file.\n");
00392
00393 LIBDARC_EXCEPTION(exception, LIBDAR_ELIBCALL,
00394 "Library call not yet implemented.");
00395 return false;
00396
00397 }
00398
00399 char* dar_drc_write_xml_buffer( dar_sup_exception* exception )
00400 {
00401 DEBUG("Function: dar_drc_write_xml_buffer: Writing drc to memory.\n");
00402
00403 LIBDARC_EXCEPTION(exception, LIBDAR_ELIBCALL,
00404 "Library call not yet implemented.");
00405 return NULL;
00406 }
00407
00408 dar_drc *dar_drc_parse_xml_memory( const char* buffer, int size,
00409 const char* dtdfilepath, dar_sup_exception* exception )
00410 {
00411 exception->type = LIBDAR_NOEXCEPT;
00412
00413 DEBUG("Function: dar_drc_parse_xml_memory: Building drc from memory.\n");
00414 dar_drc* ret = (dar_drc*)malloc(sizeof(dar_drc));
00415 if (ret == NULL)
00416 {
00417 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00418 "Memory exhausted, could not allocate drc context object.");
00419 return NULL;
00420 }
00421
00422 DEBUG("Prepring drc content.\n");
00423
00424 if ( !dar_drc_prep(ret) )
00425 {
00426 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00427 "Memory exhausted, could not allocate drc internal storage.");
00428 free(ret);
00429 return NULL;
00430 }
00431
00432 ret->read_mode = read_memory;
00433 ret->xml_buffer = (char*)malloc(size);
00434 if (ret->xml_buffer == NULL)
00435 {
00436 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00437 "Memory exhausted, could not allocate xml buffer copy.");
00438 dar_drc_destroy(ret);
00439 return NULL;
00440 }
00441 memcpy( ret->xml_buffer, buffer, size );
00442 ret->xml_buffer_size = size;
00443
00444 ret->doc = xmlReadMemory(ret->xml_buffer, size, NULL, NULL, 0);
00445 if (ret->doc == NULL)
00446 {
00447 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
00448 "Failed to parse xml file.");
00449 dar_drc_destroy(ret);
00450 return NULL;
00451 }
00452
00453 if (dtdfilepath != NULL)
00454 {
00455 ret->dtd_filename = allocate_copy_string(dtdfilepath);
00456 if (ret->dtd_filename == NULL)
00457 {
00458 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00459 "Memory exhausted, could not allocate dtd filename copy.");
00460 dar_drc_destroy(ret);
00461 return NULL;
00462 }
00463 } else {
00464 ret->dtd_filename = NULL;
00465 }
00466
00467 validate_drc(ret, exception);
00468 if (exception->type != LIBDAR_NOEXCEPT)
00469 {
00470 DEBUG("Exception caught, cleaning up and throwing.\n");
00471 dar_drc_destroy(ret);
00472 return NULL;
00473 }
00474
00475 interpret_drc(ret, exception);
00476 if (exception->type != LIBDAR_NOEXCEPT)
00477 {
00478 DEBUG("Exception caught, cleaning up and throwing.\n");
00479 dar_drc_destroy(ret);
00480 return NULL;
00481 }
00482
00483 DEBUG("File parsing complete, returning drc object.\n");
00484 return ret;
00485 }
00486
00487 dar_drc *dar_drc_parse_xml_file( const char* filename,
00488 const char* dtdfilepath, dar_sup_exception* exception)
00489 {
00490 exception->type = LIBDAR_NOEXCEPT;
00491
00492 DEBUG("Function: dar_drc_parse_xml_file: Building drc from file.\n");
00493 dar_drc* ret = (dar_drc*)malloc(sizeof(dar_drc));
00494 if (ret == NULL)
00495 {
00496 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00497 "Memory exhausted, could not allocate drc context object.");
00498 return NULL;
00499 }
00500
00501
00502
00503
00504
00505 DEBUG("Preping drc content.\n");
00506
00507 if ( !dar_drc_prep(ret) )
00508 {
00509 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00510 "Memory exhausted, could not allocate drc internal storage.");
00511 free(ret);
00512 return NULL;
00513 }
00514
00515 ret->read_mode = read_file;
00516 ret->xml_filename = allocate_copy_string(filename);
00517 if (ret->xml_filename == NULL)
00518 {
00519 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00520 "Memory exhausted, could not allocate xml filename copy.");
00521 dar_drc_destroy(ret);
00522 return NULL;
00523 }
00524 ret->doc = xmlReadFile(filename, NULL, 0);
00525 if (ret->doc == NULL)
00526 {
00527 LIBDARC_EXCEPTION( exception, LIBDAR_X_EINPUTSPEC,
00528 "Failed to parse xml file.");
00529 dar_drc_destroy(ret);
00530 return NULL;
00531 }
00532
00533 if (dtdfilepath != NULL)
00534 {
00535 ret->dtd_filename = allocate_copy_string(dtdfilepath);
00536 if (ret->dtd_filename == NULL)
00537 {
00538 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00539 "Memory exhausted, could not allocate dtd filename copy.");
00540 dar_drc_destroy(ret);
00541 return NULL;
00542 }
00543 } else {
00544 ret->dtd_filename = NULL;
00545 }
00546
00547
00548 validate_drc(ret, exception);
00549 if (exception->type != LIBDAR_NOEXCEPT)
00550 {
00551 DEBUG("Exception caught, cleaning up and throwing.\n");
00552 dar_drc_destroy(ret);
00553 return NULL;
00554 }
00555
00556 interpret_drc(ret, exception);
00557 if (exception->type != LIBDAR_NOEXCEPT)
00558 {
00559 DEBUG("Exception caught, cleaning up and throwing.\n");
00560 dar_drc_destroy(ret);
00561 return NULL;
00562 }
00563
00564 DEBUG("File parsing complete, returning drc object.\n");
00565 return ret;
00566 }
00567
00568 static void validate_drc(dar_drc* ref, dar_sup_exception* exception)
00569 {
00570 DEBUG("Function: validate_drc: Validating drc file against dtd.\n");
00571
00572
00573
00574 DEBUG("Determining xml file version.\n");
00575
00576 xmlNodePtr root = xmlDocGetRootElement(ref->doc);
00577
00578 if ( strcmp("JobSettings", root->name) != 0 )
00579 {
00580 DEBUG("Root node named %s.\n", root->name);
00581 LIBDARC_EXCEPTION( exception, LIBDAR_X_EINPUTSPEC,
00582 "Input file not valid, incorrect root node.");
00583 return;
00584 }
00585
00586 if ( !xmlHasProp(root, "FileVersion") )
00587 {
00588 LIBDARC_EXCEPTION( exception, LIBDAR_X_EINPUTSPEC,
00589 "Input file not valid, file version not present.");
00590 return;
00591 }
00592
00593 xmlChar* version = xmlGetProp(root, "FileVersion");
00594 if (version == NULL)
00595 {
00596 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00597 "Memory exhausted, could not allocate version attribute copy.");
00598 return;
00599 }
00600 DEBUG("Input file version: %s\n", version);
00601
00602 if ( strcmp( version, "1.0" ) == 0 )
00603 {
00604 ref->dtd_version = 10;
00605 } else {
00606 LIBDARC_EXCEPTION( exception, LIBDAR_X_EINPUTSPEC,
00607 "Input file version not supported.");
00608 }
00609
00610 DEBUG("Loading dtd.\n");
00611
00612 char* filename = ref->dtd_filename;
00613 ref->dtd_filename = get_dtd_location( filename, version );
00614 if (ref->dtd_filename == NULL)
00615 {
00616 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00617 "Memory exhausted, could not allocate dtd path.");
00618 return;
00619 }
00620 if (filename != NULL)
00621 free(filename);
00622 xmlFree(version);
00623
00624 DEBUG("Dtd file path: %s\n", ref->dtd_filename);
00625
00626 xmlValidCtxtPtr ctxt = xmlNewValidCtxt();
00627 if (ctxt == NULL)
00628 {
00629 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00630 "Memory exhausted, could not allocate xml validation context.");
00631 return;
00632 }
00633
00634 xmlDtdPtr dtd = xmlParseDTD(NULL, ref->dtd_filename);
00635 if (dtd == NULL)
00636 {
00637 LIBDARC_EXCEPTION( exception, LIBDAR_EMEMORY,
00638 "Memory exhausted, could not allocate dtd object.");
00639 xmlFreeValidCtxt(ctxt);
00640 return;
00641 }
00642
00643 if ( !xmlValidateDtd( ctxt, ref->doc, dtd ) )
00644 {
00645 LIBDARC_EXCEPTION( exception, LIBDAR_X_EINPUTSPEC,
00646 "Input file invalid, validation against DTD failed.");
00647 xmlFreeValidCtxt(ctxt);
00648 return;
00649 }
00650 xmlFreeValidCtxt(ctxt);
00651
00652 DEBUG("Freeing dtd context.\n");
00653 xmlFreeDtd(dtd);
00654
00655 return;
00656 }
00657
00658 static void interpret_drc(dar_drc* ref, dar_sup_exception* exception)
00659 {
00660 DEBUG("Function: interpret_drc: Translating drc xml tree to libdarc specs.\n");
00661
00662 switch ( ref->dtd_version )
00663 {
00664 case 10:
00665 interpret_drc_1_0(ref, exception);
00666 DEBUG("Exit function: interpret_drc_1_0\n");
00667 DEBUG("Returned: %d\n", exception->type);
00668 break;
00669 default:
00670 LIBDARC_EXCEPTION(exception, LIBDAR_EBUG,
00671 "Requested drc interpreter invalid.");
00672 break;
00673 }
00674 return;
00675 }
00676
00677
00678
00679
00680
00681
00682
00683 static dar_mask *interpret_drc_1_0_recurse_mask(xmlNodePtr node,
00684 dar_drc* ref, dar_sup_exception* exception)
00685 {
00686 DEBUG("Function: interpret_drc_1_0_recurse_mask: Interpret mask elements.\n");
00687
00688 xmlChar* type = xmlGetProp(node, "Type");
00689 if (type == NULL)
00690 {
00691 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00692 "Memory exhausted, could not allocate attribute copy.");
00693 }
00694 DEBUG("Element type: %s\n", type);
00695
00696 dar_mask* ret;
00697
00698
00699 if ( strcmp( node->name, "MaskUnion") == 0 )
00700 {
00701 enum { type_or, type_and, type_not } union_type;
00702
00703
00704 DEBUG("Interpreting MaskUnion type.\n");
00705 dar_mask* in = NULL;
00706 xmlNodePtr tmp = node->children;
00707
00708 DEBUG("Building specific mask union container.\n");
00709
00710 if ( strcmp(type, "and") == 0 )
00711 {
00712 DEBUG("And union found.\n");
00713 union_type = type_and;
00714 ret = dar_mask_create_and();
00715 } else if ( strcmp(type, "or") == 0 )
00716 {
00717 DEBUG("Or union found.\n");
00718 union_type = type_or;
00719 ret = dar_mask_create_or();
00720 } else if ( strcmp(type, "not") == 0 )
00721 {
00722 DEBUG("Not union found.\n");
00723 union_type = type_not;
00724
00725 dar_mask* in = NULL;
00726 xmlNodePtr tmp = node->children;
00727
00728 DEBUG("Finding union element.\n");
00729
00730 do
00731 {
00732 DEBUG("Element type: %d\n", tmp->type);
00733 DEBUG("Element name: %s\n", tmp->name);
00734 if ( tmp->type == XML_ELEMENT_NODE )
00735 {
00736 DEBUG("Element selected.\n");
00737 in = interpret_drc_1_0_recurse_mask(tmp, ref, exception);
00738 if ( exception->type != LIBDAR_NOEXCEPT)
00739 {
00740 xmlFree(type);
00741 return NULL;
00742 }
00743 break;
00744 }
00745 } while ( (tmp = tmp->next) != tmp->last );
00746
00747 if (in == NULL)
00748 {
00749 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
00750 "Input file invalid, no child node for not mask.");
00751 xmlFree(type);
00752 return NULL;
00753 }
00754
00755 ret = dar_mask_create_not(in);
00756 if (ret == NULL)
00757 {
00758 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00759 "Memory exhausted, could not allocate mask object.");
00760 }
00761 xmlFree(type);
00762 dar_mask_destroy(in);
00763 return ret;
00764 } else {
00765 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
00766 "Input file invalid, mask union type not valid.");
00767 xmlFree(type);
00768 return NULL;
00769 }
00770
00771 if (ret == NULL)
00772 {
00773 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00774 "Memory exhausted, could not allocate mask object.");
00775 xmlFree(type);
00776 return NULL;
00777 }
00778
00779 DEBUG("Finding union elements.\n");
00780
00781 for (; tmp; tmp = tmp->next)
00782 {
00783 DEBUG("Next node: %s\n", tmp->name);
00784
00785 if (tmp->type == XML_ELEMENT_NODE)
00786 {
00787 DEBUG("Element selected.\n");
00788 in = interpret_drc_1_0_recurse_mask(tmp, ref, exception);
00789 if ( exception->type != LIBDAR_NOEXCEPT )
00790 {
00791 dar_mask_destroy(ret);
00792 xmlFree(type);
00793 return NULL;
00794 } else {
00795 switch(union_type)
00796 {
00797 case type_and:
00798 dar_mask_and_add(ret, in);
00799 break;
00800 case type_or:
00801 dar_mask_or_add(ret, in);
00802 break;
00803 default:
00804 LIBDARC_EXCEPTION(exception, LIBDAR_EBUG,
00805 "Invalid mask union type selected.");
00806 dar_mask_destroy(in);
00807 dar_mask_destroy(ret);
00808 xmlFree(type);
00809 return NULL;
00810 }
00811 }
00812 dar_mask_destroy(in);
00813 }
00814 }
00815 xmlFree(type);
00816 return ret;
00817
00818 } else {
00819 DEBUG("Check for mask element properties.\n");
00820
00821 bool case_sensit = true;
00822 if ( xmlHasProp(node, "CaseSensitive") )
00823 {
00824 xmlChar* cs_tmp = xmlGetProp(node, "CaseSensitive");
00825 if ( !string_to_bool( cs_tmp, &case_sensit ) )
00826 {
00827 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
00828 "Input file invalid, could not parse case sensitive setting.");
00829 xmlFree(cs_tmp);
00830 xmlFree(type);
00831 return NULL;
00832 }
00833 xmlFree(cs_tmp);
00834 }
00835
00836
00837 if ( strcmp(type, "samepath") == 0 )
00838 {
00839 DEBUG("Samepath node type found.\n");
00840 xmlChar* cont = xmlNodeGetContent(node);
00841 ret = dar_mask_create_same_path(cont, case_sensit);
00842 if (ret == NULL)
00843 {
00844 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00845 "Memory exhausted, could not allocate mask object.");
00846 }
00847 xmlFree(type);
00848 xmlFree(cont);
00849 return ret;
00850 } else if ( strcmp(type, "boolean") == 0 )
00851 {
00852 DEBUG("Boolean node type found.\n");
00853 xmlChar* cont = xmlNodeGetContent(node);
00854 bool tmpb;
00855 if ( !string_to_bool( cont, &tmpb ) )
00856 {
00857 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
00858 "Input file invalid, could not parse boolean mask setting.");
00859 xmlFree(type);
00860 xmlFree(cont);
00861 return NULL;
00862 }
00863 ret = dar_mask_create_bool( tmpb );
00864 if (ret == NULL)
00865 {
00866 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00867 "Memory exhausted, could not allocate mask object.");
00868 }
00869 xmlFree(type);
00870 xmlFree(cont);
00871 return ret;
00872 } else if ( strcmp(type, "excludedir") == 0 )
00873 {
00874 DEBUG("Exclude dir node type found.\n");
00875 xmlChar* cont = xmlNodeGetContent(node);
00876 ret = dar_mask_create_exclude_dir(cont, case_sensit);
00877 if (ret == NULL)
00878 {
00879 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00880 "Memory exhausted, could not allocate mask object.");
00881 }
00882 xmlFree(type);
00883 xmlFree(cont);
00884 return ret;
00885 } else if ( strcmp(type, "regular") == 0 )
00886 {
00887 DEBUG("Regular node type found.\n");
00888 xmlChar* cont = xmlNodeGetContent(node);
00889 ret = dar_mask_create_regular(cont, case_sensit);
00890 if (ret == NULL)
00891 {
00892 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00893 "Memory exhausted, could not allocate mask object.");
00894 }
00895 xmlFree(type);
00896 xmlFree(cont);
00897 return ret;
00898 } else if ( strcmp(type, "simple") == 0 )
00899 {
00900 DEBUG("Simple node type found.\n");
00901 xmlChar* cont = xmlNodeGetContent(node);
00902 ret = dar_mask_create_simple(cont, case_sensit);
00903 if (ret == NULL)
00904 {
00905 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00906 "Memory exhausted, could not allocate mask object.");
00907 }
00908 xmlFree(type);
00909 xmlFree(cont);
00910 return ret;
00911 } else if ( strcmp(type, "simplepath") == 0 )
00912 {
00913 DEBUG("Simple path node type found.\n");
00914 xmlChar* cont = xmlNodeGetContent(node);
00915 ret = dar_mask_create_simple_path(cont, case_sensit);
00916 if (ret == NULL)
00917 {
00918 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
00919 "Memory exhausted, could not allocate mask object.");
00920 }
00921 xmlFree(type);
00922 xmlFree(cont);
00923 return ret;
00924 } else {
00925 DEBUG("Invalid node type found: %s\n", type);
00926 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
00927 "Input file invalid, mask type not supported.");
00928 xmlFree(type);
00929 return NULL;
00930 }
00931 }
00932 }
00933
00934
00935
00936
00937 static void interpret_drc_1_0_recurse_flags(xmlNodePtr node,
00938 dar_drc* ref, dar_sup_exception* exception)
00939 {
00940 DEBUG("Function: interpret_drc_1_0_recurse_flags: Interpret flag elements.\n");
00941 if ( node == NULL )
00942 {
00943 return;
00944 }
00945
00946
00947 bool tmp;
00948 xmlChar* cont = xmlNodeGetContent(node);
00949 if (!string_to_bool(cont, &tmp))
00950 {
00951 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
00952 "Input file invalid, flag content not valid.");
00953 if (cont != NULL)
00954 xmlFree(cont);
00955 return;
00956 }
00957 xmlFree(cont);
00958
00959 DEBUG("Element name: %s\n", node->name);
00960 DEBUG("Element value: %d\n", tmp);
00961
00962 if ( strcmp(node->name, "AllowOverwrite") == 0 )
00963 {
00964 ref->flags->allow_overwrite = tmp;
00965 } else if ( strcmp(node->name, "WarnOverwrite") == 0 )
00966 {
00967 ref->flags->warn_overwrite = tmp;
00968 } else if ( strcmp(node->name, "SlicePause") == 0 )
00969 {
00970 ref->flags->slice_pause = tmp;
00971 } else if ( strcmp(node->name, "CreateEmptyStubs") == 0 )
00972 {
00973 ref->flags->create_empty_stubs = tmp;
00974 } else if ( strcmp(node->name, "EaSystem") == 0 )
00975 {
00976 ref->flags->ea_system = tmp;
00977 } else if ( strcmp(node->name, "EaUser") == 0 )
00978 {
00979 ref->flags->ea_user = tmp;
00980 } else if ( strcmp(node->name, "NoDump") == 0 )
00981 {
00982 ref->flags->no_dump = tmp;
00983 } else if ( strcmp(node->name, "IgnoreOwner") == 0 )
00984 {
00985 ref->flags->ignore_owner = tmp;
00986 } else if ( strcmp(node->name, "TestRun") == 0 )
00987 {
00988 ref->flags->test_run = tmp;
00989 } else if ( strcmp(node->name, "AlterAtime") == 0 )
00990 {
00991 ref->flags->alter_atime = tmp;
00992 } else if ( strcmp(node->name, "SameFs") == 0 )
00993 {
00994 ref->flags->same_fs = tmp;
00995 } else if ( strcmp(node->name, "DeleteMarked") == 0 )
00996 {
00997 ref->flags->delete_marked = tmp;
00998 } else if ( strcmp(node->name, "RestoreFlat") == 0 )
00999 {
01000 ref->flags->restore_flat = tmp;
01001 } else if ( strcmp(node->name, "WarnRemoveNoMatch") == 0 )
01002 {
01003 ref->flags->warn_remove_no_match = tmp;
01004 } else if ( strcmp(node->name, "OnlyMoreRecent") == 0 )
01005 {
01006 ref->flags->only_more_recent = tmp;
01007 } else if ( strcmp(node->name, "TarFormat") == 0 )
01008 {
01009 ref->flags->tar_format = tmp;
01010 } else if ( strcmp(node->name, "FilterUnsaved") == 0 )
01011 {
01012 ref->flags->filter_unsaved = tmp;
01013 } else
01014 {
01015 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01016 "Input file invalid, flag element unsupported.");
01017 }
01018
01019 node = get_next_element_node(node->next);
01020
01021 interpret_drc_1_0_recurse_flags(node, ref, exception);
01022 return;
01023 }
01024
01025
01026 static void interpret_drc_1_0_encryption(xmlNodePtr node,
01027 dar_drc* ref, dar_sup_exception* exception)
01028 {
01029 DEBUG("Function: interpret_drc_1_0_encryption: Interpreting encryption element.\n");
01030 xmlChar* algo = xmlGetProp(node, "Algorithm");
01031
01032 if (strcmp( algo, "none" ) == 0 )
01033 {
01034 ref->storage->crypto_algo = dar_crypto_none;
01035 xmlFree(algo);
01036 return;
01037 }
01038
01039 if ( strcmp( algo, "blowfish" ) == 0 )
01040 {
01041 ref->storage->crypto_algo = dar_crypto_blowfish;
01042 } else if ( strcmp( algo, "scrambling" ) == 0 )
01043 {
01044 ref->storage->crypto_algo = dar_crypto_scrambling;
01045 } else
01046 {
01047 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01048 "Input file invalid, encryption algorithm unsupported.");
01049 xmlFree(algo);
01050 return;
01051 }
01052 xmlFree(algo);
01053
01054 xmlChar* block = xmlGetProp(node, "BlockSize");
01055
01056 errno = 0;
01057 long s = strtol(block, NULL, 10);
01058 if ( errno != 0 || s >= U_32_MAX )
01059 {
01060 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01061 "Input file invalid, could not parse block size.");
01062 xmlFree(block);
01063 return;
01064 }
01065 xmlFree(block);
01066
01067 ref->storage->crypto_size = (U_32)s;
01068
01069 xmlChar* cont = xmlNodeGetContent(node);
01070 if ( cont == NULL || strcmp ( cont, "" ) == 0 )
01071 {
01072 return;
01073 } else {
01074 ref->storage->crypto_pass = allocate_copy_string(cont);
01075 if ( ref->storage->crypto_pass == NULL )
01076 {
01077 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01078 "Memory exhausted, could not allocate passphrase copy.");
01079 }
01080 }
01081
01082 if ( cont != NULL )
01083 xmlFree(cont);
01084
01085 return;
01086 }
01087
01088
01089 static void interpret_drc_1_0_compression(xmlNodePtr node,
01090 dar_drc* ref, dar_sup_exception* exception)
01091 {
01092 DEBUG("Function: interpret_drc_1_0_compression: Interpreting compression element.\n");
01093 xmlChar* algo = xmlGetProp(node, "Algorithm");
01094
01095 if ( strcmp( algo, "none" ) == 0 )
01096 {
01097 ref->storage->compress_algo = dar_compression_none;
01098 xmlFree(algo);
01099 return;
01100 }
01101
01102 if ( strcmp( algo, "zip" ) == 0 )
01103 {
01104 ref->storage->compress_algo = dar_compression_zip;
01105 } else if ( strcmp( algo, "gzip" ) == 0 )
01106 {
01107 ref->storage->compress_algo = dar_compression_gzip;
01108 } else if ( strcmp( algo, "bzip2" ) == 0 )
01109 {
01110 ref->storage->compress_algo = dar_compression_bzip2;
01111 } else
01112 {
01113 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01114 "Input file invalid, compression algorithm unsupported.");
01115 xmlFree(algo);
01116 return;
01117 }
01118 xmlFree(algo);
01119
01120 xmlChar* tn = xmlGetProp(node, "Level");
01121
01122 errno = 0;
01123 long s = strtol(tn, NULL, 10);
01124 if ( errno != 0 || s > 9 )
01125 {
01126 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01127 "Input file invalid, compression level invalid.");
01128 xmlFree(tn);
01129 return;
01130 }
01131 xmlFree(tn);
01132
01133 ref->storage->compress_level = (U_I)s;
01134
01135 tn = xmlGetProp(node, "MinSize");
01136
01137 dar_infinint* si = dar_infhs(tn);
01138 if ( si == NULL )
01139 {
01140 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01141 "Input file invalid, compression minimum size invalid.");
01142 xmlFree(tn);
01143 dar_infinint_destroy(si);
01144 return;
01145 }
01146 xmlFree(tn);
01147
01148 ref->storage->compress_min_size = si;
01149
01150 xmlNodePtr ch = node->children;
01151
01152 if ( ch->type != XML_ELEMENT_NODE )
01153 {
01154 ch = get_next_element_node(ch);
01155 }
01156
01157 ref->storage->compress_mask =
01158 interpret_drc_1_0_recurse_mask(ch, ref, exception);
01159 if ( exception->type != LIBDAR_NOEXCEPT )
01160 {
01161 DEBUG("Exception caught, throwing.\n");
01162 return;
01163 }
01164 return;
01165 }
01166
01167
01168 static void interpret_drc_1_0_slice_size(xmlNodePtr node,
01169 dar_drc* ref, dar_sup_exception* exception)
01170 {
01171 DEBUG("Function: interpret_drc_1_0_slice_size: Interpreting slice size element.\n");
01172 xmlChar* tmp = NULL;
01173 if ( xmlHasProp( node, "Initial" ) )
01174 {
01175 tmp = xmlGetProp(node, "Initial");
01176 if (tmp == NULL)
01177 {
01178 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01179 "Memory exhausted, could not allocate copy of intial size.");
01180 return;
01181 }
01182 dar_infinint* ti = dar_tools_get_extended_size(tmp, 1024);
01183 if (ti == NULL)
01184 {
01185 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01186 "Input file invalid, could not parse initial slice size.");
01187 xmlFree(tmp);
01188 return;
01189 }
01190 xmlFree(tmp);
01191 ref->storage->first_file_size = ti;
01192 }
01193 tmp = xmlNodeGetContent(node);
01194 if (tmp == NULL)
01195 {
01196 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01197 "Memory exhausted, could not allocate copy of size element.");
01198 return;
01199 }
01200 dar_infinint* tib = dar_tools_get_extended_size(tmp, 1024);
01201 if (tib == NULL)
01202 {
01203 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01204 "Input file invalid, could not parse slice size.");
01205 xmlFree(tmp);
01206 return;
01207 }
01208 xmlFree(tmp);
01209 ref->storage->file_size = tib;
01210
01211 return;
01212 }
01213
01214
01215 static void interpret_drc_1_0_archive(xmlNodePtr node,
01216 dar_drc* ref, dar_sup_exception* exception)
01217 {
01218 DEBUG("Function: interpret_drc_1_0_archive: Interpreting archive element.\n");
01219 if ( !xmlHasProp(node, "Type") )
01220 {
01221 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01222 "Input file invalid, archive element does not have type attribute.");
01223 return;
01224 }
01225
01226 xmlChar* type = xmlGetProp(node, "Type");
01227 if (type == NULL)
01228 {
01229 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01230 "Memory exhausted, could not allocate copy of archive spec type.");
01231 return;
01232 }
01233
01234 xmlChar* tmp = NULL;
01235 if ( strcmp(type, "pipeset") == 0 )
01236 {
01237 xmlFree(type);
01238 tmp = xmlNodeGetContent(node);
01239 if (tmp == NULL)
01240 {
01241 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01242 "Input file invalid, pipe elements not listed in archive element.");
01243 return;
01244 }
01245 char* l = NULL;
01246 char* t = NULL;
01247 t = strtok_r(tmp, ";", &l);
01248 if (t == NULL)
01249 {
01250 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01251 "Input file invalid, input pipe string not found.");
01252 xmlFree(tmp);
01253 return;
01254 }
01255 ref->spec->input_pipe = allocate_copy_string(t);
01256 if ( ref->spec->input_pipe == NULL )
01257 {
01258 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01259 "Memory exhausted, could not allocate copy of input pipe.");
01260 }
01261 t = strtok_r(NULL, ";", &l);
01262 if (t == NULL)
01263 {
01264 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01265 "Input file invalid, output pipe string not found.");
01266 xmlFree(tmp);
01267 return;
01268 }
01269 ref->spec->output_pipe = allocate_copy_string(t);
01270 if ( ref->spec->output_pipe == NULL )
01271 {
01272 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01273 "Memory exhausted, could not allocate copy of output pipe.");
01274 }
01275 xmlFree(tmp);
01276
01277 ref->spec->arc_path = allocate_copy_string("");
01278 if ( ref->spec->arc_path == NULL )
01279 {
01280 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01281 "Memory exhausted, could not allocate empty archive path.");
01282 }
01283
01284 ref->spec->arc_ext = allocate_copy_string("dar");
01285 if ( ref->spec->arc_ext == NULL )
01286 {
01287 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01288 "Memory exhausted, could not allocate set archive extension.");
01289 }
01290
01291
01292 ref->spec->arc_name = allocate_copy_string("-");
01293 if ( ref->spec->arc_name == NULL )
01294 {
01295 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01296 "Memory exhausted, could not allocate set archive name.");
01297 }
01298
01299 } else if ( strcmp(type, "file") == 0 )
01300 {
01301 xmlFree(type);
01302
01303 if ( xmlHasProp(node, "Root") )
01304 {
01305 tmp = xmlGetProp(node, "Root");
01306 ref->spec->arc_path = allocate_copy_string(tmp);
01307 if ( ref->spec->arc_path == NULL )
01308 {
01309 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01310 "Memory exhausted, could not allocate copy of archive path.");
01311 xmlFree(tmp);
01312 return;
01313 }
01314 xmlFree(tmp);
01315 } else
01316 {
01317 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01318 "Input file invalid, archive path not indicated.");
01319 return;
01320 }
01321
01322 if ( xmlHasProp(node, "Extension") )
01323 {
01324 tmp = xmlGetProp(node, "Extension");
01325 ref->spec->arc_ext = allocate_copy_string(tmp);
01326 if ( ref->spec->arc_ext == NULL )
01327 {
01328 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01329 "Memory exhausted, could not allocate copy of archive extension.");
01330 xmlFree(tmp);
01331 return;
01332 }
01333 xmlFree(tmp);
01334 } else
01335 {
01336 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01337 "Input file invalid, archive extension not indicated.");
01338 return;
01339 }
01340
01341 tmp = xmlNodeGetContent(node);
01342 if (tmp == NULL)
01343 {
01344 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01345 "Input file invalid, archive name not found.");
01346 xmlFree(tmp);
01347 return;
01348 }
01349
01350 ref->spec->arc_name = allocate_copy_string(tmp);
01351 if ( ref->spec->arc_name == NULL )
01352 {
01353 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01354 "Memory exhausted, could not allocate copy of archive name.");
01355 xmlFree(tmp);
01356 return;
01357 }
01358 xmlFree(tmp);
01359
01360 ref->spec->input_pipe = allocate_copy_string("");
01361 if ( ref->spec->input_pipe == NULL )
01362 {
01363 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01364 "Memory exhausted, could not allocate set input pipe name.");
01365 }
01366
01367 ref->spec->output_pipe = allocate_copy_string("");
01368 if ( ref->spec->output_pipe == NULL )
01369 {
01370 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01371 "Memory exhausted, could not allocate set output pipe name.");
01372 }
01373
01374 } else
01375 {
01376 xmlFree(type);
01377
01378 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01379 "Input file invalid, archive type invalid.");
01380 return;
01381 }
01382 return;
01383 }
01384
01385
01386
01387
01388
01389 static void interpret_drc_1_0(dar_drc* ref, dar_sup_exception* exception)
01390 {
01391 DEBUG("Function: interpret_drc_1_0: Interpreting drc version 1.0.\n");
01392
01393 xmlNodePtr root = xmlDocGetRootElement(ref->doc);
01394 xmlNodePtr ch = root->children;
01395 xmlNodePtr ch2 = NULL;
01396 xmlNodePtr ch3 = NULL;
01397 xmlNodePtr ch4 = NULL;
01398 xmlChar* xctmp = NULL;
01399
01400 DEBUG("Root node name: %s\n", root->name);
01401 DEBUG("First child node name: %s\n", ch->name);
01402
01403 DEBUG("Seeking Specification(1) element.\n");
01404
01405 if ( ch->type != XML_ELEMENT_NODE )
01406 {
01407 DEBUG("Finding next element node.\n");
01408 ch = get_next_element_node(ch);
01409 }
01410
01411 if ( ch == NULL || strcmp(ch->name, "Specification") != 0 )
01412 {
01413 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01414 "Input file invalid, could not find archive specification.");
01415 return;
01416 }
01417
01418 DEBUG("Found, translating specification element.\n");
01419
01420
01421 ch2 = ch->children;
01422 DEBUG("Seeking Filesystem(2) element.\n");
01423
01424 if ( ch2->type != XML_ELEMENT_NODE )
01425 {
01426 ch2 = get_next_element_node(ch2);
01427 }
01428
01429 if ( xmlHasProp(ch2, "Root") )
01430 {
01431 xctmp = xmlGetProp(ch2, "Root");
01432 ref->spec->root_path = allocate_copy_string(xctmp);
01433 if ( ref->spec->root_path == NULL )
01434 {
01435 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01436 "Memory exhausted, could not allocate copy of root path.");
01437 xmlFree(xctmp);
01438 return;
01439 }
01440 xmlFree(xctmp);
01441 }
01442
01443
01444 ch3 = ch2->children;
01445 DEBUG("Seeking Selection(3) element.\n");
01446
01447 if ( ch3 != NULL && ch3->type != XML_ELEMENT_NODE )
01448 {
01449 ch3 = get_next_element_node(ch3);
01450 }
01451
01452 if ( ch3 != NULL && strcmp(ch3->name, "Selection") == 0 )
01453 {
01454
01455 ch4 = ch3->children;
01456 DEBUG("Seeking Mask(4) element.\n");
01457
01458 if ( ch4->type != XML_ELEMENT_NODE )
01459 {
01460 ch4 = get_next_element_node(ch4);
01461 }
01462
01463 dar_mask* tmpmask =
01464 interpret_drc_1_0_recurse_mask(ch4, ref, exception);
01465
01466 if ( exception->type != LIBDAR_NOEXCEPT )
01467 {
01468 DEBUG("Exception caught, throwing.\n");
01469 return;
01470 }
01471
01472 ref->spec->selection = tmpmask;
01473
01474
01475 DEBUG("Seeking Subtree(3) element.\n");
01476 ch3 = get_next_element_node(ch3->next);
01477 }
01478
01479 if ( ch3 != NULL && strcmp(ch3->name, "Subtree") == 0 )
01480 {
01481
01482 DEBUG("Seeking Mask(4) element.\n");
01483 ch4 = ch3->children;
01484
01485
01486 if ( ch4->type != XML_ELEMENT_NODE )
01487 {
01488 ch4 = get_next_element_node(ch4);
01489 }
01490
01491 dar_mask* tmpmask =
01492 interpret_drc_1_0_recurse_mask(ch4, ref, exception);
01493
01494 if ( exception->type != LIBDAR_NOEXCEPT )
01495 {
01496 DEBUG("Exception caught, throwing.\n");
01497 return;
01498 }
01499
01500 ref->spec->subtree = tmpmask;
01501 }
01502
01503
01504 DEBUG("Seeking Archive(2) element.\n");
01505 ch2 = get_next_element_node(ch2->next);
01506
01507
01508 interpret_drc_1_0_archive(ch2, ref, exception);
01509
01510 if ( exception->type != LIBDAR_NOEXCEPT )
01511 {
01512 DEBUG("Exception caught, throwing.\n");
01513 return;
01514 }
01515
01516 DEBUG("Finding reference element, continuing if not found.\n");
01517
01518
01519 DEBUG("Seeking Reference(1) element.\n");
01520 ch = get_next_element_node(ch->next);
01521
01522
01523 if ( ch != NULL && strcmp(ch->name, "Reference") == 0 )
01524 {
01525 DEBUG("Reference element found, processing.\n");
01526
01527
01528
01529
01530
01531
01532
01533 ref->has_reference = true;
01534
01535 dar_drc temp_ref;
01536
01537 temp_ref.spec = ref->ref_spec;
01538 temp_ref.storage = ref->ref_storage;
01539 temp_ref.flags = ref->ref_flags;
01540
01541
01542 ch2 = ch->children;
01543 DEBUG("Seeking Archive(2) element.\n");
01544
01545 if ( ch2->type != XML_ELEMENT_NODE )
01546 {
01547 ch2 = get_next_element_node(ch2);
01548 }
01549
01550 interpret_drc_1_0_archive(ch2, &temp_ref, exception);
01551
01552 if ( exception->type != LIBDAR_NOEXCEPT )
01553 {
01554 DEBUG("Exception caught, throwing.\n");
01555 return;
01556 }
01557
01558
01559 DEBUG("Seeking Encryption(2) element.\n");
01560 ch2 = get_next_element_node(ch2->next);
01561
01562 if ( ch2 != NULL && strcmp(ch2->name, "Encryption") == 0 )
01563 {
01564 interpret_drc_1_0_encryption(ch2, &temp_ref, exception);
01565
01566 if ( exception->type != LIBDAR_NOEXCEPT )
01567 {
01568 DEBUG("Exception caught, throwing.\n");
01569 return;
01570 }
01571
01572
01573 DEBUG("Seeking Script(2) element.\n");
01574 ch2 = get_next_element_node(ch2->next);
01575 }
01576
01577 if ( ch2 != NULL && strcmp(ch2->name, "Script") == 0 )
01578 {
01579
01580 xctmp = xmlNodeGetContent(ch2);
01581 temp_ref.storage->slice_execute = allocate_copy_string(xctmp);
01582
01583 if ( temp_ref.storage->slice_execute == NULL && xctmp != NULL )
01584 {
01585 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01586 "Memory exhausted, could not allocate copy of inter-slice command.");
01587 xmlFree(xctmp);
01588 return;
01589 }
01590 xmlFree(xctmp);
01591 }
01592
01593
01594
01595
01596
01597
01598
01599 ch = get_next_element_node(ch->next);
01600 }
01601
01602 DEBUG("Finding storage element, continuing if not found.\n");
01603
01604
01605
01606 if ( ch != NULL && strcmp(ch->name, "Storage") == 0 )
01607 {
01608 DEBUG("Storage element found, processing.\n");
01609
01610
01611 ch2 = ch->children;
01612 DEBUG("Seeking Compression(2) element.\n");
01613
01614 if ( ch2->type != XML_ELEMENT_NODE )
01615 {
01616 ch2 = get_next_element_node(ch2);
01617 }
01618
01619 if ( ch2 != NULL && strcmp(ch2->name, "Compression") == 0 )
01620 {
01621 interpret_drc_1_0_compression(ch2, ref, exception);
01622
01623 if ( exception->type != LIBDAR_NOEXCEPT )
01624 {
01625 DEBUG("Exception caught, throwing.\n");
01626 return;
01627 }
01628
01629
01630 DEBUG("Seeking Encryption(2) element.\n");
01631 ch2 = get_next_element_node(ch2->next);
01632 }
01633
01634 if ( ch2 != NULL && strcmp(ch2->name, "Encryption") == 0 )
01635 {
01636 interpret_drc_1_0_encryption(ch2, ref, exception);
01637
01638 if ( exception->type != LIBDAR_NOEXCEPT )
01639 {
01640 DEBUG("Exception caught, throwing.\n");
01641 return;
01642 }
01643
01644
01645 DEBUG("Seeking SliceSize(2) element.\n");
01646 ch2 = get_next_element_node(ch2->next);
01647 }
01648
01649 if ( ch2 != NULL && strcmp(ch2->name, "SliceSize") == 0 )
01650 {
01651 interpret_drc_1_0_slice_size(ch2, ref, exception);
01652
01653 if ( exception->type != LIBDAR_NOEXCEPT )
01654 {
01655 DEBUG("Exception caught, throwing.\n");
01656 return;
01657 }
01658
01659
01660 DEBUG("Seeking Script(2) element.\n");
01661 ch2 = get_next_element_node(ch2->next);
01662 }
01663
01664 if ( ch2 != NULL && strcmp(ch2->name, "Script") == 0 )
01665 {
01666 xctmp = xmlNodeGetContent(ch2);
01667 ref->storage->slice_execute = allocate_copy_string(xctmp);
01668
01669 if ( ref->storage->slice_execute == NULL && xctmp != NULL )
01670 {
01671 LIBDARC_EXCEPTION(exception, LIBDAR_EMEMORY,
01672 "Memory exhausted, could not allocate copy of inter-slice command.");
01673 xmlFree(xctmp);
01674 return;
01675 }
01676 xmlFree(xctmp);
01677
01678
01679 DEBUG("Seeking Hourshift(2) element.\n");
01680 ch2 = get_next_element_node(ch2->next);
01681 }
01682
01683 if ( ch2 != NULL && strcmp(ch2->name, "Hourshift") == 0 )
01684 {
01685 xctmp = xmlNodeGetContent(ch2);
01686 ref->storage->hourshift = dar_infds(xctmp);
01687
01688 if ( ref->storage->hourshift == NULL )
01689 {
01690 LIBDARC_EXCEPTION(exception, LIBDAR_X_EINPUTSPEC,
01691 "Input file invalid, could not parse hourshift value.");
01692 xmlFree(xctmp);
01693 return;
01694 }
01695 xmlFree(xctmp);
01696 }
01697
01698
01699 ch = get_next_element_node(ch->next);
01700 }
01701
01702 DEBUG("Finding flags element, continuing if not found.\n");
01703
01704 if ( ch != NULL && strcmp(ch->name, "Flags") == 0 )
01705 {
01706 DEBUG("Flags element found, processing.\n");
01707
01708
01709 ch2 = ch->children;
01710
01711 if ( ch2->type != XML_ELEMENT_NODE )
01712 {
01713 ch2 = get_next_element_node(ch2);
01714 }
01715
01716 interpret_drc_1_0_recurse_flags(ch2, ref, exception);
01717
01718 if ( exception->type != LIBDAR_NOEXCEPT )
01719 {
01720 DEBUG("Exception caught, throwing.\n");
01721 return;
01722 }
01723
01724
01725 ch = get_next_element_node(ch->next);
01726 }
01727
01728 return;
01729 }
01730
01731
01732
01733
01734
01735
01736
01737 static char* bool_to_string( bool val )
01738 {
01739 DEBUG("Function: bool_to_string: Converting boolean to string.\n");
01740 char* ret;
01741 if (val)
01742 {
01743 ret = (char*)malloc(5);
01744 if (ret == NULL) { return NULL; }
01745 strcpy(ret, "true");
01746 } else {
01747 ret = (char*)malloc(6);
01748 if (ret == NULL) { return NULL; }
01749 strcpy(ret, "false");
01750 }
01751 return ret;
01752 }
01753
01754 static bool string_to_bool( char* str, bool* val )
01755 {
01756 DEBUG("Function: string_to_bool: Converting string to boolean.\n");
01757
01758 if (val == NULL)
01759 {
01760 DEBUG("Source error: Input parameter is null.\n");
01761 return false;
01762 }
01763
01764 if (str == NULL)
01765 {
01766 DEBUG("Argument error: No input string.\n");
01767 return false;
01768 }
01769
01770 if ( strcmp( str, "true" ) == 0 )
01771 {
01772 *val = true;
01773 return true;
01774 } else if ( strcmp( str, "false" ) == 0 )
01775 {
01776 *val = false;
01777 return true;
01778 } else {
01779 DEBUG("Argument error: Improper input data format.\n");
01780 return false;
01781 }
01782 }
01783
01784 static char* allocate_copy_string( const char* source )
01785 {
01786 DEBUG("Function: allocate_copy_string: Copying string into newly allocated space.\n");
01787 if (source == NULL) { return NULL; }
01788 char* ret = (char*)malloc(strlen(source) + 1);
01789 if (ret == NULL) { return NULL; }
01790 strcpy( ret, source );
01791 return ret;
01792 }
01793
01794
01795
01796 static char* get_dtd_location(const char* dtdfilepath, const char* version)
01797 {
01798 DEBUG("Function: get_dtd_location: Determining dtd file location.\n");
01799 const char* prefix = DRC_DTD_FILE_PREFIX;
01800 const char* path = DRC_DTD_FILE_LOCATION;
01801
01802 char* ret;
01803
01804 if ( dtdfilepath != NULL )
01805 {
01806 DEBUG("dtdfilepath = %s\n", dtdfilepath);
01807 ret = (char*)malloc(strlen(dtdfilepath));
01808 if (ret == NULL) { return NULL; }
01809 strcpy( ret, dtdfilepath );
01810 return ret;
01811 }
01812
01813 #if WIN32_PLATFORM
01814
01815 ret = (char*)malloc( strlen(prefix) + strlen(version) + 23 );
01816 if (ret == NULL) { return NULL; }
01817 *ret = 0;
01818 strcat(ret, "..\\share\\libdarc\\");
01819 strcat(ret, prefix);
01820 strcat(ret, "-");
01821 strcat(ret, version);
01822 strcat(ret, ".dtd");
01823 #else
01824
01825 ret = (char*)malloc( strlen(path) + strlen(prefix) + strlen(version) + 7 );
01826 if (ret == NULL) { return NULL; }
01827 *ret = 0;
01828 strcat(ret, path);
01829 strcat(ret, DIR_SEPARATOR_STR);
01830 strcat(ret, prefix);
01831 strcat(ret, "-");
01832 strcat(ret, version);
01833 strcat(ret, ".dtd");
01834 #endif
01835
01836 return ret;
01837 }
01838
01839
01840 static bool dar_drc_prep(dar_drc* ref)
01841 {
01842 DEBUG("Function: dar_drc_prep: Zeroing out drc context.\n");
01843
01844 ref->xml_buffer = NULL;
01845 ref->xml_filename = NULL;
01846 ref->dtd_filename = NULL;
01847 ref->doc = NULL;
01848
01849 ref->xml_buffer_size = 0;
01850
01851 ref->has_reference = false;
01852
01853 ref->spec = (dar_sup_spec*)malloc(sizeof(dar_sup_spec));
01854 ref->storage = (dar_sup_storage*)malloc(sizeof(dar_sup_storage));
01855 ref->flags = (dar_sup_flags*)malloc(sizeof(dar_sup_flags));
01856
01857 ref->ref_spec = (dar_sup_spec*)malloc(sizeof(dar_sup_spec));
01858 ref->ref_storage = (dar_sup_storage*)malloc(sizeof(dar_sup_storage));
01859 ref->ref_flags = (dar_sup_flags*)malloc(sizeof(dar_sup_flags));
01860
01861 if ( ref->spec == NULL ||
01862 ref->storage == NULL ||
01863 ref->flags == NULL ||
01864 ref->ref_spec == NULL ||
01865 ref->ref_storage == NULL ||
01866 ref->ref_flags == NULL )
01867 {
01868 DEBUG("Memory exhausted, allocation failed in dar_drc_prep.\n");
01869 if (ref->spec != NULL)
01870 free(ref->spec);
01871 if (ref->storage != NULL)
01872 free(ref->storage);
01873 if (ref->flags != NULL)
01874 free(ref->flags);
01875 if (ref->ref_spec != NULL)
01876 free(ref->ref_spec);
01877 if (ref->ref_storage != NULL)
01878 free(ref->ref_storage);
01879 if (ref->ref_flags != NULL);
01880 free(ref->ref_flags);
01881
01882 ref->spec = NULL;
01883 ref->storage = NULL;
01884 ref->flags = NULL;
01885 ref->ref_spec = NULL;
01886 ref->ref_storage = NULL;
01887 ref->ref_flags = NULL;
01888
01889 return false;
01890 }
01891
01892
01893
01894
01895 dar_sup_spec_defaults(ref->spec);
01896 dar_sup_storage_defaults(ref->storage);
01897 dar_sup_flags_defaults(ref->flags);
01898
01899 dar_sup_spec_defaults(ref->ref_spec);
01900 dar_sup_storage_defaults(ref->ref_storage);
01901 dar_sup_flags_defaults(ref->ref_flags);
01902 return true;
01903 }
01904
01905 static xmlNodePtr get_next_element_node(xmlNodePtr node)
01906 {
01907 DEBUG("Function: get_next_element_node: Scanning to next element node.\n");
01908 DEBUG("Node passed in: %s\n", node->name);
01909 xmlNodePtr n;
01910
01911 for (n = node; n; n = n->next)
01912 {
01913 DEBUG("Next node: %s\n", n->name);
01914 if (n->type == XML_ELEMENT_NODE)
01915 {
01916 DEBUG("Found element node.\n");
01917 return n;
01918 }
01919 }
01920 return NULL;
01921 }
01922
01923
01924