Print this page
make: translate using gettext, rather than the unmaintainable catgets
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/make/bin/ar.cc
+++ new/usr/src/cmd/make/bin/ar.cc
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26 /*
27 27 * ar.c
28 28 *
29 29 * Deal with the lib.a(member.o) and lib.a((entry-point)) notations
30 30 *
31 31 * Look inside archives for notations a(b) and a((b))
32 32 * a(b) is file member b in archive a
33 33 * a((b)) is entry point b in object archive a
34 34 *
35 35 * For 6.0, create a make which can understand all archive
↓ open down ↓ |
35 lines elided |
↑ open up ↑ |
36 36 * formats. This is kind of tricky, and <ar.h> isnt any help.
37 37 */
38 38
39 39 /*
40 40 * Included files
41 41 */
42 42 #include <alloca.h> /* alloca() */
43 43 #include <ar.h>
44 44 #include <errno.h> /* errno */
45 45 #include <fcntl.h> /* open() */
46 +#include <libintl.h>
46 47 #include <mk/defs.h>
47 48 #include <mksh/misc.h> /* retmem_mb() */
48 49
49 50 struct ranlib {
50 51 union {
51 52 off_t ran_strx; /* string table index of */
52 53 char *ran_name; /* symbol defined by */
53 54 } ran_un;
54 55 off_t ran_off; /* library member at this offset */
55 56 };
56 57
57 58 #include <unistd.h> /* close() */
58 59
59 60
60 61 /*
61 62 * Defined macros
62 63 */
63 64 #ifndef S5EMUL
64 65 #undef BITSPERBYTE
65 66 #define BITSPERBYTE 8
66 67 #endif
67 68
68 69 /*
69 70 * Defines for all the different archive formats. See next comment
70 71 * block for justification for not using <ar.h>s versions.
71 72 */
72 73 #define AR_5_MAGIC "<ar>" /* 5.0 format magic string */
73 74 #define AR_5_MAGIC_LENGTH 4 /* 5.0 format string length */
74 75
75 76 #define AR_PORT_MAGIC "!<arch>\n" /* Port. (6.0) magic string */
76 77 #define AR_PORT_MAGIC_LENGTH 8 /* Port. (6.0) string length */
77 78 #define AR_PORT_END_MAGIC "`\n" /* Port. (6.0) end of header */
78 79 #define AR_PORT_WORD 4 /* Port. (6.0) 'word' length */
79 80
80 81 /*
81 82 * typedefs & structs
82 83 */
83 84 /*
84 85 * These are the archive file headers for the formats. Note
85 86 * that it really doesnt matter if these structures are defined
86 87 * here. They are correct as of the respective archive format
87 88 * releases. If the archive format is changed, then since backwards
88 89 * compatability is the desired behavior, a new structure is added
89 90 * to the list.
90 91 */
91 92 typedef struct { /* 5.0 ar header format: vax family; 3b family */
92 93 char ar_magic[AR_5_MAGIC_LENGTH]; /* AR_5_MAGIC*/
93 94 char ar_name[16]; /* Space terminated */
94 95 char ar_date[AR_PORT_WORD]; /* sgetl() accessed */
95 96 char ar_syms[AR_PORT_WORD]; /* sgetl() accessed */
96 97 } Arh_5;
97 98
98 99 typedef struct { /* 5.0 ar symbol format: vax family; 3b family */
99 100 char sym_name[8]; /* Space terminated */
100 101 char sym_ptr[AR_PORT_WORD]; /* sgetl() accessed */
101 102 } Ars_5;
102 103
103 104 typedef struct { /* 5.0 ar member format: vax family; 3b family */
104 105 char arf_name[16]; /* Space terminated */
105 106 char arf_date[AR_PORT_WORD]; /* sgetl() accessed */
106 107 char arf_uid[AR_PORT_WORD]; /* sgetl() accessed */
107 108 char arf_gid[AR_PORT_WORD]; /* sgetl() accessed */
108 109 char arf_mode[AR_PORT_WORD]; /* sgetl() accessed */
109 110 char arf_size[AR_PORT_WORD]; /* sgetl() accessed */
110 111 } Arf_5;
111 112
112 113 typedef struct { /* Portable (6.0) ar format: vax family; 3b family */
113 114 char ar_name[16]; /* Space terminated */
114 115 /* left-adjusted fields; decimal ascii; blank filled */
115 116 char ar_date[12];
116 117 char ar_uid[6];
117 118 char ar_gid[6];
118 119 char ar_mode[8]; /* octal ascii */
119 120 char ar_size[10];
120 121 /* special end-of-header string (AR_PORT_END_MAGIC) */
121 122 char ar_fmag[2];
122 123 } Ar_port;
123 124
124 125 enum ar_type {
125 126 AR_5,
126 127 AR_PORT
127 128 };
128 129
129 130 typedef unsigned int ar_port_word; // must be 4-bytes long
130 131
131 132 typedef struct {
132 133 FILE *fd;
133 134 /* to distiguish ar format */
134 135 enum ar_type type;
135 136 /* where first ar member header is at */
136 137 long first_ar_mem;
137 138 /* where the symbol lookup starts */
138 139 long sym_begin;
139 140 /* the number of symbols available */
140 141 long num_symbols;
141 142 /* length of symbol directory file */
142 143 long sym_size;
143 144 Arh_5 arh_5;
144 145 Ars_5 ars_5;
145 146 Arf_5 arf_5;
146 147 Ar_port ar_port;
147 148 } Ar;
148 149
149 150 /*
150 151 * Static variables
151 152 */
152 153
153 154 /*
154 155 * File table of contents
155 156 */
156 157 extern timestruc_t& read_archive(register Name target);
157 158 static Boolean open_archive(char *filename, register Ar *arp);
158 159 static void close_archive(register Ar *arp);
159 160 static Boolean read_archive_dir(register Ar *arp, Name library, char **long_names_table);
160 161 static void translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table);
161 162 static long sgetl(char *);
162 163
163 164 /*
164 165 * read_archive(target)
165 166 *
166 167 * Read the contents of an ar file.
167 168 *
168 169 * Return value:
169 170 * The time the member was created
170 171 *
171 172 * Parameters:
172 173 * target The member to find time for
173 174 *
174 175 * Global variables used:
175 176 * empty_name The Name ""
176 177 */
177 178
178 179 int read_member_header (Ar_port *header, FILE *fd, char* filename);
179 180 int process_long_names_member (register Ar *arp, char **long_names_table, char *filename);
180 181
181 182 timestruc_t&
182 183 read_archive(register Name target)
183 184 {
184 185 register Property member;
185 186 wchar_t *slash;
186 187 String_rec true_member_name;
187 188 wchar_t buffer[STRING_BUFFER_LENGTH];
188 189 register Name true_member = NULL;
189 190 Ar ar;
190 191 char *long_names_table = NULL; /* Table of long
191 192 member names */
192 193
193 194 member = get_prop(target->prop, member_prop);
194 195 /*
195 196 * Check if the member has directory component.
196 197 * If so, remove the dir and see if we know the date.
197 198 */
198 199 if (member->body.member.member != NULL) {
199 200 Wstring member_string(member->body.member.member);
200 201 wchar_t * wcb = member_string.get_string();
201 202 if((slash = (wchar_t *) wsrchr(wcb, (int) slash_char)) != NULL) {
202 203 INIT_STRING_FROM_STACK(true_member_name, buffer);
203 204 append_string(member->body.member.library->string_mb,
204 205 &true_member_name,
205 206 FIND_LENGTH);
206 207 append_char((int) parenleft_char, &true_member_name);
207 208 append_string(slash + 1, &true_member_name, FIND_LENGTH);
208 209 append_char((int) parenright_char, &true_member_name);
209 210 true_member = GETNAME(true_member_name.buffer.start,
210 211 FIND_LENGTH);
211 212 if (true_member->stat.time != file_no_time) {
212 213 target->stat.time = true_member->stat.time;
213 214 return target->stat.time;
214 215 }
215 216 }
↓ open down ↓ |
160 lines elided |
↑ open up ↑ |
216 217 }
217 218 if (open_archive(member->body.member.library->string_mb, &ar) == failed) {
218 219 if (errno == ENOENT) {
219 220 target->stat.stat_errno = ENOENT;
220 221 close_archive(&ar);
221 222 if (member->body.member.member == NULL) {
222 223 member->body.member.member = empty_name;
223 224 }
224 225 return target->stat.time = file_doesnt_exist;
225 226 } else {
226 - fatal(catgets(catd, 1, 1, "Can't access archive `%s': %s"),
227 + fatal(gettext("Can't access archive `%s': %s"),
227 228 member->body.member.library->string_mb,
228 229 errmsg(errno));
229 230 }
230 231 }
231 232 if (target->stat.time == file_no_time) {
232 233 if (read_archive_dir(&ar, member->body.member.library,
233 234 &long_names_table)
234 235 == failed){
235 - fatal(catgets(catd, 1, 2, "Can't access archive `%s': %s"),
236 + fatal(gettext("Can't access archive `%s': %s"),
236 237 member->body.member.library->string_mb,
237 238 errmsg(errno));
238 239 }
239 240 }
240 241 if (member->body.member.entry != NULL) {
241 242 translate_entry(&ar, target, member,&long_names_table);
242 243 }
243 244 close_archive(&ar);
244 245 if (long_names_table) {
245 246 retmem_mb(long_names_table);
246 247 }
247 248 if (true_member != NULL) {
248 249 target->stat.time = true_member->stat.time;
249 250 }
250 251 if (target->stat.time == file_no_time) {
251 252 target->stat.time = file_doesnt_exist;
252 253 }
253 254 return target->stat.time;
254 255 }
255 256
256 257 /*
257 258 * open_archive(filename, arp)
258 259 *
259 260 * Return value:
260 261 * Indicates if open failed or not
261 262 *
262 263 * Parameters:
263 264 * filename The name of the archive we need to read
264 265 * arp Pointer to ar file description block
265 266 *
266 267 * Global variables used:
267 268 */
268 269 static Boolean
269 270 open_archive(char *filename, register Ar *arp)
270 271 {
271 272 int fd;
272 273 char mag_5[AR_5_MAGIC_LENGTH];
273 274 char mag_port[AR_PORT_MAGIC_LENGTH];
274 275 char buffer[4];
275 276
276 277 arp->fd = NULL;
277 278 fd = open_vroot(filename, O_RDONLY, 0, NULL, VROOT_DEFAULT);
278 279 if ((fd < 0) || ((arp->fd = fdopen(fd, "r")) == NULL)) {
279 280 return failed;
280 281 }
281 282 (void) fcntl(fileno(arp->fd), F_SETFD, 1);
282 283
283 284 if (fread(mag_port, AR_PORT_MAGIC_LENGTH, 1, arp->fd) != 1) {
284 285 return failed;
285 286 }
286 287 if (IS_EQUALN(mag_port, AR_PORT_MAGIC, AR_PORT_MAGIC_LENGTH)) {
287 288 arp->type = AR_PORT;
288 289 /*
289 290 * Read in first member header to find out if there is
290 291 * a symbol definition table.
291 292 */
292 293
293 294 int ret = read_member_header(&arp->ar_port, arp->fd, filename);
294 295 if (ret == failed) {
295 296 return failed;
296 297 } else if(ret == -1) {
297 298 /* There is no member header - empty archive */
298 299 arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
299 300 arp->first_ar_mem = ftell(arp->fd);
300 301 return succeeded;
301 302 }
302 303 /*
303 304 * The following values are the default if there is
304 305 * no symbol directory and long member names.
305 306 */
306 307 arp->sym_size = arp->num_symbols = arp->sym_begin = 0L;
307 308 arp->first_ar_mem = ftell(arp->fd) - (long) sizeof (Ar_port);
308 309
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
309 310 /*
310 311 * Do we have a symbol table? A symbol table is always
311 312 * the first member in an archive. In 4.1.x it has the
312 313 * name __.SYMDEF, in SVr4, it has the name "/ "
313 314 */
314 315 /*
315 316 MBSTOWCS(wcs_buffer, "/ ");
316 317 if (IS_WEQUALN(arp->ar_port.ar_name, wcs_buffer, 16)) {
317 318 */
318 319 if (IS_EQUALN(arp->ar_port.ar_name,
319 - NOCATGETS("/ "),
320 + "/ ",
320 321 16)) {
321 322 if (sscanf(arp->ar_port.ar_size,
322 323 "%ld",
323 324 &arp->sym_size) != 1) {
324 325 return failed;
325 326 }
326 327 arp->sym_size += (arp->sym_size & 1); /* round up */
327 328 if (fread(buffer, sizeof buffer, 1, arp->fd) != 1) {
328 329 return failed;
329 330 }
330 331 arp->num_symbols = sgetl(buffer);
331 332 arp->sym_begin = ftell(arp->fd);
332 333 arp->first_ar_mem = arp->sym_begin +
333 334 arp->sym_size - sizeof buffer;
334 335 }
335 336 return succeeded;
336 337 }
337 - fatal(catgets(catd, 1, 3, "`%s' is not an archive"), filename);
338 + fatal(gettext("`%s' is not an archive"), filename);
338 339 /* NOTREACHED */
339 340 return failed;
340 341 }
341 342
342 343
343 344 /*
344 345 * close_archive(arp)
345 346 *
346 347 * Parameters:
347 348 * arp Pointer to ar file description block
348 349 *
349 350 * Global variables used:
350 351 */
351 352 static void
352 353 close_archive(register Ar *arp)
353 354 {
354 355 if (arp->fd != NULL) {
355 356 (void) fclose(arp->fd);
356 357 }
357 358 }
358 359
359 360 /*
360 361 * read_archive_dir(arp, library, long_names_table)
361 362 *
362 363 * Reads the directory of an archive and enters all
363 364 * the members into the make symboltable in lib(member) format
364 365 * with their dates.
365 366 *
366 367 * Parameters:
367 368 * arp Pointer to ar file description block
368 369 * library Name of lib to enter members for.
369 370 * Used to form "lib(member)" string.
370 371 * long_names_table table that contains list of members
371 372 * with names > 15 characters long
372 373 *
373 374 * Global variables used:
374 375 */
375 376 static Boolean
376 377 read_archive_dir(register Ar *arp, Name library, char **long_names_table)
377 378 {
378 379 wchar_t *name_string;
379 380 wchar_t *member_string;
380 381 register long len;
381 382 register wchar_t *p;
382 383 register char *q;
383 384 register Name name;
384 385 Property member;
385 386 long ptr;
386 387 long date;
387 388
388 389 int offset;
389 390
390 391 /*
391 392 * If any of the members has a name > 15 chars,
392 393 * it will be found here.
393 394 */
394 395 if (process_long_names_member(arp, long_names_table, library->string_mb) == failed) {
395 396 return failed;
396 397 }
397 398 name_string = ALLOC_WC((int) (library->hash.length +
398 399 (int) ar_member_name_len * 2));
399 400 (void) mbstowcs(name_string, library->string_mb, (int) library->hash.length);
400 401 member_string = name_string + library->hash.length;
401 402 *member_string++ = (int) parenleft_char;
402 403
403 404 if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
404 405 goto read_error;
405 406 }
406 407 /* Read the directory using the appropriate format */
407 408 switch (arp->type) {
408 409 case AR_5:
409 410 for (;;) {
410 411 if (fread((char *) &arp->arf_5, sizeof arp->arf_5, 1, arp->fd)
411 412 != 1) {
412 413 if (feof(arp->fd)) {
413 414 return succeeded;
414 415 }
415 416 break;
416 417 }
417 418 len = sizeof arp->arf_5.arf_name;
418 419 for (p = member_string, q = arp->arf_5.arf_name;
419 420 (len > 0) && (*q != (int) nul_char) && !isspace(*q);
420 421 ) {
421 422 MBTOWC(p, q);
422 423 p++;
423 424 q++;
424 425 }
425 426 *p++ = (int) parenright_char;
426 427 *p = (int) nul_char;
427 428 name = GETNAME(name_string, FIND_LENGTH);
428 429 /*
429 430 * [tolik] Fix for dmake bug 1234018.
430 431 * If name->stat.time is already set, then it should not
431 432 * be changed. (D)make propogates time stamp for one
432 433 * member, and when it calls exists() for another member,
433 434 * the first one may be changed.
434 435 */
435 436 if(name->stat.time == file_no_time) {
436 437 name->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
437 438 name->stat.time.tv_nsec = LONG_MAX;
438 439 }
439 440 name->is_member = library->is_member;
440 441 member = maybe_append_prop(name, member_prop);
441 442 member->body.member.library = library;
442 443 *--p = (int) nul_char;
443 444 if (member->body.member.member == NULL) {
444 445 member->body.member.member =
445 446 GETNAME(member_string, FIND_LENGTH);
446 447 }
447 448 ptr = sgetl(arp->arf_5.arf_size);
448 449 ptr += (ptr & 1);
449 450 if (fseek(arp->fd, ptr, 1) != 0) {
450 451 goto read_error;
451 452 }
452 453 }
453 454 break;
454 455 case AR_PORT:
455 456 for (;;) {
456 457 if ((fread((char *) &arp->ar_port,
↓ open down ↓ |
109 lines elided |
↑ open up ↑ |
457 458 sizeof arp->ar_port,
458 459 1,
459 460 arp->fd) != 1) ||
460 461 !IS_EQUALN(arp->ar_port.ar_fmag,
461 462 AR_PORT_END_MAGIC,
462 463 sizeof arp->ar_port.ar_fmag)) {
463 464 if (feof(arp->fd)) {
464 465 return succeeded;
465 466 }
466 467 fatal(
467 - catgets(catd, 1, 28, "Read error in archive `%s': invalid archive file member header at 0x%x"),
468 + gettext("Read error in archive `%s': invalid archive file member header at 0x%x"),
468 469 library->string_mb,
469 470 ftell(arp->fd)
470 471 );
471 472 }
472 473 /* If it's a long name, retrieve it from long name table */
473 474 if (arp->ar_port.ar_name[0] == '/') {
474 475 /*
475 476 * "len" is used for hashing the string.
476 477 * We're using "ar_member_name_len" instead of
477 478 * the actual name length since it's the longest
478 479 * string the "ar" command can handle at this
479 480 * point.
480 481 */
481 482 len = ar_member_name_len;
482 483 sscanf(arp->ar_port.ar_name + 1,
483 484 "%ld",
484 485 &offset);
485 486 q = *long_names_table + offset;
486 487 } else {
487 488 q = arp->ar_port.ar_name;
488 489 len = sizeof arp->ar_port.ar_name;
489 490 }
490 491
491 492 for (p = member_string;
492 493 (len > 0) &&
493 494 (*q != (int) nul_char) &&
494 495 !isspace(*q) &&
495 496 (*q != (int) slash_char);
496 497 ) {
497 498 MBTOWC(p, q);
498 499 p++;
499 500 q++;
500 501 }
501 502 *p++ = (int) parenright_char;
502 503 *p = (int) nul_char;
503 504 name = GETNAME(name_string, FIND_LENGTH);
↓ open down ↓ |
26 lines elided |
↑ open up ↑ |
504 505 name->is_member = library->is_member;
505 506 member = maybe_append_prop(name, member_prop);
506 507 member->body.member.library = library;
507 508 *--p = (int) nul_char;
508 509 if (member->body.member.member == NULL) {
509 510 member->body.member.member =
510 511 GETNAME(member_string, FIND_LENGTH);
511 512 }
512 513 if (sscanf(arp->ar_port.ar_date, "%ld", &date) != 1) {
513 514 WCSTOMBS(mbs_buffer, name_string);
514 - fatal(catgets(catd, 1, 4, "Bad date field for member `%s' in archive `%s'"),
515 + fatal(gettext("Bad date field for member `%s' in archive `%s'"),
515 516 mbs_buffer,
516 517 library->string_mb);
517 518 }
518 519 /*
519 520 * [tolik] Fix for dmake bug 1234018.
520 521 */
521 522 if(name->stat.time == file_no_time) {
522 523 name->stat.time.tv_sec = date;
523 524 name->stat.time.tv_nsec = LONG_MAX;
524 525 }
525 526 if (sscanf(arp->ar_port.ar_size, "%ld", &ptr) != 1) {
526 527 WCSTOMBS(mbs_buffer, name_string);
527 - fatal(catgets(catd, 1, 5, "Bad size field for member `%s' in archive `%s'"),
528 + fatal(gettext("Bad size field for member `%s' in archive `%s'"),
528 529 mbs_buffer,
529 530 library->string_mb);
530 531 }
531 532 ptr += (ptr & 1);
532 533 if (fseek(arp->fd, ptr, 1) != 0) {
533 534 goto read_error;
534 535 }
535 536 }
536 537 break;
537 538 }
538 539
539 540 /* Only here if fread() [or IS_EQUALN()] failed and not at EOF */
540 541 read_error:
541 - fatal(catgets(catd, 1, 6, "Read error in archive `%s': %s"),
542 + fatal(gettext("Read error in archive `%s': %s"),
542 543 library->string_mb,
543 544 errmsg(errno));
544 545 /* NOTREACHED */
545 546 }
546 547
547 548
548 549 /*
549 550 * process_long_names_member(arp)
550 551 *
551 552 * If the archive contains members with names longer
552 553 * than 15 characters, then it has a special member
553 554 * with the name "// " that contains a table
554 555 * of null-terminated long names. This member
555 556 * is always the first member, after the symbol table
556 557 * if it exists.
557 558 *
558 559 * Parameters:
559 560 * arp Pointer to ar file description block
560 561 *
561 562 * Global variables used:
562 563 */
563 564 int
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
564 565 process_long_names_member(register Ar *arp, char **long_names_table, char *filename)
565 566 {
566 567 Ar_port *ar_member_header;
567 568 int table_size;
568 569
569 570 if (fseek(arp->fd, arp->first_ar_mem, 0) != 0) {
570 571 return failed;
571 572 }
572 573 if ((ar_member_header =
573 574 (Ar_port *) alloca((int) sizeof(Ar_port))) == NULL){
574 - perror(catgets(catd, 1, 7, "memory allocation failure"));
575 + perror(gettext("memory allocation failure"));
575 576 return failed;
576 577 }
577 578 int ret = read_member_header(ar_member_header, arp->fd, filename);
578 579 if (ret == failed) {
579 580 return failed;
580 581 } else if(ret == -1) {
581 582 /* There is no member header - empty archive */
582 583 return succeeded;
583 584 }
584 585 /* Do we have special member containing long names? */
585 586 if (IS_EQUALN(ar_member_header->ar_name,
586 - NOCATGETS("// "),
587 + "// ",
587 588 16)){
588 589 if (sscanf(ar_member_header->ar_size,
589 590 "%ld",
590 591 &table_size) != 1) {
591 592 return failed;
592 593 }
593 594 *long_names_table = (char *) malloc(table_size);
594 595 /* Read the list of long member names into the table */
595 596 if (fread(*long_names_table, table_size, 1, arp->fd) != 1) {
596 597 return failed;
597 598 }
598 599 arp->first_ar_mem = ftell(arp->fd);
599 600 }
600 601 return succeeded;
601 602 }
602 603
603 604 /*
604 605 * translate_entry(arp, target, member)
605 606 *
606 607 * Finds the member for one lib.a((entry))
607 608 *
608 609 * Parameters:
609 610 * arp Pointer to ar file description block
610 611 * target Target to find member name for
611 612 * member Property to fill in with info
612 613 *
613 614 * Global variables used:
614 615 */
615 616 static void
616 617 translate_entry(register Ar *arp, Name target, register Property member, char **long_names_table)
617 618 {
618 619 register int len;
619 620 register int i;
620 621 wchar_t *member_string;
621 622 ar_port_word *offs;
622 623 int strtablen;
623 624 char *syms; /* string table */
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
624 625 char *csym; /* string table */
625 626 ar_port_word *offend; /* end of offsets table */
626 627 int date;
627 628 register wchar_t *ap;
628 629 register char *hp;
629 630 int maxs;
630 631 int offset;
631 632 char buffer[4];
632 633
633 634 if (arp->sym_begin == 0L || arp->num_symbols == 0L) {
634 - fatal(catgets(catd, 1, 8, "Cannot find symbol `%s' in archive `%s'"),
635 + fatal(gettext("Cannot find symbol `%s' in archive `%s'"),
635 636 member->body.member.entry->string_mb,
636 637 member->body.member.library->string_mb);
637 638 }
638 639
639 640 if (fseek(arp->fd, arp->sym_begin, 0) != 0) {
640 641 goto read_error;
641 642 }
642 643 member_string = ALLOC_WC((int) ((int) ar_member_name_len * 2));
643 644
644 645 switch (arp->type) {
645 646 case AR_5:
646 647 if ((len = member->body.member.entry->hash.length) > 8) {
647 648 len = 8;
648 649 }
649 650 for (i = 0; i < arp->num_symbols; i++) {
650 651 if (fread((char *) &arp->ars_5,
651 652 sizeof arp->ars_5,
652 653 1,
653 654 arp->fd) != 1) {
654 655 goto read_error;
655 656 }
656 657 if (IS_EQUALN(arp->ars_5.sym_name,
657 658 member->body.member.entry->string_mb,
658 659 len)) {
659 660 if ((fseek(arp->fd,
660 661 sgetl(arp->ars_5.sym_ptr),
661 662 0) != 0) ||
662 663 (fread((char *) &arp->arf_5,
663 664 sizeof arp->arf_5,
664 665 1,
665 666 arp->fd) != 1)) {
666 667 goto read_error;
667 668 }
668 669 MBSTOWCS(wcs_buffer, arp->arf_5.arf_name);
669 670 (void) wsncpy(member_string,
670 671 wcs_buffer,
671 672 wslen(wcs_buffer));
672 673 member_string[sizeof(arp->arf_5.arf_name)] =
673 674 (int) nul_char;
674 675 member->body.member.member =
675 676 GETNAME(member_string, FIND_LENGTH);
676 677 target->stat.time.tv_sec = sgetl(arp->arf_5.arf_date);
677 678 target->stat.time.tv_nsec = LONG_MAX;
678 679 return;
679 680 }
680 681 }
681 682 break;
682 683 case AR_PORT:
683 684 offs = (ar_port_word *) alloca((int) (arp->num_symbols * AR_PORT_WORD));
684 685 if (fread((char *) offs,
685 686 AR_PORT_WORD,
686 687 (int) arp->num_symbols,
687 688 arp->fd) != arp->num_symbols) {
688 689 goto read_error;
689 690 }
690 691
691 692 for(i=0;i<arp->num_symbols;i++) {
692 693 *((int*)buffer)=offs[i];
693 694 offs[i]=(ar_port_word)sgetl(buffer);
694 695 }
695 696
696 697 strtablen=arp->sym_size-4-(int) (arp->num_symbols * AR_PORT_WORD);
697 698 syms = (char *) alloca(strtablen);
698 699 if (fread(syms,
699 700 sizeof (char),
700 701 strtablen,
701 702 arp->fd) != strtablen) {
702 703 goto read_error;
703 704 }
704 705 offend = &offs[arp->num_symbols];
705 706 while (offs < offend) {
706 707 maxs = strlen(member->body.member.entry->string_mb);
707 708 if(strlen(syms) > maxs)
708 709 maxs = strlen(syms);
709 710 if (IS_EQUALN(syms,
710 711 member->body.member.entry->string_mb,
711 712 maxs)) {
712 713 if (fseek(arp->fd,
713 714 (long) *offs,
714 715 0) != 0) {
715 716 goto read_error;
716 717 }
717 718 if ((fread((char *) &arp->ar_port,
718 719 sizeof arp->ar_port,
↓ open down ↓ |
74 lines elided |
↑ open up ↑ |
719 720 1,
720 721 arp->fd) != 1) ||
721 722 !IS_EQUALN(arp->ar_port.ar_fmag,
722 723 AR_PORT_END_MAGIC,
723 724 sizeof arp->ar_port.ar_fmag)) {
724 725 goto read_error;
725 726 }
726 727 if (sscanf(arp->ar_port.ar_date,
727 728 "%ld",
728 729 &date) != 1) {
729 - fatal(catgets(catd, 1, 9, "Bad date field for member `%s' in archive `%s'"),
730 + fatal(gettext("Bad date field for member `%s' in archive `%s'"),
730 731 arp->ar_port.ar_name,
731 732 target->string_mb);
732 733 }
733 734 /* If it's a long name, retrieve it from long name table */
734 735 if (arp->ar_port.ar_name[0] == '/') {
735 736 sscanf(arp->ar_port.ar_name + 1,
736 737 "%ld",
737 738 &offset);
738 739 len = ar_member_name_len;
739 740 hp = *long_names_table + offset;
740 741 } else {
741 742 len = sizeof arp->ar_port.ar_name;
742 743 hp = arp->ar_port.ar_name;
743 744 }
744 745 ap = member_string;
745 746 while (*hp &&
746 747 (*hp != (int) slash_char) &&
747 748 (ap < &member_string[len])) {
748 749 MBTOWC(ap, hp);
749 750 ap++;
750 751 hp++;
751 752 }
752 753 *ap = (int) nul_char;
753 754 member->body.member.member =
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
754 755 GETNAME(member_string, FIND_LENGTH);
755 756 target->stat.time.tv_sec = date;
756 757 target->stat.time.tv_nsec = LONG_MAX;
757 758 return;
758 759 }
759 760 offs++;
760 761 while(*syms!='\0') syms++;
761 762 syms++;
762 763 }
763 764 }
764 - fatal(catgets(catd, 1, 10, "Cannot find symbol `%s' in archive `%s'"),
765 + fatal(gettext("Cannot find symbol `%s' in archive `%s'"),
765 766 member->body.member.entry->string_mb,
766 767 member->body.member.library->string_mb);
767 768 /*NOTREACHED*/
768 769
769 770 read_error:
770 771 if (ferror(arp->fd)) {
771 - fatal(catgets(catd, 1, 11, "Read error in archive `%s': %s"),
772 + fatal(gettext("Read error in archive `%s': %s"),
772 773 member->body.member.library->string_mb,
773 774 errmsg(errno));
774 775 } else {
775 - fatal(catgets(catd, 1, 12, "Read error in archive `%s': Premature EOF"),
776 + fatal(gettext("Read error in archive `%s': Premature EOF"),
776 777 member->body.member.library->string_mb);
777 778 }
778 779 }
779 780
780 781 /*
781 782 * sgetl(buffer)
782 783 *
783 784 * The intent here is to provide a means to make the value of
784 785 * bytes in an io-buffer correspond to the value of a long
785 786 * in the memory while doing the io a long at a time.
786 787 * Files written and read in this way are machine-independent.
787 788 *
788 789 * Return value:
789 790 * Long int read from buffer
790 791 * Parameters:
791 792 * buffer buffer we need to read long int from
792 793 *
793 794 * Global variables used:
794 795 */
795 796 static long
796 797 sgetl(register char *buffer)
797 798 {
798 799 register long w = 0;
799 800 register int i = BITSPERBYTE * AR_PORT_WORD;
800 801
801 802 while ((i -= BITSPERBYTE) >= 0) {
802 803 w |= (long) ((unsigned char) *buffer++) << i;
803 804 }
804 805 return w;
805 806 }
806 807
807 808
808 809 /*
809 810 * read_member_header(header, fd, filename)
810 811 *
811 812 * reads the member header for the 4.1.x and SVr4 archives.
812 813 *
813 814 * Return value:
814 815 * fails if read error or member
815 816 * header is not the right format
816 817 * Parameters:
817 818 * header There's one before each archive member
818 819 * fd file descriptor for the archive file.
819 820 *
820 821 * Global variables used:
821 822 */
822 823 int
823 824 read_member_header(Ar_port *header, FILE *fd, char* filename)
824 825 {
825 826 int num = fread((char *) header, sizeof (Ar_port), 1, fd);
826 827 if (num != 1 && feof(fd)) {
827 828 /* There is no member header - empty archive */
↓ open down ↓ |
42 lines elided |
↑ open up ↑ |
828 829 return -1;
829 830 }
830 831 if ((num != 1) ||
831 832 !IS_EQUALN(
832 833 AR_PORT_END_MAGIC,
833 834 header->ar_fmag,
834 835 sizeof (header->ar_fmag)
835 836 )
836 837 ) {
837 838 fatal(
838 - catgets(catd, 1, 28, "Read error in archive `%s': invalid archive file member header at 0x%x"),
839 + gettext("Read error in archive `%s': invalid archive file member header at 0x%x"),
839 840 filename,
840 841 ftell(fd)
841 842 );
842 843 }
843 844 return succeeded;
844 845 }
845 846
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX