⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 server.c

📁 使用TAP的蜂窝型GSM手机短消息服务中心
💻 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 + -