dmc

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

mbox.c (3067B)


      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 <stdlib.h>
      8 #include <unistd.h>
      9 
     10 #define SZ 1024
     11 
     12 FILE *fd;
     13 static char word[SZ];
     14 
     15 static void mbox_ls() {
     16 	char b[SZ], from[SZ], subject[SZ], date[SZ], *ptr;
     17 	int m = 0, headers = 1;
     18 
     19 	b[SZ-1] = '\0';
     20 	fseek (fd, 0, SEEK_SET);
     21 	while (fgets (b, SZ-1, fd)) {
     22 		if (b[0]=='\n') {
     23 			if (headers) {
     24 				printf ("%i  %s  %s  %s\n", m++, from, date, subject);
     25 				headers = 0;
     26 			} else {
     27 				fgets (b, SZ-1, fd);
     28 				if (!memcmp (b, "From ", 5))
     29 					headers = 1;
     30 			}
     31 		}
     32 		if (headers) {
     33 			if (!memcmp (b, "From: ", 6)) {
     34 				strncpy (from, b+6, SZ-1);
     35 				from[SZ-1] = '\0';
     36 				if ((ptr = strchr (from, '\n')))
     37 					ptr[0] = '\0';
     38 			} else
     39 			if (!memcmp (b, "Subject: ", 9)) {
     40 				strncpy (subject, b+9, SZ-1);
     41 				subject[SZ-1] = '\0';
     42 				if ((ptr = strchr (subject, '\n')))
     43 					ptr[0] = '\0';
     44 			} else
     45 			if (!memcmp (b, "Date: ", 6)) {
     46 				strncpy (date, b+6, SZ-1);
     47 				date[SZ-1] = '\0';
     48 				if ((ptr = strchr (date, '\n')))
     49 					ptr[0] = '\0';
     50 			}
     51 		}
     52 	}
     53 }
     54 
     55 static void mbox_cat(int idx, int body) {
     56 	char b[SZ];
     57 	int m = 0, headers = 1;
     58 
     59 	b[SZ-1] = '\0';
     60 	fseek (fd, 0, SEEK_SET);
     61 	while (fgets (b, SZ-1, fd)) {
     62 		if (b[0]=='\n') {
     63 			if (!headers) {
     64 				fgets (b, SZ-1, fd);
     65 				if (!memcmp (b, "From ", 5)) {
     66 					headers = 1;
     67 					m++;
     68 				}
     69 			} else headers = 0;
     70 		}
     71 		if (m == idx && (headers || body))
     72 			fputs (b, stdout);
     73 	}
     74 }
     75 
     76 static void mbox_rm (int idx) {
     77 	char b[SZ], *buf;
     78 	int m = 0, i = 0, headers = 1, size;
     79 
     80 	fseek(fd, 0, SEEK_END);
     81 	size = ftell (fd);
     82 	if (!(buf = malloc (size)))
     83 		return;
     84 	b[SZ-1] = '\0';
     85 	fseek (fd, 0, SEEK_SET);
     86 	while (fgets (b, SZ-1, fd)) {
     87 		if (b[0]=='\n') {
     88 			if (!headers) {
     89 				fgets (b, SZ-1, fd);
     90 				if (!memcmp (b, "From ", 5)) {
     91 					headers = 1;
     92 					if (++m == idx) {
     93 						strcpy (buf + i, "\n");
     94 						i += 1;
     95 					}
     96 				}
     97 			} else headers = 0;
     98 		}
     99 		if (m != idx) {
    100 			strcpy (buf + i, b);
    101 			i += strlen (b);
    102 		}
    103 	}
    104 	fseek (fd, 0, SEEK_SET);
    105 	fwrite (buf, 1, i, fd);
    106 	fflush (fd);
    107 	ftruncate (fileno (fd), i);
    108 	free (buf);
    109 }
    110 
    111 static char *getword () {
    112 	fscanf (stdin, "%255s", word);
    113 	if (feof (stdin))
    114 		*word = '\0';
    115 	return word;
    116 }
    117 
    118 static int doword (char *word) {
    119 	int ret = 1;
    120 	if (*word == '\0') {
    121 		/* Do nothing */
    122 	} else if (!strcmp (word, "ls")) {
    123 		mbox_ls ();
    124 	} else if (!strcmp (word, "cat")) {
    125 		mbox_cat (atoi (getword ()), 1);
    126 	} else if (!strcmp (word, "rm")) {
    127 		mbox_rm (atoi (getword ()));
    128 	} else if (!strcmp (word, "head")) {
    129 		mbox_cat (atoi (getword ()), 0);
    130 	} else if (!strcmp (word, "login")) {
    131 		getword (); // ignore login
    132 		getword (); // ignore password
    133 	} else if (!strcmp (word, "exit"))
    134 		ret = 0;
    135 	return ret;
    136 }
    137 
    138 int main (int argc, char **argv) {
    139 	int ret = 1;
    140 	if (argc>1) {
    141 		fd = fopen (argv[1], "r+");
    142 		if (fd != NULL) {
    143 			while (doword (getword ()));
    144 			ret = fclose (fd);
    145 		} else printf ("Cannot open %s\n", argv[1]);
    146 	} else printf ("Usage: dmc-mbox [mbox-file] 2> body > fifo < input\n");
    147 	return ret;
    148 }