/src/freetype/src/base/ftrfork.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 849 lines · 591 code · 183 blank · 75 comment · 77 complexity · 2fae34f9356c43374984eda1b3697dbc MD5 · raw file

  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. /* Development of the code in this file is support of */
  22. /* Information-technology Promotion Agency, Japan. */
  23. /***************************************************************************/
  24. #include <ft2build.h>
  25. #include FT_INTERNAL_DEBUG_H
  26. #include FT_INTERNAL_STREAM_H
  27. #include FT_INTERNAL_RFORK_H
  28. #include "basepic.h"
  29. #undef FT_COMPONENT
  30. #define FT_COMPONENT trace_raccess
  31. /*************************************************************************/
  32. /*************************************************************************/
  33. /*************************************************************************/
  34. /**** ****/
  35. /**** ****/
  36. /**** Resource fork directory access ****/
  37. /**** ****/
  38. /**** ****/
  39. /*************************************************************************/
  40. /*************************************************************************/
  41. /*************************************************************************/
  42. FT_BASE_DEF( FT_Error )
  43. FT_Raccess_Get_HeaderInfo( FT_Library library,
  44. FT_Stream stream,
  45. FT_Long rfork_offset,
  46. FT_Long *map_offset,
  47. FT_Long *rdata_pos )
  48. {
  49. FT_Error error;
  50. unsigned char head[16], head2[16];
  51. FT_Long map_pos, rdata_len;
  52. int allzeros, allmatch, i;
  53. FT_Long type_list;
  54. FT_UNUSED( library );
  55. error = FT_Stream_Seek( stream, rfork_offset );
  56. if ( error )
  57. return error;
  58. error = FT_Stream_Read( stream, (FT_Byte *)head, 16 );
  59. if ( error )
  60. return error;
  61. *rdata_pos = rfork_offset + ( ( head[0] << 24 ) |
  62. ( head[1] << 16 ) |
  63. ( head[2] << 8 ) |
  64. head[3] );
  65. map_pos = rfork_offset + ( ( head[4] << 24 ) |
  66. ( head[5] << 16 ) |
  67. ( head[6] << 8 ) |
  68. head[7] );
  69. rdata_len = ( head[ 8] << 24 ) |
  70. ( head[ 9] << 16 ) |
  71. ( head[10] << 8 ) |
  72. head[11];
  73. /* map_len = head[12] .. head[15] */
  74. if ( *rdata_pos + rdata_len != map_pos || map_pos == rfork_offset )
  75. return FT_Err_Unknown_File_Format;
  76. error = FT_Stream_Seek( stream, map_pos );
  77. if ( error )
  78. return error;
  79. head2[15] = (FT_Byte)( head[15] + 1 ); /* make it be different */
  80. error = FT_Stream_Read( stream, (FT_Byte*)head2, 16 );
  81. if ( error )
  82. return error;
  83. allzeros = 1;
  84. allmatch = 1;
  85. for ( i = 0; i < 16; ++i )
  86. {
  87. if ( head2[i] != 0 )
  88. allzeros = 0;
  89. if ( head2[i] != head[i] )
  90. allmatch = 0;
  91. }
  92. if ( !allzeros && !allmatch )
  93. return FT_Err_Unknown_File_Format;
  94. /* If we have reached this point then it is probably a mac resource */
  95. /* file. Now, does it contain any interesting resources? */
  96. /* Skip handle to next resource map, the file resource number, and */
  97. /* attributes. */
  98. (void)FT_STREAM_SKIP( 4 /* skip handle to next resource map */
  99. + 2 /* skip file resource number */
  100. + 2 ); /* skip attributes */
  101. if ( FT_READ_USHORT( type_list ) )
  102. return error;
  103. if ( type_list == -1 )
  104. return FT_Err_Unknown_File_Format;
  105. error = FT_Stream_Seek( stream, map_pos + type_list );
  106. if ( error )
  107. return error;
  108. *map_offset = map_pos + type_list;
  109. return FT_Err_Ok;
  110. }
  111. static int
  112. ft_raccess_sort_ref_by_id( FT_RFork_Ref* a,
  113. FT_RFork_Ref* b )
  114. {
  115. if ( a->res_id < b->res_id )
  116. return -1;
  117. else if ( a->res_id > b->res_id )
  118. return 1;
  119. else
  120. return 0;
  121. }
  122. FT_BASE_DEF( FT_Error )
  123. FT_Raccess_Get_DataOffsets( FT_Library library,
  124. FT_Stream stream,
  125. FT_Long map_offset,
  126. FT_Long rdata_pos,
  127. FT_Long tag,
  128. FT_Long **offsets,
  129. FT_Long *count )
  130. {
  131. FT_Error error;
  132. int i, j, cnt, subcnt;
  133. FT_Long tag_internal, rpos;
  134. FT_Memory memory = library->memory;
  135. FT_Long temp;
  136. FT_Long *offsets_internal = NULL;
  137. FT_RFork_Ref *ref = NULL;
  138. error = FT_Stream_Seek( stream, map_offset );
  139. if ( error )
  140. return error;
  141. if ( FT_READ_USHORT( cnt ) )
  142. return error;
  143. cnt++;
  144. for ( i = 0; i < cnt; ++i )
  145. {
  146. if ( FT_READ_LONG( tag_internal ) ||
  147. FT_READ_USHORT( subcnt ) ||
  148. FT_READ_USHORT( rpos ) )
  149. return error;
  150. FT_TRACE2(( "Resource tags: %c%c%c%c\n",
  151. (char)( 0xff & ( tag_internal >> 24 ) ),
  152. (char)( 0xff & ( tag_internal >> 16 ) ),
  153. (char)( 0xff & ( tag_internal >> 8 ) ),
  154. (char)( 0xff & ( tag_internal >> 0 ) ) ));
  155. if ( tag_internal == tag )
  156. {
  157. *count = subcnt + 1;
  158. rpos += map_offset;
  159. error = FT_Stream_Seek( stream, rpos );
  160. if ( error )
  161. return error;
  162. if ( FT_NEW_ARRAY( ref, *count ) )
  163. return error;
  164. for ( j = 0; j < *count; ++j )
  165. {
  166. if ( FT_READ_USHORT( ref[j].res_id ) )
  167. goto Exit;
  168. if ( FT_STREAM_SKIP( 2 ) ) /* resource name */
  169. goto Exit;
  170. if ( FT_READ_LONG( temp ) )
  171. goto Exit;
  172. if ( FT_STREAM_SKIP( 4 ) ) /* mbz */
  173. goto Exit;
  174. ref[j].offset = temp & 0xFFFFFFL;
  175. }
  176. ft_qsort( ref, *count, sizeof ( FT_RFork_Ref ),
  177. ( int(*)(const void*, const void*) )
  178. ft_raccess_sort_ref_by_id );
  179. if ( FT_NEW_ARRAY( offsets_internal, *count ) )
  180. goto Exit;
  181. /* XXX: duplicated reference ID,
  182. * gap between reference IDs are acceptable?
  183. * further investigation on Apple implementation is needed.
  184. */
  185. for ( j = 0; j < *count; ++j )
  186. offsets_internal[j] = rdata_pos + ref[j].offset;
  187. *offsets = offsets_internal;
  188. error = FT_Err_Ok;
  189. Exit:
  190. FT_FREE( ref );
  191. return error;
  192. }
  193. }
  194. return FT_Err_Cannot_Open_Resource;
  195. }
  196. #ifdef FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
  197. /*************************************************************************/
  198. /*************************************************************************/
  199. /*************************************************************************/
  200. /**** ****/
  201. /**** ****/
  202. /**** Guessing functions ****/
  203. /**** ****/
  204. /**** When you add a new guessing function, ****/
  205. /**** update FT_RACCESS_N_RULES in ftrfork.h. ****/
  206. /**** ****/
  207. /*************************************************************************/
  208. /*************************************************************************/
  209. /*************************************************************************/
  210. static FT_Error
  211. raccess_guess_apple_double( FT_Library library,
  212. FT_Stream stream,
  213. char *base_file_name,
  214. char **result_file_name,
  215. FT_Long *result_offset );
  216. static FT_Error
  217. raccess_guess_apple_single( FT_Library library,
  218. FT_Stream stream,
  219. char *base_file_name,
  220. char **result_file_name,
  221. FT_Long *result_offset );
  222. static FT_Error
  223. raccess_guess_darwin_ufs_export( FT_Library library,
  224. FT_Stream stream,
  225. char *base_file_name,
  226. char **result_file_name,
  227. FT_Long *result_offset );
  228. static FT_Error
  229. raccess_guess_darwin_newvfs( FT_Library library,
  230. FT_Stream stream,
  231. char *base_file_name,
  232. char **result_file_name,
  233. FT_Long *result_offset );
  234. static FT_Error
  235. raccess_guess_darwin_hfsplus( FT_Library library,
  236. FT_Stream stream,
  237. char *base_file_name,
  238. char **result_file_name,
  239. FT_Long *result_offset );
  240. static FT_Error
  241. raccess_guess_vfat( FT_Library library,
  242. FT_Stream stream,
  243. char *base_file_name,
  244. char **result_file_name,
  245. FT_Long *result_offset );
  246. static FT_Error
  247. raccess_guess_linux_cap( FT_Library library,
  248. FT_Stream stream,
  249. char *base_file_name,
  250. char **result_file_name,
  251. FT_Long *result_offset );
  252. static FT_Error
  253. raccess_guess_linux_double( FT_Library library,
  254. FT_Stream stream,
  255. char *base_file_name,
  256. char **result_file_name,
  257. FT_Long *result_offset );
  258. static FT_Error
  259. raccess_guess_linux_netatalk( FT_Library library,
  260. FT_Stream stream,
  261. char *base_file_name,
  262. char **result_file_name,
  263. FT_Long *result_offset );
  264. CONST_FT_RFORK_RULE_ARRAY_BEGIN(ft_raccess_guess_table,
  265. ft_raccess_guess_rec)
  266. CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_double, apple_double)
  267. CONST_FT_RFORK_RULE_ARRAY_ENTRY(apple_single, apple_single)
  268. CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_ufs_export, darwin_ufs_export)
  269. CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_newvfs, darwin_newvfs)
  270. CONST_FT_RFORK_RULE_ARRAY_ENTRY(darwin_hfsplus, darwin_hfsplus)
  271. CONST_FT_RFORK_RULE_ARRAY_ENTRY(vfat, vfat)
  272. CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_cap, linux_cap)
  273. CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_double, linux_double)
  274. CONST_FT_RFORK_RULE_ARRAY_ENTRY(linux_netatalk, linux_netatalk)
  275. CONST_FT_RFORK_RULE_ARRAY_END
  276. /*************************************************************************/
  277. /**** ****/
  278. /**** Helper functions ****/
  279. /**** ****/
  280. /*************************************************************************/
  281. static FT_Error
  282. raccess_guess_apple_generic( FT_Library library,
  283. FT_Stream stream,
  284. char *base_file_name,
  285. FT_Int32 magic,
  286. FT_Long *result_offset );
  287. static FT_Error
  288. raccess_guess_linux_double_from_file_name( FT_Library library,
  289. char * file_name,
  290. FT_Long *result_offset );
  291. static char *
  292. raccess_make_file_name( FT_Memory memory,
  293. const char *original_name,
  294. const char *insertion );
  295. FT_BASE_DEF( void )
  296. FT_Raccess_Guess( FT_Library library,
  297. FT_Stream stream,
  298. char* base_name,
  299. char **new_names,
  300. FT_Long *offsets,
  301. FT_Error *errors )
  302. {
  303. FT_Long i;
  304. for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
  305. {
  306. new_names[i] = NULL;
  307. if ( NULL != stream )
  308. errors[i] = FT_Stream_Seek( stream, 0 );
  309. else
  310. errors[i] = FT_Err_Ok;
  311. if ( errors[i] )
  312. continue ;
  313. errors[i] = (FT_RACCESS_GUESS_TABLE_GET[i].func)( library,
  314. stream, base_name,
  315. &(new_names[i]),
  316. &(offsets[i]) );
  317. }
  318. return;
  319. }
  320. #ifndef FT_MACINTOSH
  321. static FT_RFork_Rule
  322. raccess_get_rule_type_from_rule_index( FT_Library library,
  323. FT_UInt rule_index )
  324. {
  325. FT_UNUSED( library );
  326. if ( rule_index >= FT_RACCESS_N_RULES )
  327. return FT_RFork_Rule_invalid;
  328. return FT_RACCESS_GUESS_TABLE_GET[rule_index].type;
  329. }
  330. /*
  331. * For this function, refer ftbase.h.
  332. */
  333. FT_LOCAL_DEF( FT_Bool )
  334. ft_raccess_rule_by_darwin_vfs( FT_Library library,
  335. FT_UInt rule_index )
  336. {
  337. switch( raccess_get_rule_type_from_rule_index( library, rule_index ) )
  338. {
  339. case FT_RFork_Rule_darwin_newvfs:
  340. case FT_RFork_Rule_darwin_hfsplus:
  341. return TRUE;
  342. default:
  343. return FALSE;
  344. }
  345. }
  346. #endif
  347. static FT_Error
  348. raccess_guess_apple_double( FT_Library library,
  349. FT_Stream stream,
  350. char *base_file_name,
  351. char **result_file_name,
  352. FT_Long *result_offset )
  353. {
  354. FT_Int32 magic = ( 0x00 << 24 ) |
  355. ( 0x05 << 16 ) |
  356. ( 0x16 << 8 ) |
  357. 0x07;
  358. *result_file_name = NULL;
  359. if ( NULL == stream )
  360. return FT_Err_Cannot_Open_Stream;
  361. return raccess_guess_apple_generic( library, stream, base_file_name,
  362. magic, result_offset );
  363. }
  364. static FT_Error
  365. raccess_guess_apple_single( FT_Library library,
  366. FT_Stream stream,
  367. char *base_file_name,
  368. char **result_file_name,
  369. FT_Long *result_offset )
  370. {
  371. FT_Int32 magic = ( 0x00 << 24 ) |
  372. ( 0x05 << 16 ) |
  373. ( 0x16 << 8 ) |
  374. 0x00;
  375. *result_file_name = NULL;
  376. if ( NULL == stream )
  377. return FT_Err_Cannot_Open_Stream;
  378. return raccess_guess_apple_generic( library, stream, base_file_name,
  379. magic, result_offset );
  380. }
  381. static FT_Error
  382. raccess_guess_darwin_ufs_export( FT_Library library,
  383. FT_Stream stream,
  384. char *base_file_name,
  385. char **result_file_name,
  386. FT_Long *result_offset )
  387. {
  388. char* newpath;
  389. FT_Error error;
  390. FT_Memory memory;
  391. FT_UNUSED( stream );
  392. memory = library->memory;
  393. newpath = raccess_make_file_name( memory, base_file_name, "._" );
  394. if ( !newpath )
  395. return FT_Err_Out_Of_Memory;
  396. error = raccess_guess_linux_double_from_file_name( library, newpath,
  397. result_offset );
  398. if ( !error )
  399. *result_file_name = newpath;
  400. else
  401. FT_FREE( newpath );
  402. return error;
  403. }
  404. static FT_Error
  405. raccess_guess_darwin_hfsplus( FT_Library library,
  406. FT_Stream stream,
  407. char *base_file_name,
  408. char **result_file_name,
  409. FT_Long *result_offset )
  410. {
  411. /*
  412. Only meaningful on systems with hfs+ drivers (or Macs).
  413. */
  414. FT_Error error;
  415. char* newpath = NULL;
  416. FT_Memory memory;
  417. FT_Long base_file_len = ft_strlen( base_file_name );
  418. FT_UNUSED( stream );
  419. memory = library->memory;
  420. if ( base_file_len + 6 > FT_INT_MAX )
  421. return FT_Err_Array_Too_Large;
  422. if ( FT_ALLOC( newpath, base_file_len + 6 ) )
  423. return error;
  424. FT_MEM_COPY( newpath, base_file_name, base_file_len );
  425. FT_MEM_COPY( newpath + base_file_len, "/rsrc", 6 );
  426. *result_file_name = newpath;
  427. *result_offset = 0;
  428. return FT_Err_Ok;
  429. }
  430. static FT_Error
  431. raccess_guess_darwin_newvfs( FT_Library library,
  432. FT_Stream stream,
  433. char *base_file_name,
  434. char **result_file_name,
  435. FT_Long *result_offset )
  436. {
  437. /*
  438. Only meaningful on systems with Mac OS X (> 10.1).
  439. */
  440. FT_Error error;
  441. char* newpath = NULL;
  442. FT_Memory memory;
  443. FT_Long base_file_len = ft_strlen( base_file_name );
  444. FT_UNUSED( stream );
  445. memory = library->memory;
  446. if ( base_file_len + 18 > FT_INT_MAX )
  447. return FT_Err_Array_Too_Large;
  448. if ( FT_ALLOC( newpath, base_file_len + 18 ) )
  449. return error;
  450. FT_MEM_COPY( newpath, base_file_name, base_file_len );
  451. FT_MEM_COPY( newpath + base_file_len, "/..namedfork/rsrc", 18 );
  452. *result_file_name = newpath;
  453. *result_offset = 0;
  454. return FT_Err_Ok;
  455. }
  456. static FT_Error
  457. raccess_guess_vfat( FT_Library library,
  458. FT_Stream stream,
  459. char *base_file_name,
  460. char **result_file_name,
  461. FT_Long *result_offset )
  462. {
  463. char* newpath;
  464. FT_Memory memory;
  465. FT_UNUSED( stream );
  466. memory = library->memory;
  467. newpath = raccess_make_file_name( memory, base_file_name,
  468. "resource.frk/" );
  469. if ( !newpath )
  470. return FT_Err_Out_Of_Memory;
  471. *result_file_name = newpath;
  472. *result_offset = 0;
  473. return FT_Err_Ok;
  474. }
  475. static FT_Error
  476. raccess_guess_linux_cap( FT_Library library,
  477. FT_Stream stream,
  478. char *base_file_name,
  479. char **result_file_name,
  480. FT_Long *result_offset )
  481. {
  482. char* newpath;
  483. FT_Memory memory;
  484. FT_UNUSED( stream );
  485. memory = library->memory;
  486. newpath = raccess_make_file_name( memory, base_file_name, ".resource/" );
  487. if ( !newpath )
  488. return FT_Err_Out_Of_Memory;
  489. *result_file_name = newpath;
  490. *result_offset = 0;
  491. return FT_Err_Ok;
  492. }
  493. static FT_Error
  494. raccess_guess_linux_double( FT_Library library,
  495. FT_Stream stream,
  496. char *base_file_name,
  497. char **result_file_name,
  498. FT_Long *result_offset )
  499. {
  500. char* newpath;
  501. FT_Error error;
  502. FT_Memory memory;
  503. FT_UNUSED( stream );
  504. memory = library->memory;
  505. newpath = raccess_make_file_name( memory, base_file_name, "%" );
  506. if ( !newpath )
  507. return FT_Err_Out_Of_Memory;
  508. error = raccess_guess_linux_double_from_file_name( library, newpath,
  509. result_offset );
  510. if ( !error )
  511. *result_file_name = newpath;
  512. else
  513. FT_FREE( newpath );
  514. return error;
  515. }
  516. static FT_Error
  517. raccess_guess_linux_netatalk( FT_Library library,
  518. FT_Stream stream,
  519. char *base_file_name,
  520. char **result_file_name,
  521. FT_Long *result_offset )
  522. {
  523. char* newpath;
  524. FT_Error error;
  525. FT_Memory memory;
  526. FT_UNUSED( stream );
  527. memory = library->memory;
  528. newpath = raccess_make_file_name( memory, base_file_name,
  529. ".AppleDouble/" );
  530. if ( !newpath )
  531. return FT_Err_Out_Of_Memory;
  532. error = raccess_guess_linux_double_from_file_name( library, newpath,
  533. result_offset );
  534. if ( !error )
  535. *result_file_name = newpath;
  536. else
  537. FT_FREE( newpath );
  538. return error;
  539. }
  540. static FT_Error
  541. raccess_guess_apple_generic( FT_Library library,
  542. FT_Stream stream,
  543. char *base_file_name,
  544. FT_Int32 magic,
  545. FT_Long *result_offset )
  546. {
  547. FT_Int32 magic_from_stream;
  548. FT_Error error;
  549. FT_Int32 version_number = 0;
  550. FT_UShort n_of_entries;
  551. int i;
  552. FT_UInt32 entry_id, entry_offset, entry_length = 0;
  553. const FT_UInt32 resource_fork_entry_id = 0x2;
  554. FT_UNUSED( library );
  555. FT_UNUSED( base_file_name );
  556. FT_UNUSED( version_number );
  557. FT_UNUSED( entry_length );
  558. if ( FT_READ_LONG( magic_from_stream ) )
  559. return error;
  560. if ( magic_from_stream != magic )
  561. return FT_Err_Unknown_File_Format;
  562. if ( FT_READ_LONG( version_number ) )
  563. return error;
  564. /* filler */
  565. error = FT_Stream_Skip( stream, 16 );
  566. if ( error )
  567. return error;
  568. if ( FT_READ_USHORT( n_of_entries ) )
  569. return error;
  570. if ( n_of_entries == 0 )
  571. return FT_Err_Unknown_File_Format;
  572. for ( i = 0; i < n_of_entries; i++ )
  573. {
  574. if ( FT_READ_LONG( entry_id ) )
  575. return error;
  576. if ( entry_id == resource_fork_entry_id )
  577. {
  578. if ( FT_READ_LONG( entry_offset ) ||
  579. FT_READ_LONG( entry_length ) )
  580. continue;
  581. *result_offset = entry_offset;
  582. return FT_Err_Ok;
  583. }
  584. else
  585. {
  586. error = FT_Stream_Skip( stream, 4 + 4 ); /* offset + length */
  587. if ( error )
  588. return error;
  589. }
  590. }
  591. return FT_Err_Unknown_File_Format;
  592. }
  593. static FT_Error
  594. raccess_guess_linux_double_from_file_name( FT_Library library,
  595. char *file_name,
  596. FT_Long *result_offset )
  597. {
  598. FT_Open_Args args2;
  599. FT_Stream stream2;
  600. char * nouse = NULL;
  601. FT_Error error;
  602. args2.flags = FT_OPEN_PATHNAME;
  603. args2.pathname = file_name;
  604. error = FT_Stream_New( library, &args2, &stream2 );
  605. if ( error )
  606. return error;
  607. error = raccess_guess_apple_double( library, stream2, file_name,
  608. &nouse, result_offset );
  609. FT_Stream_Free( stream2, 0 );
  610. return error;
  611. }
  612. static char*
  613. raccess_make_file_name( FT_Memory memory,
  614. const char *original_name,
  615. const char *insertion )
  616. {
  617. char* new_name = NULL;
  618. const char* tmp;
  619. const char* slash;
  620. size_t new_length;
  621. FT_Error error = FT_Err_Ok;
  622. FT_UNUSED( error );
  623. new_length = ft_strlen( original_name ) + ft_strlen( insertion );
  624. if ( FT_ALLOC( new_name, new_length + 1 ) )
  625. return NULL;
  626. tmp = ft_strrchr( original_name, '/' );
  627. if ( tmp )
  628. {
  629. ft_strncpy( new_name, original_name, tmp - original_name + 1 );
  630. new_name[tmp - original_name + 1] = '\0';
  631. slash = tmp + 1;
  632. }
  633. else
  634. {
  635. slash = original_name;
  636. new_name[0] = '\0';
  637. }
  638. ft_strcat( new_name, insertion );
  639. ft_strcat( new_name, slash );
  640. return new_name;
  641. }
  642. #else /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
  643. /*************************************************************************/
  644. /* Dummy function; just sets errors */
  645. /*************************************************************************/
  646. FT_BASE_DEF( void )
  647. FT_Raccess_Guess( FT_Library library,
  648. FT_Stream stream,
  649. char *base_name,
  650. char **new_names,
  651. FT_Long *offsets,
  652. FT_Error *errors )
  653. {
  654. int i;
  655. FT_UNUSED( library );
  656. FT_UNUSED( stream );
  657. FT_UNUSED( base_name );
  658. for ( i = 0; i < FT_RACCESS_N_RULES; i++ )
  659. {
  660. new_names[i] = NULL;
  661. offsets[i] = 0;
  662. errors[i] = FT_Err_Unimplemented_Feature;
  663. }
  664. }
  665. #endif /* !FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK */
  666. /* END */