
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>

#include"zither.h"
#include<almemsys/almemsys.h>



// int mail_grsend_t(mail_data_t *);



/* --- スレッド分岐してメール送信 --- */
int mail_grsend_t(mail_data_t * mdd)
{
int aaa;
int stat;
int port;
int timeout;

// char * charset = "X-Mailer: zither_server\r\n";
char * swap;
char * message;
char * charset = "X-Mailer: ";
char * charversion = CL_VAR;
char * charkaigyou = "\r\n";
char * charenc = "X-Priority: ";
char * charcontyp = "Content-Type: Text/Plain; charset=iso-2022-jp\r\n";
char * chartraenc = "Content-Transfer-Encoding: 7bit\r\n";

stat = 0;
port = 25;
timeout = 6;

// Message_ID を作る
swap = (char *)calloc(256, sizeof(char));
message = (char *)calloc(512, sizeof(char));
swap = message_id(swap, "Zither_server", mdd->iserver);
message = safe_sprintf(message, BUF_LEN,"Message-Id: <%s>", swap);
free(swap);

// スレッドのデタッチ
pthread_detach(pthread_self());

// メールヘッダーの時間を取得
mail_time_getr(mdd->cp_time, BUF_LEN, "+0900");

// メールサーバに接続
if((stat = socket_connect(&mdd->my_maddr, port, mdd->iserver, &mdd->sk))< 0){
   fprintf(stderr,"mail_grsend_t():socket_connect(): err stat=<%d>\n", stat);
   goto mailend;
   }

// コネクト出来た場合に返事をまつ
mdd->swap = safe_fdcat(mdd->sk, mdd->swap, &stat, BUF_MAX, MAIL_INTERVAL);
#ifdef MAIL_DEBUG_IN
fprintf(stderr,"in0<%s>\n", mdd->swap);
#endif
if(stat < 0){
   fprintf(stderr,"mail_grsend_t():safe_fdcat(): err\n");
   goto mailend;
   }

// HELO localhost を送信
mdd->swap = safe_memcpy(mdd->swap, "HELO localhost\r\n", BUF_MAX);
#ifdef MAIL_DEBUG_OUT
fprintf(stderr,"out1<%s>\n", mdd->swap);
#endif

if(0 > (socket_send(mdd->sk, mdd->swap, timeout))){
   fprintf(stderr,"mail_grsend_t():socket_send(): err\n");
   goto mailend;
   }

// HELO に対するステータスをまつ
mdd->swap = safe_fdcat(mdd->sk, mdd->swap, &stat, BUF_MAX, MAIL_INTERVAL);
#ifdef MAIL_DEBUG_IN
fprintf(stderr,"in1<%s>\n", mdd->swap);
#endif
if(stat < 0){
   fprintf(stderr,"mail_grsend_t():safe_fdcat():2 err\n");
   goto mailend;
   }

// MAIL FORM: を送信
mdd->swap = safe_sprintf(mdd->swap, BUF_MAX, "%s<%s>\r\n", "MAIL FROM: ", mdd->ifrom);
#ifdef MAIL_DEBUG_OUT
fprintf(stderr,"out2<%s>\n", mdd->swap);
#endif

if(0 > (socket_send(mdd->sk, mdd->swap, timeout))){
   fprintf(stderr,"mail_grsend_t():socket_send():2 err\n");
   goto mailend;
   }

// MAIL FORM: に対するステータスをまつ
mdd->swap = safe_fdcat(mdd->sk, mdd->swap, &stat, BUF_MAX, MAIL_INTERVAL);
#ifdef MAIL_DEBUG_IN
fprintf(stderr,"in2<%s>\n", mdd->swap);
#endif
if(stat < 0){
   fprintf(stderr,"mail_grsend_t():safe_fdcat():3 err\n");
   goto mailend;
   }

// RCPT TO: を作成送信、そのステータスを判断
mdd->rcptto = safe_memcpy(mdd->rcptto, mdd->ircptto, BUF_MAX);
// BCC が有効の場合、BCCのアドレスを追加
if(2 < (strlen(mdd->bccadd))){
   if(0 == self_memcmp(mdd->bccadd, "NOT")){
      #ifdef MAIL_DEBUG_IN
      fprintf(stderr,"mail_grsend_t():safe_fdcat(): このメールにはBCCの設定はないようです。\n");
      #endif
      }
   else{
      mdd->rcptto = safe_strncat(mdd->rcptto, ",", BUF_MAX);
      mdd->rcptto = safe_strncat(mdd->rcptto, mdd->bccadd, BUF_MAX);
      }
   }

// CC が有効な場合、CCのアドレスを追加
if(2 < (strlen(mdd->icc))){
   if(0 != memcmp(mdd->icc, "NOT", 3)){
      mdd->rcptto = safe_strncat(mdd->rcptto, ",", BUF_MAX);
      mdd->rcptto = safe_strncat(mdd->rcptto, mdd->icc, BUF_MAX);
      }
   }


if(0 > (aaa = send_rcptto(mdd, BUF_LEN))){
   fprintf(stderr,"mail_grsend_t():send_rcptto():stat err <%s>\n", mdd->rcptto);
   goto mailend;
   }

#ifdef MAIL_DEBUG_OUT
printf("mail_grsend(): send_rcptto send data=<%s> stat =<%d>\n", mdd->rcptto, aaa);
#endif


// DATA: を送信
mdd->swap = safe_memcpy(mdd->swap, "DATA\r\n", BUF_MAX);
#ifdef MAIL_DEBUG_OUT
fprintf(stderr,"out3<%s>\n", mdd->swap);
#endif

if(0 > (socket_send(mdd->sk, mdd->swap, timeout))){
   fprintf(stderr,"mail_grsend_t():socket_send():2 err\n");
   goto mailend;
   }


// 拡張ヘッダーを作成
mdd->swap2 = safe_sprintf(mdd->swap2, BUF_MAX, "%s\r\n%s %s\r\n", message, charenc, mdd->pri);

mdd->swap = safe_sprintf(mdd->swap, BUF_MAX,"%s%s%s%s%s%s",
  charset, charversion, charkaigyou, mdd->swap2, charcontyp, chartraenc);

mdd->swap2 = safe_sprintf(mdd->swap2, BUF_MAX, "%s<%s>\r\n", "From: ", mdd->ifrom);
mdd->swap = safe_strncat(mdd->swap, mdd->swap2, BUF_MAX);

mdd->swap2 = safe_sprintf(mdd->swap2, BUF_MAX, "%s%s\r\n", "Date: ", mdd->cp_time);
mdd->swap = safe_strncat(mdd->swap, mdd->swap2, BUF_MAX);

mdd->swap2 = safe_sprintf(mdd->swap2, BUF_MAX, "%s%s\r\n", "To: ", mdd->ircptto);
mdd->swap = safe_strncat(mdd->swap, mdd->swap2, BUF_MAX);

if(2 < (strlen(mdd->icc))){
   if(0 != memcmp(mdd->icc, "NOT", 3)){
      mdd->swap2 = safe_sprintf(mdd->swap2, BUF_MAX, "Cc: %s\r\n", mdd->icc);
      mdd->swap = safe_strncat(mdd->swap, mdd->swap2, BUF_MAX);
      }
   }

// 拡張ヘッダーと本文からBODY作成

mdd->idata = swap_rn(mdd->idata, (char)0x01);
mdd->swap2 = safe_sprintf(mdd->swap2, BUF_MAX, "%s\r\n\r\n%s\r\n", mdd->isubject, mdd->idata);
mdd->swap = safe_strncat(mdd->swap, mdd->swap2, BUF_MAX);
#ifdef MAIL_DEBUG_OUT
fprintf(stderr,"out4<%s>\n", mdd->swap);
#endif

// BODY 送信
if(0 > (socket_send(mdd->sk, mdd->swap, timeout))){
   fprintf(stderr,"mail_sender():socket_send():4 err\n");
   goto mailend;
   }

// BODY に対するステータスを得る
mdd->swap = safe_fdcat(mdd->sk, mdd->swap, &stat, BUF_MAX, MAIL_INTERVAL);
#ifdef MAIL_DEBUG_IN
fprintf(stderr,"in4<%s>\n", mdd->swap);
#endif
if(stat < 0){
   fprintf(stderr,"mail_sender():safe_fdcat():4 err\n");
   goto mailend;
   }

// .\r\n を送信
mdd->swap = safe_memcpy(mdd->swap, ".\r\n", BUF_MAX);
#ifdef MAIL_DEBUG_OUT
fprintf(stderr,"out5<%s>\n", mdd->swap);
#endif

if(0 > (socket_send(mdd->sk, mdd->swap, timeout))){
   fprintf(stderr,"mail_sender():socket_send():5 err\n");
   goto mailend;
   }

// .\r\n のステータスを得る
mdd->swap = safe_fdcat(mdd->sk, mdd->swap, &stat, BUF_MAX, MAIL_INTERVAL);
#ifdef MAIL_DEBUG_IN
fprintf(stderr,"in5<%s>\n", mdd->swap);
#endif
if(stat < 0){
   fprintf(stderr,"mail_sender():safe_fdcat():5 err\n");
   goto mailend;
   }

// QUIT の送信
mdd->swap = safe_sprintf(mdd->swap, BUF_MAX, "QUIT\r\n\r\n");
#ifdef MAIL_DEBUG_OUT
fprintf(stderr,"out6<%s>\n", mdd->swap);
#endif

if(0 > (socket_send(mdd->sk, mdd->swap, timeout))){
   fprintf(stderr,"mail_sender():socket_send():6 err sk=%d, data=%s\n", mdd->sk, mdd->swap);
   goto mailend;
   }

// QUITに対するステータスをえる
mdd->swap = safe_fdcat(mdd->sk, mdd->swap, &stat, BUF_MAX, MAIL_INTERVAL);
#ifdef MAIL_DEBUG_IN
fprintf(stderr,"in6<%s>\n", mdd->swap);
#endif
if(stat < 0){
   fprintf(stderr,"mail_sender():safe_fdcat():7 err\n");
   goto mailend;
   }

// 失敗はここにくるの、、、
mailend :;

// 戦後処理

free(message);
close(mdd->sk);
mail_free(mdd);
free(mdd);
return 0;
}







