foo
[oftp] / src / main.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <signal.h>
4 #include <errno.h>
5 #include <assert.h>
6 #include <sys/select.h>
7 #include "tgfx.h"
8 #include "input.h"
9 #include "util.h"
10 #include "tui.h"
11 #include "ftp.h"
12
13 void updateui(void);
14 int proc_input(void);
15 int keypress(int key);
16 int parse_args(int argc, char **argv);
17
18 static struct ftp *ftp;
19 static struct tui_widget *uilist;
20
21 static char *host = "localhost";
22 static int port = 21;
23
24 int main(int argc, char **argv)
25 {
26         int i, numsock, maxfd;
27         int ftpsock[16];
28         fd_set rdset;
29         struct timeval tv;
30
31         if(parse_args(argc, argv) == -1) {
32                 return 1;
33         }
34
35         if(!(ftp = ftp_alloc())) {
36                 return 1;
37         }
38         if(ftp_connect(ftp, host, port) == -1) {
39                 ftp_free(ftp);
40                 return 1;
41         }
42
43         init_input();
44
45         tg_init();
46
47         tg_bgchar(' ');
48         tg_clear();
49
50         uilist = tui_list("Remote", 0, 0, 40, 23, 0, 0);
51         tui_add_list_item(uilist, "first item");
52         tui_add_list_item(uilist, "second item");
53         tui_add_list_item(uilist, "another item");
54         tui_add_list_item(uilist, "foo");
55
56         tg_setcursor(0, 23);
57
58         tui_draw(uilist);
59
60         for(;;) {
61                 FD_ZERO(&rdset);
62                 maxfd = 0;
63
64                 numsock = ftp_sockets(ftp, ftpsock, sizeof ftpsock);
65                 for(i=0; i<numsock; i++) {
66                         FD_SET(ftpsock[i], &rdset);
67                         if(ftpsock[i] > maxfd) maxfd = ftpsock[i];
68                 }
69
70 #ifdef __unix__
71                 FD_SET(0, &rdset);
72                 tv.tv_sec = 120;
73                 tv.tv_usec = 0;
74 #else
75                 tv.tv_sec = tv.tv_usec = 0;
76 #endif
77
78                 if(select(maxfd + 1, &rdset, 0, 0, &tv) == -1 && errno == EINTR) {
79                         continue;
80                 }
81
82 #ifdef __unix__
83                 if(FD_ISSET(0, &rdset)) {
84                         if(proc_input() == -1) {
85                                 break;
86                         }
87                 }
88 #endif
89
90                 for(i=0; i<numsock; i++) {
91                         if(FD_ISSET(ftpsock[i], &rdset)) {
92                                 ftp_handle(ftp, ftpsock[i]);
93                         }
94                 }
95
96                 if(ftp->modified) {
97                         updateui();
98                         ftp->modified = 0;
99                 }
100         }
101
102         tg_cleanup();
103         cleanup_input();
104         ftp_close(ftp);
105         ftp_free(ftp);
106         return 0;
107 }
108
109 void updateui(void)
110 {
111         struct ftp_dirent *ent;
112         unsigned int upd = 0;
113
114         if(ftp->curdir_rem && strcmp(tui_get_title(uilist), ftp->curdir_rem) != 0) {
115                 tui_set_title(uilist, ftp->curdir_rem);
116                 upd |= 1;
117         }
118
119         if(ftp->modified & FTP_MOD_REMDIR) {
120                 tui_clear_list(uilist);
121
122                 ent = ftp->curdir_rem;
123                 while(ent) {
124                         tui_add_list_item(uilist, ent->name);
125                         ent = ent->next;
126                 }
127                 upd |= 1;
128         }
129
130         if(upd & 1) {
131                 tui_draw(uilist);
132         }
133 }
134
135 int proc_input(void)
136 {
137         union event ev;
138
139         while(poll_input(&ev)) {
140                 switch(ev.type) {
141                 case EV_KEY:
142                         if(keypress(ev.key.key) == -1) {
143                                 return -1;
144                         }
145                         break;
146
147                 default:
148                         break;
149                 }
150         }
151         return 0;
152 }
153
154 int keypress(int key)
155 {
156         switch(key) {
157         case 27:
158         case 'q':
159                 return -1;
160
161         default:
162                 break;
163         }
164         return 0;
165 }
166
167 static const char *usage = "Usage: %s [options] [hostname] [port]\n"
168         "Options:\n"
169         "  -h: print usage information and exit\n";
170
171 int parse_args(int argc, char **argv)
172 {
173         int i, argidx = 0;
174
175         for(i=1; i<argc; i++) {
176                 if(argv[i][0] == '-') {
177                         if(argv[i][2] != 0) {
178                                 goto inval;
179                         }
180                         switch(argv[i][1]) {
181                         case 'h':
182                                 printf(usage, argv[0]);
183                                 exit(0);
184
185                         default:
186                                 goto inval;
187                         }
188
189                 } else {
190                         switch(argidx++) {
191                         case 0:
192                                 host = argv[i];
193                                 break;
194
195                         case 1:
196                                 if((port = atoi(argv[i])) <= 0) {
197                                         fprintf(stderr, "invalid port number: %s\n", argv[i]);
198                                         return -1;
199                                 }
200                                 break;
201
202                         default:
203                                 goto inval;
204                         }
205                 }
206         }
207
208         return 0;
209 inval:
210         fprintf(stderr, "invalid argument: %s\n", argv[i]);
211         fprintf(stderr, usage, argv[0]);
212         return -1;
213 }