Contiki 3.x
ftp.c
1 /*
2  * Copyright (c) 2004, 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 copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the Institute nor the names of its contributors
14  * may be used to endorse or promote products derived from this software
15  * without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * This file is part of the Contiki operating system.
30  *
31  * Author: Adam Dunkels <adam@sics.se>
32  *
33  */
34 /* Note to self: It would be nice to have a "View" option in the download dialog. */
35 
36 #include <string.h>
37 #include <stddef.h>
38 
39 #include "ftpc.h"
40 #include "contiki.h"
41 #include "ctk/ctk.h"
42 #include "cfs/cfs.h"
43 #include "net/ip/resolv.h"
44 
45 #define MAX_USERNAMELEN 16
46 #define MAX_PASSWORDLEN 16
47 #define MAX_HOSTNAMELEN 32
48 
49 #ifdef FTP_CONF_WIDTH
50 #define FILES_WIDTH FTP_CONF_WIDTH
51 #define MAX_FILENAMELEN FTP_CONF_WIDTH
52 #else
53 #define FILES_WIDTH 16
54 #define MAX_FILENAMELEN 16
55 #endif
56 
57 #ifdef FTP_CONF_HEIGHT
58 #define FILES_HEIGHT FTP_CONF_HEIGHT
59 #else
60 #define FILES_HEIGHT 18
61 #endif
62 
63 PROCESS(ftp_process, "FTP client");
64 
65 AUTOSTART_PROCESSES(&ftp_process);
66 
67 static void *connection;
68 
69 /* --- The main window --- */
70 
71 static struct ctk_window window;
72 
73 static struct ctk_label localtextlabel =
74  {CTK_LABEL(1, 0, FILES_WIDTH, 1, "Local files")};
75 static struct ctk_label remotetextlabel =
76  {CTK_LABEL(1 + FILES_WIDTH + 1, 0,
77  FILES_WIDTH, 1, "Remote files")};
78 
79 static char leftptr[FILES_HEIGHT];
80 static struct ctk_label leftptrlabel =
81  {CTK_LABEL(0, 1, 1, FILES_HEIGHT, leftptr)};
82 static char midptr[FILES_HEIGHT];
83 static struct ctk_label midptrlabel =
84  {CTK_LABEL(1 + FILES_WIDTH, 1, 1, FILES_HEIGHT, midptr)};
85 static char rightptr[FILES_HEIGHT];
86 static struct ctk_label rightptrlabel =
87  {CTK_LABEL(1 + FILES_WIDTH + 1 + FILES_WIDTH, 1,
88  1, FILES_HEIGHT, rightptr)};
89 
90 static char localfiles[FILES_WIDTH * FILES_HEIGHT];
91 static struct ctk_label localfileslabel =
92  {CTK_LABEL(1, 1,
93  FILES_WIDTH, FILES_HEIGHT, localfiles)};
94 static char remotefiles[FILES_WIDTH * FILES_HEIGHT];
95 static struct ctk_label remotefileslabel =
96  {CTK_LABEL(FILES_WIDTH + 1 + 1, 1,
97  FILES_WIDTH, FILES_HEIGHT, remotefiles)};
98 
99 static struct ctk_button reloadbutton =
100  {CTK_BUTTON(0, 1 + FILES_HEIGHT, 6, "Reload")};
101 
102 #if CTK_CONF_WINDOWS
103 static struct ctk_button connectionbutton =
104  {CTK_BUTTON(8, 1 + FILES_HEIGHT, 13, "Connection...")};
105 static struct ctk_button quitbutton =
106  {CTK_BUTTON(1 + FILES_WIDTH + 1 + FILES_WIDTH - 5,
107  1 + FILES_HEIGHT, 4, "Quit")};
108 #else /* CTK_CONF_WINDOWS */
109 #if FILES_WIDTH < 35
110 static struct ctk_label usagetextlabel =
111  {CTK_LABEL(9, 1 + FILES_HEIGHT, 24, 1, "<up><down><space><enter>")};
112 #else
113 static struct ctk_label usagetextlabel =
114  {CTK_LABEL(10, 1 + FILES_HEIGHT,
115  39, 1, "Keys: <up> <down> <space> <enter> <'u'>")};
116 #endif
117 static struct ctk_button quitbutton =
118  {CTK_BUTTON(1 + FILES_WIDTH + 1 + FILES_WIDTH - 4,
119  1 + FILES_HEIGHT, 4, "Quit")};
120 #endif /* CTK_CONF_WINDOWS */
121 
122 static char statustext[3 + FILES_WIDTH * 2 + 1];
123 static struct ctk_label statuslabel =
124  {CTK_LABEL(0, FILES_HEIGHT + 2, 3 + FILES_WIDTH * 2, 1, statustext)};
125 
126 
127 
128 /* --- The download/upload dialogs --- */
129 static char remotefilename[MAX_FILENAMELEN + 1];
130 static char localfilename[MAX_FILENAMELEN + 1];
131 
132 static struct ctk_window dialog;
133 static struct ctk_label downloadlabel =
134  {CTK_LABEL(6, 1, 13, 1, "Download file")};
135 static struct ctk_label uploadlabel =
136  {CTK_LABEL(7, 1, 11, 1, "Upload file")};
137 static struct ctk_label localfilenametextlabel =
138  {CTK_LABEL(2, 3, 15, 1, "Local filename")};
139 static struct ctk_label localfilenamelabel =
140  {CTK_LABEL(3, 5, 16, 1, localfilename)};
141 static struct ctk_textentry localfilenameentry =
142  {CTK_TEXTENTRY(2, 5, 16, 1, localfilename, sizeof(localfilename) - 1)};
143 static struct ctk_label remotefilenametextlabel =
144  {CTK_LABEL(2, 7, 15, 1, "Remote filename")};
145 static struct ctk_label remotefilenamelabel =
146  {CTK_LABEL(3, 9, 16, 1, remotefilename)};
147 static struct ctk_textentry remotefilenameentry =
148  {CTK_TEXTENTRY(2, 9, 16, 1, remotefilename, sizeof(remotefilename) - 1)};
149 static struct ctk_button downloadbutton =
150  {CTK_BUTTON(0, 11, 13, "Download file")};
151 /* static struct ctk_button uploadbutton =
152  {CTK_BUTTON(0, 11, 11, "Upload file")}; */
153 static struct ctk_button cancelbutton =
154  {CTK_BUTTON(16, 11, 6, "Cancel")};
155 
156 /* --- The connection window --- */
157 static char hostname[MAX_HOSTNAMELEN + 1];
158 static char username[MAX_USERNAMELEN + 1];
159 static char password[MAX_PASSWORDLEN + 1];
160 
161 static struct ctk_window connectionwindow;
162 static struct ctk_label serverlabel =
163  {CTK_LABEL(0, 1, 10, 1, "FTP server")};
164 static struct ctk_textentry serverentry =
165  {CTK_TEXTENTRY(0, 2, 16, 1, hostname, MAX_HOSTNAMELEN)};
166 
167 static struct ctk_button anonymousbutton =
168  {CTK_BUTTON(10, 4, 9, "Anonymous")};
169 static struct ctk_label userlabel =
170  {CTK_LABEL(0, 4, 8, 1, "Username")};
171 static struct ctk_textentry userentry =
172  {CTK_TEXTENTRY(0, 5, 16, 1, username, sizeof(username) - 1)};
173 static struct ctk_label passwordlabel =
174  {CTK_LABEL(0, 7, 8, 1, "Password")};
175 static struct ctk_textentry passwordentry =
176  {CTK_TEXTENTRY(0, 8, 16, 1, password, sizeof(password) - 1)};
177 
178 static struct ctk_button connectbutton =
179  {CTK_BUTTON(0, 10, 7, "Connect")};
180 #if CTK_CONF_WINDOWS
181 static struct ctk_button closeconnectionbutton =
182  {CTK_BUTTON(0, 10, 16, "Close connection")};
183 
184 static struct ctk_button closebutton =
185  {CTK_BUTTON(18, 10, 5, "Close")};
186 #endif /* CTK_CONF_WINDOWS */
187 
188 static struct cfs_dir dir;
189 static struct cfs_dirent dirent;
190 
191 static unsigned char localfileptr = 0;
192 static unsigned char remotefileptr = 0;
193 static unsigned char ptractive;
194 static unsigned char ptrstate;
195 #define PTRSTATE_LOCALFILES 0
196 #define PTRSTATE_REMOTEFILES 1
197 static unsigned char localptr, remoteptr;
198 
199 static int fd = -1;
200 
201 /*---------------------------------------------------------------------------*/
202 static void
203 make_uploaddialog(void)
204 {
205 #if CTK_CONF_WINDOWS
206  ctk_dialog_new(&dialog, 24, 13);
207 #else /* CTK_CONF_WINDOWS */
208  ctk_window_new(&dialog, 24, 13, "");
209 #endif /* CTK_CONF_WINDOWS */
210 
211  CTK_WIDGET_ADD(&dialog, &uploadlabel);
212  CTK_WIDGET_ADD(&dialog, &localfilenametextlabel);
213  CTK_WIDGET_ADD(&dialog, &localfilenamelabel);
214  CTK_WIDGET_ADD(&dialog, &remotefilenametextlabel);
215  CTK_WIDGET_ADD(&dialog, &remotefilenameentry);
216 /* CTK_WIDGET_ADD(&dialog, &uploadbutton); */
217  CTK_WIDGET_ADD(&dialog, &cancelbutton);
218 
219 /* CTK_WIDGET_FOCUS(&dialog, &uploadbutton); */
220  CTK_WIDGET_FOCUS(&dialog, &cancelbutton);
221 }
222 /*---------------------------------------------------------------------------*/
223 static void
224 make_downloaddialog(void)
225 {
226 #if CTK_CONF_WINDOWS
227  ctk_dialog_new(&dialog, 24, 13);
228 #else /* CTK_CONF_WINDOWS */
229  ctk_window_new(&dialog, 24, 13, "");
230 #endif /* CTK_CONF_WINDOWS */
231 
232  CTK_WIDGET_ADD(&dialog, &downloadlabel);
233  CTK_WIDGET_ADD(&dialog, &localfilenametextlabel);
234  CTK_WIDGET_ADD(&dialog, &localfilenameentry);
235  CTK_WIDGET_ADD(&dialog, &remotefilenametextlabel);
236  CTK_WIDGET_ADD(&dialog, &remotefilenamelabel);
237  CTK_WIDGET_ADD(&dialog, &downloadbutton);
238  CTK_WIDGET_ADD(&dialog, &cancelbutton);
239 
240  CTK_WIDGET_FOCUS(&dialog, &downloadbutton);
241 }
242 /*---------------------------------------------------------------------------*/
243 static void
244 show_statustext(char *text1, char *text2)
245 {
246  int len;
247 
248  len = (int)strlen(text1);
249  if(len < sizeof(statustext)) {
250  strncpy(statustext, text1, sizeof(statustext));
251  strncpy(statustext + len, text2, sizeof(statustext) - len);
252  CTK_WIDGET_REDRAW(&statuslabel);
253  }
254 
255 }
256 /*---------------------------------------------------------------------------*/
257 static void
258 close_file(void)
259 {
260  if(fd != -1) {
261  cfs_close(fd);
262  fd = -1;
263  }
264 }
265 /*---------------------------------------------------------------------------*/
266 static void
267 quit(void)
268 {
269  close_file();
270  ctk_window_close(&window);
271  process_exit(&ftp_process);
272  LOADER_UNLOAD();
273 }
274 /*---------------------------------------------------------------------------*/
275 static void
276 clearptr(void)
277 {
278  rightptr[remoteptr] = ' ';
279  midptr[remoteptr] = ' ';
280  leftptr[localptr] = ' ';
281  midptr[localptr] = ' ';
282 }
283 /*---------------------------------------------------------------------------*/
284 static void
285 showptr(void)
286 {
287  if(ptrstate == PTRSTATE_LOCALFILES) {
288  rightptr[remoteptr] = ' ';
289  midptr[remoteptr] = ' ';
290  leftptr[localptr] = '>';
291  midptr[localptr] = '<';
292  } else {
293  leftptr[localptr] = ' ';
294  midptr[localptr] = ' ';
295  rightptr[remoteptr] = '<';
296  midptr[remoteptr] = '>';
297  }
298 
299  CTK_WIDGET_REDRAW(&leftptrlabel);
300  CTK_WIDGET_REDRAW(&midptrlabel);
301  CTK_WIDGET_REDRAW(&rightptrlabel);
302 }
303 /*---------------------------------------------------------------------------*/
304 static void
305 start_loaddir(void)
306 {
307  memset(localfiles, 0, sizeof(localfiles));
308  localfileptr = 0;
309  cfs_opendir(&dir, ".");
310  process_post(&ftp_process, PROCESS_EVENT_CONTINUE, NULL);
311 }
312 /*---------------------------------------------------------------------------*/
313 static void
314 start_loadremote(void)
315 {
316  memset(remotefiles, 0, sizeof(remotefiles));
317  remotefileptr = 0;
318  clearptr();
319  remoteptr = 0;
320  showptr();
321  ftpc_list(connection);
322 }
323 /*---------------------------------------------------------------------------*/
324 static void
325 make_connectionwindow(void)
326 {
327 #if CTK_CONF_WINDOWS
328  ctk_dialog_new(&connectionwindow, 25, 11);
329 #else /* CTK_CONF_WINDOWS */
330  ctk_window_new(&connectionwindow, 25, 11, "");
331 #endif /* CTK_CONF_WINDOWS */
332 
333  CTK_WIDGET_ADD(&connectionwindow, &serverlabel);
334  CTK_WIDGET_ADD(&connectionwindow, &serverentry);
335 
336  CTK_WIDGET_ADD(&connectionwindow, &userlabel);
337  CTK_WIDGET_ADD(&connectionwindow, &anonymousbutton);
338  CTK_WIDGET_ADD(&connectionwindow, &userentry);
339  CTK_WIDGET_ADD(&connectionwindow, &passwordlabel);
340  CTK_WIDGET_ADD(&connectionwindow, &passwordentry);
341 
342 #if CTK_CONF_WINDOWS
343  if(connection == NULL) {
344 #endif /* CTK_CONF_WINDOWS */
345  CTK_WIDGET_ADD(&connectionwindow, &connectbutton);
346 #if CTK_CONF_WINDOWS
347  } else {
348  CTK_WIDGET_ADD(&connectionwindow, &closeconnectionbutton);
349  }
350  CTK_WIDGET_ADD(&connectionwindow, &closebutton);
351 #endif /* CTK_CONF_WINDOWS */
352 
353  CTK_WIDGET_FOCUS(&connectionwindow, &serverentry);
354 }
355 /*---------------------------------------------------------------------------*/
356 PROCESS_THREAD(ftp_process, ev, data)
357 {
358  uip_ipaddr_t ipaddr;
359  uip_ipaddr_t *ipaddrptr;
360 
361  PROCESS_BEGIN();
362 
363  ftpc_init();
364 
365  memset(statustext, 0, sizeof(statustext));
366  memset(remotefiles, 0, sizeof(remotefiles));
367  memset(localfiles, 0, sizeof(localfiles));
368  memset(leftptr, 0, sizeof(leftptr));
369  memset(midptr, 0, sizeof(midptr));
370  memset(rightptr, 0, sizeof(rightptr));
371 
372  ptrstate = PTRSTATE_REMOTEFILES;
373  localptr = remoteptr = 0;
374 
375  connection = NULL;
376 
377  ctk_window_new(&window,
378  3 + FILES_WIDTH * 2, 3 + FILES_HEIGHT,
379  "FTP Client");
380 
381  CTK_WIDGET_ADD(&window, &localtextlabel);
382  CTK_WIDGET_ADD(&window, &remotetextlabel);
383 
384  CTK_WIDGET_ADD(&window, &leftptrlabel);
385  CTK_WIDGET_ADD(&window, &localfileslabel);
386  CTK_WIDGET_ADD(&window, &midptrlabel);
387  CTK_WIDGET_ADD(&window, &remotefileslabel);
388  CTK_WIDGET_ADD(&window, &rightptrlabel);
389 
390  CTK_WIDGET_ADD(&window, &reloadbutton);
391 #if CTK_CONF_WINDOWS
392  CTK_WIDGET_ADD(&window, &connectionbutton);
393 #else /* CTK_CONF_WINDOWS */
394  CTK_WIDGET_ADD(&window, &usagetextlabel);
395 #endif /* CTK_CONF_WINDOWS */
396  CTK_WIDGET_ADD(&window, &quitbutton);
397 
398  CTK_WIDGET_ADD(&window, &statuslabel);
399 
400 #if CTK_CONF_WINDOWS
401  CTK_WIDGET_FOCUS(&window, &connectionbutton);
402 #endif /* CTK_CONF_WINDOWS */
403 
404 #if CTK_CONF_WINDOWS
405  ctk_window_open(&window);
406  showptr();
407  start_loaddir();
408  ptractive = 1;
409 #else /* CTK_CONF_WINDOWS */
410  make_connectionwindow();
411  ctk_window_open(&connectionwindow);
412 #endif /* CTK_CONF_WINDOWS */
413 
414  while(1) {
415 
417 
418  if(ev == PROCESS_EVENT_CONTINUE) {
419  if(cfs_readdir(&dir, &dirent) == 0 &&
420  localfileptr < FILES_HEIGHT) {
421  strncpy(&localfiles[localfileptr * FILES_WIDTH],
422  dirent.name, FILES_WIDTH);
423  CTK_WIDGET_REDRAW(&localfileslabel);
424  ++localfileptr;
425  process_post(&ftp_process, PROCESS_EVENT_CONTINUE, NULL);
426  } else{
427  cfs_closedir(&dir);
428  }
429  } else if(ev == PROCESS_EVENT_EXIT) {
430  quit();
431  } else if(ev == tcpip_event) {
432  ftpc_appcall(data);
433 #if UIP_UDP
434  } else if(ev == resolv_event_found) {
435  /* Either found a hostname, or not. */
436  if((char *)data != NULL &&
437  resolv_lookup((char *)data, &ipaddrptr) == RESOLV_STATUS_CACHED) {
438  connection = ftpc_connect(ipaddrptr, UIP_HTONS(21));
439  show_statustext("Connecting to ", hostname);
440  } else {
441  show_statustext("Host not found: ", hostname);
442  }
443 #endif /* UIP_UDP */
444  } else if(
445 #if CTK_CONF_WINDOWCLOSE
446  ev == ctk_signal_window_close &&
447 #endif /* CTK_CONF_WINDOWCLOSE */
448  data == (process_data_t)&window) {
449  quit();
450  } else if(ev == ctk_signal_widget_activate) {
451  if((struct ctk_button *)data == &quitbutton) {
452  quit();
453  } else if((struct ctk_button *)data == &cancelbutton) {
454 #if CTK_CONF_WINDOWS
455  ctk_dialog_close();
456 #else /* CTK_CONF_WINDOWS */
457  ctk_window_close(&dialog);
458  ctk_window_open(&window);
459 #endif /* CTK_CONF_WINDOWS */
460  ptractive = 1;
461  } else if((struct ctk_button *)data == &downloadbutton) {
462 #if CTK_CONF_WINDOWS
463  ctk_dialog_close();
464 #else /* CTK_CONF_WINDOWS */
465  ctk_window_close(&dialog);
466  ctk_window_open(&window);
467 #endif /* CTK_CONF_WINDOWS */
468  ptractive = 1;
469  close_file();
470  fd = cfs_open(localfilename, CFS_WRITE);
471  if(fd != -1) {
472  show_statustext("Downloading ", remotefilename);
473  ftpc_get(connection, remotefilename);
474  } else {
475  show_statustext("Could not create ", localfilename);
476  }
477  } else if((struct ctk_button *)data == &reloadbutton) {
478  start_loaddir();
479 #if CTK_CONF_WINDOWS
480  } else if((struct ctk_button *)data == &connectionbutton) {
481  ptractive = 0;
482  make_connectionwindow();
483  ctk_dialog_open(&connectionwindow);
484  } else if((struct ctk_button *)data == &closebutton) {
485  ctk_dialog_close();
486  ptractive = 1;
487 #endif /* CTK_CONF_WINDOWS */
488  } else if((struct ctk_button *)data == &anonymousbutton) {
489  strcpy(username, "anonymous");
490  strcpy(password, "contiki@ftp");
491  CTK_WIDGET_REDRAW(&userentry);
492  CTK_WIDGET_REDRAW(&passwordentry);
493 #if CTK_CONF_WINDOWS
494  } else if((struct ctk_button *)data == &closeconnectionbutton) {
495  ctk_dialog_close();
496  ptractive = 1;
497  ftpc_close(connection);
498 #endif /* CTK_CONF_WINDOWS */
499  } else if((struct ctk_button *)data == &connectbutton) {
500 #if CTK_CONF_WINDOWS
501  ctk_dialog_close();
502 #else /* CTK_CONF_WINDOWS */
503  ctk_window_close(&connectionwindow);
504  ctk_window_open(&window);
505  showptr();
506  start_loaddir();
507 #endif /* CTK_CONF_WINDOWS */
508  ptractive = 1;
509 #if UIP_UDP
510  if(uiplib_ipaddrconv(hostname, &ipaddr) == 0) {
511  if(resolv_lookup(hostname, &ipaddrptr) != RESOLV_STATUS_CACHED) {
512  resolv_query(hostname);
513  show_statustext("Resolving host ", hostname);
514  break;
515  }
516  connection = ftpc_connect(ipaddrptr, UIP_HTONS(21));
517  show_statustext("Connecting to ", hostname);
518  } else {
519  connection = ftpc_connect(&ipaddr, UIP_HTONS(21));
520  show_statustext("Connecting to ", hostname);
521  }
522 #else /* UIP_UDP */
523  uiplib_ipaddrconv(hostname, &ipaddr);
524  connection = ftpc_connect(&ipaddr, UIP_HTONS(21));
525  show_statustext("Connecting to ", hostname);
526 #endif /* UIP_UDP */
527  }
528  /* if((struct ctk_button *)data == &closebutton) {
529  ftpc_close(connection);
530  }*/
531  } else if(ptractive && ev == ctk_signal_keypress) {
532  if((ctk_arch_key_t)(size_t)data == ' ') {
533  if(ptrstate == PTRSTATE_LOCALFILES) {
534  ptrstate = PTRSTATE_REMOTEFILES;
535  } else {
536  ptrstate = PTRSTATE_LOCALFILES;
537  }
538  } else if((ctk_arch_key_t)(size_t)data == CH_CURS_UP) {
539  clearptr();
540  if(ptrstate == PTRSTATE_LOCALFILES) {
541  if(localptr > 0) {
542  --localptr;
543  }
544  } else {
545  if(remoteptr > 0) {
546  --remoteptr;
547  }
548  }
549  } else if((ctk_arch_key_t)(size_t)data == CH_CURS_DOWN) {
550  clearptr();
551  if(ptrstate == PTRSTATE_LOCALFILES) {
552  if(localptr < FILES_HEIGHT - 1) {
553  ++localptr;
554  }
555  } else {
556  if(remoteptr < FILES_HEIGHT - 1) {
557  ++remoteptr;
558  }
559  }
560  } else if((ctk_arch_key_t)(size_t)data == CH_ENTER) {
561  if(ptrstate == PTRSTATE_LOCALFILES) {
562  strncpy(localfilename,
563  &localfiles[localptr * FILES_WIDTH], FILES_WIDTH);
564  strncpy(remotefilename,
565  &localfiles[localptr * FILES_WIDTH], FILES_WIDTH);
566  ptractive = 0;
567  make_uploaddialog();
568 #if CTK_CONF_WINDOWS
569  ctk_dialog_open(&dialog);
570 #else /* CTK_CONF_WINDOWS */
571  ctk_window_close(&window);
572  ctk_window_open(&dialog);
573 #endif /* CTK_CONF_WINDOWS */
574  } else {
575  strncpy(localfilename,
576  &remotefiles[remoteptr * FILES_WIDTH], FILES_WIDTH);
577  strncpy(remotefilename,
578  &remotefiles[remoteptr * FILES_WIDTH], FILES_WIDTH);
579  ftpc_cwd(connection, remotefilename);
580  /* make_downloaddialog();
581  ctk_dialog_open(&dialog);*/
582  }
583  } else if((ctk_arch_key_t)(size_t)data == 'u') {
584  ftpc_cdup(connection);
585  }
586 
587  if(ptractive) {
588  showptr();
589  }
590  }
591  }
592 
593  PROCESS_END();
594 }
595 /*---------------------------------------------------------------------------*/
596 void
597 ftpc_closed(void)
598 {
599  strcpy(statustext, "Connection closed");
600  CTK_WIDGET_REDRAW(&statuslabel);
601  connection = NULL;
602 }
603 /*---------------------------------------------------------------------------*/
604 void
605 ftpc_aborted(void)
606 {
607  strcpy(statustext, "Connection reset");
608  CTK_WIDGET_REDRAW(&statuslabel);
609  connection = NULL;
610 }
611 /*---------------------------------------------------------------------------*/
612 void
613 ftpc_timedout(void)
614 {
615  strcpy(statustext, "Connection timed out");
616  CTK_WIDGET_REDRAW(&statuslabel);
617  connection = NULL;
618 }
619 /*---------------------------------------------------------------------------*/
620 char *
621 ftpc_username(void)
622 {
623  return username;
624 }
625 /*---------------------------------------------------------------------------*/
626 char *
627 ftpc_password(void)
628 {
629  return password;
630 }
631 /*---------------------------------------------------------------------------*/
632 void
633 ftpc_list_file(char *filename)
634 {
635  if(remotefileptr < FILES_HEIGHT && filename != NULL) {
636  strncpy(&remotefiles[remotefileptr * FILES_WIDTH], filename, FILES_WIDTH);
637  CTK_WIDGET_REDRAW(&remotefileslabel);
638  ++remotefileptr;
639  }
640 
641  if(filename == NULL) {
642  strcpy(statustext, "Connected");
643  CTK_WIDGET_REDRAW(&statuslabel);
644  }
645 }
646 /*---------------------------------------------------------------------------*/
647 void
648 ftpc_cwd_done(unsigned short status)
649 {
650  if(status == FTPC_COMPLETED ||
651  status == FTPC_OK) {
652  start_loadremote();
653  } else {
654  ptractive = 0;
655  make_downloaddialog();
656 #if CTK_CONF_WINDOWS
657  ctk_dialog_open(&dialog);
658 #else /* CTK_CONF_WINDOWS */
659  ctk_window_close(&window);
660  ctk_window_open(&dialog);
661 #endif /* CTK_CONF_WINDOWS */
662  }
663 }
664 /*---------------------------------------------------------------------------*/
665 void
666 ftpc_connected(void *connection)
667 {
668  strcpy(statustext, "Loading remote directory");
669  CTK_WIDGET_REDRAW(&statuslabel);
670 
671  start_loadremote();
672 }
673 /*---------------------------------------------------------------------------*/
674 void
675 ftpc_data(uint8_t *data, uint16_t len)
676 {
677  if(data == NULL) {
678  show_statustext("Download complete", "");
679  close_file();
680  start_loaddir();
681  } else {
682  cfs_write(fd, data, len);
683  }
684 }
685 /*---------------------------------------------------------------------------*/
#define CTK_WIDGET_ADD(win, widg)
Add a widget to a window.
Definition: ctk.h:752
process_event_t ctk_signal_window_close
Emitted when a window is closed.
Definition: ctk.c:155
char ctk_arch_key_t
The keyboard character type of the system.
Definition: ctk-conio.h:40
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
int cfs_open(const char *name, int flags)
Open a file.
Definition: cfs-coffee.c:996
#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
#define PROCESS_BEGIN()
Define the beginning of a process.
Definition: process.h:120
#define CFS_WRITE
Specify that cfs_open() should open a file for writing.
Definition: cfs.h:104
#define CTK_TEXTENTRY(x, y, w, h, text, len)
Instantiating macro for the ctk_textentry widget.
Definition: ctk.h:275
#define NULL
The null pointer.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
Definition: uip.h:1238
int cfs_readdir(struct cfs_dir *dir, struct cfs_dirent *record)
Read a directory entry.
Definition: cfs-coffee.c:1264
#define uiplib_ipaddrconv
Convert a textual representation of an IP address to a numerical representation.
Definition: uiplib.h:71
int process_post(struct process *p, process_event_t ev, process_data_t data)
Post an asynchronous event.
Definition: process.c:322
#define CTK_LABEL(x, y, w, h, text)
Instantiating macro for the ctk_label widget.
Definition: ctk.h:171
process_event_t ctk_signal_keypress
Emitted for every key being pressed.
Definition: ctk.c:126
#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.
#define LOADER_UNLOAD()
Unload a program from memory.
Definition: loader.h:104
void cfs_closedir(struct cfs_dir *dir)
Close a directory opened with cfs_opendir().
Definition: cfs-coffee.c:1290
#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
int cfs_opendir(struct cfs_dir *dir, const char *name)
Open a directory for reading directory entries.
Definition: cfs-coffee.c:1253
#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
#define CTK_WIDGET_REDRAW(widg)
Add a widget to the redraw queue.
Definition: ctk.h:771
uIP DNS resolver code header file.
CTK header file.
void process_exit(struct process *p)
Cause a process to exit.
Definition: process.c:202
void cfs_close(int fd)
Close an open file.
Definition: cfs-coffee.c:1032
CFS header file.