+ name = emalloc(sizeof(ar_head.ar_name) + strlen(fname) + 3);
+
+ rval = 0;
+
+ /* while there are more entries in the archive */
+ while (fread((char *)&ar_head, sizeof(ar_head), (size_t)1, fp) == 1) {
+ /* bad archive entry - stop processing this archive */
+ if (strncmp(ar_head.ar_fmag, ARFMAG, sizeof(ar_head.ar_fmag))) {
+ (void)fprintf(stderr,
+ "nm: %s: bad format archive header", fname);
+ (void)free(name);
+ return(1);
+ }
+
+ /* remember start position of current archive object */
+ last_ar_off = ftell(fp);
+
+ /* skip ranlib entries */
+ if (!strncmp(ar_head.ar_name, RANLIBMAG, sizeof(RANLIBMAG) - 1))
+ goto skip;
+
+ /*
+ * construct a name of the form "archive.a:obj.o:" for the
+ * current archive entry if the object name is to be printed
+ * on each output line
+ */
+ p = name;
+ if (print_file_each_line)
+ p += sprintf(p, "%s:", fname);
+ for (i = 0; i < sizeof(ar_head.ar_name); ++i)
+ if (ar_head.ar_name[i] && ar_head.ar_name[i] != ' ')
+ *p++ = ar_head.ar_name[i];
+ *p++ = '\0';
+
+ /* get and check current object's header */
+ if (fread((char *)&exec_head, sizeof(exec_head),
+ (size_t)1, fp) != 1) {
+ (void)fprintf(stderr, "nm: %s: premature EOF.\n", name);
+ (void)free(name);
+ return(1);
+ }
+
+ if (N_BADMAG(exec_head)) {
+ if (!ignore_bad_archive_entries) {
+ (void)fprintf(stderr,
+ "nm: %s: bad format.\n", name);
+ rval = 1;
+ }
+ } else {
+ (void)fseek(fp, (long)-sizeof(exec_head),
+ SEEK_CUR);
+ if (!print_file_each_line)
+ (void)printf("\n%s:\n", name);
+ rval |= show_objfile(name, fp);
+ }
+
+ /*
+ * skip to next archive object - it starts at the next
+ * even byte boundary
+ */
+#define even(x) (((x) + 1) & ~1)
+skip: if (fseek(fp, last_ar_off + even(atol(ar_head.ar_size)),
+ SEEK_SET)) {
+ (void)fprintf(stderr,
+ "nm: %s: %s\n", fname, strerror(errno));
+ (void)free(name);
+ return(1);
+ }