Commit dc887908 authored by Richard Curnow's avatar Richard Curnow

Corresponds to CVS V0.13

Original rev  : rc@rc0.org.uk--historical/mairix--history--0--patch-23
parent da2d079d
#########################################################################
#
# $Header: /cvs/src/mairix/Makefile.in,v 1.5 2003/12/04 22:18:07 richard Exp $
# $Header: /cvs/src/mairix/Makefile.in,v 1.6 2003/12/12 23:17:11 richard Exp $
#
# =======================================================================
#
......@@ -62,9 +62,11 @@ mairix : $(OBJ)
datescan.c : datescan.nfa dfasyn/dfasyn
dfasyn/dfasyn -o datescan.c -v -u datescan.nfa
fromcheck.c : fromcheck.nfa dfasyn/dfasyn
fromcheck.c : fromcheck.nfa dfasyn/dfasyn fromcheck.h
dfasyn/dfasyn -o fromcheck.c -v -u fromcheck.nfa
mbox.o : fromcheck.h
dfasyn/dfasyn:
if [ -d dfasyn ]; then cd dfasyn ; make CC="$(CC)" CFLAGS="$(CFLAGS)" ; else echo "No dfasyn subdirectory?" ; exit 1 ; fi
......
NEW IN VERSION 0.13
===================
* Fixes to support the mbox format used by Mozilla mail
* When creating vfolder directories for maildir/mh, remove existing
non-directory at the same path, if present. When creating mbox vfolder file,
complain if there's already a directory at the same path and exit.
* Switch from the term "virtual folder" to "match folder"
* Fix bug in path matches (p:) containing upper-case letters - previously they
matched on corresponding all lower-case paths.
NEW IN VERSION 0.12
===================
......
......@@ -12,15 +12,16 @@ 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
#define FS_LF 0
#define FS_CR 1
#define FS_DIGIT 2
#define FS_AT 3
#define FS_COLON 4
#define FS_WHITE 5
#define FS_LOWER 6
#define FS_UPPER 7
#define FS_PLUSMINUS 8
#define FS_OTHEREMAIL 9
#endif
......@@ -15,7 +15,7 @@
# PLUSMINUS : [+-]
# OTHER_EMAIL : other stuff valid in an address, at least [_.]
Tokens CR DIGIT AT COLON WHITE LOWER UPPER PLUSMINUS OTHER_EMAIL
Tokens LF CR DIGIT AT COLON WHITE LOWER UPPER PLUSMINUS OTHER_EMAIL
Abbrev EMAIL = LOWER | UPPER | DIGIT | PLUSMINUS | OTHER_EMAIL
......@@ -96,11 +96,21 @@ ENDBLOCK
BLOCK main
STATE in
# Real return address.
<email:in->out> -> before_date
# Cope with Mozilla mbox folder format which just uses a '-' as
# the return address field.
PLUSMINUS -> before_date
# Empty return address
-> before_date
STATE before_date
<date:in->out> ; CR = FROMCHECK_PASS
<date:in->out> ; LF = FROMCHECK_PASS
# Cope with mozilla mbox format
<date:in->out> ; CR ; LF = FROMCHECK_PASS
# Mention this state last : the last mentioned state in the last defined
# block becomes the entry state of the scanner.
......
/*
$Header: /cvs/src/mairix/mairix.c,v 1.18 2003/11/21 22:09:46 richard Exp $
$Header: /cvs/src/mairix/mairix.c,v 1.19 2004/01/06 22:00:49 richard Exp $
mairix - message index builder and finder for maildir folders.
......@@ -41,7 +41,7 @@ static char *folder_base = NULL;
static char *maildir_folders = NULL;
static char *mh_folders = NULL;
static char *mboxen = NULL;
static char *vfolder = NULL;
static char *mfolder = NULL;
static char *database_path = NULL;
static enum folder_type output_folder_type = FT_MAILDIR;
......@@ -99,7 +99,7 @@ static void parse_output_folder(char *p)/*{{{*/
output_folder_type = FT_MBOX;
}
else {
fprintf(stderr, "Unrecognized vformat <%s>\n", temp);
fprintf(stderr, "Unrecognized mformat <%s>\n", temp);
}
free(temp);
}
......@@ -177,14 +177,10 @@ static void parse_rc_file(char *name)/*{{{*/
else if (!strncasecmp(p, "mh=", 3)) add_folders(&mh_folders, copy_value(p));
else if (!strncasecmp(p, "mbox=", 5)) add_folders(&mboxen, copy_value(p));
else if (!strncasecmp(p, "vfolder_format=", 15)) {
fprintf(stderr, "'vfolder_format=' option in rc file is depracated, use 'vformat='\n");
else if (!strncasecmp(p, "mformat=", 8)) {
parse_output_folder(p);
}
else if (!strncasecmp(p, "vformat=", 8)) {
parse_output_folder(p);
}
else if (!strncasecmp(p, "vfolder=", 8)) vfolder = copy_value(p);
else if (!strncasecmp(p, "mfolder=", 8)) mfolder = copy_value(p);
else if (!strncasecmp(p, "database=", 9)) database_path = copy_value(p);
else {
if (verbose) {
......@@ -293,7 +289,7 @@ volatile void out_of_mem(char *file, int line, size_t size)/*{{{*/
static char *get_version(void)/*{{{*/
{
static char buffer[256];
static char cvs_version[] = "$Name: V0_12 $";
static char cvs_version[] = "$Name: V0_13 $";
char *p, *q;
for (p=cvs_version; *p; p++) {
if (*p == ':') {
......@@ -338,9 +334,9 @@ static void usage(void)/*{{{*/
"-f <rcfile> : use alternative rc file (default ~/.mairixrc)\n"
"-v : be verbose\n"
"-p : purge messages that no longer exist\n"
"-a : add new matches to virtual folder (default : clear it first)\n"
"-a : add new matches to match folder (default : clear it first)\n"
"-t : include all messages in same threads as matching messages\n"
"-r : force raw output regardless of vformat setting in mairixrc file\n"
"-r : force raw output regardless of mformat setting in mairixrc file\n"
"expr_i : search expression (all expr's AND'ed together):\n"
" word : match word in whole message\n"
" t:word : match word in To: header\n"
......@@ -362,11 +358,11 @@ static void usage(void)/*{{{*/
/*}}}*/
/* Notes on folder management: {{{
Assumption is that the user wants to keep the 'vfolder' directories under a
Assumption is that the user wants to keep the 'mfolder' directories under a
common root with the real maildir folders. This allows a common value for
mutt's 'folder' variable => the '+' and '=' prefixes work better. This
means the indexer here can't just scan down all subdirectories of a single
ancestor, because it'll pick up its own vfolders. So, use environment
ancestor, because it'll pick up its own mfolders. So, use environment
variables to tailor the folders.
MAIRIX_FOLDER_BASE is the common ancestor directory of the folders (aka
......@@ -376,11 +372,11 @@ static void usage(void)/*{{{*/
the feature that '...' after a component means any maildir underneath that,
e.g.
MAIRIX_VFOLDER is the parent of the vfolders underneath the base
MAIRIX_MFOLDER is the parent of the mfolders underneath the base
MAIRIX_FOLDER_BASE = "/home/foobar/mail"
MAIRIX_FOLDERS = "inbox:lists...:action:archive..."
MAIRIX_VFOLDER = "vf"
MAIRIX_MFOLDER = "mf"
so /home/foobar/mail/vf/search1/{new,cur,tmp} contain the output for search1 etc.
}}} */
......@@ -391,7 +387,7 @@ int main (int argc, char **argv)/*{{{*/
struct database *db;
char *arg_rc_file_path = NULL;
char *arg_vfolder = NULL;
char *arg_mfolder = NULL;
char *e;
int do_augment = 0;
int do_threads = 0;
......@@ -416,9 +412,9 @@ int main (int argc, char **argv)/*{{{*/
} else if (!strcmp(*argv, "-a") || !strcmp(*argv, "--augment")) {
do_search = 1;
do_augment = 1;
} else if (!strcmp(*argv, "-o") || !strcmp(*argv, "--vfolder")) {
} else if (!strcmp(*argv, "-o") || !strcmp(*argv, "--mfolder")) {
++argv, --argc;
arg_vfolder = *argv;
arg_mfolder = *argv;
} else if (!strcmp(*argv, "-p") || !strcmp(*argv, "--purge")) {
do_purge = 1;
} else if (!strcmp(*argv, "-r") || !strcmp(*argv, "--raw-output")) {
......@@ -471,16 +467,16 @@ int main (int argc, char **argv)/*{{{*/
mboxen = e;
}
if (getenv("MAIRIX_VFOLDER")) {
vfolder = getenv("MAIRIX_VFOLDER");
if (getenv("MAIRIX_MFOLDER")) {
mfolder = getenv("MAIRIX_MFOLDER");
}
if (getenv("MAIRIX_DATABASE")) {
database_path = getenv("MAIRIX_DATABASE");
}
if (arg_vfolder) {
vfolder = arg_vfolder;
if (arg_mfolder) {
mfolder = arg_mfolder;
}
if (!folder_base) {
......@@ -498,15 +494,15 @@ int main (int argc, char **argv)/*{{{*/
}
if (do_search) {
if (!vfolder) {
if (!mfolder) {
if (output_folder_type != FT_RAW) {
fprintf(stderr, "No vfolder/MAIRIX_VFOLDER set\n");
fprintf(stderr, "No mfolder/MAIRIX_MFOLDER set\n");
exit(2);
}
vfolder = new_string("");
mfolder = new_string("");
}
return search_top(do_threads, do_augment, database_path, folder_base, vfolder, argv, output_folder_type, verbose);
return search_top(do_threads, do_augment, database_path, folder_base, mfolder, argv, output_folder_type, verbose);
} else {
if (!maildir_folders && !mh_folders && !mboxen) {
......
/*
$Header: /cvs/src/mairix/mairix.h,v 1.18 2003/12/03 23:56:08 richard Exp $
$Header: /cvs/src/mairix/mairix.h,v 1.19 2004/01/06 22:00:49 richard Exp $
mairix - message index builder and finder for maildir folders.
......@@ -305,7 +305,7 @@ int is_glob_match(struct globber *g, const char *s);
void write_database(struct database *db, char *filename);
/* In search.c */
int search_top(int do_threads, int do_augment, char *database_path, char *folder_base, char *vfolder, char **argv, enum folder_type ft, int verbose);
int search_top(int do_threads, int do_augment, char *database_path, char *folder_base, char *mfolder, char **argv, enum folder_type ft, int verbose);
/* In stats.c */
void get_db_stats(struct database *db);
......
This diff is collapsed.
/*
$Header: /cvs/src/mairix/mbox.c,v 1.17 2003/12/03 23:56:08 richard Exp $
$Header: /cvs/src/mairix/mbox.c,v 1.18 2003/12/12 23:11:59 richard Exp $
mairix - message index builder and finder for maildir folders.
......@@ -248,7 +248,8 @@ static void init_fromcheck_table()/*{{{*/
fromcheck_table['-'] = FS_PLUSMINUS;
fromcheck_table['@'] = FS_AT;
fromcheck_table[':'] = FS_COLON;
fromcheck_table['\n'] = FS_CR;
fromcheck_table['\n'] = FS_LF;
fromcheck_table['\r'] = FS_CR;
fromcheck_table[' '] = FS_WHITE;
fromcheck_table['\t'] = FS_WHITE;
fromcheck_table['_'] = FS_OTHEREMAIL;
......
/*
$Header: /cvs/src/mairix/search.c,v 1.23 2003/12/03 23:05:33 richard Exp $
$Header: /cvs/src/mairix/search.c,v 1.27 2004/01/06 22:15:51 richard Exp $
mairix - message index builder and finder for maildir folders.
......@@ -850,7 +850,7 @@ static int do_search(struct read_db *db, char **args, char *output_path, int sho
* , = 'and' separator */
char *orsep;
char *andsep;
char *word, *orig_word;
char *word, *orig_word, *lower_word;
char *equal;
char *p;
int negate;
......@@ -907,31 +907,34 @@ static int do_search(struct read_db *db, char **args, char *output_path, int sho
}
/* Canonicalise search string to lowercase, since the database has all
* tokens handled that way */
for (p=word; *p; p++) {
* tokens handled that way. But not for path search! */
lower_word = new_string(word);
for (p=lower_word; *p; p++) {
*p = tolower(*p);
}
memset(hit0, 0, db->n_msgs);
if (equal) {
if (do_to) match_substring_in_table(db, &db->to, word, max_errors, hit0);
if (do_cc) match_substring_in_table(db, &db->cc, word, max_errors, hit0);
if (do_from) match_substring_in_table(db, &db->from, word, max_errors, hit0);
if (do_subject) match_substring_in_table(db, &db->subject, word, max_errors, hit0);
if (do_body) match_substring_in_table(db, &db->body, word, max_errors, hit0);
if (do_to) match_substring_in_table(db, &db->to, lower_word, max_errors, hit0);
if (do_cc) match_substring_in_table(db, &db->cc, lower_word, max_errors, hit0);
if (do_from) match_substring_in_table(db, &db->from, lower_word, max_errors, hit0);
if (do_subject) match_substring_in_table(db, &db->subject, lower_word, max_errors, hit0);
if (do_body) match_substring_in_table(db, &db->body, lower_word, max_errors, hit0);
if (do_path) match_substring_in_paths(db, word, max_errors, hit0);
if (do_msgid) match_substring_in_table2(db, &db->msg_ids, word, max_errors, hit0);
if (do_msgid) match_substring_in_table2(db, &db->msg_ids, lower_word, max_errors, hit0);
} else {
if (do_to) match_string_in_table(db, &db->to, word, hit0);
if (do_cc) match_string_in_table(db, &db->cc, word, hit0);
if (do_from) match_string_in_table(db, &db->from, word, hit0);
if (do_subject) match_string_in_table(db, &db->subject, word, hit0);
if (do_body) match_string_in_table(db, &db->body, word, hit0);
if (do_to) match_string_in_table(db, &db->to, lower_word, hit0);
if (do_cc) match_string_in_table(db, &db->cc, lower_word, hit0);
if (do_from) match_string_in_table(db, &db->from, lower_word, hit0);
if (do_subject) match_string_in_table(db, &db->subject, lower_word, hit0);
if (do_body) match_string_in_table(db, &db->body, lower_word, hit0);
/* FIXME */
if (do_path) match_substring_in_paths(db, word, 0, hit0);
if (do_msgid) match_string_in_table2(db, &db->msg_ids, word, hit0);
if (do_msgid) match_string_in_table2(db, &db->msg_ids, lower_word, hit0);
}
free(lower_word);
/* AND-combine match vectors */
for (i=0; i<db->n_msgs; i++) {
if (negate) {
......@@ -1044,6 +1047,10 @@ static int do_search(struct read_db *db, char **args, char *output_path, int sho
{
FILE *out;
out = fopen(output_path, "ab");
if (!out) {
fprintf(stderr, "Cannot open output folder %s\n", output_path);
exit(1);
}
for (i=0; i<db->n_msgs; i++) {
if (hit3[i]) {
......@@ -1124,7 +1131,7 @@ static int do_search(struct read_db *db, char **args, char *output_path, int sho
}
/*}}}*/
static int directory_exists(char *name)/*{{{*/
static int directory_exists_remove_other(char *name)/*{{{*/
{
struct stat sb;
......@@ -1134,6 +1141,8 @@ static int directory_exists(char *name)/*{{{*/
if (S_ISDIR(sb.st_mode)) {
return 1;
} else {
/* Try to remove. */
unlink(name);
return 0;
}
}
......@@ -1156,7 +1165,7 @@ static int is_file_or_nothing(char *name)/*{{{*/
static void create_dir(char *path)/*{{{*/
{
if (mkdir(path, 0700) < 0) {
perror("mkdir");
fprintf(stderr, "Could not create directory %s\n", path);
exit(2);
}
fprintf(stderr, "Created directory %s\n", path);
......@@ -1168,7 +1177,7 @@ static void maybe_create_maildir(char *path)/*{{{*/
char *subdir, *tailpos;
int len;
if (!directory_exists(path)) {
if (!directory_exists_remove_other(path)) {
create_dir(path);
}
......@@ -1179,15 +1188,15 @@ static void maybe_create_maildir(char *path)/*{{{*/
tailpos = subdir + len + 1;
strcpy(tailpos,"cur");
if (!directory_exists(subdir)) {
if (!directory_exists_remove_other(subdir)) {
create_dir(subdir);
}
strcpy(tailpos,"new");
if (!directory_exists(subdir)) {
if (!directory_exists_remove_other(subdir)) {
create_dir(subdir);
}
strcpy(tailpos,"tmp");
if (!directory_exists(subdir)) {
if (!directory_exists_remove_other(subdir)) {
create_dir(subdir);
}
free(subdir);
......@@ -1277,31 +1286,32 @@ static void clear_mbox_folder(char *path)/*{{{*/
}
/*}}}*/
int search_top(int do_threads, int do_augment, char *database_path, char *folder_base, char *vfolder, char **argv, enum folder_type ft, int verbose)/*{{{*/
int search_top(int do_threads, int do_augment, char *database_path, char *folder_base, char *mfolder, char **argv, enum folder_type ft, int verbose)/*{{{*/
{
struct read_db *db;
char *complete_vfolder;
char *complete_mfolder;
int len;
int result;
db = open_db(database_path);
if ((vfolder[0] == '/') || (vfolder[0] == '.')) {
complete_vfolder = new_string(vfolder);
if ((mfolder[0] == '/') || (mfolder[0] == '.')) {
complete_mfolder = new_string(mfolder);
} else {
len = strlen(folder_base) + strlen(vfolder) + 2;
complete_vfolder = new_array(char, len);
strcpy(complete_vfolder, folder_base);
strcat(complete_vfolder, "/");
strcat(complete_vfolder, vfolder);
len = strlen(folder_base) + strlen(mfolder) + 2;
complete_mfolder = new_array(char, len);
strcpy(complete_mfolder, folder_base);
strcat(complete_mfolder, "/");
strcat(complete_mfolder, mfolder);
}
switch (ft) {
case FT_MAILDIR:
maybe_create_maildir(complete_vfolder);
maybe_create_maildir(complete_mfolder);
break;
case FT_MH:
if (!directory_exists(complete_vfolder)) {
create_dir(complete_vfolder);
if (!directory_exists_remove_other(complete_mfolder)) {
create_dir(complete_mfolder);
}
break;
case FT_MBOX:
......@@ -1316,14 +1326,14 @@ int search_top(int do_threads, int do_augment, char *database_path, char *folder
if (!do_augment) {
switch (ft) {
case FT_MAILDIR:
clear_maildir_subfolder(complete_vfolder, "new");
clear_maildir_subfolder(complete_vfolder, "cur");
clear_maildir_subfolder(complete_mfolder, "new");
clear_maildir_subfolder(complete_mfolder, "cur");
break;
case FT_MH:
clear_mh_folder(complete_vfolder);
clear_mh_folder(complete_mfolder);
break;
case FT_MBOX:
clear_mbox_folder(complete_vfolder);
clear_mbox_folder(complete_mfolder);
break;
case FT_RAW:
break;
......@@ -1332,9 +1342,10 @@ int search_top(int do_threads, int do_augment, char *database_path, char *folder
}
}
return do_search(db, argv, complete_vfolder, do_threads, ft, verbose);
result = do_search(db, argv, complete_mfolder, do_threads, ft, verbose);
free(complete_mfolder);
close_db(db);
return result;
}
/*}}}*/
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment