├── NOTICE
├── README.rst
├── Cmd
├── smtp-c_cmd.h
└── smtp-c_cmd.c
├── Cfg
└── Template
│ └── smtp-c_cfg.h
├── Example
└── smtp-c_send.c
├── LICENSE
└── Source
├── smtp-c.h
└── smtp-c.c
/NOTICE:
--------------------------------------------------------------------------------
1 | ATTENTION ALL USERS OF THIS REPOSITORY:
2 |
3 | The original work found in this repository is provided by Silicon Labs under the
4 | Apache License, Version 2.0.
5 |
6 | Any third party may contribute derivative works to the original work in which
7 | modifications are clearly identified as being licensed under:
8 |
9 | (1) the Apache License, Version 2.0 or a compatible open source license; or
10 | (2) under a proprietary license with a copy of such license deposited.
11 |
12 | All posted derivative works must clearly identify which license choice has been
13 | elected.
14 |
15 | No such posted derivative works will be considered to be a “Contribution” under
16 | the Apache License, Version 2.0.
17 |
18 | SILICON LABS MAKES NO WARRANTY WITH RESPECT TO ALL POSTED THIRD PARTY CONTENT
19 | AND DISCLAIMS ALL OTHER WARRANTIES OR LIABILITIES, INCLUDING ALL WARRANTIES OF
20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, OWNERSHIP,
21 | NON-INFRINGEMENT, AND NON-MISAPPROPRIATION.
22 |
23 | In the event a derivative work is desired to be submitted to Silicon Labs as a
24 | “Contribution” under the Apache License, Version 2.0, a “Contributor” must give
25 | written email notice to micrium@weston-embedded.com. Unless an email response in
26 | the affirmative to accept the derivative work as a “Contribution”, such email
27 | submission should be considered to have not been incorporated into the original
28 | work.
29 |
--------------------------------------------------------------------------------
/README.rst:
--------------------------------------------------------------------------------
1 | .. raw:: html
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | µC/OS is a full-featured embedded operating system originally developed by Micriµm™. In addition to the two highly popular kernels, µC/OS features support for TCP/IP, USB-Device, USB-Host, and Modbus, as well as a robust File System.
10 |
11 | Since its founding in 1999 as a private company, Micriµm and its team of engineers have offered world-class embedded software components for the most critical and demanding real-time applications. Recognized as having some of the cleanest code in the industry, with easy-to-understand documentation, the Micrium real-time kernels, and software components have successfully been deployed in thousands of products worldwide across a broad range of industries. Micrium’s µC/OS-II™ kernel has been certified for use in safety-critical applications and remains a respected favorite in the medical, aerospace, and industrial markets. µC/OS continues to be the RTOS of choice for engineers requiring the most reliable and trusted solution for their mission-critical applications.
12 |
13 | ----------
14 |
15 | .. raw:: HTML
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Founded by a team of former Micrium employees, Weston Embedded Solutions is the official custodian for the µC/OS RTOS and Stacks software repository to ensure it remains the trusted choice for embedded engineers around the world.
24 |
25 | ----------
26 |
27 | Product Documentation and Release Notes
28 | ***************
29 | https://micrium.atlassian.net/
30 |
31 | Technical Support
32 | *****************
33 | https://weston-embedded.com/micrium-support
34 |
35 | Example Projects
36 | *********
37 | https://weston-embedded.com/micrium-examples
38 |
39 | Commercial Licensing Option
40 | *********
41 | https://weston-embedded.com/products/cesium
42 |
43 | Who to Contact
44 | *********
45 | https://weston-embedded.com/company/contact
--------------------------------------------------------------------------------
/Cmd/smtp-c_cmd.h:
--------------------------------------------------------------------------------
1 | /*
2 | *********************************************************************************************************
3 | * uC/SMTPc
4 | * Simple Mail Transfer Protocol (client)
5 | *
6 | * Copyright 2004-2021 Silicon Laboratories Inc. www.silabs.com
7 | *
8 | * SPDX-License-Identifier: APACHE-2.0
9 | *
10 | * This software is subject to an open source license and is distributed by
11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
13 | *
14 | *********************************************************************************************************
15 | */
16 |
17 | /*
18 | *********************************************************************************************************
19 | *
20 | * uC/SMTPc CMD SOURCE CODE
21 | *
22 | * Filename : smtp-c_cmd.h
23 | * Version : V2.01.01
24 | *********************************************************************************************************
25 | * Note(s) : (1) Assumes the following versions (or more recent) of software modules are included in
26 | * the project build :
27 | *
28 | * (a) uC/TCP-IP V3.03.00
29 | *********************************************************************************************************
30 | */
31 |
32 |
33 | /*
34 | *********************************************************************************************************
35 | * MODULE
36 | *********************************************************************************************************
37 | */
38 |
39 | #ifndef SMTPc_CMD_MODULE_PRESENT
40 | #define SMTPc_CMD_MODULE_PRESENT
41 |
42 |
43 | /*
44 | *********************************************************************************************************
45 | * INCLUDE FILES
46 | *
47 | * Note(s) : (1) The following common software files are located in the following directories :
48 | *
49 | * (a) \\lib*.*
50 | *
51 | * (b) (1) \\cpu_def.h
52 | *
53 | * (2) \\\\cpu*.*
54 | *
55 | * where
56 | * directory path for custom library software
57 | * directory path for common CPU-compiler software
58 | * directory name for specific processor (CPU)
59 | * directory name for specific compiler
60 | *
61 | * (2)
62 | *
63 | * (3) NO compiler-supplied standard library functions SHOULD be used.
64 | *********************************************************************************************************
65 | */
66 |
67 | #include
68 | #include
69 |
70 | #include
71 |
72 |
73 | /*
74 | *********************************************************************************************************
75 | * EXTERNS
76 | *********************************************************************************************************
77 | */
78 |
79 | #ifdef SMTPc_CMD_MODULE
80 | #define SMTPc_CMD_EXT
81 | #else
82 | #define SMTPc_CMD_EXT extern
83 | #endif
84 |
85 |
86 | /*
87 | *********************************************************************************************************
88 | * DEFAULT CONFIGURATION
89 | *********************************************************************************************************
90 | */
91 |
92 |
93 | /*
94 | *********************************************************************************************************
95 | * DEFINES
96 | *********************************************************************************************************
97 | */
98 |
99 |
100 | /*
101 | *********************************************************************************************************
102 | * DATA TYPES
103 | *********************************************************************************************************
104 | */
105 |
106 | typedef enum smtpc_test_err {
107 | SMTPc_CMD_ERR_NONE = 0, /* No errors. */
108 |
109 | SMTPc_CMD_ERR_SHELL_INIT = 10u, /* Command table not added to uC-Shell. */
110 |
111 | } SMTPc_CMD_ERR;
112 |
113 |
114 | /*
115 | *********************************************************************************************************
116 | * GLOBAL VARIABLES
117 | *********************************************************************************************************
118 | */
119 |
120 |
121 | /*
122 | *********************************************************************************************************
123 | * MACROS
124 | *********************************************************************************************************
125 | */
126 |
127 |
128 | /*
129 | *********************************************************************************************************
130 | * FUNCTION PROTOTYPES
131 | *********************************************************************************************************
132 | */
133 |
134 | void SMTPcCmd_Init (SMTPc_CMD_ERR *p_err);
135 |
136 |
137 | /*
138 | *********************************************************************************************************
139 | * CONFIGURATION ERRORS
140 | *********************************************************************************************************
141 | */
142 |
143 |
144 | /*
145 | *********************************************************************************************************
146 | * MODULE END
147 | *********************************************************************************************************
148 | */
149 |
150 | #endif /* End of smtp-c cmd module include. */
151 |
152 |
--------------------------------------------------------------------------------
/Cfg/Template/smtp-c_cfg.h:
--------------------------------------------------------------------------------
1 | /*
2 | *********************************************************************************************************
3 | * uC/SMTPc
4 | * Simple Mail Transfer Protocol (client)
5 | *
6 | * Copyright 2004-2021 Silicon Laboratories Inc. www.silabs.com
7 | *
8 | * SPDX-License-Identifier: APACHE-2.0
9 | *
10 | * This software is subject to an open source license and is distributed by
11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
13 | *
14 | *********************************************************************************************************
15 | */
16 |
17 | /*
18 | *********************************************************************************************************
19 | *
20 | * SMTP CLIENT CONFIGURATION FILE
21 | *
22 | * TEMPLATE
23 | *
24 | * Filename : smtp-c_cfg.h
25 | * Version : V2.01.01
26 | *********************************************************************************************************
27 | */
28 |
29 | #ifndef SMTPc_CFG_MODULE_PRESENT
30 | #define SMTPc_CFG_MODULE_PRESENT
31 |
32 |
33 | /*
34 | *********************************************************************************************************
35 | * SMTPc ARGUMENT CHECK CONFIGURATION
36 | *
37 | * Note(s) : (1) Configure SMTPc_CFG_ARG_CHK_EXT_EN to enable/disable the SMTP client external argument
38 | * check feature :
39 | *
40 | * (a) When ENABLED, ALL arguments received from any port interface provided by the developer
41 | * are checked/validated.
42 | *
43 | * (b) When DISABLED, NO arguments received from any port interface provided by the developer
44 | * are checked/validated.
45 | *********************************************************************************************************
46 | */
47 | /* Configure external argument check feature ... */
48 | /* See Note 1. */
49 | #define SMTPc_CFG_ARG_CHK_EXT_EN DEF_ENABLED
50 | /* DEF_DISABLED External argument check DISABLED */
51 | /* DEF_ENABLED External argument check ENABLED */
52 | /*
53 | *********************************************************************************************************
54 | * SMTPc
55 | *
56 | * Note(s) : (1) Default TCP port to use when calling SMTPc_Connect() without specifying a port
57 | * to connect to. Standard listening port for SMTP servers is 25.
58 | *
59 | * (2) Standard listening port for secure SMTP servers is 465.
60 | *
61 | * (3) Configure SMTPc_CFG_AUTH_EN to enable/disable plaintext authentication.
62 | *
63 | * (4) Configure maximum lengths for both username and password, when authentication is enabled.
64 | *
65 | * (5) Corresponds to the maximum length of the displayed name associated with a mailbox,
66 | * including '\0'. This length MUST be smaller than 600 in order to respect the same
67 | * limit.
68 | *
69 | * (6) SMTPc_CFG_MSG_SUBJECT_LEN is the maximum length of the string containing the message subject,
70 | * including '\0'. The length MUST be smaller than 900 characters in order to respect the
71 | * Internet Message Format line limit.
72 | *
73 | * (7) Maximum length of the various arrays inside the SMTPc_MSG structure.
74 | *********************************************************************************************************
75 | */
76 |
77 | #define SMTPc_CFG_IPPORT 25 /* Cfg SMTP server IP port (see note #1). */
78 | #define SMTPc_CFG_IPPORT_SECURE 465 /* Cfg SMTP secure server IP port (see Note #2). */
79 |
80 | #define SMTPc_CFG_MAX_CONN_REQ_TIMEOUT_MS 5000 /* Cfg max inactivity time (ms) on CONNECT. */
81 | #define SMTPc_CFG_MAX_CONN_CLOSE_TIMEOUT_MS 5000 /* Cfg max inactivity time (ms) on DISCONNECT. */
82 |
83 | /* Cfg SMTP auth mechanism (see Note #3). */
84 | #define SMTPc_CFG_AUTH_EN DEF_DISABLED
85 | /* DEF_DISABLED PLAIN auth DISABLED */
86 | /* DEF_ENABLED PLAIN auth ENABLED */
87 |
88 | #define SMTPc_CFG_USERNAME_MAX_LEN 50 /* Cfg username max len (see Note #4). */
89 | #define SMTPc_CFG_PW_MAX_LEN 10 /* Cfg pw max len (see Note #4). */
90 |
91 | #define SMTPc_CFG_MBOX_NAME_DISP_LEN 50 /* Cfg max len of sender's name (see Note #5). */
92 | #define SMTPc_CFG_MSG_SUBJECT_LEN 50 /* Cfg max len of msg subject (see Note #6). */
93 |
94 | /* See Note #7. */
95 | #define SMTPc_CFG_MSG_MAX_TO 5 /* Cfg msg max nbr of TO recipients. */
96 | #define SMTPc_CFG_MSG_MAX_CC 5 /* Cfg msg max nbr of CC recipients. */
97 | #define SMTPc_CFG_MSG_MAX_BCC 5 /* Cfg msg max nbr of BCC recipients. */
98 | #define SMTPc_CFG_MSG_MAX_ATTACH 5 /* Cfg msg max nbr of msg attach. */
99 |
100 | /*
101 | *********************************************************************************************************
102 | * TRACING
103 | *********************************************************************************************************
104 | */
105 |
106 | #ifndef TRACE_LEVEL_OFF
107 | #define TRACE_LEVEL_OFF 0
108 | #endif
109 |
110 | #ifndef TRACE_LEVEL_INFO
111 | #define TRACE_LEVEL_INFO 1
112 | #endif
113 |
114 | #ifndef TRACE_LEVEL_DBG
115 | #define TRACE_LEVEL_DBG 2
116 | #endif
117 |
118 | #define SMTPc_TRACE_LEVEL TRACE_LEVEL_INFO
119 | #define SMTPc_TRACE printf
120 |
121 | #endif /* End of smtpc cfg module include. */
122 |
--------------------------------------------------------------------------------
/Example/smtp-c_send.c:
--------------------------------------------------------------------------------
1 | /*
2 | *********************************************************************************************************
3 | * EXAMPLE CODE
4 | *
5 | * This file is provided as an example on how to use Micrium products.
6 | *
7 | * Please feel free to use any application code labeled as 'EXAMPLE CODE' in
8 | * your application products. Example code may be used as is, in whole or in
9 | * part, or may be used as a reference only. This file can be modified as
10 | * required to meet the end-product requirements.
11 | *
12 | *********************************************************************************************************
13 | */
14 |
15 | /*
16 | *********************************************************************************************************
17 | *
18 | * EXAMPLE
19 | *
20 | * SMTP CLIENT
21 |
22 | *
23 | * Filename : smtp-c_send.c
24 | * Version : V2.01.01
25 | *********************************************************************************************************
26 | * Note(s) : (1) This example show how to send an e-mail with SMTP client
27 | *********************************************************************************************************
28 | */
29 |
30 |
31 | /*
32 | *********************************************************************************************************
33 | * INCLUDE FILES
34 | *********************************************************************************************************
35 | */
36 |
37 | #include
38 |
39 |
40 | /*
41 | *********************************************************************************************************
42 | * LOCAL DEFINES
43 | *********************************************************************************************************
44 | */
45 |
46 | #define SERVER_IPV4 "192.168.0.5"
47 | #define SERVER_IPV6 "fe80::1234:5678"
48 | #define SERVER_DOMAIN_NAME "aspmx.l.google.com"
49 |
50 | #define MAILBOX_FROM_NAME "John Doe"
51 | #define MAILBOX_FROM_ADDR "john.doe@foo.bar"
52 | #define USERNAME "john.doe@foo.bar"
53 | #define PASSWORD "123"
54 |
55 | #define MAILBOX_TO_NAME_1 "Jane Doe"
56 | #define MAILBOX_TO_ADDR_1 "jane.doe@foo.bar"
57 |
58 | #define MAILBOX_TO_NAME_2 "Jonnie Doe"
59 | #define MAILBOX_TO_ADDR_2 "jonnie.doe@foo.bar"
60 |
61 | #define MAILBOX_CC_NAME "Janie Doe"
62 | #define MAILBOX_CC_ADDR "janie.doe@foo.bar"
63 |
64 | #define MAILBOX_BCC_NAME "Richard Roe"
65 | #define MAILBOX_BCC_ADDR "richard.roe@foo.bar"
66 |
67 | #define MSG_SUBJECT "Test"
68 | #define MSG "This is a test message"
69 |
70 |
71 | /*
72 | *********************************************************************************************************
73 | * AppMailSend()
74 | *
75 | * Description : Process all the step to prepare and send an email.
76 | *
77 | * Argument(s) : none.
78 | *
79 | * Return(s) : DEF_OK, No error, message sent.
80 | *
81 | * DEF_FAIL, Otherwise.
82 | *
83 | * Caller(s) : Application.
84 | *
85 | * Note(s) : none.
86 | *********************************************************************************************************
87 | */
88 |
89 | CPU_BOOLEAN AppMailSend (void)
90 | {
91 | CPU_CHAR *p_server_addr;
92 | SMTPc_MBOX from_mbox;
93 | SMTPc_MBOX to_mbox1;
94 | SMTPc_MBOX to_mbox2;
95 | SMTPc_MBOX cc_mbox;
96 | SMTPc_MBOX bcc_mbox;
97 | SMTPc_MSG mail;
98 | SMTPc_ERR err;
99 | CPU_INT16U port;
100 | NET_APP_SOCK_SECURE_CFG *p_secure_cfg;
101 |
102 |
103 | p_server_addr = SERVER_IPV4;
104 | /* ------------- INITIALIZE THE MAIL OBJ -------------- */
105 | /* Set the email object mailbox and content to Null. */
106 | /* All fields set to Null will be ignore in the email...*/
107 | /* ...transmission. */
108 | SMTPc_SetMsg (&mail, &err);
109 | if (err != SMTPc_ERR_NONE) {
110 | return (DEF_FAIL);
111 | }
112 | /* ---------------- SET MAIL ENVELOP ------------------ */
113 | /* Set all the mailbox which the email is related to. */
114 | /* SMTPc_MSG need at least the TO and FROM mailbox... */
115 | /* ...in order to be sent properly. */
116 |
117 | mail.From = &from_mbox; /* Set the FROM mailbox of the e-mail. */
118 | SMTPc_SetMbox(mail.From, MAILBOX_FROM_NAME, MAILBOX_FROM_ADDR, &err);
119 | if (err != SMTPc_ERR_NONE) {
120 | return (DEF_FAIL);
121 | }
122 |
123 | mail.ToArray[0] = &to_mbox1; /* Set the TO mailbox of the e-mail. */
124 | SMTPc_SetMbox(mail.ToArray[0], MAILBOX_TO_NAME_1, MAILBOX_TO_ADDR_1, &err);
125 | if (err != SMTPc_ERR_NONE) {
126 | return (DEF_FAIL);
127 | }
128 | /* Set the CC mailbox of the e-mail. */
129 | mail.CCArray[0] = &cc_mbox;
130 | SMTPc_SetMbox(mail.CCArray[0], MAILBOX_CC_NAME, MAILBOX_CC_ADDR, &err);
131 | if (err != SMTPc_ERR_NONE) {
132 | return (DEF_FAIL);
133 | }
134 | /* Set the BCC mailbox of the e-mail. */
135 | mail.BCCArray[0] = &bcc_mbox;
136 | SMTPc_SetMbox(mail.BCCArray[0], MAILBOX_BCC_NAME, MAILBOX_BCC_ADDR, &err);
137 | if (err != SMTPc_ERR_NONE) {
138 | return (DEF_FAIL);
139 | }
140 | /* The TO,CC and BCC mailbox array allow to send... */
141 | /* ... e-mails to multiple destination. */
142 | mail.ToArray[1] = &to_mbox2;
143 | SMTPc_SetMbox(mail.ToArray[1], MAILBOX_TO_NAME_2, MAILBOX_TO_ADDR_2, &err);
144 | if (err != SMTPc_ERR_NONE) {
145 | return (DEF_FAIL);
146 | }
147 |
148 | /* ----------------- SET MAIL CONTENT ----------------- */
149 | /* Set the message subject and body. */
150 | mail.Subject = MSG_SUBJECT;
151 | mail.ContentBodyMsg = MSG;
152 | mail.ContentBodyMsgLen = sizeof(MSG);
153 |
154 | /* ---------------- SET CONN SECURITY ----------------- */
155 | port = SMTPc_CFG_IPPORT;
156 | p_secure_cfg = DEF_NULL;
157 |
158 | /* -------------------- SEND MAIL --------------------- */
159 | SMTPc_SendMail( p_server_addr,
160 | port,
161 | USERNAME,
162 | PASSWORD,
163 | p_secure_cfg,
164 | &mail,
165 | &err);
166 | if (err != SMTPc_ERR_NONE) {
167 | return (DEF_FAIL);
168 | }
169 | return (DEF_OK);
170 | }
171 |
172 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/Cmd/smtp-c_cmd.c:
--------------------------------------------------------------------------------
1 | /*
2 | *********************************************************************************************************
3 | * uC/SMTPc
4 | * Simple Mail Transfer Protocol (client)
5 | *
6 | * Copyright 2004-2021 Silicon Laboratories Inc. www.silabs.com
7 | *
8 | * SPDX-License-Identifier: APACHE-2.0
9 | *
10 | * This software is subject to an open source license and is distributed by
11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
13 | *
14 | *********************************************************************************************************
15 | */
16 |
17 | /*
18 | *********************************************************************************************************
19 | *
20 | * uC/SMTPc CMD SOURCE CODE
21 | *
22 | * Filename : smtp-c_cmd.c
23 | * Version : V2.01.01
24 | *********************************************************************************************************
25 | * Note(s) : (1) Assumes the following versions (or more recent) of software modules are included in
26 | * the project build :
27 | *
28 | * (a) uC/TCP-IP V3.03.00
29 | *********************************************************************************************************
30 | */
31 |
32 |
33 | /*
34 | *********************************************************************************************************
35 | * INCLUDE FILES
36 | *********************************************************************************************************
37 | */
38 |
39 | #define MICRIUM_SOURCE
40 | #define SMTPc_CMD_MODULE
41 |
42 | #include "smtp-c_cmd.h"
43 | #include
44 | #include
45 | #include
46 |
47 |
48 | /*
49 | *********************************************************************************************************
50 | * LOCAL DEFINES
51 | *********************************************************************************************************
52 | */
53 |
54 | #define SMTPc_CMD_HELP_1 "\r\nusage: smtp_send [options]\r\n\r\n"
55 | #define SMTPc_CMD_HELP_2 " -6, Test SMTPc using IPv6 \r\n"
56 | #define SMTPc_CMD_HELP_3 " -4, Test SMTPc using IPv4 \r\n"
57 | #define SMTPc_CMD_HELP_4 " -d, Test SMTPc using server domain name (aspmx.l.google.com)\r\n"
58 | #define SMTPc_CMD_HELP_5 " -t, Set the TO address used to send the mail\r\n"
59 |
60 | #define SMTPc_CMD_OK "OK"
61 | #define SMTPc_CMD_FAIL "FAIL "
62 |
63 | #define SMTPc_CMD_SERVER_IPV4 "192.168.0.2"
64 | #define SMTPc_CMD_SERVER_IPV6 "fe80::1234:5678:"
65 | #define SMTPc_CMD_SERVER_DOMAIN_NAME "aspmx.l.google.com"
66 |
67 | #define SMTPc_CMD_MAILBOX_FROM_NAME "Test Name From"
68 | #define SMTPc_CMD_MAILBOX_FROM_ADDR "webmaster@mail.smtptest.com"
69 | #define SMTPc_CMD_MAILBOX_TO_NAME "Test Name To"
70 | #define SMTPc_CMD_MAILBOX_TO_ADDR "testto@mail.smtptest.com"
71 |
72 |
73 | #define SMTPc_CMD_USERNAME "webmaster@mail.smtptest.com"
74 | #define SMTPc_CMD_PW "password"
75 |
76 | #define SMTPc_CMD_MSG_SUBJECT "Test"
77 | #define SMTPc_CMD_MSG "This is a test message"
78 | #define SMTPc_CMD_MAILBOX_CC_ADDR "testcc1@mail.smtptest.com"
79 | #define SMTPc_CMD_MAILBOX_CC_NAME "Test Name CC1"
80 | #define SMTPc_CMD_MAILBOX_BCC_ADDR "testbcc1@mail.smtptest.com"
81 | #define SMTPc_CMD_MAILBOX_BCC_NAME "Test Name BCC 1"
82 |
83 | #define SMTPc_CMD_PARSER_DNS ASCII_CHAR_LATIN_LOWER_D
84 | #define SMTPc_CMD_PARSER_IPv6 ASCII_CHAR_DIGIT_SIX
85 | #define SMTPc_CMD_PARSER_IPv4 ASCII_CHAR_DIGIT_FOUR
86 | #define SMTPc_CMD_ARG_PARSER_CMD_BEGIN ASCII_CHAR_HYPHEN_MINUS
87 | #define SMTPc_CMD_PARSER_TO ASCII_CHAR_LATIN_LOWER_T
88 |
89 |
90 | /*
91 | *********************************************************************************************************
92 | * LOCAL FUNCTION PROTOTYPES
93 | *********************************************************************************************************
94 | */
95 |
96 | CPU_INT16S SMTPcCmd_Send (CPU_INT16U argc,
97 | CPU_CHAR *p_argv[],
98 | SHELL_OUT_FNCT out_fnct,
99 | SHELL_CMD_PARAM *p_cmd_param);
100 |
101 | CPU_INT16S SMTPcCmd_Help (CPU_INT16U argc,
102 | CPU_CHAR *p_argv[],
103 | SHELL_OUT_FNCT out_fnct,
104 | SHELL_CMD_PARAM *p_cmd_param);
105 |
106 |
107 | /*
108 | *********************************************************************************************************
109 | * LOCAL TABLES
110 | *********************************************************************************************************
111 | */
112 |
113 | static SHELL_CMD SMTPc_CmdTbl[] =
114 | {
115 | {"smtp_send" , SMTPcCmd_Send},
116 | {"smtp_help" , SMTPcCmd_Help},
117 | {0, 0}
118 | };
119 |
120 |
121 | /*
122 | *********************************************************************************************************
123 | * SMTPcCmd_Init()
124 | *
125 | * Description : Add uC/SMTPc cmd stubs to uC-Shell.
126 | *
127 | * Argument(s) : p_err is a pointer to an error code which will be returned to your application:
128 | *
129 | * SMTPc_CMD_ERR_NONE No error.
130 | *
131 | * SMTPc_CMD_ERR_SHELL_INIT Command table not added to uC-Shell
132 | *
133 | * Return(s) : none.
134 | *
135 | * Caller(s) : AppTaskStart().
136 | *
137 | * Note(s) : none.
138 | *********************************************************************************************************
139 | */
140 |
141 | void SMTPcCmd_Init (SMTPc_CMD_ERR *p_err)
142 | {
143 | SHELL_ERR err;
144 |
145 |
146 | Shell_CmdTblAdd("smtp", SMTPc_CmdTbl, &err);
147 |
148 | if (err == SHELL_ERR_NONE) {
149 | *p_err = SMTPc_CMD_ERR_NONE;
150 | } else {
151 | *p_err = SMTPc_CMD_ERR_SHELL_INIT;
152 | }
153 | }
154 |
155 |
156 | /*
157 | *********************************************************************************************************
158 | * SMTPc_Cmd_Send()
159 | *
160 | * Description : Send a predefine test e-mail.
161 | *
162 | * Argument(s) : argc is a count of the arguments supplied.
163 | *
164 | * p_argv an array of pointers to the strings which are those arguments.
165 | *
166 | * out_fnct is a callback to a respond to the requester.
167 | *
168 | * p_cmd_param is a pointer to additional information to pass to the command.
169 | *
170 | *
171 | * Return(s) : The number of positive data octets transmitted, if NO errors
172 | *
173 | * SHELL_OUT_ERR, otherwise
174 | *
175 | * Caller(s) : AppTaskStart().
176 | *
177 | * Note(s) : none.
178 | *********************************************************************************************************
179 | */
180 |
181 | CPU_INT16S SMTPcCmd_Send (CPU_INT16U argc,
182 | CPU_CHAR *p_argv[],
183 | SHELL_OUT_FNCT out_fnct,
184 | SHELL_CMD_PARAM *p_cmd_param)
185 | {
186 | SMTPc_ERR err;
187 | CPU_INT16S output;
188 | CPU_INT16S ret_val;
189 | CPU_CHAR *p_server_addr;
190 | CPU_CHAR *p_to_addr;
191 | CPU_INT16U error_code;
192 | CPU_CHAR reply_buf[16];
193 | CPU_INT16U cmd_namd_len;
194 | CPU_INT08U i;
195 | SMTPc_MBOX from_mbox;
196 | SMTPc_MBOX to_mbox;
197 | SMTPc_MSG mail;
198 |
199 |
200 | p_to_addr = SMTPc_CMD_MAILBOX_TO_ADDR;
201 | p_server_addr = SMTPc_CMD_SERVER_IPV4;
202 | /* Parse Arguments. */
203 | if (argc != 0) {
204 | for (i = 1; i < argc; i++) {
205 | if (*p_argv[i] == SMTPc_CMD_ARG_PARSER_CMD_BEGIN) {
206 | switch (*(p_argv[i] + 1)) {
207 | case SMTPc_CMD_PARSER_IPv6:
208 | p_server_addr = SMTPc_CMD_SERVER_IPV6;
209 |
210 | if (argc != i + 1) {
211 | if (*p_argv[i+1] != SMTPc_CMD_ARG_PARSER_CMD_BEGIN) {
212 | p_server_addr = p_argv[i+1];
213 | i++;
214 | }
215 | }
216 | break;
217 |
218 | case SMTPc_CMD_PARSER_IPv4:
219 | p_server_addr = SMTPc_CMD_SERVER_IPV4;
220 |
221 | if (argc != i + 1) {
222 | if (*p_argv[i+1] != SMTPc_CMD_ARG_PARSER_CMD_BEGIN) {
223 | p_server_addr = p_argv[i+1];
224 | i++;
225 | }
226 | }
227 | break;
228 |
229 | case SMTPc_CMD_PARSER_DNS:
230 | p_server_addr = SMTPc_CMD_SERVER_DOMAIN_NAME;
231 |
232 | if (argc != i + 1) {
233 | if (*p_argv[i+1] != SMTPc_CMD_ARG_PARSER_CMD_BEGIN) {
234 | p_server_addr = p_argv[i+1];
235 | i++;
236 | }
237 | }
238 | break;
239 |
240 | case SMTPc_CMD_PARSER_TO:
241 | if (argc != i + 1) {
242 | if (*p_argv[i+1] != SMTPc_CMD_ARG_PARSER_CMD_BEGIN) {
243 | p_to_addr = p_argv[i+1];
244 | i++;
245 | } else {
246 | err = SMTPc_ERR_INVALID_ADDR;
247 | goto exit_fail;
248 | }
249 | } else {
250 | err = SMTPc_ERR_INVALID_ADDR;
251 | goto exit_fail;
252 | }
253 | break;
254 |
255 | default:
256 | err = SMTPc_ERR_INVALID_ADDR;
257 | goto exit_fail;
258 | break;
259 |
260 | }
261 | }
262 | }
263 | } else {
264 | err = SMTPc_ERR_INVALID_ADDR;
265 | goto exit_fail;
266 | }
267 |
268 | /* Initialize the message obj. */
269 | SMTPc_SetMsg (&mail, &err);
270 | if (err != SMTPc_ERR_NONE) {
271 | goto exit_fail;
272 | }
273 | /* Set Mail Envelop. */
274 | mail.From = &from_mbox;
275 | SMTPc_SetMbox(mail.From, SMTPc_CMD_MAILBOX_FROM_NAME, SMTPc_CMD_MAILBOX_FROM_ADDR, &err);
276 | if (err != SMTPc_ERR_NONE) {
277 | goto exit_fail;
278 | }
279 | mail.ToArray[0] = &to_mbox;
280 | SMTPc_SetMbox(mail.ToArray[0], SMTPc_CMD_MAILBOX_TO_NAME, p_to_addr, &err);
281 | if (err != SMTPc_ERR_NONE) {
282 | goto exit_fail;
283 | }
284 |
285 | /* Set Mail Content. */
286 | mail.Subject = SMTPc_CMD_MSG_SUBJECT;
287 | mail.ContentBodyMsg = SMTPc_CMD_MSG;
288 | mail.ContentBodyMsgLen = sizeof(SMTPc_CMD_MSG);
289 |
290 | /* Send Mail. */
291 | SMTPc_SendMail( p_server_addr,
292 | 0,
293 | SMTPc_CMD_USERNAME,
294 | SMTPc_CMD_PW,
295 | DEF_NULL,
296 | &mail,
297 | &err);
298 | if (err == SMTPc_ERR_NONE) {
299 | Str_Copy(&reply_buf[0], SMTPc_CMD_OK);
300 | cmd_namd_len = Str_Len(reply_buf);
301 | } else {
302 |
303 | exit_fail:
304 | error_code = err;
305 | Str_Copy(&reply_buf[0], SMTPc_CMD_FAIL);
306 | cmd_namd_len = Str_Len(reply_buf);
307 |
308 | Str_FmtNbr_Int32U(error_code, 5, 10, ' ', DEF_YES, DEF_YES, &reply_buf[cmd_namd_len]);
309 | cmd_namd_len = Str_Len(reply_buf);
310 | }
311 |
312 | reply_buf[cmd_namd_len + 0] = '\r';
313 | reply_buf[cmd_namd_len + 1] = '\n';
314 | reply_buf[cmd_namd_len + 2] = '\0';
315 |
316 | cmd_namd_len = Str_Len(reply_buf);
317 |
318 | output = out_fnct(&reply_buf[0],
319 | cmd_namd_len,
320 | p_cmd_param->pout_opt);
321 |
322 | switch (output) {
323 | case SHELL_OUT_RTN_CODE_CONN_CLOSED:
324 | case SHELL_OUT_ERR:
325 | ret_val = SHELL_EXEC_ERR;
326 | break;
327 | default:
328 | ret_val = output;
329 | }
330 |
331 | return (ret_val);
332 | }
333 |
334 |
335 | /*
336 | *********************************************************************************************************
337 | * SMTPc_Cmd_Help()
338 | *
339 | * Description : Print SMTPc command help.
340 | *
341 | * Argument(s) : argc is a count of the arguments supplied.
342 | *
343 | * p_argv an array of pointers to the strings which are those arguments.
344 | *
345 | * out_fnct is a callback to a respond to the requester.
346 | *
347 | * p_cmd_param is a pointer to additional information to pass to the command.
348 | *
349 | *
350 | * Return(s) : The number of positive data octets transmitted, if NO errors
351 | *
352 | * SHELL_OUT_ERR, otherwise
353 | *
354 | * Caller(s) : AppTaskStart().
355 | *
356 | * Note(s) : none.
357 | *********************************************************************************************************
358 | */
359 |
360 | CPU_INT16S SMTPcCmd_Help (CPU_INT16U argc,
361 | CPU_CHAR *p_argv[],
362 | SHELL_OUT_FNCT out_fnct,
363 | SHELL_CMD_PARAM *p_cmd_param)
364 | {
365 | CPU_INT16U cmd_namd_len;
366 | CPU_INT16S output;
367 | CPU_INT16S ret_val;
368 |
369 |
370 | cmd_namd_len = Str_Len(SMTPc_CMD_HELP_1);
371 | output = out_fnct(SMTPc_CMD_HELP_1,
372 | cmd_namd_len,
373 | p_cmd_param->pout_opt);
374 |
375 | cmd_namd_len = Str_Len(SMTPc_CMD_HELP_2);
376 | output = out_fnct(SMTPc_CMD_HELP_2,
377 | cmd_namd_len,
378 | p_cmd_param->pout_opt);
379 |
380 | cmd_namd_len = Str_Len(SMTPc_CMD_HELP_3);
381 | output = out_fnct(SMTPc_CMD_HELP_3,
382 | cmd_namd_len,
383 | p_cmd_param->pout_opt);
384 |
385 | cmd_namd_len = Str_Len(SMTPc_CMD_HELP_4);
386 | output = out_fnct(SMTPc_CMD_HELP_4,
387 | cmd_namd_len,
388 | p_cmd_param->pout_opt);
389 |
390 | cmd_namd_len = Str_Len(SMTPc_CMD_HELP_5);
391 | output = out_fnct(SMTPc_CMD_HELP_5,
392 | cmd_namd_len,
393 | p_cmd_param->pout_opt);
394 |
395 | switch (output) {
396 | case SHELL_OUT_RTN_CODE_CONN_CLOSED:
397 | case SHELL_OUT_ERR:
398 | ret_val = SHELL_EXEC_ERR;
399 | break;
400 | default:
401 | ret_val = output;
402 | }
403 |
404 | return (ret_val);
405 | }
406 |
407 |
--------------------------------------------------------------------------------
/Source/smtp-c.h:
--------------------------------------------------------------------------------
1 | /*
2 | *********************************************************************************************************
3 | * uC/SMTPc
4 | * Simple Mail Transfer Protocol (client)
5 | *
6 | * Copyright 2004-2021 Silicon Laboratories Inc. www.silabs.com
7 | *
8 | * SPDX-License-Identifier: APACHE-2.0
9 | *
10 | * This software is subject to an open source license and is distributed by
11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
13 | *
14 | *********************************************************************************************************
15 | */
16 |
17 | /*
18 | *********************************************************************************************************
19 | *
20 | * SMTP CLIENT
21 | *
22 | * Filename : smtp-c.h
23 | * Version : V2.01.01
24 | *********************************************************************************************************
25 | * Note(s) : (1) This code implements a subset of the SMTP protocol (RFC 2821). More precisely, the
26 | * following commands have been implemented:
27 | *
28 | * HELO
29 | * AUTH (if enabled)
30 | * MAIL
31 | * RCPT
32 | * DATA
33 | * RSET
34 | * NOOP
35 | * QUIT
36 | *********************************************************************************************************
37 | */
38 |
39 |
40 | /*
41 | *********************************************************************************************************
42 | * MODULE
43 | *
44 | * Note(s) : (1) This header file is protected from multiple preprocessor inclusion through use of the
45 | * SMTPc present preprocessor macro definition.
46 | *********************************************************************************************************
47 | */
48 |
49 | #ifndef SMTPc_PRESENT /* See Note #1. */
50 | #define SMTPc_PRESENT
51 |
52 |
53 | /*
54 | *********************************************************************************************************
55 | * SMTPc VERSION NUMBER
56 | *
57 | * Note(s) : (1) (a) The SMTPc module software version is denoted as follows :
58 | *
59 | * Vx.yy.zz
60 | *
61 | * where
62 | * V denotes 'Version' label
63 | * x denotes major software version revision number
64 | * yy denotes minor software version revision number
65 | * zz denotes sub-minor software version revision number
66 | *
67 | * (b) The SMTPc software version label #define is formatted as follows :
68 | *
69 | * ver = x.yyzz * 100 * 100
70 | *
71 | * where
72 | * ver denotes software version number scaled as an integer value
73 | * x.yyzz denotes software version number, where the unscaled integer
74 | * portion denotes the major version number & the unscaled
75 | * fractional portion denotes the (concatenated) minor
76 | * version numbers
77 | *********************************************************************************************************
78 | */
79 |
80 | #define SMTPc_VERSION 20101u /* See Note #1. */
81 |
82 |
83 | /*
84 | *********************************************************************************************************
85 | * EXTERNS
86 | *********************************************************************************************************
87 | */
88 |
89 | #ifdef SMTPc_MODULE
90 | #define SMTPc_EXT
91 | #else
92 | #define SMTPc_EXT extern
93 | #endif
94 |
95 |
96 | /*
97 | *********************************************************************************************************
98 | * INCLUDE FILES
99 | *
100 | * Note(s) : (1) The SMTPc module files are located in the following directories :
101 | *
102 | * (a) \\smtp-c_cfg.h
103 | *
104 | * (b) (1) \\Source\net_*.*
105 | *
106 | * (2) If network security manager is to be used:
107 | *
108 | * (A) \\Secure\net_secure_mgr.*
109 | *
110 | * (B) \\Secure\\net_secure.*
111 | *
112 | * (c) \\Source\smtp-c.h
113 | * \smtp-c.c
114 | *
115 | * where
116 | * directory path for Your Product's Application
117 | * directory path for network protocol suite
118 | * directory path for SMTPc module
119 | *
120 | * (2) CPU-configuration software files are located in the following directories :
121 | *
122 | * (a) \\cpu_*.*
123 | * (b) \\\\cpu*.*
124 | *
125 | * where
126 | * directory path for common CPU-compiler software
127 | * directory name for specific processor (CPU)
128 | * directory name for specific compiler
129 | *
130 | * (3) NO compiler-supplied standard library functions SHOULD be used.
131 | *
132 | * (a) Standard library functions are implemented in the custom library module(s) :
133 | *
134 | * \\lib_*.*
135 | *
136 | * where
137 | * directory path for custom library software
138 | *
139 | * (b) #### The reference to standard library header files SHOULD be removed once all custom
140 | * library functions are implemented WITHOUT reference to ANY standard library function(s).
141 | *
142 | * (4) Compiler MUST be configured to include as additional include path directories :
143 | *
144 | * (a) '\\' directory See Note #1a
145 | *
146 | * (b) (1) '\\ See Note #1b1
147 | *
148 | * (2) (A) '\\Secure\' See Note #1b2A
149 | * (B) '\\Secure\\' See Note #1b2B
150 | *
151 | * (c) '\\' directory See Note #1c
152 | *
153 | * (d) (1) '\\' directory See Note #2a
154 | * (2) '\\\\' directory See Note #2b
155 | *
156 | * (e) '\\' directory See Note #3a
157 | *********************************************************************************************************
158 | */
159 |
160 | #include /* CPU Configuration (see Note #2b) */
161 | #include /* CPU Core Library (see Note #2a) */
162 |
163 | #include /* Standard Defines (see Note #3a) */
164 | #include /* Standard String Library (see Note #3a) */
165 |
166 |
167 | #include /* Network Protocol Suite (see Note #1b) */
168 | #include
169 | #include
170 | #include
171 | #include
172 | #include
173 | #include
174 | #include
175 |
176 |
177 | #if 1 /* See Note #3b. */
178 | #include
179 | #endif
180 |
181 |
182 | /*
183 | *********************************************************************************************************
184 | * DEFINES
185 | *********************************************************************************************************
186 | */
187 |
188 | /*
189 | *********************************************************************************************************
190 | * ERROR CODES DEFINES
191 | *********************************************************************************************************
192 | */
193 | typedef enum smtpc_err {
194 | SMTPc_ERR_NONE = 51000u,
195 | SMTPc_ERR_SOCK_OPEN_FAILED = 51001u,
196 | SMTPc_ERR_SOCK_CONN_FAILED = 51002u,
197 | SMTPc_ERR_NO_SMTP_SERV = 51003u,
198 | SMTPc_ERR_RX_FAILED = 51004u,
199 | SMTPc_ERR_TX_FAILED = 51005u,
200 | SMTPc_ERR_NULL_ARG = 51006u,
201 | SMTPc_ERR_LINE_TOO_LONG = 51007u,
202 | SMTPc_ERR_STR_TOO_LONG = 51008u,
203 | SMTPc_ERR_REP = 51009u,
204 | SMTPc_ERR_BUF_TOO_SMALL = 51010u,
205 | SMTPc_ERR_ENCODE = 51011u,
206 | SMTPc_ERR_AUTH_FAILED = 51012u,
207 | SMTPc_ERR_SECURE_NOT_AVAIL = 51013u,
208 |
209 | SMTPc_ERR_REP_POS = 51000u,
210 | SMTPc_ERR_REP_INTER = 51013u,
211 | SMTPc_ERR_REP_NEG = 51014u,
212 | SMTPc_ERR_REP_TOO_SHORT = 51015u,
213 |
214 | SMTPc_ERR_INVALID_ADDR = 51016u,
215 |
216 | } SMTPc_ERR;
217 |
218 |
219 | /*
220 | *********************************************************************************************************
221 | * SMTPc STRUCT DEFINES
222 | *
223 | * Note(s) : (1) Line length limit, as defined in RFC #2822.
224 | *
225 | * (2) SMTPc_CFG_COMM_BUF_LEN is the length of the buffer used to receive replies from the SMTP
226 | * server. As stated in RFC #2821, Section 'The SMTP Specifications, Additional Implementation
227 | * Issues, Sizes and Timeouts, Size limits and minimums', "The maximum total length of a
228 | * reply code and the is 512 characters".
229 | *
230 | * This buffer is also used to build outgoing messages and MUST NOT be smaller than 1000
231 | * (see Note #1).
232 | *
233 | * (3) Maximum length of key-value strings in structure SMTPc_KEY_VAL.
234 | *
235 | * (4) As mentioned in RFC #2821, Section 'The SMTP Specifications, Additional
236 | * Implementation Issues, Sizes and Timeouts, Size limits and minimums', "The maximum
237 | * total length of a user name or other local-part is 64 characters [and] the maximum
238 | * total length of a domain name or number is 255 characters.". Adding 2 for
239 | * '@' (see SMTPc_MBOX structure) and '\0'.
240 | *
241 | * (5) Maximum length of content-type.
242 | *
243 | * (6) From RFC #2822, Section 'Syntax, Fields definitions, Identification fields', "The message
244 | * identifier (msg-id) [field] is similar in syntax to an angle-addr construct".
245 | *
246 | * (7) Size of ParamArray in structure SMTPc_MIME_ENTITY_HDR.
247 | *
248 | * (8) Maximum length of attachment's name and description.
249 | *********************************************************************************************************
250 | */
251 |
252 | #define SMTPc_LINE_LEN_LIM 1000 /* See Note #1. */
253 |
254 | #define SMTPc_COMM_BUF_LEN 1024 /* See Note #2. */
255 |
256 | /* See Note #3. */
257 | #define SMTPc_KEY_VAL_KEY_LEN 30
258 | #define SMTPc_KEY_VAL_VAL_LEN 30
259 |
260 | /* See Note #4. */
261 | #define SMTPc_MBOX_DOMAIN_NAME_LEN 255
262 | #define SMTPc_MBOX_LOCAL_PART_LEN 64
263 | #define SMTPc_MBOX_ADDR_LEN (SMTPc_MBOX_DOMAIN_NAME_LEN + SMTPc_MBOX_LOCAL_PART_LEN + 2)
264 |
265 | /* See Note #5. */
266 | #define SMTPc_MIME_CONTENT_TYPE_LEN 20
267 |
268 | /* See Note #6. */
269 | #define SMTPc_MIME_ID_LEN SMTPc_MBOX_ADDR_LEN
270 |
271 | /* See Note #7. */
272 | #define SMTPc_MIME_MAX_KEYVAL 1
273 |
274 | /* See Note #8. */
275 | #define SMTPc_ATTACH_NAME_LEN 50
276 | #define SMTPc_ATTACH_DESC_LEN 50
277 |
278 | /* See Note #6. */
279 | #define SMTPc_MSG_MSGID_LEN SMTPc_MBOX_ADDR_LEN
280 |
281 |
282 |
283 | /*
284 | *********************************************************************************************************
285 | * STATUS CODES DEFINES
286 | *
287 | * Note(s): (1) Reply codes are defined here and classified by category. Note that this list is not meant
288 | * to be exhaustive.
289 | *********************************************************************************************************
290 | */
291 |
292 | /* ------------ POSITIVE PRELIMINARY REPLY ------------ */
293 | #define SMTPc_REP_POS_PRELIM_GRP 1
294 |
295 | /* ------------ POSITIVE COMPLETION REPLY ------------- */
296 | #define SMTPc_REP_POS_COMPLET_GRP 2
297 | #define SMTPc_REP_220 220 /* Service ready. */
298 | #define SMTPc_REP_221 221 /* Service closing transmission channel. */
299 | #define SMTPc_REP_235 235 /* Authentication successful. */
300 | #define SMTPc_REP_250 250 /* Requested mail action okay, completed. */
301 | #define SMTPc_REP_251 251 /* User not local; will forward to . */
302 |
303 | /* ------------ POSITIVE INTERMEDIATE REPLY ----------- */
304 | #define SMTPc_REP_POS_INTER_GRP 3
305 | #define SMTPc_REP_354 354 /* Start mail input; end with .. */
306 |
307 | /* -------- TRANSIENT NEGATIVE COMPLETION REPLY ------- */
308 | #define SMTPc_REP_NEG_TRANS_COMPLET_GRP 4
309 | #define SMTPc_REP_421 421 /* Service closing transmission channel. */
310 |
311 | /* -------- PERMANENT NEGATIVE COMPLETION REPLY ------- */
312 | #define SMTPc_REP_NEG_COMPLET_GRP 5
313 | #define SMTPc_REP_503 503 /* Bad sequence of commands. */
314 | #define SMTPc_REP_504 504 /* Command parameter not implemented. */
315 | #define SMTPc_REP_535 535 /* Authentication failure. */
316 | #define SMTPc_REP_550 550 /* Requested action not taken: mailbox unavailable. */
317 | #define SMTPc_REP_554 554 /* Transaction failed. */
318 |
319 |
320 | /*
321 | *********************************************************************************************************
322 | * COMMANDS AND STRINGS DEFINES
323 | *********************************************************************************************************
324 | */
325 |
326 | #define SMTPc_CMD_HELO "HELO"
327 | #define SMTPc_CMD_MAIL "MAIL"
328 | #define SMTPc_CMD_RCPT "RCPT"
329 | #define SMTPc_CMD_DATA "DATA"
330 | #define SMTPc_CMD_RSET "RSET"
331 | #define SMTPc_CMD_NOOP "NOOP"
332 | #define SMTPc_CMD_QUIT "QUIT"
333 |
334 | #define SMTPc_CMD_AUTH "AUTH"
335 | #define SMTPc_CMD_AUTH_MECHANISM_PLAIN "PLAIN"
336 |
337 |
338 | #define SMTPc_CRLF "\x0D\x0A"
339 | #define SMTPc_EOM "\x0D\x0A.\x0D\x0A"
340 | #define SMTPc_CRLF_SIZE 2u
341 |
342 | #define SMTPc_HDR_FROM "From: "
343 | #define SMTPc_HDR_SENDER "Sender: "
344 | #define SMTPc_HDR_TO "To: "
345 | #define SMTPc_HDR_REPLYTO "Reply-to: "
346 | #define SMTPc_HDR_CC "Cc: "
347 | #define SMTPc_HDR_SUBJECT "Subject: "
348 |
349 | #define SMTPc_TAG_IPv6 "IPv6:"
350 |
351 |
352 | /*
353 | *********************************************************************************************************
354 | * BASE 64 ENCODER DEFINES
355 | *
356 | * Note(s) : (1) The maximum input buffer passed to the base 64 encoder depends of the configured maximum
357 | * lengths for the username and password. Two additional characters are added to these
358 | * values to account for the delimiter (see 'smtp-c.c SMTPc_AUTH() Note #2').
359 | *
360 | * (2) The size of the output buffer the base 64 encoder produces is typically bigger than the
361 | * input buffer by a factor of (4 x 3). However, when padding is necessary, up to 3
362 | * additional characters could by appended. Finally, one more character is used to NULL
363 | * terminate the buffer.
364 | *********************************************************************************************************
365 | */
366 |
367 | #define SMTPc_ENCODER_BASE64_DELIMITER_CHAR 0
368 | /* See Note #1. */
369 | #define SMTPc_ENCODER_BASE54_IN_MAX_LEN (SMTPc_CFG_MBOX_NAME_DISP_LEN + SMTPc_CFG_MSG_SUBJECT_LEN + 2)
370 |
371 | /* See Note #2. */
372 | #define SMTPc_ENCODER_BASE64_OUT_MAX_LEN ((((SMTPc_CFG_MBOX_NAME_DISP_LEN + SMTPc_CFG_MSG_SUBJECT_LEN + 2) * 4) / 3) + 4)
373 |
374 |
375 | /*
376 | *********************************************************************************************************
377 | * DATA TYPES
378 | *
379 | * Note(s): (1) From RFC #2821 'The SMTP Model, Terminology, Mail Objects', "SMTP transports a mail
380 | * object. A mail object contains an envelope and content. The SMTP content is sent
381 | * in the SMTP DATA protocol unit and has two parts: the headers and the body":
382 | *
383 | * |----------------------|
384 | * | |
385 | * | | Envelope
386 | * | |
387 | * |======================|
388 | * | |
389 | * | Headers |
390 | * | |
391 | * | |
392 | * | |
393 | * |----------------------| Content
394 | * | |
395 | * | Body |
396 | * | |
397 | * | |
398 | * | |
399 | * |----------------------|
400 | *
401 | *********************************************************************************************************
402 | */
403 |
404 | /*
405 | *********************************************************************************************************
406 | * KEY-VALUE STRUCT DATA TYPES
407 | *
408 | * Note(s): (1) This structure makes room for additional MIME header fields (see RFC #2045, Section
409 | * 'Additional MIME Header Fields').
410 | *********************************************************************************************************
411 | */
412 |
413 | typedef struct SMTPc_key_val
414 | {
415 | CPU_CHAR Key[SMTPc_KEY_VAL_KEY_LEN]; /* Key (hdr field name). */
416 | CPU_CHAR Val[SMTPc_KEY_VAL_VAL_LEN]; /* Val associated with the preceding key. */
417 | } SMTPc_KEY_VAL;
418 |
419 |
420 | /*
421 | *********************************************************************************************************
422 | * SMTP MAILBOX AND MAILBOX LIST DATA TYPES
423 | *
424 | * Note(s): (1) Structure representing an email address, as well as the name of its owner.
425 | *********************************************************************************************************
426 | */
427 |
428 | typedef struct SMTPc_mbox
429 | {
430 | CPU_CHAR NameDisp[SMTPc_CFG_MBOX_NAME_DISP_LEN]; /* Disp'd name of addr's owner. */
431 | CPU_CHAR Addr [SMTPc_MBOX_ADDR_LEN]; /* Addr (local part '@' domain). */
432 | } SMTPc_MBOX;
433 |
434 |
435 | /*
436 | *********************************************************************************************************
437 | * SMTP MIME ENTITY HEADER
438 | *
439 | * Note(s): (1) See RFC #2045 for details.
440 | *
441 | * (2) Structure subject to change. For instance, other data structures could be used to represent
442 | * "Encoding", etc. The encoding could also be left to do by the application
443 | *********************************************************************************************************
444 | */
445 |
446 | typedef struct SMTPc_mime_entity_hdr
447 | {
448 | CPU_CHAR *ContentType[SMTPc_MIME_CONTENT_TYPE_LEN]; /* Description of contained body data (IANA assigned). */
449 | SMTPc_KEY_VAL *ParamArray[SMTPc_MIME_MAX_KEYVAL]; /* Additional param for specified content-type. */
450 | void *ContentEncoding; /* Content transfer encoding. */
451 | void (*EncodingFnctPtr)(CPU_CHAR *, /* Ptr to fnct performing the encoding of the */
452 | NET_ERR *); /* attachment. */
453 | CPU_CHAR ID[SMTPc_MIME_ID_LEN]; /* Unique attachment id. */
454 | } SMTPc_MIME_ENTITY_HDR;
455 |
456 |
457 | /*
458 | *********************************************************************************************************
459 | * SMTP MESSAGE ATTACHMENT AND ATTACHMENT LIST DATA TYPES
460 | *
461 | * Note(s): (1) Attachments are not going to be supported in the first version of the uCSMTPc module.
462 | * Hence, the format of this structure will surely change to accommodate for possible
463 | * file system access.
464 | *********************************************************************************************************
465 | */
466 |
467 | typedef struct SMTPc_attach
468 | {
469 | SMTPc_MIME_ENTITY_HDR MIMEPartHdrStruct; /* MIME content hdr for this attachment. */
470 | CPU_CHAR Name[SMTPc_ATTACH_NAME_LEN]; /* Name of attachment inserted in the message. */
471 | CPU_CHAR Desc[SMTPc_ATTACH_DESC_LEN]; /* Optional attachment description. */
472 | void *AttachData; /* Ptr to beginning of body (data of the entity). */
473 | CPU_INT32U Size ; /* Size of data in octets. */
474 |
475 | } SMTPc_ATTACH;
476 |
477 |
478 | /*
479 | *********************************************************************************************************
480 | * SMTP MSG Structure
481 | *
482 | * Note(s): (1) A mail object is represented in this module by the structure SMTPc_MSG. This
483 | * structure contains all the necessary information to generate the mail object
484 | * and to send it to the SMTP server. More specifically, it encapsulates the various
485 | * addresses of the sender and recipients, MIME information, the message itself, and
486 | * finally the eventual attachments.
487 | *********************************************************************************************************
488 | */
489 |
490 | typedef struct SMTPc_msg
491 | {
492 | SMTPc_MBOX *From; /* "From" field (1:1). */
493 | SMTPc_MBOX *ToArray[SMTPc_CFG_MSG_MAX_TO]; /* "To" field (1:*). */
494 | SMTPc_MBOX *ReplyTo; /* "Reply-to" field (0:1). */
495 | SMTPc_MBOX *Sender; /* "Sender" field (0:1). */
496 | SMTPc_MBOX *CCArray[SMTPc_CFG_MSG_MAX_CC]; /* "CC" field (0:*). */
497 | SMTPc_MBOX *BCCArray[SMTPc_CFG_MSG_MAX_BCC]; /* "BCC" field (0:*). */
498 | CPU_CHAR MsgID[SMTPc_MSG_MSGID_LEN]; /* Unique msg id. */
499 | SMTPc_MIME_ENTITY_HDR MIMEMsgHdrStruct; /* Mail obj MIME content headers. */
500 | CPU_CHAR *Subject; /* Subject of msg. */
501 | /* List of attachment(s), if any. */
502 | SMTPc_ATTACH *AttachArray[SMTPc_CFG_MSG_MAX_ATTACH];
503 | CPU_CHAR *ContentBodyMsg; /* Data of the mail obj content's body. */
504 | CPU_INT32U ContentBodyMsgLen; /* Size (in octets) of buf pointed by ContentBodyMsg. */
505 | } SMTPc_MSG;
506 |
507 |
508 | /*
509 | *********************************************************************************************************
510 | * GLOBAL VARIABLES
511 | *********************************************************************************************************
512 | */
513 |
514 | SMTPc_EXT CPU_CHAR SMTPc_Comm_Buf[SMTPc_COMM_BUF_LEN];
515 |
516 |
517 | /*
518 | *********************************************************************************************************
519 | * FUNCTION PROTOTYPES
520 | *********************************************************************************************************
521 | */
522 |
523 | void SMTPc_SendMail (CPU_CHAR *p_host_name,
524 | CPU_INT16U port,
525 | CPU_CHAR *p_username,
526 | CPU_CHAR *p_pwd,
527 | NET_APP_SOCK_SECURE_CFG *p_secure_cfg,
528 | SMTPc_MSG *p_msg,
529 | SMTPc_ERR *p_err);
530 |
531 | /* ---------------- SMTP SESSION FNCTS ---------------- */
532 | NET_SOCK_ID SMTPc_Connect (CPU_CHAR *p_host_name,
533 | CPU_INT16U port,
534 | CPU_CHAR *p_username,
535 | CPU_CHAR *p_pwd,
536 | NET_APP_SOCK_SECURE_CFG *p_secure_cfg,
537 | SMTPc_ERR *p_err);
538 |
539 |
540 | void SMTPc_SendMsg (NET_SOCK_ID sock_id,
541 | SMTPc_MSG *msg,
542 | SMTPc_ERR *perr);
543 |
544 | void SMTPc_Disconnect (NET_SOCK_ID sock_id,
545 | SMTPc_ERR *perr);
546 |
547 |
548 | /* -------------------- UTIL FNCTS -------------------- */
549 | void SMTPc_SetMbox (SMTPc_MBOX *mbox,
550 | CPU_CHAR *name,
551 | CPU_CHAR *addr,
552 | SMTPc_ERR *perr);
553 |
554 | void SMTPc_SetMsg (SMTPc_MSG *msg,
555 | SMTPc_ERR *perr);
556 |
557 |
558 | /*
559 | *********************************************************************************************************
560 | * TRACING
561 | *********************************************************************************************************
562 | */
563 | /* Trace level, default to TRACE_LEVEL_OFF */
564 | #ifndef TRACE_LEVEL_OFF
565 | #define TRACE_LEVEL_OFF 0
566 | #endif
567 |
568 | #ifndef TRACE_LEVEL_INFO
569 | #define TRACE_LEVEL_INFO 1
570 | #endif
571 |
572 | #ifndef TRACE_LEVEL_DBG
573 | #define TRACE_LEVEL_DBG 2
574 | #endif
575 |
576 | #ifndef SMTPc_TRACE_LEVEL
577 | #define SMTPc_TRACE_LEVEL TRACE_LEVEL_OFF
578 | #endif
579 |
580 | #ifndef SMTPc_TRACE
581 | #define SMTPc_TRACE printf
582 | #endif
583 |
584 | #if ((defined(SMTPc_TRACE)) && \
585 | (defined(SMTPc_TRACE_LEVEL)) && \
586 | (SMTPc_TRACE_LEVEL >= TRACE_LEVEL_INFO) )
587 |
588 | #if (SMTPc_TRACE_LEVEL >= TRACE_LEVEL_DBG)
589 | #define SMTPc_TRACE_DBG(msg) SMTPc_TRACE msg
590 | #else
591 | #define SMTPc_TRACE_DBG(msg)
592 | #endif
593 |
594 | #define SMTPc_TRACE_INFO(msg) SMTPc_TRACE msg
595 |
596 | #else
597 | #define SMTPc_TRACE_DBG(msg)
598 | #define SMTPc_TRACE_INFO(msg)
599 | #endif
600 |
601 |
602 | /*
603 | *********************************************************************************************************
604 | * CONFIGURATION ERRORS
605 | *********************************************************************************************************
606 | */
607 |
608 | #ifndef SMTPc_CFG_IPPORT
609 | #error "SMTPc_CFG_IPPORT not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
610 | #endif
611 |
612 |
613 | #ifndef SMTPc_CFG_IPPORT_SECURE
614 | #error "SMTPc_CFG_IPPORT_SECURE not #define'd in 'smtp-c_cfg.h'see template file in package named 'smtp-c_cfg.h'"
615 | #endif
616 |
617 |
618 | #ifndef SMTPc_CFG_MAX_CONN_REQ_TIMEOUT_MS
619 | #error "SMTPc_CFG_MAX_CONN_REQ_TIMEOUT_MS not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
620 | #endif
621 |
622 |
623 | #ifndef SMTPc_CFG_MAX_CONN_CLOSE_TIMEOUT_MS
624 | #error "SMTPc_CFG_MAX_CONN_CLSOE_TIMEOUT_MS not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
625 | #endif
626 |
627 |
628 | #ifndef SMTPc_CFG_AUTH_EN
629 | #error "SMTPc_CFG_AUTH_EN not #define'd in 'smtp-c_cfg.h [MUST be DEF_DISABLED || DEF_ENABLED]"
630 | #elif ((SMTPc_CFG_AUTH_EN != DEF_DISABLED) && \
631 | (SMTPc_CFG_AUTH_EN != DEF_ENABLED ))
632 | #error "SMTPc_CFG_AUTH_EN illegally #define'd in 'smtp-c_cfg.h' [MUST be DEF_DISABLED || DEF_ENABLED]"
633 | #endif
634 |
635 |
636 | #ifndef SMTPc_CFG_USERNAME_MAX_LEN
637 | #error "SMTPc_CFG_USERNAME_MAX_LEN not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
638 | #elif ((SMTPc_CFG_USERNAME_MAX_LEN < 0) || \
639 | (SMTPc_CFG_USERNAME_MAX_LEN > DEF_INT_08U_MAX_VAL))
640 | #error "SMTPc_CFG_USERNAME_MAX_LEN illegally #define'd in 'smtp-c_cfg.h'[MUST be >= 0 && <= 255]"
641 | #endif
642 |
643 |
644 | #ifndef SMTPc_CFG_PW_MAX_LEN
645 | #error "SMTPc_CFG_PW_MAX_LEN not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
646 | #elif ((SMTPc_CFG_PW_MAX_LEN < 0) || \
647 | (SMTPc_CFG_PW_MAX_LEN > DEF_INT_08U_MAX_VAL))
648 | #error "SMTPc_CFG_PW_MAX_LEN illegally #define'd in 'smtp-c_cfg.h' [MUST be >= 0 && <= 255]"
649 | #endif
650 |
651 |
652 |
653 | #ifndef SMTPc_CFG_MBOX_NAME_DISP_LEN
654 | #error "SMTPc_CFG_MBOX_NAME_DISP_LEN not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
655 | #elif ((SMTPc_CFG_MBOX_NAME_DISP_LEN < 0) || \
656 | (SMTPc_CFG_MBOX_NAME_DISP_LEN > DEF_INT_08U_MAX_VAL))
657 | #error "SMTPc_CFG_MBOX_NAME_DISP_LEN illegally #define'd in 'smtp-c_cfg.h' [MUST be >= 0 && <= 255]"
658 | #endif
659 |
660 |
661 | #ifndef SMTPc_CFG_MSG_SUBJECT_LEN
662 | #error "SMTPc_CFG_MSG_SUBJECT_LEN not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
663 | #elif ((SMTPc_CFG_MSG_SUBJECT_LEN < 0) || \
664 | (SMTPc_CFG_MSG_SUBJECT_LEN > DEF_INT_08U_MAX_VAL))
665 | #error "SMTPc_CFG_MSG_SUBJECT_LEN illegally #define'd in 'smtp-c_cfg.h' [MUST be >= 0 && <= 255]"
666 | #endif
667 |
668 |
669 | #ifndef SMTPc_CFG_MSG_MAX_TO
670 | #error "SMTPc_CFG_MSG_MAX_TO not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
671 | #elif ((SMTPc_CFG_MSG_MAX_TO < 0) || \
672 | (SMTPc_CFG_MSG_MAX_TO > DEF_INT_08U_MAX_VAL))
673 | #error "SMTPc_CFG_MSG_MAX_TO illegally #define'd in 'smtp-c_cfg.h' [MUST be >= 0 && <= 255]"
674 | #endif
675 |
676 |
677 | #ifndef SMTPc_CFG_MSG_MAX_CC
678 | #error "SMTPc_CFG_MSG_MAX_CC not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
679 | #elif ((SMTPc_CFG_MSG_MAX_CC < 0) || \
680 | (SMTPc_CFG_MSG_MAX_CC > DEF_INT_08U_MAX_VAL))
681 | #error "SMTPc_CFG_MSG_MAX_CC illegally #define'd in 'smtp-c_cfg.h' [MUST be >= 0 && <= 255]"
682 | #endif
683 |
684 |
685 | #ifndef SMTPc_CFG_MSG_MAX_BCC
686 | #error "SMTPc_CFG_MSG_MAX_BCC not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
687 | #elif ((SMTPc_CFG_MSG_MAX_BCC < 0) || \
688 | (SMTPc_CFG_MSG_MAX_BCC > DEF_INT_08U_MAX_VAL))
689 | #error "SMTPc_CFG_MSG_MAX_BCC illegally #define'd in 'smtp-c_cfg.h' [MUST be >= 0 && <= 255]"
690 | #endif
691 |
692 |
693 | #ifndef SMTPc_CFG_MSG_MAX_ATTACH
694 | #error "SMTPc_CFG_MSG_MAX_ATTACH not #define'd in 'smtp-c_cfg.h' see template file in package named 'smtp-c_cfg.h'"
695 | #elif ((SMTPc_CFG_MSG_MAX_ATTACH < 0) || \
696 | (SMTPc_CFG_MSG_MAX_ATTACH > DEF_INT_08U_MAX_VAL))
697 | #error "SMTPc_CFG_MSG_MAX_ATTACH illegally #define'd in 'smtp-c_cfg.h' [MUST be >= 0 && <= 255]"
698 | #endif
699 |
700 |
701 | /*
702 | *********************************************************************************************************
703 | * MODULE END
704 | *********************************************************************************************************
705 | */
706 |
707 | #endif /* End of SMTPc module include. */
708 |
709 |
--------------------------------------------------------------------------------
/Source/smtp-c.c:
--------------------------------------------------------------------------------
1 | /*
2 | *********************************************************************************************************
3 | * uC/SMTPc
4 | * Simple Mail Transfer Protocol (client)
5 | *
6 | * Copyright 2004-2021 Silicon Laboratories Inc. www.silabs.com
7 | *
8 | * SPDX-License-Identifier: APACHE-2.0
9 | *
10 | * This software is subject to an open source license and is distributed by
11 | * Silicon Laboratories Inc. pursuant to the terms of the Apache License,
12 | * Version 2.0 available at www.apache.org/licenses/LICENSE-2.0.
13 | *
14 | *********************************************************************************************************
15 | */
16 |
17 | /*
18 | *********************************************************************************************************
19 | *
20 | * SMTP CLIENT
21 | *
22 | * Filename : smtp-c.c
23 | * Version : V2.01.01
24 | *********************************************************************************************************
25 | * Note(s) : (1) This code implements a subset of the SMTP protocol (RFC 2821). More precisely, the
26 | * following commands have been implemented:
27 | *
28 | * HELO
29 | * AUTH (if enabled)
30 | * MAIL
31 | * RCPT
32 | * DATA
33 | * RSET
34 | * NOOP
35 | * QUIT
36 | *********************************************************************************************************
37 | */
38 |
39 | /*
40 | *********************************************************************************************************
41 | * INCLUDE FILES
42 | *********************************************************************************************************
43 | */
44 |
45 | #define MICRIUM_SOURCE
46 | #define SMTPc_MODULE
47 | #include "smtp-c.h"
48 |
49 |
50 | /*
51 | *********************************************************************************************************
52 | * LOCAL DEFINES
53 | *********************************************************************************************************
54 | */
55 |
56 |
57 | /*
58 | *********************************************************************************************************
59 | * LOCAL CONSTANTS
60 | *********************************************************************************************************
61 | */
62 |
63 |
64 | /*
65 | *********************************************************************************************************
66 | * LOCAL DATA TYPES
67 | *********************************************************************************************************
68 | */
69 |
70 |
71 | /*
72 | *********************************************************************************************************
73 | * LOCAL TABLES
74 | *********************************************************************************************************
75 | */
76 |
77 |
78 | /*
79 | *********************************************************************************************************
80 | * LOCAL DATA TYPES
81 | *********************************************************************************************************
82 | */
83 |
84 |
85 | /*
86 | *********************************************************************************************************
87 | * LOCAL GLOBAL VARIABLES
88 | *********************************************************************************************************
89 | */
90 |
91 |
92 | /*
93 | *********************************************************************************************************
94 | * FUNCTION PROTOTYPES
95 | *********************************************************************************************************
96 | */
97 |
98 | /* --------------------- RX FNCT'S -------------------- */
99 | static CPU_CHAR *SMTPc_RxReply (NET_SOCK_ID sock_id,
100 | SMTPc_ERR *perr);
101 |
102 | static void SMTPc_ParseReply (CPU_CHAR *server_reply,
103 | CPU_INT32U *completion_code,
104 | SMTPc_ERR *perr);
105 |
106 | /* --------------------- TX FNCT'S -------------------- */
107 | static void SMTPc_SendBody (NET_SOCK_ID sock_id,
108 | SMTPc_MSG *msg,
109 | SMTPc_ERR *perr);
110 |
111 | static void SMTPc_QueryServer (NET_SOCK_ID sock_id,
112 | CPU_CHAR *query,
113 | CPU_INT32U len,
114 | SMTPc_ERR *perr);
115 |
116 | /* ------------------- UTIL FNCT'S ------------------- */
117 | static CPU_INT32U SMTPc_BuildHdr (NET_SOCK_ID sock_id,
118 | CPU_CHAR *buf,
119 | CPU_INT32U buf_size,
120 | CPU_INT32U buf_wr_ix,
121 | CPU_CHAR *hdr,
122 | CPU_CHAR *val,
123 | CPU_INT32U *line_len,
124 | SMTPc_ERR *perr);
125 |
126 | /* -------------------- CMD FNCT'S ------------------- */
127 | static CPU_CHAR *SMTPc_HELO (NET_SOCK_ID sock_id,
128 | CPU_INT32U *completion_code,
129 | SMTPc_ERR *perr);
130 |
131 | #if (SMTPc_CFG_AUTH_EN == DEF_ENABLED)
132 | static CPU_CHAR *SMTPc_AUTH (NET_SOCK_ID sock_id,
133 | CPU_CHAR *username,
134 | CPU_CHAR *pw,
135 | CPU_INT32U *completion_code,
136 | SMTPc_ERR *perr);
137 | #endif
138 |
139 | static CPU_CHAR *SMTPc_MAIL (NET_SOCK_ID sock_id,
140 | CPU_CHAR *from,
141 | CPU_INT32U *completion_code,
142 | SMTPc_ERR *perr);
143 |
144 | static CPU_CHAR *SMTPc_RCPT (NET_SOCK_ID sock_id,
145 | CPU_CHAR *to,
146 | CPU_INT32U *completion_code,
147 | SMTPc_ERR *perr);
148 |
149 | static CPU_CHAR *SMTPc_DATA (NET_SOCK_ID sock_id,
150 | CPU_INT32U *completion_code,
151 | SMTPc_ERR *perr);
152 |
153 | static CPU_CHAR *SMTPc_RSET (NET_SOCK_ID sock_id,
154 | CPU_INT32U *completion_code,
155 | SMTPc_ERR *perr);
156 |
157 | static CPU_CHAR *SMTPc_QUIT (NET_SOCK_ID sock_id,
158 | CPU_INT32U *completion_code,
159 | SMTPc_ERR *perr);
160 |
161 |
162 | /*
163 | *********************************************************************************************************
164 | * SMTPc_Connect()
165 | *
166 | * Description : (1) Establish a TCP connection to the SMTP server and initiate the SMTP session.
167 | *
168 | * (a) Determine port
169 | * (b) Open the socket
170 | * (c) Receive server's reply & validate
171 | * (d) Initiate SMTP session
172 | * (e) Authenticate client, if applicable
173 | *
174 | *
175 | * Argument(s) : p_host_name Pointer to host name of the SMTP server to contact. Can be also an IP address.
176 | *
177 | * port TCP port to use, or '0' if SMTPc_DFLT_PORT.
178 | *
179 | * p_username Pointer to user name, if authentication enabled.
180 | *
181 | * p_pwd Pointer to password, if authentication enabled.
182 | *
183 | * p_secure_cfg Pointer to the secure configuration (TLS/SSL):
184 | *
185 | * DEF_NULL, if no security enabled.
186 | * Pointer to a structure that contains the parameters.
187 | *
188 | * p_err Pointer to variable that will hold the return error code from this
189 | * function :
190 | *
191 | * SMTPc_ERR_NONE No error, TCP connection established.
192 | * SMTPc_ERR_NULL_ARG Argument 'username'/'pw' passed a NULL pointer.
193 | * SMTPc_ERR_SOCK_OPEN_FAILED Error opening socket.
194 | * SMTPc_ERR_SOCK_CONN_FAILED Error connecting to server.
195 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
196 | * SMTPc_ERR_REP Error with reply.
197 | * SMTPc_ERR_SECURE_NOT_AVAIL No secure mode available.
198 | *
199 | * -------- RETURNED BY SMTPc_AUTH : --------
200 | * SMTPc_ERR_ENCODE Error encoding credentials.
201 | * SMTPc_ERR_AUTH_FAILED Error authenticating user.
202 | *
203 | *
204 | * Return(s) : Socket descriptor/handle identifier, if NO error.
205 | *
206 | * -1, otherwise.
207 | *
208 | * Caller(s) : Application.
209 | *
210 | * Note(s) : (2) Network security manager MUST be available & enabled to initialize the server in
211 | * secure mode.
212 | *
213 | * (3) If anything goes wrong while trying to connect to the server, the socket is
214 | * closed by calling NetSock_Close. Hence, all data structures are returned to
215 | * their original state in case of a failure to establish the TCP connection.
216 | *
217 | * If the failure occurs when initiating the session, the application is responsible
218 | * of the appropriate action(s) to be taken.
219 | *
220 | * (4) If authentication is disabled (SMTPc_CFG_AUTH_EN set to DEF_ENABLED), the 'p_username'
221 | * and 'p_pwd' parameters should be passed a NULL pointer.
222 | *
223 | * (5) The server will send a 220 "Service ready" reply when the connection is completed.
224 | * The SMTP protocol allows a server to formally reject a transaction while still
225 | * allowing the initial connection by responding with a 554 "Transaction failed"
226 | * reply.
227 | *
228 | * (6) The Plain-text (PLAIN) authentication mechanism is implemented here. However, it
229 | * takes some liberties from RFC #4964, section 4 'The AUTH Command', stating the "A
230 | * server implementation MUST implement a configuration in which it does not permit
231 | * any plaintext password mechanisms, unless either the STARTTLS command has been
232 | * negotiated or some other mechanism that protects the session from password snooping
233 | * has been provided".
234 | *
235 | * Since this client does not support SSL or TLS, or any other protection against
236 | * password snooping, it relies on the server NOT to fully follow RFC #4954 in order
237 | * to be successful.
238 | *********************************************************************************************************
239 | */
240 |
241 | NET_SOCK_ID SMTPc_Connect (CPU_CHAR *p_host_name,
242 | CPU_INT16U port,
243 | CPU_CHAR *p_username,
244 | CPU_CHAR *p_pwd,
245 | NET_APP_SOCK_SECURE_CFG *p_secure_cfg,
246 | SMTPc_ERR *p_err)
247 | {
248 | NET_SOCK_ID sock_id;
249 | CPU_INT32U completion_code;
250 | CPU_CHAR *reply;
251 | NET_ERR err_net;
252 | NET_SOCK_ADDR socket_addr;
253 | CPU_INT16U port_server;
254 |
255 | /* ------------------ VALIDATE PTR -------------------- */
256 | #if (SMTPc_CFG_ARG_CHK_EXT_EN == DEF_ENABLED)
257 | #if (SMTPc_CFG_AUTH_EN == DEF_ENABLED)
258 | if ((p_username == (CPU_CHAR *)0) ||
259 | (p_pwd == (CPU_CHAR *)0)) {
260 | *p_err = SMTPc_ERR_NULL_ARG;
261 | return (NET_SOCK_ID_NONE);
262 | }
263 | #else
264 | (void)&p_username; /* Prevent 'variable unused' compiler warnings. */
265 | (void)&p_pwd;
266 | #endif
267 |
268 | #ifndef NET_SECURE_MODULE_EN /* See Note #2. */
269 | if (p_secure_cfg != DEF_NULL) {
270 | *p_err = SMTPc_ERR_SECURE_NOT_AVAIL;
271 | return NET_SOCK_ID_NONE;
272 | }
273 | #endif
274 |
275 | #endif
276 | /* ------------------ DETERMINE PORT ------------------ */
277 | if (port != 0) {
278 | port_server = port;
279 | } else {
280 | if (p_secure_cfg != DEF_NULL) { /* Set the port according to the secure mode cfg. */
281 | port_server = SMTPc_CFG_IPPORT_SECURE;
282 | } else {
283 | port_server = SMTPc_CFG_IPPORT;
284 | }
285 | }
286 | /* ----------------- OPEN CLIENT STREAM --------------- */
287 | NetApp_ClientStreamOpenByHostname(&sock_id,
288 | p_host_name,
289 | port_server,
290 | &socket_addr,
291 | p_secure_cfg,
292 | SMTPc_CFG_MAX_CONN_REQ_TIMEOUT_MS,
293 | &err_net);
294 | if ( err_net != NET_APP_ERR_NONE) {
295 | *p_err = SMTPc_ERR_SOCK_CONN_FAILED;
296 | return NET_SOCK_ID_NONE;
297 | }
298 | /* ---------------- CFG SOCK BLOCK OPT ---------------- */
299 | (void)NetSock_CfgBlock(sock_id, NET_SOCK_BLOCK_SEL_BLOCK, &err_net);
300 | if (err_net != NET_SOCK_ERR_NONE) {
301 | NetApp_SockClose(sock_id,
302 | SMTPc_CFG_MAX_CONN_CLOSE_TIMEOUT_MS,
303 | &err_net);
304 | *p_err = SMTPc_ERR_SOCK_CONN_FAILED;
305 | return NET_SOCK_ID_NONE;
306 | }
307 |
308 |
309 |
310 | /* ---------- RX SERVER'S RESPONSE & VALIDATE --------- */
311 | reply = SMTPc_RxReply(sock_id, p_err); /* See Note #5. */
312 | if (*p_err != SMTPc_ERR_NONE) {
313 | NetApp_SockClose(sock_id,
314 | SMTPc_CFG_MAX_CONN_CLOSE_TIMEOUT_MS,
315 | &err_net);
316 | *p_err = SMTPc_ERR_RX_FAILED;
317 | return NET_SOCK_ID_NONE;
318 | }
319 |
320 | SMTPc_ParseReply(reply, &completion_code, p_err);
321 | switch (*p_err) {
322 | case SMTPc_ERR_REP_POS: /* If any pos rep... */
323 | *p_err = SMTPc_ERR_NONE; /* ... no err. */
324 | break;
325 |
326 | case SMTPc_ERR_REP_INTER:
327 | case SMTPc_ERR_REP_NEG:
328 | case SMTPc_ERR_REP_TOO_SHORT:
329 | default:
330 | NetApp_SockClose(sock_id,
331 | SMTPc_CFG_MAX_CONN_CLOSE_TIMEOUT_MS,
332 | &err_net);
333 | *p_err = SMTPc_ERR_REP;
334 | return NET_SOCK_ID_NONE;
335 | }
336 | /* -------------- INITIATE SMTP SESSION --------------- */
337 | reply = SMTPc_HELO(sock_id, &completion_code, p_err);
338 | if (*p_err != SMTPc_ERR_NONE) {
339 | SMTPc_Disconnect(sock_id, p_err);
340 | return NET_SOCK_ID_NONE;;
341 | }
342 |
343 | /* -------------------- AUTH CLIENT ------------------- */
344 | /* See Note #6. */
345 | #if (SMTPc_CFG_AUTH_EN == DEF_ENABLED)
346 | SMTPc_AUTH((NET_SOCK_ID ) sock_id,
347 | (CPU_CHAR *) p_username,
348 | (CPU_CHAR *) p_pwd,
349 | (CPU_INT32U *)&completion_code,
350 | (SMTPc_ERR *) p_err);
351 | if (*p_err != SMTPc_ERR_NONE) {
352 | SMTPc_Disconnect(sock_id, p_err);
353 | return NET_SOCK_ID_NONE;;
354 | }
355 | #endif
356 |
357 | return (sock_id);
358 | }
359 |
360 |
361 | /*
362 | *********************************************************************************************************
363 | * SMTPc_SendMsg()
364 | *
365 | * Description : (1) Send a message (an instance of the SMTPc_MSG structure) to the SMTP server.
366 | *
367 | * (a) Invoke the MAIL command
368 | * (b) Invoke the RCPT command for every recipient
369 | * (c) Invoke the DATA command
370 | * (d) Build and send the actual data
371 | *
372 | *
373 | * Argument(s) : sock_id Socket ID.
374 | * p_msg SMTPc_MSG structure encapsulating the message to send.
375 | * p_err Pointer to variable that will hold the return error code from this
376 | * function :
377 | *
378 | * SMTPc_ERR_NONE No error.
379 | * SMTPc_ERR_NULL_ARG Argument 'p_msg' passed a NULL pointer.
380 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
381 | * SMTPc_ERR_REP Error with reply.
382 | *
383 | * ------- RETURNED BY SMTPc_MAIL() : -------
384 | * ------- RETURNED BY SMTPc_RCPT() : -------
385 | * ------- RETURNED BY SMTPc_DATA() : -------
386 | * SMTPc_ERR_TX_FAILED Error querying server.
387 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
388 | * SMTPc_ERR_REP Error with reply.
389 | *
390 | * ----- RETURNED BY SMTPc_SendBody() : -----
391 | * SMTPc_ERR_TX_FAILED Error querying server.
392 | * SMTPc_ERR_LINE_TOO_LONG Line limit exceeded.
393 | *
394 | * Return(s) : none.
395 | *
396 | * Caller(s) : Application.
397 | *
398 | * Note(s) : (2) The function SMTPc_SetMsg has to be called before being able to send a message.
399 | *
400 | * (3) The message has to have at least one receiver, either "To", "CC", or "BCC".
401 | *********************************************************************************************************
402 | */
403 |
404 | void SMTPc_SendMsg (NET_SOCK_ID sock_id,
405 | SMTPc_MSG *p_msg,
406 | SMTPc_ERR *p_err)
407 | {
408 | CPU_INT08U i;
409 | CPU_INT32U completion_code;
410 |
411 |
412 | /* See Note #2. */
413 | if (p_msg->From == (SMTPc_MBOX *)0) {
414 | SMTPc_TRACE_DBG(("Error SMTPc_SendMsg. NULL from parameter\n\r"));
415 | *p_err = SMTPc_ERR_NULL_ARG;
416 | return;
417 | }
418 |
419 | /* See Note #3. */
420 | if ((p_msg->ToArray[0] == (SMTPc_MBOX *)0) &&
421 | (p_msg->CCArray[0] == (SMTPc_MBOX *)0) &&
422 | (p_msg->BCCArray[0] == (SMTPc_MBOX *)0)) {
423 | SMTPc_TRACE_DBG(("Error SMTPc_SendMsg. NULL parameter(s)\n\r"));
424 | *p_err = SMTPc_ERR_NULL_ARG;
425 | return;
426 | }
427 |
428 | /* --------------- INVOKE THE MAIL CMD ---------------- */
429 | SMTPc_MAIL(sock_id, p_msg->From->Addr, &completion_code, p_err);
430 | if (*p_err != SMTPc_ERR_NONE) {
431 | SMTPc_TRACE_DBG(("Error MAIL. Code: %u\n\r", (unsigned int)completion_code));
432 | if ((completion_code != SMTPc_REP_421) &&
433 | (completion_code != SMTPc_REP_221)) {
434 | SMTPc_RSET(sock_id, &completion_code, p_err);
435 | }
436 | return;
437 | }
438 |
439 | /* --------------- INVOKE THE RCTP CMD ---------------- */
440 | /* The RCPT cmd is tx'd for every recipient, */
441 | /* including CCs & BCCs. */
442 | for (i = 0; i < SMTPc_CFG_MSG_MAX_TO; i++) {
443 | if (p_msg->ToArray[i] == (SMTPc_MBOX *)0) {
444 | break;
445 | }
446 |
447 | SMTPc_RCPT(sock_id, p_msg->ToArray[i]->Addr, &completion_code, p_err);
448 | if (*p_err != SMTPc_ERR_NONE) {
449 | SMTPc_TRACE_DBG(("Error RCPT (TO %u). Code: %u\n\r", (unsigned int)i, (unsigned int)completion_code));
450 | SMTPc_RSET(sock_id, &completion_code, p_err); /* RSET p_msg if invalid RCPT fails. */
451 | return;
452 | }
453 | }
454 |
455 | /* CCs */
456 | for (i = 0; i < SMTPc_CFG_MSG_MAX_CC; i++) {
457 | if (p_msg->CCArray[i] == (SMTPc_MBOX *)0) {
458 | break;
459 | }
460 | SMTPc_RCPT(sock_id, p_msg->CCArray[i]->Addr, &completion_code, p_err);
461 | if (*p_err != SMTPc_ERR_NONE) {
462 | SMTPc_TRACE_DBG(("Error RCPT (CC %u). Code: %u\n\r", (unsigned int)i, (unsigned int)completion_code));
463 | if ((completion_code != SMTPc_REP_421) &&
464 | (completion_code != SMTPc_REP_221)) {
465 | SMTPc_RSET(sock_id, &completion_code, p_err); /* RSET p_msg if invalid RCPT fails. */
466 | }
467 | return;
468 | }
469 | }
470 |
471 | /* BCCs */
472 | for (i = 0; i < SMTPc_CFG_MSG_MAX_BCC; i++) {
473 | if (p_msg->BCCArray[i] == (SMTPc_MBOX *)0) {
474 | break;
475 | }
476 |
477 | SMTPc_RCPT(sock_id, p_msg->BCCArray[i]->Addr, &completion_code, p_err);
478 | if (*p_err != SMTPc_ERR_NONE) {
479 | SMTPc_TRACE_DBG(("Error RCPT (BCC %u). Code: %u\n\r", (unsigned int)i, (unsigned int)completion_code));
480 | if ((completion_code != SMTPc_REP_421) && /* RSET p_msg if invalid RCPT fails. */
481 | (completion_code != SMTPc_REP_221)) {
482 | SMTPc_RSET(sock_id, &completion_code, p_err);
483 | }
484 | return;
485 | }
486 | }
487 |
488 | /* --------------- INVOKE THE DATA CMD ---------------- */
489 | SMTPc_DATA(sock_id, &completion_code, p_err);
490 | if (*p_err != SMTPc_ERR_NONE) {
491 | SMTPc_TRACE_DBG(("Error DATA. Code: %u\n\r", (unsigned int)completion_code));
492 | if ((completion_code != SMTPc_REP_421) &&
493 | (completion_code != SMTPc_REP_221)) {
494 | SMTPc_RSET(sock_id, &completion_code, p_err);
495 | }
496 | return;
497 | }
498 |
499 | /* ----------- BUILD & SEND THE ACTUAL MSG ------------ */
500 | SMTPc_SendBody(sock_id, p_msg, p_err);
501 | if (*p_err != SMTPc_ERR_NONE) {
502 | SMTPc_TRACE_DBG(("Error SMTPc_SendBody. Error: %u\n\r", (unsigned int)*p_err));
503 | }
504 | }
505 |
506 |
507 | /*
508 | *********************************************************************************************************
509 | * SMTPc_Disconnect()
510 | *
511 | * Description : (1) Close the connection between client and server.
512 | *
513 | * (a) Send QUIT command
514 | * (b) Close socket
515 | *
516 | *
517 | * Argument(s) : sock_id Socket ID.
518 | * p_err Pointer to variable that will hold the return error code from this
519 | * function :
520 | *
521 | * SMTPc_ERR_NONE No error.
522 | *
523 | * Return(s) : none.
524 | *
525 | * Caller(s) : Application,
526 | * SMTPc_Connect().
527 | *
528 | * Note(s) : (2) The receiver (client) MUST NOT intentionally close the transmission channel until
529 | * it receives and replies to a QUIT command.
530 | *
531 | * (3) The receiver of the QUIT command MUST send an OK reply, and then close the
532 | * transmission channel.
533 | *********************************************************************************************************
534 | */
535 |
536 | void SMTPc_Disconnect (NET_SOCK_ID sock_id,
537 | SMTPc_ERR *p_err)
538 | {
539 | CPU_INT32U completion_code;
540 | NET_ERR err;
541 |
542 |
543 | SMTPc_QUIT(sock_id, &completion_code, p_err);
544 |
545 | NetApp_SockClose(sock_id,
546 | SMTPc_CFG_MAX_CONN_CLOSE_TIMEOUT_MS,
547 | &err);
548 |
549 | *p_err = SMTPc_ERR_NONE;
550 | }
551 |
552 |
553 | /*
554 | *********************************************************************************************************
555 | * SMTPc_SetMbox()
556 | *
557 | * Description : (1) Populates a SMTPc_MBOX structure with associated name and address.
558 | *
559 | * (a) Perform error checking.
560 | * (b) Copy arguments in structure.
561 | *
562 | *
563 | * Argument(s) : p_mbox SMTPc_MBOX structure to be populated.
564 | * p_name Name of the mailbox owner.
565 | * p_addr Address associated with the mailbox.
566 | * p_err Pointer to variable that will hold the return error code from this
567 | * function :
568 | *
569 | * SMTPc_ERR_NONE No error, structure ready.
570 | * SMTPc_ERR_NULL_ARG Argument 'mbox'/'name' passed a NULL pointer.
571 | * SMTPc_ERR_STR_TOO_LONG Argument addr too long.
572 | *
573 | * Return(s) : none.
574 | *
575 | * Caller(s) : Application.
576 | *
577 | * Note(s) : (2) The name of the mailbox owner is not mandatory. Passing NULL will result in an
578 | * empty string being copied in the structure.
579 | *********************************************************************************************************
580 | */
581 |
582 | void SMTPc_SetMbox (SMTPc_MBOX *p_mbox,
583 | CPU_CHAR *p_name,
584 | CPU_CHAR *p_addr,
585 | SMTPc_ERR *p_err)
586 | {
587 | CPU_SIZE_T len;
588 |
589 |
590 | if ((p_mbox == (SMTPc_MBOX *)0) ||
591 | (p_addr == (CPU_CHAR *)0)) {
592 | *p_err = SMTPc_ERR_NULL_ARG;
593 | return;
594 | }
595 |
596 | len = Str_Len(p_addr);
597 | if (len >= SMTPc_MBOX_ADDR_LEN) {
598 | *p_err = SMTPc_ERR_STR_TOO_LONG;
599 | return;
600 | } else {
601 | Str_Copy(p_mbox->Addr, p_addr);
602 | }
603 |
604 | if (p_name == (CPU_CHAR *)0) { /* See Note #2. */
605 | Str_Copy((CPU_CHAR *)p_mbox->NameDisp,
606 | (CPU_CHAR *)"");
607 | } else {
608 | len = Str_Len(p_name);
609 | if (len >= SMTPc_CFG_MBOX_NAME_DISP_LEN) {
610 | *p_err = SMTPc_ERR_STR_TOO_LONG;
611 | return;
612 | } else {
613 | Str_Copy(p_mbox->NameDisp, p_name);
614 | }
615 | }
616 |
617 | *p_err = SMTPc_ERR_NONE;
618 | }
619 |
620 |
621 | /*
622 | *********************************************************************************************************
623 | * SMTPc_SetMsg()
624 | *
625 | * Description : Sets the various fields of a SMTPc_MSG structure so that it is valid and usable.
626 | *
627 | * Argument(s) : p_msg SMTPc_MSG structure to be initialized.
628 | * p_err Pointer to variable that will hold the return error code from this
629 | * function :
630 | *
631 | * SMTPc_ERR_NONE No error, structure ready.
632 | * SMTPc_ERR_NULL_ARG Argument 'p_msg'/'from' passed a NULL pointer.
633 | *
634 | * Return(s) : none.
635 | *
636 | * Caller(s) : Application.
637 | *
638 | * Note(s) : (1) This function MUST be called after declaring a SMTPc_MSG structure and BEFORE beginning
639 | * to manipulate it. Failure to do so will likely produce run-time errors.
640 | *
641 | * (2) The SMTPc_MSG structure member 'MIMEMsgHdrStruct' is left uninitialized for now,
642 | * MIME extensions not being supported in this version.
643 | *********************************************************************************************************
644 | */
645 |
646 | void SMTPc_SetMsg (SMTPc_MSG *p_msg,
647 | SMTPc_ERR *p_err)
648 | {
649 | CPU_INT08U i;
650 |
651 |
652 | if (p_msg == (SMTPc_MSG *)0) {
653 | *p_err = SMTPc_ERR_NULL_ARG;
654 | return;
655 | }
656 |
657 | p_msg->From = (SMTPc_MBOX *)0;
658 | p_msg->Sender = (SMTPc_MBOX *)0;
659 |
660 | /* Set ptr's to NULL or 0 */
661 | for (i = 0; i < SMTPc_CFG_MSG_MAX_TO; i++) {
662 | p_msg->ToArray[i] = (SMTPc_MBOX *)0;
663 | }
664 |
665 | for (i = 0; i < SMTPc_CFG_MSG_MAX_CC; i++) {
666 | p_msg->CCArray[i] = (SMTPc_MBOX *)0;
667 | }
668 |
669 | for (i = 0; i < SMTPc_CFG_MSG_MAX_BCC; i++) {
670 | p_msg->BCCArray[i] = (SMTPc_MBOX *)0;
671 | }
672 |
673 | for (i = 0; i < SMTPc_CFG_MSG_MAX_ATTACH; i++) {
674 | p_msg->AttachArray[i] = (SMTPc_ATTACH *)0;
675 | }
676 |
677 | p_msg->ReplyTo = (SMTPc_MBOX *)0;
678 | p_msg->ContentBodyMsg = (CPU_CHAR *)0;
679 | p_msg->ContentBodyMsgLen = 0;
680 | p_msg->Subject = DEF_NULL;
681 | /* Clr CPU_CHAR arrays */
682 | Mem_Clr((void *)p_msg->MsgID,
683 | (CPU_SIZE_T)SMTPc_MIME_ID_LEN);
684 |
685 | SMTPc_TRACE_DBG(("SMTPc_SetMsg() success\n\r"));
686 |
687 |
688 | *p_err = SMTPc_ERR_NONE;
689 | }
690 |
691 |
692 | /*
693 | *********************************************************************************************************
694 | * SMTPc_SendMail()
695 | *
696 | * Description : Send an email.
697 | *
698 | * Argument(s) : p_host_name Pointer to host name of the SMTP server to contact. Can be also an IP address.
699 | *
700 | * port TCP port to use, or '0' if SMTPc_DFLT_PORT.
701 | *
702 | * p_username Pointer to user name, if authentication enabled.
703 | *
704 | * p_pwd Pointer to password, if authentication enabled.
705 | *
706 | * p_secure_cfg Pointer to the secure configuration (TLS/SSL):
707 | *
708 | * DEF_NULL, if no security enabled.
709 | * Pointer to a structure that contains the parameters.
710 | *
711 | * p_msg SMTPc_MSG structure encapsulating the message to send.
712 | *
713 | * p_err Pointer to variable that will hold the return error from this
714 | * function:
715 | *
716 | * SMTPc_ERR_NONE No error, TCP connection established.
717 | * SMTPc_ERR_INVALID_ADDR Argument server_addr_ascii and/or client_addr_ascii invalid
718 | *
719 | * ------ RETURNED BY SMTPc_Connect : ------
720 | * SMTPc_ERR_NULL_ARG Argument 'username'/'pw' passed a NULL pointer.
721 | * SMTPc_ERR_SOCK_OPEN_FAILED Error opening socket.
722 | * SMTPc_ERR_SOCK_CONN_FAILED Error connecting to server.
723 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
724 | * SMTPc_ERR_REP Error with reply.
725 | * SMTPc_ERR_SECURE_NOT_AVAIL No secure mode available.
726 | * SMTPc_ERR_ENCODE Error encoding credentials.
727 | * SMTPc_ERR_AUTH_FAILED Error authenticating user.
728 | *
729 | * ------- RETURNED BY SMTPc_SendMsg : ------
730 | * SMTPc_ERR_NULL_ARG Argument 'p_msg' passed a NULL pointer.
731 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
732 | * SMTPc_ERR_REP Error with reply.
733 | * SMTPc_ERR_TX_FAILED Error querying server.
734 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
735 | * SMTPc_ERR_REP Error with reply.
736 | * SMTPc_ERR_TX_FAILED Error querying server.
737 | * SMTPc_ERR_LINE_TOO_LONG Line limit exceeded.
738 | * Return(s) : none.
739 | *
740 | * Caller(s) : Application.
741 | *
742 | * Note(s) : none.
743 | *********************************************************************************************************
744 | */
745 |
746 | void SMTPc_SendMail (CPU_CHAR *p_host_name,
747 | CPU_INT16U port,
748 | CPU_CHAR *p_username,
749 | CPU_CHAR *p_pwd,
750 | NET_APP_SOCK_SECURE_CFG *p_secure_cfg,
751 | SMTPc_MSG *p_msg,
752 | SMTPc_ERR *p_err)
753 | {
754 | NET_SOCK_ID sock;
755 |
756 | /* -------------- CONNECT TO SMTP SEVER --------------- */
757 | sock = SMTPc_Connect(p_host_name,
758 | port,
759 | p_username,
760 | p_pwd,
761 | p_secure_cfg,
762 | p_err);
763 | if (*p_err != SMTPc_ERR_NONE) {
764 | return;
765 | }
766 | /* ----------------- SEND THE MESSAGE ----------------- */
767 | SMTPc_SendMsg(sock, p_msg, p_err);
768 | if (*p_err != SMTPc_ERR_NONE) {
769 | return;
770 | }
771 | /* ----------- DISCONNECT FROM SMTP SERVER ------------ */
772 | SMTPc_Disconnect(sock, p_err);
773 | }
774 |
775 |
776 | /*
777 | *********************************************************************************************************
778 | * LOCAL FUNCTIONS
779 | *********************************************************************************************************
780 | */
781 |
782 | /*
783 | *********************************************************************************************************
784 | * SMTPc_RxReply()
785 | *
786 | * Description : Receive and process reply from the SMTP server.
787 | *
788 | * Argument(s) : sock_id Socket ID.
789 | * perr Pointer to variable that will hold the return error code from this
790 | * function :
791 | *
792 | * SMTPc_ERR_NONE No error.
793 | * SMTPc_ERR_RX_FAILED Error receiving the reply.
794 | *
795 | * Return(s) : Complete reply from the server, if NO reception error.
796 | *
797 | * (CPU_CHAR *)0, otherwise.
798 | *
799 | * Caller(s) : SMTPc_Connect(),
800 | * SMTPc_SendMsg(),
801 | * SMTPc_HELO(),
802 | * SMTPc_MAIL(),
803 | * SMTPc_RCPT(),
804 | * SMTPc_DATA(),
805 | * SMTPc_RSET(),
806 | * SMTPc_QUIT().
807 | *
808 | * Note(s) : (1) Server reply is at least 3 characters long (3 digits), plus CRLF. Hence, receiving
809 | * less than that automatically indicates an error.
810 | *********************************************************************************************************
811 | */
812 |
813 | static CPU_CHAR *SMTPc_RxReply (NET_SOCK_ID sock_id,
814 | SMTPc_ERR *perr)
815 | {
816 | NET_SOCK_RTN_CODE rx_len;
817 | NET_ERR err;
818 |
819 |
820 | /* ---------------------- RX REPLY -------------------- */
821 | rx_len = NetSock_RxData(sock_id,
822 | SMTPc_Comm_Buf,
823 | SMTPc_COMM_BUF_LEN - 1,
824 | NET_SOCK_FLAG_NONE,
825 | &err);
826 |
827 | /* See Note #1. */
828 | if ((rx_len == NET_SOCK_BSD_ERR_RX) ||
829 | (rx_len <= 4 )) {
830 | *perr = SMTPc_ERR_RX_FAILED;
831 | return ((CPU_CHAR *)0);
832 | }
833 |
834 | SMTPc_Comm_Buf[rx_len] = '\0';
835 |
836 | *perr = SMTPc_ERR_NONE;
837 |
838 | return (SMTPc_Comm_Buf);
839 | }
840 |
841 |
842 | /*
843 | *********************************************************************************************************
844 | * SMTPc_ParseReply()
845 | *
846 | * Description : (1) Process reply received from the SMTP server.
847 | *
848 | * (a) Parse reply
849 | * (b) Interpret reply
850 | *
851 | *
852 | * Argument(s) : server_reply Complete reply received from the server.
853 | * completion_code Numeric value returned by server indicating command status.
854 | * perr Pointer to variable that will hold the return error code from this
855 | * function :
856 | *
857 | * SMTPc_ERR_REP_TOO_SHORT Reply not long enough.
858 | * SMTPc_ERR_REP_POS No error, positive reply received.
859 | * SMTPc_ERR_REP_INTER No error, intermediate reply received.
860 | * SMTPc_ERR_REP_NEG Negative reply received.
861 | *
862 | * Return(s) : none.
863 | *
864 | * Caller(s) : SMTPc_Connect(),
865 | * SMTPc_SendMsg(),
866 | * SMTPc_HELO(),
867 | * SMTPc_MAIL(),
868 | * SMTPc_RCPT(),
869 | * SMTPc_DATA(),
870 | * SMTPc_RSET(),
871 | * SMTPc_QUIT().
872 | *
873 | * Note(s) : none.
874 | *********************************************************************************************************
875 | */
876 |
877 | static void SMTPc_ParseReply (CPU_CHAR *server_reply,
878 | CPU_INT32U *completion_code,
879 | SMTPc_ERR *perr)
880 | {
881 | CPU_INT08U code_first_dig;
882 | CPU_INT08U len;
883 |
884 | /* -------------------- PARSE REPLY ------------------ */
885 | len = Str_Len(server_reply); /* Make sure string is at least 3 + 1 char long. */
886 | if (len < 4) {
887 | *perr = SMTPc_ERR_REP_TOO_SHORT;
888 | return;
889 | }
890 |
891 | *completion_code = Str_ParseNbr_Int32U(server_reply, DEF_NULL, 10);
892 | SMTPc_TRACE_DBG(("Code: %u\n\r", (unsigned int)*completion_code));
893 |
894 |
895 | /* ------------------ INTERPRET REPLY ----------------- */
896 | code_first_dig = *completion_code / 100;
897 | switch (code_first_dig) {
898 | case SMTPc_REP_POS_COMPLET_GRP: /* Positive reply. */
899 | *perr = SMTPc_ERR_REP_POS;
900 | break;
901 |
902 | case SMTPc_REP_POS_PRELIM_GRP: /* Intermediate reply. */
903 | case SMTPc_REP_POS_INTER_GRP:
904 | *perr = SMTPc_ERR_REP_INTER;
905 | break;
906 |
907 | case SMTPc_REP_NEG_TRANS_COMPLET_GRP: /* Negative reply. */
908 | case SMTPc_REP_NEG_COMPLET_GRP:
909 | *perr = SMTPc_ERR_REP_NEG;
910 | break;
911 |
912 | default: /* Should never happen, interpreted as negative. */
913 | *perr = SMTPc_ERR_REP_NEG;
914 | break;
915 | }
916 | }
917 |
918 |
919 | /*
920 | *********************************************************************************************************
921 | * SMTPc_QueryServer()
922 | *
923 | * Description : Send a query (or anything else) to the server.
924 | *
925 | * Argument(s) : sock_id Socket ID.
926 | * query Query in question.
927 | * len Length of message to transmit
928 | * perr Pointer to variable that will hold the return error code from this
929 | * function :
930 | *
931 | * SMTPc_ERR_NONE No error.
932 | *
933 | * ----- RETURNED BY NetSock_TxData() : -----
934 | * See uC/TCPIP source code.
935 | *
936 | * Return(s) : none.
937 | *
938 | * Caller(s) : SMTPc_SendBody(),
939 | * SMTPc_BuildHdr(),
940 | * SMTPc_HELO(),
941 | * SMTPc_MAIL(),
942 | * SMTPc_RCPT(),
943 | * SMTPc_DATA(),
944 | * SMTPc_RSET(),
945 | * SMTPc_QUIT().
946 | *
947 | * Note(s) : none.
948 | *********************************************************************************************************
949 | */
950 |
951 | static void SMTPc_QueryServer (NET_SOCK_ID sock_id,
952 | CPU_CHAR *query,
953 | CPU_INT32U len,
954 | SMTPc_ERR *perr)
955 | {
956 | NET_SOCK_RTN_CODE rtn_code;
957 | CPU_INT32U cur_pos;
958 | NET_ERR err;
959 |
960 | /* ---------------------- TX QUERY -------------------- */
961 | cur_pos = 0;
962 |
963 | do {
964 | rtn_code = NetSock_TxData( sock_id,
965 | &query[cur_pos],
966 | len,
967 | 0,
968 | &err);
969 |
970 | cur_pos = cur_pos + rtn_code;
971 | len = len - rtn_code;
972 |
973 | } while ((len != 0) && (rtn_code != NET_SOCK_BSD_ERR_TX));
974 |
975 | if (rtn_code != NET_SOCK_BSD_ERR_TX) {
976 | *perr = SMTPc_ERR_NONE;
977 | }
978 | }
979 |
980 |
981 | /*
982 | *********************************************************************************************************
983 | * SMTPc_SendBody()
984 | *
985 | * Description : (1) Prepare and send the actual data of the message, i.e. the body part of the message
986 | * content.
987 | *
988 | * (a) Built headers and transmit
989 | * (b) Transmit body content
990 | * (c) Prepare and transmit attachment(s)
991 | * (d) Transmit "end of mail data" indicator
992 | * (e) Receive the confirmation reply
993 | *
994 | *
995 | * Argument(s) : sock_id Socket ID.
996 | * msg SMTPc_MSG structure encapsulating the message to send.
997 | * perr Pointer to variable that will hold the return error code from this
998 | * function :
999 | *
1000 | * SMTPc_ERR_NONE No error.
1001 | * SMTPc_ERR_TX_FAILED Error querying server.
1002 | *
1003 | * ----- RETURNED BY SMTPc_BuildHdr() : -----
1004 | * SMTPc_ERR_NONE No error.
1005 | * SMTPc_ERR_LINE_TOO_LONG Line limit exceeded.
1006 | * SMTPc_ERR_TX_FAILED Error querying server.
1007 | *
1008 | * Return(s) : none.
1009 | *
1010 | * Caller(s) : SMTPc_SendMsg().
1011 | *
1012 | * Note(s) : (2) The current implementation does not insert the names of the mailbox owners (member
1013 | * NameDisp of structure SMTPc_MBOX).
1014 | *********************************************************************************************************
1015 | */
1016 |
1017 | static void SMTPc_SendBody (NET_SOCK_ID sock_id,
1018 | SMTPc_MSG *msg,
1019 | SMTPc_ERR *perr)
1020 | {
1021 | CPU_SIZE_T len;
1022 | CPU_INT32U cur_wr_ix;
1023 | CPU_INT08U i;
1024 | CPU_INT32U line_len;
1025 | CPU_CHAR *hdr;
1026 | CPU_CHAR *reply;
1027 | CPU_INT32U completion_code;
1028 |
1029 |
1030 | cur_wr_ix = 0;
1031 | line_len = 0;
1032 |
1033 | /* ------------------- BUILT HEADERS ------------------ */
1034 | /* Header "From: ". */
1035 | hdr = (CPU_CHAR *)SMTPc_HDR_FROM;
1036 | cur_wr_ix = SMTPc_BuildHdr( sock_id, /* Addr */
1037 | SMTPc_Comm_Buf,
1038 | SMTPc_COMM_BUF_LEN,
1039 | cur_wr_ix,
1040 | hdr,
1041 | msg->From->Addr,
1042 | &line_len,
1043 | perr);
1044 | if (*perr != SMTPc_ERR_NONE) {
1045 | return;
1046 | }
1047 |
1048 |
1049 | if (msg->Sender != (SMTPc_MBOX *)0) { /* Header "Sender: ". */
1050 | hdr = (CPU_CHAR *)SMTPc_HDR_SENDER;
1051 | cur_wr_ix = SMTPc_BuildHdr( sock_id, /* Addr */
1052 | SMTPc_Comm_Buf,
1053 | SMTPc_COMM_BUF_LEN,
1054 | cur_wr_ix,
1055 | hdr,
1056 | msg->Sender->Addr,
1057 | &line_len,
1058 | perr);
1059 | if (*perr != SMTPc_ERR_NONE) {
1060 | return;
1061 | }
1062 | }
1063 |
1064 |
1065 |
1066 | /* Header "To: ". */
1067 | hdr = (CPU_CHAR *)SMTPc_HDR_TO;
1068 | for (i = 0; (i < SMTPc_CFG_MSG_MAX_TO) && (msg->ToArray[i] != (SMTPc_MBOX *)0); i++) {
1069 | cur_wr_ix = SMTPc_BuildHdr( sock_id,
1070 | SMTPc_Comm_Buf,
1071 | SMTPc_COMM_BUF_LEN,
1072 | cur_wr_ix,
1073 | hdr,
1074 | msg->ToArray[i]->Addr,
1075 | &line_len,
1076 | perr);
1077 | if (*perr != SMTPc_ERR_NONE) {
1078 | return;
1079 | }
1080 | hdr = (CPU_CHAR *)0;
1081 | }
1082 |
1083 |
1084 | /* Header "Reply-to: ". */
1085 | hdr = (CPU_CHAR *)SMTPc_HDR_REPLYTO;
1086 | if (msg->ReplyTo != (SMTPc_MBOX *)0) {
1087 | cur_wr_ix = SMTPc_BuildHdr( sock_id,
1088 | SMTPc_Comm_Buf,
1089 | SMTPc_COMM_BUF_LEN,
1090 | cur_wr_ix,
1091 | hdr,
1092 | msg->ReplyTo->Addr,
1093 | &line_len,
1094 | perr);
1095 | if (*perr != SMTPc_ERR_NONE) {
1096 | return;
1097 | }
1098 | hdr = (CPU_CHAR *)0;
1099 | }
1100 |
1101 |
1102 | /* Header "CC: ". */
1103 | hdr = (CPU_CHAR *)SMTPc_HDR_CC;
1104 | for (i = 0; (i < SMTPc_CFG_MSG_MAX_CC) && (msg->CCArray[i] != (SMTPc_MBOX *)0); i++) {
1105 | cur_wr_ix = SMTPc_BuildHdr( sock_id,
1106 | SMTPc_Comm_Buf,
1107 | SMTPc_COMM_BUF_LEN,
1108 | cur_wr_ix,
1109 | hdr,
1110 | msg->CCArray[i]->Addr,
1111 | &line_len,
1112 | perr);
1113 | if (*perr != SMTPc_ERR_NONE) {
1114 | return;
1115 | }
1116 | hdr = (CPU_CHAR *)0;
1117 | }
1118 |
1119 |
1120 | if (msg->Subject != (CPU_CHAR *)0) { /* Header "Subject: ". */
1121 | cur_wr_ix = SMTPc_BuildHdr((NET_SOCK_ID ) sock_id,
1122 | (CPU_CHAR *) SMTPc_Comm_Buf,
1123 | (CPU_INT32U ) SMTPc_COMM_BUF_LEN,
1124 | (CPU_INT32U ) cur_wr_ix,
1125 | (CPU_CHAR *) SMTPc_HDR_SUBJECT,
1126 | (CPU_CHAR *) msg->Subject,
1127 | (CPU_INT32U *)&line_len,
1128 | (SMTPc_ERR *) perr);
1129 | if (*perr != SMTPc_ERR_NONE) {
1130 | return;
1131 | }
1132 | }
1133 | /* ----------- INSERT HEADER/BODY DELIMITER ----------- */
1134 | Mem_Copy(&SMTPc_Comm_Buf[cur_wr_ix], SMTPc_CRLF, SMTPc_CRLF_SIZE);
1135 | cur_wr_ix += SMTPc_CRLF_SIZE;
1136 |
1137 | /* ---------------- TX CONTENT HEADERS ---------------- */
1138 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, cur_wr_ix, perr);
1139 | if (*perr != SMTPc_ERR_NONE) {
1140 | *perr = SMTPc_ERR_TX_FAILED;
1141 | return;
1142 | }
1143 |
1144 |
1145 | /* ------------------ TX BODY CONTENT ----------------- */
1146 | SMTPc_QueryServer(sock_id, msg->ContentBodyMsg, msg->ContentBodyMsgLen, perr);
1147 | if (*perr != SMTPc_ERR_NONE) {
1148 | *perr = SMTPc_ERR_TX_FAILED;
1149 | return;
1150 | }
1151 |
1152 |
1153 |
1154 | /* ------------ PREPARE & TX ATTACHMENT(S) ------------ */
1155 | /* #### Not currently implemented. */
1156 |
1157 |
1158 |
1159 | /* ----------- TX END OF MAIL DATA INDICATOR ---------- */
1160 | Mem_Copy(SMTPc_Comm_Buf, SMTPc_EOM, sizeof(SMTPc_EOM));
1161 | len = Str_Len(SMTPc_Comm_Buf);
1162 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, len, perr);
1163 | if (*perr != SMTPc_ERR_NONE) {
1164 | *perr = SMTPc_ERR_TX_FAILED;
1165 | return;
1166 | }
1167 |
1168 | /* --------------- RX CONFIRMATION REPLY -------------- */
1169 | reply = SMTPc_RxReply(sock_id, perr);
1170 | if (*perr != SMTPc_ERR_NONE) {
1171 | *perr = SMTPc_ERR_RX_FAILED;
1172 | return;
1173 | }
1174 |
1175 | SMTPc_ParseReply(reply, &completion_code, perr);
1176 | switch (*perr) {
1177 | case SMTPc_ERR_REP_POS:
1178 | if (completion_code == SMTPc_REP_250) {
1179 | *perr = SMTPc_ERR_NONE;
1180 | }
1181 | break;
1182 |
1183 | default:
1184 | *perr = SMTPc_ERR_REP;
1185 | break;
1186 | }
1187 |
1188 | if (*perr != SMTPc_ERR_NONE) {
1189 | if ((completion_code != SMTPc_REP_421) &&
1190 | (completion_code != SMTPc_REP_221)) {
1191 | SMTPc_RSET(sock_id, &completion_code, perr);
1192 | }
1193 | *perr = SMTPc_ERR_REP;
1194 | }
1195 | }
1196 |
1197 |
1198 | /*
1199 | *********************************************************************************************************
1200 | * SMTPc_BuildHdr()
1201 | *
1202 | * Description : (1) Prepare (and send if necessary) the message content's headers.
1203 | *
1204 | * (a) Calculate needed space
1205 | * (b) Send data, if necessary
1206 | * (c) Build header
1207 | *
1208 | *
1209 | * Argument(s) : sock_id Socket ID.
1210 | * buf Buffer used to store the headers prior to their expedition.
1211 | * buf_size Size of buffer.
1212 | * buf_wr_ix Index of current "write" position.
1213 | * hdr Header name.
1214 | * val Value associated with header.
1215 | * line_len Current line total length.
1216 | * perr Pointer to variable that will hold the return error code from this
1217 | * function :
1218 | *
1219 | * SMTPc_ERR_NONE No error.
1220 | * SMTPc_ERR_LINE_TOO_LONG Line limit exceeded.
1221 | * SMTPc_ERR_TX_FAILED Error querying server.
1222 | *
1223 | * Return(s) : "Write" position in buffer.
1224 | *
1225 | * Caller(s) : SMTPc_SendBody().
1226 | *
1227 | * Note(s) : (2) If the parameter "hdr" is (CPU_CHAR *)0, et means that it's already been passed in a
1228 | * previous call. Hence, a "," will be inserted in the buffer prior to the value.
1229 | *
1230 | * (3) If the SMTP line limit is exceeded, perr is set to SMTPc_ERR_LINE_TOO_LONG and the
1231 | * function returns without having added the header.
1232 | *
1233 | * (4) This implementation transmit the headers buffer if the next header is too large to
1234 | * be inserted in the remaining buffer space.
1235 | *
1236 | * Note that NO EXACT calculations are performed here; a conservative approach is
1237 | * brought forward, without actually optimizing the process (i.e. a buffer could be
1238 | * sent even though a few more characters could have been inserted).
1239 | *
1240 | * (5) CRLF is inserted even though more entries are still to come for a particular header
1241 | * (line folding is performed even if unnecessary).
1242 | *********************************************************************************************************
1243 | */
1244 |
1245 | static CPU_INT32U SMTPc_BuildHdr (NET_SOCK_ID sock_id,
1246 | CPU_CHAR *buf,
1247 | CPU_INT32U buf_size,
1248 | CPU_INT32U buf_wr_ix,
1249 | CPU_CHAR *hdr,
1250 | CPU_CHAR *val,
1251 | CPU_INT32U *line_len,
1252 | SMTPc_ERR *perr)
1253 | {
1254 | CPU_INT32U hdr_len;
1255 | CPU_INT32U val_len;
1256 | CPU_INT32U total_len;
1257 |
1258 | /* ------------- CALCULATE NECESSARY SPACE ------------ */
1259 | if (hdr == (CPU_CHAR *)0) {
1260 | hdr_len = 0;
1261 | } else {
1262 | hdr_len = Str_Len(hdr);
1263 | }
1264 |
1265 | if (val == (CPU_CHAR *)0) {
1266 | val_len = 0;
1267 | } else {
1268 | val_len = Str_Len(val);
1269 | }
1270 |
1271 | total_len = hdr_len + val_len + 2;
1272 |
1273 | if ((*line_len + total_len) > SMTPc_LINE_LEN_LIM) { /* See Note #3. */
1274 | *perr = SMTPc_ERR_LINE_TOO_LONG;
1275 | return (buf_wr_ix);
1276 | }
1277 |
1278 |
1279 |
1280 | /* -------------- SEND DATA, IF NECESSARY ------------- */
1281 | /* See Note #4. */
1282 | if ((buf_size - buf_wr_ix) < total_len) {
1283 | SMTPc_QueryServer(sock_id, buf, buf_wr_ix, perr);
1284 | if (*perr != SMTPc_ERR_NONE) {
1285 | *perr = SMTPc_ERR_TX_FAILED;
1286 | return buf_wr_ix;
1287 | }
1288 | buf_wr_ix = 0;
1289 | }
1290 |
1291 |
1292 | /* ------------------ BUILDING HEADER ----------------- */
1293 | if (hdr != (CPU_CHAR *)0) {
1294 | Mem_Copy(buf + buf_wr_ix, hdr, hdr_len);
1295 | buf_wr_ix += hdr_len;
1296 | *line_len += hdr_len;
1297 | } else { /* Not first item, adding ','. */
1298 | Mem_Copy(buf + buf_wr_ix, " ,", 2);
1299 | buf_wr_ix += 2;
1300 | *line_len += 2;
1301 | }
1302 | if (val != (CPU_CHAR *)0) {
1303 | Mem_Copy(buf + buf_wr_ix, val, val_len);
1304 | buf_wr_ix += val_len;
1305 | *line_len += val_len;
1306 | }
1307 |
1308 | Mem_Copy(buf + buf_wr_ix, SMTPc_CRLF, 2); /* See Note #5. */
1309 | buf_wr_ix += 2;
1310 | *line_len = 0;
1311 |
1312 |
1313 | buf[buf_wr_ix] = '\0';
1314 | SMTPc_TRACE_DBG(("String: %s\n", buf));
1315 |
1316 | *perr = SMTPc_ERR_NONE;
1317 | return (buf_wr_ix);
1318 | }
1319 |
1320 |
1321 | /*
1322 | *********************************************************************************************************
1323 | * SMTPc_HELO()
1324 | *
1325 | * Description : (1) Build the HELO command, send it to the server and validate reply.
1326 | *
1327 | * (a) Send command to the server
1328 | * (b) Receive server's reply and validate
1329 | *
1330 | *
1331 | * Argument(s) : sock_id Socket ID.
1332 | *
1333 | * completion_code Numeric value returned by server indicating command status.
1334 | *
1335 | * perr Pointer to variable that will hold the return error code from this
1336 | * function :
1337 | *
1338 | * SMTPc_ERR_NONE No error.
1339 | * SMTPc_ERR_TX_FAILED Error querying server.
1340 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
1341 | * SMTPc_ERR_REP Error with reply.
1342 | *
1343 | * Return(s) : Complete reply from the server, if NO reception error.
1344 | *
1345 | * (CPU_CHAR *)0, otherwise.
1346 | *
1347 | * Caller(s) : SMTPc_Connect().
1348 | *
1349 | * Note(s) : (2) From RFC #2821, "the HELO command is used to identify the SMTP client to the SMTP
1350 | * server".
1351 | *
1352 | * (3) The server will send a 250 "Requested mail action okay, completed" reply upon
1353 | * success. A positive reply is the only reply that will lead to a "SMTPc_ERR_NONE"
1354 | * error return code.
1355 | *
1356 | * (4) This implementation will accept reply 250, as well as any other positive reply.
1357 | *
1358 | * (5) From RFC #2821, section 4.1.3 Address Literals:
1359 | *
1360 | * For IPv4 addresses, this form uses four small decimal integers separated
1361 | * by dots and enclosed by brackets such as [123.255.37.2], which
1362 | * indicates an (IPv4) Internet Address in sequence-of-octets form. For
1363 | * IPv6 and other forms of addressing that might eventually be
1364 | * standardized, the form consists of a standardized "tag" that
1365 | * identifies the address syntax, a colon, and the address itself, in a
1366 | * format specified as part of the IPv6 standards.
1367 | *
1368 | *
1369 | *********************************************************************************************************
1370 | */
1371 |
1372 | static CPU_CHAR *SMTPc_HELO (NET_SOCK_ID sock_id,
1373 | CPU_INT32U *completion_code,
1374 | SMTPc_ERR *perr)
1375 | {
1376 | CPU_CHAR *reply;
1377 | CPU_SIZE_T len;
1378 | CPU_INT08U client_addr[NET_CONN_ADDR_LEN_MAX];
1379 | NET_SOCK_FAMILY client_addr_family;
1380 | NET_ERR err_net;
1381 | CPU_CHAR client_addr_ascii[NET_ASCII_LEN_MAX_ADDR_IP];
1382 | NET_IPv4_ADDR ipv4_client_addr;
1383 |
1384 | /* Get the IP address used in the conn. */
1385 | NetSock_GetLocalIPAddr(sock_id,
1386 | client_addr,
1387 | &client_addr_family,
1388 | &err_net);
1389 | if (err_net != NET_SOCK_ERR_NONE) {
1390 | *perr = SMTPc_ERR_TX_FAILED;
1391 | return ((CPU_CHAR *)0);
1392 | }
1393 | /* Format the message depending of the address family. */
1394 |
1395 | switch (client_addr_family) {
1396 | #ifdef NET_IPv4_MODULE_EN
1397 | case NET_SOCK_FAMILY_IP_V4:
1398 |
1399 | ipv4_client_addr = NET_UTIL_NET_TO_HOST_32(*(CPU_INT32U *)client_addr);
1400 | NetASCII_IPv4_to_Str(ipv4_client_addr, client_addr_ascii, DEF_NO, &err_net);
1401 |
1402 | if (err_net != NET_ASCII_ERR_NONE) {
1403 | *perr = SMTPc_ERR_TX_FAILED;
1404 | return ((CPU_CHAR *)0);
1405 | }
1406 |
1407 | Str_Copy(SMTPc_Comm_Buf, SMTPc_CMD_HELO);
1408 | Str_Cat(SMTPc_Comm_Buf," [");
1409 | Str_Cat(SMTPc_Comm_Buf,client_addr_ascii);
1410 | Str_Cat(SMTPc_Comm_Buf,"]\r\n");
1411 | break;
1412 | #endif
1413 |
1414 | #ifdef NET_IPv6_MODULE_EN
1415 | case NET_SOCK_FAMILY_IP_V6:
1416 |
1417 | NetASCII_IPv6_to_Str((NET_IPv6_ADDR *) client_addr,
1418 | client_addr_ascii,
1419 | DEF_NO,
1420 | DEF_NO,
1421 | &err_net);
1422 | if (err_net != NET_ASCII_ERR_NONE) {
1423 | *perr = SMTPc_ERR_TX_FAILED;
1424 | return ((CPU_CHAR *)0);
1425 | }
1426 |
1427 | Str_Copy(SMTPc_Comm_Buf, SMTPc_CMD_HELO);
1428 | Str_Cat(SMTPc_Comm_Buf, " [");
1429 | Str_Cat(SMTPc_Comm_Buf, SMTPc_TAG_IPv6);
1430 | Str_Cat(SMTPc_Comm_Buf, " ");
1431 | Str_Cat(SMTPc_Comm_Buf, client_addr_ascii);
1432 | Str_Cat(SMTPc_Comm_Buf, "]\r\n");
1433 | break;
1434 | #endif
1435 | default:
1436 | *perr = SMTPc_ERR_TX_FAILED;
1437 | return ((CPU_CHAR *)0);
1438 | }
1439 |
1440 | len = Str_Len(SMTPc_Comm_Buf);
1441 | /* Send HELO Query. */
1442 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, len, perr);
1443 | if (*perr != SMTPc_ERR_NONE) {
1444 | *perr = SMTPc_ERR_TX_FAILED;
1445 | return ((CPU_CHAR *)0);
1446 | }
1447 |
1448 | /* --------- RX SERVER'S REPLY & VALIDATE ------------- */
1449 | reply = SMTPc_RxReply(sock_id, perr); /* See Note #3. */
1450 | if (*perr != SMTPc_ERR_NONE) {
1451 | *perr = SMTPc_ERR_RX_FAILED;
1452 | return ((CPU_CHAR *)0);
1453 | }
1454 |
1455 | SMTPc_ParseReply(reply, completion_code, perr); /* See Note #4. */
1456 | switch (*perr) {
1457 | case SMTPc_ERR_REP_POS: /* If any pos rep... */
1458 | *perr = SMTPc_ERR_NONE; /* ... no err. */
1459 | break;
1460 |
1461 | case SMTPc_ERR_REP_TOO_SHORT:
1462 | *perr = SMTPc_ERR_REP;
1463 | reply = (CPU_CHAR *)0;
1464 | break;
1465 |
1466 | default:
1467 | *perr = SMTPc_ERR_REP;
1468 | break;
1469 | }
1470 |
1471 | return (reply);
1472 | }
1473 |
1474 |
1475 | /*
1476 | *********************************************************************************************************
1477 | * SMTPc_AUTH()
1478 | *
1479 | * Description : (1) Build the AUTH command, send it to the server and validate reply.
1480 | *
1481 | * (a) Encode username & password
1482 | * (b) Send command to the server
1483 | * (c) Receive server's reply and validate
1484 | *
1485 | *
1486 | * Argument(s) : sock_id Socket ID.
1487 | * username Mailbox username name for authentication.
1488 | * pw Mailbox password for authentication.
1489 | * completion_code Numeric value returned by server indicating command status.
1490 | * perr Pointer to variable that will hold the return error code from this
1491 | * function :
1492 | *
1493 | * SMTPc_ERR_NONE No error.
1494 | * SMTPc_ERR_TX_FAILED Error querying server.
1495 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
1496 | * SMTPc_ERR_REP Error with reply.
1497 | * SMTPc_ERR_ENCODE Error encoding credentials.
1498 | * SMTPc_ERR_AUTH_FAILED Error authenticating user.
1499 | *
1500 | * Return(s) : Complete reply from the server, if NO reception error.
1501 | *
1502 | * (CPU_CHAR *)0, otherwise.
1503 | *
1504 | * Caller(s) : SMTPc_Connect().
1505 | *
1506 | * Note(s) : (2) The user's credentials are transmitted to the server using a base 64 encoding and
1507 | * formated according to RFC #4616. From Section 2 'PLAIN SALS Mechanism' "The client
1508 | * presents the authorization identity (identity to act as), followed by a NUL (U+0000)
1509 | * character, followed by the authentication identity (identity whose password will be
1510 | * used), followed by a NUL (U+0000) character, followed by the clear-text password.
1511 | * As with other SASL mechanisms, the client does not provide an authorization identity
1512 | * when it wishes the server to derive an identity from the credentials and use that
1513 | * as the authorization identity."
1514 | *
1515 | * (3) The server will send a 235 "Authentication successful" reply upon success. A positive
1516 | * reply is the only reply that will lead to a "SMTPc_ERR_NONE" error return code.
1517 | *
1518 | * (4) This implementation will accept reply 235, as well as any other positive reply.
1519 | *********************************************************************************************************
1520 | */
1521 |
1522 | #if (SMTPc_CFG_AUTH_EN == DEF_ENABLED)
1523 | static CPU_CHAR *SMTPc_AUTH (NET_SOCK_ID sock_id,
1524 | CPU_CHAR *username,
1525 | CPU_CHAR *pw,
1526 | CPU_INT32U *completion_code,
1527 | SMTPc_ERR *perr)
1528 | {
1529 | CPU_CHAR unencoded_buf[SMTPc_ENCODER_BASE54_IN_MAX_LEN];
1530 | CPU_CHAR encoded_buf[SMTPc_ENCODER_BASE64_OUT_MAX_LEN];
1531 | CPU_INT16U unencoded_len;
1532 | CPU_CHAR *reply;
1533 | CPU_INT16U wr_ix;
1534 | CPU_SIZE_T len;
1535 | NET_ERR net_err;
1536 |
1537 | /* -------------- ENCODE USERNAME & PW ---------------- */
1538 | /* See Note #2. */
1539 | wr_ix = 0;
1540 | unencoded_buf[wr_ix] = SMTPc_ENCODER_BASE64_DELIMITER_CHAR;
1541 | wr_ix++;
1542 |
1543 | Str_Copy(&unencoded_buf[wr_ix], username);
1544 | wr_ix += Str_Len(username);
1545 |
1546 | unencoded_buf[wr_ix] = SMTPc_ENCODER_BASE64_DELIMITER_CHAR;
1547 | wr_ix++;
1548 |
1549 | Str_Copy(&unencoded_buf[wr_ix], pw);
1550 | unencoded_len = wr_ix + Str_Len(pw);
1551 |
1552 | /* Base 64 encoding. */
1553 | NetBase64_Encode (unencoded_buf, unencoded_len, encoded_buf, SMTPc_ENCODER_BASE64_OUT_MAX_LEN, &net_err);
1554 | if (net_err != NET_ERR_NONE) {
1555 | *perr = SMTPc_ERR_ENCODE;
1556 | return ((CPU_CHAR *)0);
1557 | }
1558 |
1559 | /* ------------------ TX CMD TO SERVER ---------------- */
1560 | Str_Copy(SMTPc_Comm_Buf, SMTPc_CMD_AUTH);
1561 | Str_Cat(SMTPc_Comm_Buf, " ");
1562 | Str_Cat(SMTPc_Comm_Buf, SMTPc_CMD_AUTH_MECHANISM_PLAIN);
1563 | Str_Cat(SMTPc_Comm_Buf, " ");
1564 | Str_Cat(SMTPc_Comm_Buf, encoded_buf);
1565 | Str_Cat(SMTPc_Comm_Buf, "\r\n");
1566 | len = Str_Len(SMTPc_Comm_Buf);
1567 |
1568 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, len, perr);
1569 | if (*perr != SMTPc_ERR_NONE) {
1570 | *perr = SMTPc_ERR_TX_FAILED;
1571 | return ((CPU_CHAR *)0);
1572 | }
1573 |
1574 | /* ---------- RX SERVER'S RESPONSE & VALIDATE --------- */
1575 | reply = SMTPc_RxReply(sock_id, perr); /* See Note #3. */
1576 | if (*perr != SMTPc_ERR_NONE) {
1577 | *perr = SMTPc_ERR_RX_FAILED;
1578 | return ((CPU_CHAR *)0);
1579 | }
1580 |
1581 |
1582 | SMTPc_ParseReply(reply, completion_code, perr); /* See Note #4. */
1583 | switch (*perr) {
1584 | case SMTPc_ERR_REP_POS: /* If any pos rep... */
1585 | *perr = SMTPc_ERR_NONE; /* ... no err. */
1586 | break;
1587 |
1588 | case SMTPc_ERR_REP_NEG:
1589 | if (*completion_code == SMTPc_REP_535) {
1590 | *perr = SMTPc_ERR_AUTH_FAILED;
1591 | } else {
1592 | *perr = SMTPc_ERR_REP;
1593 | }
1594 | break;
1595 |
1596 | case SMTPc_ERR_REP_TOO_SHORT:
1597 | *perr = SMTPc_ERR_REP;
1598 | reply = (CPU_CHAR *)0;
1599 | break;
1600 |
1601 | default:
1602 | *perr = SMTPc_ERR_REP;
1603 | break;
1604 | }
1605 |
1606 | return (reply);
1607 | }
1608 | #endif
1609 |
1610 | /*
1611 | *********************************************************************************************************
1612 | * SMTPc_MAIL()
1613 | *
1614 | * Description : (1) Build the MAIL command, send it to the server and validate reply.
1615 | *
1616 | * (a) Send command to the server
1617 | * (b) Receive server's reply and validate
1618 | *
1619 | *
1620 | * Argument(s) : sock_id Socket ID.
1621 | * from Argument of the "MAIL" command (sender mailbox).
1622 | * completion_code Numeric value returned by server indicating command status.
1623 | * perr Pointer to variable that will hold the return error code from this
1624 | * function :
1625 | *
1626 | * SMTPc_ERR_NONE No error.
1627 | * SMTPc_ERR_TX_FAILED Error querying server.
1628 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
1629 | * SMTPc_ERR_REP Error with reply.
1630 | *
1631 | * Return(s) : Complete reply from the server, if NO reception error.
1632 | *
1633 | * (CPU_CHAR *)0, otherwise.
1634 | *
1635 | * Caller(s) : SMTPc_SendMsg().
1636 | *
1637 | * Note(s) : (2) From RFC #2821, "the MAIL command is used to initiate a mail transaction in which
1638 | * the mail data is delivered to an SMTP server [...]".
1639 | *
1640 | * (3) The server will send a 250 "Requested mail action okay, completed" reply upon
1641 | * success. A positive reply is the only reply that will lead to a "SMTPc_ERR_NONE"
1642 | * error return code.
1643 | *
1644 | * (4) This implementation will accept reply 250, as well as any other positive reply.
1645 | *********************************************************************************************************
1646 | */
1647 |
1648 | static CPU_CHAR *SMTPc_MAIL (NET_SOCK_ID sock_id,
1649 | CPU_CHAR *from,
1650 | CPU_INT32U *completion_code,
1651 | SMTPc_ERR *perr)
1652 | {
1653 | CPU_CHAR *reply;
1654 | CPU_SIZE_T len;
1655 |
1656 | /* ----------------- TX CMD TO SERVER ----------------- */
1657 | Str_Copy(SMTPc_Comm_Buf, SMTPc_CMD_MAIL);
1658 | Str_Cat(SMTPc_Comm_Buf, " FROM:<");
1659 | Str_Cat(SMTPc_Comm_Buf, from);
1660 | Str_Cat(SMTPc_Comm_Buf, ">\r\n");
1661 |
1662 | len = Str_Len(SMTPc_Comm_Buf);
1663 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, len, perr);
1664 | if (*perr != SMTPc_ERR_NONE) {
1665 | *perr = SMTPc_ERR_TX_FAILED;
1666 | return ((CPU_CHAR *)0);
1667 | }
1668 |
1669 | /* ---------- RX SERVER'S RESPONSE & VALIDATE --------- */
1670 | reply = SMTPc_RxReply(sock_id, perr); /* See Note #3. */
1671 | if (*perr != SMTPc_ERR_NONE) {
1672 | *perr = SMTPc_ERR_RX_FAILED;
1673 | return ((CPU_CHAR *)0);
1674 | }
1675 |
1676 |
1677 | SMTPc_ParseReply(reply, completion_code, perr); /* See Note #4. */
1678 | switch (*perr) {
1679 | case SMTPc_ERR_REP_POS: /* If any pos rep... */
1680 | *perr = SMTPc_ERR_NONE; /* ... no err. */
1681 | break;
1682 |
1683 | case SMTPc_ERR_REP_TOO_SHORT:
1684 | *perr = SMTPc_ERR_REP;
1685 | reply = (CPU_CHAR *)0;
1686 | break;
1687 |
1688 | default:
1689 | *perr = SMTPc_ERR_REP;
1690 | break;
1691 | }
1692 |
1693 | return (reply);
1694 | }
1695 |
1696 |
1697 | /*
1698 | *********************************************************************************************************
1699 | * SMTPc_RCPT()
1700 | *
1701 | * Description : (1) Build the RCPT command, send it to the server and validate reply.
1702 | *
1703 | * (a) Send command to the server
1704 | * (b) Receive server's reply and validate
1705 | *
1706 | *
1707 | * Argument(s) : sock_id Socket ID.
1708 | * to Argument of the "RCPT" command (receiver mailbox).
1709 | * completion_code Numeric value returned by server indicating command status.
1710 | * perr Pointer to variable that will hold the return error code from this
1711 | * function :
1712 | *
1713 | * SMTPc_ERR_NONE No error.
1714 | * SMTPc_ERR_TX_FAILED Error querying server.
1715 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
1716 | * SMTPc_ERR_REP Error with reply.
1717 | *
1718 | * Return(s) : Complete reply from the server, if NO reception error.
1719 | *
1720 | * (CPU_CHAR *)0, otherwise.
1721 | *
1722 | * Caller(s) : SMTPc_SendMsg().
1723 | *
1724 | * Note(s) : (2) From RFC #2821, "the RCPT command is used to identify an individual recipient of the
1725 | * mail data; multiple recipients are specified by multiple use of this command".
1726 | *
1727 | * (3) The server will send a 250 "Requested mail action okay, completed" or a 251 "User
1728 | * not local; will forwarded to " reply upon success.
1729 | *
1730 | * (4) This implementation will accept replies 250 and 251 as positive replies. Reply 551
1731 | * "User not local; please try " will result in an error.
1732 | *********************************************************************************************************
1733 | */
1734 |
1735 | static CPU_CHAR *SMTPc_RCPT (NET_SOCK_ID sock_id,
1736 | CPU_CHAR *to,
1737 | CPU_INT32U *completion_code,
1738 | SMTPc_ERR *perr)
1739 | {
1740 | CPU_CHAR *reply;
1741 | CPU_SIZE_T len;
1742 |
1743 | /* ----------------- TX CMD TO SERVER ----------------- */
1744 | Str_Copy(SMTPc_Comm_Buf, SMTPc_CMD_RCPT);
1745 | Str_Cat(SMTPc_Comm_Buf, " TO:<");
1746 | Str_Cat(SMTPc_Comm_Buf, to);
1747 | Str_Cat(SMTPc_Comm_Buf, ">\r\n");
1748 |
1749 | len = Str_Len(SMTPc_Comm_Buf);
1750 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, len, perr);
1751 | if (*perr != SMTPc_ERR_NONE) {
1752 | *perr = SMTPc_ERR_TX_FAILED;
1753 | return ((CPU_CHAR *)0);
1754 | }
1755 |
1756 | /* ---------- RX SERVER'S RESPONSE & VALIDATE --------- */
1757 | reply = SMTPc_RxReply(sock_id, perr); /* See Note #3. */
1758 | if (*perr != SMTPc_ERR_NONE) {
1759 | *perr = SMTPc_ERR_RX_FAILED;
1760 | return ((CPU_CHAR *)0);
1761 | }
1762 |
1763 | SMTPc_ParseReply(reply, completion_code, perr); /* See Note #4. */
1764 | switch (*perr) {
1765 | case SMTPc_ERR_REP_POS:
1766 | if ((*completion_code == SMTPc_REP_250) ||
1767 | (*completion_code == SMTPc_REP_251)) {
1768 | *perr = SMTPc_ERR_NONE;
1769 | } else {
1770 | *perr = SMTPc_ERR_REP;
1771 | }
1772 | break;
1773 |
1774 | case SMTPc_ERR_REP_TOO_SHORT:
1775 | *perr = SMTPc_ERR_REP;
1776 | reply = (CPU_CHAR *)0;
1777 | break;
1778 |
1779 | default:
1780 | *perr = SMTPc_ERR_REP;
1781 | break;
1782 | }
1783 |
1784 | return (reply);
1785 | }
1786 |
1787 |
1788 | /*
1789 | *********************************************************************************************************
1790 | * SMTPc_DATA()
1791 | *
1792 | * Description : (1) Build the DATA command, send it to the server and validate reply.
1793 | *
1794 | * (a) Send command to the server
1795 | * (b) Receive server's reply and validate
1796 | *
1797 | *
1798 | * Argument(s) : sock_id Socket ID.
1799 | * completion_code Numeric value returned by server indicating command status.
1800 | * perr Pointer to variable that will hold the return error code from this
1801 | * function :
1802 | *
1803 | * SMTPc_ERR_NONE No error.
1804 | * SMTPc_ERR_TX_FAILED Error querying server.
1805 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
1806 | * SMTPc_ERR_REP Error with reply.
1807 | *
1808 | * Return(s) : Complete reply from the server, if NO reception error.
1809 | *
1810 | * (CPU_CHAR *)0, otherwise.
1811 | *
1812 | * Caller(s) : SMTPc_SendMsg().
1813 | *
1814 | * Note(s) : (2) The DATA command is used to indicate to the SMTP server that all the following lines
1815 | * up to but not including the end of mail data indicator are to be considered as the
1816 | * message text.
1817 | *
1818 | * (3) The receiver normally sends a 354 "Start mail input" reply and then treats the lines
1819 | * following the command as mail data from the sender.
1820 | *********************************************************************************************************
1821 | */
1822 |
1823 | static CPU_CHAR *SMTPc_DATA (NET_SOCK_ID sock_id,
1824 | CPU_INT32U *completion_code,
1825 | SMTPc_ERR *perr)
1826 | {
1827 | CPU_CHAR *reply;
1828 | CPU_SIZE_T len;
1829 |
1830 | /* ----------------- TX CMD TO SERVER ----------------- */
1831 | Str_Copy(SMTPc_Comm_Buf, SMTPc_CMD_DATA);
1832 | Str_Cat(SMTPc_Comm_Buf, "\r\n");
1833 |
1834 |
1835 | len = Str_Len(SMTPc_Comm_Buf);
1836 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, len, perr);
1837 | if (*perr != SMTPc_ERR_NONE) {
1838 | *perr = SMTPc_ERR_TX_FAILED;
1839 | return ((CPU_CHAR *)0);
1840 | }
1841 |
1842 | /* ---------- RX SERVER'S RESPONSE & VALIDATE --------- */
1843 | reply = SMTPc_RxReply(sock_id, perr); /* See Note #3. */
1844 | if (*perr != SMTPc_ERR_NONE) {
1845 | *perr = SMTPc_ERR_RX_FAILED;
1846 | return ((CPU_CHAR *)0);
1847 | }
1848 |
1849 | SMTPc_ParseReply(reply, completion_code, perr);
1850 | switch (*perr) {
1851 | case SMTPc_ERR_REP_INTER:
1852 | if (*completion_code == SMTPc_REP_354) {
1853 | *perr = SMTPc_ERR_NONE;
1854 | } else {
1855 | *perr = SMTPc_ERR_REP;
1856 | }
1857 | break;
1858 |
1859 | case SMTPc_ERR_REP_TOO_SHORT:
1860 | *perr = SMTPc_ERR_REP;
1861 | reply = (CPU_CHAR *)0;
1862 | break;
1863 |
1864 | default:
1865 | *perr = SMTPc_ERR_REP;
1866 | break;
1867 | }
1868 |
1869 | return (reply);
1870 | }
1871 |
1872 |
1873 | /*
1874 | *********************************************************************************************************
1875 | * SMTPc_RSET()
1876 | *
1877 | * Description : (1) Build the RSET command, send it to the server and validate reply.
1878 | *
1879 | * (a) Send command to the server
1880 | * (b) Receive server's reply and validate
1881 | *
1882 | *
1883 | * Argument(s) : sock_id Socket ID.
1884 | * completion_code Numeric value returned by server indicating command status.
1885 | * perr Pointer to variable that will hold the return error code from this
1886 | * function :
1887 | *
1888 | * SMTPc_ERR_NONE No error.
1889 | * SMTPc_ERR_TX_FAILED Error querying server.
1890 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
1891 | * SMTPc_ERR_REP Error with reply.
1892 | *
1893 | * Return(s) : Complete reply from the server, if NO reception error.
1894 | *
1895 | * (CPU_CHAR *)0, otherwise.
1896 | *
1897 | * Caller(s) : SMTPc_SendMsg().
1898 | *
1899 | * Note(s) : (2) From RFC #2821, "the RSET command specifies that the current mail transaction will
1900 | * be aborted. Any stored sender, recipients, and mail data MUST be discarded, and all
1901 | * buffers and state tables cleared".
1902 | *
1903 | * (3) The server MUST send a 250 "Requested mail action okay, completed" reply to a RSET
1904 | * command with no arguments.
1905 | *********************************************************************************************************
1906 | */
1907 |
1908 | static CPU_CHAR *SMTPc_RSET (NET_SOCK_ID sock_id,
1909 | CPU_INT32U *completion_code,
1910 | SMTPc_ERR *perr)
1911 | {
1912 | CPU_CHAR *reply;
1913 | CPU_SIZE_T len;
1914 |
1915 | /* ----------------- TX CMD TO SERVER ----------------- */
1916 | Str_Copy(SMTPc_Comm_Buf, SMTPc_CMD_RSET);
1917 | Str_Cat(SMTPc_Comm_Buf, "\r\n");
1918 |
1919 | len = Str_Len(SMTPc_Comm_Buf);
1920 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, len, perr);
1921 | if (*perr != SMTPc_ERR_NONE) {
1922 | *perr = SMTPc_ERR_TX_FAILED;
1923 | return ((CPU_CHAR *)0);
1924 | }
1925 |
1926 | /* ---------- RX SERVER'S RESPONSE & VALIDATE --------- */
1927 | reply = SMTPc_RxReply(sock_id, perr); /* See Note #3. */
1928 | if (*perr != SMTPc_ERR_NONE) {
1929 | *perr = SMTPc_ERR_RX_FAILED;
1930 | return ((CPU_CHAR *)0);
1931 | }
1932 |
1933 | SMTPc_ParseReply(reply, completion_code, perr);
1934 | switch (*perr) {
1935 | case SMTPc_ERR_REP_POS:
1936 | if (*completion_code == SMTPc_REP_250) {
1937 | *perr = SMTPc_ERR_NONE;
1938 | } else {
1939 | *perr = SMTPc_ERR_REP;
1940 | }
1941 | break;
1942 |
1943 | case SMTPc_ERR_REP_TOO_SHORT:
1944 | *perr = SMTPc_ERR_REP;
1945 | reply = (CPU_CHAR *)0;
1946 | break;
1947 |
1948 | default:
1949 | *perr = SMTPc_ERR_REP;
1950 | break;
1951 | }
1952 |
1953 | return (reply);
1954 | }
1955 |
1956 |
1957 | /*
1958 | *********************************************************************************************************
1959 | * SMTPc_QUIT()
1960 | *
1961 | * Description : (1) Build the QUIT command, send it to the server and validate reply.
1962 | *
1963 | * (a) Send command to the server
1964 | * (b) Receive server's reply and validate
1965 | *
1966 | *
1967 | * Argument(s) : sock_id Socket ID.
1968 | * completion_code Numeric value returned by server indicating command status.
1969 | * perr Pointer to variable that will hold the return error code from this
1970 | * function :
1971 | *
1972 | * SMTPc_ERR_NONE No error.
1973 | * SMTPc_ERR_TX_FAILED Error querying server.
1974 | * SMTPc_ERR_RX_FAILED Error receiving server reply.
1975 | * SMTPc_ERR_REP Error with reply.
1976 | *
1977 | * Return(s) : Complete reply from the server, if NO reception error.
1978 | *
1979 | * (CPU_CHAR *)0, otherwise.
1980 | *
1981 | * Caller(s) : SMTPc_Disconnect().
1982 | *
1983 | * Note(s) : (2) From RFC #2821, "the QUIT command specifies that the receiver MUST send an OK reply,
1984 | * and then close the transmission channel. The receiver MUST NOT intentionally close
1985 | * the transmission channel until it receives and replies to a QUIT command (even if
1986 | * there was an error). the sender MUST NOT intentionally close the transmission
1987 | * channel until it sends a QUIT command and SHOULD wait until it receives the reply
1988 | * (even if there was an error response to a previous command)".
1989 | *
1990 | * (3) The server MUST send a 221 "Service closing transmission channel" reply to a QUIT
1991 | * command.
1992 | *********************************************************************************************************
1993 | */
1994 |
1995 | static CPU_CHAR *SMTPc_QUIT (NET_SOCK_ID sock_id,
1996 | CPU_INT32U *completion_code,
1997 | SMTPc_ERR *perr)
1998 | {
1999 | CPU_CHAR *reply;
2000 | CPU_SIZE_T len;
2001 |
2002 | /* ----------------- TX CMD TO SERVER ----------------- */
2003 | Str_Copy(SMTPc_Comm_Buf, SMTPc_CMD_QUIT);
2004 | Str_Cat(SMTPc_Comm_Buf, "\r\n");
2005 | len = Str_Len(SMTPc_Comm_Buf);
2006 |
2007 | SMTPc_QueryServer(sock_id, SMTPc_Comm_Buf, len, perr);
2008 | if (*perr != SMTPc_ERR_NONE) {
2009 | *perr = SMTPc_ERR_TX_FAILED;
2010 | return ((CPU_CHAR *)0);
2011 | }
2012 |
2013 | /* ---------- RX SERVER'S RESPONSE & VALIDATE --------- */
2014 | reply = SMTPc_RxReply(sock_id, perr); /* See Note #3. */
2015 | if (*perr != SMTPc_ERR_NONE) {
2016 | *perr = SMTPc_ERR_RX_FAILED;
2017 | return ((CPU_CHAR *)0);
2018 | }
2019 |
2020 | SMTPc_ParseReply(reply, completion_code, perr);
2021 | switch (*perr) {
2022 | case SMTPc_ERR_REP_POS:
2023 | if (*completion_code == SMTPc_REP_221) {
2024 | *perr = SMTPc_ERR_NONE;
2025 | } else {
2026 | *perr = SMTPc_ERR_REP;
2027 | }
2028 | break;
2029 |
2030 | case SMTPc_ERR_REP_TOO_SHORT:
2031 | *perr = SMTPc_ERR_REP;
2032 | reply = (CPU_CHAR *)0;
2033 | break;
2034 |
2035 | default:
2036 | *perr = SMTPc_ERR_REP;
2037 | break;
2038 | }
2039 |
2040 | return (reply);
2041 | }
2042 |
--------------------------------------------------------------------------------