예제 #1
0
파일: ezmlm-get.c 프로젝트: abh/ezmlm-idx
void normal_bottom(char format)
/* Copies bottom text and the original message to the new message */
{
  if (flagbottom) {
    copy(&qq,"text/bottom",flagcd);
    if (flagcd && format != RFC1153) {
      if (flagcd == 'B') {
	encodeB("",0,&line,2);	/* flush */
	qmail_put(&qq,line.s,line.len);
      }
      hdr_boundary(0);
      hdr_ctype(CTYPE_MESSAGE);
      hdr_adds("Content-Disposition: inline; filename=request.msg");
      qmail_puts(&qq,"\n");
    }
    qmail_puts(&qq,"Return-Path: <");
    if (!quote2(&quoted,sender)) die_nomem();
    qmail_put(&qq,quoted.s,quoted.len);
    qmail_puts(&qq,">\n");
    if (seek_begin(0) == -1)
      strerr_die2sys(111,FATAL,MSG(ERR_SEEK_INPUT));
    if (qmail_copy(&qq,&ssin2,copylines) != 0)
      strerr_die2sys(111,FATAL,MSG(ERR_READ_INPUT));
  } else {
    if (flagcd == 'B' && format != RFC1153) {
      encodeB("",0,&line,2);	/* flush */
      qmail_put(&qq,line.s,line.len);
    }
  }
}
예제 #2
0
void copybottom(int forcebottom)
{
  if (!omitbottom || forcebottom) {
    copy(&qq,"text/bottom",flagcd);
    if (flagcd) {
      if (flagcd == 'B') {
	encodeB("",0,&line,2);	/* flush */
	qmail_put(&qq,line.s,line.len);
      }
      hdr_boundary(0);
      hdr_ctype(CTYPE_MESSAGE);
      hdr_adds("Content-Disposition: inline; filename=request.msg");
      qmail_puts(&qq,"\n");
    }
    qmail_puts(&qq,"Return-Path: <");
    quote2(&quoted,sender);
    qmail_put(&qq,quoted.s,quoted.len);
    qmail_puts(&qq,">\n");
    if (seek_begin(0) == -1)
      strerr_die2sys(111,FATAL,MSG(ERR_SEEK_INPUT));
    if (qmail_copy(&qq,&ssin2,copylines) != 0)
      strerr_die2sys(111,FATAL,MSG(ERR_READ_INPUT));
    if (flagcd)
      hdr_boundary(1);
  } else {
    if (flagcd == 'B') {
      encodeB("",0,&line,2);	/* flush even if no bottom */
      qmail_put(&qq,line.s,line.len);
    }
  }

  qmail_from(&qq,from.s);
}
예제 #3
0
파일: ezmlm-get.c 프로젝트: abh/ezmlm-idx
void tosender(void)
{
  qmail_puts(&qq,"To: ");
  if (!quote2(&quoted,sender)) die_nomem();
  qmail_put(&qq,quoted.s,quoted.len);
  qmail_puts(&qq,"\n");
}
예제 #4
0
subroutine select(in mode) {

	USER1 = mode.field(FM, 2, 9999);

	//force all
	//data<2>=0

	var cmd = "SELECT CHANGELOG";
	var andword = "";
	if (USER1.a(1)) {
		cmd ^= " WITH KEYWORD " ^ quote2(USER1.a(1));
		andword = " AND";
	}
	if (USER1.a(2)) {
		cmd ^= andword ^ " WITH DATE GE " ^ (DQ ^ ((USER1.a(2)).oconv("[DATE,4*]") ^ DQ));
		andword = " AND";
	}
	if (USERNAME ne "NEOSYS") {
		cmd ^= andword ^ " WITH DISTRIBUTION \"\"";
		andword = " AND";
		//if security('DOCUMENTATION ACCESS USER') then
		cmd ^= " \"User\"";
		// end
	}
	//call safeselect(cmd ^ " (S)");
	var().select(cmd ^ " (S)");

}
예제 #5
0
void doconfirm(const char *act)
/* This should only be called with valid act for sub/unsub confirms. If act */
/* is not ACTION_[RST]C, it is assumed to be an unsubscribe conf.*/
/* "act" is the first letter of desired confirm request only as STRING! */
{
  strnum[fmt_ulong(strnum,when)] = 0;
  cookie(hash,key.s,key.len-flagdig,strnum,target.s,act);
  stralloc_copy(&confirm,&outlocal);
  stralloc_append(&confirm,'-');
  stralloc_catb(&confirm,act,1);
  stralloc_cats(&confirm,"c.");
  stralloc_cats(&confirm,strnum);
  stralloc_append(&confirm,'.');
  stralloc_catb(&confirm,hash,COOKIE);
  stralloc_append(&confirm,'-');
  stralloc_cats(&confirm,verptarget.s);
  stralloc_append(&confirm,'@');
  stralloc_cat(&confirm,&outhost);
  stralloc_0(&confirm);
  set_cpconfirm(confirm.s,outlocal.len);		/* for copy */
  set_cpaction(act);
  set_cphash(hash);
  set_cpwhen(when);

  qmail_puts(&qq,"Reply-To: ");
  quote2(&quoted,confirm.s);
  qmail_put(&qq,quoted.s,quoted.len);
  qmail_puts(&qq,"\n");

  hdr_subject((*act == ACTION_SC[0]) ? MSG(SUB_USR_SUBSCRIBE)
	      : (*act == ACTION_UC[0]) ? MSG(SUB_USR_UNSUBSCRIBE)
	      : (*act == ACTION_TC[0] || *act == ACTION_RC[0])
	      ? MSG(SUB_MOD_SUBSCRIBE)
	      : MSG(SUB_MOD_UNSUBSCRIBE));
  hdr_ctboundary();
    copy(&qq,"text/top",flagcd);
}
예제 #6
0
void Strategy::HandleRHTrading( const ou::tf::Quote& quote ) {

  // add trades to chart
  // add based upon confirmed price

  if ( quote.IsValid() ) {

    m_dtQuote = quote.DateTime();

    double mid = quote.Midpoint();

    m_pOrdersOutstandingLongs->HandleQuote( quote );
    m_pOrdersOutstandingShorts->HandleQuote( quote );

    unsigned int cntLongs = m_pOrdersOutstandingLongs->GetCountOfOutstandingMatches();
    m_ceCountLongs.Append( m_dtQuote, cntLongs );
    unsigned int cntShorts = m_pOrdersOutstandingShorts->GetCountOfOutstandingMatches();
    m_ceCountShorts.Append( m_dtQuote, cntShorts );
    unsigned int dif = ( cntLongs > cntShorts ) ? cntLongs - cntShorts : cntShorts - cntLongs;

//    m_ceOutstandingExitsLong.Add( dt, cntLongs + m_pOrdersOutstandingLongs->GetCountOfOutstandingEntries() );
//    m_ceOutstandingExitsShort.Add( dt, cntShorts + m_pOrdersOutstandingShorts->GetCountOfOutstandingEntries() );

    infoBollinger& info( m_vInfoBollinger[ 0 ] );

    // since slope is delayed, check that data confirms slope before initiating actual trade
    // also, width of bollinger can limit when trades occur
    // track maximum, minimum, average width?

    ETradingState eTradingState( eTSUnknown );
    if ( 0.0 < info.m_statsSlope.Slope() ) {
      if ( mid > info.m_ema.Ago( 0 ).Value() ) {
        eTradingState = eTSSlopeRisingAboveMean;
      }
      else {
        if ( mid < info.m_ema.Ago( 0 ).Value() ) {
          eTradingState = eTSSlopeRisingBelowMean;
        }
      }
    }
    else {
      if ( 0.0 > info.m_statsSlope.Slope() ) {
        if ( mid < info.m_ema.Ago( 0 ).Value() ) {
          eTradingState = eTSSlopeFallingBelowMean;
        }
        else {
          if ( mid > info.m_ema.Ago( 0 ).Value() ) {
            eTradingState = eTSSlopeFallingAboveMean;
          }
        }
      }
    }

    if ( m_eTradingState != eTradingState ) {
      //std::cout << "Trading state " << eTradingState << std::endl;
      m_vTradeStateHistory.push_back( TradeStateHistory( eTradingState, quote ) );
      //m_eTradingState = eTradingState;

      size_t ix( m_vTradeStateHistory.size() );
      if ( 3 <= ix ) {
        TradeStateHistorySummary& 
          ths( m_mxTradeStateHistorySummary
                  [ m_vTradeStateHistory[ ix - 3 ].eTradingState ]
                  [ m_vTradeStateHistory[ ix - 2 ].eTradingState ]
                  [ m_vTradeStateHistory[ ix - 1 ].eTradingState ]
          );
        ou::tf::Quote& quote1( m_vTradeStateHistory[ ix - 2 ].quote );
        ou::tf::Quote& quote2( m_vTradeStateHistory[ ix - 1 ].quote );
        if ( quote2.Bid() > quote1.Ask() ) { // profitable long
          ++ths.nLongs;
          ths.dblTotalLongs += quote2.Bid() - quote1.Ask();
        }
        if ( quote1.Ask() > quote2.Bid() ) { // profitable short
          ++ths.nShorts;
          ths.dblTotalShorts += quote1.Ask() - quote2.Bid();
        }
        ths.dblSpread = quote.Spread();
        ths.dblBollingerWidth = info.m_stats.BBUpper() - info.m_stats.BBLower();
      }
    }

    // todo:
    // C:\Data\Resources\Books\Moving_Averages Kennedy
    // style 1: moving average compression - search for it, then use it set up option 
    // style 2: sma1 > sma2 > sma3 > sma4
    // 

    if ( m_bTrade ) {
      /*
      // scalping based upon acceleration crossing
      double dblNormalizedPrice;
      ou::tf::Order::pOrder_t pOrder;
      ou::tf::Instrument::pInstrument_t pInstrument;
      switch ( info.m_stateAccel.State() ) {
      case ou::tf::Crossing<double>::EGTX: 
        m_pOrdersOutstandingLongs->CancelAllButNEntryOrders( 2 );
        pInstrument = m_pPositionLongs->GetInstrument();
        dblNormalizedPrice = pInstrument->NormalizeOrderPrice( quote.Midpoint() );  // -0.10? +0.10?
        pOrder = m_pPositionLongs->ConstructOrder( ou::tf::OrderType::Limit, ou::tf::OrderSide::Buy, 1, dblNormalizedPrice );
        pOrder->OnOrderFilled.Add( MakeDelegate( this, &Strategy::HandleOrderFilled ) );
        pOrder->SetDescription( "Info[0].Long" );
        m_pOrdersOutstandingLongs->AddOrderFilling( 
          new ou::tf::OrdersOutstanding::structRoundTrip( 
            pOrder, 
            dblNormalizedPrice + info.m_dblBollingerWidth, // profit point, but let it accumulate with trailing stop
            dblNormalizedPrice - 0.5 * info.m_dblBollingerWidth )  // stop  ... between the two, trail while in progress, parabolic while not in progress
          );
        m_pPositionLongs->PlaceOrder( pOrder );
        //++m_nUpTransitions;
        break;
      case ou::tf::Crossing<double>::ELTX: 
        m_pOrdersOutstandingShorts->CancelAllButNEntryOrders( 2 );
        pInstrument = m_pPositionShorts->GetInstrument();
        dblNormalizedPrice = pInstrument->NormalizeOrderPrice( quote.Midpoint() );  // -0.10? +0.10?
        pOrder = m_pPositionShorts->ConstructOrder( ou::tf::OrderType::Limit, ou::tf::OrderSide::Sell, 1, dblNormalizedPrice );
        pOrder->OnOrderFilled.Add( MakeDelegate( this, &Strategy::HandleOrderFilled ) );
        pOrder->SetDescription( "Info[0].Short" );
        m_pOrdersOutstandingShorts->AddOrderFilling( 
          new ou::tf::OrdersOutstanding::structRoundTrip( 
            pOrder, 
            dblNormalizedPrice - info.m_dblBollingerWidth, // profit point, but let it accumulate with trailing stop
            dblNormalizedPrice + 0.5 * info.m_dblBollingerWidth )  // stop  ... between the two, trail while in progress, parabolic while not in progress
          );
        m_pPositionShorts->PlaceOrder( pOrder );
        //++m_nDnTransitions;
        break;
      }
      */

      // strong rising indicator
      bool bRising = 
           ( m_vInfoBollinger[0].m_statsSlope.MeanY() > m_vInfoBollinger[1].m_statsSlope.MeanY() ) // various slopes are greater than the next longer term
        && ( m_vInfoBollinger[1].m_statsSlope.MeanY() > m_vInfoBollinger[2].m_statsSlope.MeanY() )
        && ( m_vInfoBollinger[2].m_statsSlope.MeanY() > m_vInfoBollinger[3].m_statsSlope.MeanY() )
        && ( 0 < m_vInfoBollinger[3].m_statsSlope.MeanY() )
        ;
    
      bool bFalling = 
           ( m_vInfoBollinger[0].m_statsSlope.MeanY() < m_vInfoBollinger[1].m_statsSlope.MeanY() ) // various slopes are greater than the next longer term
        && ( m_vInfoBollinger[1].m_statsSlope.MeanY() < m_vInfoBollinger[2].m_statsSlope.MeanY() )
        && ( m_vInfoBollinger[2].m_statsSlope.MeanY() < m_vInfoBollinger[3].m_statsSlope.MeanY() )
        && ( 0 > m_vInfoBollinger[3].m_statsSlope.MeanY() )
        ;

      switch ( m_eInd1 ) {
      case eInd1WaitForEntry:
        if ( bRising ) {
          m_pOrderTrending = m_pPositionLongs->ConstructOrder( ou::tf::OrderType::Market, ou::tf::OrderSide::Buy, 1 );
          m_pOrderTrending->OnOrderFilled.Add( MakeDelegate( this, &Strategy::HandleOrderFilled ) );
          m_pOrderTrending->SetDescription( "Ind1 Long" );
          m_pPositionLongs->PlaceOrder( m_pOrderTrending );
          m_eInd1 = eInd1InRising;
        }
        else {
          if ( bFalling ) {
            m_pOrderTrending = m_pPositionShorts->ConstructOrder( ou::tf::OrderType::Market, ou::tf::OrderSide::Sell, 1 );
            m_pOrderTrending->OnOrderFilled.Add( MakeDelegate( this, &Strategy::HandleOrderFilled ) );
            m_pOrderTrending->SetDescription( "Ind1 Short" );
            m_pPositionShorts->PlaceOrder( m_pOrderTrending );
            m_eInd1 = eInd1InFalling;
          }
        }
        break;
      case eInd1InRising:
        if ( !bRising ) {
          m_dblStop = ( mid - m_pOrderTrending->GetAverageFillPrice() ) / 2.0;
          m_eInd1 = eInd1FollowLongStop;
        }
        break;
      case eInd1InFalling:
        if ( !bFalling ) {
          m_dblStop = ( m_pOrderTrending->GetAverageFillPrice() - mid ) / 2.0;
          m_eInd1 = eINd1FollowShortStop;
        }
        break;
      case eInd1FollowLongStop:
        if ( bRising ) {
          m_eInd1 = eInd1InRising;
        }
        else {
          if ( mid < m_dblStop ) {
            m_pOrderTrending = m_pPositionLongs->ConstructOrder( ou::tf::OrderType::Market, ou::tf::OrderSide::Sell, 1 );
            m_pOrderTrending->OnOrderFilled.Add( MakeDelegate( this, &Strategy::HandleOrderFilled ) );
            m_pOrderTrending->SetDescription( "Ind1 Long Exit" );
            m_pPositionLongs->PlaceOrder( m_pOrderTrending );
            m_eInd1 = eInd1WaitForEntry;
          }
        }
        break;
      case eINd1FollowShortStop:
        if ( bFalling ) {
          m_eInd1 = eInd1InFalling;
        }
        else {
          if ( mid > m_dblStop ) {
            m_pOrderTrending = m_pPositionShorts->ConstructOrder( ou::tf::OrderType::Market, ou::tf::OrderSide::Buy, 1 );
            m_pOrderTrending->OnOrderFilled.Add( MakeDelegate( this, &Strategy::HandleOrderFilled ) );
            m_pOrderTrending->SetDescription( "Ind1 Short Exit" );
            m_pPositionShorts->PlaceOrder( m_pOrderTrending );
            m_eInd1 = eInd1InFalling;
          }
        }
        break;
      }

      double dblUnrealized;
      double dblRealized;
      double dblCommission;
      double dblTotal;
//      m_pPortfolio->QueryStats( dblUnrealized, dblRealized, dblCommission, dblTotal );
//      m_cePL.Append( m_dtQuote, dblTotal );

    }

    m_eTradingState = eTradingState;
/*
    if ( m_bTrade ) {
      switch ( m_eTradingState ) {
      case eTSUnknown:
        break;
      case eTSSlopeRisingAboveMean:
        switch ( eTradingState ) {
        case eTSSlopeRisingBelowMean:
          TakeLongProfits();
          GoShort();
          break;
        }
        break;
      case eTSSlopeRisingBelowMean:
        break;
      case eTSSlopeFallingAboveMean:
        break;
      case eTSSlopeFallingBelowMean:
        switch ( eTradingState ) {
        case eTSSlopeFallingAboveMean:
          TakeShortProfits();
          GoLong();
          break;
        }
        break;
      }
*/
/*
    switch ( m_eBollinger1EmaSlope ) {
    case eSlopeUnknown:
      if ( 0.0 < info.m_statsSlope.Slope() ) {
        std::cout << dt << "Starting with a long" << std::endl;
        GoLong();
        m_eBollinger1EmaSlope = eSlopePos;
      }
      else {
        if ( 0.0 > info.m_statsSlope.Slope() ) {
          std::cout << dt << "Starting with a short" << std::endl;
          GoShort();
          m_eBollinger1EmaSlope = eSlopeNeg;
        }
      }
      break;
    case eSlopeNeg:
      if ( 0.0 < info.m_statsSlope.Slope() ) {
        std::cout << dt << "Reversing Short to Long" << std::endl;
        m_pPosition->ClosePosition();
        GoLong();
        m_eBollinger1EmaSlope = eSlopePos;
      }
      break;
    case eSlopePos:
      if ( 0.0 > info.m_statsSlope.Slope() ) {
        std::cout << dt << "Reversing Long to Short" << std::endl;
        m_pPosition->ClosePosition();
        GoShort();
        m_eBollinger1EmaSlope = eSlopeNeg;
      }
      
      break;
    }
    */

  }
}
예제 #7
0
static void do_edit(const char *action)
{
  unsigned int i;
  unsigned int len;
  char ch;

  /* only remote admins and only if -e is specified may edit */
  if (!flagedit || remote.s == 0)
    strerr_die2x(100,FATAL,MSG(ERR_NOT_AVAILABLE));
  if (!ismod)
    strerr_die2x(100,FATAL,MSG(ERR_NOT_ALLOWED));
  len = str_len(ACTION_EDIT);
  if (!case_starts(action,ACTION_EDIT))
    len = str_len(ALT_EDIT);
  if (action[len]) {			/* -edit.file, not just -edit */
    if (action[len] != '.')
      strerr_die2x(100,FATAL,MSG(ERR_BAD_REQUEST));
    showsend2("edit ",action+len+1);
    stralloc_copys(&fnedit,"text/");
    stralloc_cats(&fnedit,action+len+1);
    stralloc_0(&fnedit);
    case_lowerb(fnedit.s,fnedit.len);
    i = 5;	/* after the "text/" */
    while ((ch = fnedit.s[i++])) {
      if (((ch > 'z') || (ch < 'a')) && (ch != '_'))
	strerr_die2x(100,FATAL,MSG(ERR_BAD_NAME));
      if (ch == '_') fnedit.s[i-1] = '-';
    }
    switch(slurp(fnedit.s,&text,1024)) {	/* entire file! */
    case -1:
      strerr_die2sys(111,FATAL,MSG1(ERR_READ,fnedit.s));
    case 0:
      strerr_die5x(100,FATAL,dir,"/",fnedit.s,MSG(ERR_NOEXIST));
    }
    stralloc_copy(&line,&text);

    subst_nuls(&line);

    stralloc_cat(&line,&fnedit);	/* including '\0' */
    strnum[fmt_ulong(strnum,(unsigned long) when)] = 0;
    cookie(hash,key.s,key.len,strnum,line.s,"-e");
    stralloc_copy(&confirm,&outlocal);
    stralloc_append(&confirm,'-');
    stralloc_catb(&confirm,ACTION_ED,LENGTH_ED);
    stralloc_cats(&confirm,strnum);
    stralloc_append(&confirm,'.');
		/* action part has been checked for bad chars */
    stralloc_cats(&confirm,action + len + 1);
    stralloc_append(&confirm,'.');
    stralloc_catb(&confirm,hash,COOKIE);
    stralloc_append(&confirm,'@');
    stralloc_cat(&confirm,&outhost);
    stralloc_0(&confirm);
    set_cpconfirm(confirm.s,outlocal.len);
    set_cpaction(ACTION_ED);
    set_cphash(hash);
    set_cpwhen(when);

    qmail_puts(&qq,"Reply-To: ");
    quote2(&quoted,confirm.s);
    qmail_put(&qq,quoted.s,quoted.len);
    qmail_puts(&qq,"\n");

    hdr_subject(MSG1(SUB_EDIT_REQUEST,action+len+1));
    hdr_ctboundary();
    copy(&qq,"text/top",flagcd);
    copy(&qq,"text/edit-do",flagcd);
    (void) code_qputs(MSG(TXT_EDIT_START));
    (void) code_qput(text.s,text.len);
    (void) code_qputs(MSG(TXT_EDIT_END));

  } else {	/* -edit only, so output list of editable files */
    hdr_subject(MSG(SUB_EDIT_LIST));
    hdr_ctboundary();
    copy(&qq,"text/top",flagcd);
    copy_act("text/edit-list");
  }
  qmail_puts(&qq,"\n\n");
  copybottom(0);
  qmail_to(&qq,mod.s);
}
예제 #8
0
void msg_headers(int act)
/* Writes all the headers up to but not including subject */
{
  int flaggoodfield;
  int flaggetfrom;
  unsigned int pos;

  hdr_add2s("Mailing-List: ",MSG(TXT_MAILING_LIST));
  if (listid.len > 0)
    hdr_add2("List-ID: ",listid.s,listid.len);
  quote(&quoted,&outlocal);	/* quoted has outlocal */
  qmail_puts(&qq,"List-Help: <mailto:");	/* General rfc2369 headers */
  qmail_put(&qq,quoted.s,quoted.len);
  qmail_puts(&qq,"-help@");
  qmail_put(&qq,outhost.s,outhost.len);
  qmail_puts(&qq,">\nList-Post: <mailto:");
  qmail_put(&qq,quoted.s,quoted.len);
  qmail_puts(&qq,"@");
  qmail_put(&qq,outhost.s,outhost.len);
  qmail_puts(&qq,">\nList-Subscribe: <mailto:");
  qmail_put(&qq,quoted.s,quoted.len);
  qmail_puts(&qq,"-subscribe@");
  qmail_put(&qq,outhost.s,outhost.len);
  qmail_puts(&qq,">\n");
  hdr_datemsgid(when);
  /* differnt "From:" for help to break auto-responder loops */
  hdr_from((act == AC_HELP) ? "-return-" : "-help");
  quote2(&quoted,target.s);
  hdr_add2("To: ",quoted.s,quoted.len);
  stralloc_copys(&mydtline,"Delivered-To: responder for ");
  stralloc_catb(&mydtline,outlocal.s,outlocal.len);
  stralloc_cats(&mydtline,"@");
  stralloc_catb(&mydtline,outhost.s,outhost.len);
  stralloc_cats(&mydtline,"\n");
  qmail_put(&qq,mydtline.s,mydtline.len);

  flaggoodfield = 0;
	/* do it for -sc, but if the -S flag is used, do it for -subscribe */
  flaggetfrom = flagstorefrom &&
	 ((act == AC_SC) || ((act == AC_SUBSCRIBE) && !flagsubconf));
  for (;;) {
    if (gethdrln(&ssin,&line,&match,'\n') == -1)
      strerr_die2sys(111,FATAL,MSG(ERR_READ_INPUT));
    if (!match) break;
    if (line.len == 1) break;
      flaggoodfield = 0;
      if (case_startb(line.s,line.len,"mailing-list:"))
        strerr_die2x(100,FATAL,MSG(ERR_MAILING_LIST));
      if (line.len == mydtline.len)
	if (byte_equal(line.s,line.len,mydtline.s))
          strerr_die2x(100,FATAL,MSG(ERR_LOOPING));
      if (case_startb(line.s,line.len,"delivered-to:"))
        flaggoodfield = 1;
      else if (case_startb(line.s,line.len,"received:"))
        flaggoodfield = 1;
      else if (case_startb(line.s,line.len,"content-transfer-encoding:")) {
        pos = 26;
        while (line.s[pos] == ' ' || line.s[pos] == '\t') ++pos;
        if (case_startb(line.s+pos,line.len-pos,"base64"))
          encin = 'B';
        else if (case_startb(line.s+pos,line.len-pos,"quoted-printable"))
          encin = 'Q';
      } else if (flaggetfrom && case_startb(line.s,line.len,"from:")) {
	/* for logging subscriber data */
	concatHDR(line.s+5,line.len-5,&fromline);
      }
    if (flaggoodfield)
      qmail_put(&qq,line.s,line.len);
  }
  hdr_mime(flagcd ? CTYPE_MULTIPART : CTYPE_TEXT);
}
예제 #9
0
void doit(int flagw)
{
  unsigned int i;
  int fd;
  int match;
  int fdhash;
  const char *err;

  fd = open_read(fn.s);
  if (fd == -1) die_read();
  substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf));

  if (getln(&ssin,&addr,&match,'\0') == -1) die_read();
  if (!match) { close(fd); return; }
  if (!issub(workdir,0,addr.s)) { close(fd); /*XXX*/unlink(fn.s); return; }
  cookie(hash,"",0,"",addr.s,"");
  if (!stralloc_copys(&fnhash,workdir)) die_nomem();
  if (!stralloc_cats(&fnhash,"/bounce/h/")) die_nomem();
  if (!stralloc_catb(&fnhash,hash,1)) die_nomem();
  if (!stralloc_cats(&fnhash,"/h")) die_nomem();
  if (!stralloc_catb(&fnhash,hash+1,COOKIE-1)) die_nomem();
  if (!stralloc_0(&fnhash)) die_nomem();

  if (qmail_open(&qq, (stralloc *) 0) == -1)
    strerr_die2sys(111,FATAL,ERR_QMAIL_QUEUE);

  hdr_add2("Mailing-List: ",mailinglist.s,mailinglist.len);
  if (listid.len > 0)
    hdr_add2("\nList-ID: ",listid.s,listid.len);
  hdr_datemsgid(now());
  if (flagcd) {
    if (!stralloc_0(&line)) die_nomem();
  }
  hdr_from("-help");
  if (!quote2(&quoted,addr.s)) die_nomem();
  hdr_add2("To: ",quoted.s,quoted.len);
  /* to accomodate transfer-encoding */
  hdr_mime(flagcd ? CTYPE_MULTIPART : CTYPE_TEXT);
  hdr_listsubject1(flagw ? "probe from " : "warning from ");

  if (flagcd) {			/* first part for QP/base64 multipart msg */
    hdr_boundary(0);
    hdr_ctype(CTYPE_TEXT);
    hdr_transferenc();
  } else
    qmail_puts(&qq,"\n");

  copy(&qq,"text/top",flagcd);
  copy(&qq,flagw ? "text/bounce-probe" : "text/bounce-warn",flagcd);

  if (!flagw) {
    if (flagdig)
      copy(&qq,"text/dig-bounce-num",flagcd);
    else
      copy(&qq,"text/bounce-num",flagcd);
    if (!flagcd) {
      fdhash = open_read(fnhash.s);
      if (fdhash == -1) {
        if (errno != error_noent)
          strerr_die4sys(111,FATAL,ERR_OPEN,fnhash.s,": ");
      } else {
        substdio_fdbuf(&sstext,read,fdhash,textbuf,sizeof(textbuf));
        for(;;) {
          if (getln(&sstext,&line,&match,'\n') == -1)
            strerr_die4sys(111,FATAL,ERR_READ,fnhash.s,": ");
          if (!match) break;
          code_qput(line.s,line.len);
        }
      }
      close(fdhash);
    } else {
      if (!stralloc_copys(&line,"")) die_nomem();	/* slurp adds! */
      if (slurp(fnhash.s,&line,256) < 0)
        strerr_die4sys(111,FATAL,ERR_OPEN,fnhash.s,": ");
      code_qput(line.s,line.len);
    }
  }

  copy(&qq,"text/bounce-bottom",flagcd);
  if (flagcd) {
    if (flagcd == 'B') {
      encodeB("",0,&line,2);
      qmail_put(&qq,line.s,line.len);	/* flush */
    }
    hdr_boundary(0);
    hdr_ctype(CTYPE_MESSAGE);
    qmail_puts(&qq,"\n");
  }
  if (qmail_copy(&qq,&ssin,copylines) < 0) die_read();
  close(fd);

  if (flagcd)				/* end multipart/mixed */
    hdr_boundary(1);

  strnum[fmt_ulong(strnum,when)] = 0;
  cookie(hash,key.s,key.len,strnum,addr.s,flagw ? "P" : "W");
  if (!stralloc_copy(&line,&outlocal)) die_nomem();
  if (!stralloc_cats(&line,flagw ? "-return-probe-" : "-return-warn-"))
	die_nomem();
  if (!stralloc_cats(&line,strnum)) die_nomem();
  if (!stralloc_cats(&line,".")) die_nomem();
  if (!stralloc_catb(&line,hash,COOKIE)) die_nomem();
  if (!stralloc_cats(&line,"-")) die_nomem();
  i = str_chr(addr.s,'@');
  if (!stralloc_catb(&line,addr.s,i)) die_nomem();
  if (addr.s[i]) {
    if (!stralloc_cats(&line,"=")) die_nomem();
    if (!stralloc_cats(&line,addr.s + i + 1)) die_nomem();
  }
  if (!stralloc_cats(&line,"@")) die_nomem();
  if (!stralloc_cat(&line,&outhost)) die_nomem();
  if (!stralloc_0(&line)) die_nomem();
  qmail_from(&qq,line.s);

  qmail_to(&qq,addr.s);
  if (*(err = qmail_close(&qq)) != '\0')
    strerr_die3x(111,FATAL,ERR_TMP_QMAIL_QUEUE, err + 1);

  strnum[fmt_ulong(strnum,qmail_qp(&qq))] = 0;
  strerr_warn2("ezmlm-warn: info: qp ",strnum,0);

  if (!flagw) {
    if (unlink(fnhash.s) == -1)
      if (errno != error_noent)
        strerr_die4sys(111,FATAL,ERR_DELETE,fnhash.s,": ");
  }
  if (unlink(fn.s) == -1)
    strerr_die4sys(111,FATAL,ERR_DELETE,fn.s,": ");
}