cpftogpf.c 11 KB

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