another pass, add NFS export check, writeable disk check
[unix-history] / usr / src / lib / libc / mips / gen / nlist.c
CommitLineData
bb0cfa24 1/*
4142a2c4
KB
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
269a7923 5 * %sccs.include.redist.c%
bb0cfa24
DF
6 */
7
2ce81398 8#if defined(LIBC_SCCS) && !defined(lint)
c5980113 9static char sccsid[] = "@(#)nlist.c 5.8 (Berkeley) %G%";
4142a2c4 10#endif /* LIBC_SCCS and not lint */
329a2d40 11
8fb9f90e 12#include <sys/types.h>
4142a2c4 13#include <sys/file.h>
8fb9f90e
BJ
14#include <a.out.h>
15#include <stdio.h>
c5980113 16#include <string.h>
4142a2c4
KB
17#include <unistd.h>
18
19typedef struct nlist NLIST;
20#define _strx n_un.n_strx
21#define _name n_un.n_name
22#define ISVALID(p) (p->_name && p->_name[0])
8fb9f90e 23
c5980113 24int
8fb9f90e 25nlist(name, list)
c5980113 26 const char *name;
4142a2c4 27 NLIST *list;
8fb9f90e 28{
4142a2c4
KB
29 register NLIST *p, *s;
30 struct exec ebuf;
31 FILE *fstr, *fsym;
32 NLIST nbuf;
76ecedf8 33 off_t strings_offset, symbol_offset, symbol_size, lseek();
4142a2c4
KB
34 int entries, len, maxlen;
35 char sbuf[256];
8fb9f90e 36
4142a2c4
KB
37 entries = -1;
38
39 if (!(fsym = fopen(name, "r")))
329a2d40 40 return(-1);
4142a2c4
KB
41 if (fread((char *)&ebuf, sizeof(struct exec), 1, fsym) != 1 ||
42 N_BADMAG(ebuf))
43 goto done1;
44
45 symbol_offset = N_SYMOFF(ebuf);
46 symbol_size = ebuf.a_syms;
47 strings_offset = symbol_offset + symbol_size;
48 if (fseek(fsym, symbol_offset, SEEK_SET))
49 goto done1;
50
4142a2c4
KB
51 if (!(fstr = fopen(name, "r")))
52 goto done1;
4142a2c4
KB
53
54 /*
55 * clean out any left-over information for all valid entries.
56 * Type and value defined to be 0 if not found; historical
57 * versions cleared other and desc as well. Also figure out
58 * the largest string length so don't read any more of the
59 * string table than we have to.
60 */
61 for (p = list, entries = maxlen = 0; ISVALID(p); ++p, ++entries) {
62 p->n_type = 0;
63 p->n_other = 0;
64 p->n_desc = 0;
65 p->n_value = 0;
66 if ((len = strlen(p->_name)) > maxlen)
67 maxlen = len;
68 }
69 if (++maxlen > sizeof(sbuf)) { /* for the NULL */
70 (void)fprintf(stderr, "nlist: symbol too large.\n");
71 entries = -1;
72 goto done2;
329a2d40 73 }
8fb9f90e 74
12fe6f30 75 for (s = &nbuf; symbol_size; symbol_size -= sizeof(NLIST)) {
4142a2c4
KB
76 if (fread((char *)s, sizeof(NLIST), 1, fsym) != 1)
77 goto done2;
78 if (!s->_strx || s->n_type&N_STAB)
79 continue;
76ecedf8 80 if (fseek(fstr, strings_offset + s->_strx, SEEK_SET))
4142a2c4 81 goto done2;
76ecedf8 82 (void)fread(sbuf, sizeof(sbuf[0]), maxlen, fstr);
4142a2c4
KB
83 for (p = list; ISVALID(p); p++)
84 if (!strcmp(p->_name, sbuf)) {
85 p->n_value = s->n_value;
86 p->n_type = s->n_type;
87 p->n_desc = s->n_desc;
88 p->n_other = s->n_other;
89 if (!--entries)
90 goto done2;
8fb9f90e 91 }
8fb9f90e 92 }
4142a2c4
KB
93done2: (void)fclose(fstr);
94done1: (void)fclose(fsym);
95 return(entries);
8fb9f90e 96}