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