Fossil

Check-in [8643602d]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add features to make it easier to test and debug the "fossil smtp" command from the command-line using stdin and stdout.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | smtp
Files: files | file ages | folders
SHA3-256:8643602dae8556738c9fb5ec2b47fcb568f084c04d9719dd43d6f21c3cde93a0
User & Date: drh 2018-06-29 03:29:06
Context
2018-06-29
15:30
Merge recent trunk enhancements and fixes into the smtp branch. check-in: 45939f51 user: drh tags: smtp
03:29
Add features to make it easier to test and debug the "fossil smtp" command from the command-line using stdin and stdout. check-in: 8643602d user: drh tags: smtp
03:12
Baseline implementation of the "smtp" command. check-in: be55fc60 user: drh tags: smtp
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/smtp.c.

611
612
613
614
615
616
617

618
619
620
621
622
623
624
...
666
667
668
669
670
671
672



673
674
675
676
677
678
679
680
681
682

683
684




685
686
687
688
689
690
691
692
693

694
695

696
697
698
699
700








701
702
703
704
705
706
707
...
715
716
717
718
719
720
721

722
723
724
725
726
727
728
729
730
731
732
733
734
  Blob msg;              /* Content following DATA */
  Blob transcript;       /* Session transcript */
};

#define SMTPSRV_CLEAR_MSG    1   /* smtp_server_clear() last message only */
#define SMTPSRV_CLEAR_ALL    2   /* smtp_server_clear() everything */
#define SMTPSRV_LOG       0x001  /* Record a transcript of the interaction */


#endif /* LOCAL_INTERFACE */

/*
** Clear the SmtpServer object.  Deallocate resources.
** How much to clear depends on eHowMuch 
*/
................................................................................
  n = blob_size(&b);
  assert( n>=2 );
  assert( z[n-1]=='\n' );
  assert( z[n-2]=='\r' );
  if( p->srvrFlags & SMTPSRV_LOG ){
    blob_appendf(&p->transcript, "S: %.*s\n", n-2, z);
  }



  fwrite(z, n, 1, stdout);
  fflush(stdout);
  blob_zero(&b);
}

/*
** Read a single line from the client.
*/
static int smtp_server_gets(SmtpServer *p, char *aBuf, int nBuf){
  int rc = fgets(aBuf, nBuf, stdin)!=0;

  if( rc && (p->srvrFlags & SMTPSRV_LOG)!=0 ){
    blob_appendf(&p->transcript, "C: %s\n", aBuf);




  }
  return rc;
}

/*
** Capture the incoming email data into the p->msg blob.  Dequote
** lines of "..\r\n" into just ".\r\n".
*/
static void smtp_server_capture_data(SmtpServer *p, char *z, int n){

  while( fgets(z, n, stdin) ){
    if( strncmp(z, ".\r\n", 3)==0 ) return;

    if( strncmp(z, "..\r\n", 4)==0 ){
      memmove(z, z+1, 4);
    }
    blob_append(&p->msg, z, -1);
  }








}

/*
** COMMAND: smtp
**
** Usage: %fossil smtp [options] DBNAME
**
................................................................................
  const char *zDomain;
  SmtpServer x;
  char z[5000];

  smtp_server_init(&x);
  zDomain = find_option("domain",0,1);
  if( zDomain==0 ) zDomain = "unspecified.domain";

  verify_all_options();
  if( g.argc!=3 ) usage("DBNAME");
  zDbName = g.argv[2];
  zDbName = enter_chroot_jail(zDbName, 0);
  smtp_server_send(&x, "220 %s ESMTP Fossil ([%.*s] %s)\r\n",
                   zDomain, 16, MANIFEST_VERSION, MANIFEST_DATE);
  while( smtp_server_gets(&x, z, sizeof(z)) ){
    if( strncmp(z, "EHLO ", 5)==0 ){
      smtp_server_send(&x, "250 ok\r\n");
    }else
    if( strncmp(z, "HELO ", 5)==0 ){
      smtp_server_send(&x, "250 ok\r\n");
    }else







>







 







>
>
>










>
|
|
>
>
>
>









>

|
>
|




>
>
>
>
>
>
>
>







 







>




|
|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
...
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
...
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
  Blob msg;              /* Content following DATA */
  Blob transcript;       /* Session transcript */
};

#define SMTPSRV_CLEAR_MSG    1   /* smtp_server_clear() last message only */
#define SMTPSRV_CLEAR_ALL    2   /* smtp_server_clear() everything */
#define SMTPSRV_LOG       0x001  /* Record a transcript of the interaction */
#define SMTPSRV_STDERR    0x002  /* Transcription written to stderr */

#endif /* LOCAL_INTERFACE */

/*
** Clear the SmtpServer object.  Deallocate resources.
** How much to clear depends on eHowMuch 
*/
................................................................................
  n = blob_size(&b);
  assert( n>=2 );
  assert( z[n-1]=='\n' );
  assert( z[n-2]=='\r' );
  if( p->srvrFlags & SMTPSRV_LOG ){
    blob_appendf(&p->transcript, "S: %.*s\n", n-2, z);
  }
  if( p->srvrFlags & SMTPSRV_STDERR ){
    fprintf(stderr, "S: %.*s\n", n-2, z);
  }
  fwrite(z, n, 1, stdout);
  fflush(stdout);
  blob_zero(&b);
}

/*
** Read a single line from the client.
*/
static int smtp_server_gets(SmtpServer *p, char *aBuf, int nBuf){
  int rc = fgets(aBuf, nBuf, stdin)!=0;
  if( rc ){
    if( (p->srvrFlags & SMTPSRV_LOG)!=0 ){
      blob_appendf(&p->transcript, "C: %s", aBuf);
    }
    if( (p->srvrFlags & SMTPSRV_STDERR)!=0 ){
      fprintf(stderr, "C: %s", aBuf);
    }
  }
  return rc;
}

/*
** Capture the incoming email data into the p->msg blob.  Dequote
** lines of "..\r\n" into just ".\r\n".
*/
static void smtp_server_capture_data(SmtpServer *p, char *z, int n){
  int nLine = 0;
  while( fgets(z, n, stdin) ){
    if( strncmp(z, ".\r\n", 3)==0 || strncmp(z, ".\n",2)==0 ) break;
    nLine++;
    if( strncmp(z, "..\r\n", 4)==0 || strncmp(z, "..\n",3)==0 ){
      memmove(z, z+1, 4);
    }
    blob_append(&p->msg, z, -1);
  }
  if( p->srvrFlags & SMTPSRV_LOG ){
    blob_appendf(&p->transcript, "C: # %d lines, %d bytes of content\n",
          nLine, blob_size(&p->msg));
  }
  if( p->srvrFlags & SMTPSRV_STDERR ){
    fprintf(stderr, "C: # %d lines, %d bytes of content\n",
          nLine, blob_size(&p->msg));
  }
}

/*
** COMMAND: smtp
**
** Usage: %fossil smtp [options] DBNAME
**
................................................................................
  const char *zDomain;
  SmtpServer x;
  char z[5000];

  smtp_server_init(&x);
  zDomain = find_option("domain",0,1);
  if( zDomain==0 ) zDomain = "unspecified.domain";
  if( find_option("trace",0,0)!=0 ) x.srvrFlags |= SMTPSRV_STDERR;
  verify_all_options();
  if( g.argc!=3 ) usage("DBNAME");
  zDbName = g.argv[2];
  zDbName = enter_chroot_jail(zDbName, 0);
  smtp_server_send(&x, "220 %s ESMTP https://fossil-scm.org/ %s\r\n",
                   zDomain, MANIFEST_VERSION);
  while( smtp_server_gets(&x, z, sizeof(z)) ){
    if( strncmp(z, "EHLO ", 5)==0 ){
      smtp_server_send(&x, "250 ok\r\n");
    }else
    if( strncmp(z, "HELO ", 5)==0 ){
      smtp_server_send(&x, "250 ok\r\n");
    }else