作者itoc, 信區: itoc
標題[功能] mail.c 信件自動轉寄到外站 Internet 信箱
時間06/03/31
作者: itoc (站上人數:802) 看板: plan
標題: [功能] 信件自動轉寄到外站 Internet 信箱
時間: 2006/03/31 Fri 09:23:38 Updated: 2006/03/31
※ 引述《guessi.bbs@bbs.ee.ndhu.edu.tw (沒)》之銘言:
> 想寫一個功能"自動轉寄" 當使用者收取信件時自動轉寄到站外信箱 (類似於備份?)
設定外部信箱
: global.h
#define FN_ACL "acl" /* 上站地點設定 */
+ #define FN_FORWARD "forward" /* 自動轉寄設定 */
: maple.p 加一行
+ int m_setforward(void);
: menu.c 適當的選單加入這選項
+ m_setforward, PERM_BASIC, M_SMAIL,
+ "AutoForward├ 自動轉寄 ┤",
: mail.c:m_setforward() 在 mail_hold() 後面新增這個函式
int
m_setforward()
{
char fpath[64], ip[50];
FILE *fp;
usr_fpath(fpath, cuser.userid, FN_FORWARD);
if (fp = fopen(fpath, "r"))
{
fscanf(fp, "%s", ip);
fclose(fp);
}
else
{
ip[0] = '\0';
}
vget(b_lines - 1, 0, "請輸入信件自動轉寄的 E-mail:", ip, 50, GCARRY);
if (ip[0] && !not_addr(ip) &&
vans("確定開啟自動轉信功\能(Y/N)?[N] ") == 'y')
{
if (fp = fopen(fpath, "w"))
{
fprintf(fp, "%s", ip);
fclose(fp);
vmsg("設定完成");
return XEASY;
}
}
unlink(fpath);
vmsg("取消自動轉寄或無效 E-mail");
return XEASY;
}
> ───────────────────────────────────── <
轉寄站內來信至外部信箱
: mail.c:forward_mail() 在 mail_send() 前面新增這個函式
/* cuser.userid 將「標題 title、檔案在 fpath」的信件寄給 userid 的外部信箱 */
static void
forward_mail(fpath, userid, title)
char *fpath, *userid, *title;
{
FILE *fp;
char ip[80];
usr_fpath(ip, userid, FN_FORWARD);
if (fp = fopen(ip, "r"))
{
fscanf(fp, "%s", ip);
fclose(fp);
if (ip[0])
bsmtp(fpath, title, ip, 0);
}
}
: mail.c:mail_send()
rec_add(folder, &hdr, sizeof(HDR));
+ forward_mail(fpath, rcpt, ve_title);
: mail.c:multi_send()
rec_add(buf, &hdr, sizeof(HDR));
+ forward_mail(fpath, userid, title);
> ───────────────────────────────────── <
轉寄站外來信至外部信箱
: bmtad.c:forward_mail() 在 bbs_mail() 前面新增這個函式
/* hdr->owner 將「標題 hdr->title、檔案在 folder 下 hdr->xname」
的信件寄給 userid 的外部信箱 */
static void
forward_mail(hdr, folder, userid)
HDR *hdr;
char *folder;
char *userid;
{
FILE *fp;
char ip[80], fpath[64];
usr_fpath(ip, userid, FN_FORWARD);
if (fp = fopen(ip, "r"))
{
fscanf(fp, "%s", ip);
fclose(fp);
if (ip[0])
{
hdr_fpath(fpath, folder, hdr);
bbsmtp(fpath, hdr->title, ip, hdr->owner);
}
}
}
: bmtad.c:bbs_mail()
rec_add(folder, &hdr, sizeof(HDR));
+ forward_mail(&hdr, folder, userid);
: bmtad.c:bbsmtp() 在 forward_mail() 前面新增這個函式
static int /* >=0:成功 <0:失敗 */
bbsmtp(fpath, title, rcpt, sender) /* 從 bsmtp() 抄來的 */
char *fpath, *title, *rcpt, *sender;
{
int sock;
time_t stamp;
FILE *fp, *fr, *fw;
char *str, buf[512], from[80], msgid[80];
ACCT acct;
if (acct_fetch(sender, &acct) < 0)
return -1;
time(&stamp);
sprintf(from, "%s.bbs@%s", acct.userid, MYHOSTNAME);
str = strchr(rcpt, '@') + 1;
sock = dns_smtp(str);
if (sock >= 0)
{
sleep(1); /* wait for mail server response */
fr = fdopen(sock, "r");
fw = fdopen(sock, "w");
fgets(buf, sizeof(buf), fr);
if (memcmp(buf, "220", 3))
goto smtp_error;
while (buf[3] == '-')
fgets(buf, sizeof(buf), fr);
fprintf(fw, "HELO %s\r\n", MYHOSTNAME);
fflush(fw);
do
{
fgets(buf, sizeof(buf), fr);
if (memcmp(buf, "250", 3))
goto smtp_error;
} while (buf[3] == '-');
fprintf(fw, "MAIL FROM:<%s>\r\n", from);
fflush(fw);
do
{
fgets(buf, sizeof(buf), fr);
if (memcmp(buf, "250", 3))
goto smtp_error;
} while (buf[3] == '-');
fprintf(fw, "RCPT TO:<%s>\r\n", rcpt);
fflush(fw);
do
{
fgets(buf, sizeof(buf), fr);
if (memcmp(buf, "250", 3))
goto smtp_error;
} while (buf[3] == '-');
fprintf(fw, "DATA\r\n", rcpt);
fflush(fw);
do
{
fgets(buf, sizeof(buf), fr);
if (memcmp(buf, "354", 3))
goto smtp_error;
} while (buf[3] == '-');
/* ------------------------------------------------- */
/* begin of mail header */
/* ------------------------------------------------- */
archiv32(stamp, msgid);
/* Thor.990125: 儘可能的像 RFC 822 及 sendmail 的作法, 免得別人不接:p */
fprintf(fw, "From: \"%s\" <%s>\r\nTo: %s\r\n",
acct.username, from, rcpt);
/* itoc.030411: mail 輸出 RFC 2047 */
output_rfc2047_qp(fw, "Subject: ", title, MYCHARSET, "\r\n");
/* itoc.030323: mail 輸出 RFC 2045 */
fprintf(fw, "X-Sender: %s (%s)\r\n"
"Date: %s\r\nMessage-Id: <%s@%s>\r\n"
"Mime-Version: 1.0\r\n"
"Content-Type: %s; charset=%s\r\n"
"Content-Transfer-Encoding: 8bit\r\n"
"X-Disclaimer: [%s] 對本信內容恕不負責\r\n\r\n",
acct.userid, acct.username,
Atime(&stamp), msgid, MYHOSTNAME,
"text/plain", MYCHARSET,
str_site);
/* ------------------------------------------------- */
/* begin of mail body */
/* ------------------------------------------------- */
if (fp = fopen(fpath, "r"))
{
char *ptr;
str = buf;
*str++ = '.';
while (fgets(str, sizeof(buf) - 3, fp))
{
if (ptr = strchr(str, '\n'))
{
*ptr++ = '\r';
*ptr++ = '\n';
*ptr = '\0';
}
fputs((*str == '.' ? buf : str), fw);
}
fclose(fp);
}
#ifdef HAVE_SIGNED_MAIL
if (!rec_get(FN_RUN_PRIVATE, buf, 8, 0))
{
time_t prichro;
buf[8] = '\0'; /* Thor.990413: buf 用不到了,借來用用 */
prichro = chrono32(buf);
archiv32(str_hash(msgid, prichro), buf);
fprintf(fw,"※ X-Sign: %s$%s %s\r\n",
msgid, genpasswd(buf), Btime(&stamp));
}
#endif
fputs("\r\n.\r\n", fw);
fflush(fw);
fgets(buf, sizeof(buf), fr);
if (memcmp(buf, "250", 3))
goto smtp_error;
fputs("QUIT\r\n", fw);
fflush(fw);
fclose(fw);
fclose(fr);
goto smtp_log;
smtp_error:
/* itoc.041128.註解: 凡是走到這裡的,buf 是對方回覆的錯誤訊息 */
fclose(fr);
fclose(fw);
sprintf(from, "\t%.70s\n", buf);
sock = -1;
}
else
{
strcpy(from, "\tSMTP 連線失敗\n");
}
smtp_log:
/* --------------------------------------------------- */
/* 記錄寄信 */
/* --------------------------------------------------- */
sprintf(buf, "%s %-13s%c> %s\n%s\t%s\n\t%s\n",
Btime(&stamp), acct.userid, '-', rcpt,
sock >= 0 ? "" : from, title, fpath);
f_cat(FN_RUN_MAIL_LOG, buf);
return sock;
}
--
□ 本文章由 itoc 從 itoc.Dorm11.NCTU.edu.tw 發表