Compare commits

...

46 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
dd5fefe22d
Update the TODO list and bump the version to 0.7.12. 2023-05-20 20:34:23 +02:00
cbba5c2a33
Remove config.h.in from the git repo, as it is autogenerated. 2023-05-20 20:09:23 +02:00
27082f9629
Minor updates of the documentation. 2023-05-18 13:43:09 +02:00
d17f37b3c5
Include the contrib subdirectory in the distribution tarball. 2023-05-18 13:35:35 +02:00
e004f116b7
Merge branch 'pcre2-port' 2023-05-17 19:40:41 +02:00
e5409a897d
Port to the pcre2 library. 2023-05-17 17:58:59 +02:00
55aa25eca3
Add migration from pcre to pcre2 to the TODO list. 2023-05-08 22:54:58 +02:00
7ebef4a322
Fix a compile error caused by an extra curly bracket. 2023-04-22 17:36:28 +02:00
d04349e9b4
Minor code cleanup and fix a compilation warning. 2023-04-19 23:04:57 +02:00
c19253d080
Check command-line options for conflicting matchers and actions. 2023-04-19 21:55:25 +02:00
3040f9c363
Fix Automake macros. Remove autogenerated files from the git repo. 2023-03-28 00:59:16 +02:00
033063befc
Version bump to 0.7.11. 2023-03-24 15:18:53 +01:00
7720415afa
Updates to the news and installation instructions. 2023-03-24 15:00:06 +01:00
68c0ddee91
Merge branch 'automake' 2023-03-24 14:10:14 +01:00
53d3381cd4
Merge branch 'automake' of git.datatipp.se:dspiljar/mboxgrep into automake 2023-03-24 13:50:10 +01:00
c02deefbd5
Utilize GNU Automake instead of manually written Makefile.in files. 2023-03-24 13:47:16 +01:00
b7006b77b5
Utilize GNU Automake instead of manually written Makefile.in files. 2023-03-23 22:10:04 +01:00
43e7695eac
Update the basic documentation. 2023-03-08 15:19:20 +01:00
844dc84974
Ignore backup files. 2023-03-07 16:54:41 +01:00
ee2489483b
Code cleanup and indentation.
C source files (with the exception of third-party files, i.e. getopt and
md5) have been indented with GNU indent.

The indentation "standard" has been documented in the readme file.
2023-03-07 16:51:33 +01:00
882a38f908
Refinement of the TODO list. 2023-03-01 20:53:15 +01:00
42 changed files with 13051 additions and 6728 deletions

1
.gitattributes vendored Normal file
View File

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

15
.gitignore vendored
View File

@ -1,6 +1,21 @@
Makefile
config.h
config.h.in
config.log
config.status
src/*.o
src/*.exe
src/mboxgrep
src/.deps/
src/stamp-h1
aclocal.m4
autom4te.cache/
Makefile.in
configure
compile
depcomp
install-sh
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

26
INSTALL.md Normal file
View File

@ -0,0 +1,26 @@
# Compilation and installation of mboxgrep
`mboxgrep` should compile on a modern Unix-like operating system, such as GNU/Linux or FreeBSD.
Autoconf and Automake are used, and the most basic compilation procedure consists of:
```
autoreconf --install
./configure
make
make install # root rights probably needed here, prefix with sudo in such case
```
(Invocation of `autoreconf` is only required if the source tree has been cloned from the
git repository.)
To see the list of flags accepted by the configure script, run:
```
./configure --help
```
Optionally, `mboxgrep` can be linked with the following libraries:
- PCRE2, to enable support for regular expressions compatible with Perl 5;
- zlib and bzlib, to enable support for compressed mbox folders.

2
Makefile.am Normal file
View File

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

View File

@ -1,37 +0,0 @@
# mboxgrep - scan mailbox for messages matching a regular expression
# Copyright (C) 2000, 01 Daniel Spiljar
#
# Mboxgrep is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Mboxgrep 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 mboxgrep; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# $Id: Makefile.in,v 1.1 2001-10-26 13:07:28 dspiljar Exp $
SHELL = /bin/sh
all:
cd src; $(MAKE)
clean:
cd src; $(MAKE) clean
distclean:
rm -f *~ Makefile config.status config.log config.cache
cd src; $(MAKE) distclean
cd doc; $(MAKE) distclean
install:
cd src; $(MAKE) install
cd doc; $(MAKE) install
.NOEXPORT:

60
NEWS.md
View File

@ -1,6 +1,28 @@
# Changes of mboxgrep
## Changes since 0.7.9
## 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).
- Check command-line options for conflicting matchers and actions.
- Various minor code cleanups.
## Changes in 0.7.11
- 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).
## Changes in 0.7.10
- development has been restarted after a longer hiatus
- moved the source tree to git
@ -9,7 +31,7 @@
- fixed multiple compilation errors and warnings on Linux and FreeBSD
- started implementing a debug mode
## Changes since 0.7.8
## Changes in 0.7.9
- implemented support for mbox folders compressed with bzip2 algorithm
- improved detection of PCRE library; this also fixes a compilation bug
@ -18,7 +40,7 @@
folder and temporary directory were on different filesystems;
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
and maildir folders with the same cause
@ -27,46 +49,46 @@
- mboxgrep can now read gzip compressed mbox folders from standard input
(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
## Changes since 0.7.6
## Changes in 0.7.6a
- 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
maildirs
- code cleanups
## Changes since 0.7.4
## Changes in 0.7.5
- 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
## Changes since 0.7.2
## Changes in 0.7.3
- file locking method can be selected at runtime
- mboxgrep used to coredump on messages with empty headers; the problem is
now hopefully fixed
- 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
- mboxgrep should now compile on systems which don't have `getopt_long()`
- other minor bugfixes
## Changes since 0.7.0
## Changes in 0.7.1
- 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
- mboxgrep is almost completely rewritten
@ -76,7 +98,7 @@
command)
- 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
of standard output)
@ -84,7 +106,7 @@
"NEWS")
- wrote a manual in Texinfo format
## Changes since 0.5.1
## Changes in 0.5.2
- implemented message counting (`-c, --count`)
- fixed manual page installation target in src/Makefile.in -- manual page
@ -97,17 +119,17 @@
- implemented recursive search through directories (`-r, --recursive`)
- 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
## Changes since 0.4.0
## Changes in 0.5.0
- the source of `getopt_long()` is now included, so long options are also available
on platforms that don't use GNU libc
- 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 scope selection switches `-B` (or `--body`) and `-H` (or `--headers`)
@ -118,12 +140,12 @@
- the feature of reading from standard input is gone
- 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
- 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`)
- added support for mailboxes generated by Gnus

View File

@ -1,4 +1,7 @@
mboxgrep - displays e-mail messages matching a pattern
# mboxgrep - selects e-mail messages matching a pattern
`mboxgrep` is a `grep(1)`-like tool which scans mailboxes and selects
e-mail messages matching a pattern.
Full description of mboxgrep is contained in the documentation,
which is provided both in manpage and texinfo format, to satisfy
@ -11,5 +14,8 @@ are welcome.
If you intend to bundle mboxgrep with an operating system (such as a
GNU/Linux distrubution, for example), please drop me a line about it.
For build instructions, read the file "INSTALL", and run
For build instructions, read the file `INSTALL.md`, and run
`./configure --help`.
This project aims to follow the [GNU coding style](https://www.gnu.org/prep/standards/html_node/Formatting.html),
at least loosely. The code should be indented with `indent -gnu -nut -ppi2`.

20
TODO.md
View File

@ -3,33 +3,39 @@
## Behavior
- [x] use cryptographic hashes for detecting duplicate messages
- [ ] add checking for conflicting command-line options
- [ ] support for deletion of messages after being matched and displayed
- [x] add checking for conflicting command-line options
- [x] ignore .overview when grepping Gnus folders
- [x] inverted matching
- [x] recursive search through directories
- [x] writing selected messages to a new folder
- [x] deleting selected messages
- [ ] literal date matching
- [x] reading messages from standard input
- [x] run-time selection of file locking method
- [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
- [ ] MIME support
- [ ] support for GnuPG
- [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
- [ ] MIME support
- [ ] support for GnuPG
- [ ] support for XZ-format compression
- [ ] support for mail folder conversion
- [ ] use a more modern hash function than MD5
- [ ] improve error detection when a directory is not a Maildir or MH folder
- [ ] 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
- [x] write Texinfo documentation
- [x] provide possibility to use flock() instead of fcntl()
- [ ] configuration files
- [ ] make use of lockfile library
- [ ] make use of Solaris' maillock library
- [x] provide possibility to use flock() instead of fcntl()
- [ ] provide national language support with gettext()

5274
configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
# mboxgrep - scan mailbox for messages matching a regular expression
# Copyright (C) 2000, 2001, 2002, 2003 Daniel Spiljar
# Copyright (C) 2000 - 2003, 2023 - 2024 Daniel Spiljar
#
# Mboxgrep is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@ -15,53 +15,52 @@
# along with mboxgrep; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# $Id: configure.ac,v 1.13 2003-08-10 22:45:45 dspiljar Exp $
# Process this file with autoconf to produce a configure script.
# Yawn.
AC_INIT
AC_LANG(C)
AC_CONFIG_HEADER([src/config.h])
AC_INIT([mboxgrep],[0.7.13],[dspiljar@datatipp.se],[mboxgrep],[https://www.mboxgrep.org/])
#AM_INIT_AUTOMAKE
AM_INIT_AUTOMAKE([foreign])
AC_LANG([C])
AC_CONFIG_HEADERS([src/config.h])
# Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
# Checks for standard (sp?) header files
AC_HEADER_STDC
AC_HEADER_DIRENT
# Checks for libraries.
# Check for PCRE library
AC_ARG_WITH(pcre, [ --without-pcre Compile without Perl regexp support],,
# Check for PCRE2 library
AC_ARG_WITH(pcre2, [ --without-pcre2 Compile without Perl regexp support],,
[
AC_PATH_PROG(PCRE_CONFIG, pcre-config)
AC_PATH_PROG(PCRE2_CONFIG, pcre2-config)
if test "$PCRE_CONFIG"; then
CFLAGS="$CFLAGS `$PCRE_CONFIG --cflags`"
LIBS="$LIBS `$PCRE_CONFIG --libs`"
if test "$PCRE2_CONFIG"; then
CFLAGS="$CFLAGS `$PCRE2_CONFIG --cflags`"
LIBS="$LIBS `$PCRE2_CONFIG --libs32`"
AC_LINK_IFELSE(
[
#include <pcre.h>
#define PCRE2_CODE_UNIT_WIDTH 32
#include <pcre2.h>
int main ()
{
return 0;
}
],
AC_DEFINE(HAVE_LIBPCRE),
AC_DEFINE(HAVE_LIBPCRE2),
[
AC_MSG_NOTICE(found pcre-config but could not compile test program.)
AC_MSG_FAILURE(is PCRE properly installed?)
AC_MSG_NOTICE(found pcre2-config but could not compile test program.)
AC_MSG_FAILURE(is PCRE2 properly installed?)
]
)
else
AC_MSG_NOTICE(pcre-config not found)
AC_MSG_NOTICE(trying to find PCRE anyway)
AC_CHECK_LIB(pcre, main)
AC_MSG_NOTICE(pcre2-config not found)
AC_MSG_NOTICE(trying to find PCRE2 anyway)
AC_CHECK_LIB(pcre2, main)
fi
]
)
@ -92,7 +91,5 @@ AC_CHECK_FUNCS([strptime])
AC_CHECK_FUNCS(ftw)
AC_CHECK_FUNCS(fts_open)
AC_CONFIG_FILES([Makefile
doc/Makefile
src/Makefile])
AC_CONFIG_FILES([Makefile doc/Makefile src/Makefile])
AC_OUTPUT

2
doc/Makefile.am Normal file
View File

@ -0,0 +1,2 @@
dist_man_MANS = mboxgrep.1
info_TEXINFOS = mboxgrep.texi

View File

@ -1,41 +0,0 @@
# mboxgrep - search mailbox for messages matching a regular expression
# Copyright (C) 2000, 01 Daniel Spiljar
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# 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
# $Id: Makefile.in,v 1.1 2001-10-26 13:07:55 dspiljar Exp $
MANPAGE = mboxgrep.1
INSTALL = @INSTALL@
prefix = @prefix@
mandir = @mandir@
infodir = @infodir@
SHELL = /bin/sh
.PHONY: all
all:
.PHONY: distclean
distclean:
rm -f *~ Makefile
.PHONY: install
install: mboxgrep.1
$(INSTALL) -d $(mandir)/man1
$(INSTALL) -m 0644 $(MANPAGE) $(mandir)/man1
$(INSTALL) -d $(infodir)
$(INSTALL) -m 0644 mboxgrep.info $(infodir)
.NOEXPORT:

View File

@ -1,4 +1,4 @@
.TH MBOXGREP 1 "17 Feb 2023"
.TH MBOXGREP 1 "27 September 2024"
.SH NAME
mboxgrep \- displays email messages matching a pattern
.SH SYNOPSIS
@ -10,7 +10,7 @@ mboxgrep \- displays email messages matching a pattern
This manual page refers to
.B mboxgrep
version
.BR 0.7.10 .
.BR 0.7.13 .
.PP
.B mboxgrep
scans a
@ -18,7 +18,7 @@ scans a
and displays messages matching
.I PATTERN.
.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 can read mbox folders or output from another
.B mboxgrep
@ -72,8 +72,8 @@ Do not lock files. This option is meaningful only if a mbox folder (see below)
is scanned.
.IP "-c, --count"
Suppress normal output and print a count of matching messages.
.IP "-o, --output=FOLDER"
Suppress normal output and write messages to destination folder FOLDER instead.
.IP "-o, --output=MAILBOX"
Suppress normal output and write messages to destination MAILBOX instead.
.IP "-p, --pipe=COMMAND"
Pipe each found message to COMMAND
.IP "-d, --delete"
@ -97,10 +97,26 @@ Search $MAIL for messages from Dirty Harry:
mboxgrep '^From:.*callahan@sanfranciscopolice\\.org' $MAIL
.TP
\(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
that appear to originate from AOL:
.PP
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
Report them to address below.
.SH SEE ALSO
@ -108,7 +124,8 @@ grep(1),
regex(7),
perlre(1),
mbox(5),
RFC 2822
RFC 2822,
RFC 4155
.SH DEDICATION
Mboxgrep is dedicated in loving memory of Vicky, my cat who died of
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
big heart that stopped ticking too early. I will never forget you. Sleep
well, little friend.
.SH URL
http://www.mboxgrep.org/
.SH HOMEPAGE
https://www.mboxgrep.org/
.SH GIT
https://git.datatipp.se/dspiljar/mboxgrep
.PP
https://github.com/dspiljar/mboxgrep
.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
@set EDITION 0.7
@set VERSION 0.7.10
@set UPDATED 17 Feb 2023
@set VERSION 0.7.13
@set UPDATED 23 September 2024
@dircategory Mail
@direntry
@ -19,7 +19,7 @@
This file documents @code{mboxgrep} (version @value{VERSION}), a
mailbox scanning utility.
Copyright (C) 2000, 2001, 2002, 2003 Daniel Spiljar
Copyright (C) 2000 - 2003, 2024 Daniel Spiljar
@end ifinfo
@menu
@ -171,10 +171,9 @@ Use with extreme caution.
@itemx -nd
Ignore duplicate messages.
@item --output=FOLDER
@itemx -o FOLDER
Suppress normal output and write messages to destination folder FOLDER
instead.
@item --output=MAILBOX
@itemx -o MAILBOX
Suppress normal output and write messages to destination MAILBOX instead.
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.

11772
doc/texinfo.tex Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,251 +0,0 @@
#!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0

6
src/Makefile.am Normal file
View File

@ -0,0 +1,6 @@
bin_PROGRAMS = mboxgrep
mboxgrep_SOURCES = info.c info.h maildir.c maildir.h main.c mbox.c mbox.h \
mboxgrep.h md5.c md5.h message.h misc.c misc.h mh.c mh.h \
getopt.c getopt1.c getopt.h re.c re.h scan.c scan.h wrap.c wrap.h
mboxgrep_LDADD = $(LIBOBJS)

View File

@ -1,57 +0,0 @@
# mboxgrep - scan mailbox for messages matching a regular expression
# Copyright (C) 2000, 2001, 2002, 2003, 2006 Daniel Spiljar
#
# Mboxgrep is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Mboxgrep 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 mboxgrep; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# $Id: Makefile.in,v 1.12 2006-07-07 04:38:53 dspiljar Exp $
srcdir = @srcdir@
CC = @CC@
OBJS = info.o main.o mh.o scan.o maildir.o mbox.o misc.o \
wrap.o getopt.o getopt1.o md5.o re.o
SRCS = info.c main.c mh.c scan.c maildir.c mbox.c misc.c \
wrap.c getopt.c getopt1.c md5.c re.c
TARGET = mboxgrep
CFLAGS = @CFLAGS@
LIBS = @LIBS@
INSTALL = @INSTALL@
prefix = @prefix@
SHELL = /bin/sh
INCLUDES = -I. -I$(srcdir)
.SUFFIXES:
.SUFFIXES: .c .o
.c.o:
$(CC) $(CFLAGS) $(INCLUDES) -c $<
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
.PHONY: clean
clean:
rm -f $(TARGET) $(OBJS) core
.PHONY: distclean
distclean:
rm -f *~ Makefile config.h
.PHONY: install
install: mboxgrep
$(INSTALL) -d $(prefix)/bin
$(INSTALL) -s $(TARGET) $(prefix)/bin
.NOEXPORT:

View File

@ -1,67 +0,0 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
/* Define to 1 if you have the `fcntl' function. */
#undef HAVE_FCNTL
/* Define to 1 if you have the `flock' function. */
#undef HAVE_FLOCK
/* Define to 1 if you have the `fts_open' function. */
#undef HAVE_FTS_OPEN
/* Define to 1 if you have the `ftw' function. */
#undef HAVE_FTW
/* Define to 1 if you have the `bz2' library (-lbz2). */
#undef HAVE_LIBBZ2
/* Define to 1 if you have the `dmalloc' library (-ldmalloc). */
#undef HAVE_LIBDMALLOC
/* Define to 1 if you have the `garfield' library (-lgarfield). */
#undef HAVE_LIBGARFIELD
/* Define to 1 if you have the `pcre' library (-lpcre). */
#undef HAVE_LIBPCRE
/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_LIBZ
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the `regcomp' function. */
#undef HAVE_REGCOMP
/* Define to 1 if you have the `strptime' function. */
#undef HAVE_STRPTIME
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_DIR_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_NDIR_H
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS

View File

@ -1,6 +1,6 @@
/*
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
under the terms of the GNU General Public License as published by
@ -22,149 +22,152 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "mboxgrep.h"
void
print_wrap (char *str, int len, int *n)
print_wrap (char *str)
{
*n += len;
static int n = 0;
n += strlen (str);
fprintf (stdout, "%s", str);
if (*n >= 50)
if (n >= 50)
{
fprintf (stdout, "\n");
*n = 0;
n = 0;
}
else fprintf (stdout, " ");
else
fprintf (stdout, " ");
}
void
version (void)
{
int n = 0;
fprintf (stdout, "%s %s\n\n"
"Copyright (C) 2000 - 2004, 2006, 2010, 2023 Daniel Spiljar\n"
"This program is free software; you can redistribute it and/or "
"modify\nit under the terms of the GNU General Public License "
"as published by\nthe Free Software Foundation; either version "
"2 of the License, or\n(at your option) any later version.\n\n",
APPNAME, VERSION);
"Copyright (C) 2000 - 2004, 2006, 2010, 2023 - 2024 Daniel Spiljar\n"
"This program is free software; you can redistribute it and/or "
"modify\nit under the terms of the GNU General Public License "
"as published by\nthe Free Software Foundation; either version "
"2 of the License, or\n(at your option) any later version.\n\n",
APPNAME, VERSION);
fprintf (stdout, "Compilation options:\n");
#ifdef HAVE_DIRENT_H
print_wrap ("HAVE_DIRENT_H", 13, &n);
print_wrap ("HAVE_DIRENT_H");
#endif /* HAVE_DIRENT_H */
#ifdef HAVE_FCNTL
print_wrap ("HAVE_FCNTL", 10, &n);
print_wrap ("HAVE_FCNTL");
#endif /* HAVE_FCNTL */
#ifdef HAVE_FLOCK
print_wrap ("HAVE_FLOCK", 10, &n);
print_wrap ("HAVE_FLOCK");
#endif /* HAVE_FLOCK */
#ifdef HAVE_FTS_OPEN
print_wrap ("HAVE_FTS_OPEN", 13, &n);
print_wrap ("HAVE_FTS_OPEN");
#else
# ifdef HAVE_FTW
print_wrap ("HAVE_FTW", 8, &n);
# endif /* HAVE_FTW */
# ifdef HAVE_FTW
print_wrap ("HAVE_FTW");
# endif
/* HAVE_FTW */
#endif /* HAVE_FTS_OPEN */
/*
fprintf (stdout, "HAVE_LIBLOCKFILE ");
*/
#ifdef HAVE_LIBPCRE
print_wrap ("HAVE_LIBPCRE", 12, &n);
#endif /* HAVE_LIBPCRE */
#ifdef HAVE_LIBPCRE2
print_wrap ("HAVE_LIBPCRE2");
#endif /* HAVE_LIBPCRE2 */
#ifdef HAVE_LIBZ
print_wrap ("HAVE_LIBZ", 9, &n);
print_wrap ("HAVE_LIBZ");
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
print_wrap ("HAVE_LIBBZ2", 11, &n);
print_wrap ("HAVE_LIBBZ2");
#endif /* HAVE_LIBBZ2 */
#ifdef HAVE_NDIR_H
print_wrap ("HAVE_NDIR_H", 11, &n);
print_wrap ("HAVE_NDIR_H");
#endif /* HAVE_NDIR_H */
#ifdef HAVE_SYS_DIR_H
print_wrap ("HAVE_SYS_DIR_H", 14, &n);
print_wrap ("HAVE_SYS_DIR_H");
#endif /* HAVE_SYS_DIR_H */
#ifdef HAVE_SYS_NDIR_H
print_wrap ("HAVE_SYS_NDIR_H", 15, &n);
print_wrap ("HAVE_SYS_NDIR_H");
#endif /* HAVE_SYS_NDIR_H */
#ifdef HAVE_STRPTIME
print_wrap ("HAVE_STRPTIME", 15, &n);
print_wrap ("HAVE_STRPTIME");
#endif /* HAVE_STRPTIME */
#ifdef HAVE_REGCOMP
print_wrap ("HAVE_REGCOMP", 15, &n);
print_wrap ("HAVE_REGCOMP");
#endif /* HAVE_REGCOMP */
#ifdef HAVE_LIBDMALLOC
print_wrap ("HAVE_LIBDMALLOC", 15, &n);
print_wrap ("HAVE_LIBDMALLOC");
#endif /* HAVE_LIBDMALLOC */
fprintf (stdout, "\n");
exit(0);
exit (0);
}
void
void
help (void)
{
fprintf(stdout, "%s %s - search MAILBOX for messages matching PATTERN\n\n",
APPNAME, VERSION);
fprintf(stdout,
"Miscellaneous:\n\n"
" -h, --help\t\t\tThis help screen\n"
" -V, --version\t\tDisplay version, copyright and\n"
"\t\t\t\tcompile-time options information\n"
" -r, --recursive\t\tDescend into directories recursively\n\n"
"Output control:\n\n"
" -c, --count\t\t\tPrint a count of matching messages\n"
" -d, --delete\t\t\tDelete matching messages\n"
" -nd, --no-duplicates\t\tIgnore duplicate messages\n"
" -o, --output=MAILBOX\t\tWrite messages to MAILBOX\n"
" -p, --pipe=COMMAND\t\tPipe each found message to COMMAND\n"
" -s, --no-messages\t\tSuppress most error messages\n"
" --debug\t\t\tPrint messages useful for debugging\n\n"
"Matching criteria:\n\n"
" -E, --extended-regexp\tPATTERN is an extended regular expression\n"
" -G, --basic-regexp\t\tPATTERN is a basic regular expression\n");
#ifdef HAVE_LIBPCRE
fprintf(stdout,
" -P, --perl-regexp\t\tPATTERN is a Perl regular expression\n");
#endif /* HAVE_LIBPCRE */
fprintf(stdout,
" -e, --regexp=PATTERN\t\tUse PATTERN as a regular expression\n"
" -i, --ignore-case\t\tIgnore case distinctions\n"
" -v, --invert-match\t\tSelect non-matching messages\n\n"
"Search scope selection:\n\n"
" -H, --headers\t\tMatch PATTERN against message headers\n"
" -B, --body\t\t\tMatch PATTERN against message body\n\n"
"File locking:\n\n"
" -nl, --no-file-lock\t\tDo not lock files\n"
" -l, --file-lock=METHOD\tSelect file locking METHOD\n"
"\t\t\t\tMETHOD is");
fprintf (stdout, "%s %s - search MAILBOX for messages matching PATTERN\n\n",
APPNAME, VERSION);
fprintf (stdout,
"Miscellaneous:\n\n"
" -h, --help\t\t\tThis help screen\n"
" -V, --version\t\tDisplay version, copyright and\n"
"\t\t\t\tcompile-time options information\n"
" -r, --recursive\t\tDescend into directories recursively\n\n"
"Output control:\n\n"
" -c, --count\t\t\tPrint a count of matching messages\n"
" -d, --delete\t\t\tDelete matching messages\n"
" -nd, --no-duplicates\t\tIgnore duplicate messages\n"
" -o, --output=MAILBOX\t\tWrite messages to MAILBOX\n"
" -p, --pipe=COMMAND\t\tPipe each found message to COMMAND\n"
" -s, --no-messages\t\tSuppress most error messages\n"
" --debug\t\t\tPrint messages useful for debugging\n\n"
"Matching criteria:\n\n"
" -E, --extended-regexp\tPATTERN is an extended regular expression\n"
" -G, --basic-regexp\t\tPATTERN is a basic regular expression\n");
#ifdef HAVE_LIBPCRE2
fprintf (stdout,
" -P, --perl-regexp\t\tPATTERN is a Perl regular expression\n");
#endif /* HAVE_LIBPCRE2 */
fprintf (stdout,
" -e, --regexp=PATTERN\t\tUse PATTERN as a regular expression\n"
" -i, --ignore-case\t\tIgnore case distinctions\n"
" -v, --invert-match\t\tSelect non-matching messages\n\n"
"Search scope selection:\n\n"
" -H, --headers\t\tMatch PATTERN against message headers\n"
" -B, --body\t\t\tMatch PATTERN against message body\n\n"
"File locking:\n\n"
" -nl, --no-file-lock\t\tDo not lock files\n"
" -l, --file-lock=METHOD\tSelect file locking METHOD\n"
"\t\t\t\tMETHOD is");
#ifdef HAVE_FCNTL
fprintf(stdout, " `fcntl',");
fprintf (stdout, " `fcntl',");
#endif /* HAVE_FCNTL */
#ifdef HAVE_FLOCK
fprintf(stdout, " `flock',");
fprintf (stdout, " `flock',");
#endif /* HAVE_FLOCK */
fprintf(stdout, " or `none'\n\n"
"Mailbox type selection:\n\n"
" -m, --mailbox-format=TYPE\tSelect mailbox TYPE\n"
"\t\t\t\tTYPE is `mbox', ");
fprintf (stdout, " or `none'\n\n"
"Mailbox type selection:\n\n"
" -m, --mailbox-format=TYPE\tSelect mailbox TYPE\n"
"\t\t\t\tTYPE is `mbox', ");
#ifdef HAVE_LIBZ
fprintf(stdout, "`zmbox', ");
fprintf (stdout, "`zmbox', ");
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
fprintf(stdout, "`bz2mbox', ");
fprintf (stdout, "`bz2mbox', ");
#endif /* HAVE_LIBBZ2 */
fprintf(stdout,
"`mh',\n"
"\t\t\t\t`nnml', `nnmh', or `maildir'.\n\n"
"Mail bug reports and flames to <%s>.\n", BUGREPORT_ADDR);
fprintf (stdout,
"`mh',\n"
"\t\t\t\t`nnml', `nnmh', or `maildir'.\n\n"
"Mail bug reports and flames to <%s>.\n", BUGREPORT_ADDR);
exit(0);
exit (0);
}
void
void
usage (void)
{
printf ("Usage: %s [OPTION] PATTERN MAILBOX ...\n\n"

View File

@ -18,9 +18,9 @@
*/
#ifndef INFO_H
#define INFO_H
# define INFO_H
void print_wrap (char *str, int len, int *n);
void print_wrap (char *str);
void version (void);
void help (void);
void usage (void);

View File

@ -23,20 +23,23 @@
#include <string.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
/* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
/* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif
/* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
#include <stdlib.h>
@ -52,7 +55,7 @@
#include "wrap.h"
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
# include <dmalloc.h>
#endif /* HAVE_LIBDMALLOC */
maildir_t *
@ -64,20 +67,20 @@ maildir_open (const char *path)
foo = m_opendir (path);
if (foo == NULL)
return NULL;
return NULL;
closedir (foo);
if (-1 == maildir_check (path))
{
if (config.merr)
fprintf (stderr, "%s: %s: Not a maildir folder\n", APPNAME, path);
fprintf (stderr, "%s: %s: Not a maildir folder\n", APPNAME, path);
return NULL;
}
dirname = (char *) xmalloc((sizeof (char) * (strlen (path) + 5)));
dirname = (char *) xmalloc ((sizeof (char) * (strlen (path) + 5)));
mp = (maildir_t *) xmalloc(sizeof (maildir_t));
mp = (maildir_t *) xmalloc (sizeof (maildir_t));
sprintf (dirname, "%s/new", path);
mp->new = m_opendir (dirname);
if (mp->new == NULL)
@ -108,14 +111,14 @@ maildir_open (const char *path)
free (dirname);
return mp;
} /* maildir_open */
} /* maildir_open */
message_t *
maildir_read_message (maildir_t *mdp)
maildir_read_message (maildir_t * mdp)
{
int isheaders = 1;
int have_from = 0, have_to = 0, have_message_id = 0, have_sender = 0,
have_date = 0;
have_date = 0;
static message_t *message;
static struct dirent *d_content;
char *filename, buffer[BUFSIZ];
@ -124,9 +127,9 @@ maildir_read_message (maildir_t *mdp)
message = allocate_message ();
for(;;)
for (;;)
{
if (mdp->new != NULL)
if (mdp->new != NULL)
{
d_content = readdir (mdp->new);
if (d_content == NULL)
@ -155,9 +158,10 @@ maildir_read_message (maildir_t *mdp)
if (d_content->d_name[0] == '.')
continue;
filename =
(char *) xmalloc ((sizeof (char)*((strlen (d_content->d_name))
+ (strlen (config.boxname)) + 6)));
filename =
(char *) xmalloc ((sizeof (char) * ((strlen (d_content->d_name))
+ (strlen (config.boxname)) +
6)));
/*
filename =
@ -173,7 +177,7 @@ maildir_read_message (maildir_t *mdp)
free (filename);
isheaders = 1;
fp = m_fopen(message->filename, "r");
fp = m_fopen (message->filename, "r");
if (fp == NULL)
continue;
@ -185,7 +189,7 @@ maildir_read_message (maildir_t *mdp)
{
isheaders = 0;
continue;
} /* if */
} /* if */
if (isheaders)
{
if (0 == strncasecmp ("From: ", buffer, 6))
@ -199,43 +203,45 @@ maildir_read_message (maildir_t *mdp)
if (0 == strncasecmp ("Message-ID: ", buffer, 12))
have_message_id = 1;
if (0 == strncasecmp ("Return-Path: ", buffer, 13))
message->from = parse_return_path(buffer);
message->from = parse_return_path (buffer);
message->headers =
(char *) xrealloc (message->headers,
((1 + s + message->hbytes) * sizeof (char)));
((1 + s +
message->hbytes) * sizeof (char)));
strcpy (message->headers + message->hbytes, buffer);
message->hbytes += s;
} /* if */
} /* if */
else
{
message->body =
(char *) xrealloc (message->body,
((1 + s + message->bbytes) * sizeof (char)));
((1 + s +
message->bbytes) * sizeof (char)));
strcpy (message->body + message->bbytes, buffer);
message->bbytes += s;
} /* else */
} /* while */
} /* else */
} /* while */
/* if (!have_from || !have_to || !have_message_id) */
if ((!have_from && !have_sender)|| !have_date)
if ((!have_from && !have_sender) || !have_date)
{
if (config.merr)
fprintf(stderr, "%s: %s: Not a RFC 2822 message\n",
APPNAME, message->filename);
fclose(fp);
fprintf (stderr, "%s: %s: Not a RFC 2822 message\n",
APPNAME, message->filename);
fclose (fp);
continue;
}
fclose(fp);
return message;
} /* for */
} /* maildir_read_message */
void
maildir_write_message (message_t *m, const char *path)
fclose (fp);
return message;
} /* for */
} /* maildir_read_message */
void
maildir_write_message (message_t * m, const char *path)
{
char bla[BUFSIZ], *s1, *s2;
int t;
@ -245,11 +251,11 @@ maildir_write_message (message_t *m, const char *path)
t = (int) time (NULL);
sprintf (bla, "%i.%i_%i.%s",
t, config.pid, runtime.maildir_count, config.hostname);
t, config.pid, runtime.maildir_count, config.hostname);
s1 = (char *) xmalloc ((strlen (path) + strlen (bla) + 6) * sizeof (char));
sprintf(s1, "%s/tmp/%s", path, bla);
sprintf (s1, "%s/tmp/%s", path, bla);
s2 = (char *) xmalloc ((strlen (path) + strlen (bla) + 6) * sizeof (char));
sprintf(s2, "%s/new/%s", path, bla);
sprintf (s2, "%s/new/%s", path, bla);
f1 = m_fopen (s1, "w");
fprintf (f1, "%s\n%s", m->headers, m->body);
@ -257,7 +263,7 @@ maildir_write_message (message_t *m, const char *path)
rename (s1, s2);
}
int
int
maildir_check (const char *path)
{
static struct stat fs;
@ -268,48 +274,54 @@ maildir_check (const char *path)
sprintf (s, "%s/cur", path);
i = stat (s, &fs);
if (-1 == i) return -1;
if (! S_ISDIR (fs.st_mode)) return -1;
if (-1 == i)
return -1;
if (!S_ISDIR (fs.st_mode))
return -1;
sprintf (s, "%s/new", path);
i = stat (s, &fs);
if (-1 == i) return -1;
if (! S_ISDIR (fs.st_mode)) return -1;
if (-1 == i)
return -1;
if (!S_ISDIR (fs.st_mode))
return -1;
sprintf(s, "%s/tmp", path);
sprintf (s, "%s/tmp", path);
i = stat (s, &fs);
if (-1 == i) return -1;
if (! S_ISDIR (fs.st_mode)) return -1;
if (-1 == i)
return -1;
if (!S_ISDIR (fs.st_mode))
return -1;
free (s);
return 0;
}
void
void
maildir_create (const char *path)
{
char *s;
int i;
s = (char *) xmalloc ((strlen (path) + 4) * sizeof(char));
s = (char *) xmalloc ((strlen (path) + 4) * sizeof (char));
errno = 0;
for (;;)
{
sprintf(s, "%s", path);
i = mkdir (s, S_IRWXU);
if (-1 == i)
break;
sprintf(s, "%s/new", path);
sprintf (s, "%s", path);
i = mkdir (s, S_IRWXU);
if (-1 == i)
break;
sprintf(s, "%s/cur", path);
sprintf (s, "%s/new", path);
i = mkdir (s, S_IRWXU);
if (-1 == i)
break;
sprintf(s, "%s/tmp", path);
sprintf (s, "%s/cur", path);
i = mkdir (s, S_IRWXU);
if (-1 == i)
break;
sprintf (s, "%s/tmp", path);
i = mkdir (s, S_IRWXU);
if (-1 == i)
break;
@ -321,7 +333,7 @@ maildir_create (const char *path)
{
if (config.merr)
{
fprintf(stderr, "%s:%s: ", APPNAME, s);
fprintf (stderr, "%s:%s: ", APPNAME, s);
perror (NULL);
}
}

View File

@ -18,28 +18,32 @@
*/
#ifndef MAILDIR_H
#define MAILDIR_H
# define MAILDIR_H
#include <config.h>
# include <config.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
# ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
# else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
/* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
/* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif
/* HAVE_NDIR_H */
# endif
/* HAVE_DIRENT_H */
#include "mboxgrep.h"
# include "mboxgrep.h"
typedef struct
{
@ -50,8 +54,8 @@ typedef struct
maildir_t *maildir_open (const char *path);
int maildir_check (const char *path);
void maildir_create (const char *path);
void maildir_close (maildir_t *mdp);
message_t *maildir_read_message (maildir_t *mdp);
void maildir_write_message (message_t *m, const char *path);
void maildir_close (maildir_t * mdp);
message_t *maildir_read_message (maildir_t * mdp);
void maildir_write_message (message_t * m, const char *path);
#endif /* MAILDIR_H */

View File

@ -1,6 +1,6 @@
/*
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
under the terms of the GNU General Public License as published by
@ -24,9 +24,8 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_LIBZ
#include <zlib.h>
# include <zlib.h>
#endif /* HAVE_LIBZ */
#include "getopt.h"
@ -36,11 +35,11 @@
#include "mbox.h"
#include "mh.h"
#include "scan.h"
#include "wrap.h" /* xcalloc() et cetera */
#include "wrap.h" /* xcalloc() et cetera */
#include "re.h"
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
# include <dmalloc.h>
#endif /* HAVE_LIBDMALLOC */
option_t config;
@ -54,68 +53,57 @@ main (int argc, char **argv)
runtime.count = 0;
runtime.maildir_count = 0;
static struct option long_options[] =
{
{"count", 0, 0, 'c'},
{"delete", 0, 0, 'd'},
/* {"date", 1, 0, 'D'}, */
{"extended-regexp", 0, 0, 'E'},
{"basic-regexp", 0, 0, 'G'},
{"perl-regexp", 0, 0, 'P'},
{"help", 0, 0, 'h'},
{"ignore-case", 0, 0, 'i'},
{"mailbox-format", 1, 0, 'm'},
{"no", 1, 0, 'n' },
{"pipe", 1, 0, 'p'},
{"regexp", 1, 0, 'e'},
{"invert-match", 0, 0, 'v'},
{"version", 0, 0, 'V'},
{"headers", 0, 0, 'H'},
{"body", 0, 0, 'B'},
{"no-messages", 0, 0, 's'},
{"output", 1, 0, 'o'},
{"no-duplicates", 0, 0, 200},
{"no-file-lock", 0, 0, 201},
{"debug", 0, 0, 202},
{"file-lock", 1, 0, 'l'},
{"recursive", 0, 0, 'r'},
{0, 0, 0, 0}
};
static struct option long_options[] = {
{"count", 0, 0, 'c'},
{"delete", 0, 0, 'd'},
/* {"date", 1, 0, 'D'}, */
{"extended-regexp", 0, 0, 'E'},
{"basic-regexp", 0, 0, 'G'},
{"perl-regexp", 0, 0, 'P'},
{"help", 0, 0, 'h'},
{"ignore-case", 0, 0, 'i'},
{"mailbox-format", 1, 0, 'm'},
{"no", 1, 0, 'n'},
{"pipe", 1, 0, 'p'},
{"regexp", 1, 0, 'e'},
{"invert-match", 0, 0, 'v'},
{"version", 0, 0, 'V'},
{"headers", 0, 0, 'H'},
{"body", 0, 0, 'B'},
{"no-messages", 0, 0, 's'},
{"output", 1, 0, 'o'},
{"no-duplicates", 0, 0, 200},
{"no-file-lock", 0, 0, 201},
{"debug", 0, 0, 202},
{"file-lock", 1, 0, 'l'},
{"recursive", 0, 0, 'r'},
{0, 0, 0, 0}
};
set_default_options ();
init_options ();
get_runtime_options (&argc, argv, long_options);
get_options (&argc, argv, long_options);
if ((config.body == 0) && (config.headers == 0))
{
config.body = 1;
config.headers = 1;
}
if (config.format == MAILDIR && config.action == WRITE)
{
gethostname (config.hostname, HOST_NAME_SIZE);
config.pid = (int) getpid ();
}
check_options ();
runtime.cs = (checksum_t *) xmalloc (sizeof (checksum_t));
runtime.cs->md5 = (char **) xcalloc (1, sizeof (char **));
runtime.cs->n = 0;
if (optind < argc && ! config.haveregex)
if (optind < argc && !config.haveregex)
{
config.regex_s = xstrdup (argv[optind]);
config.haveregex = 1;
++optind;
}
if (config.haveregex)
if (config.haveregex)
{
#ifdef HAVE_LIBPCRE
if (config.perl)
#ifdef HAVE_LIBPCRE2
if (config.regextype == REGEX_PERL)
pcre_init ();
else
#endif /* HAVE_LIBPCRE */
#endif /* HAVE_LIBPCRE2 */
regex_init ();
}
else
@ -126,10 +114,10 @@ main (int argc, char **argv)
while (optind < argc)
{
if (config.action == DELETE)
if (config.action == ACTION_DELETE)
{
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]);
@ -141,7 +129,7 @@ main (int argc, char **argv)
havemailbox = 1;
if (config.action == COUNT)
if (config.action == ACTION_COUNT)
{
if (singlefile)
fprintf (stdout, "%i\n", runtime.count);
@ -153,19 +141,20 @@ main (int argc, char **argv)
fprintf (stdout, "%s:%i\n", argv[optind], runtime.count);
}
}
if (config.action == DELETE)
if (config.action == ACTION_DELETE)
{
mbox_close (runtime.tmp_mbox);
rename (config.tmpfilename, argv[optind]);
}
++optind;
}
if (! havemailbox)
if (!havemailbox)
{
config.format = MBOX;
config.format = FORMAT_MBOX;
scan_mailbox ("-");
if (config.action == COUNT)
if (config.action == ACTION_COUNT)
fprintf (stdout, "%i\n", runtime.count);
}

View File

@ -1,6 +1,6 @@
/*
mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 Daniel Spiljar
Copyright (C) 2000 - 2004, 2006, 2023 - 2024 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@ -30,13 +30,13 @@
#include <errno.h>
#include <time.h>
#ifdef HAVE_FLOCK
#include <sys/file.h>
# include <sys/file.h>
#endif /* HAVE_FLOCK */
#ifdef HAVE_LIBZ
#include <zlib.h>
# include <zlib.h>
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
#include <bzlib.h>
# include <bzlib.h>
#endif /* HAVE_LIBBZ2 */
#define BUFLEN 16384
@ -46,183 +46,65 @@
#include "wrap.h"
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
# include <dmalloc.h>
#endif /* HAVE_LIBDMALLOC */
mbox_t *
mbox_open (const char *path, const char *mode)
mbox_open (const char *path, const mbox_mode_t mbox_mode)
{
mbox_t *mp;
static int fd;
#ifndef HAVE_FLOCK
struct flock lck;
#endif /* HAVE_FLOCK */
char buffer[BUFSIZ];
mp = (mbox_t *) xmalloc (sizeof (mbox_t));
mp->postmark_cache = (char *) xmalloc (BUFSIZ * sizeof (char));
mp->postmark_cache = NULL;
if (0 == strcmp ("-", path))
mp->fp = stdin;
else
{
if (mode[0] == 'r')
fd = m_open (path, O_RDONLY, 0);
else if (mode[0] == 'w')
if (mbox_mode == w)
fd = m_open (path, (O_WRONLY | O_CREAT | O_APPEND),
(S_IWUSR | S_IRUSR));
(S_IWUSR | S_IRUSR));
else
{
fprintf (stderr, "%s: mbox.c: Unknown mode %c. You shouldn't "
"get this error...", APPNAME, mode[0]);
exit (2);
}
fd = m_open (path, O_RDONLY, 0);
if (fd == -1)
{
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, path);
perror (NULL);
}
errno = 0;
return NULL;
}
if (config.lock)
{
#ifdef HAVE_FLOCK
int op;
if (mode[0] == '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 (config.lock > LOCK_NONE)
mbox_lock (fd, path, mbox_mode);
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 == MBOX)
mp->fp = (FILE *) m_fdopen (fd, "r");
#ifdef HAVE_LIBZ
else if (config.format == ZMBOX)
mp->fp = (gzFile *) m_gzdopen (fd, "rb");
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == BZ2MBOX)
mp->fp = (BZFILE *) BZ2_bzdopen (fd, "rb");
#endif /* HAVE_LIBBZ2 */
}
else if (mode[0] == 'w')
{
if (config.format == MBOX)
mp->fp = (FILE *) m_fdopen (fd, "w");
#ifdef HAVE_LIBZ
else if (config.format == ZMBOX)
mp->fp = (gzFile *) m_gzdopen (fd, "wb");
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.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;
}
mp->fp = mbox_fdopen (fd, path, mbox_mode);
}
if (mode[0] == 'r')
if (mbox_mode == r)
{
if (config.format == MBOX)
fgets (buffer, BUFSIZ, mp->fp);
#ifdef HAVE_LIBZ
else if (config.format == ZMBOX)
gzgets (mp->fp, buffer, BUFSIZ);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == BZ2MBOX)
{
char c[1] = "\0";
int n = 0;
mp->postmark_cache = mbox_check_postmark (mp, path);
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)
{
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 == MBOX)
fclose (mp->fp);
#ifdef HAVE_LIBZ
else if (config.format == ZMBOX)
gzclose (mp->fp);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == BZ2MBOX)
BZ2_bzclose (mp->fp);
#endif /* HAVE_LIBBZ2 */
return NULL;
}
strcpy (mp->postmark_cache, buffer);
if (! mp->postmark_cache)
return NULL;
}
return mp;
}
void
mbox_close (mbox_t * mp)
{
if (config.format == MBOX)
if (config.format == FORMAT_MBOX)
fclose (mp->fp);
#ifdef HAVE_LIBZ
else if (config.format == ZMBOX)
else if (config.format == FORMAT_ZMBOX)
gzclose (mp->fp);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == BZ2MBOX)
else if (config.format == FORMAT_BZ2MBOX)
BZ2_bzclose (mp->fp);
#endif /* HAVE_LIBBZ2 */
@ -248,7 +130,7 @@ mbox_read_message (mbox_t * mp)
for (;;)
{
if (config.format == MBOX)
if (config.format == FORMAT_MBOX)
{
if (fgets (buffer, BUFSIZ, mp->fp) == NULL)
{
@ -260,7 +142,7 @@ mbox_read_message (mbox_t * mp)
}
#ifdef HAVE_LIBZ
else if (config.format == ZMBOX)
else if (config.format == FORMAT_ZMBOX)
{
if (gzgets (mp->fp, buffer, BUFSIZ) == NULL)
{
@ -273,7 +155,7 @@ mbox_read_message (mbox_t * mp)
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == BZ2MBOX)
else if (config.format == FORMAT_BZ2MBOX)
{
char c[1] = "\0";
int n = 0;
@ -308,7 +190,7 @@ mbox_read_message (mbox_t * mp)
{
message->headers =
(char *) realloc (message->headers,
((1 + s + message->hbytes) * sizeof (char)));
((1 + s + message->hbytes) * sizeof (char)));
strcpy (message->headers + message->hbytes, buffer);
message->hbytes += s;
}
@ -321,7 +203,7 @@ mbox_read_message (mbox_t * mp)
}
message->body =
(char *) realloc (message->body,
((1 + s + message->bbytes) * sizeof (char)));
((1 + s + message->bbytes) * sizeof (char)));
strcpy (message->body + message->bbytes, buffer);
message->bbytes += s;
}
@ -346,7 +228,7 @@ tmpfile_name (const char *path)
{
char *fname, *tmpdir;
if (path == NULL) /* no path prefix given, use /tmp or TMPDIR */
if (path == NULL) /* no path prefix given, use /tmp or TMPDIR */
{
tmpdir = getenv ("TMPDIR");
if (tmpdir == NULL)
@ -361,26 +243,26 @@ tmpfile_name (const char *path)
config.tmpfilename =
(char *) xmalloc ((strlen (tmpdir) + (strlen (fname) + 1))
* sizeof (char));
* sizeof (char));
sprintf (config.tmpfilename, "%s%s", tmpdir, fname);
}
void
mbox_write_message (message_t *msg, mbox_t *mbox)
void
mbox_write_message (message_t * msg, mbox_t * mbox)
{
if (config.format == MBOX)
if (config.format == FORMAT_MBOX)
fprintf (mbox->fp, "%s\n%s", msg->headers, msg->body);
#ifdef HAVE_LIBZ
else if (config.format == ZMBOX)
else if (config.format == FORMAT_ZMBOX)
{
gzwrite_loop (mbox->fp, msg->headers);
gzwrite(mbox->fp, "\n", 1);
gzwrite (mbox->fp, "\n", 1);
gzwrite_loop (mbox->fp, msg->body);
}
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
else if (config.format == BZ2MBOX)
else if (config.format == FORMAT_BZ2MBOX)
{
bzwrite_loop (mbox->fp, msg->headers);
BZ2_bzwrite (mbox->fp, "\n", 1);
@ -402,11 +284,14 @@ tmpfile_mod_own (const int fd, const char *path)
if (stat (path, &s) != -1)
{
if (fchown (fd, s.st_uid, s.st_gid) == -1)
if (config.merr) perror (config.tmpfilename);
if (config.merr)
perror (config.tmpfilename);
if (fchmod (fd, s.st_mode) == -1)
if (config.merr) perror (config.tmpfilename);
if (config.merr)
perror (config.tmpfilename);
}
else if (config.merr) perror (path);
else if (config.merr)
perror (path);
}
}
@ -427,3 +312,127 @@ tmpfile_create (void)
}
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
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
under the terms of the GNU General Public License as published by
@ -18,11 +18,9 @@
*/
#ifndef MBOX_H
#define MBOX_H 1
#include <config.h>
#include "message.h"
# define MBOX_H 1
# include <config.h>
# include "message.h"
typedef struct
{
@ -31,14 +29,23 @@ typedef struct
char *postmark_cache;
} 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 tmpfile_name (const char *path);
void tmpfile_mod_own (const int fd, const char *path);
int tmpfile_create (void);
void mbox_close (mbox_t * mbp);
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 */

View File

@ -1,6 +1,6 @@
/*
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
under the terms of the GNU General Public License as published by
@ -15,15 +15,14 @@
You should have received a copy of the GNU General Public License
along with mboxgrep; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MBOXGREP_H
#define MBOXGREP_H
#define APPNAME "mboxgrep"
#define VERSION "0.7.10"
#define BUGREPORT_ADDR "dspiljar AT datatipp.se"
#define VERSION "0.7.13"
#define BUGREPORT_ADDR "dspiljar@datatipp.se"
#define HOST_NAME_SIZE 256
@ -47,34 +46,46 @@
typedef enum
{
MBOX,
ZMBOX,
MH,
NNML,
NNMH,
MAILDIR,
BZ2MBOX
FORMAT_UNDEF,
FORMAT_MBOX,
FORMAT_ZMBOX,
FORMAT_MH,
FORMAT_NNML,
FORMAT_NNMH,
FORMAT_MAILDIR,
FORMAT_BZ2MBOX
}
format_t;
typedef enum
{
NONE,
FCNTL,
FLOCK
LOCK_UNDEF,
LOCK_NONE,
LOCK_FCNTL,
LOCK_FLOCK
}
lockmethod_t;
typedef enum
{
DISPLAY,
WRITE,
COUNT,
DELETE,
PIPE
ACTION_UNDEF,
ACTION_DISPLAY,
ACTION_WRITE,
ACTION_COUNT,
ACTION_DELETE,
ACTION_PIPE
}
action_t;
typedef enum
{
REGEX_UNDEF,
REGEX_BASIC,
REGEX_EXTENDED,
REGEX_PERL
}
regextype_t;
typedef struct
{
FILE *fp;
@ -94,9 +105,6 @@ checksum_t;
typedef struct
{
int extended;
int perl;
int body;
int headers;
int dedup;
@ -112,12 +120,13 @@ typedef struct
char hostname[HOST_NAME_SIZE];
char *boxname, *outboxname, *pipecmd, *tmpfilename, *regex_s;
void *pcre_pattern, *pcre_hints, *posix_pattern;
void *pcre_pattern, *posix_pattern, *match_data;
int res1, res2;
action_t action;
format_t format;
lockmethod_t lock;
regextype_t regextype;
}
option_t;

View File

@ -18,14 +18,14 @@
*/
#ifndef MESSAGE_H
#define MESSAGE_H 1
# define MESSAGE_H 1
#include <config.h>
# include <config.h>
typedef struct
{
char *filename; /* used with directory formats, such as maildir or MH */
char *msgid;
char *filename; /* used with directory formats, such as maildir or MH */
char *msgid;
char *from;
char *headers;
int hbytes;

207
src/mh.c
View File

@ -1,6 +1,6 @@
/* -*- C -*-
mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000, 2001, 2002, 2003, 2006 Daniel Spiljar
Copyright (C) 2000, 2001, 2002, 2003, 2006, 2023 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@ -22,20 +22,23 @@
#include <string.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
/* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
/* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif
/* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
#include <sys/types.h>
@ -49,12 +52,13 @@
#include "wrap.h"
#ifdef HAVE_LIBDMALLOC
# include <dmalloc.h>
# include <dmalloc.h>
#endif /* HAVE_LIBDMALLOC */
extern option_t config;
DIR *mh_open (const char *path)
DIR *
mh_open (const char *path)
{
DIR *dp;
@ -62,22 +66,24 @@ DIR *mh_open (const char *path)
if (dp == NULL)
{
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, path);
perror (NULL);
}
{
fprintf (stderr, "%s: %s: ", APPNAME, path);
perror (NULL);
}
errno = 0;
return NULL;
}
return dp;
} /* mh_open */
} /* mh_open */
void mh_close (DIR *dp)
void
mh_close (DIR * dp)
{
closedir (dp);
} /* mh_close */
} /* mh_close */
message_t *mh_read_message (DIR *dp)
message_t *
mh_read_message (DIR * dp)
{
int isheaders = 1;
int have_from = 0, have_date = 0, have_sender = 0;
@ -91,16 +97,17 @@ message_t *mh_read_message (DIR *dp)
filename = NULL;
for(;;)
for (;;)
{
d_content = readdir(dp);
if (d_content == NULL) return NULL;
d_content = readdir (dp);
if (d_content == NULL)
return NULL;
if (d_content->d_name[0] == '.')
continue;
continue;
filename = (char *) xrealloc
(filename, ((strlen (d_content->d_name)) +
(strlen (config.boxname)) + 2));
filename = (char *) xrealloc
(filename, ((strlen (d_content->d_name)) +
(strlen (config.boxname)) + 2));
/* message->headers = (char *) xrealloc (message->headers, 0); */
/* message->hbytes = 0; */
@ -112,17 +119,17 @@ message_t *mh_read_message (DIR *dp)
fp = m_fopen (filename, "r");
isheaders = 1;
if (fp == NULL)
{
free (message->headers);
free (message->body);
message->hbytes = 0;
message->bbytes = 0;
continue;
}
{
free (message->headers);
free (message->body);
message->hbytes = 0;
message->bbytes = 0;
continue;
}
fgets (buffer, BUFSIZ, fp);
/* if (config.format == NNML || config.format == NNMH) */
/* if (config.format == FORMAT_NNML || config.format == FORMAT_NNMH) */
/* { */
/* if (0 != strncmp ("X-From-Line: ", buffer, 13)) */
/* { */
@ -137,76 +144,80 @@ message_t *mh_read_message (DIR *dp)
/* continue; */
/* } */
/* } */
fseek (fp, 0, SEEK_SET);
while (fgets (buffer, BUFSIZ, fp) != NULL)
{
s = strlen (buffer);
if (0 == strncmp ("\n", buffer, 1) && isheaders == 1)
{
isheaders = 0;
continue;
} /* if */
if (isheaders)
{
if (0 == strncasecmp ("From: ", buffer, 6))
have_from = 1;
if (0 == strncasecmp ("Sender: ", buffer, 8))
have_sender = 1;
if (0 == strncasecmp ("Date: ", buffer, 6))
have_date = 1;
if (0 == strncasecmp ("Return-Path: ", buffer, 13))
message->from = parse_return_path (buffer);
{
s = strlen (buffer);
if (0 == strncmp ("\n", buffer, 1) && isheaders == 1)
{
isheaders = 0;
continue;
} /* if */
if (isheaders)
{
if (0 == strncasecmp ("From: ", buffer, 6))
have_from = 1;
if (0 == strncasecmp ("Sender: ", buffer, 8))
have_sender = 1;
if (0 == strncasecmp ("Date: ", buffer, 6))
have_date = 1;
if (0 == strncasecmp ("Return-Path: ", buffer, 13))
message->from = parse_return_path (buffer);
message->headers =
(char *) realloc (message->headers,
((1 + s + message->hbytes) * sizeof (char)));
strcpy (message->headers + message->hbytes, buffer);
message->hbytes += s;
} /* if */
else
{
message->body =
(char *) realloc (message->body,
((1 + s + message->bbytes) * sizeof (char)));
strcpy (message->body + message->bbytes, buffer);
message->bbytes += s;
} /* else */
} /* while */
message->headers =
(char *) realloc (message->headers,
((1 + s +
message->hbytes) * sizeof (char)));
strcpy (message->headers + message->hbytes, buffer);
message->hbytes += s;
} /* if */
else
{
message->body =
(char *) realloc (message->body,
((1 + s +
message->bbytes) * sizeof (char)));
strcpy (message->body + message->bbytes, buffer);
message->bbytes += s;
} /* else */
} /* while */
if ((!have_from && !have_sender)|| !have_date)
{
if (config.merr)
fprintf (stderr, "%s: %s: Not a RFC 2822 message\n",
APPNAME, filename);
fclose (fp);
free (message->headers);
message->headers = NULL;
free (message->body);
message->body = NULL;
message->hbytes = 0;
message->bbytes = 0;
continue;
}
if ((!have_from && !have_sender) || !have_date)
{
if (config.merr)
fprintf (stderr, "%s: %s: Not a RFC 2822 message\n",
APPNAME, filename);
fclose (fp);
free (message->headers);
message->headers = NULL;
free (message->body);
message->body = NULL;
message->hbytes = 0;
message->bbytes = 0;
continue;
}
else
{
message->filename = (char *) xstrdup (filename);
fclose (fp);
free (filename);
{
message->filename = (char *) xstrdup (filename);
fclose (fp);
free (filename);
return message;
}
} /* for */
} /* mh_read_message */
return message;
}
} /* for */
} /* mh_read_message */
void mh_write_message (message_t *m, const char *path)
void
mh_write_message (message_t * m, const char *path)
{
struct dirent *dc;
int x, y = 0;
char s1[BUFSIZ];
DIR *d; FILE *f;
DIR *d;
FILE *f;
d = m_opendir (path);
rewinddir (d);
@ -215,11 +226,11 @@ void mh_write_message (message_t *m, const char *path)
{
x = strtol (dc->d_name, NULL, 10);
if (x > y)
y = x;
y = x;
}
y++;
sprintf (s1, "%s/%i", path, y);
f = m_fopen (s1, "w");
fprintf (f, "%s\n%s", m->headers, m->body);
fclose (f);

View File

@ -18,29 +18,33 @@
*/
#ifndef MH_H
#define MH_H 1
# define MH_H 1
#include <config.h>
# include <config.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#else
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
# ifdef HAVE_DIRENT_H
# include <dirent.h>
# else
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
/* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
/* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif
/* HAVE_NDIR_H */
# endif
/* HAVE_DIRENT_H */
#include "mboxgrep.h"
# include "mboxgrep.h"
DIR *mh_open (const char *path);
void mh_close (DIR *dp);
message_t *mh_read_message (DIR *dp);
void mh_write_message (message_t *m, const char *path);
void mh_close (DIR * dp);
message_t *mh_read_message (DIR * dp);
void mh_write_message (message_t * m, const char *path);
#endif /* MH_H */

View File

@ -17,9 +17,9 @@
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define _XOPEN_SOURCE /* Pull in strptime(3) from time.h */
#define _BSD_SOURCE /* Compensate for _XOPEN_SOURCE to pull in strdup(3)
* from string.h. */
#define _XOPEN_SOURCE /* Pull in strptime(3) from time.h */
#define _DEFAULT_SOURCE /* Compensate for _XOPEN_SOURCE to pull in strdup(3)
* from string.h. */
#include <config.h>
@ -28,72 +28,87 @@
#include <errno.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include "mboxgrep.h"
#include "misc.h"
#include "wrap.h"
#include "getopt.h"
#include "info.h"
#include "message.h"
format_t
folder_format (const char *name)
/* Determine the folder format passed to -m. */
void
set_folder_format (const char *name)
{
format_t f;
if (config.format > 0)
{
if (config.merr)
fprintf (stderr, "%s: multiple mailbox types specified\n", APPNAME);
exit (2);
}
if (0 == strncasecmp (name, "mbox", 4))
f = MBOX;
config.format = FORMAT_MBOX;
else if (0 == strncasecmp (name, "zmbox", 5))
f = ZMBOX;
config.format = FORMAT_ZMBOX;
else if (0 == strncasecmp (name, "gzmbox", 6))
f = ZMBOX;
config.format = FORMAT_ZMBOX;
else if (0 == strncasecmp (name, "bzmbox", 5))
f = BZ2MBOX;
config.format = FORMAT_BZ2MBOX;
else if (0 == strncasecmp (name, "bz2mbox", 5))
f = BZ2MBOX;
config.format = FORMAT_BZ2MBOX;
else if (0 == strncasecmp (name, "mh", 2))
f = MH;
config.format = FORMAT_MH;
else if (0 == strncasecmp (name, "nnml", 4))
f = NNML;
config.format = FORMAT_NNML;
else if (0 == strncasecmp (name, "nnmh", 4))
f = NNMH;
config.format = FORMAT_NNMH;
else if (0 == strncasecmp (name, "maildir", 7))
f = MAILDIR;
config.format = FORMAT_MAILDIR;
else
{
if (config.merr)
fprintf (stderr, "%s: %s: unknown folder type\n", APPNAME, name);
exit (2);
}
return f;
}
lockmethod_t lock_method (const char *name)
/* Determine the file locking method passed to -l. */
void
set_lock_method (const char *name)
{
lockmethod_t l;
if (config.lock > 0)
{
if (config.merr)
fprintf (stderr, "%s: conflicting file locking options specified\n", APPNAME);
exit (2);
}
if (0 == strncasecmp (name, "none", 4))
l = NONE;
config.lock = LOCK_NONE;
else if (0 == strncasecmp (name, "off", 3))
l = NONE;
config.lock = LOCK_NONE;
#ifdef HAVE_FCNTL
else if (0 == strncasecmp (name, "fcntl", 5))
l = FCNTL;
config.lock = LOCK_FCNTL;
#endif /* HAVE_FCNTL */
#ifdef HAVE_FLOCK
else if (0 == strncasecmp (name, "flock", 5))
l = FLOCK;
config.lock = LOCK_FLOCK;
#endif /* HAVE_FLOCK */
else
{
if (config.merr)
fprintf (stderr, "mboxgrep: %s: unknown file locking method\n", name);
fprintf (stderr, "mboxgrep: %s: unknown file locking method\n", name);
exit (2);
}
return l;
}
/* Dead code */
/*
time_t parse_date(char *datestr)
{
@ -122,17 +137,19 @@ time_t parse_date(char *datestr)
}
*/
char * parse_return_path(char *rpath)
char *
parse_return_path (char *rpath)
{
char *blah1, blah2[BUFSIZ];
sscanf(rpath, "Return-Path: <%[^\r\n>]>", blah2);
sscanf (rpath, "Return-Path: <%[^\r\n>]>", blah2);
blah1 = xstrdup (blah2);
return blah1;
}
void * allocate_message (void)
void *
allocate_message (void)
{
message_t *message;
@ -151,7 +168,8 @@ void * allocate_message (void)
return message;
}
void postmark_print (message_t *msg)
void
postmark_print (message_t * msg)
{
time_t tt;
struct tm *ct;
@ -166,133 +184,203 @@ void postmark_print (message_t *msg)
fprintf (stdout, "From nobody %s\n", date_str);
}
/* Initialize the option_t struct. */
void
set_default_options (void)
init_options (void)
{
config.perl = 0;
config.extended = 1;
config.regextype = REGEX_UNDEF;
config.invert = 0;
config.headers = 0;
config.body = 0;
config.action = DISPLAY;
config.action = ACTION_UNDEF;
config.dedup = 0;
config.recursive = 0;
config.ignorecase = 0;
config.format = MBOX; /* default mailbox format */
config.lock = FCNTL; /* default file locking method */
config.merr = 1; /* report errors by default */
config.format = FORMAT_UNDEF;
config.lock = LOCK_UNDEF; /* default file locking method */
config.merr = 1; /* report errors by default */
config.debug = 0;
}
/* Parse command-line arguments and assign values to option_t. */
void
get_runtime_options (int *argc, char **argv, struct option *long_options)
get_options (int *argc, char **argv, struct option *long_options)
{
int option_index = 0, c;
while (1)
{
c = getopt_long (*argc, argv, "BcdEe:GHhil:m:n:o:Pp:rsVv", long_options,
&option_index);
c = getopt_long (*argc, argv, "BcdEe:GHhil:m:n:o:Pp:rsVv", long_options,
&option_index);
if (c == -1)
break;
switch (c)
{
case '?':
usage();
case 'c':
config.action = COUNT;
break;
case 'd':
config.action = DELETE;
break;
case 'e':
config.regex_s = xstrdup (optarg);
config.haveregex = 1;
break;
case 'o':
config.outboxname = xstrdup (optarg);
config.action = WRITE;
break;
case 'E':
config.extended = 1;
break;
case 'G':
config.extended = 0;
break;
case 'P':
#ifdef HAVE_LIBPCRE
config.extended = 0;
config.perl = 1;
#else
fprintf(stderr,
"%s: Support for Perl regular expressions not "
"compiled in\n", APPNAME);
exit(2);
#endif /* HAVE_LIBPCRE */
break;
case 'h':
help ();
break;
case 'i':
config.ignorecase = 1;
break;
case 'm':
config.format = folder_format (optarg);
break;
case 'l':
config.lock = lock_method (optarg);
break;
case 'p':
config.action = PIPE;
config.pipecmd = xstrdup (optarg);
break;
case 'V':
version ();
break;
case 'v':
config.invert = 1;
break;
case 'H':
config.headers = 1;
break;
case 'B':
config.body = 1;
break;
case 's':
config.merr = 0;
break;
case 201:
config.lock = 0;
break;
case 202:
config.debug = 1;
fprintf (stderr, "%s: %s, line %d: enable debugging\n",
APPNAME, __FILE__, __LINE__);
break;
case 'r':
config.recursive = 1;
break;
case 200:
config.dedup = 1;
break;
case 'n':
{
switch (optarg[0])
{
case 'd':
config.dedup = 1;
break;
case 'l':
config.lock = 0;
break;
default:
fprintf(stderr, "%s: invalid option -- n%c\n",
APPNAME, optarg[0]);
exit(2);
}
}
} /* switch */
} /* while */
case '?':
usage ();
case 'c':
set_option_action (ACTION_COUNT, NULL);
break;
case 'd':
set_option_action (ACTION_DELETE, NULL);
break;
case 'e':
config.regex_s = xstrdup (optarg);
config.haveregex = 1;
break;
case 'o':
set_option_action (ACTION_WRITE, optarg);
break;
case 'E':
set_option_regextype (REGEX_EXTENDED);
break;
case 'G':
set_option_regextype (REGEX_BASIC);
break;
case 'P':
set_option_regextype (REGEX_PERL);
break;
case 'h':
help ();
break;
case 'i':
config.ignorecase = 1;
break;
case 'm':
set_folder_format (optarg);
break;
case 'l':
set_lock_method (optarg);
break;
case 'p':
set_option_action (ACTION_PIPE, optarg);
break;
case 'V':
version ();
break;
case 'v':
config.invert = 1;
break;
case 'H':
config.headers = 1;
break;
case 'B':
config.body = 1;
break;
case 's':
config.merr = 0;
break;
case 201:
config.lock = 0;
break;
case 202:
config.debug = 1;
fprintf (stderr, "%s: %s, line %d: enable debugging\n",
APPNAME, __FILE__, __LINE__);
break;
case 'r':
config.recursive = 1;
break;
case 200:
config.dedup = 1;
break;
case 'n':
{
switch (optarg[0])
{
case 'd':
config.dedup = 1;
break;
case 'l':
set_lock_method ("none");
break;
default:
fprintf (stderr, "%s: invalid option -- n%c\n",
APPNAME, optarg[0]);
exit (2);
}
}
} /* switch */
} /* while */
}
/* Check the state of command-line options after parsing them.
* Raise error on conflicting options and set uninitialized ones to default values.
*/
void
check_options (void)
{
gethostname (config.hostname, HOST_NAME_SIZE);
config.pid = (int) getpid ();
if (config.action == ACTION_UNDEF)
{
config.action = ACTION_DISPLAY;
}
if (config.format == FORMAT_UNDEF)
{
config.format = FORMAT_MBOX; /* default mailbox format */
}
if (config.regextype == REGEX_UNDEF)
{
config.regextype = REGEX_EXTENDED; /* default regex type */
}
if ((config.body == 0) && (config.headers == 0))
{
config.body = 1;
config.headers = 1;
}
}
void
set_option_action (action_t action, char *path)
{
if (config.action > 0)
{
if (config.merr)
fprintf (stderr, "%s: conflicting actions specified\n", APPNAME);
exit (2);
}
config.action = action;
if (action == ACTION_WRITE)
{
config.outboxname = xstrdup (path);
}
if (action == ACTION_PIPE)
{
config.pipecmd = xstrdup (optarg);
}
}
void
set_option_regextype (regextype_t regextype)
{
if (config.regextype > 0)
{
if (config.merr)
fprintf (stderr, "%s: conflicting matchers specified\n", APPNAME);
exit (2);
}
#ifndef HAVE_LIBPCRE2
if (regextype == REGEX_PERL);
{
fprintf (stderr,
"%s: Support for Perl regular expressions not compiled in\n",
APPNAME);
exit (2);
}
#endif /* HAVE_LIBPCRE2 */
config.regextype = regextype;
}

View File

@ -18,20 +18,24 @@
*/
#ifndef MISC_H
#define MISC_H 1
# define MISC_H 1
#include "mboxgrep.h"
#include "getopt.h"
#include "message.h"
# include "mboxgrep.h"
# include "getopt.h"
# include "message.h"
/* #include <time.h> */
format_t folder_format (const char *name);
lockmethod_t lock_method (const char *name);
void set_folder_format (const char *name);
void set_lock_method (const char *name);
/* time_t parse_date(char *datestr); */
char * parse_return_path(char *rpath);
void * allocate_message (void);
void postmark_print (message_t *msg);
void set_default_options (void);
void get_runtime_options (int *argc, char **argv, struct option *long_options);
char *parse_return_path (char *rpath);
void *allocate_message (void);
void postmark_print (message_t * msg);
void init_options (void);
void get_options (int *argc, char **argv,
struct option *long_options);
void check_options (void);
void set_option_action (action_t action, char *path);
void set_option_regextype (regextype_t regextype);
#endif /* MISC_H */

View File

@ -21,55 +21,58 @@
#include <stdio.h>
#include <string.h>
#include <regex.h>
#ifdef HAVE_LIBPCRE
#include <pcre.h>
#endif /* HAVE_LIBPCRE */
#ifdef HAVE_LIBPCRE2
# define PCRE2_CODE_UNIT_WIDTH 32
# include <pcre2.h>
#endif /* HAVE_LIBPCRE2 */
#include "mboxgrep.h"
#include "message.h"
#include "wrap.h" /* xcalloc() et cetera */
#include "wrap.h" /* xcalloc() et cetera */
#ifdef HAVE_LIBPCRE
#ifdef HAVE_LIBPCRE2
void
pcre_init (void)
{
int errptr;
const char *error;
int errornumber;
PCRE2_SIZE erroroffset;
config.pcre_pattern =
(pcre *) pcre_compile (config.regex_s,
(config.ignorecase ? PCRE_CASELESS : 0),
&error, &errptr, NULL);
(pcre2_code *) pcre2_compile ((PCRE2_SPTR) config.regex_s, (PCRE2_SIZE) strlen (config.regex_s),
(config.ignorecase ? PCRE2_CASELESS : 0),
&errornumber, &erroroffset, NULL);
if (config.pcre_pattern == NULL)
{
if (config.merr)
fprintf (stderr, "%s: %s: %s\n", APPNAME, config.regex_s,
error);
exit(2);
{
PCRE2_UCHAR buffer[256];
pcre2_get_error_message (errornumber, buffer, sizeof(buffer));
fprintf (stderr, "%s: PCRE2 compilation failed at offset %d: %s\n",
APPNAME, (int) erroroffset, (char *) buffer);
}
exit (2);
}
config.match_data =
(pcre2_match_data* ) pcre2_match_data_create_from_pattern (config.pcre_pattern, NULL);
}
void
pcre_match (message_t *msg)
pcre_match (message_t * msg)
{
int of[BUFSIZ];
if (config.headers)
config.res1 =
pcre_exec ((pcre *) config.pcre_pattern,
(pcre_extra *) config.pcre_hints,
msg->headers,
(int) strlen (msg->headers), 0, 0, of, BUFSIZ);
pcre2_match ((pcre2_code *) config.pcre_pattern,
(PCRE2_SPTR) msg->headers, (int) strlen (msg->headers), 0, 0, config.match_data, NULL);
if (config.body)
config.res2 =
pcre_exec ((pcre *) config.pcre_pattern,
(pcre_extra *) config.pcre_hints,
msg->body,
(int) strlen (msg->body), 0, 0, of, BUFSIZ);
pcre2_match ((pcre2_code *) config.pcre_pattern,
(PCRE2_SPTR) msg->body, (int) strlen (msg->body), 0, 0, config.match_data, NULL);
config.res1 = config.res1 ^ 1;
config.res2 = config.res2 ^ 1;
}
#endif /* HAVE_LIBPCRE */
#endif /* HAVE_LIBPCRE2 */
void
regex_init (void)
@ -77,20 +80,21 @@ regex_init (void)
int flag1 = 0, flag2 = 0;
int errcode = 0;
char errbuf[BUFSIZ];
if (config.ignorecase)
flag1 = REG_ICASE;
if (config.extended)
if (config.regextype == REGEX_EXTENDED)
flag2 = REG_EXTENDED;
config.posix_pattern = (regex_t *) xmalloc (sizeof (regex_t));
errcode = regcomp ((regex_t *) config.posix_pattern, config.regex_s,
(flag1 | flag2 | REG_NEWLINE ));
errcode = regcomp ((regex_t *) config.posix_pattern, config.regex_s,
(flag1 | flag2 | REG_NEWLINE));
if (0 != errcode)
{
if (config.merr)
{
regerror (errcode, (regex_t *) config.posix_pattern, errbuf, BUFSIZ);
regerror (errcode, (regex_t *) config.posix_pattern, errbuf,
BUFSIZ);
fprintf (stderr, "%s: %s: %s\n", APPNAME, config.regex_s, errbuf);
}
exit (2);
@ -98,12 +102,12 @@ regex_init (void)
}
void
regex_match (message_t *msg)
regex_match (message_t * msg)
{
if (config.headers)
config.res1 = regexec ((regex_t *) config.posix_pattern,
msg->headers, 0, NULL, 0);
msg->headers, 0, NULL, 0);
if (config.body)
config.res2 = regexec ((regex_t *) config.posix_pattern,
msg->body, 0, NULL, 0);
msg->body, 0, NULL, 0);
}

View File

@ -19,9 +19,9 @@
#include "mboxgrep.h"
#ifdef HAVE_LIBPCRE
#ifdef HAVE_LIBPCRE2
void pcre_init (void);
void pcre_match (message_t *msg);
#endif /* HAVE_LIBPCRE */
void pcre_match (message_t * msg);
#endif /* HAVE_LIBPCRE2 */
void regex_init (void);
void regex_match (message_t *msg);
void regex_match (message_t * msg);

View File

@ -1,6 +1,6 @@
/* -*- C -*-
/*
mboxgrep - scan mailbox for messages matching a regular expression
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2006 Daniel Spiljar
Copyright (C) 2000 - 2004, 2006, 2023 - 2024 Daniel Spiljar
Mboxgrep is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
@ -15,8 +15,7 @@
You should have received a copy of the GNU General Public License
along with mboxgrep; if not, write to the Free Software Foundation,
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
$Id: scan.c,v 1.32 2006-10-22 23:34:49 dspiljar Exp $ */
*/
#include <config.h>
@ -26,20 +25,23 @@
#include <sys/types.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
/* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
/* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif
/* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
#include <time.h>
@ -57,20 +59,21 @@
#include "misc.h"
#include "re.h"
#ifdef HAVE_FTS_OPEN
# include <sys/stat.h>
# include <fts.h>
# include <sys/stat.h>
# include <fts.h>
#else
# ifdef HAVE_FTW
# include <ftw.h>
# endif /* HAVE_FTW */
# ifdef HAVE_FTW
# include <ftw.h>
# endif
/* HAVE_FTW */
#endif /* HAVE_FTS_OPEN */
#ifdef HAVE_LIBDMALLOC
#include <dmalloc.h>
# include <dmalloc.h>
#endif /* HAVE_LIBDMALLOC */
void scan_mailbox (char path[])
/* {{{ */
void
scan_mailbox (char path[])
{
static FILE *outf;
static mbox_t *mbox, *out;
@ -80,42 +83,47 @@ void scan_mailbox (char path[])
int delete = 0;
int isdup = 0;
if (config.format == MAILDIR && config.action == WRITE)
if (config.format == FORMAT_MAILDIR && config.action == ACTION_WRITE)
{
foo = opendir (config.outboxname); /* do NOT change this to m_opendir! */
foo = opendir (config.outboxname); /* do NOT change this to m_opendir! */
if (foo == NULL && errno == ENOENT)
maildir_create (config.outboxname);
else closedir (foo);
maildir_create (config.outboxname);
else
closedir (foo);
if (-1 == maildir_check (config.outboxname))
{
if (config.merr)
fprintf (stderr, "%s: %s: Not a maildir folder\n", APPNAME,
config.outboxname);
exit (2);
}
{
if (config.merr)
fprintf (stderr, "%s: %s: Not a maildir folder\n", APPNAME,
config.outboxname);
exit (2);
}
}
runtime.count = 0;
if (config.action == DELETE)
if (config.action == ACTION_DELETE)
delete = 1;
if ((config.format == MBOX) || (config.format == ZMBOX) ||
(config.format == BZ2MBOX))
if ((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX)
|| (config.format == FORMAT_BZ2MBOX))
{
mbox = (mbox_t *) mbox_open (path, "r");
if (mbox == NULL) return;
mbox = (mbox_t *) mbox_open (path, r);
if (mbox == NULL)
return;
}
else if ((config.format == MH) || (config.format == NNMH) ||
(config.format == NNML))
else if ((config.format == FORMAT_MH) || (config.format == FORMAT_NNMH)
|| (config.format == FORMAT_NNML))
{
boxd = mh_open (path);
if (boxd == NULL) return;
if (boxd == NULL)
return;
}
else if (config.format == MAILDIR)
else if (config.format == FORMAT_MAILDIR)
{
maildird = maildir_open (path);
if (maildird == NULL) return;
if (maildird == NULL)
return;
}
for (;;)
@ -123,102 +131,105 @@ void scan_mailbox (char path[])
config.res1 = 1;
config.res2 = 1;
if ((config.format == MBOX) || (config.format == ZMBOX) ||
(config.format == BZ2MBOX))
msg = (message_t *) mbox_read_message (mbox);
else if ((config.format == MH) || (config.format == NNMH) ||
(config.format == NNML))
msg = (message_t *) mh_read_message (boxd);
else if (config.format == MAILDIR)
msg = (message_t *) maildir_read_message (maildird);
if ((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX)
|| (config.format == FORMAT_BZ2MBOX))
msg = (message_t *) mbox_read_message (mbox);
else if ((config.format == FORMAT_MH) || (config.format == FORMAT_NNMH)
|| (config.format == FORMAT_NNML))
msg = (message_t *) mh_read_message (boxd);
else if (config.format == FORMAT_MAILDIR)
msg = (message_t *) maildir_read_message (maildird);
if (msg == NULL) break;
if (msg == NULL)
break;
if (msg->from == NULL) msg->from = (char *) xstrdup ("nobody");
if (msg->from == NULL)
msg->from = (char *) xstrdup ("nobody");
#ifdef HAVE_LIBPCRE
if (config.perl)
pcre_match (msg);
#ifdef HAVE_LIBPCRE2
if (config.regextype == REGEX_PERL)
pcre_match (msg);
else
#endif /* HAVE_LIBPCRE */
regex_match (msg);
#endif /* HAVE_LIBPCRE2 */
regex_match (msg);
if (config.dedup)
isdup = md5_check_message (msg->body, runtime.cs);
isdup = md5_check_message (msg->body, runtime.cs);
if (((config.res1 == 0) | (config.res2 == 0)) ^
((config.invert ^ delete)) &&
((config.dedup && !isdup) || !config.dedup))
{
if (config.action == DISPLAY)
{
if (config.format != MBOX && config.format != ZMBOX
&& config.format != BZ2MBOX
&& 0 != strncmp ("From ", msg->headers, 5))
postmark_print (msg);
fprintf (stdout, "%s\n%s", msg->headers, msg->body);
}
else if (config.action == WRITE)
{
if (config.format == MAILDIR)
maildir_write_message (msg, config.outboxname);
else if (config.format == MH || config.format == NNMH ||
config.format == NNML)
mh_write_message (msg, config.outboxname);
else if ((config.format == MBOX) || (config.format == ZMBOX) ||
(config.format == BZ2MBOX))
{
out = mbox_open (config.outboxname, "w");
/* fprintf (out->fp, "%s\n%s", msg->headers, msg->body); */
mbox_write_message (msg, out);
mbox_close (out);
}
}
else if (config.action == PIPE)
{
outf = popen (config.pipecmd, "w");
if (outf == NULL)
{
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, config.pipecmd);
perror (NULL);
}
exit (2);
} /* if */
fprintf (outf, "%s\n%s", msg->headers, msg->body);
pclose (outf);
}
else if (config.action == COUNT)
runtime.count++;
else if (config.action == DELETE &&
((config.format == MBOX) || (config.format == ZMBOX) ||
(config.format == BZ2MBOX)))
mbox_write_message (msg, runtime.tmp_mbox);
}
((config.invert ^ delete)) &&
((config.dedup && !isdup) || !config.dedup))
{
if (config.action == ACTION_DISPLAY)
{
if (config.format != FORMAT_MBOX && config.format != FORMAT_ZMBOX
&& config.format != FORMAT_BZ2MBOX
&& 0 != strncmp ("From ", msg->headers, 5))
postmark_print (msg);
else if (((((config.res1 == 0) | (config.res2 == 0)) ^
config.invert) && delete) &&
((config.format == MH) || (config.format == NNMH) ||
(config.format == NNML) || (config.format == MAILDIR)))
m_unlink(msg->filename);
fprintf (stdout, "%s\n%s", msg->headers, msg->body);
}
else if (config.action == ACTION_WRITE)
{
if (config.format == FORMAT_MAILDIR)
maildir_write_message (msg, config.outboxname);
else if (config.format == FORMAT_MH || config.format == FORMAT_NNMH
|| config.format == FORMAT_NNML)
mh_write_message (msg, config.outboxname);
else if ((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX)
|| (config.format == FORMAT_BZ2MBOX))
{
out = mbox_open (config.outboxname, w);
/* fprintf (out->fp, "%s\n%s", msg->headers, msg->body); */
mbox_write_message (msg, out);
mbox_close (out);
}
}
else if (config.action == ACTION_PIPE)
{
outf = popen (config.pipecmd, "w");
if (outf == NULL)
{
if (config.merr)
{
fprintf (stderr, "%s: %s: ", APPNAME, config.pipecmd);
perror (NULL);
}
exit (2);
} /* if */
fprintf (outf, "%s\n%s", msg->headers, msg->body);
pclose (outf);
}
else if (config.action == ACTION_COUNT)
runtime.count++;
else if (config.action == ACTION_DELETE &&
((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX)
|| (config.format == FORMAT_BZ2MBOX)))
mbox_write_message (msg, runtime.tmp_mbox);
}
free(msg->body);
free(msg->headers);
free(msg);
} /* for */
if ((config.format == MBOX) || (config.format == ZMBOX) ||
(config.format == BZ2MBOX))
else
if (((((config.res1 == 0) | (config.res2 == 0)) ^ config.invert)
&& delete) && ((config.format == FORMAT_MH) || (config.format == FORMAT_NNMH)
|| (config.format == FORMAT_NNML)
|| (config.format == FORMAT_MAILDIR)))
m_unlink (msg->filename);
free (msg->body);
free (msg->headers);
free (msg);
} /* for */
if ((config.format == FORMAT_MBOX) || (config.format == FORMAT_ZMBOX)
|| (config.format == FORMAT_BZ2MBOX))
mbox_close (mbox);
else if ((config.format == MH) || (config.format == NNMH) ||
(config.format == NNML))
mh_close(boxd);
else if ((config.format == FORMAT_MH) || (config.format == FORMAT_NNMH)
|| (config.format == FORMAT_NNML))
mh_close (boxd);
}
/* }}} */
void recursive_scan (char path[])
/* {{{ */
void
recursive_scan (char path[])
{
#ifdef HAVE_FTS_OPEN
FTS *ftsfoo;
@ -236,9 +247,9 @@ void recursive_scan (char path[])
if (ftsfoo == NULL)
{
/* fixme (?) */
perror(APPNAME);
exit (2);
/* fixme (?) */
perror (APPNAME);
exit (2);
}
while ((ftsbar = fts_read (ftsfoo)))
@ -251,34 +262,34 @@ void recursive_scan (char path[])
#endif /* HAVE_FTS_OPEN */
}
/* }}} */
int md5_check_message (char *body, checksum_t *chksum)
/* {{{ */
int
md5_check_message (char *body, checksum_t * chksum)
{
struct md5_ctx a;
char b[16];
int i;
md5_init_ctx (&a);
if (body == NULL)
md5_process_bytes ("", 0, &a);
else
md5_process_bytes (body, strlen(body), &a);
md5_finish_ctx(&a, b);
md5_process_bytes (body, strlen (body), &a);
md5_finish_ctx (&a, b);
for (i = 0; i < chksum->n; i++)
{
if (0 == strncmp ((char *)chksum->md5[i], b, 16))
return 1;
if (0 == strncmp ((char *) chksum->md5[i], b, 16))
return 1;
}
chksum->md5 =
(char **) xrealloc (chksum->md5, (1 + chksum->n) * sizeof (char *));
chksum->md5 =
(char **) xrealloc (chksum->md5, (1 + chksum->n) * sizeof (char *));
chksum->md5[chksum->n] = xstrdup (b);
(chksum->n)++;
return 0;
}
/* }}} */

View File

@ -18,12 +18,12 @@
*/
#ifndef SCAN_H
#define SCAN_H 1
# define SCAN_H 1
#include "mboxgrep.h"
# include "mboxgrep.h"
void scan_mailbox (char path[]);
void recursive_scan (char path[]);
int md5_check_message (char *body, checksum_t *chksum);
int md5_check_message (char *body, checksum_t * chksum);
#endif /* SCAN_H */

View File

@ -24,26 +24,29 @@
#include <errno.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
/* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
/* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif
/* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
#ifdef HAVE_LIBZ
#include <zlib.h>
# include <zlib.h>
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
#include <bzlib.h>
# include <bzlib.h>
#endif /* HAVE_LIBBZ2 */
#include <sys/types.h>
@ -54,12 +57,13 @@
#include "mboxgrep.h"
#ifndef APPNAME
#define APPNAME "mboxgrep"
# define APPNAME "mboxgrep"
#endif
#define BUFLEN 16384
int m_open (const char *pathname, int flags, mode_t mode)
int
m_open (const char *pathname, int flags, mode_t mode)
{
int blah;
@ -76,9 +80,10 @@ int m_open (const char *pathname, int flags, mode_t mode)
exit (2);
}
return blah;
}
}
FILE *m_fopen (const char *path, const char *mode)
FILE *
m_fopen (const char *path, const char *mode)
{
FILE *blah;
@ -96,7 +101,8 @@ FILE *m_fopen (const char *path, const char *mode)
return blah;
}
FILE *m_fdopen (int fildes, const char *mode)
FILE *
m_fdopen (int fildes, const char *mode)
{
FILE *blah;
@ -111,7 +117,8 @@ FILE *m_fdopen (int fildes, const char *mode)
#ifdef HAVE_LIBZ
gzFile m_gzdopen (int fildes, const char *mode)
gzFile
m_gzdopen (int fildes, const char *mode)
{
gzFile blah;
@ -126,7 +133,8 @@ gzFile m_gzdopen (int fildes, const char *mode)
#endif /* HAVE_LIBZ */
DIR *m_opendir (const char *name)
DIR *
m_opendir (const char *name)
{
DIR *blah;
@ -144,7 +152,8 @@ DIR *m_opendir (const char *name)
#ifndef HAVE_LIBDMALLOC
void *xmalloc (size_t size)
void *
xmalloc (size_t size)
{
void *foo;
@ -158,7 +167,8 @@ void *xmalloc (size_t size)
return foo;
}
void *xrealloc (void *ptr, size_t size)
void *
xrealloc (void *ptr, size_t size)
{
void *foo;
@ -172,7 +182,8 @@ void *xrealloc (void *ptr, size_t size)
return foo;
}
void *xcalloc (size_t nmemb, size_t size)
void *
xcalloc (size_t nmemb, size_t size)
{
void *foo;
@ -186,7 +197,8 @@ void *xcalloc (size_t nmemb, size_t size)
return foo;
}
char *xstrdup (const char *s)
char *
xstrdup (const char *s)
{
char *foo;
@ -202,7 +214,8 @@ char *xstrdup (const char *s)
#endif /* HAVE_LIBDMALLOC */
int m_unlink (const char *pathname)
int
m_unlink (const char *pathname)
{
int baz;
@ -220,7 +233,8 @@ int m_unlink (const char *pathname)
#ifdef HAVE_LIBZ
void gzwrite_loop (void *fp, char *str)
void
gzwrite_loop (void *fp, char *str)
{
int quux, len, baz;
@ -228,8 +242,8 @@ void gzwrite_loop (void *fp, char *str)
baz = strlen (str);
for (;;)
{
len = gzwrite (fp, (str+quux),
(((quux + BUFLEN) < baz) ? BUFLEN : (baz - quux)));
len = gzwrite (fp, (str + quux),
(((quux + BUFLEN) < baz) ? BUFLEN : (baz - quux)));
quux += len;
if (quux == baz)
break;
@ -240,7 +254,8 @@ void gzwrite_loop (void *fp, char *str)
#ifdef HAVE_LIBBZ2
void bzwrite_loop (void *fp, char *str)
void
bzwrite_loop (void *fp, char *str)
{
int quux, len, baz;
@ -248,8 +263,8 @@ void bzwrite_loop (void *fp, char *str)
baz = strlen (str);
for (;;)
{
len = BZ2_bzwrite (fp, (str+quux),
(((quux + BUFLEN) < baz) ? BUFLEN : (baz - quux)));
len = BZ2_bzwrite (fp, (str + quux),
(((quux + BUFLEN) < baz) ? BUFLEN : (baz - quux)));
quux += len;
if (quux == baz)
break;

View File

@ -22,55 +22,64 @@
/* wrappers around certain std functions */
#ifndef WRAP_H
#define WRAP_H
# define WRAP_H
#include <config.h>
#include <stdio.h>
#include <sys/types.h>
# include <config.h>
# include <stdio.h>
# include <sys/types.h>
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#else
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif /* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif /* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif /* HAVE_NDIR_H */
#endif /* HAVE_DIRENT_H */
#ifdef HAVE_LIBZ
#include <zlib.h>
#endif /* HAVE_LIBZ */
# ifdef HAVE_DIRENT_H
# include <dirent.h>
# else
# ifdef HAVE_SYS_NDIR_H
# include <sys/ndir.h>
# endif
/* HAVE_SYS_NDIR_H */
# ifdef HAVE_SYS_DIR_H
# include <sys/dir.h>
# endif
/* HAVE_SYS_DIR_H */
# ifdef HAVE_NDIR_H
# include <ndir.h>
# endif
/* HAVE_NDIR_H */
# endif
/* HAVE_DIRENT_H */
# ifdef HAVE_LIBZ
# include <zlib.h>
# endif
/* HAVE_LIBZ */
#include <stdlib.h>
# include <stdlib.h>
#ifdef HAVE_LIBDMALLOC
# include <dmalloc.h>
#endif /* HAVE_LIBDMALLOC */
# ifdef HAVE_LIBDMALLOC
# include <dmalloc.h>
# endif
/* HAVE_LIBDMALLOC */
int m_open (const char *pathname, int flags, mode_t mode);
FILE *m_fopen (const char *path, const char *mode);
FILE *m_fdopen (int fildes, const char *mode);
#ifdef HAVE_LIBZ
# ifdef HAVE_LIBZ
gzFile m_gzdopen (int fildes, const char *mode);
void gzwrite_loop (void *fp, char *str);
#endif /* HAVE_LIBZ */
#ifdef HAVE_LIBBZ2
# endif
/* HAVE_LIBZ */
# ifdef HAVE_LIBBZ2
void bzwrite_loop (void *fp, char *str);
#endif /* HAVE_LIBBZ2 */
# endif
/* HAVE_LIBBZ2 */
DIR *m_opendir (const char *name);
#ifndef HAVE_LIBDMALLOC
# ifndef HAVE_LIBDMALLOC
void *xmalloc (size_t size);
void *xrealloc (void *ptr, size_t size);
void *xcalloc (size_t nmemb, size_t size);
char *xstrdup (const char *s);
#endif /* HAVE_LIBDMALLOC */
# endif
/* HAVE_LIBDMALLOC */
int m_unlink (const char *pathname);