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/>.
26 #include <arpa/inet.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
32 #define STATE_CONNECTED 1
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
55 unsigned key_pressed (int keycode
)
57 int scancode
= getkey ();
59 if (scancode
== keycode
)
62 if (scancode
== keycode
+128)
68 static int send_to_socket (char *data
, unsigned len
)
71 if ((ret
= send (zsock
, data
, len
, 0)) == -1) {
72 printf ("ERROR -> send () = -1\n");
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)) {
85 printf ("You've got no email to read\n");
90 sprintf (str
, "RETR %d\n", config
.mails
--);
92 send_to_socket (str
, strlen (str
));
98 static int handle_input ()
118 zmail_commmand (msg
, size
);
123 if (key_pressed (ESC
))
129 void zmail_proto_user ()
132 sprintf (str
, "USER %s\n", config
.user
);
134 send_to_socket (str
, strlen (str
));
137 void zmail_proto_pass ()
140 sprintf (str
, "PASS %s\n", config
.pass
);
142 send_to_socket (str
, strlen (str
));
145 void zmail_proto_stat ()
148 sprintf (str
, "STAT\n");
150 send_to_socket (str
, strlen (str
));
153 int zmail_proto (char *buf
, int len
)
156 printf ("ERROR -> %s\n", buf
+5);
161 printf ("UNKNOWN cmd: %s\n", buf
);
169 /* OK - succefull action */
170 if (!strncmp (cmd
, "OK", 2)) {
171 if (config
.state
== STATE_CONNECTED
) {
173 char *s
= strchr (msg
, '@');
176 printf ("ERROR -> invalid authentication\n");
182 if (!strncmp (s
, config
.server
, strlen (config
.server
))) {
184 config
.state
= STATE_PASS
;
186 printf ("ERROR -> invalid authentication\n");
190 } else if (config
.state
== STATE_PASS
) {
191 config
.state
= STATE_WAIT
;
193 } else if (config
.state
== STATE_WAIT
) {
194 config
.state
= STATE_STAT
;
195 printf ("You are logged succefully as %s\n", config
.user
);
197 } else if (config
.state
== STATE_STAT
) {
198 config
.state
= STATE_LOGGED
;
199 char *s
= strchr (msg
, ' ');
203 printf ("You've got %s new email(s)\n", msg
);
205 config
.mails
= atoi (msg
);
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
);
221 if ((zsock
= socket (AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) == -1) {
222 printf ("Cant create socket\n");
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
);
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");
247 printf ("zmail -> connected to %s:%d\n", addr
, port
);
249 buf
= (char *) malloc (sizeof (char) * 500); // receive buffer
254 msg
= (char *) malloc (sizeof (char) * 64);
261 config
.state
= STATE_CONNECTED
;
266 static int zmail_loop ()
268 int ret
= recv (zsock
, buf
, 100, 0);
270 if (handle_input () == -1)
278 zmail_proto (buf
, ret
);
281 printf ("HOST -> Connection refused\n");
287 int main (int argc
, char **argv
)
291 config
.user
= strdup ("login@server");
292 config
.pass
= strdup ("pwd");
293 config
.server
= strdup ("server");
296 printf ("user: %s\nserver: %s\n", config
.user
, config
.server
);
298 int ret
= zmail_init ((char *) config
.server
, config
.port
);
303 for (;; schedule ()) {
313 printf ("zmail -> Bye !\n");