+ if (fread((char *)&ebuf, sizeof(struct exec), 1, fsym) != 1 ||
+ N_BADMAG(ebuf))
+ goto done1;
+
+ symbol_offset = N_SYMOFF(ebuf);
+ symbol_size = ebuf.a_syms;
+ strings_offset = symbol_offset + symbol_size;
+ if (fseek(fsym, symbol_offset, SEEK_SET))
+ goto done1;
+
+ /*
+ * some versions of stdio do lseek's on every fseek call relative
+ * to the beginning of the file. For this reason, all string seeks
+ * are made relative to the beginning of the symbol table.
+ */
+ curoff = 0;
+ if (!(fstr = fopen(name, "r")))
+ goto done1;
+ if (fseek(fstr, strings_offset, SEEK_SET))
+ goto done2;
+
+ /*
+ * clean out any left-over information for all valid entries.
+ * Type and value defined to be 0 if not found; historical
+ * versions cleared other and desc as well. Also figure out
+ * the largest string length so don't read any more of the
+ * string table than we have to.
+ */
+ for (p = list, entries = maxlen = 0; ISVALID(p); ++p, ++entries) {
+ p->n_type = 0;
+ p->n_other = 0;
+ p->n_desc = 0;
+ p->n_value = 0;
+ if ((len = strlen(p->_name)) > maxlen)
+ maxlen = len;
+ }
+ if (++maxlen > sizeof(sbuf)) { /* for the NULL */
+ (void)fprintf(stderr, "nlist: symbol too large.\n");
+ entries = -1;
+ goto done2;