Fast nnspool-find-article-by-message-id function
Johan Vromans
jv at mh.nl
Tue Mar 6 06:42:07 AEST 1990
This shar archive contains a fast lookup article by id mechanism for
GNUS using NNSPOOL. It works only if yoy have built NEWS with [n]dbm
or dbz.
Enjoy.
Johan
#---------------------------------- cut here ----------------------------------
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
#
# Wrapped by Johan Vromans <jv at mhres> on Mon Mar 5 13:38:39 1990
#
# This archive contains:
# README getartbyid.c getartbyid.el
#
# Existing files will not be overwritten.
# Error checking via wc(1) will be performed.
LANG=""; export LANG
if test -f README
then
echo Ok to overwrite existing file README\?
read answer
case "$answer" in
[yY]*) echo Proceeding;;
*) echo Aborting; exit 1;;
esac
rm -f README
if test -f README
then
echo Error: could not remove README, aborting
exit 1
fi
fi
echo x - README
cat >README <<'@EOF'
This shar archive contains a fast lookup article by id mechanisme for
GNUS using NNSPOOL. It works only if yoy have built NEWS with [n]dbm
or dbz.
It consists of a replacement function for
nnspool-find-article-by-message-id, and a fast lookup program.
The program should be compiled and placed somewher in your PATH.
Compile with:
gcc -s -O getartbyid.c -o getartbyid -ldbm
It also works with vanilla CC and Jon Zeeff's DBZ.
Load getartbyid.el after loading gnus/nnspool, and you will have a blinding
fast '^' key.
Motivation: I created this function since I could not afford Emacs to
carry an 8Mb buffer all of the time - other programs started running
out of VM.
Enjoy.
@EOF
set `wc -lwc <README`
if test $1$2$3 != 22113680
then
echo ERROR: wc results of README are $* should be 22 113 680
fi
chmod 644 README
if test -f getartbyid.c
then
echo Ok to overwrite existing file getartbyid.c\?
read answer
case "$answer" in
[yY]*) echo Proceeding;;
*) echo Aborting; exit 1;;
esac
rm -f getartbyid.c
if test -f getartbyid.c
then
echo Error: could not remove getartbyid.c, aborting
exit 1
fi
fi
echo x - getartbyid.c
cat >getartbyid.c <<'@EOF'
/* getartinfo.c - fetch article info using Bnews history file */
/* Usage: getartinfo [-v] [id] ... */
#include <stdio.h>
#include <ctype.h>
#include <string.h>
/* DBM / DBZ declarations */
typedef struct { char *dptr; int dsize; } datum;
datum fetch ();
/* other forwards */
char *memcpy ();
static char *lcase ();
#define HISTFILE "/usr/lib/news/history"
#define BUFLEN 512
int f_verbose = 0;
main (argc, argv)
int argc;
char *argv[];
{
FILE *hist = NULL; /* history file, if opened */
datum key, val; /* DBM items */
int fail = 0; /* failure count */
char artbuf [BUFLEN]; /* buf to hold article id */
char *artid; /* pointer to article id */
char buf [BUFLEN]; /* read buf for history file */
long fpos; /* seek position in hist file */
char *p; /* */
if (argc >= 1 && !strcmp (argv[1], "-v")) {
argc--;
argv++;
f_verbose = 1;
}
/* initialize DBM */
if (dbminit (HISTFILE) < 0) {
perror (HISTFILE);
return -1;
}
/* process arguments */
while (--argc > 0) {
/* copy article id into article buf, provide < and > if needed */
strcpy (artid = artbuf+1, *++argv);
if (*artid != '<') {
*--artid = '<';
strcat (artid, ">");
}
/* lowcase and build DBM key */
key.dptr = artid;
key.dsize = strlen (key.dptr)+1;
lcase (key.dptr, key.dsize-1);
/* fetch from DBM */
val = fetch (key);
if (val.dptr == NULL) {
if (f_verbose)
fprintf (stderr, "%s: not found\n", *argv);
fail++; /* tally */
continue;
}
/* open the history file upon first need */
if (hist == NULL) {
if ((hist = fopen (HISTFILE, "r")) == NULL) {
perror (HISTFILE);
return -1;
}
}
/* get the file pos from the DBM return value */
memcpy ((char*)&fpos, val.dptr, sizeof(long));
/* look it up */
if (fseek (hist, fpos, 0) < 0 ) {
if (f_verbose)
perror ("seek");
fail++;
continue;
}
if (fgets (buf, BUFLEN, hist) == NULL) {
if (f_verbose)
perror ("read");
fail++;
continue;
}
/* check if it is the right article */
p = strchr (buf, '\t');
if (p == NULL)
p = strchr (buf, '\n');
*p = 0;
lcase (buf, strlen (buf));
if (strcmp (buf, key.dptr) != 0) { /* it's not */
if (f_verbose)
fprintf (stderr, "db corrupt?\n");
fail++;
continue;
}
*p = '\t';
/* print results */
buf[strlen(buf)-1] = '\0'; /* zap the \n */
printf ("%s\n", buf);
}
/* wrap up */
dbmclose ();
if (hist != NULL)
fclose (hist);
/* return number of failures */
return fail;
}
static char *lcase (s)
register char *s;
{
register int n = strlen (s);
for (s += n; n > 0; --n) {
if (isupper(*--s))
*s = tolower(*s);
}
return s;
}
@EOF
set `wc -lwc <getartbyid.c`
if test $1$2$3 != 1354542803
then
echo ERROR: wc results of getartbyid.c are $* should be 135 454 2803
fi
chmod 644 getartbyid.c
if test -f getartbyid.el
then
echo Ok to overwrite existing file getartbyid.el\?
read answer
case "$answer" in
[yY]*) echo Proceeding;;
*) echo Aborting; exit 1;;
esac
rm -f getartbyid.el
if test -f getartbyid.el
then
echo Error: could not remove getartbyid.el, aborting
exit 1
fi
fi
echo x - getartbyid.el
cat >getartbyid.el <<'@EOF'
(defun nnspool-find-article-by-message-id (id)
"Return full pathname of an article identified by message-ID.
This function uses an external C-program to do the history lookup."
(save-excursion
(let ((aname nil) (buffer (get-buffer-create "*newshistory*")))
(set-buffer buffer)
(erase-buffer)
(call-process "getartbyid" nil t nil id)
(goto-char (point-min))
(prog1
(if (re-search-forward
(concat "^" (regexp-quote id)
"[ \t].*[ \t]\\([^ \t/]+\\)/\\([0-9]+\\)[ \t]*$") nil t)
(let ((group (buffer-substring (match-beginning 1) (match-end 1)))
(number (buffer-substring (match-beginning 2) (match-end 2))))
(concat (nnspool-article-pathname
(nnspool-replace-chars-in-string group ?. ?/))
number)))
(set-buffer-modified-p nil)
(kill-buffer buffer)))))
@EOF
set `wc -lwc <getartbyid.el`
if test $1$2$3 != 2379833
then
echo ERROR: wc results of getartbyid.el are $* should be 23 79 833
fi
chmod 644 getartbyid.el
exit 0
--
Johan Vromans jv at mh.nl via internet backbones
Multihouse Automatisering bv uucp: ..!{uunet,hp4nl}!mh.nl!jv
Doesburgweg 7, 2803 PL Gouda, The Netherlands phone/fax: +31 1820 62944/62500
------------------------ "Arms are made for hugging" -------------------------
More information about the Alt.sources
mailing list