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