X-Git-Url: https://www.fleuret.org/cgi-bin/gitweb/gitweb.cgi?p=mymail.git;a=blobdiff_plain;f=mymail.c;h=ffc562145f6ef7bf69bf4d8cdc4b50610987481b;hp=3c810a117ab4ddf63b20deb4e136a63548f083b3;hb=c2a75b190fced9a626a70fb2886889ce0e231af7;hpb=7edf0cc9d64e71d1ca91dd34dbe03c12380c9466 diff --git a/mymail.c b/mymail.c index 3c810a1..ffc5621 100644 --- a/mymail.c +++ b/mymail.c @@ -59,7 +59,7 @@ regex_t leading_from_line_regexp; int paranoid; int quiet; -char *default_search_field = "p"; +char *default_search_field; /********************************************************************/ @@ -101,6 +101,7 @@ struct search_condition { struct parsable_field { int id; + int cflags; char *regexp_string; regex_t regexp; }; @@ -108,31 +109,36 @@ struct parsable_field { static struct parsable_field fields_to_parse[] = { { ID_LEADING_LINE, + 0, "^From ", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { ID_FROM, - "^\\([Ff][Rr][Oo][Mm]:\\|[Rr][Ee][Pp][Ll][Yy]-[Tt][Oo]:\\|[Ss][Ee][Nn][Dd][Ee][Rr]:\\)", + REG_ICASE, + "^\\(from\\|reply-to\\|sender\\|return-path\\): ", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { ID_TO, - "^\\([Tt][Oo]\\|[Cc][Cc]\\|[Bb][Cc][Cc]\\): ", + REG_ICASE, + "^\\(to\\|cc\\|bcc\\): ", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { ID_SUBJECT, - "^[Ss][Uu][Bb][Jj][Ee][Cc][Tt]: ", + REG_ICASE, + "^subject: ", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, { ID_DATE, - "^[Dd][Aa][Tt][Ee]: ", + REG_ICASE, + "^date: ", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, @@ -207,6 +213,8 @@ void print_usage(FILE *out) { fprintf(out, " index mails\n"); fprintf(out, " -o , --output \n"); fprintf(out, " set the result file, use stdout if unset\n"); + fprintf(out, " -a , --default-search \n"); + fprintf(out, " set the default search field\n"); } /*********************************************************************/ @@ -230,9 +238,22 @@ int ignore_entry(const char *name) { (name[0] == '.' && name[1] != '/'); } -int is_a_leading_from_line(char *s) { - return strncmp(s, "From ", 5) == 0 && - regexec(&leading_from_line_regexp, s, 0, 0, 0) == 0; +int is_a_leading_from_line(int last_mbox_line_was_empty, char *mbox_line) { + return + + /* + + The mbox man page in qmail documentation states: + + > The reader should not attempt to take advantage of the fact + > that every From_ line (past the beginning of the file) is + > preceded by a blank line. + + */ + + /* last_mbox_line_was_empty && */ + strncmp(mbox_line, "From ", 5) == 0 && + regexec(&leading_from_line_regexp, mbox_line, 0, 0, 0) == 0; } int mbox_line_match_search(struct search_condition *condition, @@ -271,7 +292,9 @@ int mbox_line_match_search(struct search_condition *condition, (condition->field_id == ID_FROM && mbox_id == ID_LEADING_LINE) ) + && + regexec(&condition->regexp, mbox_value, 0, 0, 0) == 0; } } @@ -319,8 +342,7 @@ void update_body_hits(char *mail_filename, int position_in_mail, } if(!fgets(raw_mbox_line, BUFFER_SIZE, mail_file) || - (last_mbox_line_was_empty && - is_a_leading_from_line(raw_mbox_line))) + (is_a_leading_from_line(last_mbox_line_was_empty, raw_mbox_line))) break; } } @@ -442,8 +464,7 @@ void search_in_db(const char *db_filename, fprintf(output_file, "%s", raw_mbox_line); while(1) { if(!fgets(raw_mbox_line, BUFFER_SIZE, mail_file) || - (last_mbox_line_was_empty && - is_a_leading_from_line(raw_mbox_line)) + (is_a_leading_from_line(last_mbox_line_was_empty, raw_mbox_line)) ) break; last_mbox_line_was_empty = (raw_mbox_line[0] == '\n'); @@ -569,8 +590,7 @@ void index_mbox(const char *mbox_filename, last_mbox_line_was_empty = 1; while(fgets(raw_mbox_line, BUFFER_SIZE, file)) { - if(last_mbox_line_was_empty && - is_a_leading_from_line(raw_mbox_line)) { + if(is_a_leading_from_line(last_mbox_line_was_empty, raw_mbox_line)) { if(in_header) { fprintf(stderr, "Got a ^\"From \" in the header in %s:%lu.\n", @@ -684,6 +704,7 @@ static struct option long_options[] = { { "search", 1, 0, 's' }, { "index", 0, 0, 'i' }, { "output", 1, 0, 'o' }, + { "default-search", 1, 0, 'a' }, { 0, 0, 0, 0 } }; @@ -704,7 +725,7 @@ void init_condition(struct search_condition *condition, char *full_string) { condition->negation = 0; } - /* Last 8 hours */ + /* Recently */ if(strcmp(search_field, "8h") == 0) { condition->field_id = ID_INTERVAL; @@ -718,7 +739,11 @@ void init_condition(struct search_condition *condition, char *full_string) { condition->interval_stop = 0; } - /* Today and yesterday */ + else if(strcmp(search_field, "month") == 0) { + condition->field_id = ID_INTERVAL; + condition->interval_start = time(0) - 3600 * 24 * 31; + condition->interval_stop = 0; + } else if(strcmp(search_field, "24h") == 0 || strcmp(search_field, "today") == 0) { @@ -727,6 +752,8 @@ void init_condition(struct search_condition *condition, char *full_string) { condition->interval_stop = 0; } + /* Yesterday */ + else if(strcmp(search_field, "yesterday") == 0) { condition->field_id = ID_INTERVAL; condition->interval_start = time(0) - 2 * 3600 * 24; @@ -778,6 +805,9 @@ void init_condition(struct search_condition *condition, char *full_string) { } else { + + /* header-related conditions */ + condition->field_id = -1; for(m = 0; (m < MAX_ID) && condition->field_id == -1; m++) { @@ -834,7 +864,6 @@ int main(int argc, char **argv) { char *db_filename_list; char output_filename[PATH_MAX + 1]; int action_index; - int error = 0, show_help = 0; const int nb_fields_to_parse = sizeof(fields_to_parse) / sizeof(struct parsable_field); char c; @@ -858,12 +887,13 @@ int main(int argc, char **argv) { db_root_path = 0; db_filename_list = 0; quiet = 0; + default_search_field = 0; setlocale(LC_ALL, ""); nb_search_conditions = 0; - while ((c = getopt_long(argc, argv, "hvqip:s:d:r:l:o:", + while ((c = getopt_long(argc, argv, "hvqip:s:d:r:l:o:a:", long_options, NULL)) != -1) { switch(c) { @@ -913,6 +943,10 @@ int main(int argc, char **argv) { nb_search_conditions++; break; + case 'a': + default_search_field = optarg; + break; + default: error = 1; break; @@ -996,7 +1030,7 @@ int main(int argc, char **argv) { for(f = 0; f < nb_fields_to_parse; f++) { if(regcomp(&fields_to_parse[f].regexp, fields_to_parse[f].regexp_string, - REG_ICASE)) { + fields_to_parse[f].cflags)) { fprintf(stderr, "mymail: Syntax error in regexp \"%s\" for field \"%s\".\n", fields_to_parse[f].regexp_string,