1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate * Copyright (c) 1990, 1991, 1994, Sun Microsystems, Inc.
24*7c478bd9Sstevel@tonic-gate * All rights reserved.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI"
28*7c478bd9Sstevel@tonic-gate
29*7c478bd9Sstevel@tonic-gate #include <nl_types.h>
30*7c478bd9Sstevel@tonic-gate #include <ctype.h>
31*7c478bd9Sstevel@tonic-gate #include <errno.h>
32*7c478bd9Sstevel@tonic-gate #include <fcntl.h>
33*7c478bd9Sstevel@tonic-gate #include <limits.h>
34*7c478bd9Sstevel@tonic-gate #include <memory.h>
35*7c478bd9Sstevel@tonic-gate #include <stdio.h>
36*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
37*7c478bd9Sstevel@tonic-gate #include <string.h>
38*7c478bd9Sstevel@tonic-gate #include <unistd.h>
39*7c478bd9Sstevel@tonic-gate #include <locale.h>
40*7c478bd9Sstevel@tonic-gate #include <libintl.h>
41*7c478bd9Sstevel@tonic-gate
42*7c478bd9Sstevel@tonic-gate #ifndef NL_MSGMAX
43*7c478bd9Sstevel@tonic-gate #define NL_MSGMAX 32767
44*7c478bd9Sstevel@tonic-gate #endif
45*7c478bd9Sstevel@tonic-gate
46*7c478bd9Sstevel@tonic-gate #ifndef NL_SETMAX
47*7c478bd9Sstevel@tonic-gate #define NL_SETMAX 255
48*7c478bd9Sstevel@tonic-gate #endif
49*7c478bd9Sstevel@tonic-gate
50*7c478bd9Sstevel@tonic-gate #ifndef NL_TEXTMAX
51*7c478bd9Sstevel@tonic-gate #define NL_TEXTMAX 2048
52*7c478bd9Sstevel@tonic-gate #endif
53*7c478bd9Sstevel@tonic-gate
54*7c478bd9Sstevel@tonic-gate #define BS '\b'
55*7c478bd9Sstevel@tonic-gate #define CR '\r'
56*7c478bd9Sstevel@tonic-gate #define DOLLAR '$'
57*7c478bd9Sstevel@tonic-gate #define FF '\f'
58*7c478bd9Sstevel@tonic-gate #define NEWLINE '\n'
59*7c478bd9Sstevel@tonic-gate #define NUL '\000'
60*7c478bd9Sstevel@tonic-gate #define REVERSE_SOLIDUS '\\'
61*7c478bd9Sstevel@tonic-gate #define SPACE ' '
62*7c478bd9Sstevel@tonic-gate #define TAB '\t'
63*7c478bd9Sstevel@tonic-gate #define VTAB '\v'
64*7c478bd9Sstevel@tonic-gate
65*7c478bd9Sstevel@tonic-gate #define FPRINTF (void) fprintf
66*7c478bd9Sstevel@tonic-gate #define FREE(x) free((char *)(x))
67*7c478bd9Sstevel@tonic-gate #define MALLOC(n) malloc((unsigned)(n))
68*7c478bd9Sstevel@tonic-gate #define MEMCPY(dst, src, n) \
69*7c478bd9Sstevel@tonic-gate (void) memcpy((char *)(dst), (char *)(src), (int)(n))
70*7c478bd9Sstevel@tonic-gate #define MEMSET(s, c, n) (void) memset((char *)(s), (int)(c), (int)(n));
71*7c478bd9Sstevel@tonic-gate #define MSG(n) gettext(MSG ## n)
72*7c478bd9Sstevel@tonic-gate #define READ(fd, p, n) read((int)(fd), (char *)(p), (unsigned)(n))
73*7c478bd9Sstevel@tonic-gate #define REALLOC(x, n) realloc((char *)(x), (unsigned)(n))
74*7c478bd9Sstevel@tonic-gate
75*7c478bd9Sstevel@tonic-gate /* double linked list */
76*7c478bd9Sstevel@tonic-gate struct cat_set {
77*7c478bd9Sstevel@tonic-gate struct cat_set *prev;
78*7c478bd9Sstevel@tonic-gate struct cat_set *next;
79*7c478bd9Sstevel@tonic-gate int set_no;
80*7c478bd9Sstevel@tonic-gate struct cat_msg *first_msg;
81*7c478bd9Sstevel@tonic-gate };
82*7c478bd9Sstevel@tonic-gate
83*7c478bd9Sstevel@tonic-gate /* double linked list */
84*7c478bd9Sstevel@tonic-gate struct cat_msg {
85*7c478bd9Sstevel@tonic-gate struct cat_msg *prev;
86*7c478bd9Sstevel@tonic-gate struct cat_msg *next;
87*7c478bd9Sstevel@tonic-gate int msg_no;
88*7c478bd9Sstevel@tonic-gate int msg_len;
89*7c478bd9Sstevel@tonic-gate char s[1];
90*7c478bd9Sstevel@tonic-gate };
91*7c478bd9Sstevel@tonic-gate
92*7c478bd9Sstevel@tonic-gate int catfd; /* File descriptor of catalog file */
93*7c478bd9Sstevel@tonic-gate char *catfname; /* Catalog file name */
94*7c478bd9Sstevel@tonic-gate char *msgfname; /* message source file name */
95*7c478bd9Sstevel@tonic-gate int ateof; /* boolean indicating END-OF-FILE */
96*7c478bd9Sstevel@tonic-gate int lineno; /* the line number of message source file */
97*7c478bd9Sstevel@tonic-gate int quoting; /* boolean indicating quotes is used */
98*7c478bd9Sstevel@tonic-gate int quote; /* the current quote */
99*7c478bd9Sstevel@tonic-gate int text_len; /* message text length */
100*7c478bd9Sstevel@tonic-gate int text_size; /* the size of allocated text memory */
101*7c478bd9Sstevel@tonic-gate char *text; /* messsge text */
102*7c478bd9Sstevel@tonic-gate
103*7c478bd9Sstevel@tonic-gate struct _cat_hdr hdr;
104*7c478bd9Sstevel@tonic-gate int current_set_no; /* the current set number */
105*7c478bd9Sstevel@tonic-gate struct cat_set *first_set; /* the pointer to the first set */
106*7c478bd9Sstevel@tonic-gate struct cat_set *current_set; /* the pointer to the current set */
107*7c478bd9Sstevel@tonic-gate struct cat_msg *current_msg; /* the pointer to the first message */
108*7c478bd9Sstevel@tonic-gate
109*7c478bd9Sstevel@tonic-gate
110*7c478bd9Sstevel@tonic-gate /* Error message */
111*7c478bd9Sstevel@tonic-gate /* 0 */
112*7c478bd9Sstevel@tonic-gate #define MSG0 ""
113*7c478bd9Sstevel@tonic-gate /* 1 */
114*7c478bd9Sstevel@tonic-gate #define MSG1 "usage: gencat catfile msgfile ...\n"
115*7c478bd9Sstevel@tonic-gate /* 2 */
116*7c478bd9Sstevel@tonic-gate #define MSG2 "gencat: cannot open \"%s\"\n"
117*7c478bd9Sstevel@tonic-gate /* 3 */
118*7c478bd9Sstevel@tonic-gate #define MSG3 "gencat: read error on \"%s\"\n"
119*7c478bd9Sstevel@tonic-gate /* 4 */
120*7c478bd9Sstevel@tonic-gate #define MSG4 "gencat: bad magic number (%#lx)\n"
121*7c478bd9Sstevel@tonic-gate /* 5 */
122*7c478bd9Sstevel@tonic-gate #define MSG5 "gencat: corrupt catalogue file \"%s\"\n"
123*7c478bd9Sstevel@tonic-gate /* 6 */
124*7c478bd9Sstevel@tonic-gate #define MSG6 "gencat: memory limit exceeded\n"
125*7c478bd9Sstevel@tonic-gate /* 7 */
126*7c478bd9Sstevel@tonic-gate #define MSG7 "gencat: seek error on \"%s\"\n"
127*7c478bd9Sstevel@tonic-gate /* 8 */
128*7c478bd9Sstevel@tonic-gate #define MSG8 "gencat: write error on \"%s\"\n"
129*7c478bd9Sstevel@tonic-gate /* 9 */
130*7c478bd9Sstevel@tonic-gate #define MSG9 "gencat: \"%s\", line %d: number too large (%s)\n"
131*7c478bd9Sstevel@tonic-gate /* 10 */
132*7c478bd9Sstevel@tonic-gate #define MSG10 "gencat: \"%s\", line %d: 0 is not a permissible " \
133*7c478bd9Sstevel@tonic-gate "message number\n"
134*7c478bd9Sstevel@tonic-gate /* 11 */
135*7c478bd9Sstevel@tonic-gate #define MSG11 "gencat: \"%s\", line %d: warning, message number %d " \
136*7c478bd9Sstevel@tonic-gate "exceeds limit (%d)\n"
137*7c478bd9Sstevel@tonic-gate /* 12 */
138*7c478bd9Sstevel@tonic-gate #define MSG12 "gencat: \"%s\", line %d: missing quote (%wc)\n"
139*7c478bd9Sstevel@tonic-gate /* 13 */
140*7c478bd9Sstevel@tonic-gate #define MSG13 "gencat: \"%s\", line %d: character value too large ('\\%o')\n"
141*7c478bd9Sstevel@tonic-gate /* 14 */
142*7c478bd9Sstevel@tonic-gate #define MSG14 "gencat: \"%s\", line %d: extra characters following " \
143*7c478bd9Sstevel@tonic-gate "message text\n"
144*7c478bd9Sstevel@tonic-gate /* 15 */
145*7c478bd9Sstevel@tonic-gate #define MSG15 "gencat: \"%s\", line %d: extra characters following " \
146*7c478bd9Sstevel@tonic-gate "$quote directive\n"
147*7c478bd9Sstevel@tonic-gate /* 16 */
148*7c478bd9Sstevel@tonic-gate #define MSG16 "gencat: \"%s\", line %d: no set number specified in " \
149*7c478bd9Sstevel@tonic-gate "$set directive\n"
150*7c478bd9Sstevel@tonic-gate /* 17 */
151*7c478bd9Sstevel@tonic-gate #define MSG17 "getcat: \"%s\", line %d: 0 is not a permissible set number\n"
152*7c478bd9Sstevel@tonic-gate /* 18 */
153*7c478bd9Sstevel@tonic-gate #define MSG18 "gencat: \"%s\", line %d: warning, set number %d " \
154*7c478bd9Sstevel@tonic-gate "exceeds limit (%d)\n"
155*7c478bd9Sstevel@tonic-gate /* 19 */
156*7c478bd9Sstevel@tonic-gate #define MSG19 "gencat: \"%s\", line %d: unknown directive %s\n"
157*7c478bd9Sstevel@tonic-gate /* 20 */
158*7c478bd9Sstevel@tonic-gate #define MSG20 "gencat: \"%s\", line %d: no set number specified in " \
159*7c478bd9Sstevel@tonic-gate "$delset directive\n"
160*7c478bd9Sstevel@tonic-gate /* 21 */
161*7c478bd9Sstevel@tonic-gate #define MSG21 "stdin"
162*7c478bd9Sstevel@tonic-gate /* 22 */
163*7c478bd9Sstevel@tonic-gate #define MSG22 "gencat: \"%s\", line %d: number or $ expected\n"
164*7c478bd9Sstevel@tonic-gate
165*7c478bd9Sstevel@tonic-gate struct cat_set *
new_set(n)166*7c478bd9Sstevel@tonic-gate new_set(n)
167*7c478bd9Sstevel@tonic-gate int n;
168*7c478bd9Sstevel@tonic-gate {
169*7c478bd9Sstevel@tonic-gate struct cat_set *p;
170*7c478bd9Sstevel@tonic-gate
171*7c478bd9Sstevel@tonic-gate p = (struct cat_set *) MALLOC(sizeof (struct cat_set));
172*7c478bd9Sstevel@tonic-gate if (p == NULL) {
173*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(6));
174*7c478bd9Sstevel@tonic-gate exit(1);
175*7c478bd9Sstevel@tonic-gate }
176*7c478bd9Sstevel@tonic-gate p->next = NULL;
177*7c478bd9Sstevel@tonic-gate p->prev = NULL;
178*7c478bd9Sstevel@tonic-gate p->set_no = n;
179*7c478bd9Sstevel@tonic-gate p->first_msg = NULL;
180*7c478bd9Sstevel@tonic-gate return (p);
181*7c478bd9Sstevel@tonic-gate }
182*7c478bd9Sstevel@tonic-gate
183*7c478bd9Sstevel@tonic-gate void
find_set(no)184*7c478bd9Sstevel@tonic-gate find_set(no)
185*7c478bd9Sstevel@tonic-gate int no;
186*7c478bd9Sstevel@tonic-gate {
187*7c478bd9Sstevel@tonic-gate struct cat_set *prev, *next;
188*7c478bd9Sstevel@tonic-gate
189*7c478bd9Sstevel@tonic-gate if (current_set && current_set->set_no == no) {
190*7c478bd9Sstevel@tonic-gate return;
191*7c478bd9Sstevel@tonic-gate }
192*7c478bd9Sstevel@tonic-gate
193*7c478bd9Sstevel@tonic-gate current_set_no = no;
194*7c478bd9Sstevel@tonic-gate current_msg = NULL;
195*7c478bd9Sstevel@tonic-gate /* if no set exists, create a new set */
196*7c478bd9Sstevel@tonic-gate if (current_set == NULL) {
197*7c478bd9Sstevel@tonic-gate if (first_set == NULL) {
198*7c478bd9Sstevel@tonic-gate current_set = first_set = new_set(no);
199*7c478bd9Sstevel@tonic-gate return;
200*7c478bd9Sstevel@tonic-gate }
201*7c478bd9Sstevel@tonic-gate current_set = first_set;
202*7c478bd9Sstevel@tonic-gate if (current_set->set_no == no)
203*7c478bd9Sstevel@tonic-gate return;
204*7c478bd9Sstevel@tonic-gate }
205*7c478bd9Sstevel@tonic-gate
206*7c478bd9Sstevel@tonic-gate if (current_set->set_no > no) {
207*7c478bd9Sstevel@tonic-gate if (first_set->set_no > no) {
208*7c478bd9Sstevel@tonic-gate /* prepend a new set */
209*7c478bd9Sstevel@tonic-gate current_set = new_set(no);
210*7c478bd9Sstevel@tonic-gate current_set->next = first_set;
211*7c478bd9Sstevel@tonic-gate first_set->prev = current_set;
212*7c478bd9Sstevel@tonic-gate first_set = current_set;
213*7c478bd9Sstevel@tonic-gate return;
214*7c478bd9Sstevel@tonic-gate }
215*7c478bd9Sstevel@tonic-gate current_set = first_set;
216*7c478bd9Sstevel@tonic-gate if (current_set->set_no == no)
217*7c478bd9Sstevel@tonic-gate return;
218*7c478bd9Sstevel@tonic-gate }
219*7c478bd9Sstevel@tonic-gate
220*7c478bd9Sstevel@tonic-gate /* search for the set number 'no' */
221*7c478bd9Sstevel@tonic-gate while (current_set->next && current_set->next->set_no < no)
222*7c478bd9Sstevel@tonic-gate current_set = current_set->next;
223*7c478bd9Sstevel@tonic-gate
224*7c478bd9Sstevel@tonic-gate if (current_set->next && current_set->next->set_no == no) {
225*7c478bd9Sstevel@tonic-gate /* set number 'no' found */
226*7c478bd9Sstevel@tonic-gate current_set = current_set->next;
227*7c478bd9Sstevel@tonic-gate return;
228*7c478bd9Sstevel@tonic-gate }
229*7c478bd9Sstevel@tonic-gate
230*7c478bd9Sstevel@tonic-gate /* If set number is not found, insert a new set in the middle */
231*7c478bd9Sstevel@tonic-gate prev = current_set;
232*7c478bd9Sstevel@tonic-gate next = current_set->next;
233*7c478bd9Sstevel@tonic-gate current_set = new_set(no);
234*7c478bd9Sstevel@tonic-gate current_set->prev = prev;
235*7c478bd9Sstevel@tonic-gate current_set->next = next;
236*7c478bd9Sstevel@tonic-gate if (prev)
237*7c478bd9Sstevel@tonic-gate prev->next = current_set;
238*7c478bd9Sstevel@tonic-gate else
239*7c478bd9Sstevel@tonic-gate first_set = current_set;
240*7c478bd9Sstevel@tonic-gate if (next)
241*7c478bd9Sstevel@tonic-gate next->prev = current_set;
242*7c478bd9Sstevel@tonic-gate }
243*7c478bd9Sstevel@tonic-gate
244*7c478bd9Sstevel@tonic-gate void
delete_set(no)245*7c478bd9Sstevel@tonic-gate delete_set(no)
246*7c478bd9Sstevel@tonic-gate int no;
247*7c478bd9Sstevel@tonic-gate {
248*7c478bd9Sstevel@tonic-gate struct cat_set *prev, *next, *setp;
249*7c478bd9Sstevel@tonic-gate struct cat_msg *p, *q;
250*7c478bd9Sstevel@tonic-gate
251*7c478bd9Sstevel@tonic-gate for (setp = first_set; setp && setp->set_no < no; setp = setp->next)
252*7c478bd9Sstevel@tonic-gate continue;
253*7c478bd9Sstevel@tonic-gate
254*7c478bd9Sstevel@tonic-gate if (setp == NULL || setp->set_no != no) /* set not found */
255*7c478bd9Sstevel@tonic-gate return;
256*7c478bd9Sstevel@tonic-gate
257*7c478bd9Sstevel@tonic-gate if (setp == current_set) {
258*7c478bd9Sstevel@tonic-gate current_set = NULL;
259*7c478bd9Sstevel@tonic-gate current_msg = NULL;
260*7c478bd9Sstevel@tonic-gate }
261*7c478bd9Sstevel@tonic-gate
262*7c478bd9Sstevel@tonic-gate /* free all messages in the set */
263*7c478bd9Sstevel@tonic-gate for (p = setp->first_msg; p; p) {
264*7c478bd9Sstevel@tonic-gate q = p->next;
265*7c478bd9Sstevel@tonic-gate FREE(p);
266*7c478bd9Sstevel@tonic-gate p = q;
267*7c478bd9Sstevel@tonic-gate }
268*7c478bd9Sstevel@tonic-gate
269*7c478bd9Sstevel@tonic-gate /* do the link operation to delete the set */
270*7c478bd9Sstevel@tonic-gate prev = setp->prev;
271*7c478bd9Sstevel@tonic-gate next = setp->next;
272*7c478bd9Sstevel@tonic-gate FREE(setp);
273*7c478bd9Sstevel@tonic-gate if (prev)
274*7c478bd9Sstevel@tonic-gate prev->next = next;
275*7c478bd9Sstevel@tonic-gate else
276*7c478bd9Sstevel@tonic-gate first_set = next;
277*7c478bd9Sstevel@tonic-gate if (next)
278*7c478bd9Sstevel@tonic-gate next->prev = prev;
279*7c478bd9Sstevel@tonic-gate }
280*7c478bd9Sstevel@tonic-gate
281*7c478bd9Sstevel@tonic-gate struct cat_msg *
new_msg(no,len,text)282*7c478bd9Sstevel@tonic-gate new_msg(no, len, text)
283*7c478bd9Sstevel@tonic-gate int no;
284*7c478bd9Sstevel@tonic-gate int len;
285*7c478bd9Sstevel@tonic-gate char *text;
286*7c478bd9Sstevel@tonic-gate {
287*7c478bd9Sstevel@tonic-gate struct cat_msg *p;
288*7c478bd9Sstevel@tonic-gate
289*7c478bd9Sstevel@tonic-gate p = (struct cat_msg *) MALLOC(sizeof (struct cat_msg) + len);
290*7c478bd9Sstevel@tonic-gate if (p == NULL) {
291*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(6));
292*7c478bd9Sstevel@tonic-gate exit(1);
293*7c478bd9Sstevel@tonic-gate }
294*7c478bd9Sstevel@tonic-gate p->next = NULL;
295*7c478bd9Sstevel@tonic-gate p->prev = NULL;
296*7c478bd9Sstevel@tonic-gate p->msg_no = no;
297*7c478bd9Sstevel@tonic-gate p->msg_len = len;
298*7c478bd9Sstevel@tonic-gate MEMCPY(p->s, text, len);
299*7c478bd9Sstevel@tonic-gate return (p);
300*7c478bd9Sstevel@tonic-gate }
301*7c478bd9Sstevel@tonic-gate
302*7c478bd9Sstevel@tonic-gate
303*7c478bd9Sstevel@tonic-gate void
insert_msg(no,len,text)304*7c478bd9Sstevel@tonic-gate insert_msg(no, len, text)
305*7c478bd9Sstevel@tonic-gate int no;
306*7c478bd9Sstevel@tonic-gate int len;
307*7c478bd9Sstevel@tonic-gate char *text;
308*7c478bd9Sstevel@tonic-gate {
309*7c478bd9Sstevel@tonic-gate struct cat_msg *prev, *next;
310*7c478bd9Sstevel@tonic-gate
311*7c478bd9Sstevel@tonic-gate if (current_msg == NULL) {
312*7c478bd9Sstevel@tonic-gate if (current_set == NULL)
313*7c478bd9Sstevel@tonic-gate find_set(current_set_no);
314*7c478bd9Sstevel@tonic-gate current_msg = current_set->first_msg;
315*7c478bd9Sstevel@tonic-gate if (current_msg == NULL) {
316*7c478bd9Sstevel@tonic-gate current_msg = new_msg(no, len, text);
317*7c478bd9Sstevel@tonic-gate current_set->first_msg = current_msg;
318*7c478bd9Sstevel@tonic-gate return;
319*7c478bd9Sstevel@tonic-gate }
320*7c478bd9Sstevel@tonic-gate }
321*7c478bd9Sstevel@tonic-gate if (current_msg->msg_no >= no) {
322*7c478bd9Sstevel@tonic-gate current_msg = current_set->first_msg;
323*7c478bd9Sstevel@tonic-gate if (current_msg->msg_no > no) {
324*7c478bd9Sstevel@tonic-gate current_msg = new_msg(no, len, text);
325*7c478bd9Sstevel@tonic-gate current_msg->next = current_set->first_msg;
326*7c478bd9Sstevel@tonic-gate current_set->first_msg->prev = current_msg;
327*7c478bd9Sstevel@tonic-gate current_set->first_msg = current_msg;
328*7c478bd9Sstevel@tonic-gate return;
329*7c478bd9Sstevel@tonic-gate }
330*7c478bd9Sstevel@tonic-gate if (current_msg->msg_no == no) {
331*7c478bd9Sstevel@tonic-gate current_msg = new_msg(no, len, text);
332*7c478bd9Sstevel@tonic-gate current_msg->next = current_set->first_msg->next;
333*7c478bd9Sstevel@tonic-gate if (current_set->first_msg->next)
334*7c478bd9Sstevel@tonic-gate current_set->first_msg->next->prev =
335*7c478bd9Sstevel@tonic-gate current_msg;
336*7c478bd9Sstevel@tonic-gate FREE(current_set->first_msg);
337*7c478bd9Sstevel@tonic-gate current_set->first_msg = current_msg;
338*7c478bd9Sstevel@tonic-gate return;
339*7c478bd9Sstevel@tonic-gate }
340*7c478bd9Sstevel@tonic-gate }
341*7c478bd9Sstevel@tonic-gate while (current_msg->next && current_msg->next->msg_no < no)
342*7c478bd9Sstevel@tonic-gate current_msg = current_msg->next;
343*7c478bd9Sstevel@tonic-gate
344*7c478bd9Sstevel@tonic-gate /*
345*7c478bd9Sstevel@tonic-gate * if the same msg number is found, then delte the message and
346*7c478bd9Sstevel@tonic-gate * insert the new message. This is same as replacing message.
347*7c478bd9Sstevel@tonic-gate */
348*7c478bd9Sstevel@tonic-gate if (current_msg->next && current_msg->next->msg_no == no) {
349*7c478bd9Sstevel@tonic-gate current_msg = current_msg->next;
350*7c478bd9Sstevel@tonic-gate prev = current_msg->prev;
351*7c478bd9Sstevel@tonic-gate next = current_msg->next;
352*7c478bd9Sstevel@tonic-gate FREE(current_msg);
353*7c478bd9Sstevel@tonic-gate } else {
354*7c478bd9Sstevel@tonic-gate prev = current_msg;
355*7c478bd9Sstevel@tonic-gate next = current_msg->next;
356*7c478bd9Sstevel@tonic-gate }
357*7c478bd9Sstevel@tonic-gate
358*7c478bd9Sstevel@tonic-gate current_msg = new_msg(no, len, text);
359*7c478bd9Sstevel@tonic-gate current_msg->prev = prev;
360*7c478bd9Sstevel@tonic-gate current_msg->next = next;
361*7c478bd9Sstevel@tonic-gate if (prev)
362*7c478bd9Sstevel@tonic-gate prev->next = current_msg;
363*7c478bd9Sstevel@tonic-gate else
364*7c478bd9Sstevel@tonic-gate current_set->first_msg = current_msg;
365*7c478bd9Sstevel@tonic-gate if (next)
366*7c478bd9Sstevel@tonic-gate next->prev = current_msg;
367*7c478bd9Sstevel@tonic-gate }
368*7c478bd9Sstevel@tonic-gate
369*7c478bd9Sstevel@tonic-gate void
delete_msg(no)370*7c478bd9Sstevel@tonic-gate delete_msg(no)
371*7c478bd9Sstevel@tonic-gate int no;
372*7c478bd9Sstevel@tonic-gate {
373*7c478bd9Sstevel@tonic-gate struct cat_set *p = current_set;
374*7c478bd9Sstevel@tonic-gate struct cat_msg *prev, *next;
375*7c478bd9Sstevel@tonic-gate
376*7c478bd9Sstevel@tonic-gate if (current_msg == NULL) {
377*7c478bd9Sstevel@tonic-gate if (current_set == NULL)
378*7c478bd9Sstevel@tonic-gate for (p = first_set; p && p->set_no < current_set_no;
379*7c478bd9Sstevel@tonic-gate p = p->next)
380*7c478bd9Sstevel@tonic-gate continue;
381*7c478bd9Sstevel@tonic-gate if (p == NULL || p->set_no != current_set_no)
382*7c478bd9Sstevel@tonic-gate return;
383*7c478bd9Sstevel@tonic-gate current_set = p;
384*7c478bd9Sstevel@tonic-gate current_msg = current_set->first_msg;
385*7c478bd9Sstevel@tonic-gate if (current_msg == NULL)
386*7c478bd9Sstevel@tonic-gate return;
387*7c478bd9Sstevel@tonic-gate }
388*7c478bd9Sstevel@tonic-gate if (current_msg->msg_no > no)
389*7c478bd9Sstevel@tonic-gate current_msg = current_set->first_msg;
390*7c478bd9Sstevel@tonic-gate
391*7c478bd9Sstevel@tonic-gate while (current_msg && current_msg->msg_no != no)
392*7c478bd9Sstevel@tonic-gate current_msg = current_msg->next;
393*7c478bd9Sstevel@tonic-gate
394*7c478bd9Sstevel@tonic-gate if (current_msg && current_msg->msg_no == no) {
395*7c478bd9Sstevel@tonic-gate prev = current_msg->prev;
396*7c478bd9Sstevel@tonic-gate next = current_msg->next;
397*7c478bd9Sstevel@tonic-gate FREE(current_msg);
398*7c478bd9Sstevel@tonic-gate if (prev) {
399*7c478bd9Sstevel@tonic-gate current_msg = prev;
400*7c478bd9Sstevel@tonic-gate prev->next = next;
401*7c478bd9Sstevel@tonic-gate } else {
402*7c478bd9Sstevel@tonic-gate current_set->first_msg = next;
403*7c478bd9Sstevel@tonic-gate current_msg = next;
404*7c478bd9Sstevel@tonic-gate }
405*7c478bd9Sstevel@tonic-gate if (next)
406*7c478bd9Sstevel@tonic-gate next->prev = prev;
407*7c478bd9Sstevel@tonic-gate }
408*7c478bd9Sstevel@tonic-gate }
409*7c478bd9Sstevel@tonic-gate
410*7c478bd9Sstevel@tonic-gate int
read_block(fd,p,n,pathname)411*7c478bd9Sstevel@tonic-gate read_block(fd, p, n, pathname)
412*7c478bd9Sstevel@tonic-gate int fd;
413*7c478bd9Sstevel@tonic-gate char *p;
414*7c478bd9Sstevel@tonic-gate int n;
415*7c478bd9Sstevel@tonic-gate char *pathname;
416*7c478bd9Sstevel@tonic-gate {
417*7c478bd9Sstevel@tonic-gate int nbytes, bytes_read;
418*7c478bd9Sstevel@tonic-gate
419*7c478bd9Sstevel@tonic-gate if (n == 0)
420*7c478bd9Sstevel@tonic-gate return (0);
421*7c478bd9Sstevel@tonic-gate
422*7c478bd9Sstevel@tonic-gate nbytes = 0;
423*7c478bd9Sstevel@tonic-gate while (nbytes < n) {
424*7c478bd9Sstevel@tonic-gate bytes_read = READ(fd, p + nbytes, n - nbytes);
425*7c478bd9Sstevel@tonic-gate if (bytes_read < 0) {
426*7c478bd9Sstevel@tonic-gate if (errno != EINTR) {
427*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(3), pathname);
428*7c478bd9Sstevel@tonic-gate perror("");
429*7c478bd9Sstevel@tonic-gate exit(1);
430*7c478bd9Sstevel@tonic-gate }
431*7c478bd9Sstevel@tonic-gate } else if (bytes_read == 0)
432*7c478bd9Sstevel@tonic-gate break;
433*7c478bd9Sstevel@tonic-gate else
434*7c478bd9Sstevel@tonic-gate nbytes += bytes_read;
435*7c478bd9Sstevel@tonic-gate }
436*7c478bd9Sstevel@tonic-gate
437*7c478bd9Sstevel@tonic-gate return (nbytes);
438*7c478bd9Sstevel@tonic-gate }
439*7c478bd9Sstevel@tonic-gate
440*7c478bd9Sstevel@tonic-gate /*
441*7c478bd9Sstevel@tonic-gate * Check if catalog file read is valid
442*7c478bd9Sstevel@tonic-gate *
443*7c478bd9Sstevel@tonic-gate */
444*7c478bd9Sstevel@tonic-gate int
cat_ok(cat)445*7c478bd9Sstevel@tonic-gate cat_ok(cat)
446*7c478bd9Sstevel@tonic-gate char *cat;
447*7c478bd9Sstevel@tonic-gate {
448*7c478bd9Sstevel@tonic-gate int i, j;
449*7c478bd9Sstevel@tonic-gate int nmsgs;
450*7c478bd9Sstevel@tonic-gate int msg_no;
451*7c478bd9Sstevel@tonic-gate struct _cat_msg_hdr *msg;
452*7c478bd9Sstevel@tonic-gate int set_no;
453*7c478bd9Sstevel@tonic-gate int first_msg_hdr;
454*7c478bd9Sstevel@tonic-gate struct _cat_set_hdr *set;
455*7c478bd9Sstevel@tonic-gate
456*7c478bd9Sstevel@tonic-gate set = (struct _cat_set_hdr *) cat;
457*7c478bd9Sstevel@tonic-gate set_no = 0;
458*7c478bd9Sstevel@tonic-gate for (i = 0; i < hdr.__nsets; ++set, ++i) {
459*7c478bd9Sstevel@tonic-gate if (set->__set_no < set_no)
460*7c478bd9Sstevel@tonic-gate return (0);
461*7c478bd9Sstevel@tonic-gate set_no = set->__set_no;
462*7c478bd9Sstevel@tonic-gate nmsgs = set->__nmsgs;
463*7c478bd9Sstevel@tonic-gate if (nmsgs < 0)
464*7c478bd9Sstevel@tonic-gate return (0);
465*7c478bd9Sstevel@tonic-gate if (nmsgs == 0)
466*7c478bd9Sstevel@tonic-gate continue;
467*7c478bd9Sstevel@tonic-gate first_msg_hdr = set->__first_msg_hdr;
468*7c478bd9Sstevel@tonic-gate if (first_msg_hdr < 0)
469*7c478bd9Sstevel@tonic-gate return (0);
470*7c478bd9Sstevel@tonic-gate if (hdr.__msg_hdr_offset + (first_msg_hdr + nmsgs) *
471*7c478bd9Sstevel@tonic-gate _CAT_MSG_HDR_SIZE > hdr.__mem)
472*7c478bd9Sstevel@tonic-gate return (0);
473*7c478bd9Sstevel@tonic-gate
474*7c478bd9Sstevel@tonic-gate msg = (struct _cat_msg_hdr *) (cat + hdr.__msg_hdr_offset) +
475*7c478bd9Sstevel@tonic-gate first_msg_hdr;
476*7c478bd9Sstevel@tonic-gate msg_no = 0;
477*7c478bd9Sstevel@tonic-gate for (j = 0; j < nmsgs; ++msg, ++j) {
478*7c478bd9Sstevel@tonic-gate if (msg->__msg_no < msg_no)
479*7c478bd9Sstevel@tonic-gate return (0);
480*7c478bd9Sstevel@tonic-gate msg_no = msg->__msg_no;
481*7c478bd9Sstevel@tonic-gate if (msg->__msg_offset < 0)
482*7c478bd9Sstevel@tonic-gate return (0);
483*7c478bd9Sstevel@tonic-gate if (hdr.__msg_text_offset + msg->__msg_offset +
484*7c478bd9Sstevel@tonic-gate msg->__msg_len > hdr.__mem)
485*7c478bd9Sstevel@tonic-gate return (0);
486*7c478bd9Sstevel@tonic-gate }
487*7c478bd9Sstevel@tonic-gate }
488*7c478bd9Sstevel@tonic-gate
489*7c478bd9Sstevel@tonic-gate return (1);
490*7c478bd9Sstevel@tonic-gate }
491*7c478bd9Sstevel@tonic-gate
492*7c478bd9Sstevel@tonic-gate /*
493*7c478bd9Sstevel@tonic-gate * convert a chunk of catalog file into double linked list format
494*7c478bd9Sstevel@tonic-gate */
495*7c478bd9Sstevel@tonic-gate void
initcat(cat)496*7c478bd9Sstevel@tonic-gate initcat(cat)
497*7c478bd9Sstevel@tonic-gate char *cat;
498*7c478bd9Sstevel@tonic-gate {
499*7c478bd9Sstevel@tonic-gate int i, j;
500*7c478bd9Sstevel@tonic-gate int nmsgs;
501*7c478bd9Sstevel@tonic-gate struct _cat_set_hdr *set;
502*7c478bd9Sstevel@tonic-gate struct _cat_msg_hdr *msg;
503*7c478bd9Sstevel@tonic-gate
504*7c478bd9Sstevel@tonic-gate set = (struct _cat_set_hdr *) cat;
505*7c478bd9Sstevel@tonic-gate for (i = 0; i < hdr.__nsets; ++set, ++i) {
506*7c478bd9Sstevel@tonic-gate nmsgs = set->__nmsgs;
507*7c478bd9Sstevel@tonic-gate if (nmsgs == 0)
508*7c478bd9Sstevel@tonic-gate continue;
509*7c478bd9Sstevel@tonic-gate find_set(set->__set_no);
510*7c478bd9Sstevel@tonic-gate msg = (struct _cat_msg_hdr *) (cat + hdr.__msg_hdr_offset)
511*7c478bd9Sstevel@tonic-gate + set->__first_msg_hdr;
512*7c478bd9Sstevel@tonic-gate current_msg = current_set->first_msg;
513*7c478bd9Sstevel@tonic-gate for (j = 0; j < nmsgs; ++msg, ++j) {
514*7c478bd9Sstevel@tonic-gate insert_msg(msg->__msg_no, msg->__msg_len,
515*7c478bd9Sstevel@tonic-gate cat + hdr.__msg_text_offset + msg->__msg_offset);
516*7c478bd9Sstevel@tonic-gate }
517*7c478bd9Sstevel@tonic-gate }
518*7c478bd9Sstevel@tonic-gate }
519*7c478bd9Sstevel@tonic-gate
520*7c478bd9Sstevel@tonic-gate /*
521*7c478bd9Sstevel@tonic-gate * read a catalog file in a chunk and convert it to double linked list.
522*7c478bd9Sstevel@tonic-gate */
523*7c478bd9Sstevel@tonic-gate void
readcat(fd,pathname)524*7c478bd9Sstevel@tonic-gate readcat(fd, pathname)
525*7c478bd9Sstevel@tonic-gate int fd;
526*7c478bd9Sstevel@tonic-gate char *pathname;
527*7c478bd9Sstevel@tonic-gate {
528*7c478bd9Sstevel@tonic-gate int i;
529*7c478bd9Sstevel@tonic-gate char *cat;
530*7c478bd9Sstevel@tonic-gate
531*7c478bd9Sstevel@tonic-gate i = read_block(fd, (char *) &hdr, _CAT_HDR_SIZE, pathname);
532*7c478bd9Sstevel@tonic-gate if (i == 0)
533*7c478bd9Sstevel@tonic-gate return;
534*7c478bd9Sstevel@tonic-gate
535*7c478bd9Sstevel@tonic-gate if (i >= 4 && hdr.__hdr_magic != _CAT_MAGIC) {
536*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(4), hdr.__hdr_magic);
537*7c478bd9Sstevel@tonic-gate exit(1);
538*7c478bd9Sstevel@tonic-gate }
539*7c478bd9Sstevel@tonic-gate if (i < _CAT_HDR_SIZE || hdr.__nsets < 0) {
540*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(5), pathname);
541*7c478bd9Sstevel@tonic-gate exit(1);
542*7c478bd9Sstevel@tonic-gate }
543*7c478bd9Sstevel@tonic-gate if (hdr.__nsets == 0)
544*7c478bd9Sstevel@tonic-gate return;
545*7c478bd9Sstevel@tonic-gate
546*7c478bd9Sstevel@tonic-gate if (hdr.__mem < 0 ||
547*7c478bd9Sstevel@tonic-gate hdr.__msg_hdr_offset < 0 ||
548*7c478bd9Sstevel@tonic-gate hdr.__msg_text_offset < 0 ||
549*7c478bd9Sstevel@tonic-gate hdr.__mem < hdr.__nsets * _CAT_SET_HDR_SIZE ||
550*7c478bd9Sstevel@tonic-gate hdr.__mem < hdr.__msg_hdr_offset ||
551*7c478bd9Sstevel@tonic-gate hdr.__mem < hdr.__msg_text_offset) {
552*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(5), pathname);
553*7c478bd9Sstevel@tonic-gate exit(1);
554*7c478bd9Sstevel@tonic-gate }
555*7c478bd9Sstevel@tonic-gate cat = MALLOC(hdr.__mem);
556*7c478bd9Sstevel@tonic-gate if (cat == NULL) {
557*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(6));
558*7c478bd9Sstevel@tonic-gate exit(1);
559*7c478bd9Sstevel@tonic-gate }
560*7c478bd9Sstevel@tonic-gate i = read_block(fd, cat, hdr.__mem, pathname);
561*7c478bd9Sstevel@tonic-gate if (i < hdr.__mem || !cat_ok(cat)) {
562*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(5), pathname);
563*7c478bd9Sstevel@tonic-gate exit(1);
564*7c478bd9Sstevel@tonic-gate }
565*7c478bd9Sstevel@tonic-gate initcat(cat);
566*7c478bd9Sstevel@tonic-gate
567*7c478bd9Sstevel@tonic-gate FREE(cat);
568*7c478bd9Sstevel@tonic-gate }
569*7c478bd9Sstevel@tonic-gate
570*7c478bd9Sstevel@tonic-gate /*
571*7c478bd9Sstevel@tonic-gate * Extend the memory in 1000 byte chunks whenever runs out of text space.
572*7c478bd9Sstevel@tonic-gate */
573*7c478bd9Sstevel@tonic-gate void
extend_text()574*7c478bd9Sstevel@tonic-gate extend_text()
575*7c478bd9Sstevel@tonic-gate {
576*7c478bd9Sstevel@tonic-gate text_size += 1000;
577*7c478bd9Sstevel@tonic-gate if (text)
578*7c478bd9Sstevel@tonic-gate text = REALLOC(text, text_size);
579*7c478bd9Sstevel@tonic-gate else
580*7c478bd9Sstevel@tonic-gate text = MALLOC(text_size);
581*7c478bd9Sstevel@tonic-gate if (text == NULL) {
582*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(6));
583*7c478bd9Sstevel@tonic-gate exit(1);
584*7c478bd9Sstevel@tonic-gate }
585*7c478bd9Sstevel@tonic-gate }
586*7c478bd9Sstevel@tonic-gate
587*7c478bd9Sstevel@tonic-gate int
get_number(fp,c)588*7c478bd9Sstevel@tonic-gate get_number(fp, c)
589*7c478bd9Sstevel@tonic-gate FILE *fp;
590*7c478bd9Sstevel@tonic-gate int c;
591*7c478bd9Sstevel@tonic-gate {
592*7c478bd9Sstevel@tonic-gate int i, n;
593*7c478bd9Sstevel@tonic-gate char *s, *t;
594*7c478bd9Sstevel@tonic-gate
595*7c478bd9Sstevel@tonic-gate i = 0;
596*7c478bd9Sstevel@tonic-gate do {
597*7c478bd9Sstevel@tonic-gate while (i >= text_size)
598*7c478bd9Sstevel@tonic-gate extend_text();
599*7c478bd9Sstevel@tonic-gate text[i] = c;
600*7c478bd9Sstevel@tonic-gate ++i;
601*7c478bd9Sstevel@tonic-gate c = getc(fp);
602*7c478bd9Sstevel@tonic-gate }
603*7c478bd9Sstevel@tonic-gate while (isdigit(c));
604*7c478bd9Sstevel@tonic-gate (void) ungetc(c, fp);
605*7c478bd9Sstevel@tonic-gate
606*7c478bd9Sstevel@tonic-gate while (i >= text_size)
607*7c478bd9Sstevel@tonic-gate extend_text();
608*7c478bd9Sstevel@tonic-gate text[i] = NUL;
609*7c478bd9Sstevel@tonic-gate
610*7c478bd9Sstevel@tonic-gate for (s = text; *s == '0'; ++s)
611*7c478bd9Sstevel@tonic-gate continue;
612*7c478bd9Sstevel@tonic-gate
613*7c478bd9Sstevel@tonic-gate n = 0;
614*7c478bd9Sstevel@tonic-gate for (t = s; isdigit(*t); ++t) {
615*7c478bd9Sstevel@tonic-gate if (n > INT_MAX / 10 ||
616*7c478bd9Sstevel@tonic-gate (n == INT_MAX / 10 && *t > '0' + INT_MAX % 10)) {
617*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(9), msgfname, lineno, s);
618*7c478bd9Sstevel@tonic-gate exit(1);
619*7c478bd9Sstevel@tonic-gate }
620*7c478bd9Sstevel@tonic-gate n = 10 * n + (*t - '0');
621*7c478bd9Sstevel@tonic-gate }
622*7c478bd9Sstevel@tonic-gate
623*7c478bd9Sstevel@tonic-gate return (n);
624*7c478bd9Sstevel@tonic-gate }
625*7c478bd9Sstevel@tonic-gate
626*7c478bd9Sstevel@tonic-gate void
get_text(fp)627*7c478bd9Sstevel@tonic-gate get_text(fp)
628*7c478bd9Sstevel@tonic-gate FILE *fp;
629*7c478bd9Sstevel@tonic-gate {
630*7c478bd9Sstevel@tonic-gate int c;
631*7c478bd9Sstevel@tonic-gate int n;
632*7c478bd9Sstevel@tonic-gate
633*7c478bd9Sstevel@tonic-gate text_len = 0;
634*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
635*7c478bd9Sstevel@tonic-gate if (quoting && c == quote) { /* quote is used */
636*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
637*7c478bd9Sstevel@tonic-gate while (c != quote) {
638*7c478bd9Sstevel@tonic-gate if (c == NEWLINE || c == EOF) {
639*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(12), msgfname, lineno,
640*7c478bd9Sstevel@tonic-gate quote);
641*7c478bd9Sstevel@tonic-gate exit(1);
642*7c478bd9Sstevel@tonic-gate }
643*7c478bd9Sstevel@tonic-gate if (c == REVERSE_SOLIDUS) {
644*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
645*7c478bd9Sstevel@tonic-gate switch (c) {
646*7c478bd9Sstevel@tonic-gate case EOF:
647*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(12), msgfname,
648*7c478bd9Sstevel@tonic-gate lineno, quote);
649*7c478bd9Sstevel@tonic-gate exit(1);
650*7c478bd9Sstevel@tonic-gate break;
651*7c478bd9Sstevel@tonic-gate case NEWLINE:
652*7c478bd9Sstevel@tonic-gate ++lineno;
653*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
654*7c478bd9Sstevel@tonic-gate continue;
655*7c478bd9Sstevel@tonic-gate /* NOTREACHED */
656*7c478bd9Sstevel@tonic-gate break;
657*7c478bd9Sstevel@tonic-gate case '0':
658*7c478bd9Sstevel@tonic-gate case '1':
659*7c478bd9Sstevel@tonic-gate case '2':
660*7c478bd9Sstevel@tonic-gate case '3':
661*7c478bd9Sstevel@tonic-gate case '4':
662*7c478bd9Sstevel@tonic-gate case '5':
663*7c478bd9Sstevel@tonic-gate case '6':
664*7c478bd9Sstevel@tonic-gate case '7':
665*7c478bd9Sstevel@tonic-gate n = (c - '0');
666*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
667*7c478bd9Sstevel@tonic-gate if (c >= '0' && c <= '7') {
668*7c478bd9Sstevel@tonic-gate n = 8 * n + (c - '0');
669*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
670*7c478bd9Sstevel@tonic-gate if (c >= '0' && c <= '7')
671*7c478bd9Sstevel@tonic-gate n = 8 * n + (c - '0');
672*7c478bd9Sstevel@tonic-gate else
673*7c478bd9Sstevel@tonic-gate (void) ungetwc(c, fp);
674*7c478bd9Sstevel@tonic-gate } else
675*7c478bd9Sstevel@tonic-gate (void) ungetwc(c, fp);
676*7c478bd9Sstevel@tonic-gate if (n > UCHAR_MAX) {
677*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(13),
678*7c478bd9Sstevel@tonic-gate msgfname, lineno, n);
679*7c478bd9Sstevel@tonic-gate exit(1);
680*7c478bd9Sstevel@tonic-gate }
681*7c478bd9Sstevel@tonic-gate c = n;
682*7c478bd9Sstevel@tonic-gate break;
683*7c478bd9Sstevel@tonic-gate
684*7c478bd9Sstevel@tonic-gate case 'n':
685*7c478bd9Sstevel@tonic-gate c = NEWLINE;
686*7c478bd9Sstevel@tonic-gate break;
687*7c478bd9Sstevel@tonic-gate
688*7c478bd9Sstevel@tonic-gate case 't':
689*7c478bd9Sstevel@tonic-gate c = TAB;
690*7c478bd9Sstevel@tonic-gate break;
691*7c478bd9Sstevel@tonic-gate
692*7c478bd9Sstevel@tonic-gate case 'v':
693*7c478bd9Sstevel@tonic-gate c = VTAB;
694*7c478bd9Sstevel@tonic-gate break;
695*7c478bd9Sstevel@tonic-gate
696*7c478bd9Sstevel@tonic-gate case 'b':
697*7c478bd9Sstevel@tonic-gate c = BS;
698*7c478bd9Sstevel@tonic-gate break;
699*7c478bd9Sstevel@tonic-gate
700*7c478bd9Sstevel@tonic-gate case 'r':
701*7c478bd9Sstevel@tonic-gate c = CR;
702*7c478bd9Sstevel@tonic-gate break;
703*7c478bd9Sstevel@tonic-gate
704*7c478bd9Sstevel@tonic-gate case 'f':
705*7c478bd9Sstevel@tonic-gate c = FF;
706*7c478bd9Sstevel@tonic-gate break;
707*7c478bd9Sstevel@tonic-gate }
708*7c478bd9Sstevel@tonic-gate }
709*7c478bd9Sstevel@tonic-gate while ((text_len + (int)MB_CUR_MAX + 1) >= text_size)
710*7c478bd9Sstevel@tonic-gate extend_text();
711*7c478bd9Sstevel@tonic-gate if ((n = wctomb(&text[text_len], c)) > 0)
712*7c478bd9Sstevel@tonic-gate text_len += n;
713*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
714*7c478bd9Sstevel@tonic-gate }
715*7c478bd9Sstevel@tonic-gate
716*7c478bd9Sstevel@tonic-gate while ((text_len + 1) >= text_size)
717*7c478bd9Sstevel@tonic-gate extend_text();
718*7c478bd9Sstevel@tonic-gate text[text_len] = '\0';
719*7c478bd9Sstevel@tonic-gate ++text_len;
720*7c478bd9Sstevel@tonic-gate
721*7c478bd9Sstevel@tonic-gate do {
722*7c478bd9Sstevel@tonic-gate c = getc(fp);
723*7c478bd9Sstevel@tonic-gate } while (c == SPACE || c == TAB);
724*7c478bd9Sstevel@tonic-gate if (c == NEWLINE) {
725*7c478bd9Sstevel@tonic-gate ++lineno;
726*7c478bd9Sstevel@tonic-gate return;
727*7c478bd9Sstevel@tonic-gate }
728*7c478bd9Sstevel@tonic-gate if (c == EOF) {
729*7c478bd9Sstevel@tonic-gate ateof = 1;
730*7c478bd9Sstevel@tonic-gate return;
731*7c478bd9Sstevel@tonic-gate }
732*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(14), msgfname, lineno);
733*7c478bd9Sstevel@tonic-gate exit(1);
734*7c478bd9Sstevel@tonic-gate }
735*7c478bd9Sstevel@tonic-gate
736*7c478bd9Sstevel@tonic-gate while (c != NEWLINE && c != EOF) { /* quote is not used */
737*7c478bd9Sstevel@tonic-gate if (c == REVERSE_SOLIDUS) {
738*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
739*7c478bd9Sstevel@tonic-gate switch (c) {
740*7c478bd9Sstevel@tonic-gate case EOF:
741*7c478bd9Sstevel@tonic-gate return;
742*7c478bd9Sstevel@tonic-gate
743*7c478bd9Sstevel@tonic-gate case NEWLINE:
744*7c478bd9Sstevel@tonic-gate ++lineno;
745*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
746*7c478bd9Sstevel@tonic-gate continue;
747*7c478bd9Sstevel@tonic-gate
748*7c478bd9Sstevel@tonic-gate case '0':
749*7c478bd9Sstevel@tonic-gate case '1':
750*7c478bd9Sstevel@tonic-gate case '2':
751*7c478bd9Sstevel@tonic-gate case '3':
752*7c478bd9Sstevel@tonic-gate case '4':
753*7c478bd9Sstevel@tonic-gate case '5':
754*7c478bd9Sstevel@tonic-gate case '6':
755*7c478bd9Sstevel@tonic-gate case '7':
756*7c478bd9Sstevel@tonic-gate n = (c - '0');
757*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
758*7c478bd9Sstevel@tonic-gate if (c >= '0' && c <= '7') {
759*7c478bd9Sstevel@tonic-gate n = 8 * n + (c - '0');
760*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
761*7c478bd9Sstevel@tonic-gate if (c >= '0' && c <= '7')
762*7c478bd9Sstevel@tonic-gate n = 8 * n + (c - '0');
763*7c478bd9Sstevel@tonic-gate else
764*7c478bd9Sstevel@tonic-gate (void) ungetwc(c, fp);
765*7c478bd9Sstevel@tonic-gate } else
766*7c478bd9Sstevel@tonic-gate (void) ungetwc(c, fp);
767*7c478bd9Sstevel@tonic-gate if (n > UCHAR_MAX) {
768*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(13), msgfname,
769*7c478bd9Sstevel@tonic-gate lineno, n);
770*7c478bd9Sstevel@tonic-gate exit(1);
771*7c478bd9Sstevel@tonic-gate }
772*7c478bd9Sstevel@tonic-gate c = n;
773*7c478bd9Sstevel@tonic-gate break;
774*7c478bd9Sstevel@tonic-gate
775*7c478bd9Sstevel@tonic-gate case 'n':
776*7c478bd9Sstevel@tonic-gate c = NEWLINE;
777*7c478bd9Sstevel@tonic-gate break;
778*7c478bd9Sstevel@tonic-gate
779*7c478bd9Sstevel@tonic-gate case 't':
780*7c478bd9Sstevel@tonic-gate c = TAB;
781*7c478bd9Sstevel@tonic-gate break;
782*7c478bd9Sstevel@tonic-gate
783*7c478bd9Sstevel@tonic-gate case 'v':
784*7c478bd9Sstevel@tonic-gate c = VTAB;
785*7c478bd9Sstevel@tonic-gate break;
786*7c478bd9Sstevel@tonic-gate
787*7c478bd9Sstevel@tonic-gate case 'b':
788*7c478bd9Sstevel@tonic-gate c = BS;
789*7c478bd9Sstevel@tonic-gate break;
790*7c478bd9Sstevel@tonic-gate
791*7c478bd9Sstevel@tonic-gate case 'r':
792*7c478bd9Sstevel@tonic-gate c = CR;
793*7c478bd9Sstevel@tonic-gate break;
794*7c478bd9Sstevel@tonic-gate
795*7c478bd9Sstevel@tonic-gate case 'f':
796*7c478bd9Sstevel@tonic-gate c = FF;
797*7c478bd9Sstevel@tonic-gate break;
798*7c478bd9Sstevel@tonic-gate }
799*7c478bd9Sstevel@tonic-gate }
800*7c478bd9Sstevel@tonic-gate while ((text_len + (int)MB_CUR_MAX + 1) >= text_size)
801*7c478bd9Sstevel@tonic-gate extend_text();
802*7c478bd9Sstevel@tonic-gate if ((n = wctomb(&text[text_len], c)) > 0)
803*7c478bd9Sstevel@tonic-gate text_len += n;
804*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
805*7c478bd9Sstevel@tonic-gate }
806*7c478bd9Sstevel@tonic-gate
807*7c478bd9Sstevel@tonic-gate while ((text_len + 1) >= text_size)
808*7c478bd9Sstevel@tonic-gate extend_text();
809*7c478bd9Sstevel@tonic-gate text[text_len] = '\0';
810*7c478bd9Sstevel@tonic-gate ++text_len;
811*7c478bd9Sstevel@tonic-gate
812*7c478bd9Sstevel@tonic-gate if (c == NEWLINE)
813*7c478bd9Sstevel@tonic-gate ++lineno;
814*7c478bd9Sstevel@tonic-gate else
815*7c478bd9Sstevel@tonic-gate ateof = 1;
816*7c478bd9Sstevel@tonic-gate }
817*7c478bd9Sstevel@tonic-gate
818*7c478bd9Sstevel@tonic-gate /*
819*7c478bd9Sstevel@tonic-gate * This routine handles $ <comment>, $set, $delset, $quote
820*7c478bd9Sstevel@tonic-gate */
821*7c478bd9Sstevel@tonic-gate void
directive(fp)822*7c478bd9Sstevel@tonic-gate directive(fp)
823*7c478bd9Sstevel@tonic-gate FILE *fp;
824*7c478bd9Sstevel@tonic-gate {
825*7c478bd9Sstevel@tonic-gate int c;
826*7c478bd9Sstevel@tonic-gate int n;
827*7c478bd9Sstevel@tonic-gate
828*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
829*7c478bd9Sstevel@tonic-gate if (c == SPACE || c == TAB) { /* $ <comment */
830*7c478bd9Sstevel@tonic-gate do {
831*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
832*7c478bd9Sstevel@tonic-gate } while (c != NEWLINE && c != EOF);
833*7c478bd9Sstevel@tonic-gate }
834*7c478bd9Sstevel@tonic-gate if (c == NEWLINE) {
835*7c478bd9Sstevel@tonic-gate ++lineno;
836*7c478bd9Sstevel@tonic-gate return;
837*7c478bd9Sstevel@tonic-gate }
838*7c478bd9Sstevel@tonic-gate if (c == EOF) {
839*7c478bd9Sstevel@tonic-gate ateof = 1;
840*7c478bd9Sstevel@tonic-gate return;
841*7c478bd9Sstevel@tonic-gate }
842*7c478bd9Sstevel@tonic-gate text_len = 1;
843*7c478bd9Sstevel@tonic-gate while (text_len >= text_size)
844*7c478bd9Sstevel@tonic-gate extend_text();
845*7c478bd9Sstevel@tonic-gate text[0] = DOLLAR;
846*7c478bd9Sstevel@tonic-gate while (isascii(c) && isalpha(c)) {
847*7c478bd9Sstevel@tonic-gate while ((text_len + 1) >= text_size)
848*7c478bd9Sstevel@tonic-gate extend_text();
849*7c478bd9Sstevel@tonic-gate text[text_len] = c;
850*7c478bd9Sstevel@tonic-gate ++text_len;
851*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
852*7c478bd9Sstevel@tonic-gate }
853*7c478bd9Sstevel@tonic-gate
854*7c478bd9Sstevel@tonic-gate while ((text_len + 1) >= text_size)
855*7c478bd9Sstevel@tonic-gate extend_text();
856*7c478bd9Sstevel@tonic-gate text[text_len] = NUL;
857*7c478bd9Sstevel@tonic-gate
858*7c478bd9Sstevel@tonic-gate if (strcmp(text, "$set") == 0) {
859*7c478bd9Sstevel@tonic-gate while (c == SPACE || c == TAB)
860*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
861*7c478bd9Sstevel@tonic-gate if (!isascii(c) || !isdigit(c)) {
862*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(16), msgfname, lineno);
863*7c478bd9Sstevel@tonic-gate exit(1);
864*7c478bd9Sstevel@tonic-gate }
865*7c478bd9Sstevel@tonic-gate n = get_number(fp, c);
866*7c478bd9Sstevel@tonic-gate if (n == 0) {
867*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(17), msgfname, lineno);
868*7c478bd9Sstevel@tonic-gate exit(1);
869*7c478bd9Sstevel@tonic-gate }
870*7c478bd9Sstevel@tonic-gate if (n > NL_SETMAX) {
871*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(18), msgfname, lineno,
872*7c478bd9Sstevel@tonic-gate n, NL_SETMAX);
873*7c478bd9Sstevel@tonic-gate }
874*7c478bd9Sstevel@tonic-gate find_set(n);
875*7c478bd9Sstevel@tonic-gate do { /* skip comment */
876*7c478bd9Sstevel@tonic-gate c = getc(fp);
877*7c478bd9Sstevel@tonic-gate } while (c != NEWLINE && c != EOF);
878*7c478bd9Sstevel@tonic-gate if (c == NEWLINE)
879*7c478bd9Sstevel@tonic-gate ++lineno;
880*7c478bd9Sstevel@tonic-gate else
881*7c478bd9Sstevel@tonic-gate ateof = 1;
882*7c478bd9Sstevel@tonic-gate return;
883*7c478bd9Sstevel@tonic-gate } else if (strcmp(text, "$delset") == 0) {
884*7c478bd9Sstevel@tonic-gate while (c == SPACE || c == TAB)
885*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
886*7c478bd9Sstevel@tonic-gate if (!isascii(c) || !isdigit(c)) {
887*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(20), msgfname, lineno);
888*7c478bd9Sstevel@tonic-gate exit(1);
889*7c478bd9Sstevel@tonic-gate }
890*7c478bd9Sstevel@tonic-gate n = get_number(fp, c);
891*7c478bd9Sstevel@tonic-gate if (n == 0) {
892*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(17), msgfname, lineno);
893*7c478bd9Sstevel@tonic-gate exit(1);
894*7c478bd9Sstevel@tonic-gate }
895*7c478bd9Sstevel@tonic-gate if (n > NL_SETMAX) {
896*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(18), msgfname, lineno,
897*7c478bd9Sstevel@tonic-gate n, NL_SETMAX);
898*7c478bd9Sstevel@tonic-gate }
899*7c478bd9Sstevel@tonic-gate delete_set(n);
900*7c478bd9Sstevel@tonic-gate do { /* skip comment */
901*7c478bd9Sstevel@tonic-gate c = getc(fp);
902*7c478bd9Sstevel@tonic-gate } while (c != NEWLINE && c != EOF);
903*7c478bd9Sstevel@tonic-gate if (c == NEWLINE)
904*7c478bd9Sstevel@tonic-gate ++lineno;
905*7c478bd9Sstevel@tonic-gate else
906*7c478bd9Sstevel@tonic-gate ateof = 1;
907*7c478bd9Sstevel@tonic-gate return;
908*7c478bd9Sstevel@tonic-gate } else if (strcmp(text, "$quote") == 0) {
909*7c478bd9Sstevel@tonic-gate if (c == NEWLINE) {
910*7c478bd9Sstevel@tonic-gate quoting = 0;
911*7c478bd9Sstevel@tonic-gate ++lineno;
912*7c478bd9Sstevel@tonic-gate return;
913*7c478bd9Sstevel@tonic-gate }
914*7c478bd9Sstevel@tonic-gate if (c == EOF) {
915*7c478bd9Sstevel@tonic-gate quoting = 0;
916*7c478bd9Sstevel@tonic-gate ateof = 1;
917*7c478bd9Sstevel@tonic-gate return;
918*7c478bd9Sstevel@tonic-gate }
919*7c478bd9Sstevel@tonic-gate if (c == SPACE || c == TAB)
920*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
921*7c478bd9Sstevel@tonic-gate if (c == NEWLINE) {
922*7c478bd9Sstevel@tonic-gate quoting = 0;
923*7c478bd9Sstevel@tonic-gate ++lineno;
924*7c478bd9Sstevel@tonic-gate return;
925*7c478bd9Sstevel@tonic-gate }
926*7c478bd9Sstevel@tonic-gate if (c == EOF) {
927*7c478bd9Sstevel@tonic-gate quoting = 0;
928*7c478bd9Sstevel@tonic-gate ateof = 1;
929*7c478bd9Sstevel@tonic-gate return;
930*7c478bd9Sstevel@tonic-gate }
931*7c478bd9Sstevel@tonic-gate quoting = 1;
932*7c478bd9Sstevel@tonic-gate quote = c;
933*7c478bd9Sstevel@tonic-gate do { /* skip comment */
934*7c478bd9Sstevel@tonic-gate c = getc(fp);
935*7c478bd9Sstevel@tonic-gate } while (c == SPACE || c == TAB);
936*7c478bd9Sstevel@tonic-gate if (c == NEWLINE) {
937*7c478bd9Sstevel@tonic-gate ++lineno;
938*7c478bd9Sstevel@tonic-gate return;
939*7c478bd9Sstevel@tonic-gate }
940*7c478bd9Sstevel@tonic-gate if (c == EOF) {
941*7c478bd9Sstevel@tonic-gate ateof = 1;
942*7c478bd9Sstevel@tonic-gate return;
943*7c478bd9Sstevel@tonic-gate }
944*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(15), msgfname, lineno);
945*7c478bd9Sstevel@tonic-gate exit(1);
946*7c478bd9Sstevel@tonic-gate } else {
947*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(19), msgfname, lineno, text);
948*7c478bd9Sstevel@tonic-gate exit(1);
949*7c478bd9Sstevel@tonic-gate }
950*7c478bd9Sstevel@tonic-gate }
951*7c478bd9Sstevel@tonic-gate
952*7c478bd9Sstevel@tonic-gate /*
953*7c478bd9Sstevel@tonic-gate * Read message source file and update double linked list message catalog.
954*7c478bd9Sstevel@tonic-gate */
955*7c478bd9Sstevel@tonic-gate void
read_msgfile(fp,pathname)956*7c478bd9Sstevel@tonic-gate read_msgfile(fp, pathname)
957*7c478bd9Sstevel@tonic-gate FILE *fp;
958*7c478bd9Sstevel@tonic-gate char *pathname;
959*7c478bd9Sstevel@tonic-gate {
960*7c478bd9Sstevel@tonic-gate int c;
961*7c478bd9Sstevel@tonic-gate int no;
962*7c478bd9Sstevel@tonic-gate
963*7c478bd9Sstevel@tonic-gate ateof = 0;
964*7c478bd9Sstevel@tonic-gate msgfname = pathname;
965*7c478bd9Sstevel@tonic-gate lineno = 1;
966*7c478bd9Sstevel@tonic-gate quoting = 0;
967*7c478bd9Sstevel@tonic-gate current_set_no = NL_SETD;
968*7c478bd9Sstevel@tonic-gate current_set = NULL;
969*7c478bd9Sstevel@tonic-gate current_msg = NULL;
970*7c478bd9Sstevel@tonic-gate
971*7c478bd9Sstevel@tonic-gate for (;;) {
972*7c478bd9Sstevel@tonic-gate if (ateof)
973*7c478bd9Sstevel@tonic-gate return;
974*7c478bd9Sstevel@tonic-gate do {
975*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
976*7c478bd9Sstevel@tonic-gate } while (c == SPACE || c == TAB);
977*7c478bd9Sstevel@tonic-gate if (c == DOLLAR) {
978*7c478bd9Sstevel@tonic-gate directive(fp);
979*7c478bd9Sstevel@tonic-gate continue;
980*7c478bd9Sstevel@tonic-gate }
981*7c478bd9Sstevel@tonic-gate
982*7c478bd9Sstevel@tonic-gate if (isascii(c) && isdigit(c)) {
983*7c478bd9Sstevel@tonic-gate no = get_number(fp, c);
984*7c478bd9Sstevel@tonic-gate if (no == 0) {
985*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(10), msgfname, lineno);
986*7c478bd9Sstevel@tonic-gate exit(1);
987*7c478bd9Sstevel@tonic-gate }
988*7c478bd9Sstevel@tonic-gate if (no > NL_MSGMAX) {
989*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(11), msgfname,
990*7c478bd9Sstevel@tonic-gate lineno, no, NL_MSGMAX);
991*7c478bd9Sstevel@tonic-gate }
992*7c478bd9Sstevel@tonic-gate c = fgetwc(fp);
993*7c478bd9Sstevel@tonic-gate if (c == NEWLINE || c == EOF) {
994*7c478bd9Sstevel@tonic-gate delete_msg(no);
995*7c478bd9Sstevel@tonic-gate if (c == NEWLINE)
996*7c478bd9Sstevel@tonic-gate ++lineno;
997*7c478bd9Sstevel@tonic-gate else
998*7c478bd9Sstevel@tonic-gate return;
999*7c478bd9Sstevel@tonic-gate continue;
1000*7c478bd9Sstevel@tonic-gate } else {
1001*7c478bd9Sstevel@tonic-gate if (c != SPACE && c != TAB)
1002*7c478bd9Sstevel@tonic-gate (void) ungetwc(c, fp);
1003*7c478bd9Sstevel@tonic-gate get_text(fp);
1004*7c478bd9Sstevel@tonic-gate insert_msg(no, text_len, text);
1005*7c478bd9Sstevel@tonic-gate continue;
1006*7c478bd9Sstevel@tonic-gate }
1007*7c478bd9Sstevel@tonic-gate }
1008*7c478bd9Sstevel@tonic-gate
1009*7c478bd9Sstevel@tonic-gate if (c == NEWLINE) {
1010*7c478bd9Sstevel@tonic-gate ++lineno;
1011*7c478bd9Sstevel@tonic-gate continue;
1012*7c478bd9Sstevel@tonic-gate }
1013*7c478bd9Sstevel@tonic-gate if (c == EOF)
1014*7c478bd9Sstevel@tonic-gate return;
1015*7c478bd9Sstevel@tonic-gate
1016*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(22), msgfname, lineno);
1017*7c478bd9Sstevel@tonic-gate exit(1);
1018*7c478bd9Sstevel@tonic-gate }
1019*7c478bd9Sstevel@tonic-gate }
1020*7c478bd9Sstevel@tonic-gate
1021*7c478bd9Sstevel@tonic-gate /*
1022*7c478bd9Sstevel@tonic-gate * Write double linked list to the file.
1023*7c478bd9Sstevel@tonic-gate * It first converts a linked list to one chunk of memory and
1024*7c478bd9Sstevel@tonic-gate * write it to file.
1025*7c478bd9Sstevel@tonic-gate */
1026*7c478bd9Sstevel@tonic-gate void
writecat(fd,pathname)1027*7c478bd9Sstevel@tonic-gate writecat(fd, pathname)
1028*7c478bd9Sstevel@tonic-gate int fd;
1029*7c478bd9Sstevel@tonic-gate char *pathname;
1030*7c478bd9Sstevel@tonic-gate {
1031*7c478bd9Sstevel@tonic-gate int i, n;
1032*7c478bd9Sstevel@tonic-gate int nsets;
1033*7c478bd9Sstevel@tonic-gate int mem;
1034*7c478bd9Sstevel@tonic-gate int nmsgs;
1035*7c478bd9Sstevel@tonic-gate int text_size;
1036*7c478bd9Sstevel@tonic-gate int first_msg_hdr;
1037*7c478bd9Sstevel@tonic-gate int msg_offset;
1038*7c478bd9Sstevel@tonic-gate unsigned nbytes;
1039*7c478bd9Sstevel@tonic-gate char *cat;
1040*7c478bd9Sstevel@tonic-gate struct _cat_hdr *hdrp;
1041*7c478bd9Sstevel@tonic-gate struct cat_set *setp;
1042*7c478bd9Sstevel@tonic-gate struct cat_msg *msgp;
1043*7c478bd9Sstevel@tonic-gate struct _cat_set_hdr *set;
1044*7c478bd9Sstevel@tonic-gate struct _cat_msg_hdr *msg;
1045*7c478bd9Sstevel@tonic-gate char *text;
1046*7c478bd9Sstevel@tonic-gate
1047*7c478bd9Sstevel@tonic-gate /* compute number of sets, number of messages, the total text size */
1048*7c478bd9Sstevel@tonic-gate nsets = 0;
1049*7c478bd9Sstevel@tonic-gate nmsgs = 0;
1050*7c478bd9Sstevel@tonic-gate text_size = 0;
1051*7c478bd9Sstevel@tonic-gate for (setp = first_set; setp; setp = setp->next) {
1052*7c478bd9Sstevel@tonic-gate ++nsets;
1053*7c478bd9Sstevel@tonic-gate for (msgp = setp->first_msg; msgp; msgp = msgp->next) {
1054*7c478bd9Sstevel@tonic-gate ++nmsgs;
1055*7c478bd9Sstevel@tonic-gate text_size += msgp->msg_len;
1056*7c478bd9Sstevel@tonic-gate }
1057*7c478bd9Sstevel@tonic-gate }
1058*7c478bd9Sstevel@tonic-gate
1059*7c478bd9Sstevel@tonic-gate mem = nsets * _CAT_SET_HDR_SIZE + nmsgs * _CAT_MSG_HDR_SIZE + text_size;
1060*7c478bd9Sstevel@tonic-gate n = _CAT_HDR_SIZE + mem;
1061*7c478bd9Sstevel@tonic-gate cat = MALLOC(n);
1062*7c478bd9Sstevel@tonic-gate if (cat == 0) {
1063*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(6));
1064*7c478bd9Sstevel@tonic-gate exit(1);
1065*7c478bd9Sstevel@tonic-gate }
1066*7c478bd9Sstevel@tonic-gate MEMSET(cat, 0, n);
1067*7c478bd9Sstevel@tonic-gate
1068*7c478bd9Sstevel@tonic-gate hdrp = (struct _cat_hdr *) cat;
1069*7c478bd9Sstevel@tonic-gate hdrp->__hdr_magic = _CAT_MAGIC;
1070*7c478bd9Sstevel@tonic-gate hdrp->__nsets = nsets;
1071*7c478bd9Sstevel@tonic-gate hdrp->__mem = mem;
1072*7c478bd9Sstevel@tonic-gate hdrp->__msg_hdr_offset = nsets * _CAT_SET_HDR_SIZE;
1073*7c478bd9Sstevel@tonic-gate hdrp->__msg_text_offset = nsets * _CAT_SET_HDR_SIZE +
1074*7c478bd9Sstevel@tonic-gate nmsgs * _CAT_MSG_HDR_SIZE;
1075*7c478bd9Sstevel@tonic-gate
1076*7c478bd9Sstevel@tonic-gate set = (struct _cat_set_hdr *) (cat + _CAT_HDR_SIZE);
1077*7c478bd9Sstevel@tonic-gate msg = (struct _cat_msg_hdr *) (set + nsets);
1078*7c478bd9Sstevel@tonic-gate text = (char *) (msg + nmsgs);
1079*7c478bd9Sstevel@tonic-gate
1080*7c478bd9Sstevel@tonic-gate /* convert linked list to one chunk of memory */
1081*7c478bd9Sstevel@tonic-gate first_msg_hdr = 0;
1082*7c478bd9Sstevel@tonic-gate msg_offset = 0;
1083*7c478bd9Sstevel@tonic-gate for (setp = first_set; setp; ++set, setp = setp->next) {
1084*7c478bd9Sstevel@tonic-gate set->__set_no = setp->set_no;
1085*7c478bd9Sstevel@tonic-gate set->__first_msg_hdr = first_msg_hdr;
1086*7c478bd9Sstevel@tonic-gate nmsgs = 0;
1087*7c478bd9Sstevel@tonic-gate for (msgp = setp->first_msg; msgp; ++msg, msgp = msgp->next) {
1088*7c478bd9Sstevel@tonic-gate ++nmsgs;
1089*7c478bd9Sstevel@tonic-gate msg->__msg_no = msgp->msg_no;
1090*7c478bd9Sstevel@tonic-gate msg->__msg_len = msgp->msg_len;
1091*7c478bd9Sstevel@tonic-gate msg->__msg_offset = msg_offset;
1092*7c478bd9Sstevel@tonic-gate if (msgp->msg_len > 0) {
1093*7c478bd9Sstevel@tonic-gate MEMCPY(text, msgp->s, msgp->msg_len);
1094*7c478bd9Sstevel@tonic-gate text += msgp->msg_len;
1095*7c478bd9Sstevel@tonic-gate msg_offset += msgp->msg_len;
1096*7c478bd9Sstevel@tonic-gate }
1097*7c478bd9Sstevel@tonic-gate }
1098*7c478bd9Sstevel@tonic-gate set->__nmsgs = nmsgs;
1099*7c478bd9Sstevel@tonic-gate first_msg_hdr += nmsgs;
1100*7c478bd9Sstevel@tonic-gate }
1101*7c478bd9Sstevel@tonic-gate
1102*7c478bd9Sstevel@tonic-gate /* write one chunk of memory to file */
1103*7c478bd9Sstevel@tonic-gate nbytes = 0;
1104*7c478bd9Sstevel@tonic-gate while (nbytes < n) {
1105*7c478bd9Sstevel@tonic-gate i = write(fd, cat + nbytes, n - nbytes);
1106*7c478bd9Sstevel@tonic-gate if (i < 0) {
1107*7c478bd9Sstevel@tonic-gate if (errno != EINTR) {
1108*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(8), pathname);
1109*7c478bd9Sstevel@tonic-gate perror("");
1110*7c478bd9Sstevel@tonic-gate exit(1);
1111*7c478bd9Sstevel@tonic-gate }
1112*7c478bd9Sstevel@tonic-gate } else {
1113*7c478bd9Sstevel@tonic-gate nbytes += n;
1114*7c478bd9Sstevel@tonic-gate }
1115*7c478bd9Sstevel@tonic-gate }
1116*7c478bd9Sstevel@tonic-gate
1117*7c478bd9Sstevel@tonic-gate free(cat);
1118*7c478bd9Sstevel@tonic-gate }
1119*7c478bd9Sstevel@tonic-gate
1120*7c478bd9Sstevel@tonic-gate int
main(argc,argv)1121*7c478bd9Sstevel@tonic-gate main(argc, argv)
1122*7c478bd9Sstevel@tonic-gate int argc;
1123*7c478bd9Sstevel@tonic-gate char *argv[];
1124*7c478bd9Sstevel@tonic-gate {
1125*7c478bd9Sstevel@tonic-gate int i;
1126*7c478bd9Sstevel@tonic-gate int cat_exists;
1127*7c478bd9Sstevel@tonic-gate
1128*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
1129*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
1130*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
1131*7c478bd9Sstevel@tonic-gate #endif
1132*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
1133*7c478bd9Sstevel@tonic-gate
1134*7c478bd9Sstevel@tonic-gate if (argc < 3) {
1135*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(1));
1136*7c478bd9Sstevel@tonic-gate exit(1);
1137*7c478bd9Sstevel@tonic-gate }
1138*7c478bd9Sstevel@tonic-gate catfname = argv[1];
1139*7c478bd9Sstevel@tonic-gate cat_exists = 0;
1140*7c478bd9Sstevel@tonic-gate if ((*catfname == '-') && (*(catfname + 1) == '\0')) {
1141*7c478bd9Sstevel@tonic-gate catfd = 1; /* Use stdout */
1142*7c478bd9Sstevel@tonic-gate } else {
1143*7c478bd9Sstevel@tonic-gate catfd = open(catfname, O_WRONLY | O_CREAT | O_EXCL, 0666);
1144*7c478bd9Sstevel@tonic-gate if (catfd < 0) { /* file exists */
1145*7c478bd9Sstevel@tonic-gate if (errno != EEXIST ||
1146*7c478bd9Sstevel@tonic-gate (catfd = open(catfname, O_RDWR)) < 0) {
1147*7c478bd9Sstevel@tonic-gate /* cannot open file */
1148*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(2), catfname);
1149*7c478bd9Sstevel@tonic-gate perror("");
1150*7c478bd9Sstevel@tonic-gate exit(1);
1151*7c478bd9Sstevel@tonic-gate }
1152*7c478bd9Sstevel@tonic-gate cat_exists = 1;
1153*7c478bd9Sstevel@tonic-gate /* read catalog file into memory */
1154*7c478bd9Sstevel@tonic-gate readcat(catfd, catfname);
1155*7c478bd9Sstevel@tonic-gate if (lseek(catfd, 0L, 0) < 0) {
1156*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(7), catfname);
1157*7c478bd9Sstevel@tonic-gate perror("");
1158*7c478bd9Sstevel@tonic-gate exit(1);
1159*7c478bd9Sstevel@tonic-gate }
1160*7c478bd9Sstevel@tonic-gate }
1161*7c478bd9Sstevel@tonic-gate }
1162*7c478bd9Sstevel@tonic-gate
1163*7c478bd9Sstevel@tonic-gate /* process all message source files */
1164*7c478bd9Sstevel@tonic-gate if ((**(argv + 2) == '-') && (*(*(argv + 2) + 1) == '\0')) {
1165*7c478bd9Sstevel@tonic-gate if (argc != 3) {
1166*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(1));
1167*7c478bd9Sstevel@tonic-gate exit(1);
1168*7c478bd9Sstevel@tonic-gate } else {
1169*7c478bd9Sstevel@tonic-gate read_msgfile(stdin, MSG(21));
1170*7c478bd9Sstevel@tonic-gate }
1171*7c478bd9Sstevel@tonic-gate } else {
1172*7c478bd9Sstevel@tonic-gate for (i = 2; i < argc; ++i) {
1173*7c478bd9Sstevel@tonic-gate FILE *fp;
1174*7c478bd9Sstevel@tonic-gate fp = fopen(*(argv + i), "r");
1175*7c478bd9Sstevel@tonic-gate if (fp == NULL) {
1176*7c478bd9Sstevel@tonic-gate FPRINTF(stderr, MSG(2), *(argv + i));
1177*7c478bd9Sstevel@tonic-gate perror("");
1178*7c478bd9Sstevel@tonic-gate exit(1);
1179*7c478bd9Sstevel@tonic-gate }
1180*7c478bd9Sstevel@tonic-gate read_msgfile(fp, *(argv + i));
1181*7c478bd9Sstevel@tonic-gate (void) fclose(fp);
1182*7c478bd9Sstevel@tonic-gate }
1183*7c478bd9Sstevel@tonic-gate }
1184*7c478bd9Sstevel@tonic-gate
1185*7c478bd9Sstevel@tonic-gate if (cat_exists)
1186*7c478bd9Sstevel@tonic-gate (void) ftruncate(catfd, 0L);
1187*7c478bd9Sstevel@tonic-gate
1188*7c478bd9Sstevel@tonic-gate /* write catalog to file */
1189*7c478bd9Sstevel@tonic-gate writecat(catfd, catfname);
1190*7c478bd9Sstevel@tonic-gate return (0);
1191*7c478bd9Sstevel@tonic-gate }
1192