diff -u -E -b -w -B mairix-0.21/db.c mairix-patched/db.c --- mairix-0.21/db.c 2007-06-22 22:18:00.000000000 +0200 +++ mairix-patched/db.c 2008-06-02 16:31:54.000000000 +0200 @@ -684,7 +684,7 @@ } /*}}}*/ -static void scan_maildir_flags(struct msgpath *m)/*{{{*/ +void scan_maildir_flags(struct msgpath *m)/*{{{*/ { const char *p, *start; start = m->src.mpf.path; @@ -854,6 +854,61 @@ return m; } /*}}}*/ +int change_new_to_cur(char *p)/*{{{*/ +{ + /* possibly change /new/ to /cur/ in maildir paths */ + char *pos; + int numslash; + + pos = p + strlen(p); + numslash=0; + while ((pos > p) && (numslash<2)) + if( *(--pos) == '/') numslash++; + if ((numslash==2) && (strncmp(pos, "/new/", 5) == 0)) { + strncpy(pos, "/cur/", 5); + return 1; + } + return 0; +} +/*}}}*/ +int looks_like_maildir(const char *p)/*{{{*/ +{ + const char *s; + int numdots; + + /* assume it's maildir if there are two dots after the last slash */ + s = p + strlen(p); + numdots=0; + while( (s > p) && (*s != '/')) + if( *(s--) == '.' ) + numdots++; + if (numdots != 2) return 0; + return 1; +} +/*}}}*/ +int lookup_msgpath_without_flags(struct msgpath *sorted_paths, int n_msgs, char *key)/*{{{*/ +{ + int h, l, length=0, m=-1, r; + char *colpos; + + if( !looks_like_maildir(key) ) return -1; + + colpos = strrchr(key, ':'); + if(colpos) length = colpos - key; + else length = strlen(key); + + h = n_msgs, l = 0; + while (h > l) { + m = (h + l) >> 1; + r = strncmp(sorted_paths[m].src.mpf.path, key, length); + if (r == 0) break; + if (l == m) return -1; + if (r > 0) h = m; + else l = m; + } + return m; +} +/*}}}*/ void maybe_grow_message_arrays(struct database *db)/*{{{*/ { if (db->n_msgs == db->max_msgs) { @@ -907,7 +962,7 @@ char *file_in_db, *file_in_new_list; int matched_index; int i, new_entries_start_at; - int any_new, n_newly_pruned, n_already_dead; + int any_new, n_newly_pruned, n_already_dead, n_changed_flags; int status; file_in_db = new_array(char, n_msgs); @@ -917,6 +972,7 @@ n_already_dead = 0; n_newly_pruned = 0; + n_changed_flags = 0; for (i=0; in_msgs; i++) { switch (db->type[i]) { @@ -943,6 +999,19 @@ * When that stat fails, the path won't get added to the db. */ } } + } else { + /* if file was in /new/ we search now in /cur/ */ + change_new_to_cur(db->msgs[i].src.mpf.path); + /* check if currently unknown file only has changed flags */ + matched_index = lookup_msgpath_without_flags(sorted_paths, n_msgs, db->msgs[i].src.mpf.path); + if (matched_index >= 0) { + file_in_db[matched_index] = 1; + file_in_new_list[i] = 1; + n_changed_flags++; + free(db->msgs[i].src.mpf.path); + db->msgs[i].src.mpf.path=new_string(sorted_paths[matched_index].src.mpf.path); + scan_maildir_flags(&db->msgs[i]); + } } break; case MTY_MBOX: @@ -953,6 +1022,8 @@ } } + if(verbose) fprintf(stderr,"%d maildir message files with changed flags\n", n_changed_flags); + /* Add new entries to database */ new_entries_start_at = db->n_msgs; @@ -1026,7 +1097,7 @@ free(file_in_db); free(file_in_new_list); - return any_new || (n_newly_pruned > 0); + return any_new || (n_newly_pruned > 0) || (n_changed_flags > 0); } /*}}}*/ static void recode_encoding(struct matches *m, int *new_idx)/*{{{*/ diff -u -E -b -w -B mairix-0.21/mairix.c mairix-patched/mairix.c --- mairix-0.21/mairix.c 2007-06-22 22:18:00.000000000 +0200 +++ mairix-patched/mairix.c 2008-06-02 16:31:54.000000000 +0200 @@ -410,6 +410,7 @@ "-t : include all messages in same threads as matching messages\n" "-o : override setting of mfolder from mairixrc file\n" "-r : force raw output regardless of mformat setting in mairixrc file\n" + "-c : try file name completion if maildir flags have changed\n" "expr_i : search expression (all expr's AND'ed together):\n" " word : match word in message body and major headers\n" " t:word : match word in To: header\n" @@ -483,6 +484,7 @@ int do_integrity_checks = 1; int do_forced_unlock = 0; int do_fast_index = 0; + int do_md_completion = 0; struct globber_array *omit_globs; @@ -515,6 +517,8 @@ do_excerpt_output = 1; } else if (!strcmp(*argv, "-Q") || !strcmp(*argv, "--no-integrity-checks")) { do_integrity_checks = 0; + } else if (!strcmp(*argv, "-c") || !strcmp(*argv, "--maildir-completion")) { + do_md_completion = 1; } else if (!strcmp(*argv, "--unlock")) { do_forced_unlock = 1; } else if (!strcmp(*argv, "-F") || @@ -677,7 +681,7 @@ database_path); unlock_and_exit(3); } - result = search_top(do_threads, do_augment, database_path, complete_mfolder, argv, output_folder_type, verbose); + result = search_top(do_threads, do_augment, database_path, complete_mfolder, argv, output_folder_type, verbose, do_md_completion); } else { enum filetype ftype; diff -u -E -b -w -B mairix-0.21/mairix.h mairix-patched/mairix.h --- mairix-0.21/mairix.h 2007-06-22 22:18:00.000000000 +0200 +++ mairix-patched/mairix.h 2008-06-02 16:31:54.000000000 +0200 @@ -354,6 +354,9 @@ int update_database(struct database *db, struct msgpath *sorted_paths, int n_paths, int do_fast_index); void check_database_integrity(struct database *db); int cull_dead_messages(struct database *db, int do_integrity_checks); +int looks_like_maildir(const char *p); +int change_new_to_cur(char *p); +void scan_maildir_flags(struct msgpath *m); /* In mbox.c */ void build_mbox_lists(struct database *db, const char *folder_base, @@ -377,7 +380,7 @@ void write_database(struct database *db, char *filename, int do_integrity_checks); /* In search.c */ -int search_top(int do_threads, int do_augment, char *database_path, char *complete_mfolder, char **argv, enum folder_type ft, int verbose); +int search_top(int do_threads, int do_augment, char *database_path, char *complete_mfolder, char **argv, enum folder_type ft, int verbose, int do_md_completion); /* In stats.c */ void get_db_stats(struct database *db); diff -u -E -b -w -B mairix-0.21/search.c mairix-patched/search.c --- mairix-0.21/search.c 2007-06-22 22:18:00.000000000 +0200 +++ mairix-patched/search.c 2008-06-02 16:31:54.000000000 +0200 @@ -32,6 +32,7 @@ #include #include #include +#include /* Lame fix for systems where NAME_MAX isn't defined after including the above * set of .h files (Solaris, FreeBSD so far). Probably grossly oversized but @@ -654,6 +655,50 @@ } } /*}}}*/ +char *find_new_link_target(char *link_target)/*{{{*/ +{ + int ret, colon_pos; + char *target_glob,*pos,*new_target=NULL; + glob_t pglob; + + /* create search pattern */ + pos = strrchr( link_target, ':'); + if( pos ) colon_pos = pos - link_target; + else colon_pos = strlen(link_target); + target_glob = Malloc( colon_pos + 2); + strncpy( target_glob, link_target, colon_pos); + target_glob[colon_pos] = '*'; + target_glob[colon_pos+1] = '\0'; + + ret = glob( target_glob, GLOB_NOSORT, NULL, &pglob ); + + /* if we found nothing yet, possibly replace /new/ with /cur/ + and search again */ + if( (ret == GLOB_NOMATCH) && change_new_to_cur(target_glob) ) + ret = glob( target_glob, GLOB_NOSORT, NULL, &pglob ); + + switch(ret) { + case 0: + if( pglob.gl_pathc > 1) + fprintf(stderr, "Matched more than one file for %s.\n", target_glob); + else { + if(verbose) fprintf(stderr, "Using completion %s.\n", target_glob); + new_target=new_string(pglob.gl_pathv[0]); + } + break; + case GLOB_NOMATCH: + if (verbose) fprintf(stderr, "Found no completions for %s\n", target_glob); + break; + default: + fprintf(stderr, "Error while running glob on %s\n", target_glob); + } + + free(target_glob); + globfree(&pglob); + + return new_target; +} +/*}}}*/ static void create_symlink(char *link_target, char *new_link)/*{{{*/ { if (symlink(link_target, new_link) < 0) { @@ -776,7 +821,8 @@ *is_flagged = (db->msg_type_and_flags[idx] & FLAG_FLAGGED) ? 1 : 0; } -static int do_search(struct read_db *db, char **args, char *output_path, int show_threads, enum folder_type ft, int verbose)/*{{{*/ +static int do_search(struct read_db *db, char **args, char *output_path, int show_threads, enum folder_type ft, + int verbose, int do_md_completion)/*{{{*/ { char *colon, *start_words; int do_body, do_subject, do_from, do_to, do_cc, do_date, do_size; @@ -1037,13 +1083,25 @@ switch (rd_msg_type(db, i)) { case DB_MSG_FILE: { - char *target_path; + char *target_path, *new_target=NULL; char *message_path; int is_in_new; + struct msgpath mgp; message_path = db->data + db->path_offsets[i]; + if (do_md_completion && access(message_path, F_OK)) + /* if target does not exist anymore, try file completion */ + new_target = find_new_link_target(message_path); + if(new_target) { + mgp.src.mpf.path = new_target; + scan_maildir_flags(&mgp); + target_path = mk_maildir_path(i, output_path, 0, mgp.seen, mgp.replied, mgp.flagged); + create_symlink(new_target, target_path); + free(new_target); + } else { is_in_new = looks_like_maildir_new_p(message_path); target_path = mk_maildir_path(i, output_path, is_in_new, is_seen, is_replied, is_flagged); create_symlink(message_path, target_path); + } free(target_path); ++n_hits; } @@ -1069,8 +1127,17 @@ switch (rd_msg_type(db, i)) { case DB_MSG_FILE: { + char *message_path, *new_target=NULL; char *target_path = mk_mh_path(i, output_path); - create_symlink(db->data + db->path_offsets[i], target_path); + message_path = db->data + db->path_offsets[i]; + if (do_md_completion && access(message_path, F_OK)) + /* if target does not exist anymore, try file completion */ + new_target = find_new_link_target(message_path); + if(new_target) { + create_symlink(new_target, target_path); + free(new_target); + } else + create_symlink(message_path, target_path); free(target_path); ++n_hits; } @@ -1382,7 +1449,8 @@ } /*}}}*/ -int search_top(int do_threads, int do_augment, char *database_path, char *complete_mfolder, char **argv, enum folder_type ft, int verbose)/*{{{*/ +int search_top(int do_threads, int do_augment, char *database_path, char *complete_mfolder, + char **argv, enum folder_type ft, int verbose, int do_md_completion)/*{{{*/ { struct read_db *db; int result; @@ -1428,7 +1496,7 @@ } } - result = do_search(db, argv, complete_mfolder, do_threads, ft, verbose); + result = do_search(db, argv, complete_mfolder, do_threads, ft, verbose, do_md_completion); free(complete_mfolder); close_db(db); return result; diff -u -E -b -w -B mairix-0.21/version.txt mairix-patched/version.txt --- mairix-0.21/version.txt 2007-06-22 22:19:32.000000000 +0200 +++ mairix-patched/version.txt 2008-06-02 16:32:10.000000000 +0200 @@ -1 +1 @@ -0.21 +0.21 maildirpatch