[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Nmh-workers] some indexing results
From: |
Paul Vixie |
Subject: |
Re: [Nmh-workers] some indexing results |
Date: |
Tue, 15 Feb 2011 21:37:47 +0000 |
> From: Ken Hornstein <address@hidden>
> Date: Tue, 15 Feb 2011 15:57:55 -0500
>
> Well, I'm not sure that would help _me_ all that much, since ~ is all on
> the same network filesystem. But then (assuming that it works) I would
> probably want the databases network-filesystem accessable. So I think
> what you have would work fine for me.
if you'd like to give it a try, here's a snapshot. you'll want to uncomment
MHDB_HEADERS in the Makefile, and as to how you build NMH 1.3 with the diff
applied that's up to you. my ~/.mh_profile contains the following lines:
add-hook: /home/vixie/src/mhdb/mhdb-add
del-hook: /home/vixie/src/mhdb/mhdb-del
ref-hook: /home/vixie/src/mhdb/mhdb-ref
note that i have not yet altered mhdb_store_hdr() to include the first few
lines of the body, so the modified "scan" does not show the first few words
of the message. also, this snapshot still depends on the non-standard C
library function fropen() which to the best of my knowledge make it FreeBSD
specific. if you get that far, you'll need to run mhdb-buildall.sh one time
to get things started, and after that NMH will keep everything in sync via
the hook interface.
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# Makefile
# mhdb-add.c
# mhdb-build.sh
# mhdb-buildall.sh
# mhdb-del.c
# mhdb-dump.c
# mhdb-ref.c
# mhdb.c
# mhdb.h
# mhdb_pvt.h
# nmh-1.3.diffs
#
echo x - Makefile
sed 's/^X//' >Makefile << 'b67911656ef5d18c4ae36cb6741b7965'
XALL = mhdb-add mhdb-del mhdb-ref mhdb-dump
X
XDEFS = -DDBM_HEADER='<ndbm.h>'
X# -DMHDB_HEADERS
XOPT = -g
XCFLAGS = -Wall ${DEFS} ${OPT}
X
Xall: ${ALL}
X
Xclean:
X rm -f *.o
X rm -f ${ALL}
X
Xmhdb-add: mhdb-add.o mhdb.o
X ${CC} -o $@ $>
Xmhdb-del: mhdb-del.o mhdb.o
X ${CC} -o $@ $>
Xmhdb-ref: mhdb-ref.o mhdb.o
X ${CC} -o $@ $>
Xmhdb-dump: mhdb-dump.o mhdb.o
X ${CC} -o $@ $>
X
Xmhdb.o: mhdb.c mhdb.h mhdb_pvt.h Makefile
Xmhdb-add.o: mhdb-add.c mhdb.h Makefile
Xmhdb-del.o: mhdb-del.c mhdb.h Makefile
Xmhdb-ref.o: mhdb-ref.c mhdb.h Makefile
Xmhdb-dump.o: mhdb-dump.c mhdb.h mhdb_pvt.h Makefile
b67911656ef5d18c4ae36cb6741b7965
echo x - mhdb-add.c
sed 's/^X//' >mhdb-add.c << 'bad38879bcc2b0eecb693d699b4bb7f3'
X#include <sys/param.h>
X
X#include <assert.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X
X#include "mhdb.h"
X
Xstatic mhdb_t d;
Xstatic char *p;
X
Xstatic void mhdb_add(const char *mhpath);
X
Xint
Xmain(int argc, char *argv[]) {
X if (strcmp(argv[1], "-") != 0) {
X mhdb_add(argv[1]);
X } else {
X char line[MAXPATHLEN+1];
X
X while (fgets(line, sizeof line, stdin)) {
X char *t = strrchr(line, '\n');
X
X if (t != NULL)
X *t = '\0';
X mhdb_add(line);
X }
X }
X
X if (d != NULL)
X mhdb_close(d);
X if (p != NULL)
X free(p);
X exit(0);
X}
X
Xstatic void
Xmhdb_add(const char *mhpath) {
X char *t = mhdb_path(mhpath);
X int uid;
X
X if (d != NULL && p != NULL && strcmp(t, p) != 0) {
X mhdb_close(d);
X d = NULL;
X free(p);
X p = NULL;
X }
X if (d == NULL) {
X assert(p == NULL);
X d = mhdb_open(t, mhdb_acc_exclusive);
X p = t;
X }
X uid = mhdb_assign_uid(d, mhpath, 0);
X#ifdef MHDB_HEADERS
X mhdb_store_hdr(d, mhpath, uid);
X#endif
X}
bad38879bcc2b0eecb693d699b4bb7f3
echo x - mhdb-build.sh
sed 's/^X//' >mhdb-build.sh << 'c5486321891e08b434fdda65fcfd40eb'
X#! /bin/sh
X
XPATH=/home/vixie/src/mhdb:$PATH
X
Xcase "$1" in
X+*) folder=$1 ;;
X*) echo usage: $0 +folder; exit 1
Xesac
X
Xpath=`mhpath $folder`
Xif [ ! -d $path ]; then
X echo $0: not a folder: $folder
X exit 1
Xfi
X
Xrm -f $path/mhindex.db
Xmhpath all $folder | mhdb-add -
X
Xexit
c5486321891e08b434fdda65fcfd40eb
echo x - mhdb-buildall.sh
sed 's/^X//' >mhdb-buildall.sh << '26bd47b3340bba2e977eb8b5f3c93ac4'
X#! /bin/sh
X
XPATH=/home/vixie/src/mhdb:$PATH
X
Xfolders -fast -recurse | while read folder; do
X echo +$folder
X mhdb-build.sh +$folder
Xdone
X
Xexit
26bd47b3340bba2e977eb8b5f3c93ac4
echo x - mhdb-del.c
sed 's/^X//' >mhdb-del.c << '5200b83c898774d7b2e51862a90a17e9'
X#include <sys/param.h>
X
X#include <assert.h>
X#include <stdlib.h>
X#include <stdio.h>
X#include <string.h>
X
X#include "mhdb.h"
X
Xstatic mhdb_t d;
Xstatic char *p;
X
Xstatic void mhdb_del(const char *mhpath);
X
Xint
Xmain(int argc, char *argv[]) {
X if (strcmp(argv[1], "-") != 0) {
X mhdb_del(argv[1]);
X } else {
X char line[MAXPATHLEN+1];
X
X while (fgets(line, sizeof line, stdin)) {
X char *t = strrchr(line, '\n');
X
X if (t != NULL)
X *t = '\0';
X mhdb_del(line);
X }
X }
X
X if (d != NULL)
X mhdb_close(d);
X if (p != NULL)
X free(p);
X exit(0);
X}
X
Xstatic void
Xmhdb_del(const char *mhpath) {
X char *t = mhdb_path(mhpath);
X int uid;
X
X if (d != NULL && p != NULL && strcmp(t, p) != 0) {
X mhdb_close(d);
X d = NULL;
X free(p);
X p = NULL;
X }
X if (d == NULL) {
X assert(p == NULL);
X d = mhdb_open(t, mhdb_acc_exclusive);
X p = t;
X }
X uid = mhdb_get_uid(d, mhpath);
X#ifdef MHDB_HEADERS
X mhdb_remove_hdr(d, uid);
X#endif
X mhdb_delete_uid(d, mhpath, uid);
X}
5200b83c898774d7b2e51862a90a17e9
echo x - mhdb-dump.c
sed 's/^X//' >mhdb-dump.c << '4bf3f93188fb7e605f36d4cd168ed683'
X#include <sys/stat.h>
X
X#include <err.h>
X#include <stdio.h>
X#include <stdlib.h>
X
X#include "mhdb.h"
X#include "mhdb_pvt.h"
X
Xstatic void mhdb_dump_folder(mhdb_t);
Xstatic void mhdb_dump_message(mhdb_t, const char *mhpath);
X
Xint
Xmain(int argc, char *argv[]) {
X struct stat sb;
X mhdb_t mhdb;
X
X mhdb = mhdb_openpath(argv[1], 0);
X if (mhdb == NULL)
X err(1, "mhdb_open failed (%s)", argv[1]);
X if (stat(argv[1], &sb) < 0)
X err(1, "stat failed (%s)", argv[1]);
X if (S_ISDIR(sb.st_mode)) {
X mhdb_dump_folder(mhdb);
X } else if (S_ISREG(sb.st_mode)) {
X mhdb_dump_message(mhdb, argv[1]);
X } else
X warn("%s is neither a directory nor a file", argv[1]);
X mhdb_close(mhdb);
X exit(0);
X}
X
Xstatic void
Xmhdb_dump_folder(mhdb_t mhdb) {
X datum key;
X
X for (key = dbm_firstkey(mhdb->d);
X key.dptr != NULL;
X key = dbm_nextkey(mhdb->d)) {
X datum data;
X
X data = dbm_fetch(mhdb->d, key);
X printf("'%.*s' => '%.*s'\n",
X key.dsize, key.dptr,
X data.dsize, data.dptr);
X }
X}
X
Xstatic void
Xmhdb_dump_message(mhdb_t mhdb, const char *mhpath) {
X int uid = mhdb_get_uid(mhdb, mhpath);
X
X printf("uid = %d\n", uid);
X#ifdef MHDB_HEADERS
X if (uid != 0) {
X ssize_t siz;
X char *hdr;
X
X siz = mhdb_get_hdr(mhdb, &hdr, uid);
X if (siz >= 0) {
X printf("---\n%.*s===\n", (int) siz, hdr);
X free(hdr);
X }
X }
X#endif
X}
4bf3f93188fb7e605f36d4cd168ed683
echo x - mhdb-ref.c
sed 's/^X//' >mhdb-ref.c << '748283885dfe181dcd50f277c1754ece'
X#include <stdlib.h>
X#include <string.h>
X
X#include "mhdb.h"
X
Xint
Xmain(int argc, char *argv[]) {
X char *p1, *p2;
X mhdb_t d1, d2;
X int uid;
X
X /* Here we call mhdb_path and mhdb_open separately (vs mh-add/mh-del)
X * because if it's the same folder we don't want to open the database
X * twice.
X */
X p1 = mhdb_path(argv[1]);
X p2 = mhdb_path(argv[2]);
X d1 = mhdb_open(p1, mhdb_acc_exclusive);
X d2 = (filenamecmp(p1, p2) == 0)
X ? d1
X : mhdb_open(p2, mhdb_acc_exclusive);
X free(p2);
X free(p1);
X uid = mhdb_get_uid(d1, argv[1]);
X#ifdef MHDB_HEADERS
X if (d1 != d2)
X mhdb_remove_hdr(d1, uid);
X#endif
X mhdb_delete_uid(d1, argv[1], uid);
X uid = mhdb_assign_uid(d2, argv[2], (d1 == d2) ? uid : 0);
X#ifdef MHDB_HEADERS
X if (d1 != d2)
X mhdb_store_hdr(d2, argv[2], uid);
X#endif
X mhdb_close(d2);
X if (d1 != d2)
X mhdb_close(d1);
X exit(0);
X}
748283885dfe181dcd50f277c1754ece
echo x - mhdb.c
sed 's/^X//' >mhdb.c << '10087cbdba0abeaae47aec0eb43b7228'
X#include <sys/file.h>
X
X#include <ctype.h>
X#include <err.h>
X#include <stdarg.h>
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X
X#include "mhdb.h"
X#include "mhdb_pvt.h"
X
Xstatic const char base[] = "mhindex";
X
Xstatic int mhdb_atoi(datum a);
Xstatic int mhdb_isnum(const char *s);
Xstatic int mhdb_msgno(const char *mhpath);
X
X/* Compute a dbname corresponding to this full MH path name, which could
X * be of a message (if it has an all-numeric base name) or folder (if not).
X *
X * Danger: if given /home/vixie/Mail/123 (all numeric name) this code will
X * silently do the wrong thing (/home/vixie/Mail/mhindex.db). Unlike MH,
X * it does not stat() the argument to find out if it's a directory or not.
X *
X * Danger: allocates on the heap and returns that -- caller must call free().
X */
Xchar *
Xmhdb_path(const char *mhpath) {
X char *t, *p;
X
X t = malloc(strlen(mhpath) + strlen(base) + sizeof "/");
X if (t == NULL)
X err(1, "malloc failed");
X strcpy(t, mhpath);
X p = strrchr(t, '/');
X if (p != NULL) {
X if (mhdb_isnum(p + 1)) /* ends in /msgnum */
X p[1] = '\0'; /* ...so, truncate. */
X else if (p[1] != '\0') /* ends in non-'/' */
X strcat(t, "/"); /* ...so, append '/' */
X }
X strcat(t, base);
X return (t);
X}
X
X/* Open the database, creating if nec'y, and lock it. Since we use flock()
X * the unlock is implicit upon close() or exit().
X */
Xmhdb_t
Xmhdb_open(const char *dbpath, mhdb_acc_t acc) {
X mhdb_t self;
X DBM *d;
X int writable_p = (acc == mhdb_acc_exclusive);
X
X d = dbm_open(dbpath, writable_p ? (O_CREAT | O_RDWR) : O_RDONLY, 0666);
X if (d == NULL) {
X if (writable_p)
X err(1, "dbm_open failed");
X else
X return (NULL);
X }
X
X if (acc != mhdb_acc_nolock)
X if (flock(dbm_dirfno(d), writable_p ? LOCK_EX : LOCK_SH) < 0)
X err(1, "flock failed");
X
X self = malloc(sizeof *self);
X self->d = d;
X return (self);
X}
X
X/* Convenience function so that folks who don't need to know the dbpath can
X * avoid the hassle of calling free(). (imapd and dovecot i'm looking at YOU.)
X */
Xmhdb_t
Xmhdb_openpath(const char *mhpath, mhdb_acc_t acc) {
X mhdb_t self;
X char *dbpath;
X
X dbpath = mhdb_path(mhpath);
X self = mhdb_open(dbpath, acc);
X free(dbpath);
X return (self);
X}
X
X/* Close and release.
X */
Xvoid
Xmhdb_close(mhdb_t self) {
X dbm_close(self->d);
X free(self);
X}
X
X/* Write something to the audit log.
X */
Xvoid
Xmhdb_audit(const char *fmt, ...) {
X va_list ap;
X
X va_start(ap, fmt);
X vfprintf(stderr, fmt, ap);
X va_end(ap);
X}
X
X/* Get an existing uid from the database.
X */
Xint
Xmhdb_get_uid(mhdb_t self, const char *mhpath) {
X datum key, data;
X int msg, uid;
X char *t;
X
X msg = mhdb_msgno(mhpath);
X if (msg == 0) {
X warnx("mhdb_add: no message number (%s)", mhpath);
X return (0);
X }
X
X /* Get the UID for this message number, if any. */
X asprintf(&t, "%d:msg:uid", msg);
X key.dptr = t;
X key.dsize = strlen(t);
X data = dbm_fetch(self->d, key);
X uid = (data.dptr != NULL) ? mhdb_atoi(data) : 0;
X free(key.dptr);
X
X return (uid);
X}
X
X/* Add a new msg<->uid mapping to the database. Returns new (or given) UID.
X */
Xint
Xmhdb_assign_uid(mhdb_t self, const char *mhpath, int given_uid) {
X datum key, data;
X int msg, uid;
X char *t;
X
X msg = mhdb_msgno(mhpath);
X if (msg == 0) {
X warnx("mhdb_add: no message number (%s)", mhpath);
X return (0);
X }
X
X /* Get next UID from file header, unless it was given. */
X if (given_uid != 0) {
X uid = given_uid;
X } else {
X key.dptr = "file_header";
X key.dsize = strlen(key.dptr);
X data = dbm_fetch(self->d, key);
X if (data.dptr == NULL) {
X data.dptr = "1";
X data.dsize = strlen(data.dptr);
X }
X uid = mhdb_atoi(data);
X }
X
X /* Store mapping from this UID to the message number. */
X asprintf(&t, "%d:uid:msg", uid);
X key.dptr = t;
X key.dsize = strlen(t);
X asprintf(&t, "%d", msg);
X data.dptr = t;
X data.dsize = strlen(t);
X switch (dbm_store(self->d, key, data, DBM_INSERT)) {
X case -1: err(1, "dbm_store");
X case 1: errx(1, "key %s already present", key.dptr);
X }
X free(data.dptr);
X free(key.dptr);
X
X /* Store mapping from this message number to this UID. */
X asprintf(&t, "%d:msg:uid", msg);
X key.dptr = t;
X key.dsize = strlen(t);
X asprintf(&t, "%d", uid);
X data.dptr = t;
X data.dsize = strlen(t);
X switch (dbm_store(self->d, key, data, DBM_INSERT)) {
X case -1: err(1, "dbm_store");
X case 1: errx(1, "key %s already present", key.dptr);
X }
X free(data.dptr);
X free(key.dptr);
X
X /* Increment the UID and store it back in the database,
X * unless it was given.
X */
X if (given_uid == 0) {
X key.dptr = "file_header";
X key.dsize = strlen(key.dptr);
X asprintf(&t, "%d", uid + 1);
X data.dptr = t;
X data.dsize = strlen(t);
X if (dbm_store(self->d, key, data, DBM_REPLACE) < 0)
X err(1, "dbm_store");
X free(data.dptr);
X }
X
X return (uid);
X}
X
X/* Remove a UID mapping from the database.
X */
Xvoid
Xmhdb_delete_uid(mhdb_t self, const char *mhpath, int uid) {
X datum key;
X int msg;
X char *t;
X
X msg = mhdb_msgno(mhpath);
X if (msg == 0) {
X warnx("mhdb_add: no message number (%s)", mhpath);
X return;
X }
X
X /* Remove mapping from msg to uid (or fail silently). */
X asprintf(&t, "%d:msg:uid", msg);
X key.dptr = t;
X key.dsize = strlen(t);
X dbm_delete(self->d, key);
X free(key.dptr);
X
X /* Remove mapping from uid to msg if there is one. */
X asprintf(&t, "%d:uid:msg", uid);
X key.dptr = t;
X key.dsize = strlen(t);
X dbm_delete(self->d, key);
X free(key.dptr);
X}
X
X#ifdef MHDB_HEADERS
X/* Retrieve a message's header, indexed by UID.
X */
Xssize_t
Xmhdb_get_hdr(mhdb_t self, char **bufp, int uid) {
X datum key, data;
X char *t;
X
X asprintf(&t, "%d:uid:hdr", uid);
X key.dptr = t;
X key.dsize = strlen(t);
X
X data = dbm_fetch(self->d, key);
X if (data.dptr == NULL) {
X warnx("mhdb_get_hdr: no message header (uid %d)", uid);
X free(key.dptr);
X return (-1);
X }
X
X *bufp = malloc(data.dsize);
X memcpy(*bufp, data.dptr, data.dsize);
X free(key.dptr);
X return (data.dsize);
X}
X
X/* Store a message's header, indexed by UID.
X */
Xvoid
Xmhdb_store_hdr(mhdb_t self, const char *mhpath, int uid) {
X datum key, data;
X char ch, pch, *t;
X FILE *fp;
X
X asprintf(&t, "%d:uid:hdr", uid);
X key.dptr = t;
X key.dsize = strlen(t);
X
X fp = fopen(mhpath, "r");
X if (fp == NULL) {
X warn("mhdb_store_hdr: cannot open file (%s)", mhpath);
X return;
X }
X for (pch = EOF; (ch = getc(fp)) != EOF; pch = ch)
X if (ch == '\n' && pch == '\n')
X break;
X data.dsize = ftell(fp);
X data.dptr = malloc(data.dsize);
X rewind(fp);
X fread(data.dptr, sizeof(char), data.dsize, fp);
X fclose(fp);
X
X if (dbm_store(self->d, key, data, DBM_INSERT) < 0)
X warn("dbm_store");
X free(data.dptr);
X free(key.dptr);
X}
X
X/* Remove a message's header, indexed by UID.
X */
Xvoid
Xmhdb_remove_hdr(mhdb_t self, int uid) {
X datum key;
X char *t;
X
X asprintf(&t, "%d:uid:hdr", uid);
X key.dptr = t;
X key.dsize = strlen(t);
X dbm_delete(self->d, key);
X free(key.dptr);
X}
X#endif
X
X/* --- private --- */
X
X/* Do what atoi would do but for a counted string (not null terminated)
X * held in a datum.
X */
Xstatic int
Xmhdb_atoi(datum a) {
X int i = 0;
X
X while (a.dsize-- > 0)
X i *= 10, i += *a.dptr++ - '0';
X return (i);
X}
X
X/* Is this string all-numeric?
X */
Xstatic int
Xmhdb_isnum(const char *s) {
X char ch;
X
X while ((ch = *s++) != '\0')
X if (isascii(ch) && isdigit(ch))
X /*next*/;
X else
X return (0);
X return (1);
X}
X
X/* Retrieve MH message number from path name.
X */
Xstatic int
Xmhdb_msgno(const char *mhpath) {
X const char *p = strrchr(mhpath, '/');
X
X if (p != NULL)
X p++;
X else
X p = mhpath;
X return (atoi(p));
X}
X
10087cbdba0abeaae47aec0eb43b7228
echo x - mhdb.h
sed 's/^X//' >mhdb.h << 'b1edf5d0ed51f0163028cca21f9ec519'
X#ifndef MHDB_H
X#define MHDB_H 1
X
X#ifdef APPLE
X#define filenamecmp strcasecmp
X#else
X#define filenamecmp strcmp
X#endif
X
X#include <sys/types.h>
X#include <fcntl.h>
X
Xstruct mhdb;
Xtypedef struct mhdb *mhdb_t;
X
Xtypedef enum {
X mhdb_acc_nolock = 0,
X mhdb_acc_shared,
X mhdb_acc_exclusive
X} mhdb_acc_t;
X
Xchar *mhdb_path(const char *mhpath);
Xmhdb_t mhdb_open(const char *dbpath, mhdb_acc_t);
Xmhdb_t mhdb_openpath(const char *mhpath, mhdb_acc_t);
Xvoid mhdb_close(mhdb_t);
Xvoid mhdb_audit(const char *fmt, ...);
Xint mhdb_get_uid(mhdb_t, const char *mhpath);
Xint mhdb_assign_uid(mhdb_t, const char *mhpath, int given_uid);
Xvoid mhdb_delete_uid(mhdb_t, const char *mhpath, int uid);
X#ifdef MHDB_HEADERS
Xssize_t mhdb_get_hdr(mhdb_t, char **, int uid);
Xvoid mhdb_store_hdr(mhdb_t, const char *mhpath, int uid);
Xvoid mhdb_remove_hdr(mhdb_t, int uid);
X#endif
X
X#endif /*MHDB_H*/
b1edf5d0ed51f0163028cca21f9ec519
echo x - mhdb_pvt.h
sed 's/^X//' >mhdb_pvt.h << '3e3c03f8520d5ba4363c9fc2c4ba2a52'
X#ifndef MHDB_PVT_H
X#define MHDB_PVT_H 1
X
X#include DBM_HEADER
X
Xstruct mhdb {
X DBM *d;
X};
X
X#endif /*MHDB_PVT_H*/
3e3c03f8520d5ba4363c9fc2c4ba2a52
echo x - nmh-1.3.diffs
sed 's/^X//' >nmh-1.3.diffs << '0605ee6e1463c974ef5ec76760fe8d32'
X--- nmh-1.3/uip/scan.c.pre-vixie 2011-02-07 05:20:02.000000000 +0000
X+++ nmh-1.3/uip/scan.c 2011-02-08 16:38:51.000000000 +0000
X@@ -17,6 +17,26 @@
X #include <h/utils.h>
X #include <errno.h>
X
X+#define MHDB 1
X+
X+#ifdef MHDB
X+#include "/home/vixie/src/mhdb/mhdb.h"
X+struct functx {
X+ char *dptr, *hdr;
X+ ssize_t dsize;
X+ int uid;
X+};
X+static int funread (void *cookie, char *buf, int len) {
X+ struct functx *fc = cookie;
X+ int plan = min(len, fc->dsize);
X+
X+ memcpy(buf, fc->dptr, plan);
X+ fc->dptr += plan;
X+ fc->dsize -= plan;
X+ return (plan);
X+}
X+#endif
X+
X static struct swit switches[] = {
X #define CLRSW 0
X { "clear", 0 },
X@@ -72,6 +92,9 @@
X struct msgs_array msgs = { 0, 0, NULL };
X struct msgs *mp;
X FILE *in;
X+#ifdef MHDB
X+ mhdb_t mhdb;
X+#endif
X
X #ifdef LOCALE
X setlocale(LC_ALL, "");
X@@ -212,6 +235,9 @@
X if (!folder)
X folder = getfolder (1);
X maildir = m_maildir (folder);
X+#ifdef MHDB
X+ mhdb = mhdb_openpath (maildir, mhdb_acc_shared);
X+#endif
X
X if (chdir (maildir) == NOTOK)
X adios (maildir, "unable to change directory to");
X@@ -262,7 +288,25 @@
X (revflag ? msgnum >= mp->lowsel : msgnum <= mp->hghsel);
X msgnum += (revflag ? -1 : 1)) {
X if (is_selected(mp, msgnum)) {
X- if ((in = fopen (cp = m_name (msgnum), "r")) == NULL) {
X+ struct functx *fc = NULL;
X+ in = NULL;
X+#ifdef MHDB
X+ if (mhdb != NULL) {
X+ fc = malloc (sizeof *fc);
X+ fc->uid = mhdb_get_uid (mhdb, m_name (msgnum));
X+ fc->dsize = mhdb_get_hdr (mhdb, &fc->hdr, fc->uid);
X+ fc->dptr = fc->hdr;
X+ if (fc->dsize > 0)
X+ in = fropen (fc, funread);
X+ else {
X+ free (fc);
X+ fc = NULL;
X+ }
X+ }
X+#endif
X+ if (in == NULL)
X+ in = fopen (cp = m_name (msgnum), "r");
X+ if (in == NULL) {
X #if 0
X if (errno != EACCES)
X #endif
X@@ -313,6 +357,13 @@
X }
X hdrflag = 0;
X fclose (in);
X+#ifdef MHDB
X+ if (fc != NULL) {
X+ free(fc->hdr);
X+ free(fc);
X+ fc = NULL;
X+ }
X+#endif
X if (ontty)
X fflush (stdout);
X }
X--- nmh-1.3/uip/scansbr.c.pre-vixie 2011-02-07 18:52:37.000000000 +0000
X+++ nmh-1.3/uip/scansbr.c 2011-02-07 18:54:12.000000000 +0000
X@@ -325,6 +325,7 @@
X if ((datecomp && !datecomp->c_text) || (!size && !outnum)) {
X struct stat st;
X
X+ if (fileno(inb) != -1) { /*MHDB*/
X fstat (fileno(inb), &st);
X if (!size && !outnum)
X dat[2] = st.st_size;
X@@ -341,6 +342,7 @@
X datecomp->c_flags &= ~CF_DATEFAB;
X }
X }
X+ } /*MHDB*/
X }
X
X fmt_scan (fmt, scanl, slwidth, dat);
0605ee6e1463c974ef5ec76760fe8d32
exit
- Re: [Nmh-workers] some indexing results, (continued)
- Re: [Nmh-workers] some indexing results, Ken Hornstein, 2011/02/08
- Re: [Nmh-workers] some indexing results, Earl Hood, 2011/02/08
- Re: [Nmh-workers] some indexing results, Paul Vixie, 2011/02/08
- Re: [Nmh-workers] some indexing results, Paul Vixie, 2011/02/15
- Re: [Nmh-workers] some indexing results, Valdis . Kletnieks, 2011/02/15
- Re: [Nmh-workers] some indexing results, Paul Vixie, 2011/02/15
- Re: [Nmh-workers] some indexing results, Valdis . Kletnieks, 2011/02/15
- Re: [Nmh-workers] some indexing results, Ken Hornstein, 2011/02/15
- Re: [Nmh-workers] some indexing results, Paul Vixie, 2011/02/15
- Re: [Nmh-workers] some indexing results, Ken Hornstein, 2011/02/15
- Re: [Nmh-workers] some indexing results,
Paul Vixie <=
fun (was Re: [Nmh-workers] some indexing results), Paul Vixie, 2011/02/07