remove OSF1 support
[oweals/cde.git] / cde / programs / dtudcfonted / dtcpftogpf / cpftogpf.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 libraries 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: cpftogpf.c /main/7 1996/11/08 02:02:48 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        <stdlib.h>
33 #include        <stdio.h>
34 #include        <fcntl.h>
35 #include        <signal.h>
36 #include        <sys/types.h>
37 #ifndef SVR4
38 #if !defined( SYSV )
39 #include        <sys/resource.h>
40 #endif
41 #include        <sys/wait.h>
42 #else
43 #include        <wait.h>
44 #endif
45 #include        <sys/stat.h>
46 #include        <string.h>
47
48 #include        <unistd.h>
49
50 #include        <X11/Xmd.h>
51 #include        <X11/Xproto.h>
52
53 #include        "bdfgpf.h"
54
55 #include        "snfstruct.h"
56 #include        "fontstruct.h"
57
58 #include        "FaLib.h"
59 #include        "udcutil.h"
60
61 #include        <errno.h>
62
63
64 static  void    sigint_out() ;
65 static  void    put_error_and_exit();
66 static  void    put_help();
67 static  int     CnvGPFtoBDF() ;
68
69 static struct ptobhead Head;
70
71 static  char    *targ_file = NULL;      /* UDC character filename */
72 static  char    *com = NULL;            /* command name */
73 static  char    *spacing ;
74 static  char    *char_set ;
75
76
77 static void
78 sigint_out()
79 {
80         if (Head.out_file) {
81                 Unlink_Tmpfile(Head.out_file, com);
82         }
83         exit(0);
84 }
85
86 main( argc, argv )
87 int     argc;
88 char    *argv[];
89 {
90         FontInfoRec   *finf;
91         int     help, no_infile, style_err, rtn, i;
92         struct  stat    statbuf;
93         char    snf_file[BUFSIZE], buf[BUFSIZE];
94         int     pfd[2], fd, snf_fd, permission;
95         int     exit_stat;
96         char    *style ;        /* style */
97         int     chk_fd;
98         pid_t   chld_pid = 0;
99 #if defined( SVR4 ) || defined( SYSV ) || defined(CSRG_BASED) || defined(linux)
100         int     chld_stat ;
101 #else
102         union   wait    chld_stat ;
103 #endif
104         int     code_no, code_area ;
105         FalFontData     key ;
106         char    *xlfdname, *cbuf, *ep ;
107         char    *codeset = DEFAULT_CODESET ;
108
109         /* format */
110         Head.in_file = Head.bdf_file = Head.snf_file = Head.out_file = NULL;
111         help = no_infile = style_err = 0;
112         com = argv[0];
113         COMM_SETDEFAULTSTYLE( style ) ;
114         memset( &key, '\0', sizeof(FalFontData) ) ;
115         xlfdname = cbuf = ep = '\0' ;
116         spacing = char_set = NULL ;
117         code_no = code_area = 0 ;
118
119         if (!( bdftopcf = get_cmd_path( getenv( "PATH" ), BDFTOPCF_CMD ))) {
120                 bdftopcf = BDFTOPCF;
121         }
122         if (!( oakgtobdf = get_cmd_path( getenv( "PATH" ), SNFTOBDF_CMD ))) {
123                 oakgtobdf = SNFTOBDF;
124         }
125         if (!( bdftosnf = get_cmd_path( getenv( "PATH" ), BDFTOSNF_CMD ))) {
126                 bdftosnf = BDFTOSNF;
127         }
128
129         Head.code_category = ALL_CODE;
130         Head.start_code = MIN_CODE;
131         Head.end_code   = MAX_CODE;
132
133         for (i=1; i<argc; i++) {
134                 if ( !strcmp( argv[i], "-system" ) ) {
135                         code_area |= SYSTM ;
136                 } else if ( !strcmp( argv[i], "-help" ) ) {
137                         help = 1;
138                 } else if ( !strcmp( argv[i], "-g" ) ) {
139                         if ( ( i < argc-1 ) && ( *argv[i+1] != '-' ) ) {
140                                 Head.snf_file = argv[++i];
141                         }
142                 } else if (!strcmp(argv[i], "-p")) {
143                         if ( ( i < argc-1 ) && ( *argv[i+1] != '-' ) ) {
144                                 Head.in_file = argv[++i];
145                         } else {
146                                 no_infile = 1;
147                         }
148                 } else if ( !strcmp(argv[i], "-style" ) ) {
149                         if ( ( i < argc-1 ) && ( *argv[i+1] != '-' ) ){
150                                 style = argv[++i];
151                         } else {
152                                 style_err = 1;
153                         }
154
155                 } else if ( !strcmp( argv[i], "-codeset" ) ) {
156                         if (
157                                 ( ( i < argc-1 ) && ( *argv[i+1] != '-' ) ) &&
158                                 ( strlen( argv[i + 1] ) == 1 )
159                         ) {
160                                 if ( *argv[i+1] == '1' )        code_area |= CDSET1 ;
161                                 codeset = argv[++i] ;
162                         } else {
163                                 put_help( argv[0] );
164                                 exit( 1 );
165                         }
166                 } else if ( !strcmp( argv[i], "-xlfd" ) ) {
167                         if ( i < argc-1 ) {
168                                 xlfdname = argv[++i] ;
169                         } else {
170                                 put_help( argv[0] );
171                                 exit( 1 );
172                         }
173                 } else {
174                         put_help( argv[0] );
175                         exit( 1 );
176                 }
177         }
178
179         ep = (char *)strchr( codeset, '\0' ) ;
180         code_no = (int)strtol( codeset, &cbuf, 10 ) ;
181         if( cbuf == codeset || cbuf != ep ) {
182             USAGE1("%s : The code set number is not right.\n", argv[0] ) ;
183             exit(1) ;
184         }
185
186         if ( help ) {
187                 put_help( argv[0] );
188                 exit( 0 );
189         }
190
191         if ( no_infile ) {
192                 USAGE1("%s : The input file name following -p option cannot be omitted.\n", argv[0] );
193                 exit( 1 );
194         }
195
196         if ( style_err ) {
197                 USAGE1("%s : The style is not specified.\n", argv[0] );
198                 exit( 1 );
199         }
200
201         if ( Head.snf_file == NULL && xlfdname == NULL ) {
202                 if ( code_area & SYSTM ) {
203                         USAGE1("%s : The SNF output file name cannot be omitted.\n", argv[0] );
204                 } else {
205                         USAGE1("%s : The character size specification cannot be omitted.\n", argv[0] );
206                 }
207                 exit( 1 );
208         }
209
210         if ( !( code_area & SYSTM ) ) {
211
212
213             if( xlfdname ) { 
214                 if( GetUdcFileName( com, code_no, xlfdname, snf_file ) ) {
215                     USAGE1("%s : The font file name cannot be obtained. Terminates abnormally.\n", com );
216                     exit( 1 );
217                 }
218                 Head.snf_file = snf_file;
219             } else { 
220                 switch ( GetFileName( argv[0], Head.snf_file, style, code_no, snf_file ) ) {
221                 case    0:
222                     Head.snf_file = snf_file;
223                     break;
224                 case    -1:
225                     /* output GetFileName() */
226                     exit( 1 );
227                 default:
228                     USAGE1("%s : The font file name cannot be obtained. Terminates abnormally.\n", argv[0] );
229                     exit( 1 );
230                 }
231             } 
232         }
233
234         /*
235          * refuse proportional fonts
236          */
237         if ( GetUdcFontName( Head.snf_file, NULL, &xlfdname ) ) {
238             USAGE1("%s : This font cannot get XLFD. Terminates abnormally.\n", argv[0]);
239             exit( 1 );
240         }
241         GETSPACINGSTR( spacing, xlfdname ) ;
242         if ( !strcmp( "p", spacing ) || !strcmp( "P", spacing ) ) {
243             USAGE2("%s cannot edit proportional fonts.(SPACING \"%s\")\n", argv[0], spacing );
244             exit( 1 );
245         }
246         GETCHARSETSTR( char_set, xlfdname ) ;
247
248         COMM_SET_CODECATEGORY( char_set, code_area, Head) ;
249
250         if ( ( targ_file = GetRealFileName( Head.snf_file ) ) == NULL ){
251                 USAGE2("%s : It was not possible to refer to the substance of the font file. \"%s\"\n", argv[0], Head.snf_file );
252                 exit( 1 );
253         }
254
255
256         if ( ( chk_fd = open( targ_file, O_RDWR ) ) < 0  ) {
257                 USAGE2("%s : The font file of substance \"%s\" cannot be opened.\n", argv[0] , targ_file );
258         exit( 1 );
259         }
260         if ( isLock( chk_fd ) == 1 ) {
261                 USAGE1("%s : Editing by other application.\n", argv[0] );
262                 close( chk_fd );
263                 exit( 1 );
264         }
265         close( chk_fd );
266
267         /* 
268          * open input file(CPF) 
269          */
270         if ( Head.in_file == NULL ) {
271                 Head.input = stdin;
272         } else {
273                 if ( ( Head.input = fopen( Head.in_file, "r" ) ) == NULL ) {
274                         put_error_and_exit( &Head, GPF_OPEN_IN, argv[0] );
275                 }
276         }
277
278         /* 
279          * get GPF filename
280          */
281         if ( !( Head.out_file = GetTmpPath( targ_file ) ) ) {
282                 put_error_and_exit( &Head, MKTMP_ERROR, argv[0] );
283         }
284
285         permission = 0;
286         if ( ( snf_fd = open( Head.snf_file, O_RDONLY ) ) >= 0 ) {
287                 if ( ChkPcfFontFile( Head.snf_file) ) {
288                         /* snf file */
289                         COMM_SNF_FILEVERSION( snf_fd, finf, buf, permission ) ;
290                         if( permission < 0 ) {
291                                 put_error_and_exit( &Head, BDF_INVAL, argv[0] );
292                         }
293                 } else {
294                         /* pcf */
295                         close( snf_fd );
296                 }
297
298         } else {
299                 put_error_and_exit( &Head, BDF_OPEN_IN, argv[0] );
300         }
301
302
303         if ( pipe( pfd ) != 0 ) {
304                 put_error_and_exit( &Head, PIPE_ERROR, argv[0] );
305         }
306
307         signal( SIGHUP , (void(*)())sigint_out );
308         signal( SIGINT , (void(*)())sigint_out );
309         signal( SIGQUIT, (void(*)())sigint_out );
310         signal( SIGTERM, (void(*)())sigint_out );
311
312         switch ( chld_pid = fork() ) {
313         case    0:
314                 if ( ( fd = open( Head.out_file, O_WRONLY | O_CREAT, 0664 ) ) < 0 ) {
315                         put_error_and_exit( &Head, BDF_OPEN_OUT, argv[0] );
316                 }
317                 close(0);
318                 if ( dup( pfd[0] ) < 0 ) {
319                         put_error_and_exit( &Head, DUP_ERROR, argv[0] );
320                 }
321                 close( pfd[0] );
322                 close( pfd[1] );
323                 close( 1 );
324                 if ( dup( fd ) < 0 ) {
325                         put_error_and_exit( &Head, DUP_ERROR, argv[0] );
326                 }
327
328
329                 if ( ChkPcfFontFile( Head.snf_file ) == 0 ) {
330                         execl( bdftopcf, bdftopcf, 0 );
331                         /* exec error */
332                         put_error_and_exit( &Head, PCFFONTC_ERROR, argv[0] );
333                 }
334
335                 COMM_SNF_EXECLBDFTOSNF( permission, buf, Head.snf_file ) ;
336                 /* exec error */
337                 put_error_and_exit( &Head, SNFFONTC_ERROR, argv[0] );
338
339         case    -1:
340                 /* fork() error */
341                 put_error_and_exit( &Head, FORK_ERROR, argv[0] );
342
343         default:
344                 break;
345         }
346
347         close( pfd[0] );
348         if ( ( Head.output = fdopen( pfd[1], "w" ) ) == NULL ) {
349                 close( pfd[1] );
350                 kill( chld_pid, SIGKILL );
351                 WaitID( chld_pid, chld_stat ) ;
352                 put_error_and_exit( &Head, FDOPEN_ERROR, argv[0] );
353         }
354
355         if ( ( rtn = CnvGPFtoBDF( &Head ) ) ) {
356                 fclose( Head.input );
357                 fclose( Head.output );
358                 close( pfd[1] );
359                 kill( chld_pid, SIGKILL );
360                 WaitID( chld_pid, chld_stat ) ;
361                 Unlink_Tmpfile( Head.out_file, argv[0] );
362                 put_error_and_exit( &Head, rtn, argv[0] );
363         }
364         fclose( Head.output );
365         close( pfd[1] );
366         wait( &exit_stat );
367 #if !defined( SVR4 ) && !defined( SYSV ) && !defined(__FreeBSD__)
368         if ( !WIFEXITED(exit_stat) ) {
369 #else
370         if (! ( WIFEXITED(exit_stat) && !WEXITSTATUS(exit_stat) ) ) {
371 #endif
372                 USAGE3("%s: The error occurred by %s (%08x).\n", argv[0], bdftopcf, exit_stat );
373                 Unlink_Tmpfile( Head.out_file, argv[0] );
374                 exit( 1 );
375         }
376         fclose( Head.input );
377         signal( SIGHUP , SIG_IGN );
378         signal( SIGINT , SIG_IGN );
379         signal( SIGQUIT, SIG_IGN );
380         signal( SIGTERM, SIG_IGN );
381
382         sleep(1) ;
383         if ( (stat( Head.out_file,&statbuf ) ) ||
384             ( statbuf.st_size == 0 ) ) {
385                 Unlink_Tmpfile( Head.out_file, argv[0] );
386                 put_error_and_exit( &Head, BDF_WRITE, argv[0] );
387         }
388         if ( stat( targ_file, &statbuf ) ) {
389                 Unlink_Tmpfile( Head.out_file, argv[0] );
390                 put_error_and_exit( &Head, BDF_WRITE, argv[0] );
391         }
392
393         exit ( Make_NewFefFile( targ_file, Head.out_file,
394             FONT_FILE_PARM, (uid_t)statbuf.st_uid, (gid_t)statbuf.st_gid, argv[0]) );
395 }
396
397
398 static
399 CnvGPFtoBDF( head )
400 struct ptobhead *head;
401 {
402         int         rtn;
403         char    textbuf[BUFSIZE];
404
405         if ( ( rtn = ReadGpfHeader( head, textbuf ) ) ) {
406                 return  rtn;
407         }
408
409         if ( ( rtn = WriteBdfHeader( head ) ) ) {
410                 return  rtn;
411         }
412
413         if ( ( head->p_width != head->bdf_width ) ||
414                 ( head->p_height != head->bdf_height ) 
415         ) {
416                 head->zoomf = 1;
417         } else {
418                 head->zoomf = 0;
419         }
420
421         if ( ( head->code = (int *)malloc( sizeof(int) * head->num_chars ) ) == NULL ) {
422                 return  MALLOC_ERROR;
423         }
424
425         if ( ( head->ptn = (char **)malloc( sizeof(char *)*head->num_chars ) ) == NULL ) {
426                 return  MALLOC_ERROR;
427         }
428
429         if ( ( rtn = ReadGpfToMemory(head, textbuf ) ) ) {
430                 return  rtn;
431         }
432
433         if ( ( rtn = WritePtnToBdf( head ) ) ) {
434                 return  rtn;
435         }
436
437         return  0;
438 }
439
440
441 static  void
442 put_error_and_exit( ptob, er_no, prog_name )
443 struct ptobhead *ptob;
444 int    er_no;
445 char   *prog_name;
446 {
447         ErrMsgTable_AndExit( er_no, ptob->snf_file, ptob->out_file,
448             ptob->in_file,  NULL,
449             ptob->bdf_file,
450             prog_name
451             );
452         return;
453 }
454
455
456 static  void
457 put_help( prog_name )
458 char    *prog_name;
459 {
460         USAGE1("Usage: %s -xlfd xlfd_name\n", prog_name);
461         USAGE("\t\t[-g character_size][-p character_pattern_file_name]\n" );
462         USAGE("\t\t [-style style] \n");
463         COMM_HELP_MSG ;
464         USAGE("The character size may be obtained using the dtlsgpf command.\n");
465         USAGE("\n");
466 }