34#define FT_COMPONENT raccess
49 FT_BASE_DEF( FT_Error )
50 FT_Raccess_Get_HeaderInfo( FT_Library library,
57 unsigned char head[16], head2[16];
58 FT_Long map_pos, map_len, rdata_len;
59 int allzeros, allmatch, i;
65 error = FT_Stream_Seek( stream, (FT_ULong)rfork_offset );
69 error = FT_Stream_Read( stream, (FT_Byte*)head, 16 );
74 if ( head[0] >= 0x80 ||
78 return FT_THROW( Unknown_File_Format );
80 *rdata_pos = ( head[ 0] << 24 ) |
84 map_pos = ( head[ 4] << 24 ) |
88 rdata_len = ( head[ 8] << 24 ) |
92 map_len = ( head[12] << 24 ) |
99 return FT_THROW( Unknown_File_Format );
102 if ( *rdata_pos < map_pos )
104 if ( *rdata_pos > map_pos - rdata_len )
105 return FT_THROW( Unknown_File_Format );
109 if ( map_pos > *rdata_pos - map_len )
110 return FT_THROW( Unknown_File_Format );
114 if ( FT_LONG_MAX - rdata_len < *rdata_pos ||
115 FT_LONG_MAX - map_len < map_pos ||
117 FT_LONG_MAX - ( *rdata_pos + rdata_len ) < rfork_offset ||
118 FT_LONG_MAX - ( map_pos + map_len ) < rfork_offset ||
120 (FT_ULong)( rfork_offset + *rdata_pos + rdata_len ) > stream->size ||
121 (FT_ULong)( rfork_offset + map_pos + map_len ) > stream->size )
122 return FT_THROW( Unknown_File_Format );
124 *rdata_pos += rfork_offset;
125 map_pos += rfork_offset;
127 error = FT_Stream_Seek( stream, (FT_ULong)map_pos );
131 head2[15] = (FT_Byte)( head[15] + 1 );
133 error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
139 for ( i = 0; i < 16; i++ )
143 if ( head2[i] != head[i] )
146 if ( !allzeros && !allmatch )
147 return FT_THROW( Unknown_File_Format );
152 (void)FT_STREAM_SKIP( 4
156 if ( FT_READ_SHORT( type_list ) )
159 return FT_THROW( Unknown_File_Format );
161 error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) );
165 *map_offset = map_pos + type_list;
170 FT_COMPARE_DEF(
int )
171 ft_raccess_sort_ref_by_id(
const void* a,
174 return ( (FT_RFork_Ref*)a )->res_id - ( (FT_RFork_Ref*)b )->res_id;
178 FT_BASE_DEF( FT_Error )
179 FT_Raccess_Get_DataOffsets( FT_Library library,
184 FT_Bool sort_by_res_id,
189 int i, j, cnt, subcnt;
190 FT_Long tag_internal, rpos;
191 FT_Memory memory = library->memory;
193 FT_Long *offsets_internal = NULL;
194 FT_RFork_Ref *ref = NULL;
198 error = FT_Stream_Seek( stream, (FT_ULong)map_offset );
202 if ( FT_READ_SHORT( cnt ) )
223 return FT_THROW( Invalid_Table );
225 for ( i = 0; i < cnt; i++ )
227 if ( FT_READ_LONG( tag_internal ) ||
228 FT_READ_SHORT( subcnt ) ||
229 FT_READ_SHORT( rpos ) )
232 FT_TRACE2((
"Resource tags: %c%c%c%c\n",
233 (
char)( 0xFF & ( tag_internal >> 24 ) ),
234 (
char)( 0xFF & ( tag_internal >> 16 ) ),
235 (
char)( 0xFF & ( tag_internal >> 8 ) ),
236 (
char)( 0xFF & ( tag_internal >> 0 ) ) ));
237 FT_TRACE3((
" : subcount=%d, suboffset=0x%04lx\n",
240 if ( tag_internal == tag )
247 if ( *count < 1 || *count > 2727 )
248 return FT_THROW( Invalid_Table );
250 error = FT_Stream_Seek( stream, (FT_ULong)rpos );
254 if ( FT_QNEW_ARRAY( ref, *count ) )
257 for ( j = 0; j < *count; j++ )
259 if ( FT_READ_SHORT( ref[j].res_id ) )
261 if ( FT_STREAM_SKIP( 2 ) )
263 if ( FT_READ_LONG( temp ) )
265 if ( FT_STREAM_SKIP( 4 ) )
274 ref[j].offset = temp & 0xFFFFFFL;
277 " resource_id=0x%04x, offset=0x%08lx\n",
278 j, (FT_UShort)ref[j].res_id, ref[j].offset ));
281 if ( sort_by_res_id )
285 sizeof ( FT_RFork_Ref ),
286 ft_raccess_sort_ref_by_id );
288 FT_TRACE3((
" -- sort resources by their ids --\n" ));
290 for ( j = 0; j < *count; j++ )
292 " resource_id=0x%04x, offset=0x%08lx\n",
293 j, ref[j].res_id, ref[j].offset ));
296 if ( FT_QNEW_ARRAY( offsets_internal, *count ) )
303 for ( j = 0; j < *count; j++ )
304 offsets_internal[j] = rdata_pos + ref[j].offset;
306 *offsets = offsets_internal;
315 return FT_THROW( Cannot_Open_Resource );
319#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
336 raccess_guess_apple_double( FT_Library library,
338 char *base_file_name,
339 char **result_file_name,
340 FT_Long *result_offset );
343 raccess_guess_apple_single( FT_Library library,
345 char *base_file_name,
346 char **result_file_name,
347 FT_Long *result_offset );
350 raccess_guess_darwin_ufs_export( FT_Library library,
352 char *base_file_name,
353 char **result_file_name,
354 FT_Long *result_offset );
357 raccess_guess_darwin_newvfs( FT_Library library,
359 char *base_file_name,
360 char **result_file_name,
361 FT_Long *result_offset );
364 raccess_guess_darwin_hfsplus( FT_Library library,
366 char *base_file_name,
367 char **result_file_name,
368 FT_Long *result_offset );
371 raccess_guess_vfat( FT_Library library,
373 char *base_file_name,
374 char **result_file_name,
375 FT_Long *result_offset );
378 raccess_guess_linux_cap( FT_Library library,
380 char *base_file_name,
381 char **result_file_name,
382 FT_Long *result_offset );
385 raccess_guess_linux_double( FT_Library library,
387 char *base_file_name,
388 char **result_file_name,
389 FT_Long *result_offset );
392 raccess_guess_linux_netatalk( FT_Library library,
394 char *base_file_name,
395 char **result_file_name,
396 FT_Long *result_offset );
399 CONST_FT_RFORK_RULE_ARRAY_BEGIN( ft_raccess_guess_table,
400 ft_raccess_guess_rec )
401 CONST_FT_RFORK_RULE_ARRAY_ENTRY( apple_double, apple_double )
402 CONST_FT_RFORK_RULE_ARRAY_ENTRY( apple_single, apple_single )
403 CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_ufs_export, darwin_ufs_export )
404 CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_newvfs, darwin_newvfs )
405 CONST_FT_RFORK_RULE_ARRAY_ENTRY( darwin_hfsplus, darwin_hfsplus )
406 CONST_FT_RFORK_RULE_ARRAY_ENTRY( vfat, vfat )
407 CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_cap, linux_cap )
408 CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_double, linux_double )
409 CONST_FT_RFORK_RULE_ARRAY_ENTRY( linux_netatalk, linux_netatalk )
410 CONST_FT_RFORK_RULE_ARRAY_END
420 raccess_guess_apple_generic( FT_Library library,
422 char *base_file_name,
424 FT_Long *result_offset );
427 raccess_guess_linux_double_from_file_name( FT_Library library,
429 FT_Long *result_offset );
432 raccess_make_file_name( FT_Memory memory,
433 const char *original_name,
434 const char *insertion );
437 FT_Raccess_Guess( FT_Library library,
447 for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
450 if ( NULL != stream )
451 errors[i] = FT_Stream_Seek( stream, 0 );
453 errors[i] = FT_Err_Ok;
458 errors[i] = ft_raccess_guess_table[i].func( library,
468#if defined( FT_CONFIG_OPTION_MAC_FONTS ) && !defined( FT_MACINTOSH )
470 raccess_get_rule_type_from_rule_index( FT_Library library,
473 FT_UNUSED( library );
475 if ( rule_index >= FT_RACCESS_N_RULES )
476 return FT_RFork_Rule_invalid;
478 return ft_raccess_guess_table[rule_index].type;
485 FT_LOCAL_DEF( FT_Bool )
486 ft_raccess_rule_by_darwin_vfs( FT_Library library,
489 switch( raccess_get_rule_type_from_rule_index( library, rule_index ) )
491 case FT_RFork_Rule_darwin_newvfs:
492 case FT_RFork_Rule_darwin_hfsplus:
503 raccess_guess_apple_double( FT_Library library,
505 char *base_file_name,
506 char **result_file_name,
507 FT_Long *result_offset )
509 FT_Int32 magic = ( 0x00 << 24 ) |
515 *result_file_name = NULL;
516 if ( NULL == stream )
517 return FT_THROW( Cannot_Open_Stream );
519 return raccess_guess_apple_generic( library, stream, base_file_name,
520 magic, result_offset );
525 raccess_guess_apple_single( FT_Library library,
527 char *base_file_name,
528 char **result_file_name,
529 FT_Long *result_offset )
531 FT_Int32 magic = ( 0x00 << 24 ) |
537 *result_file_name = NULL;
538 if ( NULL == stream )
539 return FT_THROW( Cannot_Open_Stream );
541 return raccess_guess_apple_generic( library, stream, base_file_name,
542 magic, result_offset );
547 raccess_guess_darwin_ufs_export( FT_Library library,
549 char *base_file_name,
550 char **result_file_name,
551 FT_Long *result_offset )
560 memory = library->memory;
561 newpath = raccess_make_file_name( memory, base_file_name,
"._" );
563 return FT_THROW( Out_Of_Memory );
565 error = raccess_guess_linux_double_from_file_name( library, newpath,
568 *result_file_name = newpath;
577 raccess_guess_darwin_hfsplus( FT_Library library,
579 char *base_file_name,
580 char **result_file_name,
581 FT_Long *result_offset )
587 char* newpath = NULL;
589 FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name );
594 memory = library->memory;
596 if ( base_file_len + 6 > FT_INT_MAX )
597 return FT_THROW( Array_Too_Large );
599 if ( FT_QALLOC( newpath, base_file_len + 6 ) )
602 FT_MEM_COPY( newpath, base_file_name, base_file_len );
603 FT_MEM_COPY( newpath + base_file_len,
"/rsrc", 6 );
605 *result_file_name = newpath;
613 raccess_guess_darwin_newvfs( FT_Library library,
615 char *base_file_name,
616 char **result_file_name,
617 FT_Long *result_offset )
623 char* newpath = NULL;
625 FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name );
630 memory = library->memory;
632 if ( base_file_len + 18 > FT_INT_MAX )
633 return FT_THROW( Array_Too_Large );
635 if ( FT_QALLOC( newpath, base_file_len + 18 ) )
638 FT_MEM_COPY( newpath, base_file_name, base_file_len );
639 FT_MEM_COPY( newpath + base_file_len,
"/..namedfork/rsrc", 18 );
641 *result_file_name = newpath;
649 raccess_guess_vfat( FT_Library library,
651 char *base_file_name,
652 char **result_file_name,
653 FT_Long *result_offset )
661 memory = library->memory;
663 newpath = raccess_make_file_name( memory, base_file_name,
666 return FT_THROW( Out_Of_Memory );
668 *result_file_name = newpath;
676 raccess_guess_linux_cap( FT_Library library,
678 char *base_file_name,
679 char **result_file_name,
680 FT_Long *result_offset )
688 memory = library->memory;
690 newpath = raccess_make_file_name( memory, base_file_name,
".resource/" );
692 return FT_THROW( Out_Of_Memory );
694 *result_file_name = newpath;
702 raccess_guess_linux_double( FT_Library library,
704 char *base_file_name,
705 char **result_file_name,
706 FT_Long *result_offset )
715 memory = library->memory;
717 newpath = raccess_make_file_name( memory, base_file_name,
"%" );
719 return FT_THROW( Out_Of_Memory );
721 error = raccess_guess_linux_double_from_file_name( library, newpath,
724 *result_file_name = newpath;
733 raccess_guess_linux_netatalk( FT_Library library,
735 char *base_file_name,
736 char **result_file_name,
737 FT_Long *result_offset )
746 memory = library->memory;
748 newpath = raccess_make_file_name( memory, base_file_name,
751 return FT_THROW( Out_Of_Memory );
753 error = raccess_guess_linux_double_from_file_name( library, newpath,
756 *result_file_name = newpath;
765 raccess_guess_apple_generic( FT_Library library,
767 char *base_file_name,
769 FT_Long *result_offset )
771 FT_Int32 magic_from_stream;
773 FT_Int32 version_number = 0;
774 FT_UShort n_of_entries;
777 FT_Int32 entry_id, entry_offset, entry_length = 0;
779 const FT_Int32 resource_fork_entry_id = 0x2;
781 FT_UNUSED( library );
782 FT_UNUSED( base_file_name );
783 FT_UNUSED( version_number );
784 FT_UNUSED( entry_length );
787 if ( FT_READ_LONG( magic_from_stream ) )
789 if ( magic_from_stream != magic )
790 return FT_THROW( Unknown_File_Format );
792 if ( FT_READ_LONG( version_number ) )
796 error = FT_Stream_Skip( stream, 16 );
800 if ( FT_READ_USHORT( n_of_entries ) )
802 if ( n_of_entries == 0 )
803 return FT_THROW( Unknown_File_Format );
805 for ( i = 0; i < n_of_entries; i++ )
807 if ( FT_READ_LONG( entry_id ) )
809 if ( entry_id == resource_fork_entry_id )
811 if ( FT_READ_LONG( entry_offset ) ||
812 FT_READ_LONG( entry_length ) )
814 *result_offset = entry_offset;
820 error = FT_Stream_Skip( stream, 4 + 4 );
826 return FT_THROW( Unknown_File_Format );
831 raccess_guess_linux_double_from_file_name( FT_Library library,
833 FT_Long *result_offset )
841 args2.flags = FT_OPEN_PATHNAME;
842 args2.pathname = file_name;
843 error = FT_Stream_New( library, &args2, &stream2 );
847 error = raccess_guess_apple_double( library, stream2, file_name,
848 &nouse, result_offset );
850 FT_Stream_Free( stream2, 0 );
857 raccess_make_file_name( FT_Memory memory,
858 const char *original_name,
859 const char *insertion )
861 char* new_name = NULL;
868 new_length = ft_strlen( original_name ) + ft_strlen( insertion );
869 if ( FT_QALLOC( new_name, new_length + 1 ) )
872 tmp = ft_strrchr( original_name,
'/' );
875 ft_strncpy( new_name,
877 (
size_t)( tmp - original_name + 1 ) );
878 new_name[tmp - original_name + 1] =
'\0';
883 slash = original_name;
887 ft_strcat( new_name, insertion );
888 ft_strcat( new_name, slash );
902 FT_Raccess_Guess( FT_Library library,
911 FT_UNUSED( library );
913 FT_UNUSED( base_name );
916 for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
920 errors[i] = FT_ERR( Unimplemented_Feature );