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

Web服务器

开发平台:

Unix_Linux

  1. /*
  2. ** util.c        Misc helper functions.
  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 <syslog.h>
  20. #include <string.h>
  21. #include "phttpd.h"
  22. static int get_addr(const char *host, struct in_addr *ia)
  23. {
  24.     if (s_isdigit(*host))
  25. ia->s_addr = inet_addr(host);
  26.     else
  27.     {
  28. struct hostent hp;
  29. int h_errno;
  30. char buf[2048];
  31. if (gethostbyname_r(host, &hp, buf, sizeof(buf), &h_errno) == NULL)
  32.     return -1;
  33. memcpy(ia, hp.h_addr_list[0], hp.h_length);
  34.     }
  35.     return 0;
  36. }
  37. int create_listen_socket(const char *addr, int port)
  38. {
  39.     int one = 1;
  40.     struct sockaddr_in sa_in;
  41. /* fprintf(stderr,"IN...n");  */
  42.     
  43.     if ((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  44.     {
  45. syslog(LOG_ERR, "create_listen_socket(): socket() failed: %m");
  46. return -1;
  47.     }
  48.     
  49.     /* We ignore any error here - not fatal anyway.. */
  50.     setsockopt(listen_sock,
  51.        SOL_SOCKET, SO_REUSEADDR, (void *) &one, sizeof(one));
  52.     
  53.     memset(&sa_in, 0, sizeof(sa_in));
  54.     sa_in.sin_family = AF_INET;
  55.     
  56. /* fprintf(stderr,"IN-1...%sn", (addr == NULL ) ? "<NULL>": addr ); */
  57.     if (addr == NULL || strcmp(addr, "*") == 0)
  58. sa_in.sin_addr.s_addr = INADDR_ANY;
  59.     else
  60. get_addr(addr, &sa_in.sin_addr);
  61. /* fprintf(stderr,"IN-2...n");  */
  62.     sa_in.sin_port = htons(port);
  63. /* fprintf(stderr,"IN-3...n"); */
  64.     
  65.     if (bind(listen_sock, (struct sockaddr *) &sa_in, sizeof(sa_in)))
  66.     {
  67. syslog(LOG_ERR, "create_listen_socket(): bind() failed: %m");
  68. return -1;
  69.     }
  70. /* fprintf(stderr,"IN-4...n");  */
  71.     
  72.     if (listen(listen_sock, n_listen))
  73.     {
  74. syslog(LOG_ERR, "create_listen_socket(): listen() failed: %m");
  75. return -1;
  76.     }
  77.     return listen_sock;
  78. }
  79. void stderr_open(const char *path)
  80. {
  81.     int fd;
  82.     if (debug)
  83. return;
  84.     
  85.     if (path == NULL)
  86.         path = "/dev/null";
  87.     fd = s_open(path, O_WRONLY+O_APPEND+O_CREAT, 0644);
  88.     if (fd < 0)
  89.     {
  90. syslog(LOG_ERR, "stderr_init(): %s: %m", path);
  91.     }
  92.     else if (fd != 2)
  93.     {
  94. s_dup2(fd, 2);
  95. s_close(fd);
  96.     }
  97. }
  98. void become_daemon(void)
  99. {
  100.     pid_t pid;
  101.     int i, fd;
  102.     
  103.     for (i = 0; i < 2; i++)
  104. if (i != listen_sock)
  105. {
  106.     s_close(i);
  107.     
  108.     fd = s_open("/dev/null", O_RDONLY);
  109.     if (fd != i)
  110.     {
  111. s_dup2(fd, i);
  112. s_close(fd);
  113.     }
  114. }
  115.     
  116.     pid = fork();
  117.     if (pid < 0)
  118.     {
  119. syslog(LOG_ERR, "fork() failed: %m");
  120. exit(1);
  121.     }
  122.     else if (pid > 0)
  123. _exit(0);
  124.     
  125.     setsid();
  126. }
  127. static char b64tab[] =
  128. {
  129.     'A','B','C','D','E','F','G','H','I','J','K','L','M',
  130.     'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
  131.     'a','b','c','d','e','f','g','h','i','j','k','l','m',
  132.     'n','o','p','q','r','s','t','u','v','w','x','y','z',
  133.     '0','1','2','3','4','5','6','7','8','9','+','/', 0
  134. };
  135. static int b64tonum(int c)
  136. {
  137.     char *cp;
  138.     cp = strchr(b64tab, c);
  139.     if (cp == NULL)
  140. return -1;
  141.     return cp - b64tab;
  142. }
  143. int base64_decode(const char *b64data, char *buf, int bufsize)
  144. {
  145.     int state, i;
  146.     char *end;
  147.     end = buf + bufsize;
  148.     
  149.     state = 0;
  150.     i = 0;
  151.     while (s_isspace(b64data[i]))
  152. ++i;
  153.     
  154.     while (b64data[i] && b64data[i+1] &&
  155.    b64data[i+2] && b64data[i+3] && buf + 4 < end)
  156.     {
  157. *buf = ((b64tonum(b64data[i]) << 2) +
  158. (b64tonum(b64data[i+1]) >> 4));
  159. if (*buf == -1)
  160.     break;
  161. ++buf;
  162. *buf = ((b64tonum(b64data[i+1]) << 4) +
  163.   (b64tonum(b64data[i+2]) >> 2));
  164. if (*buf == -1)
  165.     break;
  166. ++buf;
  167. *buf = ((b64tonum(b64data[i+2]) << 6) +
  168.   b64tonum(b64data[i+3]));
  169. if (*buf == -1)
  170.     break;
  171. ++buf;
  172. i += 4;
  173.     }
  174.     *buf = '';
  175.     return 1;
  176. }