1/***************************************************************************/
2/*                                                                         */
3/*  ftrfork.c                                                              */
4/*                                                                         */
5/*    Embedded resource forks accessor (body).                             */
6/*                                                                         */
7/*  Copyright 2004-2010, 2013 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 "../../include/ft2build.h"
28#include "../../include/freetype/internal/ftdebug.h"
29#include "../../include/freetype/internal/ftstream.h"
30#include "../../include/freetype/internal/ftrfork.h"
31#include "basepic.h"
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 )
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_THROW( 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_THROW( 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_THROW( 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
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 )
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 = NULL;
163    FT_RFork_Ref  *ref = NULL;
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_THROW( 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  static FT_Error
257  raccess_guess_apple_double( FT_Library  library,
258                              FT_Stream   stream,
259                              char       *base_file_name,
260                              char      **result_file_name,
261                              FT_Long    *result_offset );
262
263  static FT_Error
264  raccess_guess_apple_single( FT_Library  library,
265                              FT_Stream   stream,
266                              char       *base_file_name,
267                              char      **result_file_name,
268                              FT_Long    *result_offset );
269
270  static FT_Error
271  raccess_guess_darwin_ufs_export( FT_Library  library,
272                                   FT_Stream   stream,
273                                   char       *base_file_name,
274                                   char      **result_file_name,
275                                   FT_Long    *result_offset );
276
277  static FT_Error
278  raccess_guess_darwin_newvfs( FT_Library  library,
279                               FT_Stream   stream,
280                               char       *base_file_name,
281                               char      **result_file_name,
282                               FT_Long    *result_offset );
283
284  static FT_Error
285  raccess_guess_darwin_hfsplus( FT_Library  library,
286                                FT_Stream   stream,
287                                char       *base_file_name,
288                                char      **result_file_name,
289                                FT_Long    *result_offset );
290
291  static FT_Error
292  raccess_guess_vfat( FT_Library  library,
293                      FT_Stream   stream,
294                      char       *base_file_name,
295                      char      **result_file_name,
296                      FT_Long    *result_offset );
297
298  static FT_Error
299  raccess_guess_linux_cap( FT_Library  library,
300                           FT_Stream   stream,
301                           char       *base_file_name,
302                           char      **result_file_name,
303                           FT_Long    *result_offset );
304
305  static FT_Error
306  raccess_guess_linux_double( FT_Library  library,
307                              FT_Stream   stream,
308                              char       *base_file_name,
309                              char      **result_file_name,
310                              FT_Long    *result_offset );
311
312  static FT_Error
313  raccess_guess_linux_netatalk( FT_Library  library,
314                                FT_Stream   stream,
315                                char       *base_file_name,
316                                char      **result_file_name,
317                                FT_Long    *result_offset );
318
319
320  CONST_FT_RFORK_RULE_ARRAY_BEGIN(ft_raccess_guess_table,
321                                  ft_raccess_guess_rec)
322  CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_double,      apple_double)
323  CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_single,      apple_single)
324  CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_ufs_export, darwin_ufs_export)
325  CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_newvfs,     darwin_newvfs)
326  CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_hfsplus,    darwin_hfsplus)
327  CONST_FT_RFORK_RULE_ARRAY_ENTRY(vfat,              vfat)
328  CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_cap,         linux_cap)
329  CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_double,      linux_double)
330  CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_netatalk,    linux_netatalk)
331  CONST_FT_RFORK_RULE_ARRAY_END
332
333
334  /*************************************************************************/
335  /****                                                                 ****/
336  /****                       Helper functions                          ****/
337  /****                                                                 ****/
338  /*************************************************************************/
339
340  static FT_Error
341  raccess_guess_apple_generic( FT_Library  library,
342                               FT_Stream   stream,
343                               char       *base_file_name,
344                               FT_Int32    magic,
345                               FT_Long    *result_offset );
346
347  static FT_Error
348  raccess_guess_linux_double_from_file_name( FT_Library  library,
349                                             char *      file_name,
350                                             FT_Long    *result_offset );
351
352  static char *
353  raccess_make_file_name( FT_Memory    memory,
354                          const char  *original_name,
355                          const char  *insertion );
356
357  FT_BASE_DEF( void )
358  FT_Raccess_Guess( FT_Library  library,
359                    FT_Stream   stream,
360                    char*       base_name,
361                    char      **new_names,
362                    FT_Long    *offsets,
363                    FT_Error   *errors )
364  {
365    FT_Int  i;
366
367
368    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
369    {
370      new_names[i] = NULL;
371      if ( NULL != stream )
372        errors[i] = FT_Stream_Seek( stream, 0 );
373      else
374        errors[i] = FT_Err_Ok;
375
376      if ( errors[i] )
377        continue ;
378
379      errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library,
380                                                 stream, base_name,
381                                                 &(new_names[i]),
382                                                 &(offsets[i]) );
383    }
384
385    return;
386  }
387
388
389#ifndef FT_MACINTOSH
390  static FT_RFork_Rule
391  raccess_get_rule_type_from_rule_index( FT_Library  library,
392                                         FT_UInt     rule_index )
393  {
394    FT_UNUSED( library );
395
396    if ( rule_index >= FT_RACCESS_N_RULES )
397      return FT_RFork_Rule_invalid;
398
399    return FT_RACCESS_GUESS_TABLE_GET[rule_index].type;
400  }
401
402
403  /*
404   * For this function, refer ftbase.h.
405   */
406  FT_LOCAL_DEF( FT_Bool )
407  ft_raccess_rule_by_darwin_vfs( FT_Library  library,
408                                 FT_UInt     rule_index )
409  {
410    switch( raccess_get_rule_type_from_rule_index( library, rule_index ) )
411    {
412      case FT_RFork_Rule_darwin_newvfs:
413      case FT_RFork_Rule_darwin_hfsplus:
414        return TRUE;
415
416      default:
417        return FALSE;
418    }
419  }
420#endif
421
422
423  static FT_Error
424  raccess_guess_apple_double( FT_Library  library,
425                              FT_Stream   stream,
426                              char       *base_file_name,
427                              char      **result_file_name,
428                              FT_Long    *result_offset )
429  {
430    FT_Int32  magic = ( 0x00 << 24 ) |
431                      ( 0x05 << 16 ) |
432                      ( 0x16 <<  8 ) |
433                        0x07;
434
435
436    *result_file_name = NULL;
437    if ( NULL == stream )
438      return FT_THROW( Cannot_Open_Stream );
439
440    return raccess_guess_apple_generic( library, stream, base_file_name,
441                                        magic, result_offset );
442  }
443
444
445  static FT_Error
446  raccess_guess_apple_single( FT_Library  library,
447                              FT_Stream   stream,
448                              char       *base_file_name,
449                              char      **result_file_name,
450                              FT_Long    *result_offset )
451  {
452    FT_Int32  magic = ( 0x00 << 24 ) |
453                      ( 0x05 << 16 ) |
454                      ( 0x16 <<  8 ) |
455                        0x00;
456
457
458    *result_file_name = NULL;
459    if ( NULL == stream )
460      return FT_THROW( Cannot_Open_Stream );
461
462    return raccess_guess_apple_generic( library, stream, base_file_name,
463                                        magic, result_offset );
464  }
465
466
467  static FT_Error
468  raccess_guess_darwin_ufs_export( FT_Library  library,
469                                   FT_Stream   stream,
470                                   char       *base_file_name,
471                                   char      **result_file_name,
472                                   FT_Long    *result_offset )
473  {
474    char*      newpath;
475    FT_Error   error;
476    FT_Memory  memory;
477
478    FT_UNUSED( stream );
479
480
481    memory  = library->memory;
482    newpath = raccess_make_file_name( memory, base_file_name, "._" );
483    if ( !newpath )
484      return FT_THROW( Out_Of_Memory );
485
486    error = raccess_guess_linux_double_from_file_name( library, newpath,
487                                                       result_offset );
488    if ( !error )
489      *result_file_name = newpath;
490    else
491      FT_FREE( newpath );
492
493    return error;
494  }
495
496
497  static FT_Error
498  raccess_guess_darwin_hfsplus( FT_Library  library,
499                                FT_Stream   stream,
500                                char       *base_file_name,
501                                char      **result_file_name,
502                                FT_Long    *result_offset )
503  {
504    /*
505      Only meaningful on systems with hfs+ drivers (or Macs).
506     */
507    FT_Error   error;
508    char*      newpath = NULL;
509    FT_Memory  memory;
510    FT_Long    base_file_len = (FT_Long)ft_strlen( base_file_name );
511
512    FT_UNUSED( stream );
513
514
515    memory = library->memory;
516
517    if ( base_file_len + 6 > FT_INT_MAX )
518      return FT_THROW( Array_Too_Large );
519
520    if ( FT_ALLOC( newpath, base_file_len + 6 ) )
521      return error;
522
523    FT_MEM_COPY( newpath, base_file_name, base_file_len );
524    FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
525
526    *result_file_name = newpath;
527    *result_offset    = 0;
528
529    return FT_Err_Ok;
530  }
531
532
533  static FT_Error
534  raccess_guess_darwin_newvfs( FT_Library  library,
535                               FT_Stream   stream,
536                               char       *base_file_name,
537                               char      **result_file_name,
538                               FT_Long    *result_offset )
539  {
540    /*
541      Only meaningful on systems with Mac OS X (> 10.1).
542     */
543    FT_Error   error;
544    char*      newpath = NULL;
545    FT_Memory  memory;
546    FT_Long    base_file_len = (FT_Long)ft_strlen( base_file_name );
547
548    FT_UNUSED( stream );
549
550
551    memory = library->memory;
552
553    if ( base_file_len + 18 > FT_INT_MAX )
554      return FT_THROW( Array_Too_Large );
555
556    if ( FT_ALLOC( newpath, base_file_len + 18 ) )
557      return error;
558
559    FT_MEM_COPY( newpath, base_file_name, base_file_len );
560    FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 );
561
562    *result_file_name = newpath;
563    *result_offset    = 0;
564
565    return FT_Err_Ok;
566  }
567
568
569  static FT_Error
570  raccess_guess_vfat( FT_Library  library,
571                      FT_Stream   stream,
572                      char       *base_file_name,
573                      char      **result_file_name,
574                      FT_Long    *result_offset )
575  {
576    char*      newpath;
577    FT_Memory  memory;
578
579    FT_UNUSED( stream );
580
581
582    memory = library->memory;
583
584    newpath = raccess_make_file_name( memory, base_file_name,
585                                      "resource.frk/" );
586    if ( !newpath )
587      return FT_THROW( Out_Of_Memory );
588
589    *result_file_name = newpath;
590    *result_offset    = 0;
591
592    return FT_Err_Ok;
593  }
594
595
596  static FT_Error
597  raccess_guess_linux_cap( FT_Library  library,
598                           FT_Stream   stream,
599                           char       *base_file_name,
600                           char      **result_file_name,
601                           FT_Long    *result_offset )
602  {
603    char*      newpath;
604    FT_Memory  memory;
605
606    FT_UNUSED( stream );
607
608
609    memory = library->memory;
610
611    newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
612    if ( !newpath )
613      return FT_THROW( Out_Of_Memory );
614
615    *result_file_name = newpath;
616    *result_offset    = 0;
617
618    return FT_Err_Ok;
619  }
620
621
622  static FT_Error
623  raccess_guess_linux_double( FT_Library  library,
624                              FT_Stream   stream,
625                              char       *base_file_name,
626                              char      **result_file_name,
627                              FT_Long    *result_offset )
628  {
629    char*      newpath;
630    FT_Error   error;
631    FT_Memory  memory;
632
633    FT_UNUSED( stream );
634
635
636    memory = library->memory;
637
638    newpath = raccess_make_file_name( memory, base_file_name, "%" );
639    if ( !newpath )
640      return FT_THROW( Out_Of_Memory );
641
642    error = raccess_guess_linux_double_from_file_name( library, newpath,
643                                                       result_offset );
644    if ( !error )
645      *result_file_name = newpath;
646    else
647      FT_FREE( newpath );
648
649    return error;
650  }
651
652
653  static FT_Error
654  raccess_guess_linux_netatalk( FT_Library  library,
655                                FT_Stream   stream,
656                                char       *base_file_name,
657                                char      **result_file_name,
658                                FT_Long    *result_offset )
659  {
660    char*      newpath;
661    FT_Error   error;
662    FT_Memory  memory;
663
664    FT_UNUSED( stream );
665
666
667    memory = library->memory;
668
669    newpath = raccess_make_file_name( memory, base_file_name,
670                                      ".AppleDouble/" );
671    if ( !newpath )
672      return FT_THROW( Out_Of_Memory );
673
674    error = raccess_guess_linux_double_from_file_name( library, newpath,
675                                                       result_offset );
676    if ( !error )
677      *result_file_name = newpath;
678    else
679      FT_FREE( newpath );
680
681    return error;
682  }
683
684
685  static FT_Error
686  raccess_guess_apple_generic( FT_Library  library,
687                               FT_Stream   stream,
688                               char       *base_file_name,
689                               FT_Int32    magic,
690                               FT_Long    *result_offset )
691  {
692    FT_Int32   magic_from_stream;
693    FT_Error   error;
694    FT_Int32   version_number = 0;
695    FT_UShort  n_of_entries;
696
697    int        i;
698    FT_UInt32  entry_id, entry_offset, entry_length = 0;
699
700    const FT_UInt32  resource_fork_entry_id = 0x2;
701
702    FT_UNUSED( library );
703    FT_UNUSED( base_file_name );
704    FT_UNUSED( version_number );
705    FT_UNUSED( entry_length   );
706
707
708    if ( FT_READ_LONG( magic_from_stream ) )
709      return error;
710    if ( magic_from_stream != magic )
711      return FT_THROW( Unknown_File_Format );
712
713    if ( FT_READ_LONG( version_number ) )
714      return error;
715
716    /* filler */
717    error = FT_Stream_Skip( stream, 16 );
718    if ( error )
719      return error;
720
721    if ( FT_READ_USHORT( n_of_entries ) )
722      return error;
723    if ( n_of_entries == 0 )
724      return FT_THROW( Unknown_File_Format );
725
726    for ( i = 0; i < n_of_entries; i++ )
727    {
728      if ( FT_READ_LONG( entry_id ) )
729        return error;
730      if ( entry_id == resource_fork_entry_id )
731      {
732        if ( FT_READ_LONG( entry_offset ) ||
733             FT_READ_LONG( entry_length ) )
734          continue;
735        *result_offset = entry_offset;
736
737        return FT_Err_Ok;
738      }
739      else
740      {
741        error = FT_Stream_Skip( stream, 4 + 4 );    /* offset + length */
742        if ( error )
743          return error;
744      }
745    }
746
747    return FT_THROW( Unknown_File_Format );
748  }
749
750
751  static FT_Error
752  raccess_guess_linux_double_from_file_name( FT_Library  library,
753                                             char       *file_name,
754                                             FT_Long    *result_offset )
755  {
756    FT_Open_Args  args2;
757    FT_Stream     stream2;
758    char *        nouse = NULL;
759    FT_Error      error;
760
761
762    args2.flags    = FT_OPEN_PATHNAME;
763    args2.pathname = file_name;
764    error = FT_Stream_New( library, &args2, &stream2 );
765    if ( error )
766      return error;
767
768    error = raccess_guess_apple_double( library, stream2, file_name,
769                                        &nouse, result_offset );
770
771    FT_Stream_Free( stream2, 0 );
772
773    return error;
774  }
775
776
777  static char*
778  raccess_make_file_name( FT_Memory    memory,
779                          const char  *original_name,
780                          const char  *insertion )
781  {
782    char*        new_name = NULL;
783    const char*  tmp;
784    const char*  slash;
785    size_t       new_length;
786    FT_Error     error = FT_Err_Ok;
787
788    FT_UNUSED( error );
789
790
791    new_length = ft_strlen( original_name ) + ft_strlen( insertion );
792    if ( FT_ALLOC( new_name, new_length + 1 ) )
793      return NULL;
794
795    tmp = ft_strrchr( original_name, '/' );
796    if ( tmp )
797    {
798      ft_strncpy( new_name, original_name, tmp - original_name + 1 );
799      new_name[tmp - original_name + 1] = '\0';
800      slash = tmp + 1;
801    }
802    else
803    {
804      slash       = original_name;
805      new_name[0] = '\0';
806    }
807
808    ft_strcat( new_name, insertion );
809    ft_strcat( new_name, slash );
810
811    return new_name;
812  }
813
814
815#else   /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
816
817
818  /*************************************************************************/
819  /*                  Dummy function; just sets errors                     */
820  /*************************************************************************/
821
822  FT_BASE_DEF( void )
823  FT_Raccess_Guess( FT_Library  library,
824                    FT_Stream   stream,
825                    char       *base_name,
826                    char      **new_names,
827                    FT_Long    *offsets,
828                    FT_Error   *errors )
829  {
830    FT_Int  i;
831
832    FT_UNUSED( library );
833    FT_UNUSED( stream );
834    FT_UNUSED( base_name );
835
836
837    for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
838    {
839      new_names[i] = NULL;
840      offsets[i]   = 0;
841      errors[i]    = FT_ERR( Unimplemented_Feature );
842    }
843  }
844
845
846#endif  /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
847
848
849/* END */
850