Contiki 3.x
email.c
1 /*
2  * Copyright (c) 2002, Adam Dunkels.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following
12  * disclaimer in the documentation and/or other materials provided
13  * with the distribution.
14  * 3. The name of the author may not be used to endorse or promote
15  * products derived from this software without specific prior
16  * written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * This file is part of the Contiki desktop environment for the C64.
31  *
32  *
33  */
34 
35 
36 #include "contiki.h"
37 #include "ctk/ctk.h"
38 #include "smtp.h"
39 #include "lib/petsciiconv.h"
40 
41 #include "ctk/ctk-textentry-multiline.h"
42 
43 
44 #include <string.h>
45 
46 #ifdef EMAIL_CONF_WIDTH
47 #define MAIL_WIDTH EMAIL_CONF_WIDTH
48 #else
49 #define MAIL_WIDTH 37
50 #endif
51 
52 #ifdef EMAIL_CONF_HEIGHT
53 #define MAIL_HEIGHT EMAIL_CONF_HEIGHT
54 #else
55 #define MAIL_HEIGHT 17
56 #endif
57 
58 #ifdef EMAIL_CONF_ERASE
59 #define MAIL_ERASE EMAIL_CONF_ERASE
60 #else
61 #define MAIL_ERASE 1
62 #endif
63 
64 #if (MAIL_WIDTH - 9) < 39
65 #define TEXTENTRY_WIDTH (MAIL_WIDTH - 9)
66 #else
67 #define TEXTENTRY_WIDTH 39
68 #endif
69 
70 static struct ctk_menu menu;
71 unsigned char menuitem_compose, menuitem_setup, menuitem_quit;
72 
73 /* The main window. */
74 static struct ctk_window composewindow;
75 
76 static struct ctk_separator sep1 =
77  {CTK_SEPARATOR(0, MAIL_HEIGHT + 3, MAIL_WIDTH + 1)};
78 static struct ctk_label statuslabel =
79  {CTK_LABEL(7, MAIL_HEIGHT + 4, MAIL_WIDTH - 14, 1, "")};
80 
81 
82 static struct ctk_label tolabel =
83  {CTK_LABEL(0, 0, 3, 1, "To:")};
84 static char to[40];
85 static struct ctk_textentry totextentry =
86  {CTK_TEXTENTRY(8, 0, TEXTENTRY_WIDTH, 1, to, 39)};
87 
88 static struct ctk_label cclabel =
89  {CTK_LABEL(0, 1, 3, 1, "Cc:")};
90 static char cc[40];
91 static struct ctk_textentry cctextentry =
92  {CTK_TEXTENTRY(8, 1, TEXTENTRY_WIDTH, 1, cc, 39)};
93 
94 static struct ctk_label subjectlabel =
95  {CTK_LABEL(0, 2, 8, 1, "Subject:")};
96 static char subject[40];
97 static struct ctk_textentry subjecttextentry =
98  {CTK_TEXTENTRY(8, 2, TEXTENTRY_WIDTH, 1, subject, 39)};
99 
100 static char mail[MAIL_WIDTH * MAIL_HEIGHT];
101 struct ctk_textentry mailtextentry =
102  {CTK_TEXTENTRY_INPUT(0, 3, MAIL_WIDTH - 1, MAIL_HEIGHT, mail, MAIL_WIDTH - 1, \
103  ctk_textentry_multiline_input)};
104 
105 static struct ctk_button sendbutton =
106  {CTK_BUTTON(0, MAIL_HEIGHT + 4, 4, "Send")};
107 
108 #if MAIL_ERASE
109 static struct ctk_button erasebutton =
110  {CTK_BUTTON(MAIL_WIDTH - 6, MAIL_HEIGHT + 4, 5, "Erase")};
111 
112 /* The "Really erase message?" dialog. */
113 static struct ctk_window erasedialog;
114 static struct ctk_label erasedialoglabel1 =
115  {CTK_LABEL(2, 1, 22, 1, "Really erase message?")};
116 static struct ctk_label erasedialoglabel2 =
117  {CTK_LABEL(0, 2, 26, 1, "All contents will be lost.")};
118 static struct ctk_button eraseyesbutton =
119  {CTK_BUTTON(4, 4, 3, "Yes")};
120 static struct ctk_button erasenobutton =
121  {CTK_BUTTON(18, 4, 2, "No")};
122 #endif /* MAIL_ERASE */
123 
124 /* The setup window. */
125 static struct ctk_window setupwindow;
126 static struct ctk_label fromaddresslabel =
127  {CTK_LABEL(0, 0, 25, 1, "Name and e-mail address")};
128 static char fromaddress[40];
129 static struct ctk_textentry fromaddresstextentry =
130  {CTK_TEXTENTRY(0, 1, 26, 1, fromaddress, 39)};
131 
132 static struct ctk_label smtpserverlabel =
133  {CTK_LABEL(0, 3, 20, 1, "Outgoing mailserver")};
134 static char smtpserver[40];
135 static struct ctk_textentry smtpservertextentry =
136  {CTK_TEXTENTRY(0, 4, 26, 1, smtpserver, 39)};
137 
138 /*
139 static struct ctk_label pop3serverlabel =
140  {CTK_LABEL(0, 6, 20, 1, "Incoming mailserver")};
141 static char pop3server[40];
142 static struct ctk_textentry pop3servertextentry =
143  {CTK_TEXTENTRY(0, 7, 26, 1, pop3server, 39)};
144 */
145 
146 /*
147 static struct ctk_label pop3userlabel =
148  {CTK_LABEL(0, 9, 20, 1, "Mailserver username")};
149 static char pop3user[40];
150 static struct ctk_textentry pop3usertextentry =
151  {CTK_TEXTENTRY(0, 10, 26, 1, pop3user, 39)};
152 */
153 
154 /*
155 static struct ctk_label pop3passwordlabel =
156  {CTK_LABEL(0, 12, 20, 1, "Mailserver password")};
157 static char pop3password[40];
158 static struct ctk_textentry pop3passwordtextentry =
159  {CTK_TEXTENTRY(0, 13, 26, 1, pop3password, 39)};
160 */
161 
162 static struct ctk_button setupokbutton =
163 /* {CTK_BUTTON(24, 15, 2, "Ok")};*/
164  {CTK_BUTTON(24, 6, 2, "Ok")};
165 
166 PROCESS(email_process, "E-mail client");
167 
168 AUTOSTART_PROCESSES(&email_process);
169 
170 /*-----------------------------------------------------------------------------------*/
171 static void
172 email_quit(void)
173 {
174  ctk_window_close(&setupwindow);
175  ctk_window_close(&composewindow);
176  ctk_menu_remove(&menu);
177  process_exit(&email_process);
178  LOADER_UNLOAD();
179 }
180 /*-----------------------------------------------------------------------------------*/
181 static void
182 applyconfig(void)
183 {
184  uip_ipaddr_t addr;
185  uip_ipaddr_t *addrptr;
186  char *cptr;
187 
188  for(cptr = smtpserver; *cptr != ' ' && *cptr != 0; ++cptr);
189  *cptr = 0;
190 
191  addrptr = &addr;
192 #if UIP_UDP
193  if(uiplib_ipaddrconv(smtpserver, &addr) == 0) {
194  if(resolv_lookup(smtpserver, &addrptr) != RESOLV_STATUS_CACHED) {
195  resolv_query(smtpserver);
196  ctk_label_set_text(&statuslabel, "Resolving host...");
197  return;
198  }
199  }
200 #else /* UIP_UDP */
201  uiplib_ipaddrconv(smtpserver, &addr);
202 #endif /* UIP_UDP */
203  smtp_configure("contiki", addrptr);
204 
205  petsciiconv_toascii(fromaddress, sizeof(fromaddress));
206 }
207 /*-----------------------------------------------------------------------------------*/
208 static void
209 prepare_message(void)
210 {
211  /* Convert fields to ASCII. */
212  petsciiconv_toascii(to, sizeof(to));
213  petsciiconv_toascii(cc, sizeof(cc));
214  petsciiconv_toascii(subject, sizeof(subject));
215  petsciiconv_toascii(mail, sizeof(mail));
216 }
217 /*-----------------------------------------------------------------------------------*/
218 static void
219 erase_message(void)
220 {
221  CTK_TEXTENTRY_CLEAR(&totextentry);
222  CTK_TEXTENTRY_CLEAR(&cctextentry);
223  CTK_TEXTENTRY_CLEAR(&subjecttextentry);
224  CTK_TEXTENTRY_CLEAR(&mailtextentry);
225 }
226 /*-----------------------------------------------------------------------------------*/
227 PROCESS_THREAD(email_process, ev, data)
228 {
229  struct ctk_widget *w;
230 
231  PROCESS_BEGIN();
232 
233 #if MAIL_ERASE
234  /* Create the "Really erase message?" dialog. */
235  ctk_dialog_new(&erasedialog, 26, 6);
236  CTK_WIDGET_ADD(&erasedialog, &erasedialoglabel1);
237  CTK_WIDGET_ADD(&erasedialog, &erasedialoglabel2);
238  CTK_WIDGET_ADD(&erasedialog, &eraseyesbutton);
239  CTK_WIDGET_ADD(&erasedialog, &erasenobutton);
240  CTK_WIDGET_FOCUS(&erasedialog, &erasenobutton);
241 #endif /* MAIL_ERASE */
242 
243  /* Create setup window. */
244 /* ctk_window_new(&setupwindow, 28, 16, "E-mail setup");*/
245  ctk_window_new(&setupwindow, 28, 7, "E-mail setup");
246 
247  CTK_WIDGET_ADD(&setupwindow, &fromaddresslabel);
248  CTK_WIDGET_ADD(&setupwindow, &fromaddresstextentry);
249  CTK_WIDGET_ADD(&setupwindow, &smtpserverlabel);
250  CTK_WIDGET_ADD(&setupwindow, &smtpservertextentry);
251 /* CTK_WIDGET_ADD(&setupwindow, &pop3serverlabel);*/
252 /* CTK_WIDGET_ADD(&setupwindow, &pop3servertextentry);*/
253 /* CTK_WIDGET_ADD(&setupwindow, &pop3userlabel);*/
254 /* CTK_WIDGET_ADD(&setupwindow, &pop3usertextentry);*/
255 /* CTK_WIDGET_ADD(&setupwindow, &pop3passwordlabel);*/
256 /* CTK_WIDGET_ADD(&setupwindow, &pop3passwordtextentry);*/
257  CTK_WIDGET_ADD(&setupwindow, &setupokbutton);
258 
259  CTK_WIDGET_FOCUS(&setupwindow, &fromaddresstextentry);
260 
261 
262  /* Create compose window. */
263  ctk_window_new(&composewindow, MAIL_WIDTH + 1, MAIL_HEIGHT + 5, "Compose e-mail");
264 
265  CTK_WIDGET_ADD(&composewindow, &tolabel);
266  CTK_WIDGET_ADD(&composewindow, &cclabel);
267  CTK_WIDGET_ADD(&composewindow, &subjectlabel);
268 
269  CTK_WIDGET_ADD(&composewindow, &totextentry);
270  CTK_WIDGET_FOCUS(&composewindow, &totextentry);
271  CTK_WIDGET_ADD(&composewindow, &cctextentry);
272  CTK_WIDGET_ADD(&composewindow, &subjecttextentry);
273 
274  CTK_WIDGET_ADD(&composewindow, &mailtextentry);
275 
276  CTK_WIDGET_ADD(&composewindow, &sep1);
277  CTK_WIDGET_ADD(&composewindow, &statuslabel);
278 
279  CTK_WIDGET_ADD(&composewindow, &sendbutton);
280 #if MAIL_ERASE
281  CTK_WIDGET_ADD(&composewindow, &erasebutton);
282 #endif /* MAIL_ERASE */
283 
284  erase_message();
285 
286  /* Create and add the menu */
287  ctk_menu_new(&menu, "E-mail");
288  menuitem_setup = ctk_menuitem_add(&menu, "Setup");
289  menuitem_compose = ctk_menuitem_add(&menu, "Compose");
290  menuitem_quit = ctk_menuitem_add(&menu, "Quit");
291  ctk_menu_add(&menu);
292 
293  /* Open setup window */
294  ctk_window_open(&setupwindow);
295 
296  while(1) {
297 
299 
300  if(ev == tcpip_event) {
301  smtp_appcall(data);
302  } else if(ev == ctk_signal_widget_activate) {
303  w = (struct ctk_widget *)data;
304  if(w == (struct ctk_widget *)&sendbutton) {
305  prepare_message();
306  smtp_send(to, cc, fromaddress, subject, mail, MAIL_WIDTH, MAIL_HEIGHT);
307  ctk_label_set_text(&statuslabel, "Sending message...");
308  CTK_WIDGET_REDRAW(&statuslabel);
309 #if MAIL_ERASE
310  } else if(w == (struct ctk_widget *)&erasebutton) {
311  ctk_dialog_open(&erasedialog);
312  } else if(w == (struct ctk_widget *)&eraseyesbutton) {
313  erase_message();
314  ctk_dialog_close();
315  } else if(w == (struct ctk_widget *)&erasenobutton) {
316  ctk_dialog_close();
317 #endif /* MAIL_ERASE */
318  } else if(w == (struct ctk_widget *)&setupokbutton) {
319  applyconfig();
320  ctk_window_close(&setupwindow);
321  ctk_window_open(&composewindow);
322  }
323  } else if(ev == ctk_signal_menu_activate) {
324  if((struct ctk_menu *)data == &menu) {
325  if(menu.active == menuitem_compose) {
326  ctk_window_open(&composewindow);
327  } else if(menu.active == menuitem_setup) {
328  ctk_window_open(&setupwindow);
329  } else if(menu.active == menuitem_quit) {
330  email_quit();
331  }
332  }
333 #if UIP_UDP
334  } else if(ev == resolv_event_found) {
335  if(strcmp(data, smtpserver) == 0) {
336  if(resolv_lookup(smtpserver, NULL) == RESOLV_STATUS_CACHED) {
337  applyconfig();
338  ctk_label_set_text(&statuslabel, "");
339  } else {
340  ctk_label_set_text(&statuslabel, "Host not found");
341  }
342  CTK_WIDGET_REDRAW(&statuslabel);
343  }
344 #endif /* UIP_UDP */
345  } else if(ev == PROCESS_EVENT_EXIT) {
346  email_quit();
347  }
348  }
349  PROCESS_END();
350 }
351 /*-----------------------------------------------------------------------------------*/
352 void
353 smtp_done(unsigned char error)
354 {
355  if(error == SMTP_ERR_OK) {
356  ctk_label_set_text(&statuslabel, "Mail sent");
357  erase_message();
358  ctk_window_open(&composewindow);
359  } else {
360  ctk_label_set_text(&statuslabel, "Mail error");
361  }
362  CTK_WIDGET_REDRAW(&statuslabel);
363 }
364 /*-----------------------------------------------------------------------------------*/
#define CTK_WIDGET_ADD(win, widg)
Add a widget to a window.
Definition: ctk.h:752
#define CTK_SEPARATOR(x, y, w)
Instantiating macro for the ctk_separator widget.
Definition: ctk.h:111
#define CTK_TEXTENTRY_CLEAR(e)
Clears a text entry widget and sets the cursor to the start of the text line.
Definition: ctk.h:231
unsigned char ctk_menuitem_add(CC_REGISTER_ARG struct ctk_menu *menu, char *name)
Adds a menu item to a menu.
Definition: ctk.c:800
Hostname is fresh and usable.
Definition: resolv.h:68
void ctk_window_open(CC_REGISTER_ARG struct ctk_window *w)
Open a window, or bring window to front if already open.
Definition: ctk.c:347
#define CTK_WIDGET_FOCUS(win, widg)
Set focus to a widget.
Definition: ctk.h:763
void ctk_window_close(struct ctk_window *w)
Close a window if it is open.
Definition: ctk.c:400
unsigned char active
The currently active menu item.
Definition: ctk.h:601
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
void ctk_menu_add(struct ctk_menu *menu)
Add a menu to the menu bar.
Definition: ctk.c:504
#define CTK_TEXTENTRY(x, y, w, h, text, len)
Instantiating macro for the ctk_textentry widget.
Definition: ctk.h:275
#define ctk_label_set_text(l, t)
Set the text of a label.
Definition: ctk.h:849
#define NULL
The null pointer.
process_event_t ctk_signal_menu_activate
Emitted when a menu item is activated.
Definition: ctk.c:151
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
Definition: uiplib.h:71
#define CTK_LABEL(x, y, w, h, text)
Instantiating macro for the ctk_label widget.
Definition: ctk.h:171
#define PROCESS_THREAD(name, ev, data)
Define the body of a process.
Definition: process.h:273
#define PROCESS_END()
Define the end of a process.
Definition: process.h:131
void ctk_window_new(struct ctk_window *window, unsigned char w, unsigned char h, char *title)
Create a new window.
Definition: ctk.c:732
CCIF process_event_t resolv_event_found
Event that is broadcasted when a DNS name has been resolved.
PETSCII/ASCII conversion functions.
#define LOADER_UNLOAD()
Unload a program from memory.
Definition: loader.h:104
void ctk_menu_new(CC_REGISTER_ARG struct ctk_menu *menu, char *title)
Creates a new menu.
Definition: ctk.c:775
void ctk_menu_remove(struct ctk_menu *menu)
Remove a menu from the menu bar.
Definition: ctk.c:532
#define PROCESS_WAIT_EVENT()
Wait for an event to be posted to the process.
Definition: process.h:141
#define PROCESS(name, strname)
Declare a process.
Definition: process.h:307
process_event_t ctk_signal_widget_activate
Emitted when a widget is activated (pressed).
Definition: ctk.c:126
process_event_t tcpip_event
The uIP event.
Definition: tcpip.c:75
Representation of an individual menu.
Definition: ctk.h:586
#define CTK_BUTTON(x, y, w, text)
Instantiating macro for the ctk_button widget.
Definition: ctk.h:140
Representation of a CTK window.
Definition: ctk.h:506
The generic CTK widget structure that contains all other widget structures.
Definition: ctk.h:444
#define CTK_WIDGET_REDRAW(widg)
Add a widget to the redraw queue.
Definition: ctk.h:771
unsigned char w
The width of the widget in character coordinates.
Definition: ctk.h:464
CTK header file.
void process_exit(struct process *p)
Cause a process to exit.
Definition: process.c:202