Commit da2d079d authored by Richard Curnow's avatar Richard Curnow

Corresponds to CVS V0.12

Original rev  : rc@rc0.org.uk--historical/mairix--history--0--patch-22
parent 54d79744
......@@ -9,8 +9,10 @@ Dan Egnor
Emil Sit
James Leifer
Jerry Jorgenson
Joerg Desch
John Arthur Kane
John Keener
Josh Purinton
Kevin Rosenberg
Mikael Ylikoski
Robert Hofer
......@@ -18,6 +20,7 @@ Roberto Boati
Satyaki Das
Vladimir V. Kisil
Will Yardley
Wolfgang Weisselberg
I apologise to any contributors who have been omitted from this list!
#########################################################################
#
# $Header: /cvs/src/mairix/Attic/Makefile,v 1.7 2003/03/12 23:57:40 richard Exp $
# $Header: /cvs/src/mairix/Makefile.in,v 1.5 2003/12/04 22:18:07 richard Exp $
#
# =======================================================================
#
......@@ -25,23 +25,31 @@
#########################################################################
# Edit the following variables as required
CC=gcc
#CFLAGS=-O2
#CFLAGS=-O2 -pg
CFLAGS=-Wall -g
prefix=/usr/local
bindir=$(prefix)/bin
mandir=$(prefix)/man
CC=@cc@
CFLAGS=@cflags@ @defs@
#######################################################################
# If you're generating a package, you may want to use
# make DESTDIR=temporary_dir install
# to get the software installed to a directory where you can create
# a tdl.tar.gz from it
DESTDIR=
#######################################################################
prefix=$(DESTDIR)@prefix@
bindir=$(DESTDIR)@bindir@
mandir=$(DESTDIR)@mandir@
man1dir=$(mandir)/man1
infodir=$(prefix)/info
docdir=$(prefix)/docs
infodir=$(DESTDIR)@infodir@
docdir=$(DESTDIR)@docdir@
#########################################################################
# Things below this point shouldn't need to be edited.
OBJ = mairix.o db.o rfc822.o tok.o hash.o dirscan.o writer.o \
reader.o search.o stats.o dates.o datescan.o
reader.o search.o stats.o dates.o datescan.o mbox.o md5.o \
fromcheck.o glob.o
all : mairix
......@@ -54,14 +62,21 @@ mairix : $(OBJ)
datescan.c : datescan.nfa dfasyn/dfasyn
dfasyn/dfasyn -o datescan.c -v -u datescan.nfa
fromcheck.c : fromcheck.nfa dfasyn/dfasyn
dfasyn/dfasyn -o fromcheck.c -v -u fromcheck.nfa
dfasyn/dfasyn:
if [ -d dfasyn ]; then cd dfasyn ; make CC="$(CC)" CFLAGS="$(CFLAGS)" ; else echo "No dfasyn subdirectory?" ; exit 1 ; fi
clean:
-rm -f *~ *.o mairix *.s core mairix.txt mairix.html mairix.dvi mairix.ps mairix.pdf mairix.info
-rm -f mairix.cp mairix.fn mairix.aux mairix.log mairix.ky mairix.pg mairix.toc mairix.tp mairix.vr
-rm -f fromcheck.c datescan.c
if [ -d dfasyn ]; then cd dfasyn ; make clean ; fi
distclean: clean
-rm -f Makefile config.log
install:
[ -d $(prefix) ] || mkdir -p $(prefix)
[ -d $(bindir) ] || mkdir -p $(bindir)
......
NEW IN VERSION 0.12
===================
! Change in database file format - existing databases need to be destroyed and
recreated.
* Indexing of mbox folders in addition to the existing maildir & MH support
* Output to mbox format vfolder
* Return exit status 1 if no messages are matched in search mode, and exit
status 2 for all error conditions.
* Allow wildcards to be used in specifying maildir and mh folder paths.
* Searching on messages having a particular Message-ID (m:msgid expression in
search mode).
* When indexing whole email addresses, '+' is now considered a valid character.
* Use ',' instead of '+' in search expressions, and '/' instead of ','. This
is to allow '+' to be used inside email addresses that are being searched
for. The '/' character is traditionally associated with meaning 'or', so it
made more sense to move ',' to mean 'and'. (Unfortunately, there were very
few metacharacters left which don't have some special meaning to shells, and
I wanted to avoid the need to quote or escape the search expressions.)
* Bug fix checking return status of mmap.
* Handle ">From " at the start of the message headers
* Handle mis-formatted encoding strings "7 bit" and "8 bit"
* Make every database use a random seed for the token hash function (to prevent
denial of service attacks against mairix through carefully crafted messages.)
* Rename some options in the mairixrc file, to put the folder formats on an
equal footing.
* Properly handle the case where a maildir vfolder exists but one or more of
the new,tmp,cur subdirectories is missing.
* Add configure script (not autoconf-based)
NEW IN VERSION 0.11
===================
......
......@@ -46,5 +46,4 @@ The website for mairix is http://www.rc0.org.uk/mairix
ACKNOWLEDGEMENTS
================
* John Keener found and fixed several bugs in v0.2.
See the ACKNOWLEDGEMENTS file
#!/usr/bin/env perl
system("make mairix.txt");
system("make -f Makefile.in mairix.txt");
unlink "build_kit";
($version = $ARGV[0]) || ($version = "UNKNOWN");
......@@ -15,5 +16,5 @@ close (OUT);
unlink "mairix.spec.sample";
system("cvs export -d dfasyn -r V0_2 dfasyn");
system("cvs export -d dfasyn -r V0_3 dfasyn");
#!/bin/sh
#########################################################################
#
# $Id: configure,v 1.5 2003/12/04 23:06:35 richard Exp $
#
# =======================================================================
#
# mairix - message index builder and finder for maildir folders.
#
# Copyright (C) Richard P. Curnow 2003
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
#
# =======================================================================
if [ -f config.log ]; then rm -f config.log ; fi
exec 5>config.log
if [ "x${CC}" = "x" ]; then
MYCC="gcc"
else
MYCC="${CC}"
fi
if [ "x${CFLAGS}" = "x" ]; then
MYCFLAGS="-O2 -Wall"
else
MYCFLAGS="${CFLAGS}"
fi
# =======================================================================
# Functions
#{{{ cleanup
cleanup () {
if [ -f docheck.c ]; then rm -f docheck.c ; fi
if [ -f docheck.o ]; then rm -f docheck.o ; fi
if [ -f docheck ]; then rm -f docheck ; fi
rm -rf docheck.c docheck.o docheck
}
#}}}
#{{{ test_cc : basic compiler sanity check
test_cc () {
printf "Testing whether your compiler \"$MYCC $MYCFLAGS\" works : "
cat >docheck.c <<EOF;
#include <stdio.h>
int main (int argc, char **argv)
{
return 0;
}
EOF
${MYCC} ${MYCFLAGS} -o docheck docheck.c 1>&5 2>&5
if [ $? -eq 0 ]
then
printf "it works\n"
else
printf "it doesn't work\n"
printf "Failed program was\n" 1>&5
cat docheck.c 1>&5
rm -f docheck.c docheck
exit 1
fi
cleanup
}
#}}}
#{{{ test_for_stdint_h
test_for_stdint_h () {
cat >docheck.c <<EOF;
#include <stdint.h>
int main(int argc, char **argv) {
return 0;
}
EOF
${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
if [ $? -eq 0 ]
then
result=0
else
result=1
fi
rm -f docheck.c docheck.o
echo $result
}
#}}}
#{{{ test_for_inttypes_h
test_for_inttypes_h () {
cat >docheck.c <<EOF;
#include <inttypes.h>
int main(int argc, char **argv) {
return 0;
}
EOF
${MYCC} ${MYCFLAGS} -c -o docheck.o docheck.c >/dev/null 2>&1
if [ $? -eq 0 ]
then
result=0
else
result=1
fi
rm -f docheck.c docheck.o
echo $result
}
#}}}
#{{{ usage
usage () {
cat <<EOF;
\`configure' configures tdl to adapt to many kinds of systems.
Usage: ./configure [OPTION]...
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
[/usr/local]
By default, \`make install' will install all the files in
\`/usr/local/bin', \`/usr/local/lib' etc. You can specify
an installation prefix other than \`/usr/local' using \`--prefix',
for instance \`--prefix=$HOME'.
Fine tuning of the installation directories:
--bindir=DIR user executables [EPREFIX/bin]
--infodir=DIR info documentation [PREFIX/info]
--mandir=DIR man documentation [PREFIX/man]
--docdir=DIR other documentation [PREFIX/doc/mairix-\$version]
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
Use these variables to override the choices made by \`configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to <rc@rc0.org.uk>.
EOF
}
#}}}
# =======================================================================
# Defaults for variables
PREFIX=/usr/local
use_readline=yes
bad_options=no
# Parse options to configure
for option
do
case "$option" in
--prefix=* | --install-prefix=* )
PREFIX=`echo $option | sed -e 's/[^=]*=//;'`
;;
--bindir=* )
BINDIR=`echo $option | sed -e 's/[^=]*=//;'`
;;
--mandir=* )
MANDIR=`echo $option | sed -e 's/[^=]*=//;'`
;;
--infodir=* )
INFODIR=`echo $option | sed -e 's/[^=]*=//;'`
;;
--docdir=* )
DOCDIR=`echo $option | sed -e 's/[^=]*=//;'`
;;
-h | --help )
usage
exit 1
;;
* )
printf "Unrecognized option : $option\n"
bad_options=yes
;;
esac
done
if [ ${bad_options} = yes ]; then
exit 1
fi
DEFS=""
test_cc
printf "Checking for <stdint.h> : "
if [ `test_for_stdint_h` -eq 0 ]; then
printf "Yes\n"
DEFS="${DEFS} -DHAS_STDINT_H"
else
printf "No\n"
fi
printf "Checking for <inttypes.h> : "
if [ `test_for_inttypes_h` -eq 0 ]; then
printf "Yes\n"
DEFS="${DEFS} -DHAS_INTTYPES_H"
else
printf "No\n"
fi
#{{{ Determine version number of the program.
# (CVS tags are of the form V1_0 for version 1.0)
Name="ZZZ"
revision="$Name: V0_12 $";
if [ "$revision" = "ZZZ\$" ]; then revision="dev"; fi
revision=`echo $revision | sed 's/_/./g;' | sed 's/ZZZ: V//;' | sed 's/ \$$//;'`
#}}}
if [ "x" = "x${BINDIR}" ]; then BINDIR=${PREFIX}/bin ; fi
if [ "x" = "x${MANDIR}" ]; then MANDIR=${PREFIX}/man ; fi
if [ "x" = "x${INFODIR}" ]; then INFODIR=${PREFIX}/info ; fi
if [ "x" = "x${DOCDIR}" ]; then DOCDIR=${PREFIX}/doc/mairix-${revision} ; fi
echo "Generating Makefile"
rm -f Makefile
sed -e "s%@cc@%${MYCC}%; \
s%@defs@%${DEFS}%; \
s%@cflags@%${MYCFLAGS}%; \
s%@prefix@%${PREFIX}%; \
s%@bindir@%${BINDIR}%; \
s%@mandir@%${MANDIR}%; \
s%@infodir@%${INFODIR}%; \
s%@docdir@%${DOCDIR}%; \
" < Makefile.in > Makefile
# Avoid editing Makefile instead of Makefile.in
chmod ugo-w Makefile
# =======================================================================
# vim:et:sw=2:ht=2:sts=2:fdm=marker:cms=#%s
This diff is collapsed.
This diff is collapsed.
#######################################################################
#
# Example ~/.mairixrc file
#
# Any line starting with # is a comment.
#
#######################################################################
# Set this to the directory where your maildir folders live
base=/home/richard/mail
# Set this to a list of folders within 'base'. 3 dots at the end
# means there are sub-folders within this folder.
folders=new-mail:new-chrony:new-lojban:new-jbofihe:recent...:ancient...
#######################################################################
# You need to define at least one of maildir, mh and mbox. You probably don't
# need to define all three! You can use >1 line for any of these.
# Set this to a list of maildir folders within 'base'. 3 dots at the end means
# there are sub-folders within this folder.
maildir=inbox:archive...
maildir=lists...
# Set this to a list of MH folders within 'base'. 3 dots at the end means
# there are sub-folders within this folder.
mh=mh_archive...
# Set this to a list of mbox folders within 'base'.
mbox=mboxen/folder1:mboxen/folder2:mboxen/foobar
#######################################################################
# Set this to the folder within 'base' where you want the search mode
# to write its output
# to write its output.
vfolder=vfolder
# Set this if you want the format of vfolder to be mh or mbox (the default is
# maildir).
#
# vformat=mh
# vformat=mbox
#######################################################################
# Set this to the path where the index database file will be kept
database=/home/richard/mail/mairix_database
#ifndef _FROMCHECK_H
#define _FROMCHECK_H
enum fromcheck_result {
FROMCHECK_PASS,
FROMCHECK_FAIL
};
extern int fromcheck_next_state(int, int);
extern enum fromcheck_result fromcheck_exitval[];
/* Tokens, keep in the same sequence as the list in the fromcheck.nfa file */
#define FS_CR 0
#define FS_DIGIT 1
#define FS_AT 2
#define FS_COLON 3
#define FS_WHITE 4
#define FS_LOWER 5
#define FS_UPPER 6
#define FS_PLUSMINUS 7
#define FS_OTHEREMAIL 8
#endif
%{
#include "fromcheck.h"
%}
# Define tokens
# CR : \n
# DIGIT : [0-9]
# AT : @
# COLON : :
# WHITE : ' ', \t
# LOWER : [a-z]
# UPPER : [A-Z]
# PLUSMINUS : [+-]
# OTHER_EMAIL : other stuff valid in an address, at least [_.]
Tokens CR DIGIT AT COLON WHITE LOWER UPPER PLUSMINUS OTHER_EMAIL
Abbrev EMAIL = LOWER | UPPER | DIGIT | PLUSMINUS | OTHER_EMAIL
BLOCK email
STATE in
EMAIL -> in, before_at
STATE before_at
EMAIL -> before_at
AT -> after_at
STATE after_at
EMAIL -> after_at, out
ENDBLOCK
BLOCK zone
# Make this pretty lenient
STATE in
UPPER -> zone2
UPPER -> out
PLUSMINUS -> zone2
STATE zone2
UPPER | LOWER -> zone2, out
DIGIT -> zone2, out
ENDBLOCK
BLOCK date
STATE in
-> before_weekday
WHITE -> before_weekday
STATE before_weekday
UPPER ; LOWER ; LOWER ; WHITE -> after_weekday
STATE after_weekday
WHITE -> after_weekday
UPPER ; LOWER ; LOWER ; WHITE -> after_month
STATE after_month
WHITE -> after_month
DIGIT ; WHITE -> after_day
DIGIT ; DIGIT ; WHITE -> after_day
STATE after_day
WHITE -> after_day
# Accept HH:MM:SS
DIGIT ; DIGIT ; COLON ; DIGIT ; DIGIT ; COLON ; DIGIT ; DIGIT ; WHITE -> after_time
# Accept HH:MM
DIGIT ; DIGIT ; COLON ; DIGIT ; DIGIT ; WHITE -> after_time
# Allow either 1 or 2 words of timezone
STATE after_time
WHITE -> after_time
-> after_timezone
<zone:in->out> ; WHITE -> after_timezone
<zone:in->out> ; WHITE -> after_timezone_1
STATE after_timezone_1
WHITE -> after_timezone_1
<zone:in->out> ; WHITE -> after_timezone
STATE after_timezone
WHITE -> after_timezone
DIGIT ; DIGIT ; DIGIT ; DIGIT -> after_year
STATE after_year
WHITE -> after_year
-> out
ENDBLOCK
# Assume the earlier code has identified the '\nFrom ' sequence,
# and the validator starts scanning from the character beyond the space
BLOCK main
STATE in
<email:in->out> -> before_date
-> before_date
STATE before_date
<date:in->out> ; CR = FROMCHECK_PASS
# Mention this state last : the last mentioned state in the last defined
# block becomes the entry state of the scanner.
STATE in
ENDBLOCK
RESULT FROMCHECK_PASS
RESULT FROMCHECK_FAIL
DEFRESULT FROMCHECK_FAIL
PREFIX fromcheck
TYPE "enum fromcheck_result"
# vim:ft=txt:et:sw=4:sts=4:ht=4
/*
$Header: /cvs/src/mairix/glob.c,v 1.4 2003/12/01 22:30:23 richard Exp $
mairix - message index builder and finder for maildir folders.
**********************************************************************
* Copyright (C) Richard P. Curnow 2003
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
**********************************************************************
*/
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>
#include "mairix.h"
struct globber {
unsigned int pat[256];
unsigned int starpat;
unsigned int hit;
};
static const char *parse_charclass(const char *in, struct globber *result, unsigned int mask)/*{{{*/
{
int first = 1;
int prev = -1;
in++; /* Advance over '[' */
while (*in) {
if (*in == ']') {
if (first) {
result->pat[(int)']'] |= mask;
} else {
return in;
}
} else if (*in == '-') {
/* Maybe range */
if ((prev < 0) || !in[1] || (in[1]==']')) {
/* - at either end of string (or right after an earlier range) means
* normal - */
result->pat['-'] |= mask;
} else {
int next = in[1];
int hi, lo;
int i;
/* Cope with range being inverted */
if (prev < next) {
lo = prev, hi = next;
} else {
lo = next, hi = prev;
}
for (i=lo; i<=hi; i++) {
int index = 0xff & i;
result->pat[index] |= mask;
}
/* require 1 extra increment */
in++;
prev = -1; /* Avoid junk like [a-e-z] */
}
} else {
int index = 0xff & (int)*in;
result->pat[index] |= mask;
}
prev = *in;
first = 0;
in++;
}
return in;
}
/*}}}*/
struct globber *make_globber(const char *wildstring)/*{{{*/
{
struct globber *result;
int n, i;
const char *p;
char c;
int index;
unsigned int mask;
result = new(struct globber);
memset(&result->pat, 0x00, 256*sizeof(unsigned long));
memset(&result->starpat, 0x00, sizeof(unsigned long));
mask = 0x1;
n = 0;
for (p=wildstring; *p; p++) {
mask = 1<<n;
c = *p;
switch (c) {
case '*':/*{{{*/
/* Match zero or more of anything */
result->starpat |= mask;
break;
/*}}}*/
case '[':/*{{{*/
p = parse_charclass(p, result, mask);
n++;
break;
/*}}}*/
case '?':/*{{{*/
for (i=0; i<256; i++) {
result->pat[i] |= mask;
}
n++;
break;
/*}}}*/
default:/*{{{*/
index = 0xff & (int)c;
result->pat[index] |= mask;
n++;
break;
/*}}}*/
}
}
result->hit = (1<<n);
return result;
}
/*}}}*/
void free_globber(struct globber *old)/*{{{*/
{
free(old);
}
/*}}}*/
#define DODEBUG 0
int is_glob_match(struct globber *g, const char *s)/*{{{*/
{
unsigned int reg;
unsigned int stars;
int index;
reg = 0x1;
while (*s) {
index = 0xff & (int) *s;
#if DODEBUG
printf("*s=%c index=%02x old_reg=%08lx pat=%08lx ",
*s, index, reg, g->pat[index]);
#endif
stars = (reg & g->starpat);
reg &= g->pat[index];
reg <<= 1;
reg |= stars;
#if DODEBUG
printf("new_reg=%08lx ", reg);
printf("starpat=%08lx stars=%08lx\n", g->starpat, stars);
#endif
s++;
}
#if DODEBUG
printf("reg=%08lx hit=%08lx\n", reg, g->hit);
#endif
reg &= g->hit;
if (reg) {
return 1;
} else {
return 0;
}
}