server.c
上传用户:mei_mei897
上传日期:2007-01-05
资源大小:82k
文件大小:8k
源码类别:

手机短信编程

开发平台:

Unix_Linux

  1. /* -------------------------------------------------------------------- */
  2. /* SMS Client, send messages to mobile phones and pagers */
  3. /* */
  4. /* server.c */
  5. /* */
  6. /*  Copyright (C) 1997,1998 Angelo Masci */
  7. /* */
  8. /*  This library is free software; you can redistribute it and/or */
  9. /*  modify it under the terms of the GNU Library General Public */
  10. /*  License as published by the Free Software Foundation; either */
  11. /*  version 2 of the License, or (at your option) any later version. */
  12. /* */
  13. /*  This library is distributed in the hope that it will be useful, */
  14. /*  but WITHOUT ANY WARRANTY; without even the implied warranty of */
  15. /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU */
  16. /*  Library General Public License for more details. */
  17. /* */
  18. /*  You should have received a copy of the GNU Library General Public */
  19. /*  License along with this library; if not, write to the Free */
  20. /*  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  21. /* */
  22. /*  You can contact the author at this e-mail address: */
  23. /* */
  24. /*  angelo@styx.demon.co.uk */
  25. /* */
  26. /* --------------------------------------------------------------------
  27.    $Id$
  28.    -------------------------------------------------------------------- */
  29. #include <stdio.h>
  30. #include <ctype.h>
  31. #include <stdlib.h>
  32. #include <unistd.h>
  33. #include <errno.h>
  34. #include <string.h>
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #include <fcntl.h>
  38. #include <stdarg.h>
  39. #include <pwd.h>
  40. #include <netinet/in.h>
  41. #include <sys/socket.h>
  42. #include <arpa/inet.h>
  43. #include <sys/wait.h>
  44. #include <signal.h>
  45. #include <netdb.h>
  46. #include "server.h"
  47. #include "logfile.h"
  48. #include "common.h"
  49. /* -------------------------------------------------------------------- */
  50. #if !defined(WNOHANG)
  51. #define WNOHANG 0
  52. #endif
  53. /* -------------------------------------------------------------------- */
  54. /* Read a complete 'n' terminated string from socket */
  55. /* upto maxlen characters will be read and a '' is appended */
  56. /* -------------------------------------------------------------------- */
  57. char *hgets(char *buf, int maxlen, int fd)
  58. {
  59. int result, 
  60. i;
  61. /* NOTE -  */
  62. /* As this function now uses recv instead of read */
  63. /* it probably makes sense to use the MSG_PEEK functionality */
  64. /* to read a block of data find the newline and then */
  65. /* make another call to receive with the correct length */
  66. /* of the line. */
  67. i = 0;
  68. buf[0] = '';
  69. while (i < (maxlen -1))
  70. {
  71. result = read(fd, &buf[i], 1);
  72. if (result < 0) 
  73. {  if (errno != EINTR) 
  74. { lprintf(LOG_ERROR, "read() failed");
  75. exit(-1);
  76. }
  77. }
  78. else
  79. if (result == 0)
  80. {
  81. buf[i+1] = '';
  82. if (i == 0)
  83. { return NULL;
  84. }
  85. break;
  86. }
  87. else
  88. { if (buf[i] == 'n')
  89. { i++;
  90. break;
  91. }
  92. i++;
  93. }
  94. }
  95. buf[i] = '';
  96. return buf;
  97. }
  98. /* -------------------------------------------------------------------- */
  99. /* -------------------------------------------------------------------- */
  100. void hprintf(int fd, char *fmt, ...)
  101. {
  102. va_list args;
  103. int line_len,
  104. len;
  105. static char line[MAX_STRING_LEN];
  106. char *line_ptr;
  107. /* ---------------------------- */
  108. va_start(args, fmt);
  109. vsprintf(line, fmt, args);
  110. va_end(args);
  111. line_len = sms_strlen(line);
  112. line_ptr = line;
  113. while ((len = write(fd, line_ptr, line_len)) != line_len)
  114. {
  115. if (len < 0)
  116. { if (errno == EINTR)
  117. { continue;
  118. }
  119. else
  120. { lprintf(LOG_ERROR, "write() failed");
  121. exit(-1);
  122. }
  123. }
  124. line_ptr += len;
  125. line_len -= len;
  126. }
  127. }
  128. /* -------------------------------------------------------------------- */
  129. /* Reap child processes on receipt of SIGCHLD */
  130. /* -------------------------------------------------------------------- */
  131. #if defined(LINUX) || defined(SOLARIS)
  132. void sigchld_handler(int signum)
  133. {
  134. while (waitpid((pid_t)-1, NULL, WNOHANG) > 0)
  135. {
  136. /* Reap children */
  137. }
  138. signal(SIGCHLD, sigchld_handler); /* Re-establish signal  */
  139. /* handler  */
  140. }
  141. #endif
  142. /* -------------------------------------------------------------------- */
  143. /* -------------------------------------------------------------------- */
  144. int server_init(int server_port)
  145. {
  146.         int  sockfd;   /* listen on sock_fd */
  147. struct  sockaddr_in 
  148. server_addr;    /* my address information  */
  149. if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  150. { lprintf(LOG_ERROR, "socket() failedn");
  151. return(-1);
  152. }
  153. server_addr.sin_family      = AF_INET;  /* host byte order  */
  154. server_addr.sin_port        = htons(server_port);  /* short, network byte order  */
  155. server_addr.sin_addr.s_addr = INADDR_ANY;  /* auto-fill with my IP  */
  156. memset(&(server_addr.sin_zero), 0, 8); /* zero rest of struct  */
  157. if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0)
  158. {
  159. switch (errno)
  160. {
  161. case EADDRINUSE:
  162. lprintf(LOG_ERROR, "bind() - Socket %d allready in usen", server_port);
  163. break;
  164. case EACCES:
  165. lprintf(LOG_ERROR, "bind() - Socket %d protected port and not superusern", server_port);
  166. break;
  167. default:
  168. lprintf(LOG_ERROR, "bind() failedn");
  169. }
  170. return(-1);
  171. }
  172. if (listen(sockfd, MAX_BACKLOG) < 0)
  173. { lprintf(LOG_ERROR, "listen() failedn");
  174. return(-1);
  175. }
  176. lprintf(LOG_STANDARD, "Listening on port %dn", server_port);
  177. return sockfd;
  178. }
  179. /* -------------------------------------------------------------------- */
  180. /* -------------------------------------------------------------------- */
  181. int server_main(int server_port, void (*handle_child)(int new_fd))
  182. {
  183. pid_t pid;
  184. int  sockfd,
  185.   sin_size,
  186.   new_fd;
  187. struct  sockaddr_in 
  188. client_addr;  /* connector's address information  */
  189. sockfd = server_init(server_port);
  190. if (sockfd == -1)
  191. { return(1);
  192. }
  193. if (deamon_init() != 0)
  194. { return(1);
  195. }
  196. #if defined(LINUX) || defined(SOLARIS)
  197. signal(SIGCHLD, sigchld_handler);
  198. #else
  199. signal(SIGCHLD, SIG_IGN); /* Automagically reap zombies  */
  200. /* under SYSV */
  201. #endif
  202. set_consolelog(FALSE); /* No more login output */
  203. /* to be sent to the console */
  204. while(TRUE)
  205. {
  206. /* main accept() loop */
  207. sin_size = sizeof(struct sockaddr_in);
  208. if ((new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size)) < 0)
  209. {
  210. if (errno == EINTR)
  211. { continue;
  212. }
  213. else
  214. { lprintf(LOG_ERROR, "accept failedn");
  215. exit(-1);
  216. }
  217. }
  218. pid = fork();
  219. if (pid == 0)
  220. {
  221. (*handle_child)(new_fd);
  222. close(new_fd);
  223. exit(0);
  224. }
  225. else if (pid < 0)
  226. { lprintf(LOG_ERROR, "Trying to fork child processn");
  227. exit(-1);
  228. }
  229. close(new_fd);
  230. }
  231. return 0;
  232. }
  233. /* -------------------------------------------------------------------- */
  234. /* -------------------------------------------------------------------- */
  235. void default_echo(int new_fd)
  236. {
  237. char buf[MAX_STRING_LEN];
  238. while (hgets(buf, MAX_STRING_LEN, new_fd) != NULL)
  239. { printf("Received Data +%s+n", buf);
  240. hprintf(new_fd, "Echo: +%s+n", buf);
  241. }
  242. }
  243. /* -------------------------------------------------------------------- */
  244. /* -------------------------------------------------------------------- */
  245. int deamon_init(void)
  246. {
  247. pid_t pid;
  248. pid = fork();
  249. if (pid < 0)
  250. { return -1;
  251. }
  252. else 
  253. if (pid != 0)
  254. { exit(0); /* Parent Exits */
  255. }
  256. if (setsid() < 0) /* Become session leader  */
  257. {
  258. lprintf(LOG_ERROR, "setsid failedn");
  259. exit(-1);
  260. }
  261. if (chdir("/") < 0) /* Change working directory */
  262. {
  263. lprintf(LOG_ERROR, "chdir failedn");
  264. exit(-1);
  265. }
  266. return 0;
  267. }
  268. /* -------------------------------------------------------------------- */
  269. /* -------------------------------------------------------------------- */
  270. int get_client_information(int fd, char *host_name, char *ip_address)
  271. {
  272. int  sin_size;
  273. struct  sockaddr_in 
  274. client_addr;  /* connector's address information  */
  275. struct  hostent
  276. *host;
  277. u_long addr;
  278. sin_size = sizeof(struct sockaddr_in);
  279. if ((getpeername(fd, (struct sockaddr *)&client_addr, &sin_size)) < 0)
  280. { return -1;
  281. }
  282. sms_strcpy(ip_address, inet_ntoa(client_addr.sin_addr));
  283. addr = inet_addr(ip_address);
  284. host = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET);
  285. if (host != NULL)
  286. { sms_strcpy(host_name, host->h_name);
  287. }
  288. else
  289. { sms_strcpy(host_name, "");
  290. }
  291. return 0;
  292. }