User Tools

Site Tools


sending_20an_20email_20with_20attachments

This is an old revision of the document!


Sending an email with attachments

by Richard Russell, October 2012, corrected August 2015

See also [[/Sending%20an%20HTML%20email%20with%20optional%20attachments|Sending an HTML email with optional attachments]]


In the article Sending an email automatically the procedure PROCsendmail() automatically sends an email using the SOCKLIB library. Listed below is a procedure which performs the same function except that you can specify one or more files to attach to the email. The final parameter is a comma-separated list of the pathnames of the file(s) you wish to attach. The procedure might be called as follows:

        INSTALL @lib$+"SOCKLIB"
 
        SMTP$    = "smtp.gmail.com"
        From$    = "sender@somewhere"
        To$      = "recipient@elsewhere"
        Subject$ = "Test of sending attachments"
        ReplyTo$ = "reallyme@myaddress"
        Message$ = "This is a test of sending an email with attachments."
        Attach$ =  "C:\invoice12345.pdf, " + \
        \          """C:\Program Files\BBC BASIC for Windows\readme.txt"""
 
        PROCsendmailattach(SMTP$,From$,To$,"","",Subject$,ReplyTo$,Message$,Attach$)

The calling program should first check that the attached files actually exist, because if not PROCattach() will abort with an error and not terminate the SMTP transaction; this could leave the server 'in limbo'. Note that if an attached file path contains spaces or punctuation characters you must enclose it in quotes.

Here is PROCsendmailattach(); like PROCsendmail() it cannot be used if authentication is required so in practice that probably means that your ISP's SMTP server must be used:

        DEF PROCsendmailattach(smtp$,from$,rcpt$,cc$,bcc$,subject$,replyto$,body$,attach$)
        LOCAL D%, S%, skt%, comma%, reply$, file$
        DIM D% LOCAL 31, S% LOCAL 15
 
        SYS "GetLocalTime", S%
        SYS "GetDateFormat", 0, 0, S%, "ddd, dd MMM yyyy ", D%, 18
        SYS "GetTimeFormat", 0, 0, S%, "HH:mm:ss +0000", D%+17, 15
        D%?31 = 13
 
        PROC_initsockets
        skt% = FN_tcpconnect(smtp$,"mail")
        IF skt% <= 0 skt% = FN_tcpconnect(smtp$,"25")
        IF skt% <= 0 ERROR 100, "Failed to connect to mail server"
        IF FN_readlinesocket(skt%, 1000, reply$)
        WHILE FN_readlinesocket(skt%, 10, reply$) > 0 : ENDWHILE
 
        PROCsend(skt%,"HELO "+FN_gethostname)
        PROCmail(skt%,"MAIL FROM: ",from$)
        IF rcpt$<>"" PROClist(skt%,rcpt$)
        IF cc$<>"" PROClist(skt%,cc$)
        IF bcc$<>"" PROClist(skt%,bcc$)
        PROCsend(skt%, "DATA")
 
        IF FN_writelinesocket(skt%, "Date: "+$D%)
        IF FN_writelinesocket(skt%, "From: "+from$)
        IF FN_writelinesocket(skt%, "To: "+rcpt$)
        IF cc$<>"" IF FN_writelinesocket(skt%, "Cc: "+cc$)
        IF subject$<>"" IF FN_writelinesocket(skt%, "Subject: "+subject$)
        IF replyto$<>"" IF FN_writelinesocket(skt%, "Reply-To: "+replyto$)
        IF FN_writelinesocket(skt%, "MIME-Version: 1.0")
        IF attach$="" THEN
          IF FN_writelinesocket(skt%, "Content-Type: text/plain; charset=US-ASCII")
        ELSE
          IF FN_writelinesocket(skt%, "Content-Type: multipart/mixed; boundary=""BB4Wsep""")
          IF FN_writelinesocket(skt%, "")
          IF FN_writelinesocket(skt%, "--BB4Wsep")
          IF FN_writelinesocket(skt%, "Content-Type: text/plain")
          IF FN_writelinesocket(skt%, "Content-Transfer-Encoding: 7bit")
        ENDIF
 
        IF FN_writelinesocket(skt%, "")
        IF FN_writelinesocket(skt%, body$)
        IF attach$<>"" THEN
          REPEAT
            WHILE ASCattach$=32 attach$ = MID$(attach$,2) : ENDWHILE
            IF ASCattach$=34 THEN
              file$ = EVAL(attach$)
              comma% = INSTR(attach$, ",", LENfile$)
            ELSE
              comma% = INSTR(attach$, ",")
              IF comma% file$ = LEFT$(attach$, comma%-1) ELSE file$ = attach$
            ENDIF
            PROCattach(skt%, file$)
            attach$ = MID$(attach$, comma%+1)
          UNTIL comma%=0
          IF FN_writelinesocket(skt%, "--BB4Wsep--")
        ENDIF
        IF FN_writelinesocket(skt%, ".")
 
        PROCsend(skt%,"QUIT")
 
        PROC_exitsockets
        ENDPROC
 
        DEF PROClist(skt%,list$)
        LOCAL comma%
        REPEAT
          WHILE ASClist$=32 list$=MID$(list$,2):ENDWHILE
          comma% = INSTR(list$,",")
          IF comma% THEN
            PROCmail(skt%,"RCPT TO: ",LEFT$(list$,comma%-1))
            list$ = MID$(list$,comma%+1)
          ELSE
            PROCmail(skt%,"RCPT TO: ",list$)
          ENDIF
        UNTIL comma% = 0
        ENDPROC
 
        DEF PROCmail(skt%,cmd$,mail$)
        LOCAL I%,J%
        I% = INSTR(mail$,"<")
        J% = INSTR(mail$,">",I%)
        IF I% IF J% THEN
          PROCsend(skt%, cmd$+MID$(mail$,I%,J%-I%+1))
        ELSE
          PROCsend(skt%, cmd$+"<"+mail$+">")
        ENDIF
        ENDPROC
 
        DEF PROCsend(skt%,cmd$)
        LOCAL reply$
        IF FN_writelinesocket(skt%,cmd$) < 0 THEN
          ERROR 100, "Send failed"
        ENDIF
        IF FN_readlinesocket(skt%, 200, reply$)
        WHILE FN_readlinesocket(skt%, 10, reply$) > 0 : ENDWHILE
        ENDPROC
 
        DEF PROCattach(skt%,file$)
        LOCAL D%, F%, I%, L%, N%, A$, B$
        B$ = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
        F% = OPENIN(file$)
        IF F%=0 ERROR 100, "Failed to open attached file " + file$
        REPEAT
          D% = INSTR(file$, "\")
          IF D%=0 D% = INSTR(file$, "/")
          IF D% file$ = MID$(file$, D%+1)
        UNTIL D%=0
        IF FN_writelinesocket(skt%, "")
        IF FN_writelinesocket(skt%, "--BB4Wsep")
        IF FN_writelinesocket(skt%, "Content-Type: application/octet-stream")
        IF FN_writelinesocket(skt%, "Content-Disposition: attachment; filename="+file$)
        IF FN_writelinesocket(skt%, "Content-Transfer-Encoding: base64")
        IF FN_writelinesocket(skt%, "")
        L% = EXT#F%
        WHILE NOT EOF#F%
          N% = L% - PTR#F%
          D% = BGET#F% << 16 OR BGET#F% << 8 OR BGET#F%
          FOR I% = 1 TO 4 : A$ += MID$(B$,(D% >>> 18)+1,1) : D% = D% << 6 AND &FFFFFF : NEXT
          IF N%=1 RIGHT$(A$,2) = "==" ELSE IF N%=2 RIGHT$(A$) = "="
          IF LENA$>=72 IF FN_writelinesocket(skt%,A$)=0 A$ = ""
        ENDWHILE
        IF A$<>"" IF FN_writelinesocket(skt%, A$)
        CLOSE #F%
        ENDPROC
This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
sending_20an_20email_20with_20attachments.1523990439.txt.gz · Last modified: 2018/04/17 18:40 by tbest3112