📄 common.cc
字号:
/*
* 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 + -