www.pudn.com > saac.rar > mail.c


#define _MAIL_C_

#include "main.h"
#include "mail.h"
#include "util.h"
#include "saacproto_serv.h"

#include 
#include 
#include 
#include 
#include 
#include 

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, "10000\n" );
        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:%u\n", 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( "回复邮件缓冲: 内件不足!! 新邮件大小:%d\n",
             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 新地址:%x\n",
         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
                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:%u\n",
                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= 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: %s\n",
                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("创建 %s\n", 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 %s\n",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;
}