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 }