/***************************************************************************/ | |
/* */ | |
/* ftrfork.c */ | |
/* */ | |
/* Embedded resource forks accessor (body). */ | |
/* */ | |
/* Copyright 2004-2015 by */ | |
/* Masatake YAMATO and Redhat K.K. */ | |
/* */ | |
/* FT_Raccess_Get_HeaderInfo() and raccess_guess_darwin_hfsplus() are */ | |
/* derived from ftobjs.c. */ | |
/* */ | |
/* This file is part of the FreeType project, and may only be used, */ | |
/* modified, and distributed under the terms of the FreeType project */ | |
/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | |
/* this file you indicate that you have read the license and */ | |
/* understand and accept it fully. */ | |
/* */ | |
/***************************************************************************/ | |
/***************************************************************************/ | |
/* Development of the code in this file is support of */ | |
/* Information-technology Promotion Agency, Japan. */ | |
/***************************************************************************/ | |
#include <ft2build.h> | |
#include FT_INTERNAL_DEBUG_H | |
#include FT_INTERNAL_STREAM_H | |
#include FT_INTERNAL_RFORK_H | |
#include "basepic.h" | |
#include "ftbase.h" | |
#undef FT_COMPONENT | |
#define FT_COMPONENT trace_raccess | |
/*************************************************************************/ | |
/*************************************************************************/ | |
/*************************************************************************/ | |
/**** ****/ | |
/**** ****/ | |
/**** Resource fork directory access ****/ | |
/**** ****/ | |
/**** ****/ | |
/*************************************************************************/ | |
/*************************************************************************/ | |
/*************************************************************************/ | |
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 ) | |
{ | |
FT_Error error; | |
unsigned char head[16], head2[16]; | |
FT_Long map_pos, rdata_len; | |
int allzeros, allmatch, i; | |
FT_Long type_list; | |
FT_UNUSED( library ); | |
error = FT_Stream_Seek( stream, (FT_ULong)rfork_offset ); | |
if ( error ) | |
return error; | |
error = FT_Stream_Read( stream, (FT_Byte *)head, 16 ); | |
if ( error ) | |
return error; | |
/* ensure positive values */ | |
if ( head[0] >= 0x80 || head[4] >= 0x80 || head[8] >= 0x80 ) | |
return FT_THROW( Unknown_File_Format ); | |
*rdata_pos = ( head[ 0] << 24 ) | | |
( head[ 1] << 16 ) | | |
( head[ 2] << 8 ) | | |
head[ 3]; | |
map_pos = ( head[ 4] << 24 ) | | |
( head[ 5] << 16 ) | | |
( head[ 6] << 8 ) | | |
head[ 7]; | |
rdata_len = ( head[ 8] << 24 ) | | |
( head[ 9] << 16 ) | | |
( head[10] << 8 ) | | |
head[11]; | |
/* map_len = head[12] .. head[15] */ | |
if ( *rdata_pos != map_pos - rdata_len || map_pos == 0 ) | |
return FT_THROW( Unknown_File_Format ); | |
if ( FT_LONG_MAX - rfork_offset < *rdata_pos || | |
FT_LONG_MAX - rfork_offset < map_pos ) | |
return FT_THROW( Unknown_File_Format ); | |
*rdata_pos += rfork_offset; | |
map_pos += rfork_offset; | |
error = FT_Stream_Seek( stream, (FT_ULong)map_pos ); | |
if ( error ) | |
return error; | |
head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */ | |
error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 ); | |
if ( error ) | |
return error; | |
allzeros = 1; | |
allmatch = 1; | |
for ( i = 0; i < 16; ++i ) | |
{ | |
if ( head2[i] != 0 ) | |
allzeros = 0; | |
if ( head2[i] != head[i] ) | |
allmatch = 0; | |
} | |
if ( !allzeros && !allmatch ) | |
return FT_THROW( Unknown_File_Format ); | |
/* If we have reached this point then it is probably a mac resource */ | |
/* file. Now, does it contain any interesting resources? */ | |
/* Skip handle to next resource map, the file resource number, and */ | |
/* attributes. */ | |
(void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */ | |
+ 2 /* skip file resource number */ | |
+ 2 ); /* skip attributes */ | |
if ( FT_READ_USHORT( type_list ) ) | |
return error; | |
if ( type_list == -1 ) | |
return FT_THROW( Unknown_File_Format ); | |
error = FT_Stream_Seek( stream, (FT_ULong)( map_pos + type_list ) ); | |
if ( error ) | |
return error; | |
*map_offset = map_pos + type_list; | |
return FT_Err_Ok; | |
} | |
static int | |
ft_raccess_sort_ref_by_id( FT_RFork_Ref* a, | |
FT_RFork_Ref* b ) | |
{ | |
if ( a->res_id < b->res_id ) | |
return -1; | |
else if ( a->res_id > b->res_id ) | |
return 1; | |
else | |
return 0; | |
} | |
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_Bool sort_by_res_id, | |
FT_Long **offsets, | |
FT_Long *count ) | |
{ | |
FT_Error error; | |
int i, j, cnt, subcnt; | |
FT_Long tag_internal, rpos; | |
FT_Memory memory = library->memory; | |
FT_Long temp; | |
FT_Long *offsets_internal = NULL; | |
FT_RFork_Ref *ref = NULL; | |
FT_TRACE3(( "\n" )); | |
error = FT_Stream_Seek( stream, (FT_ULong)map_offset ); | |
if ( error ) | |
return error; | |
if ( FT_READ_USHORT( cnt ) ) | |
return error; | |
cnt++; | |
for ( i = 0; i < cnt; ++i ) | |
{ | |
if ( FT_READ_LONG( tag_internal ) || | |
FT_READ_USHORT( subcnt ) || | |
FT_READ_USHORT( rpos ) ) | |
return error; | |
FT_TRACE2(( "Resource tags: %c%c%c%c\n", | |
(char)( 0xFF & ( tag_internal >> 24 ) ), | |
(char)( 0xFF & ( tag_internal >> 16 ) ), | |
(char)( 0xFF & ( tag_internal >> 8 ) ), | |
(char)( 0xFF & ( tag_internal >> 0 ) ) )); | |
FT_TRACE3(( " : subcount=%d, suboffset=0x%04x\n", | |
subcnt, rpos )); | |
if ( tag_internal == tag ) | |
{ | |
*count = subcnt + 1; | |
rpos += map_offset; | |
error = FT_Stream_Seek( stream, (FT_ULong)rpos ); | |
if ( error ) | |
return error; | |
if ( FT_NEW_ARRAY( ref, *count ) ) | |
return error; | |
for ( j = 0; j < *count; ++j ) | |
{ | |
if ( FT_READ_USHORT( ref[j].res_id ) ) | |
goto Exit; | |
if ( FT_STREAM_SKIP( 2 ) ) /* resource name */ | |
goto Exit; | |
if ( FT_READ_LONG( temp ) ) | |
goto Exit; | |
if ( FT_STREAM_SKIP( 4 ) ) /* mbz */ | |
goto Exit; | |
ref[j].offset = temp & 0xFFFFFFL; | |
FT_TRACE3(( " [%d]:" | |
" resource_id=0x%04x, offset=0x%08x\n", | |
j, ref[j].res_id, ref[j].offset )); | |
} | |
if (sort_by_res_id) | |
{ | |
ft_qsort( ref, (size_t)*count, sizeof ( FT_RFork_Ref ), | |
( int(*)(const void*, const void*) ) | |
ft_raccess_sort_ref_by_id ); | |
FT_TRACE3(( " -- sort resources by their ids --\n" )); | |
for ( j = 0; j < *count; ++ j ) { | |
FT_TRACE3(( " [%d]:" | |
" resource_id=0x%04x, offset=0x%08x\n", | |
j, ref[j].res_id, ref[j].offset )); | |
} | |
} | |
if ( FT_NEW_ARRAY( offsets_internal, *count ) ) | |
goto Exit; | |
/* XXX: duplicated reference ID, | |
* gap between reference IDs are acceptable? | |
* further investigation on Apple implementation is needed. | |
*/ | |
for ( j = 0; j < *count; ++j ) | |
offsets_internal[j] = rdata_pos + ref[j].offset; | |
*offsets = offsets_internal; | |
error = FT_Err_Ok; | |
Exit: | |
FT_FREE( ref ); | |
return error; | |
} | |
} | |
return FT_THROW( Cannot_Open_Resource ); | |
} | |
#ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK | |
/*************************************************************************/ | |
/*************************************************************************/ | |
/*************************************************************************/ | |
/**** ****/ | |
/**** ****/ | |
/**** Guessing functions ****/ | |
/**** ****/ | |
/**** When you add a new guessing function, ****/ | |
/**** update FT_RACCESS_N_RULES in ftrfork.h. ****/ | |
/**** ****/ | |
/*************************************************************************/ | |
/*************************************************************************/ | |
/*************************************************************************/ | |
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 ); | |
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 ); | |
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 ); | |
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 ); | |
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 ); | |
static FT_Error | |
raccess_guess_vfat( FT_Library library, | |
FT_Stream stream, | |
char *base_file_name, | |
char **result_file_name, | |
FT_Long *result_offset ); | |
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 ); | |
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 ); | |
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 ); | |
CONST_FT_RFORK_RULE_ARRAY_BEGIN(ft_raccess_guess_table, | |
ft_raccess_guess_rec) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_double, apple_double) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_single, apple_single) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_ufs_export, darwin_ufs_export) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_newvfs, darwin_newvfs) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_hfsplus, darwin_hfsplus) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(vfat, vfat) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_cap, linux_cap) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_double, linux_double) | |
CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_netatalk, linux_netatalk) | |
CONST_FT_RFORK_RULE_ARRAY_END | |
/*************************************************************************/ | |
/**** ****/ | |
/**** Helper functions ****/ | |
/**** ****/ | |
/*************************************************************************/ | |
static FT_Error | |
raccess_guess_apple_generic( FT_Library library, | |
FT_Stream stream, | |
char *base_file_name, | |
FT_Int32 magic, | |
FT_Long *result_offset ); | |
static FT_Error | |
raccess_guess_linux_double_from_file_name( FT_Library library, | |
char * file_name, | |
FT_Long *result_offset ); | |
static char * | |
raccess_make_file_name( FT_Memory memory, | |
const char *original_name, | |
const char *insertion ); | |
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 ) | |
{ | |
FT_Int i; | |
for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) | |
{ | |
new_names[i] = NULL; | |
if ( NULL != stream ) | |
errors[i] = FT_Stream_Seek( stream, 0 ); | |
else | |
errors[i] = FT_Err_Ok; | |
if ( errors[i] ) | |
continue ; | |
errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library, | |
stream, base_name, | |
&(new_names[i]), | |
&(offsets[i]) ); | |
} | |
return; | |
} | |
#ifndef FT_MACINTOSH | |
static FT_RFork_Rule | |
raccess_get_rule_type_from_rule_index( FT_Library library, | |
FT_UInt rule_index ) | |
{ | |
FT_UNUSED( library ); | |
if ( rule_index >= FT_RACCESS_N_RULES ) | |
return FT_RFork_Rule_invalid; | |
return FT_RACCESS_GUESS_TABLE_GET[rule_index].type; | |
} | |
/* | |
* For this function, refer ftbase.h. | |
*/ | |
FT_LOCAL_DEF( FT_Bool ) | |
ft_raccess_rule_by_darwin_vfs( FT_Library library, | |
FT_UInt rule_index ) | |
{ | |
switch( raccess_get_rule_type_from_rule_index( library, rule_index ) ) | |
{ | |
case FT_RFork_Rule_darwin_newvfs: | |
case FT_RFork_Rule_darwin_hfsplus: | |
return TRUE; | |
default: | |
return FALSE; | |
} | |
} | |
#endif | |
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 ) | |
{ | |
FT_Int32 magic = ( 0x00 << 24 ) | | |
( 0x05 << 16 ) | | |
( 0x16 << 8 ) | | |
0x07; | |
*result_file_name = NULL; | |
if ( NULL == stream ) | |
return FT_THROW( Cannot_Open_Stream ); | |
return raccess_guess_apple_generic( library, stream, base_file_name, | |
magic, result_offset ); | |
} | |
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 ) | |
{ | |
FT_Int32 magic = ( 0x00 << 24 ) | | |
( 0x05 << 16 ) | | |
( 0x16 << 8 ) | | |
0x00; | |
*result_file_name = NULL; | |
if ( NULL == stream ) | |
return FT_THROW( Cannot_Open_Stream ); | |
return raccess_guess_apple_generic( library, stream, base_file_name, | |
magic, result_offset ); | |
} | |
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 ) | |
{ | |
char* newpath; | |
FT_Error error; | |
FT_Memory memory; | |
FT_UNUSED( stream ); | |
memory = library->memory; | |
newpath = raccess_make_file_name( memory, base_file_name, "._" ); | |
if ( !newpath ) | |
return FT_THROW( Out_Of_Memory ); | |
error = raccess_guess_linux_double_from_file_name( library, newpath, | |
result_offset ); | |
if ( !error ) | |
*result_file_name = newpath; | |
else | |
FT_FREE( newpath ); | |
return error; | |
} | |
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 ) | |
{ | |
/* | |
Only meaningful on systems with hfs+ drivers (or Macs). | |
*/ | |
FT_Error error; | |
char* newpath = NULL; | |
FT_Memory memory; | |
FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name ); | |
FT_UNUSED( stream ); | |
memory = library->memory; | |
if ( base_file_len + 6 > FT_INT_MAX ) | |
return FT_THROW( Array_Too_Large ); | |
if ( FT_ALLOC( newpath, base_file_len + 6 ) ) | |
return error; | |
FT_MEM_COPY( newpath, base_file_name, base_file_len ); | |
FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 ); | |
*result_file_name = newpath; | |
*result_offset = 0; | |
return FT_Err_Ok; | |
} | |
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 ) | |
{ | |
/* | |
Only meaningful on systems with Mac OS X (> 10.1). | |
*/ | |
FT_Error error; | |
char* newpath = NULL; | |
FT_Memory memory; | |
FT_Long base_file_len = (FT_Long)ft_strlen( base_file_name ); | |
FT_UNUSED( stream ); | |
memory = library->memory; | |
if ( base_file_len + 18 > FT_INT_MAX ) | |
return FT_THROW( Array_Too_Large ); | |
if ( FT_ALLOC( newpath, base_file_len + 18 ) ) | |
return error; | |
FT_MEM_COPY( newpath, base_file_name, base_file_len ); | |
FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 ); | |
*result_file_name = newpath; | |
*result_offset = 0; | |
return FT_Err_Ok; | |
} | |
static FT_Error | |
raccess_guess_vfat( FT_Library library, | |
FT_Stream stream, | |
char *base_file_name, | |
char **result_file_name, | |
FT_Long *result_offset ) | |
{ | |
char* newpath; | |
FT_Memory memory; | |
FT_UNUSED( stream ); | |
memory = library->memory; | |
newpath = raccess_make_file_name( memory, base_file_name, | |
"resource.frk/" ); | |
if ( !newpath ) | |
return FT_THROW( Out_Of_Memory ); | |
*result_file_name = newpath; | |
*result_offset = 0; | |
return FT_Err_Ok; | |
} | |
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 ) | |
{ | |
char* newpath; | |
FT_Memory memory; | |
FT_UNUSED( stream ); | |
memory = library->memory; | |
newpath = raccess_make_file_name( memory, base_file_name, ".resource/" ); | |
if ( !newpath ) | |
return FT_THROW( Out_Of_Memory ); | |
*result_file_name = newpath; | |
*result_offset = 0; | |
return FT_Err_Ok; | |
} | |
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 ) | |
{ | |
char* newpath; | |
FT_Error error; | |
FT_Memory memory; | |
FT_UNUSED( stream ); | |
memory = library->memory; | |
newpath = raccess_make_file_name( memory, base_file_name, "%" ); | |
if ( !newpath ) | |
return FT_THROW( Out_Of_Memory ); | |
error = raccess_guess_linux_double_from_file_name( library, newpath, | |
result_offset ); | |
if ( !error ) | |
*result_file_name = newpath; | |
else | |
FT_FREE( newpath ); | |
return error; | |
} | |
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 ) | |
{ | |
char* newpath; | |
FT_Error error; | |
FT_Memory memory; | |
FT_UNUSED( stream ); | |
memory = library->memory; | |
newpath = raccess_make_file_name( memory, base_file_name, | |
".AppleDouble/" ); | |
if ( !newpath ) | |
return FT_THROW( Out_Of_Memory ); | |
error = raccess_guess_linux_double_from_file_name( library, newpath, | |
result_offset ); | |
if ( !error ) | |
*result_file_name = newpath; | |
else | |
FT_FREE( newpath ); | |
return error; | |
} | |
static FT_Error | |
raccess_guess_apple_generic( FT_Library library, | |
FT_Stream stream, | |
char *base_file_name, | |
FT_Int32 magic, | |
FT_Long *result_offset ) | |
{ | |
FT_Int32 magic_from_stream; | |
FT_Error error; | |
FT_Int32 version_number = 0; | |
FT_UShort n_of_entries; | |
int i; | |
FT_Int32 entry_id, entry_offset, entry_length = 0; | |
const FT_Int32 resource_fork_entry_id = 0x2; | |
FT_UNUSED( library ); | |
FT_UNUSED( base_file_name ); | |
FT_UNUSED( version_number ); | |
FT_UNUSED( entry_length ); | |
if ( FT_READ_LONG( magic_from_stream ) ) | |
return error; | |
if ( magic_from_stream != magic ) | |
return FT_THROW( Unknown_File_Format ); | |
if ( FT_READ_LONG( version_number ) ) | |
return error; | |
/* filler */ | |
error = FT_Stream_Skip( stream, 16 ); | |
if ( error ) | |
return error; | |
if ( FT_READ_USHORT( n_of_entries ) ) | |
return error; | |
if ( n_of_entries == 0 ) | |
return FT_THROW( Unknown_File_Format ); | |
for ( i = 0; i < n_of_entries; i++ ) | |
{ | |
if ( FT_READ_LONG( entry_id ) ) | |
return error; | |
if ( entry_id == resource_fork_entry_id ) | |
{ | |
if ( FT_READ_LONG( entry_offset ) || | |
FT_READ_LONG( entry_length ) ) | |
continue; | |
*result_offset = entry_offset; | |
return FT_Err_Ok; | |
} | |
else | |
{ | |
error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */ | |
if ( error ) | |
return error; | |
} | |
} | |
return FT_THROW( Unknown_File_Format ); | |
} | |
static FT_Error | |
raccess_guess_linux_double_from_file_name( FT_Library library, | |
char *file_name, | |
FT_Long *result_offset ) | |
{ | |
FT_Open_Args args2; | |
FT_Stream stream2; | |
char * nouse = NULL; | |
FT_Error error; | |
args2.flags = FT_OPEN_PATHNAME; | |
args2.pathname = file_name; | |
error = FT_Stream_New( library, &args2, &stream2 ); | |
if ( error ) | |
return error; | |
error = raccess_guess_apple_double( library, stream2, file_name, | |
&nouse, result_offset ); | |
FT_Stream_Free( stream2, 0 ); | |
return error; | |
} | |
static char* | |
raccess_make_file_name( FT_Memory memory, | |
const char *original_name, | |
const char *insertion ) | |
{ | |
char* new_name = NULL; | |
const char* tmp; | |
const char* slash; | |
size_t new_length; | |
FT_Error error = FT_Err_Ok; | |
FT_UNUSED( error ); | |
new_length = ft_strlen( original_name ) + ft_strlen( insertion ); | |
if ( FT_ALLOC( new_name, new_length + 1 ) ) | |
return NULL; | |
tmp = ft_strrchr( original_name, '/' ); | |
if ( tmp ) | |
{ | |
ft_strncpy( new_name, | |
original_name, | |
(size_t)( tmp - original_name + 1 ) ); | |
new_name[tmp - original_name + 1] = '\0'; | |
slash = tmp + 1; | |
} | |
else | |
{ | |
slash = original_name; | |
new_name[0] = '\0'; | |
} | |
ft_strcat( new_name, insertion ); | |
ft_strcat( new_name, slash ); | |
return new_name; | |
} | |
#else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ | |
/*************************************************************************/ | |
/* Dummy function; just sets errors */ | |
/*************************************************************************/ | |
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 ) | |
{ | |
FT_Int i; | |
FT_UNUSED( library ); | |
FT_UNUSED( stream ); | |
FT_UNUSED( base_name ); | |
for ( i = 0; i < FT_RACCESS_N_RULES; i++ ) | |
{ | |
new_names[i] = NULL; | |
offsets[i] = 0; | |
errors[i] = FT_ERR( Unimplemented_Feature ); | |
} | |
} | |
#endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */ | |
/* END */ |