home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 0 / 0977 < prev    next >
Internet Message Format  |  1990-12-28  |  7KB

  1. From: jv@mh.nl (Johan Vromans)
  2. Newsgroups: gnu.emacs.gnus,alt.sources
  3. Subject: Fast nnspool-find-article-by-message-id function
  4. Message-ID: <JV.90Mar5134207@mhres.mh.nl>
  5. Date: 5 Mar 90 20:42:07 GMT
  6.  
  7. This shar archive contains a fast lookup article by id mechanism for
  8. GNUS using NNSPOOL. It works only if yoy have built NEWS with [n]dbm
  9. or dbz.
  10.  
  11. Enjoy.
  12.  
  13.     Johan
  14.  
  15. #---------------------------------- cut here ----------------------------------
  16. # This is a shell archive.  Remove anything before this line,
  17. # then unpack it by saving it in a file and typing "sh file".
  18. #
  19. # Wrapped by Johan Vromans <jv@mhres> on Mon Mar  5 13:38:39 1990
  20. #
  21. # This archive contains:
  22. #    README        getartbyid.c    getartbyid.el    
  23. #
  24. # Existing files will not be overwritten.
  25. # Error checking via wc(1) will be performed.
  26.  
  27. LANG=""; export LANG
  28.  
  29. if test -f README
  30. then
  31.     echo Ok to overwrite existing file README\?
  32.     read answer
  33.     case "$answer" in
  34.     [yY]*)    echo Proceeding;;
  35.     *)    echo Aborting; exit 1;;
  36.     esac
  37.     rm -f README
  38.     if test -f README
  39.     then
  40.         echo Error: could not remove README, aborting
  41.         exit 1
  42.     fi
  43. fi
  44. echo x - README
  45. cat >README <<'@EOF'
  46. This shar archive contains a fast lookup article by id mechanisme for
  47. GNUS using NNSPOOL. It works only if yoy have built NEWS with [n]dbm
  48. or dbz.
  49.  
  50. It consists of a replacement function for
  51. nnspool-find-article-by-message-id, and a fast lookup program.
  52.  
  53. The program should be compiled and placed somewher in your PATH.
  54. Compile with:
  55.  
  56.     gcc -s -O getartbyid.c -o getartbyid -ldbm
  57.  
  58. It also works with vanilla CC and Jon Zeeff's DBZ.
  59.  
  60. Load getartbyid.el after loading gnus/nnspool, and you will have a blinding
  61. fast '^' key.
  62.  
  63. Motivation: I created this function since I could not afford Emacs to
  64. carry an 8Mb buffer all of the time - other programs started running
  65. out of VM.
  66.  
  67. Enjoy.
  68. @EOF
  69. set `wc -lwc <README`
  70. if test $1$2$3 != 22113680
  71. then
  72.     echo ERROR: wc results of README are $* should be 22 113 680
  73. fi
  74.  
  75. chmod 644 README
  76.  
  77. if test -f getartbyid.c
  78. then
  79.     echo Ok to overwrite existing file getartbyid.c\?
  80.     read answer
  81.     case "$answer" in
  82.     [yY]*)    echo Proceeding;;
  83.     *)    echo Aborting; exit 1;;
  84.     esac
  85.     rm -f getartbyid.c
  86.     if test -f getartbyid.c
  87.     then
  88.         echo Error: could not remove getartbyid.c, aborting
  89.         exit 1
  90.     fi
  91. fi
  92. echo x - getartbyid.c
  93. cat >getartbyid.c <<'@EOF'
  94. /* getartinfo.c - fetch article info using Bnews history file */
  95.  
  96. /* Usage: getartinfo [-v] [id] ... */
  97.  
  98. #include <stdio.h>
  99. #include <ctype.h>
  100. #include <string.h>
  101.  
  102. /* DBM / DBZ declarations */
  103.  
  104. typedef struct { char *dptr; int dsize; } datum;
  105. datum fetch ();
  106.  
  107. /* other forwards */
  108.  
  109. char *memcpy ();
  110. static char *lcase ();
  111.  
  112. #define HISTFILE    "/usr/lib/news/history"
  113. #define BUFLEN    512
  114.  
  115. int f_verbose = 0;
  116.  
  117. main (argc, argv)
  118. int argc;
  119. char *argv[];
  120. {
  121.   FILE *hist = NULL;        /* history file, if opened */
  122.   datum key, val;        /* DBM items */
  123.   int fail = 0;            /* failure count */
  124.   char artbuf [BUFLEN];        /* buf to hold article id */
  125.   char *artid;            /* pointer to article id */
  126.   char buf [BUFLEN];        /* read buf for history file */
  127.   long fpos;            /* seek position in hist file */
  128.   char *p;            /*  */
  129.  
  130.   if (argc >= 1 && !strcmp (argv[1], "-v")) {
  131.     argc--;
  132.     argv++;
  133.     f_verbose = 1;
  134.   }
  135.  
  136.   /* initialize DBM */
  137.   if (dbminit (HISTFILE) < 0) {
  138.     perror (HISTFILE);
  139.     return -1;
  140.   }
  141.  
  142.   /* process arguments */
  143.   while (--argc > 0) {
  144.  
  145.     /* copy article id into article buf, provide < and > if needed */
  146.     strcpy (artid = artbuf+1, *++argv);
  147.     if (*artid != '<') {
  148.       *--artid = '<';
  149.       strcat (artid, ">");
  150.     }
  151.  
  152.     /* lowcase and build DBM key */
  153.     key.dptr = artid;
  154.     key.dsize = strlen (key.dptr)+1;
  155.     lcase (key.dptr, key.dsize-1);
  156.  
  157.     /* fetch from DBM */
  158.     val = fetch (key);
  159.     if (val.dptr == NULL) {
  160.       if (f_verbose)
  161.     fprintf (stderr, "%s: not found\n", *argv);
  162.       fail++;            /* tally */
  163.       continue;
  164.     }
  165.  
  166.     /* open the history file upon first need */
  167.     if (hist == NULL) {
  168.       if ((hist = fopen (HISTFILE, "r")) == NULL) {
  169.     perror (HISTFILE);
  170.     return -1;
  171.       }
  172.     }
  173.  
  174.     /* get the file pos from the DBM return value */
  175.     memcpy ((char*)&fpos, val.dptr, sizeof(long));
  176.  
  177.     /* look it up */
  178.     if (fseek (hist, fpos, 0) < 0 ) {
  179.       if (f_verbose)
  180.     perror ("seek");
  181.       fail++;
  182.       continue;
  183.     }
  184.     if (fgets (buf, BUFLEN, hist) == NULL) {
  185.       if (f_verbose)
  186.     perror ("read");
  187.       fail++;
  188.       continue;
  189.     }
  190.  
  191.     /* check if it is the right article */
  192.     p = strchr (buf, '\t');
  193.     if (p == NULL)
  194.       p = strchr (buf, '\n');
  195.     *p = 0;
  196.     lcase (buf, strlen (buf));
  197.     if (strcmp (buf, key.dptr) != 0) { /* it's not */
  198.       if (f_verbose)
  199.     fprintf (stderr, "db corrupt?\n");
  200.       fail++;
  201.       continue;
  202.     }
  203.     *p = '\t';
  204.  
  205.     /* print results */
  206.     buf[strlen(buf)-1] = '\0';    /* zap the \n */
  207.     printf ("%s\n", buf);
  208.   }
  209.  
  210.   /* wrap up */
  211.   dbmclose ();
  212.   if (hist != NULL)
  213.     fclose (hist);
  214.  
  215.   /* return number of failures */
  216.   return fail;
  217. }
  218.  
  219. static char *lcase (s)
  220. register char *s;
  221. {
  222.   register int n = strlen (s);
  223.   for (s += n; n > 0; --n) {
  224.     if (isupper(*--s))
  225.       *s = tolower(*s);
  226.   }
  227.   return s;
  228. }
  229. @EOF
  230. set `wc -lwc <getartbyid.c`
  231. if test $1$2$3 != 1354542803
  232. then
  233.     echo ERROR: wc results of getartbyid.c are $* should be 135 454 2803
  234. fi
  235.  
  236. chmod 644 getartbyid.c
  237.  
  238. if test -f getartbyid.el
  239. then
  240.     echo Ok to overwrite existing file getartbyid.el\?
  241.     read answer
  242.     case "$answer" in
  243.     [yY]*)    echo Proceeding;;
  244.     *)    echo Aborting; exit 1;;
  245.     esac
  246.     rm -f getartbyid.el
  247.     if test -f getartbyid.el
  248.     then
  249.         echo Error: could not remove getartbyid.el, aborting
  250.         exit 1
  251.     fi
  252. fi
  253. echo x - getartbyid.el
  254. cat >getartbyid.el <<'@EOF'
  255. (defun nnspool-find-article-by-message-id (id)
  256.   "Return full pathname of an article identified by message-ID.
  257. This function uses an external C-program to do the history lookup."
  258.   (save-excursion
  259.     (let ((aname nil) (buffer (get-buffer-create "*newshistory*")))
  260.       (set-buffer buffer)
  261.       (erase-buffer)
  262.       (call-process "getartbyid" nil t nil id)
  263.       (goto-char (point-min))
  264.       (prog1
  265.       (if (re-search-forward
  266.            (concat "^" (regexp-quote id)
  267.                "[ \t].*[ \t]\\([^ \t/]+\\)/\\([0-9]+\\)[ \t]*$") nil t)
  268.           (let ((group (buffer-substring (match-beginning 1) (match-end 1)))
  269.             (number (buffer-substring (match-beginning 2) (match-end 2))))
  270.         (concat (nnspool-article-pathname
  271.              (nnspool-replace-chars-in-string group ?. ?/))
  272.             number)))
  273.     (set-buffer-modified-p nil)
  274.     (kill-buffer buffer)))))
  275.  
  276.  
  277.  
  278. @EOF
  279. set `wc -lwc <getartbyid.el`
  280. if test $1$2$3 != 2379833
  281. then
  282.     echo ERROR: wc results of getartbyid.el are $* should be 23 79 833
  283. fi
  284.  
  285. chmod 644 getartbyid.el
  286.  
  287. exit 0
  288. --
  289. Johan Vromans                       jv@mh.nl via internet backbones
  290. Multihouse Automatisering bv               uucp: ..!{uunet,hp4nl}!mh.nl!jv
  291. Doesburgweg 7, 2803 PL Gouda, The Netherlands  phone/fax: +31 1820 62944/62500
  292. ------------------------ "Arms are made for hugging" -------------------------
  293.