home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / A / PS / PROCPS-0.000 / PROCPS-0 / procps-0.97 / psupdate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-25  |  6.9 KB  |  303 lines

  1. /*
  2.  * update_db.c    - create/update psdatabase
  3.  *
  4.  * Copyright (c) 1992 Branko Lankester
  5.  *
  6.  * munged into psupdate.c by Michael K. Johnson for the procps suite.
  7.  */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <a.out.h>
  11. #include <unistd.h>
  12. #include <fcntl.h>
  13. #include <string.h>
  14. #include <sys/utsname.h>
  15. #include "psdata.h"
  16. #include "ps.h"
  17.  
  18. #define    SYS_PATH    "/usr/src/linux/tools/zSystem"
  19.  
  20.  
  21. int update_psdb(char *syspath);
  22. int read_nlist(char *systemfile);
  23. int write_tbl(int fd, struct dbtbl_s *dbtbl, struct tbl_s *tbl);
  24. void make_fnctbl(void);
  25. void make_vartbl(void);
  26. __compar_fn_t addrcmp(struct sym_s *p1, struct sym_s *p2);
  27. __compar_fn_t varcmp(struct sym_s *p1, struct sym_s *p2);
  28. unsigned long k_addr(char *sym);
  29.  
  30. static struct nlist *namelist;
  31. static int nsym;
  32. static char *strings;
  33. static int stringsize;
  34.  
  35. int main(int argc, char **argv) {
  36.  
  37.   char nsyspath[128];
  38.  
  39.   if(argc == 1)
  40.     update_psdb(SYS_PATH);
  41.   if(argc == 2) {
  42.     sscanf(argv[1], "%s", nsyspath);
  43.     update_psdb(nsyspath);
  44.   }
  45.   return 0;
  46. }
  47.  
  48.  
  49. /*
  50.  * Open systemfile, if update is non zero the psdatabase will be
  51.  * updated from sysfile. If sysfile is NULL the system file that
  52.  * was used to create the existing database will be used for
  53.  * updating.
  54.  */
  55.  
  56. int open_sys(char *sysfile, int update)
  57. {
  58.  
  59.     if (sysfile == NULL || *sysfile == '\0') {
  60.     if (open_psdb() == -1) {
  61. #if 0
  62.         if (!update)
  63.         return -1;
  64. #else
  65.         read_nlist(SYS_PATH);
  66. #endif
  67.         sysfile = SYS_PATH;
  68.     } else
  69.         sysfile = db_hdr.sys_path;
  70.     } else
  71.     read_nlist(sysfile);
  72.  
  73.     if (update)
  74.     update_psdb(sysfile);
  75.  
  76.     return(0);
  77. }
  78.  
  79.  
  80. int update_psdb(char *syspath)
  81. {
  82.     int fd, sysfd;
  83.     struct utsname uts;
  84.  
  85.     if (namelist == NULL)
  86.     read_nlist(syspath);
  87.     
  88.     close_psdb();
  89.  
  90.     if ((fd = open(PSDATABASE, O_RDWR|O_TRUNC|O_CREAT, 0666)) == -1) {
  91.     perror(PSDATABASE);
  92.     exit(1);
  93.     }
  94.     if (*syspath != '/') {
  95.     memset(db_hdr.sys_path, 0, sizeof db_hdr.sys_path);
  96.     if (getcwd(db_hdr.sys_path, sizeof db_hdr.sys_path - 2) != NULL)
  97.         strcat(db_hdr.sys_path, "/");
  98.     strncat(db_hdr.sys_path, syspath, sizeof db_hdr.sys_path -
  99.                 strlen(db_hdr.sys_path) - 1);
  100.     } else
  101.     strncpy(db_hdr.sys_path, syspath, sizeof db_hdr.sys_path);
  102.     strncpy(db_hdr.magic, PS_MAGIC, sizeof db_hdr.magic);
  103.  
  104. /*    strncpy(db_hdr.swap_path, swappath[0], sizeof db_hdr.swap_path);*/
  105.     strncpy(db_hdr.swap_path, "/dev/swap", sizeof db_hdr.swap_path);
  106.  
  107.  
  108.     make_vartbl();
  109.     make_fnctbl();
  110.  
  111.     write(fd, (char *) &db_hdr, sizeof db_hdr);
  112.     write_tbl(fd, &db_hdr.vars, &vars);
  113.     write_tbl(fd, &db_hdr.fncs, &fncs);
  114.  
  115.     if ((sysfd = open(syspath, O_RDONLY)) == -1) {
  116.     perror(syspath);
  117.     exit(1);
  118.     }
  119.     lseek(sysfd, k_addr("_system_utsname") + 1024, SEEK_SET);
  120.     read(sysfd, (char *) &uts, sizeof(struct utsname));
  121.     close(sysfd);
  122.     strncpy(db_hdr.uts_release, uts.release, sizeof db_hdr.uts_release);
  123.     strncpy(db_hdr.uts_version, uts.version, sizeof db_hdr.uts_version);
  124.  
  125.     lseek(fd, 0L, SEEK_SET);
  126.     write(fd, (char *) &db_hdr, sizeof db_hdr);
  127.     close(fd);
  128.  
  129.     free(namelist);
  130.     namelist = NULL;
  131.     return(0);
  132. }
  133.  
  134. int read_nlist(char *systemfile)
  135. {
  136.     int fd;
  137.     struct exec hdr;
  138.     unsigned symsize, size;
  139.  
  140.     if ((fd = open(systemfile, O_RDONLY)) < 0) {
  141.     perror(systemfile);
  142.     exit(1);
  143.     }
  144.     if (read(fd, (char *) &hdr, sizeof(hdr)) != sizeof(hdr)) {
  145.     perror(systemfile);
  146.     exit(1);
  147.     }
  148.     if (N_BADMAG(hdr)) {
  149.     fprintf(stderr, "%s: bad magic number\n", systemfile);
  150.     exit(1);
  151.     }
  152.     if (N_STROFF(hdr) == 0) {
  153.     fprintf(stderr, "%s has no symbols\n", systemfile);
  154.     exit(1);
  155.     }
  156.     lseek(fd, N_STROFF(hdr), SEEK_SET);
  157.     read(fd, (char *) &stringsize, sizeof(stringsize));
  158.     symsize = N_STROFF(hdr) - N_SYMOFF(hdr);
  159.     size = symsize + stringsize;
  160.     namelist = (struct nlist *) xmalloc(size);
  161.     lseek(fd, N_SYMOFF(hdr), SEEK_SET);
  162.     if (read(fd, (char *) namelist, size) != size) {
  163.     perror(systemfile);
  164.     exit(1);
  165.     }
  166.     close(fd);
  167.  
  168.     strings = ((char *) namelist) + symsize;
  169.     nsym = symsize / sizeof(struct nlist);
  170.     if (Debug > 1)
  171.     fprintf(stderr, "read %d symbols from %s\n", nsym, systemfile);
  172.     return(0);
  173. }
  174.  
  175.  
  176. /*
  177.  * make list of all text symbols, sorted on address for easy
  178.  * lookup of wait channel.
  179.  */
  180. void make_fnctbl(void)
  181. {
  182.     int i;
  183.     struct sym_s *fp;
  184.  
  185.     fp= fncs.tbl= (struct sym_s *) xmalloc(nsym * sizeof(struct sym_s));
  186.     fncs.strings = strings;
  187.     for (i = 0; i < nsym; ++i) {
  188.     if ((namelist[i].n_type & ~N_EXT) == N_TEXT && 
  189.         !strchr(strings + namelist[i].n_un.n_strx, '.')) {
  190.         fp->addr = namelist[i].n_value;
  191.         fp->name = namelist[i].n_un.n_strx;
  192.         ++fp;
  193.     }
  194.     }
  195.     fncs.nsym = fp - fncs.tbl;
  196.  
  197.     if (Debug > 1)
  198.     fprintf(stderr, "%d text symbols\n", fncs.nsym);
  199.     qsort(fncs.tbl, fncs.nsym, sizeof(struct sym_s), (__compar_fn_t) addrcmp);
  200.     if (Debug > 1)
  201.     for (i = 1; i<fncs.nsym; ++i)
  202.         if (fncs.tbl[i].addr == fncs.tbl[i-1].addr)
  203.         printf("text symbols %s and %s both have address %lx\n",
  204.                 strings + fncs.tbl[i-1].name,
  205.             strings + fncs.tbl[i].name, fncs.tbl[i].addr);
  206. }
  207.  
  208.  
  209. void make_vartbl(void)
  210. {
  211.     int i;
  212.     struct sym_s *vp;
  213.  
  214.     vp= vars.tbl= (struct sym_s *) xmalloc(nsym * sizeof(struct sym_s));
  215.     vars.strings = strings;
  216.     for (i = 0; i < nsym; ++i) {
  217.     int typ = namelist[i].n_type & ~N_EXT;
  218.  
  219.     if (typ == N_DATA || typ == N_BSS) {
  220.         vp->addr = namelist[i].n_value;
  221.         vp->name = namelist[i].n_un.n_strx;
  222.         ++vp;
  223.     }
  224.     }
  225.     vars.nsym = vp - vars.tbl;
  226.  
  227.     if (Debug > 1)
  228.     fprintf(stderr, "%d data/bss symbols\n", vars.nsym);
  229.  
  230.     qsort(vars.tbl, vars.nsym, sizeof(struct sym_s), (__compar_fn_t) varcmp);
  231. }
  232.  
  233.  
  234. /*
  235.  * write table tbl to descriptor fd, header structure dbtdl is updated
  236.  */
  237. int write_tbl(int fd, struct dbtbl_s *dbtbl, struct tbl_s *tbl)
  238. {
  239.     int i;
  240.     struct sym_s *p;
  241.     char *s;
  242.     int strsize, symsize;
  243.  
  244.     dbtbl->off = lseek(fd, 0L, SEEK_CUR);
  245.     s= tbl->strings= xmalloc(stringsize);
  246.     for (i = tbl->nsym, p = tbl->tbl; i--; ) {
  247.     strcpy(s, strings + p->name);
  248.     p->name = s - tbl->strings;
  249.     ++p;
  250.     s += strlen(s) + 1;
  251.     }
  252.     symsize = tbl->nsym * sizeof(struct sym_s);
  253.     if (write(fd, (char *) tbl->tbl, symsize) != symsize)
  254.     return -1;
  255.     strsize = (s - tbl->strings + 3) & ~3;
  256.     if (write(fd, tbl->strings, strsize) != strsize)
  257.     return -1;
  258.     
  259.     dbtbl->size = strsize + symsize;
  260.     dbtbl->nsym = tbl->nsym;
  261.  
  262.     return(0);
  263. }
  264.  
  265. /*
  266.  * fncs are sorted on address
  267.  */
  268. __compar_fn_t addrcmp(struct sym_s *p1, struct sym_s *p2)
  269. {
  270.     return((__compar_fn_t)(p1->addr - p2->addr));
  271. }
  272.  
  273.  
  274.  
  275. /*
  276.  * vars are sorted on name
  277.  */
  278. __compar_fn_t varcmp(struct sym_s *p1, struct sym_s *p2)
  279. {
  280.     return((__compar_fn_t)strcmp(vars.strings + p1->name,
  281.                  vars.strings + p2->name));
  282. }
  283.  
  284.  
  285.  
  286. /*
  287.  * get address of data symbol
  288.  */
  289. unsigned long k_addr(char *sym)
  290. {
  291.     struct sym_s *p, key;
  292.  
  293.     if (vars.tbl == NULL)
  294.         read_tbl(&db_hdr.vars, &vars);
  295.  
  296.     key.name = sym - vars.strings;
  297.     p = (struct sym_s *) bsearch(&key, vars.tbl, vars.nsym,
  298.                 sizeof(struct sym_s), (__compar_fn_t) varcmp);
  299.     return(p ? p->addr : -1);
  300. }
  301.  
  302.  
  303.