mail.c
资源名称:saac.tar.gz [点击查看]
上传用户:qys8201
上传日期:2021-12-11
资源大小:978k
文件大小:17k
源码类别:
模拟服务器
开发平台:
C/C++
- #define _MAIL_C_
- #include "main.h"
- #include "mail.h"
- #include "util.h"
- #include "saacproto_serv.h"
- #include <malloc.h>
- #include <stdio.h>
- #include <time.h>
- #include <sys/types.h>
- #include <dirent.h>
- #include <sys/stat.h>
- typedef enum
- {
- MS_NOUSE = 0,
- MS_NEWMESSAGE,
- MS_WAIT_ACK,
- } MAILSTATE;
- #define TEXT_MAX 1024
- struct mail
- {
- int use;
- unsigned int id_charname_hash;
- char id_to[USERID_MAX];
- char charname_to[CHARNAME_MAX];
- char id_from[USERID_MAX];
- char charname_from[CHARNAME_MAX];
- char text[TEXT_MAX];
- int option;
- unsigned int message_id;
- MAILSTATE state;
- time_t recv_time;
- };
- struct mail *mailbuf;
- int mailbufsize = 0;
- static unsigned int
- getNextMessageID(void)
- {
- FILE *fp;
- unsigned int i;
- char filename[1024];
- char line[1000];
- snprintf( filename, sizeof( filename ),
- "%s/mail_id" , maildir );
- fp = fopen( filename, "r" );
- if( fp == NULL ){
- fp = fopen( filename ,"w" );
- if( fp == NULL ){
- log( "不能创建 %s ... 使用同样的邮件ID,"
- " saac 发送变得缓慢!(id:9999)n", filename );
- return 9999;
- }
- fprintf( fp, "10000n" );
- fclose(fp);
- return 1000;
- }
- fgets( line, sizeof(line), fp);
- i = strtoul( line, NULL, 10 );
- fclose(fp);
- fp = fopen( filename, "w" );
- if( fp == NULL ){
- log( "不能写入新的ID到 %s ... 使用同样的数字!n", filename );
- return i;
- }
- fprintf( fp, "%u", i+1 );
- fclose(fp);
- log( "新邮件ID:%un", i);
- return i;
- }
- static int reallocMailBuf( void )
- {
- struct mail *previous = mailbuf;
- struct mail *newbuf;
- int new_mailbufsize;
- if( mailbufsize == 0 ){
- new_mailbufsize = 1;
- } else {
- new_mailbufsize = mailbufsize * 2;
- }
- newbuf = ( struct mail * )calloc( 1, new_mailbufsize *
- sizeof( struct mail ));
- if( newbuf == NULL ){
- log( "回复邮件缓冲: 内件不足!! 新邮件大小:%dn",
- new_mailbufsize );
- return -1;
- }
- memset( newbuf, 0 , new_mailbufsize * sizeof( struct mail ));
- if( previous ) memcpy( (char*)newbuf, (char*)previous,
- mailbufsize * sizeof( struct mail ));
- free( previous );
- mailbufsize = new_mailbufsize;
- mailbuf = newbuf;
- log( "重新分配邮件缓冲: "
- "新邮件缓冲:%d 旧地址:%x 新地址:%xn",
- new_mailbufsize, (unsigned int)previous,(unsigned int)newbuf );
- return 0;
- }
- static int mailbuf_finder = 0;
- static int allocMail( int use_msgid, unsigned int msgid )
- {
- int i;
- for(i=0;i<mailbufsize;i++){
- mailbuf_finder ++;
- if( mailbuf_finder == mailbufsize ) mailbuf_finder = 0;
- if( mailbuf[mailbuf_finder].use == 0 ){
- mailbuf[mailbuf_finder].use = 1;
- mailbuf[mailbuf_finder].text[0] = 0;
- mailbuf[mailbuf_finder].id_to[0] = 0;
- mailbuf[mailbuf_finder].charname_to[0] = 0;
- mailbuf[mailbuf_finder].id_from[0] = 0;
- mailbuf[mailbuf_finder].charname_from[0] = 0;
- if( use_msgid ){
- mailbuf[mailbuf_finder].message_id = msgid;
- } else {
- mailbuf[mailbuf_finder].message_id = getNextMessageID();
- }
- mailbuf[mailbuf_finder].state = MS_NEWMESSAGE;
- mailbuf[mailbuf_finder].recv_time = time(NULL);
- return mailbuf_finder;
- }
- }
- log( "分配邮件: 邮件缓冲失败.正在进行分配...n" );
- if( reallocMailBuf() < 0 ){
- log( "分配邮件: 分配失败n" );
- } else {
- return allocMail(use_msgid, msgid );
- }
- return -1;
- }
- void receiveMail( char *id_from,
- char *charname_from,
- char *id_to,
- char *charname_to,
- char *message,
- int option,
- int use_msgid,
- unsigned int msgid
- )
- {
- char id_charname[1024];
- int h, mbindex;
- snprintf( id_charname, sizeof( id_charname), "%s_%s", id_to, charname_to );
- h = hashpjw( id_charname ) & 0xff ;
- if( (mbindex = allocMail(use_msgid, msgid )) < 0 ){
- log( "回复邮件: 获取新的邮件缓冲失败.n" );
- return;
- }
- mailbuf[mbindex].id_charname_hash = h;
- snprintf( mailbuf[mbindex].text, sizeof( mailbuf[mbindex].text ), "%s", message );
- snprintf( mailbuf[mbindex].id_to, sizeof( mailbuf[mbindex].id_to ), "%s", id_to );
- snprintf( mailbuf[mbindex].charname_to, sizeof( mailbuf[mbindex].charname_to ), "%s", charname_to );
- snprintf( mailbuf[mbindex].id_from, sizeof( mailbuf[mbindex].id_from ),"%s", id_from );
- snprintf( mailbuf[mbindex].charname_from, sizeof( mailbuf[mbindex].charname_from ),"%s", charname_from );
- mailbuf[mbindex].option = option;
- {
- char childname[1000];
- char savefile[1000];
- char charname2[CHARNAME_MAX*2+1];
- char text2[TEXT_MAX*2+1];
- FILE *fp;
- snprintf( childname, sizeof( childname ),"%u" ,
- mailbuf[mbindex].message_id );
- makeDirFilename( savefile , sizeof(savefile), maildir, h, childname );
- fp = fopen( savefile, "w" );
- if( fp == NULL ){
- log( "回复邮件 : 不能保存邮件文件: %s %sn",
- savefile, strerror( errno ));
- return;
- }
- #define TO_ID_HEAD "ToID: "
- #define TO_CHAR_HEAD "ToChar: "
- #define FROM_ID_HEAD "FromID: "
- #define FROM_CHAR_HEAD "FromChar: "
- #define OPTION_HEAD "Option: "
- #define TEXT_HEAD "Text: "
- fprintf( fp, TO_ID_HEAD "%sn", id_to );
- snprintf( charname2, sizeof( charname2), "%s", charname_to );
- fprintf( fp, TO_CHAR_HEAD "%sn", makeEscapeString( charname_to,
- charname2,sizeof(charname2)) );
- fprintf( fp, FROM_ID_HEAD "%sn", id_from );
- snprintf( charname2, sizeof( charname2), "%s", charname_from );
- fprintf( fp, FROM_CHAR_HEAD "%sn", makeEscapeString( charname_from,
- charname2,sizeof(charname2)) );
- fprintf( fp, OPTION_HEAD "%dn", option );
- snprintf( text2, sizeof( text2 ) , "%s", message );
- fprintf( fp, TEXT_HEAD "%sn", makeEscapeString( message,
- text2, sizeof(text2)) );
- fclose(fp);
- {
- static int mailnum=0;
- if( mailnum%10 == 0)
- log(".");
- mailnum = (++mailnum%1000);
- if( mailnum == 0 )
- log("n");
- }
- }
- {
- extern gmsv gs[MAXCONNECTION];
- int i;
- for(i=0;i<MAXCONNECTION;i++){
- if( gs[i].use && gs[i].name[0] ){
- saacproto_Message_send( i,
- id_from, charname_from,
- id_to, charname_to,
- message, option,
- mailbuf[mbindex].message_id );
- mailbuf[mbindex].state = MS_WAIT_ACK;
- }
- }
- }
- }
- void receiveMailAck( char *id, char *charname, int a , int mesgid )
- {
- int i;
- unsigned int h;
- char id_charname[1024];
- snprintf( id_charname, sizeof( id_charname), "%s_%s", id, charname );
- h = hashpjw( id_charname ) & 0xff ;
- for(i=0;i<mailbufsize;i++){
- if( mailbuf[i].message_id == mesgid ){
- if( mailbuf[i].use
- && mailbuf[i].id_charname_hash == h
- && strcmp( mailbuf[i].id_to, id ) == 0
- && strcmp( mailbuf[i].charname_to, charname ) == 0
- && mailbuf[i].state == MS_WAIT_ACK ){
- char savefile[1024];
- char childname[1000];
- snprintf( childname,sizeof(childname),"%u",
- mailbuf[i].message_id );
- makeDirFilename( savefile, sizeof(savefile),maildir,
- h, childname );
- if( unlink( savefile ) != 0 ){
- log( "failed to unlink %s: %sn",
- savefile, strerror(errno ));
- } else {
- log( "回复邮件: 删除邮件 "
- "%u 从 %s(%s) to %s(%s)n",
- mailbuf[i].message_id,
- mailbuf[i].id_from,
- mailbuf[i].charname_from,
- mailbuf[i].id_to,
- mailbuf[i].charname_to );
- }
- memset( &mailbuf[i], 0 , sizeof( mailbuf[0] ));
- return;
- } else {
- log( "回复邮件: 无用信息或ID或名称或声明严重错误" );
- log( "use[%d] h[%d][%d] id[%s][%s] nm[%s][%s] st[%d]n",
- mailbuf[i].use, mailbuf[i].id_charname_hash, h,
- mailbuf[i].id_to, id,
- mailbuf[i].charname_to, charname,
- mailbuf[i].state);
- }
- }
- }
- log( "回复邮件: 邮件 %u 不能从 %s(%s) 找到n",
- mesgid, id,charname );
- }
- void flushMail( int fd,
- char *id,
- char *charname )
- {
- int i,c=0;
- unsigned int h ;
- char id_charname[1000];
- #define MAX_FLUSH_MAIL 1024
- int flush_index[MAX_FLUSH_MAIL];
- int flush_i=0;
- snprintf( id_charname, sizeof( id_charname ) , "%s_%s", id, charname );
- h = hashpjw( id_charname );
- // Nuke +1
- log("邮件缓冲大小:%d (%s)n",mailbufsize,chartime());
- // Nuke *1
- for(i=0;(i<mailbufsize)&&(i<MAX_FLUSH_MAIL);i++){
- if( mailbuf[i].id_charname_hash == h &&
- mailbuf[i].use &&
- strcmp( mailbuf[i].id_to , id ) == 0 &&
- strcmp( mailbuf[i].charname_to, charname ) == 0 ){
- log( "消息ID:%un", mailbuf[i].message_id );
- flush_index[flush_i++] = i;
- c++;
- }
- }
- for(i=0; i< flush_i ; i++ ){
- int j;
- for(j=0; j < flush_i-1 ; j++ ){
- if( mailbuf[flush_index[j]].message_id >
- mailbuf[flush_index[j+1]].message_id ){
- int sw = flush_index[j];
- flush_index[j] = flush_index[j+1];
- flush_index[j+1] = sw;
- log( "inverted %d and %d in %d n", flush_index[j],
- flush_index[j+1], j );
- }
- }
- }
- /* 端卞霜耨允月 */
- for(i=0;i< flush_i; i++ ){
- /* flush 及桦宁反}flush毛霜耨仄化五凶必□丞扔□田□卞
- 覆仄化分仃霜耨允木壬中中 */
- saacproto_Message_send( fd,
- mailbuf[flush_index[i]].id_from,
- mailbuf[flush_index[i]].charname_from,
- mailbuf[flush_index[i]].id_to,
- mailbuf[flush_index[i]].charname_to,
- mailbuf[flush_index[i]].text,
- mailbuf[flush_index[i]].option,
- mailbuf[flush_index[i]].message_id );
- mailbuf[flush_index[i]].state = MS_WAIT_ACK;
- log( "分类邮件ID:%un",
- mailbuf[flush_index[i]].message_id );
- }
- // Nuke *1
- log( "邮件: 发送 %d 封邮件到 %s(%s)(%s)n", c, id, charname ,chartime());
- }
- // Nuke start: To expire undelivered mail
- #define MAIL_EXPIRE_TIME 3600
- void
- expireMail()
- {
- int i,c=0;
- unsigned int h ;
- char id_charname[1000];
- time_t now=time(NULL);
- /* 1荚及flush 匹霜耨允月 醒 */
- #define MAX_FLUSH_MAIL 1024
- int flush_index[MAX_FLUSH_MAIL];
- int flush_i=0;
- // Nuke +1
- log("邮件缓冲大小:%d (%s)n",mailbufsize,chartime());
- // Nuke *1
- for(i=0;(i<mailbufsize)&&(i<MAX_FLUSH_MAIL);i++){
- if(mailbuf[i].use && (now - mailbuf[i].recv_time >= MAIL_EXPIRE_TIME)) {
- log( "消息ID:%u 已过期n", mailbuf[i].message_id );
- flush_index[flush_i++] = i;
- c++;
- }
- }
- /* 端卞霜耨允月 */
- for(i=0;i< flush_i; i++ ){
- snprintf( id_charname, sizeof( id_charname), "%s_%s",
- mailbuf[flush_index[i]].id_to,
- mailbuf[flush_index[i]].charname_to );
- h = hashpjw( id_charname ) & 0xff ;
- {
- char savefile[1024];
- char childname[1000];
- snprintf( childname,sizeof(childname),"%u",
- mailbuf[flush_index[i]].message_id );
- makeDirFilename( savefile, sizeof(savefile),maildir,
- h, childname );
- if( unlink( savefile ) != 0 ){
- log( "failed to unlink %s: %sn",
- savefile, strerror(errno ));
- } else {
- log( "过期邮件: 删除游戏 "
- "%u 从 %s(%s) 到 %s(%s)n",
- mailbuf[flush_index[i]].message_id,
- mailbuf[flush_index[i]].id_from,
- mailbuf[flush_index[i]].charname_from,
- mailbuf[flush_index[i]].id_to,
- mailbuf[flush_index[i]].charname_to );
- }
- memset( &mailbuf[flush_index[i]], 0 , sizeof( mailbuf[0] ));
- }
- }
- // Nuke *1
- log( "过期邮件: 过期 %d 消息 (%s)n", c ,chartime());
- }
- int readMail( char *dir )
- {
- int i, read_count=0;
- for( i=0; i<256; i++){
- char dirname[1000];
- DIR *d;
- snprintf(dirname, sizeof( dirname ), "%s/0x%x", dir, i );
- d = opendir(dirname);
- if(d == NULL ){
- mkdir( dirname, 0755);
- log("创建 %sn", dirname);
- continue;
- }
- while(1){
- struct dirent *de;
- de = readdir( d );
- if( de == NULL )break;
- if( de->d_name[0] != '.' ){
- char filename[1000];
- FILE *fp;
- struct stat s;
- snprintf( filename, sizeof( filename),
- "%s/%s", dirname, de->d_name );
- if( stat( filename, &s ) < 0 ){
- continue;
- }
- if( !(s.st_mode & S_IFREG)) continue;
- fp = fopen( filename, "r" );
- if( fp == NULL ){
- log( "不能打开文件 %s %sn",filename,strerror(errno));
- continue;
- }
- {
- char line[16384];
- char toid[1000] , fromid[1000];
- char tochar[CHARNAME_MAX*2+1];
- char fromchar[CHARNAME_MAX*2+1];
- char text[TEXT_MAX*2+1];
- int opt=0;
- toid[0] = fromid[0] = tochar[0] =
- fromchar[0] = text[0] = 0;
- fgets( line, sizeof(line), fp );
- chop(line);
- if( strncmp( TO_ID_HEAD , line, strlen(TO_ID_HEAD) )==0){
- snprintf( toid , sizeof( toid ),"%s",
- line+strlen(TO_ID_HEAD ));
- }
- fgets( line, sizeof( line ), fp );
- chop(line);
- if( strncmp( TO_CHAR_HEAD, line,strlen(TO_CHAR_HEAD))==0){
- snprintf( tochar, sizeof( tochar ), "%s",
- line+strlen( TO_CHAR_HEAD ));
- makeStringFromEscaped( tochar );
- }
- fgets( line, sizeof( line ),fp );
- chop(line);
- if( strncmp( FROM_ID_HEAD,line,strlen(FROM_ID_HEAD))==0){
- snprintf( fromid, sizeof( fromid ),"%s",
- line + strlen( FROM_ID_HEAD ));
- }
- fgets( line,sizeof(line),fp);
- chop(line);
- if(strncmp(FROM_CHAR_HEAD,line,strlen(FROM_CHAR_HEAD))==0){
- snprintf( fromchar, sizeof( fromchar ),
- line + strlen(FROM_CHAR_HEAD ));
- makeStringFromEscaped( fromchar );
- }
- fgets( line,sizeof(line),fp);
- chop(line);
- if( strncmp( OPTION_HEAD,line, strlen(OPTION_HEAD))==0){
- opt = atoi( line + strlen( OPTION_HEAD ) );
- }
- fgets( line, sizeof( line),fp);
- chop(line);
- if( strncmp(TEXT_HEAD,line,strlen(TEXT_HEAD))==0){
- snprintf( text, sizeof( text), "%s",
- line + strlen( TEXT_HEAD ));
- makeStringFromEscaped( text );
- }
- if( toid[0] == 0 || fromid[0] == 0 ||
- tochar[0] == 0 || fromchar[0] == 0 ||
- text[0] == 0 ){
- log( "有问题邮件! %s 接收ID[%c] 接收名字[%c]"
- " 发送ID[%c] 发送名字[%c] 文本[%c]n",
- filename,
- toid[0], tochar[0], fromid[0], fromchar[0],
- text[0] );
- // Nuke +1 1027: Close for safe
- fclose(fp);
- continue;
- }
- receiveMail( fromid, fromchar,
- toid, tochar,
- text, opt , 1,
- strtoul(de->d_name,NULL,10));
- read_count++;
- }
- fclose(fp);
- }
- }
- closedir(d);
- }
- log( "读取邮件: 在'%s'目录里读取到 %d 封邮件 n", dir, read_count );
- return 0;
- }