Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / apps / zmail / main.c
blob451e65d73c28d88d7d4d7807425cf3dd3afe3c98
1 /*
2 * ZeX/OS
3 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <fcntl.h>
21 #include <netdb.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <arpa/inet.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
30 #define ESC 1
32 #define STATE_CONNECTED 1
33 #define STATE_PASS 2
34 #define STATE_WAIT 3
35 #define STATE_STAT 4
36 #define STATE_LOGGED 5
38 static struct sockaddr_in serverSock; // Remote connection
39 static struct hostent *host; // Remote host
40 static int zsock; // Socket
41 static int size; // Count of input/output bytes
42 static char *buf; // Buffer
43 static char *msg;
45 typedef struct {
46 unsigned char state;
47 unsigned char mails;
48 char *user;
49 char *pass;
50 char *server;
51 unsigned short port;
52 } CONFIG;
53 CONFIG config;
55 unsigned key_pressed (int keycode)
57 int scancode = getkey ();
59 if (scancode == keycode)
60 return 1;
62 if (scancode == keycode+128)
63 return 2;
64 else
65 return 0;
68 static int send_to_socket (char *data, unsigned len)
70 int ret;
71 if ((ret = send (zsock, data, len, 0)) == -1) {
72 printf ("ERROR -> send () = -1\n");
73 return -1;
76 return ret;
79 int zmail_commmand (char *buf, int len)
81 if (!strncmp (buf, "quit", 4)) {
82 send_to_socket ("QUIT\n", 5);
83 } else if (!strncmp (buf, "read", 4)) {
84 if (!config.mails) {
85 printf ("You've got no email to read\n");
86 return 0;
89 char str[64];
90 sprintf (str, "RETR %d\n", config.mails --);
92 send_to_socket (str, strlen (str));
95 return 0;
98 static int handle_input ()
100 char i = getch ();
102 if (i) {
103 setcolor (7, 0);
105 putch (i);
107 if (size < 64) {
108 if (i != '\b') {
109 msg[size] = i;
110 size ++;
111 } else {
112 size --;
113 msg[size] = '\0';
117 if (i == '\n') {
118 zmail_commmand (msg, size);
119 size = 0;
123 if (key_pressed (ESC))
124 return -1;
126 return 1;
129 void zmail_proto_user ()
131 char str[64];
132 sprintf (str, "USER %s\n", config.user);
134 send_to_socket (str, strlen (str));
137 void zmail_proto_pass ()
139 char str[64];
140 sprintf (str, "PASS %s\n", config.pass);
142 send_to_socket (str, strlen (str));
145 void zmail_proto_stat ()
147 char str[64];
148 sprintf (str, "STAT\n");
150 send_to_socket (str, strlen (str));
153 int zmail_proto (char *buf, int len)
155 if (buf[0] == '-') {
156 printf ("ERROR -> %s\n", buf+5);
157 return -1;
160 if (buf[0] != '+') {
161 printf ("UNKNOWN cmd: %s\n", buf);
163 return 0;
166 char *cmd = buf+1;
167 char *msg = buf+4;
169 /* OK - succefull action */
170 if (!strncmp (cmd, "OK", 2)) {
171 if (config.state == STATE_CONNECTED) {
172 if (msg[0] == '<') {
173 char *s = strchr (msg, '@');
175 if (!s) {
176 printf ("ERROR -> invalid authentication\n");
177 return -1;
180 s ++;
182 if (!strncmp (s, config.server, strlen (config.server))) {
183 zmail_proto_user ();
184 config.state = STATE_PASS;
185 } else {
186 printf ("ERROR -> invalid authentication\n");
187 return -1;
190 } else if (config.state == STATE_PASS) {
191 config.state = STATE_WAIT;
192 zmail_proto_pass ();
193 } else if (config.state == STATE_WAIT) {
194 config.state = STATE_STAT;
195 printf ("You are logged succefully as %s\n", config.user);
196 zmail_proto_stat ();
197 } else if (config.state == STATE_STAT) {
198 config.state = STATE_LOGGED;
199 char *s = strchr (msg, ' ');
200 if (s)
201 *s = '\0';
203 printf ("You've got %s new email(s)\n", msg);
205 config.mails = atoi (msg);
209 return 0;
212 static int zmail_init (const char *addr, int port)
214 // Let's get info about remote computer
215 if ((host = gethostbyname ((char *) addr)) == NULL) {
216 printf ("Wrong address -> %s:%d\n", addr, port);
217 return 0;
220 // Create socket
221 if ((zsock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
222 printf ("Cant create socket\n");
223 return 0;
226 // Fill structure sockaddr_in
227 // 1) Family of protocols
228 serverSock.sin_family = AF_INET;
229 // 2) Number of server port
230 serverSock.sin_port = htons (port);
231 // 3) Setup ip address of server, where we want to connect
232 memcpy (&(serverSock.sin_addr), host->h_addr, host->h_length);
234 // Now we are able to connect to remote server
235 if (connect (zsock, (struct sockaddr *) &serverSock, sizeof (serverSock)) == -1) {
236 printf ("Connection cant be estabilished -> %s:%d\n", addr, port);
237 return -1;
240 // Set socket to non-blocking mode
241 int oldFlag = fcntl (zsock, F_GETFL, 0);
242 if (fcntl (zsock, F_SETFL, oldFlag | O_NONBLOCK) == -1) {
243 printf ("Cant set socket to nonblocking mode\n");
244 return 0;
247 printf ("zmail -> connected to %s:%d\n", addr, port);
249 buf = (char *) malloc (sizeof (char) * 500); // receive buffer
251 if (!buf)
252 return 0;
254 msg = (char *) malloc (sizeof (char) * 64);
256 if (!msg)
257 return 0;
259 size = 0;
261 config.state = STATE_CONNECTED;
263 return 1;
266 static int zmail_loop ()
268 int ret = recv (zsock, buf, 100, 0);
270 if (handle_input () == -1)
271 return -1;
273 if (ret > 0) {
274 setcolor (14, 0);
275 buf[ret] = '\0';
276 printf (buf);
278 zmail_proto (buf, ret);
279 } else {
280 if (ret == -1)
281 printf ("HOST -> Connection refused\n");
284 return ret;
287 int main (int argc, char **argv)
289 config.mails = 0;
290 config.state = 0;
291 config.user = strdup ("login@server");
292 config.pass = strdup ("pwd");
293 config.server = strdup ("server");
294 config.port = 110;
296 printf ("user: %s\nserver: %s\n", config.user, config.server);
298 int ret = zmail_init ((char *) config.server, config.port);
300 if (ret < 1)
301 goto end;
303 for (;; schedule ()) {
304 ret = zmail_loop ();
306 if (ret == -1)
307 break;
310 free (msg);
311 free (buf);
312 end:
313 printf ("zmail -> Bye !\n");
315 close (zsock);
317 return 0;