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

📄 transerver.cc

📁 此源代码只用于学习,不得用于其他商业活动 .
💻 CC
字号:
/*
* Copyright (c) 2002, 南京联创系统集成股份有限公司综合结算产品部
* All rights reserved.
*
* 文件名称:transerver.cc
* 摘    要:传输服务器端
*
* 当前版本:
* 作    者:冯亮(fengl@lianchuang.com)
* 完成日期:
*/
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/socket.h>
#include <string.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/param.h>
#include <signal.h>
#include <syslog.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <sys/utsname.h>
#include <netdb.h>
#include <limits.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/resource.h>
#include <sys/wait.h>
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include "transerver.h"

struct GOBALINFO GobalInfo;
struct GOBALMUTEX GobalMutex;

int main(int argc, char **argv)
{
	int on;
	/*客户端,服务端地址*/
	struct sockaddr_in cliaddr, servaddr;

	int clilen;
	int listenfd, connfd;

	fd_set rset, allset;
	pthread_t tid;

	if(argc > 1)
	{
		if(strcmp(argv[1], "-k") == 0)
		{
			KillProc(argc, argv);
			printf("%s killed!\n", argv[0]);
			return 0;
		}
		else
		{
			printf("%s: runtime param error! \n", argv[0]);
			return -1;
		}
	}

	if(1 == ProcIsExist(argc, argv))
	{
		Runing();
		return -1;
	}

	memset(&GobalInfo, 0, sizeof(struct GOBALINFO));
	GetExePath();
	Init_GobalInfo();

	if(1 == GobalInfo.iDaemonFlag)
	{
		Init_Daemon();
	}

	Init_GobalMutex();

	signal(SIGHUP, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);
	signal(SIGTERM, UserTerm);
	signal(SIGINT, SIG_IGN);

	if((listenfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("socket init error");
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		return -1;
	}
	bzero(&servaddr, sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(GobalInfo.iListenPort);
	/*防止此端口上已有连接存在*/
	setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on));

	#if defined(xlC) || defined(CC) || defined(gcc)
	if(bind(listenfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) == -1)
	#else
	if(bind(listenfd, &servaddr, sizeof(servaddr)) == -1)
	#endif
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("Bind socket Error");
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		close(listenfd);
		listenfd = -1;
		return -1;
	}
	if(listen(listenfd, QLEN) == -1)
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("Listen socket Error");
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		close(listenfd);
		listenfd = -1;
		return -1;
	}

	FD_ZERO(&allset);
	FD_SET(listenfd,&allset);

	while(GobalInfo.iRunFlag)
	{
		rset = allset;
		if(select(listenfd + 1, &rset, 0, 0, 0) == -1)
		{
			if (errno == EINTR || errno == EBADF || errno == 0)
			{
				continue;
			}
			pthread_mutex_lock(&GobalMutex.AlertMutex);
			Msg("select error");
			pthread_mutex_unlock(&GobalMutex.AlertMutex);
			close(listenfd);
			listenfd = -1;
			break;
		}
		if(FD_ISSET(listenfd, &rset))
		{
			clilen = sizeof(cliaddr);
			
			#ifdef aCC
			if((connfd = accept(listenfd, &servaddr, &clilen)) == -1)
			#endif
			
			#ifdef CC
			if((connfd = accept(listenfd, (struct sockaddr *)&servaddr, &clilen)) == -1)
			#endif
			
			#if defined(xlC) || defined(gcc)
			if((connfd = accept(listenfd, (struct sockaddr *)&servaddr, (socklen_t *)&clilen)) == -1)
			#endif
			
			{
				pthread_mutex_lock(&GobalMutex.AlertMutex);
				Msg("accept socket eroor");
				pthread_mutex_unlock(&GobalMutex.AlertMutex);
				continue;
			}
			else
			{
				/*客户连接*/
				if(pthread_create(&tid, 0, TransferServer, ( void * )connfd ) != 0)
				{
					pthread_mutex_lock(&GobalMutex.AlertMutex);
					Msg("Create thread error");
					pthread_mutex_unlock(&GobalMutex.AlertMutex);
					continue;
				}
			}
		}//end if(FD_ISSET(listenfd, &rset))
	}//end while(GobalInfo.iRunFlag)

	pthread_mutex_destroy(&GobalMutex.LogMutex);
	pthread_mutex_destroy(&GobalMutex.AlertMutex);
	pthread_mutex_destroy(&GobalMutex.SearchFileMutex);

	return 0;
}

/****************************************************************
**
**	Function: TransferServer
**	Purpose:  接收客户端传来的数据并作出相应的处理
** 	Input Parammeters:
	          SocketFd -- socket连接句柄
**	Return:
**	datetime:
**
*****************************************************************/
void *TransferServer(void *SocketFd)
{
	struct S_DataInfo data;
	int iError = 0;
	int iSockfd = (int)SocketFd;

	pthread_detach(pthread_self());
	if((GetSockData(iSockfd, &data)) == -1)
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("GetSockData error!\n");
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		close((int)SocketFd);
		return 0;
	}
	if(!IsDirectory(data.chRemotePath))
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("The RemotePath directory \"%s\" is not exist!",data.chRemotePath);
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		close((int)SocketFd);
		return 0;
	}

	if(!IsDirectory(data.chRemoteTargetPath))
	{
		printf("The RemoteTargetPath directory \"%s\" is not exist!",data.chRemoteTargetPath);
		close((int)SocketFd);
		return 0;
	}

	if(!IsDirectory(data.chRemoteBackupPath))
	{
		printf("The chRemoteBackupPath directory \"%s\" is not exist!",data.chRemoteBackupPath);
		close((int)SocketFd);
		return 0;
	}
	
	switch(ntohl(data.iTransferType))
	{
		case CMD_GET:
			ProcessGetConnect(iSockfd, &data);
			break;

		case CMD_PUT:
			ProcessPutConnect(iSockfd, &data);
			break;

		default:
			iError=1;
			break;
	}
	close((int)SocketFd);
	return 0;
}

void Init_GobalMutex(void)
{
	pthread_mutex_init(&GobalMutex.LogMutex, 0);
	pthread_mutex_init(&GobalMutex.AlertMutex, 0);
	pthread_mutex_init(&GobalMutex.SearchFileMutex, 0);
	return;
}
/****************************************************************
**
**	Function: GetExePath
**	Purpose:  获取应用程序目录,和配置文件目录名。
** 	Input Parammeters:
			全局参数

**	Return:	无
**	datetime:
**
*****************************************************************/
void GetExePath(void)
{
	char *pch = 0;
	//getwd(GobalInfo.chExePath);
	pch = getenv("PWD");
	if(0 == pch)
	{
		printf("\"PWD\" is not in environment!\n");
		exit(-1);
	}
	strcpy(GobalInfo.chExePath, pch);
	FullPath(GobalInfo.chExePath);
	sprintf(GobalInfo.chConfigFile, "%s/transerver.ini", GobalInfo.chExePath);
	return ;
}
/****************************************************************
**
**	Function: UserTerm
**	Purpose:  收到SIGTERM信号时,程序退出
** 	Input Parammeters:

**	Return:	无
**	datetime:
**
*****************************************************************/
void UserTerm(int signo)
{
	GobalInfo.iRunFlag = 0;
	return ;
}

/****************************************************************
**
**	Function: GetItemString
**	Purpose:  从配置文件中读出需要的配置信息。
** 	Input Parammeters:
			chTitle  :配置项区名
			chItem   :配置项名称
			chValue  :配置项值
			GobalInfo:全局信息

**	Return:	配置项值,同chValue
**	datetime:
**
*****************************************************************/
char *GetItemString(char * chTitle, char * chItem,char *chValue)
{
	FILE * f=0;
	char chTemp[MAX_PATH+1],chBuf[MAX_PATH+1];
	int len,pos;
	int find;
	char *p;

	f=fopen(GobalInfo.chConfigFile, "r");
	if(f == 0)
	{
		return 0;
	}
	chValue[0] = '\0';
	while(!feof(f))
	{
		memset(chTemp,0,sizeof(chTemp));
		fgets(chTemp, MAX_PATH, f);
		chTemp[strlen(chTemp) - 1] = 0;
		Trim(chTemp);
		find=0;
		if(strncmp(chTemp,chTitle,strlen(chTitle))==0)
		{
			while(!feof(f) && !find)
			{

				fgets(chTemp,MAX_PATH,f);
				chTemp[strlen(chTemp)-1]=0;
				Trim(chTemp);

				if(strncmp(chTemp,chItem,strlen(chItem)-1))
				{
					continue;
				}
				p=strchr(chTemp,'=');
				if(p==0)
				{
					continue;
				}
				strcpy(chValue,p+1);
				Trim(chValue);
				find=1;
			 }
		}
		if(find)
		{
			break;
		}
	}
	fclose(f);
	return chValue;
}

int GetItemInt(char * title,char * item,char *chValue)
{
	return atoi(GetItemString(title,item,chValue));
}
/****************************************************************
**
**	Function: Init_GobalInfo
**	Purpose:  初使化全局信息
** 	Input Parammeters:
	          	GobalInfo:全局信息
**	Return:	无
**	datetime:
**
*****************************************************************/
void Init_GobalInfo(void)
{
	char chBuf[MAX_PATH];

	if(access(GobalInfo.chConfigFile,R_OK))
	{
		printf("\n\n\tWarning! File transmission system hasn\'t been configured!\n");
		exit(1);
	}

	GobalInfo.iListenPort = GetItemInt((char *)"[TransferServer]", (char *)"ListenPort", chBuf);
	GobalInfo.iDebugFlag = GetItemInt((char *)"[TransferServer]", (char *)"DebugFlag", chBuf);
	GobalInfo.iDaemonFlag = GetItemInt((char *)"[TransferServer]", (char *)"DaemonFlag", chBuf);
	strcpy(GobalInfo.chLogPath, GetItemString((char *)"[TransferServer]", (char *)"LogPath", chBuf));
	strcpy(GobalInfo.chAlertPath, GetItemString((char *)"[TransferServer]", (char *)"AlertPath", chBuf));
	GobalInfo.iMoveFlag = GetItemInt((char *)"[TransferServer]", (char *)"MoveFlag", chBuf);
	GobalInfo.iBackupFlag = GetItemInt((char *)"[TransferServer]", (char *)"BackupFlag", chBuf);

	if(!IsDirectory(GobalInfo.chLogPath))
	{
		printf(
			"The directory \"%s\" is not exist!",
			GobalInfo.chLogPath
			);
		return;
	}
	FullPath(GobalInfo.chLogPath);
	if(!IsDirectory(GobalInfo.chAlertPath))
	{
		printf(
			"The directory \"%s\" is not exist!",
			GobalInfo.chAlertPath
			);
		return;
	}
	FullPath(GobalInfo.chAlertPath);
	GobalInfo.iRunFlag = 1;
	return ;

}

/****************************************************************
**
**	Function: Runing
**	Purpose:  如果程序已经运行,打印错误信息
** 	Input Parammeters:无
**	Return:	无
**	datetime:
**
*****************************************************************/
void Runing()
{
	printf("Program already running!\n");
	return;
}

/****************************************************************
**
**	Function: daemon_init
**	Purpose:  程序设置为守护进程
** 	Input Parammeters:


**	Return:	无
**	datetime:
**
*****************************************************************/
void Init_Daemon(void)
{
	int i;

	switch(fork())
	{
		case -1:
			exit(-1);
		case 0:
			break;
		default:
			_exit(0);
	}

	setsid();

	switch(fork())
	{

		case -1:
			exit(-1);
		case 0:
			break;
		default:
			_exit(0);
	}
	for(i = 3; i < NOFILE; ++i)
	{
		close(i);
	}
	umask(0);
	return;
}

/*
*	Function Name	:ProcIsExist
*	Description	:检查本进程是否已经存在
*	Input Param	:与main函数同
*	Returns		:true(存在) or false(不存在)
*	complete	:
*/
bool ProcIsExist(int argc, char *argv[])
{
	int i;
	int iNums = 0;
	FILE *fp = 0;
	char *lv_chPoint = 0;
	char *pchLoginName = 0;
	char chScanBuff[BUF_SIZE];
	char chCommandLine[BUF_SIZE];
	char chTemp[BUF_SIZE];
	memset(chScanBuff, 0, sizeof(chScanBuff));
	memset(chCommandLine, 0, sizeof(chCommandLine));
	memset(chTemp, 0, sizeof(chTemp));

	if((pchLoginName = getenv("LOGNAME")) == 0)
	{
		printf("Transerver:Not get the environment \"LOGNAME\" in ProcIsExist!\n");
		return false;
	}
	lv_chPoint = argv[0];
	for(i = 0; *lv_chPoint; lv_chPoint++, i++)
	{
		if (*lv_chPoint == '/')
		{
			i = -1;
			continue;
		}
		chCommandLine[i] = *lv_chPoint;
	}
	chCommandLine[i] = '\0';
	for(i = 1; i < argc; i++)
	{
		strcat(chCommandLine, " ");
		strcat(chCommandLine, argv[i]);
	}
	Trim(chCommandLine);
	sprintf(
		chScanBuff,
		"ps -fu %s | cut -c 40-",
		pchLoginName
		);
	if((fp = popen(chScanBuff , "r")) == 0)
	{
		return false;
	}
	while(fgets(chScanBuff, sizeof(chScanBuff), fp) != 0)
	{
		memset(chTemp, 0, sizeof(chTemp));
		strcpy(chTemp, chScanBuff);
		lv_chPoint = strchr(chScanBuff, ':');
		if(lv_chPoint == 0)
		{
			memset(chScanBuff, 0, sizeof(chScanBuff));
			continue;
		}
		lv_chPoint += 3;
		memset(chTemp, 0, sizeof(chTemp));
		strcpy(chTemp, lv_chPoint);
		Trim(chTemp);
		lv_chPoint = chTemp;

		memset(chScanBuff, 0, sizeof(chScanBuff));

		for(i = 0; (*lv_chPoint) && (*lv_chPoint != ' '); lv_chPoint++,i++)
		{
			if (*lv_chPoint == '/')
			{
				i = -1;
				continue;
			}
			chScanBuff[i] = *lv_chPoint;
		}
		chScanBuff[i] = 0;
		lv_chPoint = strchr(chTemp, ' ');

		if(lv_chPoint != 0)
		{
			Trim(lv_chPoint);
			strcat(chScanBuff, " ");
			strcat(chScanBuff, lv_chPoint);
		}

		Trim(chScanBuff);
		Trim(chCommandLine);
		if(strcmp(chScanBuff, chCommandLine) == 0)
		{
			iNums++;
		}
		memset(chScanBuff, 0, sizeof(chScanBuff));
	}//end while(fgets(chScanBuff, sizeof(chScanBuff), fp) != 0)
	pclose(fp);
	if(iNums > 1)
	{
		return true;
	}
	else
	{
		return false;
	}
}
/****************************************************************
**
**	Function: killproc
**	Purpose:	停止进程以其所有子进程
** 	Input Parammeters:
**			同主函数
**	Return:
**	datetime:
**
*****************************************************************/
void KillProc(int argc,char *argv[])
{
	FILE *fp = 0;
	char *LoginName = 0;
	char ScanBuff[BUF_SIZE];
	char chTemp[BUF_SIZE];

	if((LoginName = getenv("LOGNAME")) == 0)
	{
		printf("Transerver:Not get the environment \"LOGNAME\" in KillProc!\n");
		exit(-1);
	}
	if(memcmp(argv[0], "./", 2) == 0)
	{
		strcpy(chTemp, argv[0] + 2);
	}
	else
	{
		strcpy(chTemp, argv[0]);
	}
	sprintf(
		ScanBuff,
		"ps -fu %s|awk '{if(($NF == \"%s\") || ($NF == \"./%s\")) print $2 }'",
		LoginName,
		chTemp,
		chTemp
		);
	if((fp = popen(ScanBuff ,"r")) == 0)
	{
		exit(-1);
	}
	while(fgets(ScanBuff,sizeof(ScanBuff),fp) != 0)
	{
		Trim(ScanBuff);
		if (atoi(ScanBuff) != getpid())
		{
			kill(atoi(ScanBuff),SIGTERM);
		}
	}
	pclose(fp);
	return;
}
//------------------------------The End-------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -