1 /* 2 * Copyright (c) 2007 Vreixo Formoso 3 * Copyright (c) 2009 - 2012 Thomas Schmitt 4 * 5 * This file is part of the libisofs project; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License version 2 7 * or later as published by the Free Software Foundation. 8 * See COPYING file for details. 9 */ 10 11 #ifndef LIBISO_UTIL_H_ 12 #define LIBISO_UTIL_H_ 13 14 #ifdef HAVE_STDINT_H 15 #include <stdint.h> 16 #else 17 #ifdef HAVE_INTTYPES_H 18 #include <inttypes.h> 19 #endif 20 #endif 21 22 #include <time.h> 23 24 #ifdef HAVE_STDLIB_H 25 #include <stdlib.h> 26 #endif 27 28 #include <fcntl.h> 29 30 #ifndef MAX 31 # define MAX(a, b) (((a) > (b)) ? (a) : (b)) 32 #endif 33 34 #ifndef MIN 35 # define MIN(a, b) (((a) < (b)) ? (a) : (b)) 36 #endif 37 38 #define DIV_UP(n,div) ((n + div - 1) / div) 39 #define ROUND_UP(n,mul) (DIV_UP(n, mul) * mul) 40 41 int int_pow(int base, int power); 42 43 /** 44 * Set up locale by LC_* environment variables. 45 */ 46 int iso_init_locale(int flag); 47 48 /** 49 * Convert the charset encoding of a given string. 50 * 51 * @param input 52 * Input string 53 * @param icharset 54 * Input charset. Must be supported by iconv 55 * @param ocharset 56 * Output charset. Must be supported by iconv 57 * @param output 58 * Location where the pointer to the output string will be stored 59 * @return 60 * 1 on success, < 0 on error 61 */ 62 int strconv(const char *input, const char *icharset, const char *ocharset, 63 char **output); 64 65 /* Like strconv but processing len input bytes rather than strlen(input) 66 */ 67 int strnconv(const char *str, const char *icharset, const char *ocharset, 68 size_t len, char **output); 69 70 /* Like strnconv but also returning the number of bytes in *output. 71 */ 72 int strnconvl(const char *str, const char *icharset, const char *ocharset, 73 size_t len, char **output, size_t *out_len); 74 75 /** 76 * Convert a given string from any input charset to ASCII 77 * 78 * @param icharset 79 * Input charset. Must be supported by iconv 80 * @param input 81 * Input string 82 * @param output 83 * Location where the pointer to the output string will be stored 84 * @return 85 * 1 on success, < 0 on error 86 */ 87 int str2ascii(const char *icharset, const char *input, char **output); 88 89 /** 90 * Convert a given string from any input charset to UCS-2BE charset, 91 * used for Joliet file identifiers. 92 * 93 * @param icharset 94 * Input charset. Must be supported by iconv 95 * @param input 96 * Input string 97 * @param output 98 * Location where the pointer to the output string will be stored 99 * @return 100 * 1 on success, < 0 on error 101 */ 102 int str2ucs(const char *icharset, const char *input, uint16_t **output); 103 104 /** 105 * Convert a given string from any input charset to UTF-16BE charset, 106 * used for HFS+ file identifiers. 107 * (UTF-16 differs from older UCS-2 by having multi word characters.) 108 * 109 * @param icharset 110 * Input charset. Must be supported by iconv 111 * @param input 112 * Input string 113 * @param output 114 * Location where the pointer to the output string will be stored 115 * @return 116 * 1 on success, < 0 on error 117 */ 118 int str2utf16be(const char *icharset, const char *input, uint16_t **output); 119 120 /** 121 * Create a level 1 directory identifier. 122 * 123 * @param src 124 * The identifier, in ASCII encoding. 125 * @param relaxed 126 * 0 only allow d-characters, 1 allow also lowe case chars, 127 * 2 allow all characters 128 */ 129 char *iso_1_dirid(const char *src, int relaxed); 130 131 /** 132 * Create a level 2 directory identifier. 133 * 134 * @param src 135 * The identifier, in ASCII encoding. 136 */ 137 char *iso_2_dirid(const char *src); 138 139 /** 140 * Create a dir name suitable for an ISO image with relaxed constraints. 141 * 142 * @param src 143 * The identifier, in ASCII encoding. 144 * @param size 145 * Max len for the name 146 * @param relaxed 147 * 0 only allow d-characters, 1 allow also lowe case chars, 148 * 2 allow all characters 149 */ 150 char *iso_r_dirid(const char *src, int size, int relaxed); 151 152 /** 153 * Create a level 1 file identifier that consists of a name, in 8.3 154 * format. 155 * Note that version number is not added to the file name 156 * 157 * @param src 158 * The identifier, in ASCII encoding. 159 * @param relaxed 160 * 0 only allow d-characters, 1 allow also lowe case chars, 161 * 2 allow all characters 162 * @param force_dots 163 * If 1 then prepend empty extension by SEPARATOR1 = '.' 164 */ 165 char *iso_1_fileid(const char *src, int relaxed, int force_dots); 166 167 /** 168 * Create a level 2 file identifier. 169 * Note that version number is not added to the file name 170 * 171 * @param src 172 * The identifier, in ASCII encoding. 173 */ 174 char *iso_2_fileid(const char *src); 175 176 /** 177 * Create a file name suitable for an ISO image with relaxed constraints. 178 * 179 * @param src 180 * The identifier, in ASCII encoding. 181 * @param len 182 * Max len for the name, without taken the "." into account. 183 * @param relaxed 184 * 0 only allow d-characters, 1 allow also lowe case chars, 185 * 2 allow all characters 186 * @param forcedot 187 * Whether to ensure that "." is added 188 */ 189 char *iso_r_fileid(const char *src, size_t len, int relaxed, int forcedot); 190 191 /** 192 * Create a Joliet file identifier that consists of name and extension. The 193 * combined name and extension length will normally not exceed 64 characters 194 * (= 128 bytes). The name and the extension will be separated (.). 195 * All characters consist of 2 bytes and the resulting string is 196 * NULL-terminated by a 2-byte NULL. 197 * 198 * Note that version number and (;1) is not appended. 199 * @param flag 200 * bit0= no_force_dots 201 * bit1= allow 103 characters rather than 64 202 * @return 203 * NULL if the original name and extension both are of length 0. 204 */ 205 uint16_t *iso_j_file_id(const uint16_t *src, int flag); 206 207 /** 208 * Create a Joliet directory identifier that consists of name and optionally 209 * extension. The combined name and extension length will not exceed 128 bytes, 210 * and the name and extension will be separated (.). All characters consist of 211 * 2 bytes and the resulting string is NULL-terminated by a 2-byte NULL. 212 * 213 * @param flag 214 * bit1= allow 103 characters rather than 64 215 * @return 216 * NULL if the original name and extension both are of length 0. 217 */ 218 uint16_t *iso_j_dir_id(const uint16_t *src, int flag); 219 220 /** 221 * Like strlen, but for Joliet strings. 222 */ 223 size_t ucslen(const uint16_t *str); 224 225 /** 226 * Like strrchr, but for Joliet strings. 227 */ 228 uint16_t *ucsrchr(const uint16_t *str, char c); 229 230 /** 231 * Like strdup, but for Joliet strings. 232 */ 233 uint16_t *ucsdup(const uint16_t *str); 234 235 /** 236 * Like strcmp, but for Joliet strings. 237 */ 238 int ucscmp(const uint16_t *s1, const uint16_t *s2); 239 240 /** 241 * Like strcpy, but for Joliet strings. 242 */ 243 uint16_t *ucscpy(uint16_t *dest, const uint16_t *src); 244 245 /** 246 * Like strncpy, but for Joliet strings. 247 * @param n 248 * Maximum number of characters to copy (2 bytes per char). 249 */ 250 uint16_t *ucsncpy(uint16_t *dest, const uint16_t *src, size_t n); 251 252 /** 253 * Check whether utf_word is the first surrogate word of a pair. 254 * If so, change it to UTF-16 character '_'. 255 */ 256 void iso_handle_split_utf16(uint16_t *utf_word); 257 258 /** 259 * Convert a given input string to d-chars. 260 * @return 261 * 1 on success, < 0 error, 0 if input was null (output is set to null) 262 */ 263 int str2d_char(const char *icharset, const char *input, char **output); 264 int str2a_char(const char *icharset, const char *input, char **output); 265 266 void iso_lsb(uint8_t *buf, uint32_t num, int bytes); 267 void iso_lsb64(uint8_t *buf, uint64_t num); 268 void iso_msb(uint8_t *buf, uint32_t num, int bytes); 269 void iso_bb(uint8_t *buf, uint32_t num, int bytes); 270 271 /* An alternative to iso_lsb() which advances the write pointer 272 */ 273 int iso_lsb_to_buf(char **wpt, uint32_t value, int bytes, int flag); 274 275 uint32_t iso_read_lsb(const uint8_t *buf, int bytes); 276 uint32_t iso_read_msb(const uint8_t *buf, int bytes); 277 278 /** 279 * if error != NULL it will be set to 1 if LSB and MSB integers don't match. 280 */ 281 uint32_t iso_read_bb(const uint8_t *buf, int bytes, int *error); 282 283 uint64_t iso_read_lsb64(const uint8_t *buf); 284 uint64_t iso_read_msb64(const uint8_t *buf); 285 286 /** 287 * Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5) 288 * 289 * @param buf 290 * Buffer where the date will be written 291 * @param t 292 * The time to be written 293 * @param always_gmt 294 * Always write the date in GMT and not in local time. 295 */ 296 void iso_datetime_7(uint8_t *buf, time_t t, int always_gmt); 297 298 /** Records the date/time into a 17 byte buffer (ECMA-119, 8.4.26.1) */ 299 void iso_datetime_17(uint8_t *buf, time_t t, int always_gmt); 300 301 time_t iso_datetime_read_7(const uint8_t *buf); 302 time_t iso_datetime_read_17(const uint8_t *buf); 303 304 /** 305 * Check whether the caller process has read access to the given local file. 306 * 307 * @return 308 * 1 on success (i.e, the process has read access), < 0 on error 309 * (including ISO_FILE_ACCESS_DENIED on access denied to the specified file 310 * or any directory on the path). 311 */ 312 int iso_eaccess(const char *path); 313 314 /** 315 * Copy up to \p len chars from \p buf and return this newly allocated 316 * string. The new string is null-terminated. 317 */ 318 char *iso_util_strcopy(const char *buf, size_t len); 319 320 /** 321 * Copy up to \p len chars from \p buf and return this newly allocated 322 * string. The new string is null-terminated. 323 * Any trailing blanks will be removed. 324 */ 325 char *iso_util_strcopy_untail(const char *buf, size_t len); 326 327 /** 328 * Copy up to \p max characters from \p src to \p dest. If \p src has less than 329 * \p max characters, we pad dest with " " characters. 330 */ 331 void strncpy_pad(char *dest, const char *src, size_t max); 332 333 /** 334 * Convert a Joliet string with a length of \p len bytes to a new string 335 * in local charset. 336 */ 337 char *ucs2str(const char *buf, size_t len); 338 339 typedef struct iso_rbtree IsoRBTree; 340 typedef struct iso_htable IsoHTable; 341 342 typedef unsigned int (*hash_funtion_t)(const void *key); 343 typedef int (*compare_function_t)(const void *a, const void *b); 344 typedef void (*hfree_data_t)(void *key, void *data); 345 346 /** 347 * Create a new binary tree. libisofs binary trees allow you to add any data 348 * passing it as a pointer. You must provide a function suitable for compare 349 * two elements. 350 * 351 * @param compare 352 * A function to compare two keys. It takes a pointer to both keys 353 * and return 0, -1 or 1 if the first key is equal, less or greater 354 * than the second one. 355 * @param tree 356 * Location where the tree structure will be stored. 357 */ 358 int iso_rbtree_new(int (*compare)(const void*, const void*), IsoRBTree **tree); 359 360 /** 361 * Destroy a given tree. 362 * 363 * Note that only the structure itself is deleted. To delete the elements, you 364 * should provide a valid free_data function. It will be called for each 365 * element of the tree, so you can use it to free any related data. 366 */ 367 void iso_rbtree_destroy(IsoRBTree *tree, void (*free_data)(void *)); 368 369 /** 370 * Inserts a given element in a Red-Black tree. 371 * 372 * @param tree 373 * the tree where to insert 374 * @param data 375 * element to be inserted on the tree. It can't be NULL 376 * @param item 377 * if not NULL, it will point to a location where the tree element ptr 378 * will be stored. If data was inserted, *item == data. If data was 379 * already on the tree, *item points to the previously inserted object 380 * that is equal to data. 381 * @return 382 * 1 success, 0 element already inserted, < 0 error 383 */ 384 int iso_rbtree_insert(IsoRBTree *tree, void *data, void **item); 385 386 /** 387 * Get the number of elements in a given tree. 388 */ 389 size_t iso_rbtree_get_size(IsoRBTree *tree); 390 391 /** 392 * Get an array view of the elements of the tree. 393 * 394 * @param include_item 395 * Function to select which elements to include in the array. It that takes 396 * a pointer to an element and returns 1 if the element should be included, 397 * 0 if not. If you want to add all elements to the array, you can pass a 398 * NULL pointer. 399 * @param size 400 * If not null, will be filled with the number of elements in the array, 401 * without counting the final NULL item. 402 * @return 403 * A sorted array with the contents of the tree, or NULL if there is not 404 * enough memory to allocate the array. You should free(3) the array when 405 * no more needed. Note that the array is NULL-terminated, and thus it 406 * has size + 1 length. 407 */ 408 void **iso_rbtree_to_array(IsoRBTree *tree, int (*include_item)(void *), 409 size_t *size); 410 411 /** Predict the size of the array which gets returned by iso_rbtree_to_array(). 412 */ 413 size_t iso_rbtree_count_array(IsoRBTree *tree, size_t initial_count, 414 int (*include_item)(void *)); 415 416 417 /** 418 * Create a new hash table. 419 * 420 * @param size 421 * Number of slots in table. 422 * @param hash 423 * Function used to generate 424 */ 425 int iso_htable_create(size_t size, hash_funtion_t hash, 426 compare_function_t compare, IsoHTable **table); 427 428 /** 429 * Put an element in a Hash Table. The element will be identified by 430 * the given key, that you should use to retrieve the element again. 431 * 432 * This function allow duplicates, i.e., two items with the same key. In those 433 * cases, the value returned by iso_htable_get() is undefined. If you don't 434 * want to allow duplicates, use iso_htable_put() instead; 435 * 436 * Both the key and data pointers will be stored internally, so you should 437 * free the objects they point to. Use iso_htable_remove() to delete an 438 * element from the table. 439 */ 440 int iso_htable_add(IsoHTable *table, void *key, void *data); 441 442 /** 443 * Like iso_htable_add(), but this doesn't allow dulpicates. 444 * 445 * @return 446 * 1 success, 0 if an item with the same key already exists, < 0 error 447 */ 448 int iso_htable_put(IsoHTable *table, void *key, void *data); 449 450 /** 451 * Retrieve an element from the given table. 452 * 453 * @param table 454 * Hash table 455 * @param key 456 * Key of the element that will be removed 457 * @param data 458 * Will be filled with the element found. Remains untouched if no 459 * element with the given key is found. 460 * @return 461 * 1 if found, 0 if not, < 0 on error 462 */ 463 int iso_htable_get(IsoHTable *table, void *key, void **data); 464 465 /** 466 * Remove an item with the given key from the table. In tables that allow 467 * duplicates, it is undefined the element that will be deleted. 468 * 469 * @param table 470 * Hash table 471 * @param key 472 * Key of the element that will be removed 473 * @param free_data 474 * Function that will be called passing as parameters both the key and 475 * the element that will be deleted. The user can use it to free the 476 * element. You can pass NULL if you don't want to delete the item itself. 477 * @return 478 * 1 success, 0 no element exists with the given key, < 0 error 479 */ 480 int iso_htable_remove(IsoHTable *table, void *key, hfree_data_t free_data); 481 482 /** 483 * Like remove, but instead of checking for key equality using the compare 484 * function, it just compare the key pointers. If the table allows duplicates, 485 * and you provide different keys (i.e. different pointers) to elements 486 * with same key (i.e. same content), this function ensure the exact element 487 * is removed. 488 * 489 * It has the problem that you must provide the same key pointer, and not just 490 * a key whose contents are equal. Moreover, if you use the same key (same 491 * pointer) to identify several objects, what of those are removed is 492 * undefined. 493 * 494 * @param table 495 * Hash table 496 * @param key 497 * Key of the element that will be removed 498 * @param free_data 499 * Function that will be called passing as parameters both the key and 500 * the element that will be deleted. The user can use it to free the 501 * element. You can pass NULL if you don't want to delete the item itself. 502 * @return 503 * 1 success, 0 no element exists with the given key, < 0 error 504 */ 505 int iso_htable_remove_ptr(IsoHTable *table, void *key, hfree_data_t free_data); 506 507 /** 508 * Destroy the given hash table. 509 * 510 * Note that you're responsible to actually destroy the elements by providing 511 * a valid free_data function. You can pass NULL if you only want to delete 512 * the hash structure. 513 */ 514 void iso_htable_destroy(IsoHTable *table, hfree_data_t free_data); 515 516 /** 517 * Hash function suitable for keys that are char strings. 518 */ 519 unsigned int iso_str_hash(const void *key); 520 521 /** 522 * Encode an integer as LEN,BYTES for being a component in certain AAIP 523 * attribute values. 524 */ 525 int iso_util_encode_len_bytes(uint32_t data, char *buffer, int data_len, 526 int *result_len, int flag); 527 528 /** 529 * Decode an integer as LEN,BYTES for being a component in certain AAIP 530 * attribute values. 531 * @param data returns the decoded value 532 * @param buffer contains the encoded value 533 * @param data_len returns the number of value bytes (without len byte) 534 * @param buffer_len tells the number of valid buffer bytes 535 */ 536 int iso_util_decode_len_bytes(uint32_t *data, char *buffer, int *data_len, 537 int buffer_len, int flag); 538 539 540 /* Evaluate a data block whether it is a libisofs session checksum tag of 541 desired type and eventually use it to verify the MD5 checksum computed 542 so far. 543 @param block The data block to be evaluated 544 @param desired Bit map which tells what tag types are expected 545 (0 to 30) 546 @param lba The address from where block was read 547 @param ctx The checksum context computed so far 548 @param ctx_start_lba The block address where checksum computing started 549 @param tag_type Returns the tag type (0 means invalid tag type) 550 @param flag Bitfield for control purposes, unused yet, submit 0 551 @return 1= tag is desired and matches 552 0= not a recognizable tag or a undesired tag 553 <0 is error or mismatch 554 */ 555 int iso_util_eval_md5_tag(char *block, int desired, uint32_t lba, 556 void *ctx, uint32_t ctx_start_lba, 557 int *tag_type, uint32_t *next_tag, int flag); 558 559 560 int iso_util_tag_magic(int tag_type, char **tag_magic, int *len, int flag); 561 562 563 int iso_util_bin_to_hex(char *target, uint8_t *bytes, int num_bytes, int flag); 564 565 int iso_util_hex_to_bin(char *hex, char *bin, int bin_size, int *bin_count, 566 int flag); 567 568 int iso_truncate_rr_name(int truncate_mode, int truncate_length, 569 char *name, int flag); 570 571 /* ------------------------------------------------------------------------- */ 572 573 /* In md5.h these function prototypes would be neighbors of (Ecma119Image *) 574 which needs inclusion of ecma119.h and more. So, being generic, they ended 575 up here. 576 */ 577 578 /* Function to identify and manage md5sum indice of the old image. 579 * data is supposed to be a 4 byte integer, bit 31 shall be 0, 580 * value 0 of this integer means that it is not a valid index. 581 */ 582 int checksum_cx_xinfo_func(void *data, int flag); 583 584 /* The iso_node_xinfo_cloner function which gets associated to 585 * checksum_cx_xinfo_func by iso_init() resp. iso_init_with_flag() via 586 * iso_node_xinfo_make_clonable() 587 */ 588 int checksum_cx_xinfo_cloner(void *old_data, void **new_data, int flag); 589 590 591 /* Function to identify and manage md5 sums of unspecified providence stored 592 * directly in this xinfo. This is supposed to override any other recorded 593 * MD5 of the node unless data get copied and checksummed during that copying. 594 */ 595 int checksum_md5_xinfo_func(void *data, int flag); 596 597 /* The iso_node_xinfo_cloner function which gets associated to 598 * checksum_md5_xinfo_func by iso_init() resp. iso_init_with_flag() via 599 * iso_node_xinfo_make_clonable() 600 */ 601 int checksum_md5_xinfo_cloner(void *old_data, void **new_data, int flag); 602 603 /* The iso_node_xinfo_cloner function which gets associated to 604 * iso_hfsplus_xinfo_func by iso_init() resp. iso_init_with_flag() via 605 * iso_node_xinfo_make_clonable() 606 */ 607 int iso_hfsplus_xinfo_cloner(void *old_data, void **new_data, int flag); 608 609 610 /* ------------------------------------------------------------------------- */ 611 612 613 void *iso_alloc_mem(size_t size, size_t count, int flag); 614 615 #define LIBISO_ALLOC_MEM(pt, typ, count) { \ 616 pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \ 617 if(pt == NULL) { \ 618 ret= ISO_OUT_OF_MEM; goto ex; \ 619 } } 620 621 #define LIBISO_ALLOC_MEM_VOID(pt, typ, count) { \ 622 pt= (typ *) iso_alloc_mem(sizeof(typ), (size_t) (count), 0); \ 623 if(pt == NULL) { \ 624 goto ex; \ 625 } } 626 627 #define LIBISO_FREE_MEM(pt) { \ 628 if(pt != NULL) \ 629 free((char *) pt); \ 630 } 631 632 633 /* 634 @param in Valid memory or NULL 635 @param out Returns valid memory or NULL 636 @param size Number of bytes to copy. 0 means strlen(in)+1 if not NULL. 637 @return 1 or ISO_OUT_OF_MEM 638 */ 639 int iso_clone_mem(char *in, char **out, size_t size); 640 641 /* Like iso_clone_mem but first freeing *out if not NULL 642 */ 643 int iso_clone_mgtd_mem(char *in, char **out, size_t size); 644 645 /** Convert a text into a number of type double and multiply it by unit code 646 [kmgt] (2^10 to 2^40) or [s] (2048) or [d] (512). 647 (Also accepts capital letters.) 648 @param text Input like "42", "223062s", "3m" or "-1g" 649 @param flag Bitfield for control purposes: 650 bit0= return -1 rather than 0 on failure 651 bit1= if scaled then compute the last byte of the last unit 652 @return The derived value 653 */ 654 off_t iso_scanf_io_size(char *text, int flag); 655 656 /* ------------------------------------------------------------------------- */ 657 658 659 /* To avoid the need to include more system header files */ 660 uint16_t iso_ntohs(uint16_t v); 661 uint16_t iso_htons(uint16_t v); 662 663 664 #endif /*LIBISO_UTIL_H_*/ 665