Compare commits

...

25 Commits

Author SHA1 Message Date
b93a60572b
Remove an obsolete macro. 2024-09-28 12:36:22 +02:00
1938d25ced
Update the copyright statement. 2024-09-28 12:35:18 +02:00
7b7bafd5f8
Re-arrange the TODO list for readability. 2024-09-27 23:42:13 +02:00
eec14b33ff
Fix a typo. 2024-09-27 23:41:15 +02:00
fdab5e8c5e
Automake settings
Omit the contrib subdirectory from the distribution tarball.
2024-09-27 11:11:11 +02:00
66dd5fed23
Git settings
- Clean up the .gitignore file.
- Treat Info pages as binary files.
2024-09-27 10:46:40 +02:00
4cb77488bc
Bump the version to 0.7.13. 2024-09-23 21:34:04 +02:00
6f8e688a46
Merge branch 'master' of github.com:dspiljar/mboxgrep 2024-09-23 16:04:20 +02:00
d8f44235f5
Fix Automake to include AUTHORS.md. 2024-09-23 14:37:53 +02:00
6e9600426a
Minor update to the man and info pages
Sync the examples section, refer to RFC 4155 for the mbox mailbox
format, and add URLs to Gitea and Github.
2024-09-23 13:15:05 +02:00
b4d3034c8c
Minor update to the man and info pages
Sync the examples section, refer to RFC 4155 for the mbox mailbox
format, and add URLs to Gitea and Github.
2024-09-23 12:59:51 +02:00
9515236244
Merge branch 'mbox_cleanup' 2024-09-20 23:43:29 +02:00
a790494133
Code refactoring
Refactor of mbox_open(). Checking for a "postmark" line, i.e. whether
the file is an mbox mailbox, has been moved to mbox_check_postmark().
2024-09-20 22:18:30 +02:00
ec8062309d
Readability of the news file
Headings in the news file now refer to changes in the current version,
as opposed to changes since the last version.
2024-09-20 13:48:55 +02:00
631998a849
Code refactoring
Partial refactor of mbox_open(). Opening of file descripts has been
moved to mbox_fdopen().
2024-09-20 13:11:06 +02:00
bd64536e89
Function prototype
Use an enum type instead of a string to define the file opening mode.
2024-09-19 22:40:20 +02:00
b30f2f2362
Suppress "Not an mbox folder" error messages on empty files. 2024-09-19 00:24:21 +02:00
1a63374e73
Move file locking code to a separate function.
Failure to lock a file is now fatal.
2024-09-18 23:48:21 +02:00
efc6f92cdb
Update the TODO list. 2024-09-13 15:54:50 +02:00
191b24433f
Mention the contributors and convert to Markdown. 2024-09-11 18:07:50 +02:00
40b6f8799f
Merge branch 'giachello-master' 2024-09-11 13:47:18 +02:00
Giovanni Iachello
13bf23b9a2 fix autoconf on Windows 2024-09-10 22:39:39 -07:00
c732d4f949
Phrasing
Clarify that the parameter to the "-o" switch is a MAILBOX instead of a
FOLDER (which could be confused with an ordinary filesystem folder).

Added per Roman Nezval's comment.
2023-12-29 00:59:25 +01:00
7255fae5d0
Bump the version to 0.7.12a. 2023-05-21 15:09:44 +02:00
03407c7afb
Correction of Automake macros
Fix Automake macros to include the license file and other files and
directories in the distribution tarball.
2023-05-21 12:05:18 +02:00
17 changed files with 244 additions and 204 deletions

1
.gitattributes vendored Normal file
View File

@ -0,0 +1 @@
*.info binary

6
.gitignore vendored
View File

@ -4,8 +4,7 @@ config.h.in
config.log config.log
config.status config.status
src/*.o src/*.o
src/*.c~ src/*.exe
src/*.h~
src/mboxgrep src/mboxgrep
src/.deps/ src/.deps/
src/stamp-h1 src/stamp-h1
@ -17,3 +16,6 @@ compile
depcomp depcomp
install-sh install-sh
missing missing
.gitignore
.vscode/*
*~

View File

@ -1,5 +0,0 @@
-*- text -*-
mboxgrep is written and maintained by Daniel Spiljar.
$Id: AUTHORS,v 1.3 2005-11-16 01:37:18 dspiljar Exp $

1
AUTHORS.md Normal file
View File

@ -0,0 +1 @@
mboxgrep is written and maintained by Daniel Spiljar with contributors.

View File

@ -1,2 +1,2 @@
SUBDIRS = doc src SUBDIRS = doc src
dist_data_DATA = contrib EXTRA_DIST = COPYING.md INSTALL.md NEWS.md README.md TODO.md AUTHORS.md

53
NEWS.md
View File

@ -1,17 +1,28 @@
# Changes of mboxgrep # Changes of mboxgrep
## Changes since 0.7.11 ## Changes in 0.7.13
- Improve the readability of this file.
- Failure to lock a file (mbox) is now a fatal error.
- Fix Autoconf on Windows.
- Code refactoring, mostly of mbox-related functions.
## Changes in 0.7.12a
- Fix Automake macros to include the license file and others.
## Changes in 0.7.12
- Port to the pcre2 library (pcre1 is no longer supported). - Port to the pcre2 library (pcre1 is no longer supported).
- Check command-line options for conflicting matchers and actions. - Check command-line options for conflicting matchers and actions.
- Various minor code cleanups. - Various minor code cleanups.
## Changes since 0.7.10 ## Changes in 0.7.11
- GNU Automake is now utilized instead of manually written Makefile.in files. - GNU Automake is now utilized instead of manually written Makefile.in files.
- Code indentation has been corrected and documented (GNU indent is used for this purpose). - Code indentation has been corrected and documented (GNU indent is used for this purpose).
## Changes since 0.7.9 ## Changes in 0.7.10
- development has been restarted after a longer hiatus - development has been restarted after a longer hiatus
- moved the source tree to git - moved the source tree to git
@ -20,7 +31,7 @@
- fixed multiple compilation errors and warnings on Linux and FreeBSD - fixed multiple compilation errors and warnings on Linux and FreeBSD
- started implementing a debug mode - started implementing a debug mode
## Changes since 0.7.8 ## Changes in 0.7.9
- implemented support for mbox folders compressed with bzip2 algorithm - implemented support for mbox folders compressed with bzip2 algorithm
- improved detection of PCRE library; this also fixes a compilation bug - improved detection of PCRE library; this also fixes a compilation bug
@ -29,7 +40,7 @@
folder and temporary directory were on different filesystems; folder and temporary directory were on different filesystems;
thanks to James P. Dugal <jpd AT louisiana.edu> for providing a patch thanks to James P. Dugal <jpd AT louisiana.edu> for providing a patch
## Changes since 0.7.7 ## Changes in 0.7.8
- fixed crashes on MH folders, as well as a potential problem with mbox - fixed crashes on MH folders, as well as a potential problem with mbox
and maildir folders with the same cause and maildir folders with the same cause
@ -38,46 +49,46 @@
- mboxgrep can now read gzip compressed mbox folders from standard input - mboxgrep can now read gzip compressed mbox folders from standard input
(which is a side effect of a code cleanup!) (which is a side effect of a code cleanup!)
## Changes since 0.7.6a ## Changes in 0.7.7
- mboxgrep can now read mbox folders from standard input - mboxgrep can now read mbox folders from standard input
## Changes since 0.7.6 ## Changes in 0.7.6a
- fixed a bug which prevented mboxgrep from being compiled - fixed a bug which prevented mboxgrep from being compiled
## Changes since 0.7.5 ## Changes in 0.7.6
- fixed a bug which caused mboxgrep to coredump on recursive search of - fixed a bug which caused mboxgrep to coredump on recursive search of
maildirs maildirs
- code cleanups - code cleanups
## Changes since 0.7.4 ## Changes in 0.7.5
- recursive search through directories has been reimplemented - recursive search through directories has been reimplemented
## Changes since 0.7.3 ## Changes in 0.7.4
- mboxgrep can now ignore messages with identical bodies - mboxgrep can now ignore messages with identical bodies
## Changes since 0.7.2 ## Changes in 0.7.3
- file locking method can be selected at runtime - file locking method can be selected at runtime
- mboxgrep used to coredump on messages with empty headers; the problem is - mboxgrep used to coredump on messages with empty headers; the problem is
now hopefully fixed now hopefully fixed
- mboxgrep now compiles on FreeBSD - mboxgrep now compiles on FreeBSD
## Changes since 0.7.1 ## Changes in 0.7.2
- file locking with `flock()` instead of `fcntl()` is now supported - file locking with `flock()` instead of `fcntl()` is now supported
- mboxgrep should now compile on systems which don't have `getopt_long()` - mboxgrep should now compile on systems which don't have `getopt_long()`
- other minor bugfixes - other minor bugfixes
## Changes since 0.7.0 ## Changes in 0.7.1
- bugfixes - bugfixes
## Changes since 0.5.3 ## Changes in 0.7.0
- NOTE: there was no stable version between 0.5.x and 0.7.x - NOTE: there was no stable version between 0.5.x and 0.7.x
- mboxgrep is almost completely rewritten - mboxgrep is almost completely rewritten
@ -87,7 +98,7 @@
command) command)
- added support for compressed mbox folders - added support for compressed mbox folders
## Changes since 0.5.2 ## Changes in 0.5.3
- implemented ability to write found messages to another folder (instead - implemented ability to write found messages to another folder (instead
of standard output) of standard output)
@ -95,7 +106,7 @@
"NEWS") "NEWS")
- wrote a manual in Texinfo format - wrote a manual in Texinfo format
## Changes since 0.5.1 ## Changes in 0.5.2
- implemented message counting (`-c, --count`) - implemented message counting (`-c, --count`)
- fixed manual page installation target in src/Makefile.in -- manual page - fixed manual page installation target in src/Makefile.in -- manual page
@ -108,17 +119,17 @@
- implemented recursive search through directories (`-r, --recursive`) - implemented recursive search through directories (`-r, --recursive`)
- config.h[.in] is now wrapped (`#ifndef CONFIG_H` and stuff) - config.h[.in] is now wrapped (`#ifndef CONFIG_H` and stuff)
## Changes since 0.5.0 ## Changes in 0.5.1
- added support for qmail-style maildir folders - added support for qmail-style maildir folders
## Changes since 0.4.0 ## Changes in 0.5.0
- the source of `getopt_long()` is now included, so long options are also available - the source of `getopt_long()` is now included, so long options are also available
on platforms that don't use GNU libc on platforms that don't use GNU libc
- file locking is now performed on mbox folders only - file locking is now performed on mbox folders only
## Changes since 0.2.0 ## Changes in 0.4.0
- added support for MH mailboxes - added support for MH mailboxes
- added scope selection switches `-B` (or `--body`) and `-H` (or `--headers`) - added scope selection switches `-B` (or `--body`) and `-H` (or `--headers`)
@ -129,12 +140,12 @@
- the feature of reading from standard input is gone - the feature of reading from standard input is gone
- added `-v` (or `--version`) switch - added `-v` (or `--version`) switch
## Changes since 0.1.1 ## Changes in 0.2.0
- mboxgrep now puts a shared lock on a mailbox before reading it - mboxgrep now puts a shared lock on a mailbox before reading it
- various code cleanups - various code cleanups
## Changes since 0.1.0 ## Changes in 0.1.1
- fixed install target in Makefile (`install` is now used instead of `cp`) - fixed install target in Makefile (`install` is now used instead of `cp`)
- added support for mailboxes generated by Gnus - added support for mailboxes generated by Gnus

14
TODO.md
View File

@ -4,36 +4,38 @@
- [x] use cryptographic hashes for detecting duplicate messages - [x] use cryptographic hashes for detecting duplicate messages
- [x] add checking for conflicting command-line options - [x] add checking for conflicting command-line options
- [ ] support for deletion of messages after being matched and displayed
- [x] ignore .overview when grepping Gnus folders - [x] ignore .overview when grepping Gnus folders
- [x] inverted matching - [x] inverted matching
- [x] recursive search through directories - [x] recursive search through directories
- [x] writing selected messages to a new folder - [x] writing selected messages to a new folder
- [x] deleting selected messages - [x] deleting selected messages
- [ ] basic time and date matching
- [ ] more advanced time and date matching, with strings such as "yesterday"
- [x] reading messages from standard input - [x] reading messages from standard input
- [x] run-time selection of file locking method - [x] run-time selection of file locking method
- [x] add a debug function - [x] add a debug function
- [ ] support for deletion of messages after being matched and displayed
- [ ] basic time and date matching
- [ ] more advanced time and date matching, with strings such as "yesterday"
- [ ] Remove the option to recursively traverse directories and instruct the users to run mboxgrep in conjuction with find(1) instead.
## File formats, encodings and standards ## File formats, encodings and standards
- [x] migrate to pcre2, as pcre is obsolete - [x] migrate to pcre2, as pcre is obsolete
- [x] support for compressed mbox folders
- [x] support for bzip2 compression
- [ ] use a more modern hash function than MD5 - [ ] use a more modern hash function than MD5
- [ ] MIME support - [ ] MIME support
- [ ] support for GnuPG - [ ] support for GnuPG
- [x] support for compressed mbox folders
- [x] support for bzip2 compression
- [ ] support for XZ-format compression - [ ] support for XZ-format compression
- [ ] support for mail folder conversion - [ ] support for mail folder conversion
- [ ] improve error detection when a directory is not a Maildir or MH folder - [ ] improve error detection when a directory is not a Maildir or MH folder
- [ ] document criteria for folder format detection - [ ] document criteria for folder format detection
- [ ] Maildir: check if an atomic rename() fails. This could be caused if "new" and "cur" subdirectories are not on the same filesystem, for example.
## Miscellaneous ## Miscellaneous
- [x] write Texinfo documentation - [x] write Texinfo documentation
- [x] provide possibility to use flock() instead of fcntl()
- [ ] configuration files - [ ] configuration files
- [ ] make use of lockfile library - [ ] make use of lockfile library
- [ ] make use of Solaris' maillock library - [ ] make use of Solaris' maillock library
- [x] provide possibility to use flock() instead of fcntl()
- [ ] provide national language support with gettext() - [ ] provide national language support with gettext()

View File

@ -1,5 +1,5 @@
# mboxgrep - scan mailbox for messages matching a regular expression # mboxgrep - scan mailbox for messages matching a regular expression
# Copyright (C) 2000 - 2003, 2023 Daniel Spiljar # Copyright (C) 2000 - 2003, 2023 - 2024 Daniel Spiljar
# #
# Mboxgrep is free software; you can redistribute it and/or modify it # Mboxgrep is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by # under the terms of the GNU General Public License as published by
@ -18,18 +18,16 @@
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
# Yawn. # Yawn.
AC_INIT([mboxgrep], [0.7.12], [dspiljar@datatipp.se], [mboxgrep], [https://www.mboxgrep.org/]) AC_INIT([mboxgrep],[0.7.13],[dspiljar@datatipp.se],[mboxgrep],[https://www.mboxgrep.org/])
#AM_INIT_AUTOMAKE #AM_INIT_AUTOMAKE
AM_INIT_AUTOMAKE([foreign]) AM_INIT_AUTOMAKE([foreign])
AC_LANG([C]) AC_LANG([C])
AC_CONFIG_HEADER([src/config.h]) AC_CONFIG_HEADERS([src/config.h])
# Checks for programs. # Checks for programs.
AC_PROG_CC AC_PROG_CC
AC_PROG_INSTALL AC_PROG_INSTALL
# Checks for standard (sp?) header files
AC_HEADER_STDC
AC_HEADER_DIRENT AC_HEADER_DIRENT
# Checks for libraries. # Checks for libraries.
@ -93,7 +91,5 @@ AC_CHECK_FUNCS([strptime])
AC_CHECK_FUNCS(ftw) AC_CHECK_FUNCS(ftw)
AC_CHECK_FUNCS(fts_open) AC_CHECK_FUNCS(fts_open)
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile doc/Makefile src/Makefile])
doc/Makefile
src/Makefile])
AC_OUTPUT AC_OUTPUT

View File

@ -1,4 +1,4 @@
.TH MBOXGREP 1 "20 May 2023" .TH MBOXGREP 1 "27 September 2024"
.SH NAME .SH NAME
mboxgrep \- displays email messages matching a pattern mboxgrep \- displays email messages matching a pattern
.SH SYNOPSIS .SH SYNOPSIS
@ -10,7 +10,7 @@ mboxgrep \- displays email messages matching a pattern
This manual page refers to This manual page refers to
.B mboxgrep .B mboxgrep
version version
.BR 0.7.12 . .BR 0.7.13 .
.PP .PP
.B mboxgrep .B mboxgrep
scans a scans a
@ -18,7 +18,7 @@ scans a
and displays messages matching and displays messages matching
.I PATTERN. .I PATTERN.
.PP .PP
If a mailbox name is ommited, or a single dash (-) is given instead, If a mailbox name is omitted, or a single dash (-) is given instead,
it reads from standard input. it reads from standard input.
It can read mbox folders or output from another It can read mbox folders or output from another
.B mboxgrep .B mboxgrep
@ -72,8 +72,8 @@ Do not lock files. This option is meaningful only if a mbox folder (see below)
is scanned. is scanned.
.IP "-c, --count" .IP "-c, --count"
Suppress normal output and print a count of matching messages. Suppress normal output and print a count of matching messages.
.IP "-o, --output=FOLDER" .IP "-o, --output=MAILBOX"
Suppress normal output and write messages to destination folder FOLDER instead. Suppress normal output and write messages to destination MAILBOX instead.
.IP "-p, --pipe=COMMAND" .IP "-p, --pipe=COMMAND"
Pipe each found message to COMMAND Pipe each found message to COMMAND
.IP "-d, --delete" .IP "-d, --delete"
@ -97,10 +97,26 @@ Search $MAIL for messages from Dirty Harry:
mboxgrep '^From:.*callahan@sanfranciscopolice\\.org' $MAIL mboxgrep '^From:.*callahan@sanfranciscopolice\\.org' $MAIL
.TP .TP
\(bu \(bu
Re-mail to George messages that mention his name:
.PP
mboxgrep --pipe="/usr/lib/sendmail george" --ignore-case george ~/Mail/*
.TP
\(bu
Display all messages contained in folder ~/Mail/incoming, except those Display all messages contained in folder ~/Mail/incoming, except those
that appear to originate from AOL: that appear to originate from AOL:
.PP .PP
mboxgrep -v 'Received:.*aol\\.com' ~/Mail/incoming mboxgrep -v 'Received:.*aol\\.com' ~/Mail/incoming
.TP
\(bu
Do a case-insensitive scan of ~/Mail/incoming for messages with subject
``Weekly News'' and write them to folder ~/Mail/archive:
.PP
mboxgrep -o ~/Mail/archive -H -i '^Subject: Weekly News' ~/Mail/incoming
.TP
\(bu
Count all messages stored in folder spam, ignoring duplicates:
.PP
mboxgrep -nd -c . spam
.SH BUGS .SH BUGS
Report them to address below. Report them to address below.
.SH SEE ALSO .SH SEE ALSO
@ -108,7 +124,8 @@ grep(1),
regex(7), regex(7),
perlre(1), perlre(1),
mbox(5), mbox(5),
RFC 2822 RFC 2822,
RFC 4155
.SH DEDICATION .SH DEDICATION
Mboxgrep is dedicated in loving memory of Vicky, my cat who died of Mboxgrep is dedicated in loving memory of Vicky, my cat who died of
tumor on Sep 12, 2002. tumor on Sep 12, 2002.
@ -116,7 +133,11 @@ tumor on Sep 12, 2002.
You haven't been long with us, but you gave us a lot of joy and all your You haven't been long with us, but you gave us a lot of joy and all your
big heart that stopped ticking too early. I will never forget you. Sleep big heart that stopped ticking too early. I will never forget you. Sleep
well, little friend. well, little friend.
.SH URL .SH HOMEPAGE
http://www.mboxgrep.org/ https://www.mboxgrep.org/
.SH GIT
https://git.datatipp.se/dspiljar/mboxgrep
.PP
https://github.com/dspiljar/mboxgrep
.SH AUTHOR .SH AUTHOR
Daniel Spiljar <dspiljar AT datatipp.se> Daniel Spiljar <dspiljar@datatipp.se>

Binary file not shown.

View File

@ -5,8 +5,8 @@
@setchapternewpage odd @setchapternewpage odd
@set EDITION 0.7 @set EDITION 0.7
@set VERSION 0.7.12 @set VERSION 0.7.13
@set UPDATED 20 May 2023 @set UPDATED 23 September 2024
@dircategory Mail @dircategory Mail
@direntry @direntry
@ -19,7 +19,7 @@
This file documents @code{mboxgrep} (version @value{VERSION}), a This file documents @code{mboxgrep} (version @value{VERSION}), a
mailbox scanning utility. mailbox scanning utility.
Copyright (C) 2000, 2001, 2002, 2003 Daniel Spiljar Copyright (C) 2000 - 2003, 2024 Daniel Spiljar
@end ifinfo @end ifinfo
@menu @menu
@ -171,10 +171,9 @@ Use with extreme caution.
@itemx -nd @itemx -nd
Ignore duplicate messages. Ignore duplicate messages.
@item --output=FOLDER @item --output=MAILBOX
@itemx -o FOLDER @itemx -o MAILBOX
Suppress normal output and write messages to destination folder FOLDER Suppress normal output and write messages to destination MAILBOX instead.
instead.
Note that @code{mboxgrep} assumes the output folder is of the same format Note that @code{mboxgrep} assumes the output folder is of the same format
as the input folder. Currently there is no possibility to convert folders. as the input folder. Currently there is no possibility to convert folders.

View File

@ -1,6 +1,6 @@
/* /*
mboxgrep - scan mailbox for messages matching a regular expression mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000 - 2004, 2006, 2010, 2023 Daniel Spiljar Copyright (C) 2000 - 2004, 2006, 2010, 2023 - 2024 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
@ -47,7 +47,7 @@ void
version (void) version (void)
{ {
fprintf (stdout, "%s %s\n\n" fprintf (stdout, "%s %s\n\n"
"Copyright (C) 2000 - 2004, 2006, 2010, 2023 Daniel Spiljar\n" "Copyright (C) 2000 - 2004, 2006, 2010, 2023 - 2024 Daniel Spiljar\n"
"This program is free software; you can redistribute it and/or " "This program is free software; you can redistribute it and/or "
"modify\nit under the terms of the GNU General Public License " "modify\nit under the terms of the GNU General Public License "
"as published by\nthe Free Software Foundation; either version " "as published by\nthe Free Software Foundation; either version "

View File

@ -1,6 +1,6 @@
/* /*
mboxgrep - scan mailbox for messages matching a regular expression mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000 - 2004, 2006, 2023 Daniel Spiljar Copyright (C) 2000 - 2004, 2006, 2023 - 2024 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
@ -117,7 +117,7 @@ main (int argc, char **argv)
if (config.action == ACTION_DELETE) if (config.action == ACTION_DELETE)
{ {
tmpmbox_create (argv[optind]); tmpmbox_create (argv[optind]);
runtime.tmp_mbox = (mbox_t *) mbox_open (config.tmpfilename, "w"); runtime.tmp_mbox = (mbox_t *) mbox_open (config.tmpfilename, w);
} }
config.boxname = xstrdup (argv[optind]); config.boxname = xstrdup (argv[optind]);

View File

@ -1,6 +1,6 @@
/* /*
mboxgrep - scan mailbox for messages matching a regular expression mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006, 2023 Daniel Spiljar Copyright (C) 2000 - 2004, 2006, 2023 - 2024 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
@ -50,166 +50,47 @@
#endif /* HAVE_LIBDMALLOC */ #endif /* HAVE_LIBDMALLOC */
mbox_t * mbox_t *
mbox_open (const char *path, const char *mode) mbox_open (const char *path, const mbox_mode_t mbox_mode)
{ {
mbox_t *mp; mbox_t *mp;
static int fd; static int fd;
#ifndef HAVE_FLOCK #ifndef HAVE_FLOCK
struct flock lck; struct flock lck;
#endif /* HAVE_FLOCK */ #endif /* HAVE_FLOCK */
char buffer[BUFSIZ];
mp = (mbox_t *) xmalloc (sizeof (mbox_t)); mp = (mbox_t *) xmalloc (sizeof (mbox_t));
mp->postmark_cache = (char *) xmalloc (BUFSIZ * sizeof (char)); mp->postmark_cache = NULL;
if (0 == strcmp ("-", path)) if (0 == strcmp ("-", path))
mp->fp = stdin; mp->fp = stdin;
else else
{ {
if (mode[0] == 'r') if (mbox_mode == w)
fd = m_open (path, O_RDONLY, 0);
else if (mode[0] == 'w')
fd = m_open (path, (O_WRONLY | O_CREAT | O_APPEND), fd = m_open (path, (O_WRONLY | O_CREAT | O_APPEND),
(S_IWUSR | S_IRUSR)); (S_IWUSR | S_IRUSR));
else else
{ fd = m_open (path, O_RDONLY, 0);
fprintf (stderr, "%s: mbox.c: Unknown mode %c. You shouldn't "
"get this error...", APPNAME, mode[0]);
exit (2);
}
if (fd == -1) if (fd == -1)
{ {
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, path);
perror (NULL);
}
errno = 0; errno = 0;
return NULL; return NULL;
} }
if (config.lock > LOCK_NONE) if (config.lock > LOCK_NONE)
{ mbox_lock (fd, path, mbox_mode);
#ifdef HAVE_FLOCK
int op;
if (mode[0] == 'r') mp->fp = mbox_fdopen (fd, path, mbox_mode);
op = LOCK_SH;
else
op = LOCK_EX;
if (-1 == flock (fd, op))
#else
memset (&lck, 0, sizeof (struct flock));
lck.l_whence = SEEK_SET;
if (mode[0] == 'r')
lck.l_type = F_RDLCK;
else
lck.l_type = F_WRLCK;
if (-1 == fcntl (fd, F_SETLK, &lck))
#endif /* HAVE_FLOCK */
{
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, path);
perror (NULL);
}
errno = 0;
close (fd);
return NULL;
}
}
if (mode[0] == 'r')
{
if (config.format == FORMAT_MBOX)
mp->fp = (FILE *) m_fdopen (fd, "r");
#ifdef HAVE_LIBZ
else if (config.format == FORMAT_ZMBOX)
mp->fp = (gzFile *) m_gzdopen (fd, "rb");
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == FORMAT_BZ2MBOX)
mp->fp = (BZFILE *) BZ2_bzdopen (fd, "rb");
#endif /* HAVE_LIBBZ2 */
}
else if (mode[0] == 'w')
{
if (config.format == FORMAT_MBOX)
mp->fp = (FILE *) m_fdopen (fd, "w");
#ifdef HAVE_LIBZ
else if (config.format == FORMAT_ZMBOX)
mp->fp = (gzFile *) m_gzdopen (fd, "wb");
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == FORMAT_BZ2MBOX)
mp->fp = (BZFILE *) BZ2_bzdopen (fd, "wb");
#endif /* HAVE_LIBBZ2 */
}
if (mp->fp == NULL)
{
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, path);
perror (NULL);
}
errno = 0;
close (fd);
return NULL;
}
} }
if (mode[0] == 'r') if (mbox_mode == r)
{ {
if (config.format == FORMAT_MBOX) mp->postmark_cache = mbox_check_postmark (mp, path);
fgets (buffer, BUFSIZ, mp->fp);
#ifdef HAVE_LIBZ
else if (config.format == FORMAT_ZMBOX)
gzgets (mp->fp, buffer, BUFSIZ);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == FORMAT_BZ2MBOX)
{
char c[1] = "\0";
int n = 0;
while (c[0] != '\n' && n < BUFSIZ) if (! mp->postmark_cache)
{ return NULL;
BZ2_bzread (mp->fp, c, 1);
buffer[n] = c[0];
n++;
}
buffer[n] = '\0';
}
#endif /* HAVE_LIBBZ2 */
if (0 != strncmp ("From ", buffer, 5))
{
if (config.merr)
{
if (0 == strcmp ("-", path))
fprintf (stderr, "%s: (standard input): Not a mbox folder\n",
APPNAME);
else
fprintf (stderr, "%s: %s: Not a mbox folder\n", APPNAME,
path);
}
if (config.format == FORMAT_MBOX)
fclose (mp->fp);
#ifdef HAVE_LIBZ
else if (config.format == FORMAT_ZMBOX)
gzclose (mp->fp);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == FORMAT_BZ2MBOX)
BZ2_bzclose (mp->fp);
#endif /* HAVE_LIBBZ2 */
return NULL;
}
strcpy (mp->postmark_cache, buffer);
} }
return mp; return mp;
} }
@ -431,3 +312,127 @@ tmpfile_create (void)
} }
return fd; return fd;
} }
void
mbox_lock (int fd, const char *path, const mbox_mode_t mbox_mode)
{
#ifdef HAVE_FLOCK
int op;
if (mbox_mode == r)
op = LOCK_SH;
else
op = LOCK_EX;
if (-1 == flock (fd, op))
#else
memset (&lck, 0, sizeof (struct flock));
lck.l_whence = SEEK_SET;
if (mode[0] == 'r')
lck.l_type = F_RDLCK;
else
lck.l_type = F_WRLCK;
if (-1 == fcntl (fd, F_SETLK, &lck))
#endif /* HAVE_FLOCK */
{
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, path);
perror (NULL);
exit (2);
}
}
}
void *
mbox_fdopen (int fd, const char *path, const mbox_mode_t mbox_mode)
{
void *f;
char *file_mode;
if (mbox_mode == w)
file_mode = xstrdup("wb");
else
file_mode = xstrdup("rb");
if (config.format == FORMAT_MBOX)
f = (FILE *) m_fdopen (fd, file_mode);
#ifdef HAVE_LIBZ
else if (config.format == FORMAT_ZMBOX)
f = (gzFile *) m_gzdopen (fd, file_mode);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == FORMAT_BZ2MBOX)
f = (BZFILE *) BZ2_bzdopen (fd, file_mode);
#endif /* HAVE_LIBBZ2 */
if (f == NULL)
{
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, path);
perror (NULL);
}
errno = 0;
close (fd);
return NULL;
}
return f;
}
char *
mbox_check_postmark(mbox_t *mp, const char *path)
{
char *buffer;
buffer = (char *) xmalloc (BUFSIZ * sizeof (char));
memset (buffer, 0, BUFSIZ);
if (config.format == FORMAT_MBOX)
fgets (buffer, BUFSIZ, mp->fp);
#ifdef HAVE_LIBZ
else if (config.format == FORMAT_ZMBOX)
gzgets (mp->fp, buffer, BUFSIZ);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == FORMAT_BZ2MBOX)
{
char c[1] = "\0";
int n = 0;
while (c[0] != '\n' && n < BUFSIZ)
{
BZ2_bzread (mp->fp, c, 1);
buffer[n] = c[0];
n++;
}
buffer[n] = '\0';
}
#endif /* HAVE_LIBBZ2 */
if (0 != strncmp ("From ", buffer, 5))
{
if ((config.merr) && (buffer[0] != '\0'))
{
if (0 == strcmp ("-", path))
fprintf (stderr, "%s: (standard input): Not an mbox folder\n",
APPNAME);
else
fprintf (stderr, "%s: %s: Not an mbox folder\n", APPNAME,
path);
}
if (config.format == FORMAT_MBOX)
fclose (mp->fp);
#ifdef HAVE_LIBZ
else if (config.format == FORMAT_ZMBOX)
gzclose (mp->fp);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == FORMAT_BZ2MBOX)
BZ2_bzclose (mp->fp);
#endif /* HAVE_LIBBZ2 */
return NULL;
}
return buffer;
}

View File

@ -1,6 +1,6 @@
/* /*
mboxgrep - scan mailbox for messages matching a regular expression mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000 - 2004, 2023 Daniel Spiljar Copyright (C) 2000 - 2004, 2023 - 2024 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
@ -19,9 +19,7 @@
#ifndef MBOX_H #ifndef MBOX_H
# define MBOX_H 1 # define MBOX_H 1
# include <config.h> # include <config.h>
# include "message.h" # include "message.h"
typedef struct typedef struct
@ -31,8 +29,14 @@ typedef struct
char *postmark_cache; char *postmark_cache;
} mbox_t; } mbox_t;
typedef enum
{
r,
w,
} mbox_mode_t;
mbox_t *mbox_open (const char *path, const char *mode);
mbox_t *mbox_open (const char *path, const mbox_mode_t mbox_mode);
void tmpmbox_create (const char *path); void tmpmbox_create (const char *path);
void tmpfile_name (const char *path); void tmpfile_name (const char *path);
void tmpfile_mod_own (const int fd, const char *path); void tmpfile_mod_own (const int fd, const char *path);
@ -40,5 +44,8 @@ int tmpfile_create (void);
void mbox_close (mbox_t * mbp); void mbox_close (mbox_t * mbp);
message_t *mbox_read_message (mbox_t * mp); message_t *mbox_read_message (mbox_t * mp);
void mbox_write_message (message_t * m, mbox_t * mbox); void mbox_write_message (message_t * m, mbox_t * mbox);
void mbox_lock (int fd, const char *path, const mbox_mode_t mbox_mode);
void *mbox_fdopen (int fd, const char *path, const mbox_mode_t mbox_mode);
char *mbox_check_postmark(mbox_t *mp, const char *path);
#endif /* MBOX_H */ #endif /* MBOX_H */

View File

@ -1,6 +1,6 @@
/* /*
mboxgrep - scan mailbox for messages matching a regular expression mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000 - 2003, 2006, 2023 Daniel Spiljar Copyright (C) 2000 - 2003, 2006, 2023 - 2024 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
@ -21,8 +21,8 @@
#define MBOXGREP_H #define MBOXGREP_H
#define APPNAME "mboxgrep" #define APPNAME "mboxgrep"
#define VERSION "0.7.12" #define VERSION "0.7.13"
#define BUGREPORT_ADDR "dspiljar AT datatipp.se" #define BUGREPORT_ADDR "dspiljar@datatipp.se"
#define HOST_NAME_SIZE 256 #define HOST_NAME_SIZE 256

View File

@ -1,6 +1,6 @@
/* /*
mboxgrep - scan mailbox for messages matching a regular expression mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000 - 2004, 2006, 2023 Daniel Spiljar Copyright (C) 2000 - 2004, 2006, 2023 - 2024 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
@ -107,7 +107,7 @@ scan_mailbox (char path[])
if ((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX) if ((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX)
|| (config.format == FORMAT_BZ2MBOX)) || (config.format == FORMAT_BZ2MBOX))
{ {
mbox = (mbox_t *) mbox_open (path, "r"); mbox = (mbox_t *) mbox_open (path, r);
if (mbox == NULL) if (mbox == NULL)
return; return;
} }
@ -179,7 +179,7 @@ scan_mailbox (char path[])
else if ((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX) else if ((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX)
|| (config.format == FORMAT_BZ2MBOX)) || (config.format == FORMAT_BZ2MBOX))
{ {
out = mbox_open (config.outboxname, "w"); out = mbox_open (config.outboxname, w);
/* fprintf (out->fp, "%s\n%s", msg->headers, msg->body); */ /* fprintf (out->fp, "%s\n%s", msg->headers, msg->body); */
mbox_write_message (msg, out); mbox_write_message (msg, out);
mbox_close (out); mbox_close (out);