簡單整理BBS減少廣告信的常見方法(三)
程式碼修改一:util/bbsmail.c
/*-------------------------------------------------------*/
/* util/bbsmail.c ( NTHU CS MapleBBS Ver 2.36 ) */
/*-------------------------------------------------------*/
/* target : 由 Internet 寄信給 BBS 站內使用者 */
/* create : 95/03/29 */
/* update : 95/12/15 */
/* spam : 97/12/25 deltstar modify */
/*-------------------------------------------------------*/
#include <stdio.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#include <time.h>
#include <sysexits.h>
#include "bbs.h"
char *fn_passwd = BBSHOME "/.PASSWDS";
#define _BBS_UTIL_C_
#include "cache.c"
#include "record.c"
#define LOG_FILE (BBSHOME "/etc/mailog")
/*
DeltaStar BBS -- benyx 蕭還
廣告信自動防治修改版
原作者 rexchen.bbs@bbs.tku.edu.tw 淡大小旭旭
副作用是連 mailing-list 一起擋掉,但是 Load 輕、I/O 少
要不擋到 mailing-list 可以修改 Sendmail 的訂閱者形式和 mailer
可以觀察廣告信內容和來源用的BBS帳號,請自行決定加不加ꐠSPAMID
相似信件容忍封數定義為 COMPARE
當 Table 滿了後重置嫌疑輕的時後有嫌疑信件的容忍次數定義為 SUFFER
TODO:開檔放 mail_flag 廣告信的特徵資料,而在重開機後自動重新載入SHM
*/
#undef SPAMID "spam"
#define SPAMRULE 3 /* rule 2 到 10 不建議超過 10 */
#define COMPARE 3
#define SUFFER 2
#define SPAMTABLE 512
#ifndef SPAMSHM_KEY
#define SPAMSHM_KEY 1227
#endif
struct SPAM
{
int spam_a;
int spam_b;
int spam_c;
int spam_times;
};
struct SPAM_MAIL
{
struct SPAM mail_flag[SPAMTABLE];
time_t uptime;
time_t touchtime;
time_t update_time;
};
struct SPAM_MAIL *spam;
void
resolve_mailspam()
{
if (spam == NULL)
{
spam = attach_shm(SPAMSHM_KEY, sizeof(*spam));
if (spam->touchtime == 0)
spam->touchtime = 1;
}
}
int
seek_mailflag(spam_a,spam_b,spam_c)
int spam_a;
int spam_b;
int spam_c;
{
int i=0,j=0;
if ( spam_a == 0 && spam_b == 0 && spam_c == 0 )
return 0;
for ( i = 0 ; i < SPAMTABLE ; i++ )
{
if ( spam->mail_flag[i].spam_a == spam_a &&
spam->mail_flag[i].spam_b == spam_b &&
spam->mail_flag[i].spam_c == spam_c )
{
if ( spam->mail_flag[i].spam_times < COMPARE )
{
spam->mail_flag[i].spam_times++;
return 0;
} else {
spam->mail_flag[i].spam_times++;
return 1;
}
}
}
for ( i = 0 ; i < SPAMTABLE ; i++ )
{
if ( spam->mail_flag[i].spam_times == 0 )
{
spam->mail_flag[i].spam_a = spam_a;
spam->mail_flag[i].spam_b = spam_b;
spam->mail_flag[i].spam_c = spam_c;
spam->mail_flag[i].spam_times = 1 ;
j = 1;
break;
}
}
if ( j != 1 )
{
for ( i = 0 ; i < SPAMTABLE ; i++ )
{
if ( spam->mail_flag[i].spam_times <= SUFFER )
{
spam->mail_flag[i].spam_times = 0 ;
spam->mail_flag[i].spam_a = 0 ;
spam->mail_flag[i].spam_b = 0 ;
spam->mail_flag[i].spam_c = 0 ;
}
}
}
return 0;
}
Link(char* src, char* dst)
{
char cmd[200];
if (link(src, dst) == 0)
return 0;
sprintf(cmd, "/bin/cp -R %s %s", src, dst);
return system(cmd);
}
/* new code end */
void
mailog(msg)
char *msg;
{
FILE *fp;
if (fp = fopen(LOG_FILE, "a"))
{
time_t now;
struct tm *p;
time(&now);
p = localtime(&now);
fprintf(fp, "%02d/%02d/%02d %02d:%02d:%02d <bbsmail> %s\n",
p->tm_year, p->tm_mon+1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec,
msg);
fclose(fp);
}
}
int
mail2bbs(userid)
char *userid;
{
fileheader mymail;
char genbuf[256], title[80], sender[80], *ip, *ptr;
time_t tmp_time;
struct stat st;
FILE *fout;
int spam_a=0,spam_b=0,spam_c=0,spaming=0; /* new code */
/* check if the userid is in our bbs now */
if (!searchuser(userid))
{
sprintf(genbuf, "BBS user <%s> not existed", userid);
puts(genbuf);
mailog(genbuf);
return EX_NOUSER;
}
sprintf(genbuf, BBSHOME "/home/%s", userid);
if (stat(genbuf, &st) == -1)
{
if (mkdir(genbuf, 0755) == -1)
{
printf("mail box create error %s \n", genbuf);
return -1;
}
}
else if (!(st.st_mode & S_IFDIR))
{
printf("mail box error\n");
return -1;
}
printf("dir: %s\n", genbuf);
/* allocate a file for the new mail */
stampfile(genbuf, &mymail);
printf("file: %s\n", genbuf);
/* copy the stdin to the specified file */
if ((fout = fopen(genbuf, "w")) == NULL)
{
printf("Cannot open %s\n", genbuf);
return -1;
}
/* parse header */
while (fgets(genbuf, 255, stdin))
{
if (!strncmp(genbuf, "From", 4))
{
if ((ip = strchr(genbuf, '<')) && (ptr = strrchr(ip, '>')))
{
*ptr = '\0';
if (ip[-1] == ' ')
ip[-1] = '\0';
ptr = (char *) strchr(genbuf, ' ');
while (*++ptr == ' ');
sprintf(sender, "%s (%s)", ip + 1, ptr);
}
else
{
strtok(genbuf, " \t\n\r");
strcpy(sender, (char *) strtok(NULL, " \t\n\r"));
}
continue;
}
if (!strncmp(genbuf, "Subject: ", 9))
{
strcpy(title, genbuf + 9);
continue;
}
if (genbuf[0] == '\n')
break;
}
if (ptr = strchr(sender, '\n'))
*ptr = '\0';
if (ptr = strchr(title, '\n'))
*ptr = '\0';
if (strchr(sender, '@') == NULL) /* 由 local host 寄信 */
{
strcat(sender, "@" MYHOSTNAME);
}
time(&tmp_time);
if (!title[0])
sprintf(title, "來自 %.64s", sender);
fprintf(fout, "作者: %s\n標題: %s\n時間: %s\n",
sender, title, ctime(&tmp_time));
/* DeltaStar BBS -- benyx
摘取信的特徵 */
while (fgets( genbuf, 255, stdin )) {
fputs( genbuf, fout );
spam_b++;
spam_a = spam_a + genbuf[strlen(genbuf)/((spam_b%SPAMRULE)+1)];
spam_c = spam_c + genbuf[strlen(genbuf)/SPAMRULE] ;
}
fclose(fout);
/* DeltaStar BBS -- benyx
特徵放入 mail_flag,並分析它的嫌疑 :p */
if ( seek_mailflag(spam_a,spam_b,spam_c) == 1 )
{
spaming ++;
sprintf(genbuf, BBSHOME "/home/%s/%s", userid, mymail.filename);
#ifdef SPAMID
Link(genbuf, BBSHOME "/home/" SPAMID );
#endif
unlink(genbuf);
sprintf(genbuf,"SPAM: %x %x %x => %s => %s",
spam_a,spam_b,spam_c,sender,userid);
}
else
sprintf(genbuf, "%s => %s", sender, userid);
mailog(genbuf);
/* append the record to the MAIL control file */
strncpy(mymail.title, title, 72);
if (strtok(sender, " .@\t\n\r"))
strcat(sender, ".");
sender[IDLEN + 1] = '\0';
strcpy(mymail.owner, sender);
if (!spaming)
sprintf(genbuf, BBSHOME "/home/%s/.DIR", userid);
#ifdef SPAMID
else
sprintf(genbuf, BBSHOME "/home/%s/.DIR", SPAMID);
#endif
return append_record(genbuf, &mymail, sizeof(mymail));
}
void
main(argc, argv)
int argc;
char *argv[];
{
char receiver[256];
/* argv[1] is userid in bbs */
if (argc < 2)
{
printf("Usage:\t%s <bbs_uid>\n", argv[0]);
exit(-1);
}
strcpy(receiver, argv[1]);
/*
DeltaStar BBS -- benyx
*/
resolve_mailspam();
if (mail2bbs(receiver))
{
/* eat mail queue */
while (fgets(receiver, sizeof(receiver), stdin));
}
exit(0);
}
--
映千江月 還天地心
-- benyx 蕭還
benyx@star.ee.ttit.edu.tw
--
●無限星雲● ※,緣起※, (star.ee.ttit.edu.tw)
★ Post From ~\ ~\ star.ee.ttit.edu.tw ★