89ab3e205894d23576cd708895c22d8e58207d02
[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         unsigned int upd = 0;
112
113         if(ftp->curdir_rem && strcmp(tui_get_title(uilist), ftp->curdir_rem) != 0) {
114                 tui_set_title(uilist, ftp->curdir_rem);
115                 upd |= 1;
116         }
117
118         if(upd & 1) {
119                 tui_draw(uilist);
120         }
121 }
122
123 int proc_input(void)
124 {
125         union event ev;
126
127         while(poll_input(&ev)) {
128                 switch(ev.type) {
129                 case EV_KEY:
130                         if(keypress(ev.key.key) == -1) {
131                                 return -1;
132                         }
133                         break;
134
135                 default:
136                         break;
137                 }
138         }
139         return 0;
140 }
141
142 int keypress(int key)
143 {
144         switch(key) {
145         case 27:
146         case 'q':
147                 return -1;
148
149         default:
150                 break;
151         }
152         return 0;
153 }
154
155 static const char *usage = "Usage: %s [options] [hostname] [port]\n"
156         "Options:\n"
157         "  -h: print usage information and exit\n";
158
159 int parse_args(int argc, char **argv)
160 {
161         int i, argidx = 0;
162
163         for(i=1; i<argc; i++) {
164                 if(argv[i][0] == '-') {
165                         if(argv[i][2] != 0) {
166                                 goto inval;
167                         }
168                         switch(argv[i][1]) {
169                         case 'h':
170                                 printf(usage, argv[0]);
171                                 exit(0);
172
173                         default:
174                                 goto inval;
175                         }
176
177                 } else {
178                         switch(argidx++) {
179                         case 0:
180                                 host = argv[i];
181                                 break;
182
183                         case 1:
184                                 if((port = atoi(argv[i])) <= 0) {
185                                         fprintf(stderr, "invalid port number: %s\n", argv[i]);
186                                         return -1;
187                                 }
188                                 break;
189
190                         default:
191                                 goto inval;
192                         }
193                 }
194         }
195
196         return 0;
197 inval:
198         fprintf(stderr, "invalid argument: %s\n", argv[i]);
199         fprintf(stderr, usage, argv[0]);
200         return -1;
201 }