Public feed
#723859
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <sys/types.h>
#include <fcntl.h>
#include <pthread.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <GeoIP.h>
#include <arpa/inet.h>
#include <string>
#include <iostream>
#include <fstream>
#include <list>
#include <vector>
#include <sstream>
#ifndef O_NONBLOCK
#define O_NONBLOCK O_NDELAY
#endif
using namespace std;
class logfile_class
{
private:
public:
int fd;
string name;
unsigned long ino;
};
logfile_class logfile;
GeoIP *gi;
int parse(string line);
int listenfd, len, status,dsize=0,connfd;;
fd_set rfd,c_rfd;
pthread_mutex_t mut,read_mut;
pthread_t serverside_id,readlog_id;
/********************************************************************************/
vector<string> split(const string& str, const string& delimiters)
{
vector<string> tokens;
string::size_type lastpos = str.find_first_not_of(delimiters, 0);
string::size_type pos = str.find_first_of(delimiters, lastpos);
while (string::npos != pos || string::npos != lastpos)
{
tokens.push_back(str.substr(lastpos, pos - lastpos));
lastpos = str.find_first_not_of(delimiters, pos);
pos = str.find_first_of(delimiters, lastpos);
}
return tokens;
}
/********************************************************************************/
int recheck()
{
int fd=0;
struct stat stats;
if((fd=open(logfile.name.c_str(),O_RDONLY))==-1) return 0;
fstat(fd,&stats);
if(stats.st_ino!=logfile.ino) { close(fd); return 0; }
close(fd);
return 1;
}
int reopen()
{
struct stat stats;
close(logfile.fd);
if((logfile.fd=open(logfile.name.c_str(),O_RDONLY))==-1) { printf("Error Opening File.. %s\n",logfile.name.c_str());return 0; }
fstat(logfile.fd,&stats);
logfile.ino=stats.st_ino;
return 1;
}
void *read_log(void *parm)
{
int oldflags=0;
struct stat stats;
char tmpchar[1];
string buffer;
if((logfile.fd=open(logfile.name.c_str(),O_RDONLY))==-1) { printf("Error Opening File.. %s\n",logfile.name.c_str());exit(0); }
fstat(logfile.fd,&stats);
logfile.ino=stats.st_ino;
oldflags=fcntl(logfile.fd,F_GETFL,0);
if(oldflags<0) printf("Something Failed Trying to read fcntl\n");
if(fcntl(logfile.fd,F_SETFL,oldflags & ~O_NONBLOCK)==-1) { printf("Something Broke Setting Block Mode\n"); exit(0); }
//goto end of file.
lseek(logfile.fd,0,SEEK_END);
//pthread_join(serverside_id,NULL);
gi=GeoIP_open("/usr/share/GeoIP/GeoIP.dat",0);
printf("got here and reading..\n");
while(1)
{
if(read(logfile.fd,tmpchar,1))
{
if(tmpchar[0]!='\n') buffer+=tmpchar[0];
else
{
parse(buffer); buffer="";
}
}
else
{
usleep(10000);
if(!recheck()) { sleep(1); printf("Failed To Read From File..\n"); reopen(); }
}
}
pthread_exit(0);
}
/********************************************************************************/
int parse(string line)
{
int i=0;
string oBuf;
stringstream tmpoBuf;
//Rejected RBL
if(strstr(line.c_str(),"NOQUEUE:"))
{
vector<string> result=split(line," ");
result=split(result[9],"[");
result=split(result[1],"]");
// stupid const pointer in GeoIP_country_name_by_addr
// 45mins wondering wtf was wrong
if(GeoIP_country_name_by_addr(gi,result[0].c_str())==NULL)
tmpoBuf << "SPAM:" << result[0] << ":" << "(null)\n";
else
tmpoBuf << "SPAM:" << result[0] << ":" << GeoIP_country_name_by_addr(gi,result[0].c_str()) << "\n";
oBuf=tmpoBuf.str();
tmpoBuf.str("");
for(i=0;i<dsize;i++)
if(i!=listenfd && FD_ISSET(i,&c_rfd))
{
if(send(i,oBuf.c_str(),strlen(oBuf.c_str()),MSG_NOSIGNAL)==-1)
{
close(i);
FD_CLR(i,&rfd);
}
}
}
if(strstr(line.c_str(),"client=") && !strstr(line.c_str(),"localhost"))
{
vector<string> result=split(line," ");
result=split(result[6],"[");
result=split(result[1],"]");
if(GeoIP_country_name_by_addr(gi,result[0].c_str())==NULL)
tmpoBuf << "OK:" << result[0] << ":" << "(null)\n";
else
tmpoBuf << "OK:" << result[0] << ":" << GeoIP_country_name_by_addr(gi,result[0].c_str()) << "\n";
oBuf=tmpoBuf.str();
tmpoBuf.str("");
for(i=0;i<dsize;i++)
if(i!=listenfd && FD_ISSET(i,&c_rfd))
{
if(send(i,oBuf.c_str(),strlen(oBuf.c_str()),MSG_NOSIGNAL)==-1)
{
close(i);
FD_CLR(i,&rfd);
}
}
}
return 1;
}
/********************************************************************************/
int main()
{
int i=0;
socklen_t len;
struct sockaddr_in servaddr, cliaddr;
logfile.name="/var/log/maillog";
listenfd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr("192.168.164.147");
//servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
servaddr.sin_port = htons(8898);
bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen(listenfd,3);
len = sizeof(cliaddr);
dsize=getdtablesize();
for(i=4;i<dsize;i++) if(i!=listenfd) close(i);
pthread_mutex_init(&read_mut,NULL);
pthread_mutex_init(&mut,NULL);
printf("Creating Thread..\n");
pthread_create(&readlog_id,NULL,read_log,NULL);
FD_ZERO(&rfd);
FD_SET(listenfd,&rfd);
printf("Going into loop\n");
for(;;)
{
c_rfd=rfd;
select(dsize,&c_rfd,NULL,NULL,(struct timeval *)NULL);
if(FD_ISSET(listenfd,&c_rfd))
{
connfd=accept(listenfd, (struct sockaddr *) &cliaddr, &len);
//printf("** Connection Accepted From: [%s:%d]\n",inet_ntoa(cliaddr.sin_addr.s_addr), ntohs(cliaddr.sin_port));
FD_SET(connfd,&rfd);
}
}
pthread_mutex_destroy(&mut);
pthread_mutex_destroy(&read_mut);
}