Edit

kc3-lang/smtp/src/smtp.h

Branch :

  • Show log

    Commit

  • Author : humphreyj
    Date : 2018-08-21 04:29:41
    Hash : ee6d4b2c
    Message : Set all source files to version 1.00.

  • src/smtp.h
  • /**
     * @file
     * @brief SMTP client library.
     * @author James Humphrey (mail@somnisoft.com)
     * @version 1.00
     *
     * This SMTP client library allows the user to send emails to an SMTP server.
     * The user can include custom headers and MIME attachments.
     *
     * This software has been placed into the public domain using CC0.
     */
    #ifndef SMTP_H
    #define SMTP_H
    
    #include <sys/types.h>
    #include <stddef.h>
    #include <stdio.h>
    
    /**
     * Status codes indicating success or failure from calling any of the
     * SMTP library functions.
     *
     * This code gets returned by all functions in this header.
     */
    enum smtp_status_code{
      /**
       * Successful operation completed.
       */
      SMTP_STATUS_OK,
    
      /**
       * Memory allocation failed.
       */
      SMTP_STATUS_NOMEM,
    
      /**
       * Failed to connect to the mail server.
       */
      SMTP_STATUS_CONNECT,
    
      /**
       * Failed to handshake or negotiate a TLS connection with the server.
       */
      SMTP_STATUS_HANDSHAKE,
    
      /**
       * Failed to authenticate with the given credentials.
       */
      SMTP_STATUS_AUTH,
    
      /**
       * Failed to send bytes to the server.
       */
      SMTP_STATUS_SEND,
    
      /**
       * Failed to receive bytes from the server.
       */
      SMTP_STATUS_RECV,
    
      /**
       * Failed to properly close a connection.
       */
      SMTP_STATUS_CLOSE,
    
      /**
       * SMTP server sent back an unexpected status code.
       */
      SMTP_STATUS_SERVER_RESPONSE,
    
      /**
       * Invalid parameter.
       */
      SMTP_STATUS_PARAM,
    
      /**
       * Failed to open or read a local file.
       */
      SMTP_STATUS_FILE,
    
      /**
       * Failed to get the local date and time.
       */
      SMTP_STATUS_DATE,
    
      /**
       * Indicates the last status code in the enumeration, useful for
       * bounds checking.
       *
       * Not a valid status code.
       */
      SMTP_STATUS__LAST
    };
    
    /**
     * Address source and destination types.
     */
    enum smtp_address_type{
      /**
       * From address.
       */
      SMTP_ADDRESS_FROM,
    
      /**
       * To address.
       */
      SMTP_ADDRESS_TO,
    
      /**
       * Copy address.
       */
      SMTP_ADDRESS_CC,
    
      /**
       * Blind copy address.
       *
       * Recipients should not see any of the BCC addresses when they receive
       * their email. However, some SMTP server implementations may copy this
       * information into the mail header, so do not assume that this will
       * always get hidden. If the BCC addresses must not get shown to the
       * receivers, then send one separate email to each BCC party and add
       * the TO and CC addresses manually as a header property using
       * @ref smtp_header_add instead of as an address using
       * @ref smtp_address_add.
       */
      SMTP_ADDRESS_BCC
    };
    
    /**
     * Connect to the SMTP server using either an unencrypted socket or
     * TLS encryption.
     */
    enum smtp_connection_security{
    #ifdef SMTP_OPENSSL
      /**
       * First connect without encryption, then negotiate an encrypted connection
       * by issuing a STARTTLS command.
       */
      SMTP_SECURITY_STARTTLS,
    
      /**
       * Use TLS when initially connecting to server.
       *
       * @deprecated SMTP clients should not use this connection type unless
       *             connecting to a legacy SMTP server which requires it.
       *             Instead, use @ref SMTP_SECURITY_STARTTLS if possible.
       */
      SMTP_SECURITY_TLS,
    #endif /* SMTP_OPENSSL */
    
      /**
       * Do not use TLS encryption.
       *
       * Not recommended unless connecting to the SMTP server locally.
       */
      SMTP_SECURITY_NONE
    };
    
    /**
     * List of supported methods for authenticating a mail user account on
     * the server.
     */
    enum smtp_authentication_method{
    #ifdef SMTP_OPENSSL
      /**
       * Use HMAC-MD5.
       */
      SMTP_AUTH_CRAM_MD5,
    #endif /* SMTP_OPENSSL */
      /**
       * No authentication required.
       *
       * Some servers support this option if connecting locally.
       */
      SMTP_AUTH_NONE,
    
      /**
       * Authenticate using base64 user and password.
       */
      SMTP_AUTH_PLAIN,
    
      /**
       * Another base64 authentication method, similar to SMTP_AUTH_PLAIN.
       */
      SMTP_AUTH_LOGIN
    };
    
    /**
     * Special flags defining certain behaviors for the SMTP client context.
     */
    enum smtp_flag{
      /**
       * Print client and server communication on stderr.
       */
      SMTP_DEBUG          = 1 << 0,
    
      /**
       * Do not verify TLS certificate.
       *
       * By default, the TLS handshake function will check if a certificate
       * has expired or if using a self-signed certificate. Either of those
       * conditions will cause the connection to fail. This option allows the
       * connection to proceed even if those checks fail.
       */
      SMTP_NO_CERT_VERIFY = 1 << 1
    };
    
    struct smtp;
    
    #ifdef __cplusplus
    extern "C" {
    #endif /* __cplusplus */
    
    enum smtp_status_code
    smtp_open(const char *const server,
              const char *const port,
              enum smtp_connection_security connection_security,
              enum smtp_flag flags,
              const char *const cafile,
              struct smtp **smtp);
    
    enum smtp_status_code
    smtp_auth(struct smtp *const smtp,
              enum smtp_authentication_method auth_method,
              const char *const user,
              const char *const pass);
    
    enum smtp_status_code
    smtp_mail(struct smtp *const smtp,
              const char *const body);
    
    enum smtp_status_code
    smtp_close(struct smtp *smtp);
    
    enum smtp_status_code
    smtp_status_code_get(const struct smtp *const smtp);
    
    enum smtp_status_code
    smtp_status_code_set(struct smtp *const smtp,
                         enum smtp_status_code new_status_code);
    
    const char *
    smtp_status_code_errstr(enum smtp_status_code status_code);
    
    enum smtp_status_code
    smtp_header_add(struct smtp *const smtp,
                    const char *const key,
                    const char *const value);
    
    void smtp_header_clear_all(struct smtp *const smtp);
    
    enum smtp_status_code
    smtp_address_add(struct smtp *const smtp,
                     enum smtp_address_type type,
                     const char *const email,
                     const char *const name);
    
    void smtp_address_clear_all(struct smtp *const smtp);
    
    enum smtp_status_code
    smtp_attachment_add_path(struct smtp *const smtp,
                             const char *const name,
                             const char *const path);
    
    enum smtp_status_code
    smtp_attachment_add_fp(struct smtp *const smtp,
                           const char *const name,
                           FILE *fp);
    
    enum smtp_status_code
    smtp_attachment_add_mem(struct smtp *const smtp,
                            const char *const name,
                            const void *const data,
                            ssize_t datasz);
    
    void smtp_attachment_clear_all(struct smtp *const smtp);
    
    
    /*
     * The SMTP_INTERNAL DEFINE section contains definitions that get used
     * internally by the SMTP client library.
     */
    #ifdef SMTP_INTERNAL_DEFINE
    /**
     * SMTP codes returned by the server and parsed by the client.
     */
    enum smtp_result_code{
      /**
       * Client error code which does not get set by the server.
       */
      SMTP_INTERNAL_ERROR =  -1,
    
      /**
       * Returned when ready to begin processing next step.
       */
      SMTP_READY          = 220,
    
      /**
       * Returned in response to QUIT.
       */
      SMTP_CLOSE          = 221,
    
      /**
       * Returned if client successfully authenticates.
       */
      SMTP_AUTH_SUCCESS   = 235,
    
      /**
       * Returned when some commands successfully complete.
       */
      SMTP_DONE           = 250,
    
      /**
       * Returned for some multi-line authentication mechanisms where this code
       * indicates the next stage in the authentication step.
       */
      SMTP_AUTH_CONTINUE  = 334,
    
      /**
       * Returned in response to DATA command.
       */
      SMTP_BEGIN_MAIL     = 354
    };
    
    /**
     * Used for parsing out the responses from the SMTP server.
     *
     * For example, if the server sends back '250-STARTTLS', then code would
     * get set to 250, more would get set to 1, and text would get set to STARTTLS.
     */
    struct smtp_command{
      /**
       * Result code converted to an integer.
       */
      enum smtp_result_code code;
    
      /**
       * Indicates if more server commands follow.
       *
       * This will get set to 1 if the fourth character in the response line
       * contains a '-', otherwise this will get set to 0.
       */
      int more;
    
      /**
       * The text shown after the status code.
       */
      const char *text;
    };
    
    /**
     * Return codes for the getdelim interface which allows the caller to check
     * if more delimited lines can get processed.
     */
    enum str_getdelim_retcode{
      /**
       * An error occurred during the getdelim processing.
       */
      STRING_GETDELIMFD_ERROR = -1,
    
      /**
       * Found a new line and can process more lines in the next call.
       */
      STRING_GETDELIMFD_NEXT  =  0,
    
      /**
       * Found a new line and unable to read any more lines at this time.
       */
      STRING_GETDELIMFD_DONE  =  1
    };
    
    /**
     * Data structure for read buffer and line parsing.
     *
     * This assists with getting and parsing the server response lines.
     */
    struct str_getdelimfd{
      /**
       * Read buffer which may include bytes past the delimiter.
       */
      char *_buf;
    
      /**
       * Number of allocated bytes in the read buffer.
       */
      size_t _bufsz;
    
      /**
       * Number of actual stored bytes in the read buffer.
       */
      size_t _buf_len;
    
      /**
       * Character delimiter used for determining line separation.
       */
      int delim;
    
      /**
       * Current line containing the text up to the delimiter.
       */
      char *line;
    
      /**
       * Number of stored bytes in the line buffer.
       */
      size_t line_len;
    
      /**
       * Function pointer to a custom read function for the
       * @ref smtp_str_getdelimfd interface.
       *
       * This function prototype has similar semantics to the read function.
       * The @p gdfd parameter allows the custom function to pull the user_data
       * info from the @ref str_getdelimfd struct which can contain file pointer,
       * socket connection, etc.
       */
      ssize_t (*getdelimfd_read)(struct str_getdelimfd *const gdfd,
                                 void *buf,
                                 size_t count);
    
      /**
       * User data which gets sent to the read handler function.
       */
      void *user_data;
    };
    
    #endif /* SMTP_INTERNAL_DEFINE */
    
    #ifdef __cplusplus
    }
    #endif /* __cplusplus */
    
    #endif /* SMTP_H */