diff uip/pick.c @ 0:bce86c4163a3

Initial revision
author kono
date Mon, 18 Apr 2005 23:46:02 +0900
parents
children a6481689f99c
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/uip/pick.c	Mon Apr 18 23:46:02 2005 +0900
@@ -0,0 +1,303 @@
+/* pick.c - select messages by content */
+#ifndef lint
+static char ident[] = "@(#)$Id$";
+#endif	/*  lint */
+
+#include "../h/mh.h"
+#include "../zotnet/tws.h"
+#include <stdio.h>
+#ifdef LOCALE
+#include	<locale.h>
+#endif
+
+/*  */
+
+static struct swit switches[] = {
+#define	ANDSW	0
+    "and", 0,
+#define	ORSW	1
+    "or", 0,
+#define	NOTSW	2
+    "not", 0,
+#define	LBRSW	3
+    "lbrace", 0,
+#define	RBRSW	4
+    "rbrace", 0,
+
+#define	CCSW	5
+    "cc  pattern", 0,
+#define	DATESW	6
+    "date  pattern", 0,
+#define	FROMSW	7
+    "from  pattern", 0,
+#define	SRCHSW	8
+    "search  pattern", 0,
+#define	SUBJSW	9
+    "subject  pattern", 0,
+#define	TOSW	10
+    "to  pattern", 0,
+#define	OTHRSW	11
+    "-othercomponent  pattern", 0,
+#define	AFTRSW	12
+    "after date", 0,
+#define	BEFRSW	13
+    "before date", 0,
+#define	DATFDSW	14
+    "datefield field", 5,
+
+#define	SEQSW	15
+    "sequence name", 0,
+#define	PUBLSW	16
+    "public", 0,
+#define	NPUBLSW	17
+    "nopublic", 0,
+#define	ZEROSW	18
+    "zero", 0,
+#define	NZEROSW	19
+    "nozero", 0,
+
+#define	LISTSW	20
+    "list", 0,
+#define	NLISTSW	21
+    "nolist", 0,
+
+#define	HELPSW	22
+    "help", 4,
+
+    NULL, 0
+};
+
+/*  */
+
+static int  listsw = 0;
+
+/*  */
+
+/* ARGSUSED */
+
+main (argc, argv)
+char   *argv[];
+{
+    int     publicsw = -1,
+            zerosw = 1,
+            msgp = 0,
+            seqp = 0,
+            vecp = 0,
+	    lo,
+	    hi,
+            msgnum;
+    char   *maildir,
+           *folder = NULL,
+            buf[100],
+           *cp,
+          **ap,
+          **argp,
+           *arguments[MAXARGS],
+           *msgs[MAXARGS],
+           *seqs[NATTRS + 1],
+           *vec[MAXARGS];
+    struct msgs *mp;
+    register FILE *fp;
+
+#ifdef LOCALE
+	setlocale(LC_ALL, "");
+#endif
+#ifdef JAPAN
+	ml_init();
+#endif /* JAPAN */
+    invo_name = r1bindex (argv[0], '/');
+    if ((cp = m_find (invo_name)) != NULL) {
+	ap = brkstring (cp = getcpy (cp), " ", "\n");
+	ap = copyip (ap, arguments);
+    }
+    else
+	ap = arguments;
+    (void) copyip (argv + 1, ap);
+    argp = arguments;
+
+/*  */
+
+    while (cp = *argp++) {
+	if (*cp == '-') {
+	    if (*++cp == '-') {
+		vec[vecp++] = --cp;
+		goto pattern;
+	    }
+	    switch (smatch (cp, switches)) {
+		case AMBIGSW: 
+		    ambigsw (cp, switches);
+		    done (1);
+		case UNKWNSW: 
+		    adios (NULLCP, "-%s unknown", cp);
+		case HELPSW: 
+		    (void) sprintf (buf, "%s [+folder] [msgs] [switches]",
+			    invo_name);
+		    help (buf, switches);
+		    listsw = 0;	/* HACK */
+		    done (1);
+
+		case CCSW: 
+		case DATESW: 
+		case FROMSW: 
+		case SUBJSW: 
+		case TOSW: 
+		case DATFDSW: 
+		case AFTRSW: 
+		case BEFRSW: 
+		case SRCHSW: 
+		    vec[vecp++] = --cp;
+	    pattern: ;
+		    if (!(cp = *argp++))/* allow -xyz arguments */
+			adios (NULLCP, "missing argument to %s", argp[-2]);
+		    vec[vecp++] = cp;
+		    continue;
+		case OTHRSW: 
+		    adios (NULLCP, "internal error!");
+
+		case ANDSW:
+		case ORSW:
+		case NOTSW:
+		case LBRSW:
+		case RBRSW:
+		    vec[vecp++] = --cp;
+		    continue;
+
+		case SEQSW: 
+		    if (!(cp = *argp++) || *cp == '-')
+			adios (NULLCP, "missing argument to %s", argp[-2]);
+		    if (seqp < NATTRS)
+			seqs[seqp++] = cp;
+		    else
+			adios (NULLCP, "only %d sequences allowed!", NATTRS);
+		    listsw = 0;
+		    continue;
+		case PUBLSW: 
+		    publicsw = 1;
+		    continue;
+		case NPUBLSW: 
+		    publicsw = 0;
+		    continue;
+		case ZEROSW: 
+		    zerosw++;
+		    continue;
+		case NZEROSW: 
+		    zerosw = 0;
+		    continue;
+
+		case LISTSW: 
+		    listsw++;
+		    continue;
+		case NLISTSW: 
+		    listsw = 0;
+		    continue;
+	    }
+	}
+	if (*cp == '+' || *cp == '@')
+	    if (folder)
+		adios (NULLCP, "only one folder at a time!");
+	    else
+		folder = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
+	else
+	    msgs[msgp++] = cp;
+    }
+    vec[vecp] = NULL;
+
+/*  */
+
+    if (!m_find ("path"))
+	free (path ("./", TFOLDER));
+    if (!msgp)
+	msgs[msgp++] = "all";
+    if (!folder)
+	folder = m_getfolder ();
+    maildir = m_maildir (folder);
+
+    if (chdir (maildir) == NOTOK)
+	adios (maildir, "unable to change directory to");
+    if (!(mp = m_gmsg (folder)))
+	adios (NULLCP, "unable to read folder %s", folder);
+    if (mp -> hghmsg == 0)
+	adios (NULLCP, "no messages in %s", folder);
+
+    for (msgnum = 0; msgnum < msgp; msgnum++)
+	if (!m_convert (mp, msgs[msgnum]))
+	    done (1);
+    m_setseq (mp);
+
+    if (seqp == 0)
+	listsw++;
+    if (publicsw == -1)
+	publicsw = mp -> msgflags & READONLY ? 0 : 1;
+    if (publicsw && (mp -> msgflags & READONLY))
+	adios (NULLCP, "folder %s is read-only, so -public not allowed",
+		folder);
+
+/*  */
+
+    if (!pcompile (vec, NULLCP))
+	done (1);
+
+    lo = mp -> lowsel;
+    hi = mp -> hghsel;
+
+    for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
+	if (mp -> msgstats[msgnum] & SELECTED) {
+	    if ((fp = fopen (cp = m_name (msgnum), "r")) == NULL)
+		admonish (cp, "unable to read message");
+	    if (fp && pmatches (fp, msgnum, 0L, 0L)) {
+		if (msgnum < lo)
+		    lo = msgnum;
+		if (msgnum > hi)
+		    hi = msgnum;
+	    }
+	    else {
+		mp -> msgstats[msgnum] &= ~SELECTED;
+		mp -> numsel--;
+	    }
+	    if (fp)
+		(void) fclose (fp);
+	}
+
+    mp -> lowsel = lo;
+    mp -> hghsel = hi;
+
+    if (mp -> numsel <= 0)
+	adios (NULLCP, "no messages match specification");
+
+/*  */
+
+    seqs[seqp] = NULL;
+    for (seqp = 0; seqs[seqp]; seqp++) {
+	if (zerosw && !m_seqnew (mp, seqs[seqp], publicsw))
+	    done (1);
+	for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
+	    if (mp -> msgstats[msgnum] & SELECTED)
+		if (!m_seqadd (mp, seqs[seqp], msgnum, publicsw))
+		    done (1);
+    }
+
+    if (listsw) {
+	for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
+	    if (mp -> msgstats[msgnum] & SELECTED)
+		printf ("%s\n", m_name (msgnum));
+    }
+    else
+	printf ("%d hit%s\n", mp -> numsel,
+		mp -> numsel == 1 ? "" : "s");
+
+    m_replace (pfolder, folder);
+    m_sync (mp);
+    m_update ();
+
+    done (0);
+}
+
+/*  */
+
+void done (status)
+int	status;
+{
+    if (listsw && status && !isatty (fileno (stdout)))
+	printf ("0\n");
+    exit (status);
+}