home *** CD-ROM | disk | FTP | other *** search
- From: jv@mh.nl (Johan Vromans)
- Newsgroups: gnu.emacs.gnus,alt.sources
- Subject: Fast nnspool-find-article-by-message-id function
- Message-ID: <JV.90Mar5134207@mhres.mh.nl>
- Date: 5 Mar 90 20:42:07 GMT
-
- 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@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@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" -------------------------
-