?? server.c
字號:
/* -------------------------------------------------------------------- *//* SMS Client, send messages to mobile phones and pagers *//* *//* server.c *//* *//* Copyright (C) 1997,1998 Angelo Masci *//* *//* This library is free software; you can redistribute it and/or *//* modify it under the terms of the GNU Library General Public *//* License as published by the Free Software Foundation; either *//* version 2 of the License, or (at your option) any later version. *//* *//* This library is distributed in the hope that it will be useful, *//* but WITHOUT ANY WARRANTY; without even the implied warranty of *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *//* Library General Public License for more details. *//* *//* You should have received a copy of the GNU Library General Public *//* License along with this library; if not, write to the Free *//* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* *//* You can contact the author at this e-mail address: *//* *//* angelo@styx.demon.co.uk *//* *//* -------------------------------------------------------------------- $Id$ -------------------------------------------------------------------- */#include <stdio.h>#include <ctype.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <stdarg.h>#include <pwd.h>#include <netinet/in.h>#include <sys/socket.h>#include <arpa/inet.h>#include <sys/wait.h>#include <signal.h>#include <netdb.h>#include "server.h"#include "logfile.h"#include "common.h"/* -------------------------------------------------------------------- */#if !defined(WNOHANG)#define WNOHANG 0#endif/* -------------------------------------------------------------------- *//* Read a complete '\n' terminated string from socket *//* upto maxlen characters will be read and a '\0' is appended *//* -------------------------------------------------------------------- */char *hgets(char *buf, int maxlen, int fd){ int result, i; /* NOTE - */ /* As this function now uses recv instead of read */ /* it probably makes sense to use the MSG_PEEK functionality */ /* to read a block of data find the newline and then */ /* make another call to receive with the correct length */ /* of the line. */ i = 0; buf[0] = '\0'; while (i < (maxlen -1)) { result = read(fd, &buf[i], 1); if (result < 0) { if (errno != EINTR) { lprintf(LOG_ERROR, "read() failed"); exit(-1); } } else if (result == 0) { buf[i+1] = '\0'; if (i == 0) { return NULL; } break; } else { if (buf[i] == '\n') { i++; break; } i++; } } buf[i] = '\0'; return buf;}/* -------------------------------------------------------------------- *//* -------------------------------------------------------------------- */void hprintf(int fd, char *fmt, ...){ va_list args; int line_len, len;static char line[MAX_STRING_LEN]; char *line_ptr; /* ---------------------------- */ va_start(args, fmt); vsprintf(line, fmt, args); va_end(args); line_len = sms_strlen(line); line_ptr = line; while ((len = write(fd, line_ptr, line_len)) != line_len) { if (len < 0) { if (errno == EINTR) { continue; } else { lprintf(LOG_ERROR, "write() failed"); exit(-1); } } line_ptr += len; line_len -= len; }}/* -------------------------------------------------------------------- *//* Reap child processes on receipt of SIGCHLD *//* -------------------------------------------------------------------- */#if defined(LINUX) || defined(SOLARIS)void sigchld_handler(int signum){ while (waitpid((pid_t)-1, NULL, WNOHANG) > 0) { /* Reap children */ } signal(SIGCHLD, sigchld_handler); /* Re-establish signal */ /* handler */}#endif/* -------------------------------------------------------------------- *//* -------------------------------------------------------------------- */int server_init(int server_port){ int sockfd; /* listen on sock_fd */ struct sockaddr_in server_addr; /* my address information */ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { lprintf(LOG_ERROR, "socket() failed\n"); return(-1); } server_addr.sin_family = AF_INET; /* host byte order */ server_addr.sin_port = htons(server_port); /* short, network byte order */ server_addr.sin_addr.s_addr = INADDR_ANY; /* auto-fill with my IP */ memset(&(server_addr.sin_zero), 0, 8); /* zero rest of struct */ if (bind(sockfd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) < 0) { switch (errno) { case EADDRINUSE: lprintf(LOG_ERROR, "bind() - Socket %d allready in use\n", server_port); break; case EACCES: lprintf(LOG_ERROR, "bind() - Socket %d protected port and not superuser\n", server_port); break; default: lprintf(LOG_ERROR, "bind() failed\n"); } return(-1); } if (listen(sockfd, MAX_BACKLOG) < 0) { lprintf(LOG_ERROR, "listen() failed\n"); return(-1); } lprintf(LOG_STANDARD, "Listening on port %d\n", server_port); return sockfd;}/* -------------------------------------------------------------------- *//* -------------------------------------------------------------------- */int server_main(int server_port, void (*handle_child)(int new_fd)){ pid_t pid; int sockfd, sin_size, new_fd; struct sockaddr_in client_addr; /* connector's address information */ sockfd = server_init(server_port); if (sockfd == -1) { return(1); } if (deamon_init() != 0) { return(1); }#if defined(LINUX) || defined(SOLARIS) signal(SIGCHLD, sigchld_handler);#else signal(SIGCHLD, SIG_IGN); /* Automagically reap zombies */ /* under SYSV */#endif set_consolelog(FALSE); /* No more login output */ /* to be sent to the console */ while(TRUE) { /* main accept() loop */ sin_size = sizeof(struct sockaddr_in); if ((new_fd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size)) < 0) { if (errno == EINTR) { continue; } else { lprintf(LOG_ERROR, "accept failed\n"); exit(-1); } } pid = fork(); if (pid == 0) { (*handle_child)(new_fd); close(new_fd); exit(0); } else if (pid < 0) { lprintf(LOG_ERROR, "Trying to fork child process\n"); exit(-1); } close(new_fd); } return 0;}/* -------------------------------------------------------------------- *//* -------------------------------------------------------------------- */void default_echo(int new_fd){ char buf[MAX_STRING_LEN]; while (hgets(buf, MAX_STRING_LEN, new_fd) != NULL) { printf("Received Data +%s+\n", buf); hprintf(new_fd, "Echo: +%s+\n", buf); } }/* -------------------------------------------------------------------- *//* -------------------------------------------------------------------- */int deamon_init(void){ pid_t pid; pid = fork(); if (pid < 0) { return -1; } else if (pid != 0) { exit(0); /* Parent Exits */ } if (setsid() < 0) /* Become session leader */ { lprintf(LOG_ERROR, "setsid failed\n"); exit(-1); } if (chdir("/") < 0) /* Change working directory */ { lprintf(LOG_ERROR, "chdir failed\n"); exit(-1); } return 0;}/* -------------------------------------------------------------------- *//* -------------------------------------------------------------------- */int get_client_information(int fd, char *host_name, char *ip_address){ int sin_size; struct sockaddr_in client_addr; /* connector's address information */ struct hostent *host; u_long addr; sin_size = sizeof(struct sockaddr_in); if ((getpeername(fd, (struct sockaddr *)&client_addr, &sin_size)) < 0) { return -1; } sms_strcpy(ip_address, inet_ntoa(client_addr.sin_addr)); addr = inet_addr(ip_address); host = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); if (host != NULL) { sms_strcpy(host_name, host->h_name); } else { sms_strcpy(host_name, ""); } return 0;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -