21f92ddceebd57aede79a58f860d66f330cd65e3
[oweals/cde.git] / cde / programs / dtudcfonted / libfuty / getfname.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: getfname.c /main/9 1996/11/08 02:06:43 cde-fuj $ */
24 /*
25  *  (c) Copyright 1995 FUJITSU LIMITED
26  *  This is source code modified by FUJITSU LIMITED under the Joint
27  *  Development Agreement for the CDEnext PST.
28  *  This is unpublished proprietary source code of FUJITSU LIMITED
29  */
30
31
32 #include  <sys/types.h>
33 #include  <sys/stat.h>
34 #include  <locale.h>
35 #include  <unistd.h>
36 #include  <stdio.h>
37 #include  <stdlib.h>
38 #include  <errno.h>
39
40 #include  "FaLib.h"
41 #include  "falfont.h"
42 #include  "udcutil.h"
43
44 #include  <string.h>
45
46 #ifndef SVR4
47 #if !defined( SYSV )
48 #include <sys/resource.h>
49 #endif
50 #ifdef __osf__
51 #define _BSD
52 #endif
53 #include  <sys/wait.h>
54 #ifdef __osf__
55 #undef _BSD
56 #endif
57 #else
58 #include  <wait.h>
59 #endif  /* SVR4 */
60 #include  <signal.h>
61
62 #include  "bdfgpf.h"
63
64 static  void    ErrMsgTable_GetDefaultFile();
65 static  int     falcom_split_data() ;
66 static  void    dsp_font_list() ;
67 static  int     search_Font_File_Name();
68
69 extern  int     searchFontFileName();
70 extern  int     falReadFontProp() ;
71
72 /* 
73  * get "character size" and "letter size" from a character of an interface
74  *
75  *      return code¡§
76  *               1... get "character size"
77  *               2... get "character size" and "letter size"
78  *              -1... NG
79  */
80
81 #define BODY_ONLY       1
82 #define BODY_AND_LETTER 2
83
84 static int
85 GetSize( size_str, body, letter )
86 char    *size_str;      /* a character of a size */
87 int     *body;          /* set "character size" (output) */
88 int     *letter;        /* set "letter size" (output) */
89 {
90         char    *str_dot;
91         /* char *str_end; */
92         int     bdy, ltr;
93
94         str_dot = strchr( size_str, '.');
95         /* str_end = strchr( size_str, '\0'); */
96
97         if ( str_dot == NULL) {
98                 /* change a size of "character size"*/
99                 if (falcom_atoi( size_str, '\0', &bdy ) ==-1) {
100                         return  -1;
101                 }
102                 *body = bdy;
103                 return  BODY_ONLY;
104         }
105
106         /* change a size of "character size"*/
107         if (falcom_atoi( size_str, '.', &bdy ) ==-1) {
108                 return  -1;
109         }
110
111         /* change a size of "letter size"*/
112         str_dot++;
113         if (falcom_atoi( str_dot, '\0', &ltr ) ==-1) {
114                 return  -1;
115         }
116         *body   = bdy;
117         *letter = ltr;
118         return  BODY_AND_LETTER;
119 }
120
121
122 /*
123  *
124  * change numerical character for numarical data
125  *
126  */
127
128 int
129 #if NeedFunctionPrototypes
130 falcom_atoi(
131     char        *str,   /* numerical character */
132     char        ed_code,/* an end code in numerical character */
133     int         *val    /* set numarical data */
134 )
135 #else
136 falcom_atoi(str, ed_code, val)
137 char    *str;   /* numerical character */
138 char    ed_code;/* an end code in numerical character */
139 int     *val;   /* set numarical data */
140 #endif
141 {
142         char    *ptr;
143         char    *str_end;
144         int     tmp;
145
146         /* get an end index */
147         str_end = strchr( str, ed_code );
148
149         /* change numarical data */
150         tmp = (int)strtol(str, &ptr, 10);
151
152         /* error check */
153         if ((ptr == str) || (ptr != str_end)) {
154                 return(-1);
155         }
156         *val = tmp;
157         return  0;
158 }
159
160
161 static int
162 falcom_cr_to_null(buf)
163 char    *buf;
164 {
165         buf = strchr( buf, '\n');
166         if (buf != NULL) {
167                 *buf = '\0';
168         }
169         return  0;
170 }
171
172
173
174 #define FALCOM_DATA_ELM         3
175
176 #define FALCOM_ELM_SIZE         0
177 #define FALCOM_ELM_STYLE        1
178 #define FALCOM_ELM_FNAME        2
179
180
181 int
182 #if NeedFunctionPrototypes
183 GetDefaultFile( 
184     int         size,
185     char        *style,
186     char        *fname
187 )
188 #else
189 GetDefaultFile( size, style, fname )
190 int     size;           /* character size */
191 char    *style;         /* character style */
192 char    *fname;         /* buffer */
193 #endif
194 {
195         FILE    *fp;
196         int     ret;
197
198
199         char    *locale;
200         char    *fal_search_path;
201         char    uflist_d[BUFSIZE];
202         char    uflist_c[ BUFSIZE ];
203         char    uflist_l[ BUFSIZE ];
204
205         GETLISTFILEPATH( locale, fal_search_path, uflist_d, uflist_c, uflist_l, UDFLIST_DEF ) ;
206
207         if ( ( fp = fopen( uflist_l, "r" ) ) == NULL ) {
208             if ( ( fp = fopen( uflist_c, "r" ) ) == NULL ) {
209                 if ( ( fp = fopen( uflist_d, "r" ) ) == NULL ) {
210                     return  FAL_ERROR;
211                 }
212             }
213         }
214
215         ret = get_default_file( fp, size, style, fname );
216         fclose( fp );
217         return  ret;
218 }
219
220
221 int
222 #if NeedFunctionPrototypes
223 get_default_file( 
224     FILE        *fp,
225     int         size,
226     char        *style, 
227     char        *fname  
228 )
229 #else
230 get_default_file( fp, size, style, fname )
231 FILE    *fp;
232 int     size;           /* character size */
233 char    *style;         /* character style */
234 char    *fname;         /* buffer */
235 #endif
236 {
237         char    buf[BUFSIZE];           /* buffer */
238         int     size_tmp;               /* size (read file) */
239         int     ret;
240         char    *elm[FALCOM_DATA_ELM];
241
242         ret = 0;
243
244         /* read from a file */
245         while( fgets(buf, BUFSIZE, fp) != (char *)NULL ) {
246
247                 falcom_cr_to_null( buf );
248                 if ((buf[0] == '#') || (buf[0] == '\0')) {
249                         continue;
250                 }
251                 if (falcom_split_data( buf, FALCOM_DATA_ELM, &elm ) == -1) {
252                         ret = -4;
253                         continue;
254                 }
255                 if (falcom_atoi( elm[FALCOM_ELM_SIZE], '\0', &size_tmp ) == -1) {
256                         ret = -4;
257                         continue;
258                 }
259                 if ( style ) {
260                     if ((size_tmp == size) && !strcmp(elm[FALCOM_ELM_STYLE], style)) {
261                         strcpy( fname, elm[FALCOM_ELM_FNAME] );
262                         fclose( fp );
263                         return  0;
264                     }
265                 }
266         }
267         if (ret != 0) {
268                 return  ret;
269         }
270
271         if ( feof(fp) != 0 ) {
272                 return  -2;
273         }
274         return  -3;
275 }
276
277 /**************************************************************/
278 /* read from a file and divide a data that read from file     */
279 /**************************************************************/
280
281 static int
282 falcom_split_data( buf, entry_num, elm )
283 char    *buf;           /* read a font information character array from a file */
284 int     entry_num;
285 char    *elm[];
286 {
287         int     cnt;            /* counter */
288         int     strtop_flg;     /* flag of a head of a character array */
289
290         /* divide a data */
291         strtop_flg = 1;
292         for (cnt=0  ; *buf != '\0' && cnt < entry_num  ;  buf++){
293                 /* skip a separate character */
294                 if ((*buf == '\t') || (*buf == ' ')) {
295                         /* change NULL */
296                         *buf = '\0';
297                         /* skip a separate character */
298                         do {
299                                 buf++;
300                         } while((*buf == '\t') || (*buf == ' '));
301                         strtop_flg = 1;
302                 }
303                 if (strtop_flg) {
304                         elm[cnt] = buf;
305                         cnt++;
306                         strtop_flg = 0;
307                 }
308         }
309         /* check a data's number */
310         if (cnt != entry_num ) {
311                 return  -1;
312         }
313         return  0;
314 }
315
316
317 char *
318 #if NeedFunctionPrototypes
319 falcom_get_base_name( char      *str )  
320 #else
321 falcom_get_base_name( str )
322 char    *str;   /* a full path character of a file name */
323 #endif
324 {
325         char    *str_slash;
326
327         str_slash = strrchr( str, '/');
328         if ( str_slash == NULL ) {
329                 return  str;
330         }
331         return  ++str_slash;
332 }
333
334
335 static int
336 is_letter_size_not_only_one( lst )
337 FalFontDataList *lst;   /* a font list */
338 {
339         int     i, letter_cmp;
340
341         letter_cmp = lst->list[0].letter.h;
342         for (i=0 ; i < lst->num ; i++) {
343                 if (lst->list[i].letter.h != letter_cmp){
344                         return  1;
345                 }
346         }
347         return  0;
348 }
349
350
351 /* 
352  * get a real file name from a character of "size" and "style"
353  *
354  * return code¡§
355  *               0 ... OK
356  *              -1 ... NG
357  *
358  */
359 int
360 #if NeedFunctionPrototypes
361 GetFileName(
362     char        *com,
363     char        *size_str,
364     char        *style, 
365     int         codeset,
366     char        *ofile  
367 )
368 #else
369 GetFileName(com, size_str, style, codeset, ofile)
370 char    *com;           /* a character of a command name(case error) */
371 char    *size_str;      /* a character of "size" */
372 char    *style;         /* a character of "style" */
373 int     codeset;        /* a codeset */
374 char    *ofile;         /* set a target file name (output) */
375 #endif
376 {
377         int     body, letter;
378         int     size_sw;                /* a size flag */
379         char    buf[BUFSIZE] ;          /* an area for a file name */
380         char    *filename;              /* a pointer for a file name */
381         char    fname[BUFSIZE];         /* a pointer for a file name */
382         FalFontDataList *lst;           /* a font list */
383         FalFontData     key;            /* search an information of a font */
384         unsigned int    mask;           /* search a mask of a font */
385         int     i, ret;
386         struct  stat    statbuf ;
387         char    *locale;
388
389         char    *fal_search_path;
390         char    uflist_d[ BUFSIZE ];
391         char    uflist_c[ BUFSIZE ];
392         char    uflist_l[ BUFSIZE ];
393
394         GETLISTFILEPATH( locale, fal_search_path, uflist_d, uflist_c, uflist_l, UDFLIST_DEF ) ;
395
396         /* change a character of a size */
397         if ((size_sw = GetSize(size_str, &body, &letter)) == -1) {
398                 USAGE2("%s : The specification of the character size is improper.\"%s\"\n",
399                         com, size_str);
400                 return  -1;
401         }
402
403         mask = 0;
404         mask |= FAL_FONT_MASK_UNDEFINED ;
405         mask |= FAL_FONT_MASK_DEFINED ;
406         memset( &key, '\0', sizeof(FalFontData) ) ;
407         /* set information to search fonts */
408
409         key.cd_set = FALGETFALCODESET( codeset ) ;
410         mask |= FAL_FONT_MASK_CODE_SET ;
411
412         switch( size_sw ) {
413         case BODY_AND_LETTER:
414                 key.letter.h  = letter;         
415                 mask |= FAL_FONT_MASK_LETTER_H;
416         case BODY_ONLY:
417                 key.size.h    = body;           
418                 mask |= FAL_FONT_MASK_SIZE_H;
419         }
420
421         /* aet and check an information of a style */
422         COMM_SETSTYLE_TO_FONTDATA( style, key, mask ) ; 
423
424         /* get a font information */
425         if (FalGetFontList( &key, mask, &lst ) == FAL_ERROR ) {
426                 ErrMsgTable_FalGetFontList( com, fal_utyerror, fal_utyderror );
427                 return  -1;
428         }
429
430         if ( lst->num == 0 ) {  
431                 USAGE3("%s : The user defined character of the specified size and style does not exist.\"%s , %s\"\n",
432                         com, size_str, (style)?style:" ");
433                 FalFreeFontList( lst );
434                 return  -1;
435         }
436
437         memset( fname, '\0', sizeof(fname) ) ;
438         switch( size_sw ) {
439         case BODY_ONLY:
440
441             if ( is_letter_size_not_only_one(lst) ) {
442                 ret = GetDefaultFile( key.size.h, style, buf) ; 
443                 if ( ret < 0 ) {
444                     COMM_GET_DEFAULTFILE_ERROR( buf, com, ret, key.size.h, style, uflist_d, uflist_c, uflist_l, statbuf ) ;
445                 }
446                 for ( i = 0 ; i < lst->num; i++ ) {
447                     ret = search_Font_File_Name( lst->list[i], fname );
448                     if ( ret == FAL_ERROR ) {
449                         FalFreeFontList( lst );
450                         return  -1;
451                     }
452                     filename = falcom_get_base_name( fname );
453                     if ( (buf[0] != '\0' && fname[0] != '\0')
454                         && !strcmp( buf, filename ) ) {
455                         strcpy( ofile, fname );
456                         FalFreeFontList( lst );
457                         return  0;
458                     }
459                 }
460                 COMM_DISPERRORFILE( com, lst, style, i, size_str ) ;
461                 FalFreeFontList( lst );
462                 return  -1;
463             }
464
465         case BODY_AND_LETTER:
466                 switch( lst->num ) {
467                 case 1:
468                         ret = search_Font_File_Name( lst->list[0], fname );
469                         if ( ret == FAL_ERROR ) {
470                                 FalFreeFontList( lst );
471                                 return  -1;
472                         }
473                         strcpy( ofile, fname );
474                         FalFreeFontList( lst );
475                         return  0;
476                 default:
477                         ret = GetDefaultFile( key.size.h, style, buf);
478                         if ( ret < 0 ) {
479                                 buf[0]='\0';
480                         }
481                         for( i = 0 ; i < lst->num; i++ ) {
482                             ret = search_Font_File_Name( lst->list[0], fname );
483                             if ( ret == FAL_ERROR ) {
484                                 FalFreeFontList( lst );
485                                 return  -1;
486                             }
487                             filename = falcom_get_base_name( fname );
488                             if ( (buf[0] != '\0' && fname[0] != '\0')
489                                 && !strcmp( buf, filename ) ) {
490                                 strcpy( ofile, fname );
491                                 FalFreeFontList( lst );
492                                 return  0;
493                             }
494                         }
495                         USAGE1("%s : Two or more corresponding user defined characters exist.\n", com);
496                         for ( i = 0 ; i < lst->num; i++ ) {
497                             ret = search_Font_File_Name( lst->list[i], fname );
498                             if ( ret == FAL_ERROR ) {
499                                 FalFreeFontList( lst );
500                                 return  -1;
501                             }
502                             fprintf( stdout, "\t%s\n", fname );
503                         }
504                         FalFreeFontList( lst );
505                         return  -1;
506                 }               /* <--- switch( lst->num ) { */
507         }                       /* <--- switch( size_sw ) { */
508         return -1 ;
509 }
510
511
512 /* take out an error message of "FalGetFontList()" */
513
514 /*
515  * Error messages(by origin)
516  */
517 char    *fal_errmsg_org[0xff] = {
518 /* 0x00 */
519     " ",
520     "Cannot open the font file.",
521     "Cannot read the font file.",
522     "There is no more memory .",
523     "Fatal error occurred.",
524     "The specified font file does not exist.",
525     "This font is not a pcf or snf format.",
526     "Cannot open fonts.list file.",
527     "The format of fonts.list file is illegal.",
528     "The descriptions of the fonts.list file are incorrect.",
529     "The format of fonts.list file is illegal.",
530     "Cannot open fonts.dir file.",
531     "Cannot read fonts.dir file.",
532     "Cannot read font properties.",
533     "Cannot get \"FONT\" property.",
534     "Cannot get \"FAMILY_NAME\" property.",
535 /* 0x10 */
536     "This font file is already opened by other application.",
537     "Cannot lock font file.",
538     "Cannot unlock font file.",
539     "Cannot get lock information from the font file.",
540     "Cannot find the specified font file.",
541     "Cannot read NLS database.",
542     "Cannot get charset names from NLS database.",
543     "Charset name not defined in NLS database.",
544     "The specified font has not been opened.",
545     "Fatal error occurred.",
546     " "," "," "," "," "," ",
547 /* 0x20 */
548     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ", 
549 /* 0x30 */
550     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ", 
551 /* 0x40 */
552     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
553 /* 0x50 */
554     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
555 /* 0x60 */
556     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
557 /* 0x70 */
558     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
559 /* 0x80 */
560     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
561 /* 0x90 */
562     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
563 /* 0xa0 */
564     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
565 /* 0xb0 */
566     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
567 /* 0xc0 */
568     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
569 /* 0xd0 */
570     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
571 /* 0xe0 */
572     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," ",
573 /* 0xf0 */
574     " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
575 } ;
576
577
578 void
579 #if NeedFunctionPrototypes
580 ErrMsgTable_FalGetFontList(
581     char        *com,
582     int         utyerr,
583     int         utyderr
584 )
585 #else
586 ErrMsgTable_FalGetFontList( com, utyerr, utyderr )
587 char    *com;           /* command name */
588 int     utyerr;         /* fal_utyerror */
589 int     utyderr;        /* fal_utyderror */
590 #endif
591 {
592         char    *fontsdir, *locale ;
593
594         if( (locale = (char *)getenv( "LANG" )) == NULL ){
595             locale = "C" ;
596         }
597
598         if( (fontsdir = (char *)getenv( "DTUDCFONTS" )) == NULL ) {
599             fontsdir = DTUDCFONTSLISTDIR ;
600         }
601         switch( utyerr ) {
602         case 1:
603                 if( fal_utyerrno ) {
604                     USAGE2("%s : %s\n", com, fal_errmsg_org[ fal_utyerrno & 0xff ] ) ;
605                     return ;
606                 }
607                 USAGE4("%s : The font directory information file(%s/%s/%s) cannot be opened.\n",
608                         com, fontsdir, locale, FONTS_LIST_FILE ) ;
609                 break;
610         case 2:
611                 USAGE4("%s : Information cannot be read from the font directory information file(%s/%s/%s).\n", com, fontsdir, locale, FONTS_LIST_FILE );
612                 break;
613         case 3:
614                 USAGE1("%s : The work area cannot be secured.\n", com );
615                 break;
616         case 7:
617                 USAGE4("%s :  Abnormality is found in the content of the font directory information file((%s/%s/%s).\n",
618                         com , fontsdir, locale, FONTS_LIST_FILE);
619                 break;
620         case 8:
621                 USAGE4("%s : The font directory information file(%s/%s/%s) cannot be opened.\n",
622                         com , fontsdir, locale, FONTS_LIST_FILE);
623                 break;
624         case 9:
625                 USAGE4("%s : Information cannot be read from the font directory information file(%s/%s/%s).\n",
626                         com , fontsdir, locale, FONTS_LIST_FILE);
627         default:
628                 if( fal_utyerrno ) {
629                     USAGE2("%s : %s\n", com, fal_errmsg_org[ fal_utyerrno & 0xff ] ) ;
630                     return ;
631                 }
632                 USAGE1("%s : Terminates abnormally.\n", com );
633         }
634 }
635
636
637
638 /* take out an error message of "GetDefaultFile()" */
639
640 static void
641 ErrMsgTable_GetDefaultFile( com, ret, size, style, fname )
642 char    *com;                   /* a command name */
643 int     ret;                    /* return code */
644 int     size;                   /* a character size */
645 char    *style;                 /* a character style */
646 char    *fname;                 /* user defined character information file name */
647 {
648         switch (ret) {
649         case -1:
650                 USAGE2("%s : The user defined character information file cannot be opened. \"%s \"\n",
651                         com, fname);
652                 break;
653         case -2:
654                 USAGE4("%s : The representative user defined character of the character size (%d) and style (%s) is not defined.\"%s\"\n",
655                         com, size, (style)?style:" ", fname);
656                 break;
657         case -3:
658                 USAGE2("%s : Information cannot be read from the user defined character information file.\"%s\"\n", com, fname);
659                 break;
660         case -4:
661                 USAGE2("%s : The mistake is found in the description of the user defined character information file. \"%s\"\n", com, fname);
662                 break;
663         }
664 }
665
666
667 /* 
668  * if an end character of a file name is "/",it is cleared
669  *
670  * return code¡§none
671  *      none
672  */
673
674 void
675 #if NeedFunctionPrototypes
676 fal_cut_tailslash( char *name )
677 #else
678 fal_cut_tailslash( name )
679 char *name;
680 #endif
681 {
682         char *p;
683
684         p = strrchr( name, '\0');
685         if (p == NULL) {
686                 return;
687         }
688         for (p-- ; (p>=name) && (*p == '/') ; p--) {
689                 *p = '\0';
690         }
691 }
692
693
694 /* 
695  * get a real file name from a link file name
696  *
697  * return code¡§
698  *      OK¡¡¡¥¡¥a pointer of a file name
699  *      NG¡¡¡¥¡¥NULL
700  *
701  */
702
703 char    *
704 #if NeedFunctionPrototypes
705 GetRealFileName( char   *name )
706 #else
707 GetRealFileName( name )
708 char    *name;
709 #endif
710 {
711         static char     *ret_name ;
712         char    link_name[BUFSIZE];
713         int             len;
714
715         struct stat st;
716
717         AllocString( ret_name, name, NULL ) ;
718         /* strcpy( ret_name, name ) ; */
719         fal_cut_tailslash( ret_name ); /* for example /tmp/aa/ --> /tmp/aa  */
720
721         while ( 1 ) {
722                 if ( lstat( ret_name, &st ) == -1) {
723                         FreeString( ret_name ) ;
724                         return  NULL;
725                 }
726                 errno = 0;
727                 if ( ( len = readlink( ret_name, link_name, BUFSIZE ) ) == -1 ) {
728                         if ( errno == EINVAL ) {
729                                 return( ret_name ) ;
730                                 /* return( strdup( ret_name ) ) ; */
731                         } else {
732                                 FreeString( ret_name ) ;
733                                 return  NULL;
734                         }
735                 }
736                 link_name[len] = '\0';
737                 if ( link_name[0] == '/' ) {
738                         /* strcpy( ret_name, link_name ) ; */
739                         FreeString( ret_name ) ;
740                         AllocString( ret_name, link_name, NULL ) ;
741                 } else {
742                         char    *slash;
743
744                         slash = strrchr( ret_name, '/' );
745                         if (slash != NULL) {
746                                 *slash = '\0';
747                                 fal_cut_tailslash( ret_name );
748                                 ResizeString( ret_name, NULL );
749                                 AddString(ret_name, "/", NULL);
750                         } else {
751                                 /* ret_name[0] = '\0' ; */
752                                 FreeString( ret_name ) ;
753                                 AllocString(ret_name, "/", NULL);
754                         }
755                         /* strcat( ret_name, "/" ) ;
756                         strcat( ret_name, link_name ) ; */
757                         AddString( ret_name, link_name, NULL ) ;
758                 }
759         }
760 }
761
762
763
764 /*
765  *      funtctions for search fonts by XLFD and NLS database
766  */
767
768 int
769 #if NeedFunctionPrototypes
770 IsInRegion(
771     int                 code ,
772     int                 num_gr ,
773     FalGlyphRegion      *gr
774 )
775 #else
776 IsInRegion(code, num_gr, gr)
777 int             code ;
778 int             num_gr ;
779 FalGlyphRegion  *gr ;
780 #endif
781 {
782         int     i ;
783         if( code < MIN_CODE || code > MAX_CODE )        return -1 ;
784         for( i=0; i<num_gr; i++ ) {
785             if( gr[i].start < MIN_CODE || gr[i].end > MAX_CODE )        continue ;
786             if( gr[i].start <= code && gr[i].end >= code )
787                 return 0 ;
788         }
789         return -1 ;
790 }
791
792
793
794
795 static  int
796 search_Font_File_Name( data, fname )
797 FalFontData     data ;
798 char            *fname ;
799 {
800         FalFontID       fid ;
801         FalFontDataList *flist ;
802         int             mask ;
803         char            *tmp_fname ;
804
805         mask = FAL_FONT_MASK_UNDEFINED | FAL_FONT_MASK_DEFINED ;
806
807         if( data.xlfdname )     mask |= FAL_FONT_MASK_XLFDNAME ; 
808         if( data.size.h )       mask |= FAL_FONT_MASK_SIZE_H ;
809         if( data.size.w >= 0 )  mask |= FAL_FONT_MASK_SIZE_W ;
810         if( data.style.name )   mask |= FAL_FONT_MASK_STYLE_NAME ;
811         if( data.cd_set )       mask |= FAL_FONT_MASK_CODE_SET ;
812
813         if( data.letter.w )     mask |= FAL_FONT_MASK_LETTER_W ;
814         if( data.letter.h )     mask |= FAL_FONT_MASK_LETTER_H ;
815         if( data.letter.x )     mask |= FAL_FONT_MASK_LETTER_X ;
816         if( data.letter.y )     mask |= FAL_FONT_MASK_LETTER_Y ;
817
818         if( data.style.def )    mask |= FAL_FONT_MASK_STYLE_DEF ;
819         if( data.shape.name )   mask |= FAL_FONT_MASK_SHAPE_NAME ;
820         if( data.shape.def )    mask |= FAL_FONT_MASK_SHAPE_DEF ;
821         COMM_SBCHR_SETFONTDATA( data, mask ) ;
822         if( data.prm )          mask |= FAL_FONT_MASK_PERMISSION ;
823
824         fid = FalOpenSysFont( &data, mask, &flist ) ;
825         if( fid == 0 ) {
826             memset( fname, '\0', sizeof(fname) ) ;
827             if( flist ){
828                 dsp_font_list( flist ) ;
829                 FalFreeFontList( flist ) ;
830                 return(-1);
831             } else {
832                 switch( fal_utyerror ) {
833                 case _FAL_OPEN_ER :
834                 case _FAL_READ_ER :
835                 case _FAL_STAT_ER :
836                     switch( fal_utyderror ) {
837                     case EACCES :
838                     case ENOENT :
839                         return(0) ;
840                     default :
841                         USAGE3("There is no font file correspond to specified font.\n(%s)\n fal_utyerror = %d fal_utyderror = %d\n",
842                         ((data.xlfdname)?data.xlfdname:"null font name"), fal_utyerror, fal_utyderror ) ;
843                         return(-2) ;
844                     }
845                 case _FAL_MALOC_ER :
846                     USAGE("System call error occured.\n" ) ;
847                     return(-2) ;
848                 default :
849                     USAGE3("There is no font file correspond to specified font.\n(%s)\n fal_utyerror = %d fal_utyderror = %d\n",
850                     ((data.xlfdname)?data.xlfdname:"null font name"), fal_utyerror, fal_utyderror ) ;
851                         return(-2) ;
852                 }
853             }
854         } 
855         if( FalFontIDToFileName( fid, &tmp_fname ) == FAL_ERROR ) {
856             USAGE3("There is no font file correspond to specified font.\n(%s)\n fal_utyerror = %d fal_utyderror = %d\n",
857             ((data.xlfdname)?data.xlfdname:"null font name"), fal_utyerror, fal_utyderror ) ;
858             FalCloseFont( fid ) ;
859             return(-1) ;
860         }
861         strcpy( fname, tmp_fname ) ;
862         FalFree( tmp_fname ) ;
863         FalCloseFont( fid ) ;
864
865         return(0) ;
866 }
867
868
869 int
870 #if NeedFunctionPrototypes
871 GetUdcFileName(
872     char        *com ,
873     int         code_no ,
874     char        *xlfdname ,
875     char        *fname
876 )
877 #else
878 GetUdcFileName( com, code_no, xlfdname, fname )
879 char    *com ;
880 int     code_no ;
881 char    *xlfdname ;
882 char    *fname ;
883 #endif
884 {
885         FalFontData     data ;
886
887         if( !xlfdname || !fname ) {
888             USAGE1("%s: null parameter\n", com ) ;
889             return(-1) ;
890         }
891         memset( &data, '\0', sizeof(FalFontData) ) ;
892         data.size.w = -1 ;
893         data.xlfdname = xlfdname ;
894         data.cd_set = FALGETFALCODESET( code_no ) ;
895         return( search_Font_File_Name( data, fname ) ) ;
896 }
897
898
899 static  void
900 dsp_font_list( flist )
901 FalFontDataList *flist ;
902 {
903         int     i ;
904
905         USAGE(" code set / size / style / xlfd\n" ) ; 
906         USAGE("-------------------------------------------------------\n" ) ; 
907         for( i=0; i<flist->num; i++ ) {
908             USAGE4("\t%d\t%d\t%s\t%s\n", 
909                     FALCODESETTONUM( flist->list[i].cd_set ),
910                     flist->list[i].size.h,
911                     flist->list[i].style.name,
912                     flist->list[i].xlfdname
913                 ) ;
914         }
915 }
916
917
918 int
919 #if NeedFunctionPrototypes
920 GetUdcRegion( 
921     char        *com ,
922     int         codeset ,
923     char        *gpf_file ,
924     int         *num_gr ,
925     FalGlyphRegion      **gr
926 )
927 #else
928 GetUdcRegion( com, codeset, gpf_file, num_gr, gr )
929 char            *com ;
930 int             codeset ;
931 char            *gpf_file ;
932 int             *num_gr ;
933 FalGlyphRegion  **gr ;
934 #endif
935 {
936         FalFontData     fdata ;
937         char    *locale, *char_set, *tmp_gpf ;  
938
939         if( (locale = (char *)getenv( "LANG" )) == NULL ){
940             locale = "C" ;
941         }
942         /* parameter check */
943         if( gpf_file == NULL || gr == NULL ) {
944                 USAGE1("%s : null parameters.\n", com);
945                 return( -1 ) ;
946         }
947
948         /* get font properties */
949         tmp_gpf = (char *)GetRealFileName( gpf_file ) ;
950         if( tmp_gpf == NULL ){
951                 return -1 ;
952         }
953         if( falReadFontProp( tmp_gpf, FAL_FONT_PRM, &fdata, 1 ) ) {
954                 USAGE1("%s : Failed to get font properties.\n", com ) ;
955                 return -1 ;
956         }
957
958         GETCHARSETSTR( char_set, fdata.xlfdname ) ;
959         if( FalGetUDCGIArea( locale, FALGETFALCODESET(codeset), char_set, gr, num_gr ) == FAL_ERROR )
960         {
961                 USAGE3("%s : Failed to get UDC code region. ( code set %d charset %s )\n",
962                                 com, codeset, char_set ) ;
963                 return( -1 );   
964         }
965
966         if( *num_gr == 0 ) {
967                 USAGE3("%s : Failed to get UDC code region. ( code set %d charset %s )\n",
968                                 com, codeset, char_set ) ;
969                 return -1 ;
970         }
971
972         return(0) ;
973 }
974
975
976
977 #define MAX_CODESET     8
978
979 int
980 #if NeedFunctionPrototypes
981 DispUdcCpArea( FILE     *fp )
982 #else
983 DispUdcCpArea( fp )
984 FILE    *fp ;
985 #endif
986 {
987         int     cd_set, j ;
988         FalFontDataList *fls ;
989         FalFontData     fdata ;
990         int             mask ;
991         FalCodeRegion   *cr ;
992         int             num_cr ;
993         char            *locale ;
994
995         if( (locale = (char *)getenv( "LANG" )) == NULL ){
996             locale = "C" ;
997         }
998         memset( &fdata, 0, sizeof(FalFontData) ) ;
999         mask = 0 ;
1000         mask =  FAL_FONT_MASK_DEFINED | FAL_FONT_MASK_UNDEFINED |
1001                 FAL_FONT_MASK_CODE_SET ;
1002
1003         for( cd_set=0; cd_set<MAX_CODESET; cd_set++ ){
1004                 char    *char_set ;
1005                 fdata.cd_set = FALGETFALCODESET(cd_set) ;
1006                 if( FalGetFontList(&fdata, mask, &fls) == FAL_ERROR ){
1007                     return -1 ;
1008                 }
1009                 if( fls->num == 0 ){
1010                     continue ;
1011                 }
1012                 GETCHARSETSTR( char_set, fls->list[0].xlfdname ) ;
1013                 if( FalGetUDCCPArea( locale,
1014                                 fls->list[0].cd_set, char_set, &cr, &num_cr ) == FAL_ERROR ){
1015                     return -1 ;
1016                 }
1017                 if( num_cr == 0 ){
1018                     continue ;
1019                 }
1020                 /* display UDC code region */
1021                 USAGE1("  %d", cd_set ) ;
1022                 for( j=0; j<num_cr; j++ ){
1023                     USAGE2("\t\t0x%x - 0x%x\n", cr[j].start, cr[j].end ) ;
1024                 }
1025                 if( FalFreeFontList( fls ) == FAL_ERROR ){
1026                     return -1 ;
1027                 }
1028         }
1029         return 0 ;
1030 }
1031
1032
1033
1034 int     
1035 #if NeedFunctionPrototypes
1036 GetUdcFontName( 
1037     char        *gpf_file ,
1038     char        *bdf_file ,
1039     char        **fontname
1040 )
1041 #else
1042 GetUdcFontName( gpf_file, bdf_file, fontname )
1043 char    *gpf_file ;
1044 char    *bdf_file ;
1045 char    **fontname ;
1046 #endif
1047 {
1048         FILE    *fp ;
1049         pid_t   chld_pid = 0;
1050 #if defined( SVR4 ) || defined( SYSV ) || defined(CSRG_BASED)
1051         int     chld_stat ;
1052 #else
1053         union   wait    chld_stat ;
1054 #endif
1055         struct  ptobhead head ;
1056         char    *p, *tmp_font ;
1057         char    readbuf[BUFSIZE], fntbuf[BUFSIZE] ;
1058         unsigned int    getstat;
1059         int     fd[2];
1060
1061         p = tmp_font = NULL ;
1062         /*
1063          * get temorary file
1064          */
1065         memset( &head, 0, sizeof(struct ptobhead) ) ;
1066         if( gpf_file ){
1067             head.snf_file = GetRealFileName( gpf_file ) ;
1068             if( head.snf_file == NULL ) return STAT_ERROR ;
1069         }else if( bdf_file ){
1070             head.bdf_file = GetRealFileName( bdf_file ) ;
1071             if( head.bdf_file == NULL ) return STAT_ERROR ;
1072         }else{
1073             return STAT_ERROR ;
1074         }
1075
1076         /*
1077          * write BDF header into FIFO
1078          */
1079         if (head.snf_file != NULL) {
1080             if (pipe(fd) != 0) {
1081                 return  PIPE_ERROR;
1082             }
1083             switch (chld_pid = fork()) {
1084             case        0:
1085                 close(1);
1086                 if(dup(fd[1]) < 0) {
1087                     return(DUP_ERROR);
1088                 }
1089                 close(fd[0]);
1090                 close(fd[1]);
1091                 execl( oakgtobdf, oakgtobdf, head.snf_file, "-H", 0);
1092                 USAGE1("Cannot execute %s\n", oakgtobdf ) ;
1093                 return  EXEC_ERROR;
1094             case        -1:
1095                 return(FORK_ERROR);
1096             default:
1097                 break;
1098             }
1099             close(fd[1]);
1100             if((fp = (FILE *)fdopen(fd[0], "r")) == NULL) {
1101                 close( fd[0] );
1102                 kill( chld_pid, SIGKILL );
1103                 WaitID( chld_pid, chld_stat ) ;
1104                 return  FDOPEN_ERROR;
1105             }
1106         } else {
1107             if ((fp = fopen(head.bdf_file, "r")) == NULL) {
1108                 return(BDF_OPEN_HEAD);
1109             }
1110         }
1111
1112         /*
1113          * read BDF header
1114          */
1115         getstat = 0 ;
1116         while ( 1 ) {
1117             if (fgets(readbuf, BUFSIZE, fp) == NULL) {
1118                 fclose( fp );
1119                 if (head.snf_file != NULL) {
1120                     kill( chld_pid, SIGKILL );
1121                     WaitID( chld_pid, chld_stat ) ;
1122                 }
1123                 return(BDF_INVAL);
1124             }
1125             p = readbuf;
1126             SCAN_TO_NONSP(p);
1127
1128             if (!strncmp( p, "ENDPROPERTIES", strlen("ENDPROPERTIES") )) {
1129                 fclose( fp );
1130                 if (head.snf_file != NULL) {
1131                     kill( chld_pid, SIGKILL );
1132                     WaitID( chld_pid, chld_stat ) ;
1133                 }
1134                 return(BDF_INVAL);
1135             }
1136             if (!strncmp( p, "FONT ", strlen("FONT ") )) {
1137                 char    *sp, *ep ;
1138                 sp = ep = p ;
1139                 SCAN_TO_NONSP(sp);
1140                 sp++ ;
1141                 while( *ep != '\n' ){
1142                     ep++ ;
1143                 }
1144                 *ep = '\0' ;
1145                 strcpy(fntbuf, sp) ;
1146                 getstat |= 0x01 ;
1147                 fclose( fp );
1148                 if (head.snf_file != NULL) {
1149                     kill( chld_pid, SIGKILL );
1150                     WaitID( chld_pid, chld_stat ) ;
1151                 }
1152                 break;
1153             }
1154         }
1155
1156         if( getstat != 0x01 ){
1157                 return BDF_INVAL ;
1158         }
1159
1160         /*
1161          * dup font name
1162          */
1163         if( (tmp_font = (char *)strdup( fntbuf )) == NULL ){
1164             return MALLOC_ERROR ;
1165         }
1166         *fontname = tmp_font ;
1167
1168         return 0 ;
1169 }
1170
1171