rohrpost

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

flag.c (4459B)


      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 <strings.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 "flag.h"
     19 
     20 llist_t *
     21 flag_sanitize(char *flags)
     22 {
     23 	llist_t *aflags, *rflags;
     24 	llistelem_t *flag;
     25 
     26 	aflags = llist_splitstr(flags, " ,");
     27 	if (aflags == NULL)
     28 		return NULL;
     29 
     30 	rflags = llist_new();
     31 	forllist(aflags, flag) {
     32 		if (!strcasecmp(flag->key, "seen"))
     33 			llist_add(rflags, "\\Seen", NULL, 0);
     34 		else if (!strcasecmp(flag->key, "answered"))
     35 			llist_add(rflags, "\\Answered", NULL, 0);
     36 		else if (!strcasecmp(flag->key, "flagged"))
     37 			llist_add(rflags, "\\Flagged", NULL, 0);
     38 		else if (!strcasecmp(flag->key, "deleted"))
     39 			llist_add(rflags, "\\Deleted", NULL, 0);
     40 		else if (!strcasecmp(flag->key, "draft"))
     41 			llist_add(rflags, "\\Draft", NULL, 0);
     42 		else if (!strcasecmp(flag->key, "recent"))
     43 			llist_add(rflags, "\\Recent", NULL, 0);
     44 		else
     45 			continue;
     46 	}
     47 	llist_free(aflags);
     48 	if (rflags->len < 1) {
     49 		llist_free(rflags);
     50 		return NULL;
     51 	}
     52 
     53 	return rflags;
     54 }
     55 
     56 void
     57 flagsyntax(void)
     58 {
     59 	fprintf(stderr, "The 'flag' parameter should be an enclosed argument, "
     60 			"consisting of space separated flags.\n"
     61 			"\n"
     62 			"The flags will be converted in the following way:\n"
     63 			"\t'seen' -> '\\Seen'\n"
     64 			"\t'answered' -> '\\Answered'\n"
     65 			"\t'flagged' -> '\\Flagged'\n"
     66 			"\t'deleted' -> '\\Deleted'\n"
     67 			"\t'draft' -> '\\Draft'\n"
     68 			"\t'recent' -> '\\Recent'\n"
     69 			"\n"
     70 			"Example: ... inc -d \"seen flagged\" 10\n");
     71 	exit(1);
     72 }
     73 
     74 void
     75 flagusage(char *argv0)
     76 {
     77 	die("usage: %s [-fhu] [-c cfg] [-m folder] [[-s|-d] flag] [msgs]\n"
     78 		"Use -f for displaying the flag syntax.\n", argv0);
     79 }
     80 
     81 int
     82 flagmain(int argc, char *argv[])
     83 {
     84 	config_t *cfg;
     85 	imap_t *imap;
     86 	int status;
     87 	char *user, *pass, *netspec, *selected, *cfgn, *argv0;
     88 	llist_t *ids, *flagl, *flagrl, *flagel;
     89 	llistelem_t *elem;
     90 
     91 	enum {
     92 		BEQUIET = 0x01,
     93 		DOSET = 0x02,
     94 		DODELETE = 0x04,
     95 		SETSEEN = 0x08,
     96 
     97 		NOARGS = 0x10
     98 	};
     99 
    100 	status = 0;
    101 	flagl = NULL;
    102 	selected = NULL;
    103 	cfgn = NULL;
    104 
    105 	ARGBEGIN(argv0) {
    106 	case 'c':
    107 		cfgn = EARGF(flagusage(argv0));
    108 		break;
    109 	case 'd':
    110 		status |= DODELETE;
    111 		break;
    112 	case 'f':
    113 		flagsyntax();
    114 		break;
    115 	case 'm':
    116 		selected = EARGF(flagusage(argv0));
    117 		break;
    118 	case 'q':
    119 		status |= BEQUIET;
    120 		break;
    121 	case 's':
    122 		status |= DOSET;
    123 		break;
    124 	case 'u':
    125 		status |= SETSEEN;
    126 		break;
    127 	default:
    128 		flagusage(argv0);
    129 	} ARGEND;
    130 
    131 	if (argc < 1 && !(status & SETSEEN))
    132 		flagusage(argv0);
    133 
    134 	if (status & DOSET || status & DODELETE) {
    135 		flagl = flag_sanitize(argv[0]);
    136 		if (flagl == NULL)
    137 			flagsyntax();
    138 		argc--;
    139 		argv = &argv[1];
    140 	}
    141 	if (argc < 1 && !(status & SETSEEN))
    142 		flagusage(argv0);
    143 
    144 	cfg = config_init(cfgn);
    145 	user = config_checkgetstr(cfg, "imapuser");
    146 	pass = config_checkgetstr(cfg, "imappass");
    147 	netspec = config_checkgetstr(cfg, "imapnet");
    148 	if (selected == NULL) {
    149 		selected = config_checkgetstr(cfg, "selected");
    150 	} else {
    151 		selected = memdups(selected);
    152 	}
    153 	config_free(cfg);
    154 
    155 	if (status & SETSEEN) {
    156 		if (argc == 0) {
    157 			argc = 1;
    158 			argv = (char *[]){ "u", NULL };
    159 		}
    160 
    161 		flagl = flag_sanitize("seen");
    162 		if (flagl == NULL)
    163 			flagsyntax();
    164 		status |= DOSET;
    165 	}
    166 
    167 	ids = imap_argv2ids(cfgn, selected, argc, argv);
    168 	if (ids == NULL)
    169 		die("No msgids selected. Aborting.\n");
    170 
    171 	imap = imap_new(netspec, user, pass);
    172 	free(user);
    173 	free(pass);
    174 	free(netspec);
    175 
    176 	if (imap_init(imap))
    177 		imap_die(imap, "imap_init");
    178 	if (imap_select(imap, selected))
    179 		imap_die(imap, "imap_select");
    180 
    181 	if (flagl != NULL) {
    182 		pass = llist_joinstr(flagl, " ");
    183 	} else {
    184 		pass = NULL;
    185 	}
    186 
    187 	if (status & DOSET) {
    188 		if (imap_setflags(imap, ids, flagl))
    189 			imap_die(imap, "imap_setflags");
    190 	} else if (status & DODELETE) {
    191 		if (imap_delflags(imap, ids, flagl))
    192 			imap_die(imap, "imap_delflags");
    193 	}
    194 
    195 	flagrl = imap_getflags(imap, ids);
    196 	if (flagrl == NULL)
    197 		imap_die(imap, "imap_getflags");
    198 	llist_free(ids);
    199 
    200 	printf("ID\tFlags\n");
    201 
    202 	forllist(flagrl, elem) {
    203 		flagel = (llist_t *)elem->data;
    204 		user = llist_joinstr((llist_t *)flagel->last->data,
    205 				" ");
    206 		if (user == NULL)
    207 			user = memdup("", 1);
    208 		printf("%s\t%s\n", (char *)flagel->first->data, user);
    209 		free(user);
    210 		user = NULL;
    211 	}
    212 	llist_efree(flagrl);
    213 
    214 	if (flagl != NULL)
    215 		llist_free(flagl);
    216 	if (user != NULL)
    217 		free(user);
    218 	if (pass != NULL)
    219 		free(pass);
    220 	free(selected);
    221 	imap_close(imap);
    222 	imap_free(imap);
    223 
    224 	return 0;
    225 }
    226