dmc

dynamic mail client
git clone git://git.suckless.org/dmc
Log | Files | Refs | README | LICENSE

pop3.c (2637B)


      1 /* dmc - dynamic mail client
      2  * See LICENSE file for copyright and license details.
      3  */
      4 
      5 #include <stdio.h>
      6 #include <string.h>
      7 #include <signal.h>
      8 #include <stdlib.h>
      9 #include <unistd.h>
     10 #include <sys/types.h>
     11 #include <sys/stat.h>
     12 #include <fcntl.h>
     13 #include <poll.h>
     14 #include "sock.c"
     15 
     16 #define STRSZ 4095
     17 static char cmd[STRSZ], word[STRSZ];
     18 
     19 static char *getword() {
     20 	fscanf (stdin, "%s", word);
     21 	if (feof (stdin))
     22 		*word = '\0';
     23 	return word;
     24 }
     25 
     26 static int waitreply(int foo) {
     27 	char *ch, *str, res[STRSZ];
     28 	int reply = -1;
     29 
     30 	ftruncate (2, 0);
     31 	lseek (2, 0, SEEK_SET);
     32 	*res = '\0';
     33 	while (sock_ready () && sock_read (word, sizeof (word)) > 1) {
     34 		str = word;
     35 		if (reply == -1 && (reply = (word[0] == '+'))) {
     36 			if ((ch = strchr (str, '\r')) || (ch = strchr (str, '\n'))) {
     37 				*ch = '\0';
     38 				snprintf (res, sizeof (res), "### %s %d \"%s\"\n", cmd, reply, str);
     39 				str = ch + (ch[1] == '\n' ? 2 : 1);
     40 			}
     41 		}
     42 		// TODO: Fix possible \r\n issues
     43 		if ((ch = strstr (str, "\r\n.")))
     44 			*ch = '\0';
     45 		write (2, str, strlen (str));
     46 	}
     47 	write (2, "\n", 1);
     48 	if (foo) {
     49 		if (!*res)
     50 			snprintf (res, sizeof (res), "### %s %d \"\"\n", cmd, reply);
     51 		write (1, res, strlen (res));
     52 	}
     53 	return reply;
     54 }
     55 
     56 static int doword(char *word) {
     57 	int ret = 1;
     58 	strcpy (cmd, word);
     59 
     60 	if (*word == '\0') {
     61 		/* Do nothing */
     62 	} else
     63 	if (!strcmp (word, "exit")) {
     64 		sock_printf ("QUIT\n");
     65 		waitreply (1);
     66 		ret = 0;
     67 	} else
     68 	if (!strcmp (word, "help") || !strcmp (word, "?")) {
     69 		printf ("Use: ls cat head rm login exit\n");
     70 	} else
     71 	if (!strcmp (word, "ls")) {
     72 		sock_printf ("LIST\n");
     73 		waitreply (1);
     74 	} else
     75 	if (!strcmp (word, "cat")) {
     76 		sock_printf ("RETR %d\n", atoi (getword ()));
     77 		waitreply (1);
     78 	} else
     79 	if (!strcmp (word, "head")) {
     80 		sock_printf ("TOP %d 50\n", atoi (getword ()));
     81 		waitreply (1);
     82 	} else
     83 	if (!strcmp (word, "rm")) {
     84 		sock_printf ("DELE %d\n", atoi (getword ()));
     85 		waitreply (1);
     86 	} else
     87 	if (!strcmp (word, "login")) {
     88 		sock_printf ("USER %s\n", getword ());
     89 		waitreply (0); // TODO: if user fail, do not send pass
     90 		sock_printf ("PASS %s\n", getword ());
     91 		waitreply (1);
     92 	} else sock_printf ("NOOP\n");
     93 	return ret;
     94 }
     95 
     96 int main(int argc, char **argv) {
     97 	int ssl = 0, ret = 1;
     98 	if (argc > 2) {
     99 		if (argc > 3)
    100 			ssl = (*argv[3] == '1');
    101 		if (sock_connect (argv[1], atoi (argv[2]), ssl) >= 0) {
    102 			ret = atexit (sock_close);
    103 			strcpy (cmd, ".");
    104 			waitreply (1);
    105 			while (doword (getword ()));
    106 		} else {
    107 			printf ("## on -1 Cannot connect to %s %d\n", argv[1], atoi (argv[2]));
    108 			fprintf(stderr, "\n");
    109 		}
    110 	} else printf ("Usage: dmc-pop3 host port [ssl] 2> body > fifo < input\n");
    111 	return 0;
    112 }