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

Web服务器

开发平台:

Unix_Linux

  1. /*
  2. ** ident.c IDENT (RFC1413) lookup routines
  3. **
  4. ** Copyright (c) 1994-1997 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 <errno.h>
  20. #include <string.h>
  21. #include <syslog.h>
  22. #define IN_IDENT_C
  23. #include "phttpd.h"
  24. static void *ident_thread(identinfo_t *iip)
  25. {
  26.     int fd, p1, p2;
  27.     struct sockaddr_in sin;
  28.     char buf[2048];
  29.     char *user = NULL;
  30.     char *os = NULL;
  31.     char *error = NULL;
  32.     char *scp, *cp;
  33.     int saved_errno = 0;
  34.     
  35.     
  36.     sin = iip->remote;
  37.     sin.sin_port = htons(113);
  38.     
  39.     fd = fd_connect((struct sockaddr *) &sin, sizeof(sin));
  40.     if (fd < 0)
  41.     {
  42. saved_errno = errno;
  43. error = s_strdup("protocol error: connection refused");
  44. goto Done;
  45.     }
  46.     
  47.     fd_printf(fd, "%d , %dn",
  48.       ntohs(iip->remote.sin_port),
  49.       ntohs(iip->local.sin_port));
  50.     
  51.     fd_shutdown(fd, 1);
  52.     if (fd_gets(buf, sizeof(buf), fd) == NULL)
  53.     {
  54. saved_errno = errno;
  55. error = s_strdup("protocol error: no data");
  56. goto Done;
  57.     }
  58.     
  59.     cp = strtok_r(buf, ":", &scp);
  60.     if (cp)
  61.     {
  62. /* Got "port,port" pair */
  63. if (sscanf(cp, " %d , %d ", &p1, &p2) != 2)
  64. {
  65.     saved_errno = errno;
  66.     error = s_strdup("protocol error: port pair format");
  67.     goto Done;
  68. }
  69. if ((p1 != ntohs(iip->remote.sin_port)) ||
  70.     (p2 != ntohs(iip->local.sin_port)))
  71. {
  72.     saved_errno = errno;
  73.     error = s_strdup("protocol error: invalid ports");
  74.     goto Done;
  75. }
  76. cp = strtok_r(NULL, " trn:", &scp);
  77. if (cp)
  78. {
  79.     /* Got "USERID" or "ERROR" */
  80.     
  81.     if (strcasecmp(cp, "USERID") == 0)
  82.     {
  83. cp = strtok_r(NULL, " trn:", &scp);
  84. if (cp)
  85. {
  86.     /* Got OS-name */
  87.     os = s_strdup(cp);
  88.     
  89.     cp = strtok_r(NULL, "rn", &scp);
  90.     if (cp)
  91.     {
  92. /* Got ident identifier */
  93. user = s_strdup(cp);
  94. goto Done;
  95.     }
  96. }
  97.     }
  98.     else if (strcasecmp(cp, "ERROR") == 0)
  99.     {
  100. cp = strtok_r(NULL, "rn", &scp);
  101. if (cp)
  102. {
  103.     error = s_strdup(cp);
  104.     goto Done;
  105. }
  106.     }
  107. }
  108.     }
  109.     
  110.   Done:
  111.     if (fd >= 0)
  112. fd_close(fd);
  113.     
  114.     mutex_lock(&iip->mtx);
  115.     
  116.     iip->error = error;
  117.     iip->os = os;
  118.     iip->user = user;
  119.     
  120.     iip->saved_errno = saved_errno;
  121.     iip->state = 1;
  122.     
  123.     cond_broadcast(&iip->cv);
  124.     mutex_unlock(&iip->mtx);
  125.     return NULL;
  126. }
  127. static void _ident_start(identinfo_t *iip)
  128. {
  129.     mutex_init(&iip->mtx, USYNC_THREAD, NULL);
  130.     cond_init(&iip->cv, USYNC_THREAD, NULL);
  131.     
  132.     iip->error = NULL;
  133.     iip->os = NULL;
  134.     iip->user = NULL;
  135.     iip->saved_errno = 0;
  136.     iip->state = 0;
  137.     
  138.     if (thr_create(NULL,
  139.    0,
  140.    (void *(*)(void *)) ident_thread,
  141.    (void *) iip,
  142.    THR_DETACHED,
  143.    NULL))
  144.     {
  145. syslog(LOG_ERR, "thr_create(ident_thread) failed: %m");
  146.     }
  147. }
  148. identinfo_t *ident_lookup(struct sockaddr_in *remote,
  149.   struct sockaddr_in *local)
  150. {
  151.     identinfo_t *iip;
  152.     iip = s_malloc(sizeof(*iip));
  153.     iip->remote = *remote;
  154.      iip->local = *local;
  155.     _ident_start(iip);
  156.     return iip;
  157. }
  158. int ident_get(identinfo_t *iip,
  159.       char **error,
  160.       char **os,
  161.       char **user)
  162. {
  163.     if (iip == NULL)
  164. return -1;
  165.     
  166.     mutex_lock(&iip->mtx);
  167.     while (iip->state == 0) {
  168. cond_wait(&iip->cv, &iip->mtx);
  169.     }
  170.     mutex_unlock(&iip->mtx);
  171.     if (error)
  172. *error = iip->error;
  173.     if (os)
  174. *os = iip->os;
  175.     if (user)
  176. *user = iip->user;
  177.     return iip->saved_errno;
  178. }
  179. void ident_free(identinfo_t *iip)
  180. {
  181.     if (iip == NULL)
  182. return;
  183.     
  184.     /* Make sure the thread has terminated */
  185.     (void) ident_get(iip, NULL, NULL, NULL);
  186.     
  187.     mutex_destroy(&iip->mtx);
  188.     cond_destroy(&iip->cv);
  189.     s_free(iip->error);
  190.     s_free(iip->os);
  191.     s_free(iip->user);
  192.     s_free(iip);
  193. }