rohrpost

A commandline mail client to change the world as we see it.
git clone git://r-36.net/rohrpost
Log | Files | Refs | README | LICENSE

scan.c (4377B)


      1 /*
      2  * Copy me if you can.
      3  * by 20h
      4  */
      5 
      6 #include <unistd.h>
      7 #include <stdio.h>
      8 #include <stdlib.h>
      9 #include <time.h>
     10 #include <string.h>
     11 
     12 #include "ind.h"
     13 #include "arg.h"
     14 #include "cfg.h"
     15 #include "llist.h"
     16 #include "folder.h"
     17 #include "imap.h"
     18 #include "pager.h"
     19 #include "mime.h"
     20 #include "scan.h"
     21 
     22 void
     23 scan_print(char *id, char *date, char *from, char *subject)
     24 {
     25 	printf("%s\t%s\t%s\t%s\n", id, date, from, subject);
     26 }
     27 
     28 void
     29 scanusage(char *argv0)
     30 {
     31 	die("usage: %s [-h] [-c cfg] [-m folder] msgs\n", argv0);
     32 }
     33 
     34 int
     35 scanmain(int argc, char *argv[])
     36 {
     37 	config_t *cfg;
     38 	imap_t *imap;
     39 	int filelen;
     40 	char *user, *pass, *netspec, *selected, *date, *subject, *from,
     41 	     *id, *filec, *cfgn, *argv0;
     42 	llist_t *ids, *msgs;
     43 	llistelem_t *elem, *msg, *datee, *subjecte, *frome, *ide;
     44 	mime_t *mime;
     45 	struct tm *tim;
     46 
     47 	selected = NULL;
     48 	cfgn = NULL;
     49 
     50 	ARGBEGIN(argv0) {
     51 	case 'c':
     52 		cfgn = EARGF(scanusage(argv0));
     53 		break;
     54 	case 'm':
     55 		selected = EARGF(scanusage(argv0));
     56 		break;
     57 	default:
     58 		scanusage(argv0);
     59 	} ARGEND;
     60 
     61 	filelen = 0;
     62 	if (argc < 1) {
     63 		filec = readtoeoffd(0, &filelen);
     64 		if (filec == NULL)
     65 			edie("readtoeoffd");
     66 	} else {
     67 		filec = NULL;
     68 	}
     69 
     70 	cfg = config_init(cfgn);
     71 	if (filec == NULL) {
     72 		user = config_checkgetstr(cfg, "imapuser");
     73 		pass = config_checkgetstr(cfg, "imappass");
     74 		netspec = config_checkgetstr(cfg, "imapnet");
     75 		if (selected == NULL) {
     76 			selected = config_checkgetstr(cfg, "selected");
     77 		} else {
     78 			selected = memdup(selected, strlen(selected)+1);
     79 		}
     80 	}
     81 	if (cfg->name != NULL) {
     82 		cfgn = memdup(cfg->name, strlen(cfg->name)+1);
     83 	} else {
     84 		cfgn = memdup(cfgn, strlen(cfgn)+1);
     85 	}
     86 
     87 	config_free(cfg);
     88 
     89 	if (filec != NULL) {
     90 		scan_print("ID", "Date", "From", "Subject");
     91 
     92 		mime = mime_parsebuf(filec, filelen);
     93 		free(filec);
     94 		if (mime == NULL)
     95 			die("Input does not seem to be valid MIME.\n");
     96 
     97 		subjecte = llist_ciget(mime->hdrs, "subject");
     98 		datee = llist_ciget(mime->hdrs, "date");
     99 		frome = llist_ciget(mime->hdrs, "from");
    100 
    101 		if (subjecte != NULL) {
    102 			subject = mime_guessheader((char *)subjecte->data);
    103 		} else {
    104 			subject = "<empty>";
    105 		}
    106 
    107 		if (datee != NULL) {
    108 			tim = mime_parsedate((char *)datee->data);
    109 			if (tim != NULL)
    110 				date = smftime("%F/%H:%M", tim);
    111 			else
    112 				date = smprintf("invalid");
    113 			free(tim);
    114 		} else {
    115 			date = "<empty>";
    116 		}
    117 
    118 		if (frome != NULL) {
    119 			from = mime_guessheader((char *)frome->data);
    120 		} else {
    121 			from = "<empty>";
    122 		}
    123 
    124 		scan_print("", date, from, subject);
    125 
    126 		if (subjecte != NULL)
    127 			free(subject);
    128 		if (datee != NULL)
    129 			free(date);
    130 		if (frome != NULL)
    131 			free(from);
    132 
    133 		mime_free(mime);
    134 
    135 		goto scancleanup;
    136 	}
    137 
    138 	imap = imap_new(netspec, user, pass);
    139 	free(user);
    140 	free(pass);
    141 	free(netspec);
    142 
    143 	if (imap_init(imap))
    144 		imap_die(imap, "imap_init");
    145 	if (imap_select(imap, selected))
    146 		imap_die(imap, "imap_select");
    147 
    148 	ids = imap_argv2ids(cfgn, selected, argc, argv);
    149 	if (ids == NULL)
    150 		die("No msgids selected. Aborting.\n");
    151 
    152 	msgs = imap_fetchheaders(imap, ids);
    153 	if (msgs == NULL)
    154 		imap_die(imap, "imap_fetchheaders");
    155 	llist_free(ids);
    156 
    157 	scan_print("ID", "Date", "From", "Subject");
    158 	forllist(msgs, msg) {
    159 		elem = llist_get((llist_t *)msg->data, "literal");
    160 		if (elem == NULL)
    161 			continue;
    162 		mime = mime_parsebuf((char *)elem->data, elem->datalen);
    163 		if (mime == NULL)
    164 			continue;
    165 
    166 		ide = llist_get((llist_t *)msg->data, "id");
    167 		subjecte = llist_ciget(mime->hdrs, "subject");
    168 		datee = llist_ciget(mime->hdrs, "date");
    169 		frome = llist_ciget(mime->hdrs, "from");
    170 
    171 		if (subjecte != NULL) {
    172 			subject = mime_guessheader((char *)subjecte->data);
    173 		} else {
    174 			subject = "<empty>";
    175 		}
    176 
    177 		if (datee != NULL) {
    178 			tim = mime_parsedate((char *)datee->data);
    179 			if (tim != NULL)
    180 				date = smftime("%F/%H:%M", tim);
    181 			else
    182 				date = smprintf("invalid");
    183 			free(tim);
    184 		} else {
    185 			date = "<empty>";
    186 		}
    187 
    188 		if (frome != NULL) {
    189 			from = mime_guessheader((char *)frome->data);
    190 		} else {
    191 			from = "<empty>";
    192 		}
    193 
    194 		id = smprintf("rp:/%s/%s/%s",
    195 			(!strcmp(cfgn, "default")? "" : cfgn),
    196 			selected,
    197 			(char *)ide->data);
    198 
    199 		scan_print(id, date, from, subject);
    200 
    201 		free(id);
    202 
    203 		if (subjecte != NULL)
    204 			free(subject);
    205 		if (datee != NULL)
    206 			free(date);
    207 		if (frome != NULL)
    208 			free(from);
    209 
    210 		mime_free(mime);
    211 	}
    212 	llist_efree(msgs);
    213 
    214 scancleanup:
    215 	free(cfgn);
    216 	if (filec == NULL) {
    217 		free(selected);
    218 		imap_close(imap);
    219 		imap_free(imap);
    220 	}
    221 	return 0;
    222 }
    223