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

📄 common.cc

📁 此源代码只用于学习,不得用于其他商业活动 .
💻 CC
📖 第 1 页 / 共 2 页
字号:
/*
* Copyright (c) 2002, 南京联创系统集成股份有限公司综合结算产品部
* All rights reserved.
*
* 文件名称:common.cc
* 摘    要:传输程序中用到的一些基本函数
*
* 当前版本:
* 作    者:冯亮(fengl@lianchuang.com)
* 完成日期:
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <dirent.h>
#include <sys/socket.h>
#include <string.h>
#include <strings.h>
#include <sys/file.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 <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 "common.h"

/****************************************************************
**
**	Function:Msg
**	Purpose:写告警文件
**	Input Parammeters:chMsg:写入文件的消息
**	Return:无
**	datetime:
**
*****************************************************************/
void Msg(const char *chMsg, ...)
{
	char chBuf[STRING_LEN];
	FILE *fp = 0;
	char chFileName[STRING_LEN];
	char chTemp[STRING_LEN];

	time_t ticks;
	va_list	ap;
	va_start(ap, chMsg);
	vsprintf(chTemp, chMsg, ap);
	va_end(ap);

	ticks = time(0);
	sprintf(chBuf, "%.24s ", ctime(&ticks));
	strcat(chBuf, chTemp);

	if(GobalInfo.iDebugFlag)
	{
		printf("%s\n", chBuf);
	}
	sprintf(chFileName, "%s%s", GobalInfo.chAlertPath, "alert.log");
	fp = fopen(chFileName, "a+");
	if(fp != 0)
	{
		fprintf(fp, "%s\n", chBuf);
	}
	fclose(fp);
	return;
}

/****************************************************************
**
**	Function:Log
**	Purpose:写日志文件
**	Input Parammeters:chLog:写入文件的消息
**	Return:无
**	datetime:
**
*****************************************************************/

void Log(const char *chLog, ...)
{
	char chBuf[STRING_LEN];
	FILE *fp = 0;
	char chFileName[STRING_LEN];
	char chTemp[STRING_LEN];

	time_t ticks;
	va_list ap;
	va_start(ap, chLog);
	vsprintf(chTemp, chLog, ap);
	va_end(ap);

	ticks = time(0);
	sprintf(chBuf, "%.24s ", ctime(&ticks));
	strcat(chBuf, chTemp);

	if(GobalInfo.iDebugFlag)
	{
		printf("%s\n", chBuf);
	}
	sprintf(chFileName, "%s%s", GobalInfo.chLogPath, "transerver.log");
	fp = fopen(chFileName, "a+");
	if(fp != 0)
	{
		fprintf(fp, "%s\n", chBuf);
	}
	fclose(fp);
	return;
}

/****************************************************************
**
**	Function:GetFullName
**	Purpose:获得文件的绝对路径名
**	Input Parammeters:data:存放有路径的结构体,chFullName:出口参数
**	Return:无
**	datetime:
**
*****************************************************************/
void GetFullName(struct S_DataInfo *data, char *chFullName)
{
	if(data->chRemotePath[strlen(data->chRemotePath)-1] == '/')
	{
		sprintf(chFullName, "%s%s\0", data->chRemotePath, data->chFileName);
	}
	else
	{
		sprintf(chFullName, "%s/%s\0", data->chRemotePath, data->chFileName);
	}
	return ;
}

/****************************************************************
**
**	Function:print_data

**	Purpose:打印结构体里的所有数据
**	Input Parammeters:
			data:要打印的结构体
**	Return:无
**	datetime:
**
*****************************************************************/
void print_data(struct S_DataInfo *data)
{
	printf("iTransferType=%d\n", ntohl(data->iTransferType));
	printf("chRemotePath=%s\n", data->chRemotePath);
	printf("chFileFilter=%s\n", data->chFileFilter);
	printf("lFilePos=%ld\n", ntohl(data->lFilePos));
	printf("iCompress=%d\n", ntohl(data->iCompress));
	printf("iStatus=%d\n", ntohl(data->iStatus));
	printf("chErrorMsg=%s\n", data->chErrorMsg);
	printf("chFileName=%s\n", data->chFileName);
	printf("lFileLen=%ld\n", ntohl(data->lFileLen));
	printf("lZipSize=%ld\n", ntohl(data->lZipSize));
	printf("lDataLen=%ld\n", ntohl(data->lDataLen));
	printf("iCheckvalue=%ld\n", ntohl(data->lCheckValue));
	printf("\n");
	return ;
}

/****************************************************************
**
**	Function:GetFileSize
**	Purpose:获取文件的大小
**	Input Parammeters:
			chFileName:文件的名字
**	Return:成功,返回文件的大小。出错,返回-1。
**	datetime:
**
*****************************************************************/
long GetFileSize(char *chFileName)
{
	struct stat buf;

	if(stat(chFileName, &buf) < 0)
	{
		return -1;
	}
	return buf.st_size;
}

/****************************************************************
**
**	Function:GetSockData
**	Purpose:从对方获得一个S_DataInfo结构体大小的数据。
**	Input Parammeters:
			iSockfd:本地的socket。
			data:  要传输的结构体
**	Return:成功返回0,出错返回-1。
**	datetime:
**
*****************************************************************/
int GetSockData(int iSockfd, struct S_DataInfo *data)
{
	long lReadLen = sizeof(struct S_DataInfo);
	long lHasRead = -1;
	char *pch = (char *)data;
	memset(data, 0, sizeof(struct S_DataInfo));

	while(lReadLen > 0)
	{
		if(TimeWait(iSockfd, MODE_READ) == -1)
		{
			pthread_mutex_lock(&GobalMutex.AlertMutex);
			Msg("Read Socket Timeout");
			pthread_mutex_unlock(&GobalMutex.AlertMutex);
			//close(iSockfd);
			//iSockfd = -1;
			return -1;
		}
		if((lHasRead = read(iSockfd, pch, lReadLen)) < 0)
		{
			pthread_mutex_lock(&GobalMutex.AlertMutex);
			Msg("Read Socket error");
			pthread_mutex_unlock(&GobalMutex.AlertMutex);
			//close(iSockfd);
			//iSockfd = -1;
			return -1;
		}
//		else if(lHasRead == 0)
//		{
//			break;
//		}
		pch += lHasRead;
		lReadLen -= lHasRead;
	}
	if(CheckData(data) == -1)
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("Data CheckValue Error");
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		return -1;
	}
	return 0;
}

/****************************************************************
**
**	Function:WriteSockData
**	Purpose:向对方写入一个S_DataInfo结构体大小的数据。
**	Input Parammeters:
**	Return:成功,返回0,出错返回-1。
**	datetime:
**
*****************************************************************/
int WriteSockData(int iSockfd, struct S_DataInfo *data)
{
	long lWriteLen = sizeof(struct S_DataInfo);
	long lHasWrite = -1;
	const char *pch = (const char *)data;

	SetCheckValue(data);

	while(lWriteLen > 0)
	{
		if(TimeWait(iSockfd, MODE_WRITE) == -1)
		{
			pthread_mutex_lock(&GobalMutex.AlertMutex);
			Msg("Write Socket Timeout");
			pthread_mutex_unlock(&GobalMutex.AlertMutex);
			//close(iSockfd);
			//iSockfd = -1;
			return -1;
		}
		if((lHasWrite = write(iSockfd, pch, lWriteLen)) < 0)
		{
			pthread_mutex_lock(&GobalMutex.AlertMutex);
			Msg("Write Socket error");
			pthread_mutex_unlock(&GobalMutex.AlertMutex);
			//close(iSockfd);
			//iSockfd = -1;
			return -1;
		}
//		else if(lHasWrite == 0)
//		{
//			break;
//		}
		pch += lHasWrite;
		lWriteLen -= lHasWrite;
	}
	return 0;
}
/****************************************************************
**
**	Function:TimeWait
**	Purpose:设置超时,等待套接口可读
**	Input Parammeters:成功检测到套接口可读返回1,超时或出错返回-1。
**	Return:
**	datetime:
**
*****************************************************************/
int TimeWait(int fd, int Mode)
{
	fd_set rset;
	struct timeval timewait;
	FD_ZERO(&rset);
	FD_SET(fd, &rset);
	timewait.tv_sec = SOCK_TIME_OUT;
	timewait.tv_usec = 0;
	if(MODE_WRITE == Mode)
	{
		switch(select(fd+1, NULL, &rset, NULL, &timewait))
		{
			case -1:
				perror("MODE_WRITE : invoke select error");
				return -1;
			case 0:
				perror("MODE_WRITE : timeout");
				return -1;
			default:
				break;
		}
	}
	else
	{
		switch(select(fd+1, &rset, NULL, NULL, &timewait))
		{
			case -1:
				perror("MODE_READ : invoke select error");
				return -1;
			case 0:
				perror("MODE_READ : timeout");
				return -1;
			default:
				break;
		}
	}
	if(!FD_ISSET(fd, &rset))
	{
		perror("fd isn't in rset");
		return -1;
	}
	return 1;
}

int SearchFile(struct S_DataInfo *data)
{
	DIR *dirp = 0;
	struct dirent entry;
	struct dirent temp;
	struct dirent *dp = &temp;
	char Pathname[MAX_PATH];
	char Format[STRING_LEN];
	char Filename[STRING_LEN];
	char chFullFileName[STRING_LEN];

	strcpy(Pathname, data->chRemotePath);
	strcpy(Format, data->chFileFilter);
	FullPath(Pathname);

	dirp = opendir(Pathname);
	if(NULL == dirp)
	{
		sprintf(data->chFileName, "open dir %s FAILED", Pathname);
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg(data->chFileName);
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		return -1;
	}

	data->iStatus = htonl(STATUS_NOFILE);

	while(true)
	{
		readdir_r(dirp, &entry, &dp);

		if(dp == 0)
		{
			closedir(dirp);
			return 0;
		}
		strcpy(chFullFileName, Pathname);
		strcat(chFullFileName, dp->d_name);

		if((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..") == 0))
		{

			continue;
		}
		if((IsDirectory(chFullFileName) == true) || (access(chFullFileName, F_OK|R_OK) == -1))
		{
			continue;
		}
		if((dp->d_name)[0] == '~')
		{
			continue;
		}
		if((Compare(dp->d_name, Format) == true))
		{
			strcpy(Filename, dp->d_name);
			FileToTemp(data->chRemotePath, Filename, data->chRemotePath, data->chFileName);
			data->iStatus = htonl(STATUS_FILEEXIST);
			closedir(dirp);
			return 0;
		}
	}//end while(true)
}

/****************************************************************
**
**	Function:SendFile
**	Purpose:发送文件
**	Input Parammeters:
**	Return:
**	datetime:
**
*****************************************************************/
int SendFile(int iSockfd, struct S_DataInfo *data, char *chFullName)
{
	long lReadLen;
	long lDataLen;
	FILE *fp = NULL;

	lDataLen = sizeof(data->chData);

	fp = fopen(chFullName, "rb");
	if(fp == NULL)
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("open file  %s failure", chFullName);
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		data->iStatus = htonl(STATUS_ERROR);
		return WriteSockData(iSockfd, data);
	}
	if(fseek(fp, ntohl(data->lFilePos), SEEK_SET))
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("seek file %s failure", chFullName);
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		data->iStatus = htonl(STATUS_ERROR);
		fclose(fp);
		return WriteSockData(iSockfd, data);
	}
	data->iStatus = htonl(STATUS_SENDFILE);
	memset(data->chData, 0, lDataLen);
	lReadLen = fread(data->chData, sizeof(char), lDataLen-1, fp);
	if(lReadLen < lDataLen - 1)
	{
		/*这是最后的文件块*/
		data->iStatus = htonl(STATUS_LASTDATA);
	}
	fclose(fp);
	data->lDataLen = htonl(lReadLen);
	return WriteSockData(iSockfd, data);
}

/****************************************************************
**
**	Function:ZipFile
**	Purpose:压缩文件
**	Input Parammeters:
**	Return:成功返回0,失败返回-1。
**	datetime:
**
*****************************************************************/

int ZipFile(char *chFileName)
{

	char chShellCmd[STRING_LEN];

	if(IsZipFile(chFileName))
	{
		return 1;
	}
	sprintf(chShellCmd, "compress -f %s\0", chFileName);
	if(system(chShellCmd) == -1)
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("zip file");
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		return -1;
	}
	return 0;
}

/****************************************************************
**
**	Function:UnZipFile
**	Purpose:解压文件
**	Input Parammeters:
**	Return:成功返回0,失败返回-1。
**	datetime:
**
*****************************************************************/

int UnZipFile(char *chFileName)
{
	char chShellCmd[STRING_LEN];
	sprintf(chShellCmd, "uncompress -f %s\0", chFileName);
	if(system(chShellCmd) == -1)
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("unzip file %s failure", chFileName);
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		return -1;
	}
	return 0;
}

/****************************************************************
**
**	Function:IsZipFile
**	Purpose:判断文件是否是压缩文件
**	Input Parammeters:
**	Return:是则返回1,否则返回0。
**	datetime:
**
*****************************************************************/
/*因为不知到Lempel-Zev algorithm文件头,所以只用文件名判断*/
int IsZipFile(char *chFileName)
{
	int iFileNameLen;
	iFileNameLen = strlen(chFileName);
	if(chFileName[iFileNameLen-1] == 'Z' && chFileName[iFileNameLen-2] == '.')
	{
		/*已压缩*/
		return 1;
	}
	return 0;
}

/****************************************************************
**
**	Function:DeleteFile
**	Purpose:删除文件
**	Input Parammeters:
**	Return:
**	datetime:
**
*****************************************************************/
int DeleteFile(struct S_DataInfo *data)
{
	char chFullName[STRING_LEN];

	GetFullName(data, chFullName);
	if(remove(chFullName))
	{
		pthread_mutex_lock(&GobalMutex.AlertMutex);
		Msg("remove file");
		pthread_mutex_unlock(&GobalMutex.AlertMutex);
		return -1;
	}
	return 0;

}

/****************************************************************
**
**	Function:ProcessGetConnect
**	Purpose:处理Get连接
**	Input Parammeters:
**	Return:
**	datetime:
**
*****************************************************************/
int ProcessGetConnect(int iSockfd, struct S_DataInfo *data)
{
	char chFullName[STRING_LEN];
	char chFileName[STRING_LEN];
	int iEnd = 0;

	while(!iEnd)
	{
		switch(ntohl(data->iStatus))
		{
			/*客户请求发送文件信息*/
			case STATUS_FILEINFO:
				if(SendFileInfo(iSockfd, data) == -1)
				{
					return -1;
				}
				break;
			/*客户请求发下一个数据包*/
			case STATUS_SENDFILE:

⌨️ 快捷键说明

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