modules.c
上传用户:ladybrid91
上传日期:2007-01-04
资源大小:287k
文件大小:4k
源码类别:

Web服务器

开发平台:

Unix_Linux

  1. /*
  2. ** modules.c
  3. **
  4. ** Copyright (c) 1995 Peter Eriksson <pen@signum.se>
  5. **
  6. ** This program is free software; you can redistribute it and/or modify
  7. ** it under the terms of the GNU General Public License as published by
  8. ** the Free Software Foundation; either version 2 of the License, or
  9. ** (at your option) any later version.
  10. **
  11. ** This program is distributed in the hope that it will be useful,
  12. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ** GNU General Public License for more details.
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program; if not, write to the Free Software
  17. ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <thread.h>
  22. #include <synch.h>
  23. #include <dlfcn.h>
  24. #include <errno.h>
  25. #include <sys/stat.h>
  26. #include "phttpd.h"
  27. static hashtable_t modlist_table;
  28. void md_init(void)
  29. {
  30.     ht_init(&modlist_table, 0, NULL);
  31. }
  32. static void _md_unload(struct modinfo *mp)
  33. {
  34.     if (debug > 2)
  35. fprintf(stderr, "_md_unload("%s")n", mp->name);
  36.     
  37.     dlclose(mp->libp);
  38.     mp->libp = NULL;
  39.     
  40.     mp->mtime = 0;
  41.     mp->update = 0;
  42.     mp->use = 0;
  43.     mp->pm_init = NULL;
  44.     mp->pm_exit = NULL;
  45.     mp->pm_request = NULL;
  46.     mp->pm_auth = NULL;
  47. }
  48. static int _md_load(struct modinfo *mp)
  49. {
  50.     int status;
  51.     struct stat sb;
  52.     const char *argv[2];
  53.     
  54.     if (debug > 2)
  55. fprintf(stderr, "_md_load("%s")n", mp->name);
  56.     
  57.     while ((status = s_stat(mp->name, &sb)) < 0 &&
  58.    errno == EINTR)
  59. ;
  60.     if (status < 0)
  61. return -1;
  62.     
  63.     mp->libp = dlopen(mp->name, RTLD_NOW);
  64.     if (mp->libp == NULL)
  65. return -1;
  66.     
  67.     mp->mtime = sb.st_mtime;
  68.     mp->update = 0;
  69.     mp->use = 0;
  70.     
  71.     mp->pm_init = (int (*)(const char **))
  72. dlsym(mp->libp, "pm_init");
  73.     
  74.     mp->pm_exit = (void (*)(void))
  75. dlsym(mp->libp, "pm_exit");
  76.     
  77.     mp->pm_request = (int (*)(struct connectioninfo *cip))
  78. dlsym(mp->libp, "pm_request");
  79.     mp->pm_auth = (int (*)(struct authinfo *aip, struct connectioninfo *cip,
  80.    const char *))
  81. dlsym(mp->libp, "pm_auth");
  82.     
  83.     argv[0] = mp->name;
  84.     argv[1] = NULL;
  85.     if (mp->pm_init)
  86.     {
  87. if (mp->pm_init(argv) < 0)
  88. {
  89.     /* Module init failed, do something */
  90.     if (debug > 2)
  91. fprintf(stderr, "%s:pm_init() failedn", argv[0]);
  92.     
  93.     _md_unload(mp);
  94.     return -2;
  95. }
  96.     }
  97.     return 0;
  98. }
  99. int md_release(void *key)
  100. {
  101.     if (debug > 2)
  102. fprintf(stderr, "md_release()n");
  103.     ht_release((hashentry_t *) key);
  104.     
  105.     return 0;
  106. }
  107. struct modinfo *md_load(const char *name, void **key)
  108. {
  109.     struct modinfo *mp;
  110.     hashentry_t *hep;
  111.     
  112.     if (debug > 2)
  113. fprintf(stderr, "md_load("%s")n", name);
  114.     hep = ht_lookup(&modlist_table, name, 0);
  115.     if (hep)
  116.     {
  117. mp = (struct modinfo *) hep->data;
  118. *key = (void *) hep;
  119. return mp;
  120.     }
  121.     
  122.     mp = s_malloc(sizeof(struct modinfo));
  123.     mp->name = s_strdup(name);
  124.     if (_md_load(mp) < 0)
  125.     {
  126. s_free(mp->name);
  127. s_free(mp);
  128. return NULL;
  129.     }
  130.     
  131.     hep = ht_insert(&modlist_table, mp->name, 0, mp, HTF_REPLACE, NULL);
  132.     *key = hep;
  133.     return (struct modinfo *) hep->data;
  134. }
  135. struct ht_foreach_s
  136. {
  137.     int (*fcnp)(struct modinfo *mp, void *misc);
  138.     void *misc;
  139. };
  140. static int ht_foreach_fun(hashentry_t *hep,
  141.   void *misc)
  142. {
  143.     struct ht_foreach_s *hfsp;
  144.     hfsp = misc;
  145.     return hfsp->fcnp(hep->data, hfsp->misc);
  146. }
  147. int md_foreach(int (*fcnp)(struct modinfo *mp, void *misc), void *misc)
  148. {
  149.     struct ht_foreach_s hfs;
  150.     hfs.fcnp = fcnp;
  151.     hfs.misc = misc;
  152.     
  153.     return ht_foreach(&modlist_table, ht_foreach_fun, &hfs);
  154. }
  155. const char *md_error(void)
  156. {
  157.     const char *msg;
  158.     msg = dlerror();
  159.     if (msg == NULL)
  160. msg = strerror(errno);
  161.     return msg;
  162. }