1 /***************************************************************************/ 2 /* */ 3 /* ftrfork.c */ 4 /* */ 5 /* Embedded resource forks accessor (body). */ 6 /* */ 7 /* Copyright 2004, 2005, 2006, 2007, 2008, 2009 by */ 8 /* Masatake YAMATO and Redhat K.K. */ 9 /* */ 10 /* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ 11 /* derived from ftobjs.c. */ 12 /* */ 13 /* This file is part of the FreeType project, and may only be used, */ 14 /* modified, and distributed under the terms of the FreeType project */ 15 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 16 /* this file you indicate that you have read the license and */ 17 /* understand and accept it fully. */ 18 /* */ 19 /***************************************************************************/ 20 21 /***************************************************************************/ 22 /* Development of the code in this file is support of */ 23 /* Information-technology Promotion Agency, Japan. */ 24 /***************************************************************************/ 25 26 27 #include <ft2build.h> 28 #include FT_INTERNAL_DEBUG_H 29 #include FT_INTERNAL_STREAM_H 30 #include FT_INTERNAL_RFORK_H 31 32 33 #undef FT_COMPONENT 34 #define FT_COMPONENT trace_raccess 35 36 37 /*************************************************************************/ 38 /*************************************************************************/ 39 /*************************************************************************/ 40 /**** ****/ 41 /**** ****/ 42 /**** Resource fork directory access ****/ 43 /**** ****/ 44 /**** ****/ 45 /*************************************************************************/ 46 /*************************************************************************/ 47 /*************************************************************************/ 48 49 FT_BASE_DEF( FT_Error ) FT_Raccess_Get_HeaderInfo(FT_Library library,FT_Stream stream,FT_Long rfork_offset,FT_Long * map_offset,FT_Long * rdata_pos)50 FT_Raccess_Get_HeaderInfo( FT_Library library, 51 FT_Stream stream, 52 FT_Long rfork_offset, 53 FT_Long *map_offset, 54 FT_Long *rdata_pos ) 55 { 56 FT_Error error; 57 unsigned char head[16], head2[16]; 58 FT_Long map_pos, rdata_len; 59 int allzeros, allmatch, i; 60 FT_Long type_list; 61 62 FT_UNUSED( library ); 63 64 65 error = FT_Stream_Seek( stream, rfork_offset ); 66 if ( error ) 67 return error; 68 69 error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); 70 if ( error ) 71 return error; 72 73 *rdata_pos = rfork_offset + ( ( head[0] << 24 ) | 74 ( head[1] << 16 ) | 75 ( head[2] << 8 ) | 76 head[3] ); 77 map_pos = rfork_offset + ( ( head[4] << 24 ) | 78 ( head[5] << 16 ) | 79 ( head[6] << 8 ) | 80 head[7] ); 81 rdata_len = ( head[ 8] << 24 ) | 82 ( head[ 9] << 16 ) | 83 ( head[10] << 8 ) | 84 head[11]; 85 86 /* map_len = head[12] .. head[15] */ 87 88 if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset ) 89 return FT_Err_Unknown_File_Format; 90 91 error = FT_Stream_Seek( stream, map_pos ); 92 if ( error ) 93 return error; 94 95 head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ 96 97 error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); 98 if ( error ) 99 return error; 100 101 allzeros = 1; 102 allmatch = 1; 103 for ( i = 0; i < 16; ++i ) 104 { 105 if ( head2[i] != 0 ) 106 allzeros = 0; 107 if ( head2[i] != head[i] ) 108 allmatch = 0; 109 } 110 if ( !allzeros && !allmatch ) 111 return FT_Err_Unknown_File_Format; 112 113 /* If we have reached this point then it is probably a mac resource */ 114 /* file. Now, does it contain any interesting resources? */ 115 /* Skip handle to next resource map, the file resource number, and */ 116 /* attributes. */ 117 (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ 118 + 2 /* skip file resource number */ 119 + 2 ); /* skip attributes */ 120 121 if ( FT_READ_USHORT( type_list ) ) 122 return error; 123 if ( type_list == -1 ) 124 return FT_Err_Unknown_File_Format; 125 126 error = FT_Stream_Seek( stream, map_pos + type_list ); 127 if ( error ) 128 return error; 129 130 *map_offset = map_pos + type_list; 131 return FT_Err_Ok; 132 } 133 134 135 static int ft_raccess_sort_ref_by_id(FT_RFork_Ref * a,FT_RFork_Ref * b)136 ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, 137 FT_RFork_Ref* b ) 138 { 139 if ( a->res_id < b->res_id ) 140 return -1; 141 else if ( a->res_id > b->res_id ) 142 return 1; 143 else 144 return 0; 145 } 146 147 148 FT_BASE_DEF( FT_Error ) FT_Raccess_Get_DataOffsets(FT_Library library,FT_Stream stream,FT_Long map_offset,FT_Long rdata_pos,FT_Long tag,FT_Long ** offsets,FT_Long * count)149 FT_Raccess_Get_DataOffsets( FT_Library library, 150 FT_Stream stream, 151 FT_Long map_offset, 152 FT_Long rdata_pos, 153 FT_Long tag, 154 FT_Long **offsets, 155 FT_Long *count ) 156 { 157 FT_Error error; 158 int i, j, cnt, subcnt; 159 FT_Long tag_internal, rpos; 160 FT_Memory memory = library->memory; 161 FT_Long temp; 162 FT_Long *offsets_internal; 163 FT_RFork_Ref *ref; 164 165 166 error = FT_Stream_Seek( stream, map_offset ); 167 if ( error ) 168 return error; 169 170 if ( FT_READ_USHORT( cnt ) ) 171 return error; 172 cnt++; 173 174 for ( i = 0; i < cnt; ++i ) 175 { 176 if ( FT_READ_LONG( tag_internal ) || 177 FT_READ_USHORT( subcnt ) || 178 FT_READ_USHORT( rpos ) ) 179 return error; 180 181 FT_TRACE2(( "Resource tags: %c%c%c%c\n", 182 (char)( 0xff & ( tag_internal >> 24 ) ), 183 (char)( 0xff & ( tag_internal >> 16 ) ), 184 (char)( 0xff & ( tag_internal >> 8 ) ), 185 (char)( 0xff & ( tag_internal >> 0 ) ) )); 186 187 if ( tag_internal == tag ) 188 { 189 *count = subcnt + 1; 190 rpos += map_offset; 191 192 error = FT_Stream_Seek( stream, rpos ); 193 if ( error ) 194 return error; 195 196 if ( FT_NEW_ARRAY( ref, *count ) ) 197 return error; 198 199 for ( j = 0; j < *count; ++j ) 200 { 201 if ( FT_READ_USHORT( ref[j].res_id ) ) 202 goto Exit; 203 if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ 204 goto Exit; 205 if ( FT_READ_LONG( temp ) ) 206 goto Exit; 207 if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ 208 goto Exit; 209 210 ref[j].offset = temp & 0xFFFFFFL; 211 } 212 213 ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ), 214 ( int(*)(const void*, const void*) ) 215 ft_raccess_sort_ref_by_id ); 216 217 if ( FT_NEW_ARRAY( offsets_internal, *count ) ) 218 goto Exit; 219 220 /* XXX: duplicated reference ID, 221 * gap between reference IDs are acceptable? 222 * further investigation on Apple implementation is needed. 223 */ 224 for ( j = 0; j < *count; ++j ) 225 offsets_internal[j] = rdata_pos + ref[j].offset; 226 227 *offsets = offsets_internal; 228 error = FT_Err_Ok; 229 230 Exit: 231 FT_FREE( ref ); 232 return error; 233 } 234 } 235 236 return FT_Err_Cannot_Open_Resource; 237 } 238 239 240 #ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK 241 242 /*************************************************************************/ 243 /*************************************************************************/ 244 /*************************************************************************/ 245 /**** ****/ 246 /**** ****/ 247 /**** Guessing functions ****/ 248 /**** ****/ 249 /**** When you add a new guessing function, ****/ 250 /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/ 251 /**** ****/ 252 /*************************************************************************/ 253 /*************************************************************************/ 254 /*************************************************************************/ 255 256 typedef FT_Error 257 (*raccess_guess_func)( FT_Library library, 258 FT_Stream stream, 259 char *base_file_name, 260 char **result_file_name, 261 FT_Long *result_offset ); 262 263 264 static FT_Error 265 raccess_guess_apple_double( FT_Library library, 266 FT_Stream stream, 267 char *base_file_name, 268 char **result_file_name, 269 FT_Long *result_offset ); 270 271 static FT_Error 272 raccess_guess_apple_single( FT_Library library, 273 FT_Stream stream, 274 char *base_file_name, 275 char **result_file_name, 276 FT_Long *result_offset ); 277 278 static FT_Error 279 raccess_guess_darwin_ufs_export( FT_Library library, 280 FT_Stream stream, 281 char *base_file_name, 282 char **result_file_name, 283 FT_Long *result_offset ); 284 285 static FT_Error 286 raccess_guess_darwin_newvfs( FT_Library library, 287 FT_Stream stream, 288 char *base_file_name, 289 char **result_file_name, 290 FT_Long *result_offset ); 291 292 static FT_Error 293 raccess_guess_darwin_hfsplus( FT_Library library, 294 FT_Stream stream, 295 char *base_file_name, 296 char **result_file_name, 297 FT_Long *result_offset ); 298 299 static FT_Error 300 raccess_guess_vfat( FT_Library library, 301 FT_Stream stream, 302 char *base_file_name, 303 char **result_file_name, 304 FT_Long *result_offset ); 305 306 static FT_Error 307 raccess_guess_linux_cap( FT_Library library, 308 FT_Stream stream, 309 char *base_file_name, 310 char **result_file_name, 311 FT_Long *result_offset ); 312 313 static FT_Error 314 raccess_guess_linux_double( FT_Library library, 315 FT_Stream stream, 316 char *base_file_name, 317 char **result_file_name, 318 FT_Long *result_offset ); 319 320 static FT_Error 321 raccess_guess_linux_netatalk( FT_Library library, 322 FT_Stream stream, 323 char *base_file_name, 324 char **result_file_name, 325 FT_Long *result_offset ); 326 327 328 /*************************************************************************/ 329 /**** ****/ 330 /**** Helper functions ****/ 331 /**** ****/ 332 /*************************************************************************/ 333 334 static FT_Error 335 raccess_guess_apple_generic( FT_Library library, 336 FT_Stream stream, 337 char *base_file_name, 338 FT_Int32 magic, 339 FT_Long *result_offset ); 340 341 static FT_Error 342 raccess_guess_linux_double_from_file_name( FT_Library library, 343 char * file_name, 344 FT_Long *result_offset ); 345 346 static char * 347 raccess_make_file_name( FT_Memory memory, 348 const char *original_name, 349 const char *insertion ); 350 351 352 FT_BASE_DEF( void ) FT_Raccess_Guess(FT_Library library,FT_Stream stream,char * base_name,char ** new_names,FT_Long * offsets,FT_Error * errors)353 FT_Raccess_Guess( FT_Library library, 354 FT_Stream stream, 355 char* base_name, 356 char **new_names, 357 FT_Long *offsets, 358 FT_Error *errors ) 359 { 360 FT_Long i; 361 362 363 raccess_guess_func funcs[FT_RACCESS_N_RULES] = 364 { 365 raccess_guess_apple_double, 366 raccess_guess_apple_single, 367 raccess_guess_darwin_ufs_export, 368 raccess_guess_darwin_newvfs, 369 raccess_guess_darwin_hfsplus, 370 raccess_guess_vfat, 371 raccess_guess_linux_cap, 372 raccess_guess_linux_double, 373 raccess_guess_linux_netatalk, 374 }; 375 376 for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) 377 { 378 new_names[i] = NULL; 379 if ( NULL != stream ) 380 errors[i] = FT_Stream_Seek( stream, 0 ); 381 else 382 errors[i] = FT_Err_Ok; 383 384 if ( errors[i] ) 385 continue ; 386 387 errors[i] = (funcs[i])( library, stream, base_name, 388 &(new_names[i]), &(offsets[i]) ); 389 } 390 391 return; 392 } 393 394 395 static FT_Error raccess_guess_apple_double(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)396 raccess_guess_apple_double( FT_Library library, 397 FT_Stream stream, 398 char *base_file_name, 399 char **result_file_name, 400 FT_Long *result_offset ) 401 { 402 FT_Int32 magic = ( 0x00 << 24 ) | 403 ( 0x05 << 16 ) | 404 ( 0x16 << 8 ) | 405 0x07; 406 407 408 *result_file_name = NULL; 409 if ( NULL == stream ) 410 return FT_Err_Cannot_Open_Stream; 411 412 return raccess_guess_apple_generic( library, stream, base_file_name, 413 magic, result_offset ); 414 } 415 416 417 static FT_Error raccess_guess_apple_single(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)418 raccess_guess_apple_single( FT_Library library, 419 FT_Stream stream, 420 char *base_file_name, 421 char **result_file_name, 422 FT_Long *result_offset ) 423 { 424 FT_Int32 magic = ( 0x00 << 24 ) | 425 ( 0x05 << 16 ) | 426 ( 0x16 << 8 ) | 427 0x00; 428 429 430 *result_file_name = NULL; 431 if ( NULL == stream ) 432 return FT_Err_Cannot_Open_Stream; 433 434 return raccess_guess_apple_generic( library, stream, base_file_name, 435 magic, result_offset ); 436 } 437 438 439 static FT_Error raccess_guess_darwin_ufs_export(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)440 raccess_guess_darwin_ufs_export( FT_Library library, 441 FT_Stream stream, 442 char *base_file_name, 443 char **result_file_name, 444 FT_Long *result_offset ) 445 { 446 char* newpath; 447 FT_Error error; 448 FT_Memory memory; 449 450 FT_UNUSED( stream ); 451 452 453 memory = library->memory; 454 newpath = raccess_make_file_name( memory, base_file_name, "._" ); 455 if ( !newpath ) 456 return FT_Err_Out_Of_Memory; 457 458 error = raccess_guess_linux_double_from_file_name( library, newpath, 459 result_offset ); 460 if ( !error ) 461 *result_file_name = newpath; 462 else 463 FT_FREE( newpath ); 464 465 return error; 466 } 467 468 469 static FT_Error raccess_guess_darwin_hfsplus(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)470 raccess_guess_darwin_hfsplus( FT_Library library, 471 FT_Stream stream, 472 char *base_file_name, 473 char **result_file_name, 474 FT_Long *result_offset ) 475 { 476 /* 477 Only meaningful on systems with hfs+ drivers (or Macs). 478 */ 479 FT_Error error; 480 char* newpath; 481 FT_Memory memory; 482 FT_Long base_file_len = ft_strlen( base_file_name ); 483 484 FT_UNUSED( stream ); 485 486 487 memory = library->memory; 488 489 if ( base_file_len + 6 > FT_INT_MAX ) 490 return FT_Err_Array_Too_Large; 491 492 if ( FT_ALLOC( newpath, base_file_len + 6 ) ) 493 return error; 494 495 FT_MEM_COPY( newpath, base_file_name, base_file_len ); 496 FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 ); 497 498 *result_file_name = newpath; 499 *result_offset = 0; 500 501 return FT_Err_Ok; 502 } 503 504 505 static FT_Error raccess_guess_darwin_newvfs(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)506 raccess_guess_darwin_newvfs( FT_Library library, 507 FT_Stream stream, 508 char *base_file_name, 509 char **result_file_name, 510 FT_Long *result_offset ) 511 { 512 /* 513 Only meaningful on systems with Mac OS X (> 10.1). 514 */ 515 FT_Error error; 516 char* newpath; 517 FT_Memory memory; 518 FT_Long base_file_len = ft_strlen( base_file_name ); 519 520 FT_UNUSED( stream ); 521 522 523 memory = library->memory; 524 525 if ( base_file_len + 18 > FT_INT_MAX ) 526 return FT_Err_Array_Too_Large; 527 528 if ( FT_ALLOC( newpath, base_file_len + 18 ) ) 529 return error; 530 531 FT_MEM_COPY( newpath, base_file_name, base_file_len ); 532 FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); 533 534 *result_file_name = newpath; 535 *result_offset = 0; 536 537 return FT_Err_Ok; 538 } 539 540 541 static FT_Error raccess_guess_vfat(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)542 raccess_guess_vfat( FT_Library library, 543 FT_Stream stream, 544 char *base_file_name, 545 char **result_file_name, 546 FT_Long *result_offset ) 547 { 548 char* newpath; 549 FT_Memory memory; 550 551 FT_UNUSED( stream ); 552 553 554 memory = library->memory; 555 556 newpath = raccess_make_file_name( memory, base_file_name, 557 "resource.frk/" ); 558 if ( !newpath ) 559 return FT_Err_Out_Of_Memory; 560 561 *result_file_name = newpath; 562 *result_offset = 0; 563 564 return FT_Err_Ok; 565 } 566 567 568 static FT_Error raccess_guess_linux_cap(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)569 raccess_guess_linux_cap( FT_Library library, 570 FT_Stream stream, 571 char *base_file_name, 572 char **result_file_name, 573 FT_Long *result_offset ) 574 { 575 char* newpath; 576 FT_Memory memory; 577 578 FT_UNUSED( stream ); 579 580 581 memory = library->memory; 582 583 newpath = raccess_make_file_name( memory, base_file_name, ".resource/" ); 584 if ( !newpath ) 585 return FT_Err_Out_Of_Memory; 586 587 *result_file_name = newpath; 588 *result_offset = 0; 589 590 return FT_Err_Ok; 591 } 592 593 594 static FT_Error raccess_guess_linux_double(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)595 raccess_guess_linux_double( FT_Library library, 596 FT_Stream stream, 597 char *base_file_name, 598 char **result_file_name, 599 FT_Long *result_offset ) 600 { 601 char* newpath; 602 FT_Error error; 603 FT_Memory memory; 604 605 FT_UNUSED( stream ); 606 607 608 memory = library->memory; 609 610 newpath = raccess_make_file_name( memory, base_file_name, "%" ); 611 if ( !newpath ) 612 return FT_Err_Out_Of_Memory; 613 614 error = raccess_guess_linux_double_from_file_name( library, newpath, 615 result_offset ); 616 if ( !error ) 617 *result_file_name = newpath; 618 else 619 FT_FREE( newpath ); 620 621 return error; 622 } 623 624 625 static FT_Error raccess_guess_linux_netatalk(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)626 raccess_guess_linux_netatalk( FT_Library library, 627 FT_Stream stream, 628 char *base_file_name, 629 char **result_file_name, 630 FT_Long *result_offset ) 631 { 632 char* newpath; 633 FT_Error error; 634 FT_Memory memory; 635 636 FT_UNUSED( stream ); 637 638 639 memory = library->memory; 640 641 newpath = raccess_make_file_name( memory, base_file_name, 642 ".AppleDouble/" ); 643 if ( !newpath ) 644 return FT_Err_Out_Of_Memory; 645 646 error = raccess_guess_linux_double_from_file_name( library, newpath, 647 result_offset ); 648 if ( !error ) 649 *result_file_name = newpath; 650 else 651 FT_FREE( newpath ); 652 653 return error; 654 } 655 656 657 static FT_Error raccess_guess_apple_generic(FT_Library library,FT_Stream stream,char * base_file_name,FT_Int32 magic,FT_Long * result_offset)658 raccess_guess_apple_generic( FT_Library library, 659 FT_Stream stream, 660 char *base_file_name, 661 FT_Int32 magic, 662 FT_Long *result_offset ) 663 { 664 FT_Int32 magic_from_stream; 665 FT_Error error; 666 FT_Int32 version_number = 0; 667 FT_UShort n_of_entries; 668 669 int i; 670 FT_UInt32 entry_id, entry_offset, entry_length = 0; 671 672 const FT_UInt32 resource_fork_entry_id = 0x2; 673 674 FT_UNUSED( library ); 675 FT_UNUSED( base_file_name ); 676 FT_UNUSED( version_number ); 677 FT_UNUSED( entry_length ); 678 679 680 if ( FT_READ_LONG( magic_from_stream ) ) 681 return error; 682 if ( magic_from_stream != magic ) 683 return FT_Err_Unknown_File_Format; 684 685 if ( FT_READ_LONG( version_number ) ) 686 return error; 687 688 /* filler */ 689 error = FT_Stream_Skip( stream, 16 ); 690 if ( error ) 691 return error; 692 693 if ( FT_READ_USHORT( n_of_entries ) ) 694 return error; 695 if ( n_of_entries == 0 ) 696 return FT_Err_Unknown_File_Format; 697 698 for ( i = 0; i < n_of_entries; i++ ) 699 { 700 if ( FT_READ_LONG( entry_id ) ) 701 return error; 702 if ( entry_id == resource_fork_entry_id ) 703 { 704 if ( FT_READ_LONG( entry_offset ) || 705 FT_READ_LONG( entry_length ) ) 706 continue; 707 *result_offset = entry_offset; 708 709 return FT_Err_Ok; 710 } 711 else 712 { 713 error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ 714 if ( error ) 715 return error; 716 } 717 } 718 719 return FT_Err_Unknown_File_Format; 720 } 721 722 723 static FT_Error raccess_guess_linux_double_from_file_name(FT_Library library,char * file_name,FT_Long * result_offset)724 raccess_guess_linux_double_from_file_name( FT_Library library, 725 char *file_name, 726 FT_Long *result_offset ) 727 { 728 FT_Open_Args args2; 729 FT_Stream stream2; 730 char * nouse = NULL; 731 FT_Error error; 732 733 734 args2.flags = FT_OPEN_PATHNAME; 735 args2.pathname = file_name; 736 error = FT_Stream_New( library, &args2, &stream2 ); 737 if ( error ) 738 return error; 739 740 error = raccess_guess_apple_double( library, stream2, file_name, 741 &nouse, result_offset ); 742 743 FT_Stream_Free( stream2, 0 ); 744 745 return error; 746 } 747 748 749 static char* raccess_make_file_name(FT_Memory memory,const char * original_name,const char * insertion)750 raccess_make_file_name( FT_Memory memory, 751 const char *original_name, 752 const char *insertion ) 753 { 754 char* new_name; 755 char* tmp; 756 const char* slash; 757 unsigned new_length; 758 FT_Error error = FT_Err_Ok; 759 760 FT_UNUSED( error ); 761 762 763 new_length = ft_strlen( original_name ) + ft_strlen( insertion ); 764 if ( FT_ALLOC( new_name, new_length + 1 ) ) 765 return NULL; 766 767 tmp = ft_strrchr( original_name, '/' ); 768 if ( tmp ) 769 { 770 ft_strncpy( new_name, original_name, tmp - original_name + 1 ); 771 new_name[tmp - original_name + 1] = '\0'; 772 slash = tmp + 1; 773 } 774 else 775 { 776 slash = original_name; 777 new_name[0] = '\0'; 778 } 779 780 ft_strcat( new_name, insertion ); 781 ft_strcat( new_name, slash ); 782 783 return new_name; 784 } 785 786 787 #else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ 788 789 790 /*************************************************************************/ 791 /* Dummy function; just sets errors */ 792 /*************************************************************************/ 793 794 FT_BASE_DEF( void ) FT_Raccess_Guess(FT_Library library,FT_Stream stream,char * base_name,char ** new_names,FT_Long * offsets,FT_Error * errors)795 FT_Raccess_Guess( FT_Library library, 796 FT_Stream stream, 797 char *base_name, 798 char **new_names, 799 FT_Long *offsets, 800 FT_Error *errors ) 801 { 802 int i; 803 804 FT_UNUSED( library ); 805 FT_UNUSED( stream ); 806 FT_UNUSED( base_name ); 807 808 809 for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) 810 { 811 new_names[i] = NULL; 812 offsets[i] = 0; 813 errors[i] = FT_Err_Unimplemented_Feature; 814 } 815 } 816 817 818 #endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ 819 820 821 /* END */ 822