home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / djlsr106.arj / NLIST.C < prev    next >
C/C++ Source or Header  |  1992-03-02  |  4KB  |  113 lines

  1. /* This is file NLIST.C */
  2. /* This file may have been modified by DJ Delorie (Jan 1991).  If so,
  3. ** these modifications are Coyright (C) 1991 DJ Delorie, 24 Kirsten Ave,
  4. ** Rochester NH, 03867-2954, USA.
  5. */
  6.  
  7. /*
  8.  * Copyright (c) 1989 The Regents of the University of California.
  9.  * All rights reserved.
  10.  *
  11.  * Redistribution and use in source and binary forms are permitted
  12.  * provided that: (1) source distributions retain this entire copyright
  13.  * notice and comment, and (2) distributions including binaries display
  14.  * the following acknowledgement:  ``This product includes software
  15.  * developed by the University of California, Berkeley and its contributors''
  16.  * in the documentation or other materials provided with the distribution
  17.  * and in all advertising materials mentioning features or use of this
  18.  * software. Neither the name of the University nor the names of its
  19.  * contributors may be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  22.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  23.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  24.  */
  25.  
  26. #if defined(LIBC_SCCS) && !defined(lint)
  27. static char sccsid[] = "@(#)nlist.c    5.7 (Berkeley) 6/1/90";
  28. #endif /* LIBC_SCCS and not lint */
  29.  
  30. #include <sys/types.h>
  31. #include <sys/file.h>
  32. #include <aout.h>
  33. #include <stdio.h>
  34. #include <unistd.h>
  35.  
  36. typedef struct nlist NLIST;
  37. #define    _strx    n_un.n_strx
  38. #define    _name    n_un.n_name
  39. #define    ISVALID(p)    (p->_name && p->_name[0])
  40.  
  41. nlist(name, list)
  42.     char *name;
  43.     NLIST *list;
  44. {
  45.     register NLIST *p, *s;
  46.     struct exec ebuf;
  47.     FILE *fstr, *fsym;
  48.     NLIST nbuf;
  49.     off_t strings_offset, symbol_offset, symbol_size, lseek();
  50.     int entries, len, maxlen;
  51.     char sbuf[256];
  52.  
  53.     entries = -1;
  54.  
  55.     if (!(fsym = fopen(name, "r")))
  56.         return(-1);
  57.     if (fread((char *)&ebuf, sizeof(struct exec), 1, fsym) != 1 ||
  58.         N_BADMAG(ebuf))
  59.         goto done1;
  60.  
  61.     symbol_offset = N_SYMOFF(ebuf);
  62.     symbol_size = ebuf.a_syms;
  63.     strings_offset = symbol_offset + symbol_size;
  64.     if (fseek(fsym, symbol_offset, SEEK_SET))
  65.         goto done1;
  66.  
  67.     if (!(fstr = fopen(name, "r")))
  68.         goto done1;
  69.  
  70.     /*
  71.      * clean out any left-over information for all valid entries.
  72.      * Type and value defined to be 0 if not found; historical
  73.      * versions cleared other and desc as well.  Also figure out
  74.      * the largest string length so don't read any more of the
  75.      * string table than we have to.
  76.      */
  77.     for (p = list, entries = maxlen = 0; ISVALID(p); ++p, ++entries) {
  78.         p->n_type = 0;
  79.         p->n_other = 0;
  80.         p->n_desc = 0;
  81.         p->n_value = 0;
  82.         if ((len = strlen(p->_name)) > maxlen)
  83.             maxlen = len;
  84.     }
  85.     if (++maxlen > sizeof(sbuf)) {        /* for the NULL */
  86.         (void)fprintf(stderr, "nlist: symbol too large.\n");
  87.         entries = -1;
  88.         goto done2;
  89.     }
  90.  
  91.     for (s = &nbuf; symbol_size; symbol_size -= sizeof(NLIST)) {
  92.         if (fread((char *)s, sizeof(NLIST), 1, fsym) != 1)
  93.             goto done2;
  94.         if (!s->_strx || s->n_type&N_STAB)
  95.             continue;
  96.         if (fseek(fstr, strings_offset + s->_strx, SEEK_SET))
  97.             goto done2;
  98.         (void)fread(sbuf, sizeof(sbuf[0]), maxlen, fstr);
  99.         for (p = list; ISVALID(p); p++)
  100.             if (!strcmp(p->_name, sbuf)) {
  101.                 p->n_value = s->n_value;
  102.                 p->n_type = s->n_type;
  103.                 p->n_desc = s->n_desc;
  104.                 p->n_other = s->n_other;
  105.                 if (!--entries)
  106.                     goto done2;
  107.             }
  108.     }
  109. done2:    (void)fclose(fstr);
  110. done1:    (void)fclose(fsym);
  111.     return(entries);
  112. }
  113.