4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
34 * Create message files in a specific format.
35 * the gettxt message retrieval function must know the format of
36 * the data file created by this utility.
38 * FORMAT OF MESSAGE FILES
40 __________________________
41 | Number of messages |
42 --------------------------
43 | offset to the 1st mesg |
44 --------------------------
45 | offset to the 2nd mesg |
46 --------------------------
47 | offset to the 3rd mesg |
48 --------------------------
52 --------------------------
53 | offset to the nth mesg |
54 --------------------------
56 --------------------------
58 --------------------------
60 --------------------------
64 --------------------------
66 --------------------------
74 #include <sys/types.h>
84 #define LINESZ 2048 /* max line in input base */
86 #define P_locale "/usr/lib/locale/" /* locale info directory */
87 #define L_locale sizeof(P_locale)
88 #define MESSAGES "/LC_MESSAGES/" /* messages category */
94 static char *syserr(void); /* Returns description of error */
95 static void usage(void); /* Displays valid invocations */
96 static int mymkdir(char *); /* Creates sub-directories */
97 static void clean(int); /* removes work file */
103 static char *cmdname
; /* Last qualifier of arg0 */
104 static char *workp
; /* name of the work file */
111 int c
; /* contains option letter */
112 char *ifilep
; /* input file name */
113 char *ofilep
; /* output file name */
114 char *localep
; /* locale name */
115 char *localedirp
; /* full-path name of parent directory
116 * of the output file */
117 char *outfilep
; /* full-path name of output file */
118 FILE *fp_inp
; /* input file FILE pointer */
119 FILE *fp_outp
; /* output file FILE pointer */
120 char *bufinp
, *bufworkp
; /* pointers to input and work areas */
121 int *bufoutp
; /* pointer to the output area */
122 char *msgp
; /* pointer to the a message */
123 int num_msgs
; /* number of messages in input file */
124 int iflag
; /* -i option was specified */
125 int oflag
; /* -o option was slecified */
126 int nitems
; /* number of bytes to write */
127 char *pathoutp
; /* full-path name of output file */
128 struct stat buf
; /* buffer to stat the work file */
129 unsigned size
; /* used for argument to malloc */
132 /* Initializations */
134 localep
= (char *)NULL
;
139 /* Get name of command */
141 if (cmdname
= strrchr(argv
[0], '/'))
146 /* Check for invalid number of arguments */
148 if (argc
< 3 && argc
> 6)
151 /* Get command line options */
153 while ((c
= getopt(argc
, argv
, "oi:")) != EOF
) {
168 /* Initialize pointers to input and output file names */
170 ifilep
= argv
[optind
];
171 ofilep
= argv
[optind
+ 1];
173 /* check for invalid invocations */
175 if (iflag
&& oflag
&& argc
!= 6)
177 if (iflag
&& ! oflag
&& argc
!= 5)
179 if (! iflag
&& oflag
&& argc
!= 4)
181 if (! iflag
&& ! oflag
&& argc
!= 3)
184 /* Construct a full-path to the output file */
187 size
= L_locale
+ strlen(localep
) +
188 sizeof(MESSAGES
) + strlen(ofilep
);
189 if ((pathoutp
= malloc(2 * (size
+ 1))) == NULL
) {
190 (void)fprintf(stderr
, "%s: malloc error (size = %d)\n",
194 localedirp
= pathoutp
+ size
+ 1;
195 (void)strcpy(pathoutp
, P_locale
);
196 (void)strcpy(&pathoutp
[L_locale
- 1], localep
);
197 (void)strcat(pathoutp
, MESSAGES
);
198 (void)strcpy(localedirp
, pathoutp
);
199 (void)strcat(pathoutp
, ofilep
);
202 /* Check for overwrite error conditions */
206 if (access(pathoutp
, 0) == 0) {
207 (void)fprintf(stderr
, "%s: Message file \"%s\" already exists;\ndid not overwrite it\n", cmdname
, pathoutp
);
214 if (access(ofilep
, 0) == 0) {
215 (void)fprintf(stderr
, "%s: Message file \"%s\" already exists;\ndid not overwrite it\n", cmdname
, ofilep
);
222 /* Open input file */
223 if ((fp_inp
= fopen(ifilep
, "r")) == NULL
) {
224 (void)fprintf(stderr
, "%s: %s: %s\n",
225 cmdname
, ifilep
, syserr());
229 /* Allocate buffer for input and work areas */
231 if ((bufinp
= malloc(2 * LINESZ
)) == NULL
) {
232 (void)fprintf(stderr
, "%s: malloc error (size = %d)\n",
233 cmdname
, 2 * LINESZ
);
236 bufworkp
= bufinp
+ LINESZ
;
238 if (sigset(SIGINT
, SIG_IGN
) == SIG_DFL
)
239 (void)sigset(SIGINT
, clean
);
243 workp
= tempnam(".", "xx");
244 if ((fp_outp
= fopen(workp
, "a+")) == NULL
) {
245 (void)fprintf(stderr
, "%s: %s: %s\n", cmdname
, workp
, syserr());
252 /* Search for C-escape sequences in input file and
253 * replace them by the appropriate characters.
254 * The modified lines are copied to the work area
255 * and written to the work file */
258 if (!fgets(bufinp
, LINESZ
, fp_inp
)) {
260 (void)fprintf(stderr
,"%s: %s: %s\n",
261 cmdname
, ifilep
, syserr());
269 if(*(bufinp
+strlen(bufinp
)-1) != '\n') {
270 (void)fprintf(stderr
, "%s: %s: data base file: error on line %d\n", cmdname
, ifilep
, num_msgs
);
274 *(bufinp
+ strlen(bufinp
) -1) = (char)0; /* delete newline */
276 (void)strccpy(bufworkp
, bufinp
);
277 nitems
= strlen(bufworkp
) + 1;
278 if (fwrite(bufworkp
, sizeof(*bufworkp
), nitems
, fp_outp
) != nitems
) {
279 (void)fprintf(stderr
, "%s: %s: %s\n",
280 cmdname
, workp
, syserr());
285 (void)fclose(fp_outp
);
287 /* Open and stat the work file */
289 if ((fp_outp
= fopen(workp
, "r")) == NULL
) {
290 (void)fprintf(stderr
, "%s: %s: %s\n", cmdname
, workp
, syserr());
293 if ((stat(workp
, &buf
)) != 0) {
294 (void)fprintf(stderr
, "%s: %s: %s\n", cmdname
, workp
, syserr());
297 /* Find the size of the output message file
298 * and copy the control information and the messages
299 * to the output file */
301 size
= sizeof(int) + num_msgs
* sizeof(int) + buf
.st_size
;
303 if ( (bufoutp
= (int *)malloc((uint
)size
)) == NULL
) {
304 (void)fprintf(stderr
, "%s: malloc error (size = %d)\n",
308 bufinp
= (char *)bufoutp
;
309 if ( (fread(bufinp
+ sizeof(int) + num_msgs
* sizeof(int), sizeof(*bufinp
), buf
.st_size
, fp_outp
)) != buf
.st_size
) {
311 (void) fprintf(stderr
, "%s: %s: %s\n", cmdname
, workp
, syserr());
313 (void) fclose(fp_outp
);
314 (void) unlink(workp
);
316 msgp
= bufinp
+ sizeof(int) + num_msgs
* sizeof(int);
318 *(bufoutp
+ 1) = (bufinp
+ sizeof(int) + num_msgs
* sizeof(int)) - bufinp
;
320 for(i
= 2; i
<= num_msgs
; i
++) {
321 *(bufoutp
+ i
) = (msgp
+ strlen(msgp
) + 1) - bufinp
;
322 msgp
= msgp
+ strlen(msgp
) + 1;
327 if (mymkdir(localedirp
) == 0) {
337 if ((fp_outp
= fopen(outfilep
, "w")) == NULL
) {
338 (void)fprintf(stderr
, "%s: %s: %s\n",
339 cmdname
, outfilep
, syserr());
346 if (fwrite((char *)bufinp
, sizeof(*bufinp
), size
, fp_outp
) != size
) {
347 (void)fprintf(stderr
, "%s: %s: %s\n",
348 cmdname
, ofilep
, syserr());
363 * Return a pointer to a system error message.
368 return (strerror(errno
));
374 (void)fprintf(stderr
, "Usage: %s [-o] inputstrings outputmsgs\n",
376 (void)fprintf(stderr
, " %s [-o] [-i locale] inputstrings outputmsgs\n", cmdname
);
388 if ((path
= malloc(strlen(localdir
)+1)) == NULL
)
391 while( (dirp
= strtok(s1
, "/")) != NULL
) {
393 (void)strcat(path
, "/");
394 (void)strcat(path
, dirp
);
395 if (access(path
, 3) == 0)
397 if (mkdir(path
, 0777) == -1) {
398 (void)fprintf(stderr
, "%s: %s: %s\n",
399 cmdname
, path
, syserr());
412 (void)sigset(SIGINT
, SIG_IGN
);
414 (void) unlink(workp
);