作者Efen.bbs@bbs.med.ncku.edu.tw (^^) 看板: plan
標題[功能]POP3郵件伺服器
時間迴風谷 (2004/04/02 Fri 13:22:41) Updated: 2004/04/03
從Windtop那邊轉植過來的。
: modes.h
#define XZ_GEM (XO_ZONE + 13) /* 精華區 */
+ #define XZ_MIME (XO_ZONE + 14) /* MIME 收信 */
: ufo.h
#define UFO_LOGINCLOAK BFLAG(21) /* 上站直接隱身 */
+ #define UFO_MIME BFLAG(22) /* MIME 解碼 */
"隱身上站 (隱身/現身)", /* UFO_LOGINCLOAK */
+ "MIME編碼 (開啟/關閉)", /* UFO_MIME */
: global.h
+ #define FN_MAILSERVICE_LOG "run/mailservice.log" /* MailSevice 使用紀錄 */
+ #define FN_ETC_MAILSERVICE "etc/mailservice" /* 電子郵件服務 */
: theme.h
+ #define FEETER_POP3 \
COLOR1 " POP3服務 " COLOR2 " (y)回信 (F/x)轉寄 (d)刪除 (D)區段刪除 (m)標記
\033[m"
: maple.p
+/* socket.c */
+int Get_Socket(char *site,int *sock);
: admutil.c
"收信白名單",
"收信黑名單",
#ifdef HAVE_LOGIN_DENIED
"拒絕連線名單",
#endif
+ "POP3服務說明",
MAIL_ACLFILE,
UNMAIL_ACLFILE,
#ifdef HAVE_LOGIN_DENIED
BBS_ACLFILE,
#endif
+ FN_ETC_MAILSERVICE,
: menu.c
找地方加上
"bin/pop3mail.so:Pop3mail", PERM_BASIC, -M_XMODE,
"Pop3 ├ POP3 郵件┤",
: so/Makefile
加上 pop3mail.so
: ~/mailservice
需要在/home/bbs之下,
mkdir mailservice
: so/pop3mail.c
加上下面這段程式
..這部分還有問題,轉信/寄信/回信的動作都可以了,
只是刪文的部分還沒改好…
原來的刪文是用大D標好,然後離開時問你要不要刪除(WindTop都這樣???)
最後離開伺服器時再刪掉
現在我改了前半,讓他直接刪掉…
然後後半還沒想到怎麼改…
so...^^;;變成沒辦法有效的刪件,只是自己瀏覽時,刪好玩的,
遠端的mail server不會受到影響!@.@
/*-------------------------------------------------------*/
/* pop3mail.c ( YZU WindTop BBS ) */
/*-------------------------------------------------------*/
/* author : statue.bbs@bbs.yzu.edu.tw */
/* author : visor.bbs@bbs.yzu.edu.tw */
/* target : pop3 mail client in mime transfer */
/* create : 2000/06/22 */
/* update : 2000/07/11 */
/* rfc : 1734, 1939, 2449, 1225 */
/*-------------------------------------------------------*/
#include "bbs.h"
#define MIME_BASE64 0x10000000
#define MIME_QP 0x20000000
#define MIME_MIME 0x40000000
static int is_mime; /* 切換 MIME 用的旗標 */
static int is_base64;
static int is_qp;
static int is_bbsmail;
static char boundary[128];
extern XZ xz[];
extern char xo_pool[];
static FILE *fsock; /* 連線用的 FILE */
static int del_num; /* 用來 UnDelete 用 , 已刪除文章數*/
extern int TagNum;
static int server_login();
static char *pop3_mime_transfer(unsigned char *);
static void
logitfile(file, key, msg)
char *file;
char *key;
char *msg;
{
time_t now;
struct tm *p;
char buf[100];
time(&now);
p = localtime(&now);
sprintf(buf, "%02d/%02d/%02d %02d:%02d:%02d %s %-14s %s\n",
p->tm_year % 100, p->tm_mon + 1, p->tm_mday,
p->tm_hour, p->tm_min, p->tm_sec, key, cuser.userid, msg ? msg : "");
f_cat(file, buf);
}
/* ----------------------------------------------------- */
/* QP code : "0123456789ABCDEF" */
/* QP 是一種解碼方式 quoted-printable */
/* 一篇文章中的 '=' 有沒有超過一定數目. */
/* ----------------------------------------------------- */
static int
qp_code(x)
register int x;
{
if (x >= '0' && x <= '9')
return x - '0';
if (x >= 'a' && x <= 'f')
return x - 'a' + 10;
if (x >= 'A' && x <= 'F')
return x - 'A' + 10;
return -1;
}
/* ------------------------------------------------------------------ */
/* BASE64 : */
/* "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" */
/* Base64無法判斷, 除非我們有header */
/* ------------------------------------------------------------------ */
static int
base64_code(x)
register int x;
{
if (x >= 'A' && x <= 'Z')
return x - 'A';
if (x >= 'a' && x <= 'z')
return x - 'a' + 26;
if (x >= '0' && x <= '9')
return x - '0' + 52;
if (x == '+')
return 62;
if (x == '/')
return 63;
return -1;
}
/* ----------------------------------------------------- */
/* judge & decode QP / BASE64 */
/* ----------------------------------------------------- */
/* 去除不必要的標頭 */
static int
pop3_mime_cut(unsigned char* src,HDR *hdr, FILE *fp,FILE *sock)
{
char *ptr;
/* 若沒有開啟 MIME 解碼選項則不予解碼 */
if(!is_mime)
return 1;
if(*boundary != 0 && !strncmp(src+2,boundary,strlen(boundary)-2))
{
fprintf(fp, "> ------------------------------------------------------------
----------- <\n"
);
return -1;
}
if(str_str(src,"<pre>"))
return -1;
if(str_str(src,"</pre>"))
{
hdr->xmode |= MIME_MIME;
return 0;
}
if(!strncmp(src, "----", strlen("----"))||
!strncmp(src, "\tboundary", strlen("\tboundary")))
return 0; /* 跳過此部份解碼 */
#if 1
if(!strncmp(src, "Content-Type: ", strlen("Content-Type: ")))
{
ptr = src + strlen("Content-Type: ");
if(!str_ncmp(ptr, "text/html",strlen("text/html")))
{
hdr->xmode |= MIME_MIME;
fprintf(fp, "html 有網頁格式\n");
return 0;
}
if(!str_ncmp(ptr, "image",strlen("image")))
{
hdr->xmode |= MIME_MIME;
fprintf(fp, "image 有附件 : 圖片檔\n");
return 0;
}
if(!str_ncmp(ptr, "audio",strlen("audio")))
{
hdr->xmode |= MIME_MIME;
fprintf(fp, "audio 有附件 : 音效檔\n");
return 0;
}
if(!str_ncmp(ptr, "video",strlen("video")))
{
hdr->xmode |= MIME_MIME;
fprintf(fp, "video 有附件 : 影音檔\n");
return 0;
}
if(!str_ncmp(ptr, "application",strlen("application")))
{
hdr->xmode |= MIME_MIME;
fprintf(fp, "application 有附件 : 不明格式\n");
return 0;
}
hdr->xmode &= (MIME_QP|MIME_BASE64);
/* 遇到 text or image 結束解碼動作 */
fgets(src, 256, sock);
if(*src == '\t') /* Contect-Type 後有 boundary & charset,前會有 tab */
{
return 0;
}
}
#endif
if(!str_ncmp(src, "\tname", strlen("\tname")))
{
char *end;
ptr = strstr(src,"name");
ptr = strchr(ptr,'"');
end = strchr(ptr+1,'"');
*end = 0;
fprintf(fp, "\t附件名稱 : %s\n",pop3_mime_transfer((char *)ptr+1));
return 0;
}
if(!strncmp(src, "Content-Transfer-Encoding: ", strlen("Content-Transfer-Enco
ding: ")))
{ /* 解 rfc1522 body code */
ptr = src + strlen("Content-Transfer-Encoding: ");
if(!strncmp(ptr, "base64", strlen("base64")))
{
hdr->xmode |= MIME_BASE64;
hdr->xmode &= ~MIME_QP;
}
if(!strncmp(ptr, "quoted-printable", strlen("quoted-printable")))
{
hdr->xmode |= MIME_QP;
hdr->xmode &= ~MIME_BASE64;
}
return 0;
}
if(hdr->xmode & MIME_MIME)
return 0;
return 1; /* 進行解碼動作 */
}
/* 解碼 , 跟 bmtad.c 的 multipart() 很像*/
static char*
pop3_mime_transfer(unsigned char* src)
{
unsigned char* dst = src;
char *ans;
register int is_done;
register int c1, c2, c3, c4;
/* 若沒有開啟 MIME 解碼選項則不予解碼 */
if(!is_mime)
return src;
ans = src;
/* 判斷前 10 個字元是否都在base64 中 */
for (c1 = 0; c1 < 10 ; c1++)
if (base64_code(src[c1]) == -1)
{
is_base64 = 0;
break;
}
for (is_done = 0; c1 = *src; src++) /* 把傳進來的值作解碼 */
{
if (c1 == '?' && src[1] == '=') /* qb code 的 To: From: */
{
if(src[2] == ' ') /* 通常 qb code 或 base64 的第三個不會是空白 */
{
src++;
is_qp = is_base64 = 0;
}
continue;
}
else if ((c1 == '=') && (src[1] == '?'))
{
/* c2 : qmarks, c3 : code_kind */
c2 = c3 = 0;
for (;;)
{
c1 = *++src;
if (c1 != '?')
{
if (c2 == 2)
c3 = c1 | 0x20;
}
else
{
if (++c2 >= 3)
break;
}
}
if (c3 == 'q') /* =?q */
is_qp = MIME_QP;
else if (c3 == 'b') /* =?big5? */
is_base64 = MIME_BASE64;
}
else if (c1 == '\n') /* chuan: multi line encoding */
{
if (!is_base64)
*dst++ = c1;
is_done = is_qp = is_base64 = 0;
continue;
}
else if (is_qp && c1 == '=')
{
c1 = *++src;
if (!*src)
break;
c2 = *++src;
if (!*src)
break;
*dst++ = (qp_code(c1) << 4) | qp_code(c2);
if (dst[-1] == (unsigned char)-1)
--dst;
}
else if (is_base64 && !is_done)
{
while (isspace(c1))
{
c1 = *++src;
}
if (!c1)
break;
do
{
c2 = *++src;
} while (isspace(c2));
if (!c2)
break;
do
{
c3 = *++src;
} while (isspace(c3));
if (!c3)
break;
do
{
c4 = *++src;
} while (isspace(c4));
if (!c4)
break;
if (c1 == '=' || c2 == '=')
{
is_done = 1;
continue;
}
c2 = base64_code(c2);
*dst++ = (base64_code(c1) << 2) | ((c2 & 0x30) >> 4);
if (c3 == '=')
is_done = 1;
else
{
c3 = base64_code(c3);
*dst++ = ((c2 & 0xF) << 4) | ((c3 & 0x3c) >> 2);
if (c4 == '=')
is_done = 1;
else
{
*dst++ = ((c3 & 0x03) << 6) | base64_code(c4);
}
}
}
else
*dst++ = c1;
}
if (!is_base64 && dst[-1] == '=')
dst[-1] = '\n';
*dst = '\0';
return ans;
}
static int
int_len(num)
int num;
{
int i;
i = 1;
while((num/10) > 0)
{
num/=10;
i++;
}
return i;
}
/* 把來源取出需要的部分 */
static char *
parse_owner(token)
char *token;
{
char *ptr;
/* =?big5?B?qHSyzrresnqt+w==?= <postmaster@mail86.yzu.edu.tw> */
ptr = strchr(token,'>'); /* > */
if(ptr) /* 看最後一個字元是否為 > */
{
*ptr = 0; /* */
ptr = strchr(token, '<'); /* <postmaster@mail86.yzu.edu.tw */
if(ptr[-1] == ' ')
ptr[-1] = 0; /* <postmaster@mail86.yzu.edu.tw */
*ptr++ = 0; /* postmaster@mail86.yzu.edu.tw */
pop3_mime_transfer(ptr);
}
else /* statue.bbs@cnpa-6.admin.yzu.edu.tw */
ptr = token;
return ptr;
}
static char *
parse_nick(token)
char *token;
{
char *ptr;
/* =?big5?B?qHSyzrresnqt+w==?= <postmaster@mail86.yzu.edu.tw> */
ptr = token;
if(*ptr == '=')
{
ptr = strchr(token, '<'); /* <postmaster@mail86.yzu.edu.tw> */
if(ptr[-1] == ' ');
ptr[-1] = 0; /* <postmaster@mail86.yzu.edu.tw> */
}
return token; /* =?big5?B?qHSyzrresnqt+w==?= */
}
/* 從 header 取出需要的部分 */
static void
parse_header(hdr, count)
HDR *hdr;
int count;
{
char *ptr, *token, buf[256];
int lines;
struct tm tmdate;
lines = -1;
fprintf(fsock, "TOP %d 0\r\n", count);
fgets(buf, 256, fsock);
while(strncmp(buf, ".", 1))
{
/* 作者 */
if(!strncmp(buf, "From: ", strlen("From: ")))
{
char tmp[256];
token = ptr = buf + strlen("From: ");
strcpy(tmp,token);
buf[strlen(buf)-2] = 0;
tmp[strlen(tmp)-2] = 0;
/* 要不要 is_base64 | is_qb */
snprintf(hdr->nick, 48, "%s", pop3_mime_transfer(parse_nick(token)));
/* 來源需取出只需要的部分 <s874070@mail.yzu.edu.tw> */
hdr->nick[48] = 0;
snprintf(hdr->owner, 78, "%s", pop3_mime_transfer(parse_owner(tmp)));
hdr->owner[78] = 0;
}
/* 日期 */
/* Date: Sun, 26 Dec 1999 02:07:46 -0800 */
/* Date: 04 Jul 2000 07:18:54 GMT */
if(!strncmp(buf, "Date: ", strlen("Date: ")))
{
token = ptr = buf + strlen("Date: ");
buf[strlen(buf)-2] = 0;
if(!strstr(token, "GMT"))
token += 5;
strptime(token, "%d %b %Y", &tmdate);
// strptime(token, "%a, %d %b %Y", &tmdate);
snprintf(hdr->date, 9, "%02d/%02d/%02d",
(tmdate.tm_year)%100, tmdate.tm_mon+1, tmdate.tm_mday);
}
/* 標題 */
/* Subject: xxxxxx */
if(!strncmp(buf, "Subject: ", strlen("Subject: ")))
{
token = ptr = buf + strlen("Subject: ");
buf[strlen(buf)-2] = 0;
pop3_mime_transfer(ptr);
strncpy(hdr->title, ptr, 72);
hdr->title[72] = 0;
}
fgets(buf, 256, fsock);
lines++;
}
hdr->xid = lines;
}
static int
pop3_load_dir()
{
char buf[256],tmp[80];
int total = 0, step = 0, begin = 1, count;
HDR hdr;
/* int totalsize;*/
fprintf(fsock, "STAT\r\n");
fgets(buf, 256, fsock); /* +OK 14 63665 */
if(!strncmp(buf, "+OK", 3))
{
total = atoi(buf+4);
/* count = int_len(total);
totalsize = atoi(buf+4+count);
sprintf(tmp,"信件:%d 封,共 %d bytes", total, totalsize);
vmsg(tmp);*/
if(total == 0)
{
vmsg("您的電子郵件信箱沒有信件。");
return 1;
}
else
begin = 1;
}
else
return 1;
sprintf(tmp, "mailservice/%s.DIR", cuser.userid); /* DIRECTORY/MBOX */
unlink(tmp);
if((step = open(tmp, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0)
return 1;
for(count = begin; count <= total; count++)
{
hdr.xmode = MAIL_READ;
hdr.chrono = count;
snprintf(hdr.xname, 32, "%s.mail", cuser.userid);
parse_header(&hdr, count); // 解譯 header
write(step, &hdr, sizeof(HDR)); /* hdr to file */
}
close(step);
return 0;
}
static int
chkpop3(hdr)
HDR *hdr;
{
return (hdr->xmode & MAIL_MARKED);
}
static int
vfypop3(hdr, pos)
HDR *hdr;
int pos;
{
return (Tagger(hdr->chrono, pos, TAG_NIN) || chkpop3(hdr));
}
static void
delpop3(xo, hdr)
XO *xo;
HDR *hdr;
{
char fpath[64];
hdr_fpath(fpath, xo->dir, hdr);
unlink(fpath);
}
static int
pop3_rangedel(xo)
XO *xo;
{
return xo_rangedel(xo, sizeof(HDR), chkpop3, delpop3);
}
static int
pop3_delete(xo)
XO *xo;
{
int pos;
HDR *hdr;
char fpath[64], *dir;
pos = xo->pos;
hdr = (HDR *) xo_pool + (pos - xo->top);
if (hdr->xmode & MAIL_MARKED)
return XO_NONE;
if (vans(msg_del_ny) == 'y')
{
dir = xo->dir;
currchrono = hdr->chrono;
if (!rec_del(dir, sizeof(HDR), pos, cmpchrono))
{
hdr_fpath(fpath, dir, hdr);
unlink(fpath);
return XO_LOAD;
}
}
return XO_FOOT;
}
static int
pop3_get(fpath,hdr)
char *fpath;
HDR *hdr;
{
char mail[80], buf[256] , *ptr ,*end;
int start, totalsize,count,ck,page;
int check_size;
FILE *fp;
snprintf(hdr->xname, 32, "%s.mail", cuser.userid);
sprintf(mail, "mailservice/%s.mail", cuser.userid);
fp = fopen(mail, "w");
/* GET SIZE*/
fprintf(fsock, "LIST %d\r\n", (int)hdr->chrono);
fgets(buf, 256, fsock);
totalsize = atoi(buf+5+int_len(hdr->chrono));
if(totalsize > 10485760)
{
fprintf(fp, "\n信件容量太大,無法收取。\n");
fclose(fp);
return 0;
}
count = hdr->xid;
if(!is_bbsmail)
{
fprintf(fp, "作者: %s\n", hdr->owner); /* 把 From 改成 作者 */
fprintf(fp, "標題: %s\n", hdr->title);
fprintf(fp, "時間: %s\n\n", hdr->date);
}
/* GET BODY */
fprintf(fsock, "RETR %d\r\n", (int)hdr->chrono);
fgets(buf, 256, fsock);
start = is_bbsmail ? -1 : 1;
page = 0;
is_qp = hdr->xmode & MIME_QP;
is_base64 = hdr->xmode & MIME_BASE64;
fgets(buf, 256, fsock);
totalsize = 0;
boundary[0] = 0;
page = 1;
check_size = 0;
do
{
start++;
ck = pop3_mime_cut(buf, hdr, fp,fsock);
if(start < count && *boundary == 0 && (ptr = strstr(buf,"boundary")))
{
ptr = strchr(buf,'"');
end = strchr(ptr+1,'"');
*end = 0;
strcpy(boundary,ptr+1);
}
}
if(ck == -1)
{
page = 1;
hdr->xmode &= ~MIME_MIME;
}
is_qp = hdr->xmode & MIME_QP;
is_base64 = hdr->xmode & MIME_BASE64;
if(start >= count && page == 1 && ck == 1 && !check_size)
{
pop3_mime_transfer(buf);
fprintf(fp, "%s", buf);
totalsize += strlen(buf);
if(totalsize > 10485760)
{
fprintf(fp, "\n信件容量太大,無法收取。\n");
check_size = 1;
}
}
ptr = fgets(buf, 256, fsock);
} while(strcmp(buf, ".\r\n") && ptr);
if((hdr->xmode & (MIME_BASE64|MIME_QP)) && is_mime)
{
fprintf(fp, "\n**這是一封經過 MIME 解碼的文件,如有問題請通知系統管理者。**
\n");
}
fclose(fp);
return 1;
}
static int
pop3_browse(xo)
XO *xo;
{
char file[32];
HDR *hdr;
hdr = (HDR *) xo_pool + (xo->pos - xo->top);
sprintf(file, "mailservice/%s.mail", cuser.userid);
if(!pop3_get(file, hdr))
return XO_NONE;
strncpy(currtitle, hdr->title, 40); /* title 只取用前 40 個 ? */
more(file, NULL);
hdr->xmode |= MAIL_READ;
return XO_HEAD;
}
static inline int
mbox_attr(type)
int type;
{
if (type & MAIL_DELETE)
return 'D';
if (type & MAIL_REPLIED)
return (type & MAIL_MARKED) ? 'R' : 'r';
return "+ Mm"[type & 3];
}
static int
pop3_tag(xo)
XO *xo;
{
HDR *hdr;
int tag, pos, cur;
pos = xo->pos;
cur = pos - xo->top;
hdr = (HDR *) xo_pool + cur;
if (tag = Tagger(hdr->chrono, pos, TAG_TOGGLE))
{
move(3 + cur, 7);
outc(tag > 0 ? '*' : ' ');
}
return xo->pos + 1 + XO_MOVE;
}
static int
pop3_prune(xo)
XO *xo;
{
return xo_prune(xo, sizeof(HDR), vfypop3, delpop3);
}
static int
pop3_mime_change()
{
is_mime ^= 1;
return XO_HEAD;
}
static int
pop3_mark(xo)
XO *xo;
{
HDR *mhdr;
int cur, pos;
pos = xo->pos;
cur = pos - xo->top;
mhdr = (HDR *) xo_pool + cur;
move(3 + cur, 6);
outc(mbox_attr(mhdr->xmode ^= MAIL_MARKED));
rec_put(xo->dir, mhdr, sizeof(HDR), pos, NULL);
return XO_NONE;
}
static void
pop3_item(pos, hdr)
int pos;
HDR *hdr;
{
#ifdef OVERDUE_MAILDEL
int xmode;
xmode = hdr->xmode;
prints(xmode & MAIL_DELETE ? "%6d%c\033[1;5;37;41m%c\033[m " : "%6d%c%c ",
pos, tag_char(hdr->chrono), mbox_attr(xmode));
#else
prints("%6d%c%c ", pos, tag_char(hdr->chrono), mbox_attr(hdr->xmode));
#endif
hdr_outs(hdr, 47);
}
#ifdef HAVE_LIGHTBAR
static int
pop3_item_bar(xo, mode)
XO *xo; /* sequence number */
int mode;
{
HDR *hdr;
hdr = (HDR *) xo_pool + xo->pos - xo->top;
#ifdef OVERDUE_MAILDEL
int xmode;
xmode = hdr->xmode;
prints(xmode & MAIL_DELETE ? mode ?
"\033[1;44m%6d%c\033[5;37;41m%c\033[0;1;44m " : "%6d%c\033[1;5;37;41m%c\033
[m " : mode ? "\
033[1;44m%6d%c%c " : "%6d%c%c ", xo->pos + 1, tag_char(hdr->chrono), mbox_attr(
xmode));
#else
prints("%s%6d%c%c ", mode ? "\033[1;44m" : "", xo->pos + 1,
tag_char(hdr->chrono), mbox_attr(hdr->xmode));
#endif
if (mode)
hdr_outs_bar(hdr, 47);
else
hdr_outs(hdr, 47);
return XO_NONE;
}
#endif
static int
pop3_body(xo)
XO *xo;
{
HDR *pop3;
int num, max, tail;
max = xo->max;
if (max <= 0)
{
vmsg("您的電子郵件信箱沒有信件。");
return XO_QUIT;
}
pop3 = (HDR *) xo_pool;
num = xo->top;
tail = num + XO_TALL;
if (max > tail)
max = tail;
move(3, 0);
do
{
pop3_item(++num, pop3++);
} while (num < max);
clrtobot();
return XO_FOOT;
}
static int
pop3_head(xo)
XO *xo;
{
vs_head("Pop3服務", str_site);
outs("[←]離開 [→,r]讀信 [d]刪除/救回 [S]重讀 [R]回信 [x]轉達 [h]說明");
if(is_mime)
outs(" [MIME 解碼]");
else
outs(" [ 無 解碼]");
outs("\n\033[44m\
編號 日 期 作 者 信 件 標 題 \03
3[m");
return pop3_body(xo);
}
static int
pop3_load(xo)
XO *xo;
{
xo_load(xo, sizeof(HDR));
return pop3_body(xo);
}
static int
pop3_init(xo)
XO *xo;
{
xo_load(xo, sizeof(HDR));
return pop3_head(xo);
}
static int
pop3_help(xo)
XO *xo;
{
vmsg("懶得寫 :p");
return XO_FOOT;
}
static int
pop3_send(xo)
XO *xo;
{
m_send();
return pop3_head(xo);
}
static int
pop3_reply(xo)
XO *xo;
{
HDR *hdr;
hdr = (HDR *) xo_pool + (xo->pos - xo->top);
sprintf(quote_file,"mailservice/%s.mail",cuser.userid);
if(!pop3_get(quote_file,hdr))
return XO_NONE;
do_mreply(hdr);
return XO_HEAD;
}
static int
pop3_forward(xo)
XO *xo;
{
HDR *hdr,mhdr;
char fpath[80],rcpt[64],folder[128];
int userno;
hdr = (HDR *) xo_pool + (xo->pos - xo->top);
strcpy(rcpt,cuser.email);
sprintf(fpath,"mailservice/%s.mail",cuser.userid);
if(!pop3_get(fpath,hdr))
return XO_NONE;
if (!vget(b_lines, 0, "目的地:", rcpt, sizeof(rcpt), GCARRY))
return XO_FOOT;
if (mail_external(rcpt))
bsmtp(fpath, hdr->title, rcpt, 0);
else
{
if ((userno = acct_userno(rcpt)) <= 0)
return -1;
usr_fpath(folder, rcpt, fn_dir);
hdr_stamp(folder, HDR_LINK, &mhdr, fpath);
strcpy(mhdr.owner, cuser.userid);
strcpy(mhdr.nick, cuser.username);
strcpy(mhdr.title, hdr->title);
rec_add(folder, &mhdr, sizeof(mhdr));
m_biff(userno);
}
return XO_HEAD;
}
static int
pop3_reload_dir(xo)
XO *xo;
{
char buf[128];
fprintf(fsock,"RSET\r\n");
do
{
fgets(buf,128,fsock);
} while (strncmp(buf,"+OK",3));
if(pop3_load_dir())
{
fclose(fsock);
vmsg("重讀失敗");
return XO_QUIT;
}
del_num = 0; /* 重設已刪除文章為 1 */
return XO_INIT;
}
static int
pop3_mailsize(xo)
XO *xo;
{
char buf[128],msg[128],*str;
HDR *hdr;
int total,totalsize;
hdr = (HDR *) xo_pool + (xo->pos - xo->top);
fprintf(fsock,"LIST %d\r\n",xo->pos+1);
do
{
str = fgets(buf,128,fsock);
} while (strncmp(buf,"+OK",3) && str);
if(str)
{
str = strchr(buf,' ');
total = atoi(str);
str = strchr(str+1,' ');
totalsize = atoi(str);
sprintf(msg,"信件:第 %d 封,共 %d bytes", total, totalsize);
vmsg(msg);
}
else
return XO_HEAD;
return XO_INIT;
}
static int
pop3_stat(xo)
XO *xo;
{
char buf[128],msg[128],*str;
int total,totalsize;
fprintf(fsock,"STAT\r\n");
do
{
str = fgets(buf,128,fsock);
} while (strncmp(buf,"+OK",3) && str);
if(str)
{
str = strchr(buf,' ');
total = atoi(str);
str = strchr(str+1,' ');
totalsize = atoi(str);
sprintf(msg,"信件:%d 封,共 %d bytes", total, totalsize);
vmsg(msg);
}
else
return XO_HEAD;
return XO_INIT;
}
KeyFunc pop3_cb[] =
{
#ifdef HAVE_LIGHTBAR
XO_ITEM, pop3_item_bar,
#endif
XO_INIT, pop3_init,
XO_LOAD, pop3_load,
XO_HEAD, pop3_head,
XO_BODY, pop3_body,
'r', pop3_browse,
'd', pop3_delete,
'R', pop3_reply,
'y', pop3_reply,
's', pop3_send,
'C', pop3_stat,
'c', pop3_mailsize,
't', pop3_tag,
'S', pop3_reload_dir,
'x', pop3_forward,
'm', pop3_mark,
'M', pop3_mime_change,
Ctrl('D'), pop3_prune,
'D', pop3_rangedel,
'h', pop3_help
};
static int
server_login(inputemail)
char *inputemail;
{
char buf[256], user[60], email[60], pass[20], *host;
int sock = 110; /* pop3 port */
more(FN_ETC_MAILSERVICE, (char *)-1);
if(inputemail)
strcpy(email,inputemail);
else
strcpy(email,cuser.email); /* 自動幫 user 加上帳號名 */
pass[0] = 0;
if(!vget(21, 0, "帳號:", email, 60, GCARRY) ||
!vget(22, 0, "密碼:", pass, 20, NOECHO))
{ /* 有一項沒輸入則放棄 */
return -1;
}
if(!strchr(email, '@'))
{
vmsg("輸入帳號有誤");
return 1;
}
strcpy(user, email);
*(strchr(user,'@')) = 0;
host = strchr(email, '@')+1;
if(Get_Socket(host, &sock))
{
vmsg("主機無法連線");
return 1;
}
fsock = fdopen(sock, "r+");
fgets(buf, 256, fsock); /* Welcome */
fprintf(fsock, "USER %s\r\n", user); /* USER NAME */
fgets(buf, 256, fsock);
if(!strncmp(buf, "+OK", 3))
{
is_bbsmail = strstr(buf,".bbs@") ? 1 : 0;
fprintf(fsock,"PASS %s\r\n", pass); /* PASSWORD */
fgets(buf, 256, fsock);
if(strncmp(buf, "+OK", 3))
{
logitfile(FN_MAILSERVICE_LOG, "-pop3 NO-", email); /* 登入失敗記錄
*/
vmsg("登入失敗, 密碼錯誤.");
fclose(fsock);
return 1;
}
else
{
logitfile(FN_MAILSERVICE_LOG, "-pop3 OK-", email); /* 登入成功記錄
*/
}
}
else
{
logitfile(FN_MAILSERVICE_LOG, "-pop3 NO-", email); /* 登入失敗記錄 *
/
vmsg("登入失敗, 無此帳號.");
fclose(fsock);
return 1;
}
if(pop3_load_dir())
{
fclose(fsock);
return 1;
}
return 0;
}
static int
server_logout(xo)
XO *xo;
{
if (del_num && vans(msg_del_ny) == 'y')
{
int fd;
HDR hdr;
char buf[200];
if ((fd = open(xo->dir, O_RDONLY)) >= 0)
{
while (read(fd, &hdr, sizeof(hdr)) == sizeof(HDR))
{
if (hdr.xmode & POST_DELETE)
{
fprintf(fsock, "DELE %d\r\n", hdr.chrono);
while (1)
{
if (!strncmp(fgets(buf, 200, fsock), "+OK", 3))/* purge messages */
break;
}
}
}
close(fd);
}
}
fprintf(fsock, "QUIT\r\n");
fclose(fsock);
return 0;
}
int
Pop3mail()
{
XO *xo;
char currsmaildir[30];
del_num = is_base64 = is_qp = 0; /* 預設已刪除文章數為 0, 無解碼方式 */
is_mime = (cuser.ufo & UFO_MIME) ? 1 : 0; /* 若無 UFO_MIME 則將這行取消 */
sprintf(currsmaildir, "mailservice/%s.DIR", cuser.userid); /*DIRECTORY/MBOX*/
/* by statue */
if (server_login(NULL))
return 0;
xz[XZ_MIME - XO_ZONE].xo = xo = xo_new(currsmaildir); /* 設取 .DIR 路徑 */
xz[XZ_MIME - XO_ZONE].cb = pop3_cb;
xover(XZ_MIME);
server_logout(xo);
free(xo);
return 0;
}
int
Pop3Contact(email)
char *email;
{
XO *xo;
char currsmaildir[30];
del_num = is_base64 = is_qp = 0; /* 預設已刪除文章數為 0, 無解碼方式 */
is_mime = (cuser.ufo & UFO_MIME) ? 1 : 0; /* 若無 UFO_MIME 則將這行取消 */
sprintf(currsmaildir, "mailservice/%s.DIR", cuser.userid); /*DIRECTORY/MBOX*/
if (server_login(email))
return 0;
xz[XZ_MIME - XO_ZONE].xo = xo = xo_new(currsmaildir); /* 設取 .DIR 路徑 */
xz[XZ_MIME - XO_ZONE].cb = pop3_cb;
xover(XZ_MIME);
server_logout(xo);
free(xo);
return 0;
}
--
『╭╯成大醫學╭╯ ◥◢ ﹌ ☆ �i�i bbs.med.ncku.edu.tw �i�i ☆ ﹋
╭╯迴 風 谷╭╯』 ◤◣ →From:backwind.g1.dorm.ncku.edu.tw ←