• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /***************************************************************************/
2 /*                                                                         */
3 /*  ftrfork.c                                                              */
4 /*                                                                         */
5 /*    Embedded resource forks accessor (body).                             */
6 /*                                                                         */
7 /*  Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 #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 )
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 = 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_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   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 )
FT_Raccess_Guess(FT_Library library,FT_Stream stream,char * base_name,char ** new_names,FT_Long * offsets,FT_Error * errors)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_Long  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
raccess_get_rule_type_from_rule_index(FT_Library library,FT_UInt rule_index)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 )
ft_raccess_rule_by_darwin_vfs(FT_Library library,FT_UInt rule_index)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
raccess_guess_apple_double(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_Err_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
raccess_guess_apple_single(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_Err_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
raccess_guess_darwin_ufs_export(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_Err_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
raccess_guess_darwin_hfsplus(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_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_Err_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
raccess_guess_darwin_newvfs(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_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_Err_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
raccess_guess_vfat(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_Err_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
raccess_guess_linux_cap(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_Err_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
raccess_guess_linux_double(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_Err_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
raccess_guess_linux_netatalk(FT_Library library,FT_Stream stream,char * base_file_name,char ** result_file_name,FT_Long * result_offset)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_Err_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
raccess_guess_apple_generic(FT_Library library,FT_Stream stream,char * base_file_name,FT_Int32 magic,FT_Long * result_offset)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_Err_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_Err_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_Err_Unknown_File_Format;
748   }
749 
750 
751   static FT_Error
raccess_guess_linux_double_from_file_name(FT_Library library,char * file_name,FT_Long * result_offset)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*
raccess_make_file_name(FT_Memory memory,const char * original_name,const char * insertion)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 )
FT_Raccess_Guess(FT_Library library,FT_Stream stream,char * base_name,char ** new_names,FT_Long * offsets,FT_Error * errors)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     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