Gnus development mailing list
 help / color / mirror / Atom feed
* Asynchronous hashcash.el
@ 2004-11-02 17:08 Magnus Henoch
  2004-11-02 21:11 ` Simon Josefsson
                   ` (2 more replies)
  0 siblings, 3 replies; 26+ messages in thread
From: Magnus Henoch @ 2004-11-02 17:08 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 2518 bytes --]

This is my first attempt at making hashcash.el asynchronous.  It
doesn't address all the ideas brought up in the discussion here, but
it's a good start.

User-visible changes:

* New function mail-add-payment-async takes all recipients in To and
  CC headers and starts generating hashcash tokens for them
  asynchronously.
* New function hashcash-cancel-async stops all asynchronous hashcash
  processes for the current buffer.
* New function hashcash-wait-async waits for all asynchronous hashcash
  processes in the current buffer to finish.
* New function hashcash-wait-or-cancel does one of the above depending
  on user input.
* hashcash-default-payment and hashcash-default-accept-payment are now
  20 by default, as recommended near the end of
  http://www.hashcash.org/dev/ .

Recommended hooks:

(add-hook 'message-setup-hook 'mail-add-payment-async)
(add-hook 'message-send-hook 'hashcash-wait-or-cancel)

Unfeatures:

* Asynchronous processes are not started automatically when you enter
  new addresses; you have to type M-x mail-add-payment-async
  yourself.  It seems that an idle timer, checking for point being
  outside of the header (to prevent tokens for halfwritten addresses)
  would be the solution.
* Incrementally increasing the collision length while the message is
  being written is not implemented.  Strictly speaking this is
  impossible, as the collision length is part of the hashed string,
  but this could be emulated, calculating longer and discarding
  shorter tokens.  I'm not sure it's worth it, though.

Bugs:

* If you call mail-add-payment{,-async} while a token is being
  generated asynchronously, you will get duplicate tokens.  Tokens
  already generated and inserted in the buffer are not duplicated,
  though, using hashcash-already-paid-p.

Changelog:

2004-11-02  Magnus Henoch  <mange@freemail.hu>

	* hashcash.el (hashcash-default-payment): Change default to 20
	(hashcash-default-accept-payment): Change default to 20
	(hashcash-process-alist): New variable
	(hashcash-generate-payment-async): Add
	(hashcash-already-paid-p): Add
	(hashcash-insert-payment): Don't generate payments twice
	(hashcash-insert-payment-async): Add
	(hashcash-insert-payment-async-2): Add
	(hashcash-cancel-async): Add
	(hashcash-wait-async): Add
	(hashcash-processes-running-p): Add
	(hashcash-wait-or-cancel): Add
	(mail-add-payment): New optional argument.  Conditionally start
	asynchronous calculation.
	(mail-add-payment-async): Add

What do you think about this?

Regards,
Magnus



[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: hashcash-async.patch --]
[-- Type: text/x-patch, Size: 7168 bytes --]

--- orig/lisp/hashcash.el
+++ mod/lisp/hashcash.el
@@ -32,13 +32,23 @@
 ;;
 ;; To automatically add payments to all outgoing mail:
 ;;    (add-hook 'message-send-hook 'mail-add-payment)
+;;
+;; Call mail-add-payment-async after writing the addresses but before
+;; writing the mail to start calculating the hashcash payment
+;; asynchronously.
+;;
+;; To do this automatically when addresses are prefilled:
+;;    (add-hook 'message-setup-hook 'mail-add-payment-async)
+;;
+;; To check whether calculations are done before sending:
+;;    (add-hook 'message-send-hook 'hashcash-wait-or-cancel)
 
 ;;; Code:
 
 (eval-and-compile
  (autoload 'executable-find "executable"))
 
-(defcustom hashcash-default-payment 10
+(defcustom hashcash-default-payment 20
   "*The default number of bits to pay to unknown users.
 If this is zero, no payment header will be generated.
 See `hashcash-payment-alist'."
@@ -51,7 +61,7 @@
 the value of hashcash payment to be made to that user.  STRING, if
 present, is the string to be hashed; if not present ADDR will be used.")
 
-(defcustom hashcash-default-accept-payment 10
+(defcustom hashcash-default-accept-payment 20
   "*The default minimum number of bits to accept on incoming payments."
   :type 'integer)
 
@@ -71,6 +81,9 @@
   "*Specifies whether or not hashcash payments should be made to newsgroups."
   :type 'boolean)
 
+(defvar hashcash-process-alist nil
+  "Alist of asynchronous hashcash processes and buffers.")
+
 (require 'mail-utils)
 
 (eval-and-compile
@@ -122,6 +135,19 @@
 	(hashcash-token-substring))
     (error "No `hashcash' binary found")))
 
+(defun hashcash-generate-payment-async (str val callback)
+  "Generate a hashcash payment by finding a VAL-bit collison on STR.
+Return immediately.  Call CALLBACK with process and result when ready."
+  (if (> val 0)
+      (let ((process (start-process "hashcash" nil
+				    hashcash-path "-m" "-q" "-b" (number-to-string val) str)))
+	(setq hashcash-process-alist (cons
+				      (cons process (current-buffer))
+				      hashcash-process-alist))
+	(set-process-filter process `(lambda (process output)
+				       (funcall ,callback process output))))
+    (funcall callback nil)))
+
 (defun hashcash-check-payment (token str val)
   "Check the validity of a hashcash payment."
   (if hashcash-path
@@ -151,17 +177,87 @@
 	((equal (aref token 6) ?:) 1.1)
 	(t (error "Unknown hashcash format version"))))
 
+(defun hashcash-already-paid-p (recipient)
+  "Check for hashcash token to RECIPIENT in current buffer."
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-headers-or-head)
+      (let ((token (message-fetch-field "x-hashcash")))
+	(and (stringp token)
+	     (string-match (regexp-quote recipient) token))))))
+
 ;;;###autoload
 (defun hashcash-insert-payment (arg)
   "Insert X-Payment and X-Hashcash headers with a payment for ARG"
   (interactive "sPay to: ")
-  (let ((pay (hashcash-generate-payment (hashcash-payment-to arg)
-					(hashcash-payment-required arg))))
-    (when pay
+  (unless (hashcash-already-paid-p arg)
+    (let ((pay (hashcash-generate-payment (hashcash-payment-to arg)
+					  (hashcash-payment-required arg))))
+      (when pay
+	;;      (insert-before-markers "X-Payment: hashcash "
+	;;			     (number-to-string (hashcash-version pay)) " "
+	;;			     pay "\n")
+	(insert-before-markers "X-Hashcash: " pay "\n")))))
+
+;;;###autoload
+(defun hashcash-insert-payment-async (arg)
+  "Insert X-Payment and X-Hashcash headers with a payment for ARG
+Only start calculation.  Results are inserted when ready."
+  (interactive "sPay to: ")
+  (unless (hashcash-already-paid-p arg)
+    (hashcash-generate-payment-async (hashcash-payment-to arg)
+				     (hashcash-payment-required arg)
+				     `(lambda (process payment)
+					(hashcash-insert-payment-async-2 ,(current-buffer) process payment)))))
+
+(defun hashcash-insert-payment-async-2 (buffer process pay)
+  (with-current-buffer buffer
+    (save-excursion
+      (save-restriction
+	(setq hashcash-process-alist (delq
+				      (assq process hashcash-process-alist)
+				      hashcash-process-alist))
+	(goto-char (point-min))
+	(search-forward mail-header-separator)
+	(beginning-of-line)
+	(when pay
 ;;      (insert-before-markers "X-Payment: hashcash "
 ;;			     (number-to-string (hashcash-version pay)) " "
 ;;			     pay "\n")
-      (insert-before-markers "X-Hashcash: " pay "\n"))))
+	  (insert-before-markers "X-Hashcash: " pay))))))
+
+(defun hashcash-cancel-async (&optional buffer)
+  "Delete any hashcash processes associated with BUFFER.
+BUFFER defaults to the current buffer."
+  (interactive)
+  (unless buffer (setq buffer (current-buffer)))
+  (let (entry)
+    (while (setq entry (rassq buffer hashcash-process-alist))
+      (delete-process (car entry))
+      (setq hashcash-process-alist
+	    (delq entry hashcash-process-alist)))))
+
+(defun hashcash-wait-async (&optional buffer)
+  "Wait for asynchronous hashcash processes in BUFFER to finish.
+BUFFER defaults to the current buffer."
+  (interactive)
+  (unless buffer (setq buffer (current-buffer)))
+  (let (entry)
+    (while (setq entry (rassq buffer hashcash-process-alist))
+      (accept-process-output (car entry)))))
+
+(defun hashcash-processes-running-p (buffer)
+  "Return non-nil if hashcash processes in BUFFER are still running."
+  (rassq buffer hashcash-process-alist))
+
+(defun hashcash-wait-or-cancel ()
+  "Ask user whether to wait for hashcash processes to finish."
+  (interactive)
+  (when (hashcash-processes-running-p (current-buffer))
+    (if (y-or-n-p 
+	  "Hashcash process(es) still running; wait for them to finish? ")
+	(hashcash-wait-async)
+      (hashcash-cancel-async))))
 
 ;;;###autoload
 (defun hashcash-verify-payment (token &optional resource amount)
@@ -182,9 +278,11 @@
 	  (t nil))))
 
 ;;;###autoload
-(defun mail-add-payment (&optional arg)
+(defun mail-add-payment (&optional arg async)
   "Add X-Payment: and X-Hashcash: headers with a hashcash payment
-for each recipient address.  Prefix arg sets default payment temporarily."
+for each recipient address.  Prefix arg sets default payment temporarily.
+Set ASYNC to t to start asynchronous calculation.  (See
+`mail-add-payment-async')."
   (interactive "P")
   (let ((hashcash-default-payment (if arg (prefix-numeric-value arg)
 				    hashcash-default-payment))
@@ -206,10 +304,21 @@
 	  (when (and hashcash-in-news ng)
 	    (setq addrlist (nconc addrlist (split-string ng ",[ \t\n]*")))))
 	(when addrlist
-	  (mapcar #'hashcash-insert-payment addrlist))))) ; mapc
+	  (mapcar (if async
+		      #'hashcash-insert-payment-async
+		    #'hashcash-insert-payment)
+		  addrlist))))) ; mapc
   t)
 
 ;;;###autoload
+(defun mail-add-payment-async (&optional arg)
+  "Add X-Payment: and X-Hashcash: headers with a hashcash payment
+for each recipient address.  Prefix arg sets default payment temporarily.
+Calculation is asynchronous."
+  (interactive "P")
+  (mail-add-payment arg t))
+
+;;;###autoload
 (defun mail-check-payment (&optional arg)
   "Look for a valid X-Payment: or X-Hashcash: header.
 Prefix arg sets default accept amount temporarily."




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-02 17:08 Asynchronous hashcash.el Magnus Henoch
@ 2004-11-02 21:11 ` Simon Josefsson
  2004-11-03 14:54   ` Magnus Henoch
  2004-11-14  1:33 ` Dan Christensen
  2004-12-01  7:09 ` Graham Murray
  2 siblings, 1 reply; 26+ messages in thread
From: Simon Josefsson @ 2004-11-02 21:11 UTC (permalink / raw)


Magnus Henoch <mange@freemail.hu> writes:

> What do you think about this?

I haven't tested it yet, but the general idea seem useful to me.  Have
you assigned copyright for your changes to the FSF?  I believe that
would be needed to add the patch to Gnus.




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-02 21:11 ` Simon Josefsson
@ 2004-11-03 14:54   ` Magnus Henoch
  2004-11-04 14:36     ` Simon Josefsson
  0 siblings, 1 reply; 26+ messages in thread
From: Magnus Henoch @ 2004-11-03 14:54 UTC (permalink / raw)


Simon Josefsson <jas@extundo.com> writes:

> I haven't tested it yet, but the general idea seem useful to me.  Have
> you assigned copyright for your changes to the FSF?  I believe that
> would be needed to add the patch to Gnus.

Yes, I've signed the papers and received confirmation.

Magnus




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-03 14:54   ` Magnus Henoch
@ 2004-11-04 14:36     ` Simon Josefsson
  2004-11-09 15:48       ` Magnus Henoch
  2004-11-09 15:56       ` Magnus Henoch
  0 siblings, 2 replies; 26+ messages in thread
From: Simon Josefsson @ 2004-11-04 14:36 UTC (permalink / raw)


Magnus Henoch <mange@freemail.hu> writes:

> Simon Josefsson <jas@extundo.com> writes:
>
>> I haven't tested it yet, but the general idea seem useful to me.  Have
>> you assigned copyright for your changes to the FSF?  I believe that
>> would be needed to add the patch to Gnus.
>
> Yes, I've signed the papers and received confirmation.

Great.  Hm.  Is your patch backwards compatible?  If so, I think we
should just install your patch.  Do you want to work on updating the
manual's node on hashcash too, to document the new interfaces?

Thanks.




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-04 14:36     ` Simon Josefsson
@ 2004-11-09 15:48       ` Magnus Henoch
  2004-11-09 15:56       ` Magnus Henoch
  1 sibling, 0 replies; 26+ messages in thread
From: Magnus Henoch @ 2004-11-09 15:48 UTC (permalink / raw)


Simon Josefsson <jas@extundo.com> writes:

> Great.  Hm.  Is your patch backwards compatible?  If so, I think we
> should just install your patch.  Do you want to work on updating the
> manual's node on hashcash too, to document the new interfaces?

It's backwards compatible, but while reading the manual I noticed the
variable message-generate-hashcash, with which my patch doesn't
cooperate.  That is, if you just set that variable, you get the old
synchronous behaviour.

I'll fix that, and update the manual as well.

Magnus




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-04 14:36     ` Simon Josefsson
  2004-11-09 15:48       ` Magnus Henoch
@ 2004-11-09 15:56       ` Magnus Henoch
  1 sibling, 0 replies; 26+ messages in thread
From: Magnus Henoch @ 2004-11-09 15:56 UTC (permalink / raw)


Simon Josefsson <jas@extundo.com> writes:

> Great.  Hm.  Is your patch backwards compatible?  If so, I think we
> should just install your patch.  Do you want to work on updating the
> manual's node on hashcash too, to document the new interfaces?

It's backwards compatible, but in the manual I noticed the variable
message-generate-hashcash, which I haven't changed to use the
asynchronous functions.  I'll fix that, and update the manual.

Magnus




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-02 17:08 Asynchronous hashcash.el Magnus Henoch
  2004-11-02 21:11 ` Simon Josefsson
@ 2004-11-14  1:33 ` Dan Christensen
  2004-11-14  1:59   ` Simon Josefsson
  2004-12-01  7:09 ` Graham Murray
  2 siblings, 1 reply; 26+ messages in thread
From: Dan Christensen @ 2004-11-14  1:33 UTC (permalink / raw)


Magnus Henoch <mange@freemail.hu> writes:

> This is my first attempt at making hashcash.el asynchronous.

Just wondering if anyone is planning to apply this patch to
Gnus cvs...  It looks like a great feature, and if I understand
correctly, doesn't change Gnus' behaviour unless the suggested
functions are added to hooks.

Dan



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14  1:33 ` Dan Christensen
@ 2004-11-14  1:59   ` Simon Josefsson
  2004-11-14 13:59     ` Magnus Henoch
  0 siblings, 1 reply; 26+ messages in thread
From: Simon Josefsson @ 2004-11-14  1:59 UTC (permalink / raw)


Dan Christensen <jdc@uwo.ca> writes:

> Magnus Henoch <mange@freemail.hu> writes:
>
>> This is my first attempt at making hashcash.el asynchronous.
>
> Just wondering if anyone is planning to apply this patch to
> Gnus cvs...  It looks like a great feature, and if I understand
> correctly, doesn't change Gnus' behaviour unless the suggested
> functions are added to hooks.

Yup.  Still waiting for the final version, though:

Magnus Henoch <mange@freemail.hu> writes:

> It's backwards compatible, but while reading the manual I noticed the
> variable message-generate-hashcash, with which my patch doesn't
> cooperate.  That is, if you just set that variable, you get the old
> synchronous behaviour.
>
> I'll fix that, and update the manual as well.

Magnus, do you have an updated version?  I'd be happy to install it.




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14  1:59   ` Simon Josefsson
@ 2004-11-14 13:59     ` Magnus Henoch
  2004-11-14 14:28       ` Simon Josefsson
  2004-11-15  3:26       ` Dan Christensen
  0 siblings, 2 replies; 26+ messages in thread
From: Magnus Henoch @ 2004-11-14 13:59 UTC (permalink / raw)


[-- Attachment #1: Type: text/plain, Size: 164 bytes --]

Simon Josefsson <jas@extundo.com> writes:

> Magnus, do you have an updated version?  I'd be happy to install it.

Yes, finally got around to do it... here it is:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: gnus-hashcash.patch --]
[-- Type: text/x-patch, Size: 9195 bytes --]

* looking for miles@gnu.org--gnu-2004/gnus--devo--0--patch-169 to compare with
* comparing to miles@gnu.org--gnu-2004/gnus--devo--0--patch-169
M  lisp/hashcash.el
M  lisp/message.el
M  texi/gnus.texi

* modified files

--- orig/lisp/hashcash.el
+++ mod/lisp/hashcash.el
@@ -30,15 +30,29 @@
 ;; Call mail-add-payment to add a hashcash payment to a mail message
 ;; in the current buffer.
 ;;
-;; To automatically add payments to all outgoing mail:
+;; Call mail-add-payment-async after writing the addresses but before
+;; writing the mail to start calculating the hashcash payment
+;; asynchronously.
+;;
+;; The easiest way to do this automatically for all outgoing mail
+;; is to set `message-generate-hashcash' to t.  If you want more
+;; control, try the following hooks.
+;;
+;; To automatically add payments to all outgoing mail when sending:
 ;;    (add-hook 'message-send-hook 'mail-add-payment)
+;;
+;; To start calculations automatically when addresses are prefilled:
+;;    (add-hook 'message-setup-hook 'mail-add-payment-async)
+;;
+;; To check whether calculations are done before sending:
+;;    (add-hook 'message-send-hook 'hashcash-wait-or-cancel)
 
 ;;; Code:
 
 (eval-and-compile
  (autoload 'executable-find "executable"))
 
-(defcustom hashcash-default-payment 10
+(defcustom hashcash-default-payment 20
   "*The default number of bits to pay to unknown users.
 If this is zero, no payment header will be generated.
 See `hashcash-payment-alist'."
@@ -51,7 +65,7 @@
 the value of hashcash payment to be made to that user.  STRING, if
 present, is the string to be hashed; if not present ADDR will be used.")
 
-(defcustom hashcash-default-accept-payment 10
+(defcustom hashcash-default-accept-payment 20
   "*The default minimum number of bits to accept on incoming payments."
   :type 'integer)
 
@@ -71,6 +85,9 @@
   "*Specifies whether or not hashcash payments should be made to newsgroups."
   :type 'boolean)
 
+(defvar hashcash-process-alist nil
+  "Alist of asynchronous hashcash processes and buffers.")
+
 (require 'mail-utils)
 
 (eval-and-compile
@@ -122,6 +139,19 @@
 	(hashcash-token-substring))
     (error "No `hashcash' binary found")))
 
+(defun hashcash-generate-payment-async (str val callback)
+  "Generate a hashcash payment by finding a VAL-bit collison on STR.
+Return immediately.  Call CALLBACK with process and result when ready."
+  (if (> val 0)
+      (let ((process (start-process "hashcash" nil
+				    hashcash-path "-m" "-q" "-b" (number-to-string val) str)))
+	(setq hashcash-process-alist (cons
+				      (cons process (current-buffer))
+				      hashcash-process-alist))
+	(set-process-filter process `(lambda (process output)
+				       (funcall ,callback process output))))
+    (funcall callback nil)))
+
 (defun hashcash-check-payment (token str val)
   "Check the validity of a hashcash payment."
   (if hashcash-path
@@ -151,17 +181,87 @@
 	((equal (aref token 6) ?:) 1.1)
 	(t (error "Unknown hashcash format version"))))
 
+(defun hashcash-already-paid-p (recipient)
+  "Check for hashcash token to RECIPIENT in current buffer."
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-headers-or-head)
+      (let ((token (message-fetch-field "x-hashcash")))
+	(and (stringp token)
+	     (string-match (regexp-quote recipient) token))))))
+
 ;;;###autoload
 (defun hashcash-insert-payment (arg)
   "Insert X-Payment and X-Hashcash headers with a payment for ARG"
   (interactive "sPay to: ")
-  (let ((pay (hashcash-generate-payment (hashcash-payment-to arg)
-					(hashcash-payment-required arg))))
-    (when pay
+  (unless (hashcash-already-paid-p arg)
+    (let ((pay (hashcash-generate-payment (hashcash-payment-to arg)
+					  (hashcash-payment-required arg))))
+      (when pay
+	;;      (insert-before-markers "X-Payment: hashcash "
+	;;			     (number-to-string (hashcash-version pay)) " "
+	;;			     pay "\n")
+	(insert-before-markers "X-Hashcash: " pay "\n")))))
+
+;;;###autoload
+(defun hashcash-insert-payment-async (arg)
+  "Insert X-Payment and X-Hashcash headers with a payment for ARG
+Only start calculation.  Results are inserted when ready."
+  (interactive "sPay to: ")
+  (unless (hashcash-already-paid-p arg)
+    (hashcash-generate-payment-async (hashcash-payment-to arg)
+				     (hashcash-payment-required arg)
+				     `(lambda (process payment)
+					(hashcash-insert-payment-async-2 ,(current-buffer) process payment)))))
+
+(defun hashcash-insert-payment-async-2 (buffer process pay)
+  (with-current-buffer buffer
+    (save-excursion
+      (save-restriction
+	(setq hashcash-process-alist (delq
+				      (assq process hashcash-process-alist)
+				      hashcash-process-alist))
+	(goto-char (point-min))
+	(search-forward mail-header-separator)
+	(beginning-of-line)
+	(when pay
 ;;      (insert-before-markers "X-Payment: hashcash "
 ;;			     (number-to-string (hashcash-version pay)) " "
 ;;			     pay "\n")
-      (insert-before-markers "X-Hashcash: " pay "\n"))))
+	  (insert-before-markers "X-Hashcash: " pay))))))
+
+(defun hashcash-cancel-async (&optional buffer)
+  "Delete any hashcash processes associated with BUFFER.
+BUFFER defaults to the current buffer."
+  (interactive)
+  (unless buffer (setq buffer (current-buffer)))
+  (let (entry)
+    (while (setq entry (rassq buffer hashcash-process-alist))
+      (delete-process (car entry))
+      (setq hashcash-process-alist
+	    (delq entry hashcash-process-alist)))))
+
+(defun hashcash-wait-async (&optional buffer)
+  "Wait for asynchronous hashcash processes in BUFFER to finish.
+BUFFER defaults to the current buffer."
+  (interactive)
+  (unless buffer (setq buffer (current-buffer)))
+  (let (entry)
+    (while (setq entry (rassq buffer hashcash-process-alist))
+      (accept-process-output (car entry)))))
+
+(defun hashcash-processes-running-p (buffer)
+  "Return non-nil if hashcash processes in BUFFER are still running."
+  (rassq buffer hashcash-process-alist))
+
+(defun hashcash-wait-or-cancel ()
+  "Ask user whether to wait for hashcash processes to finish."
+  (interactive)
+  (when (hashcash-processes-running-p (current-buffer))
+    (if (y-or-n-p 
+	  "Hashcash process(es) still running; wait for them to finish? ")
+	(hashcash-wait-async)
+      (hashcash-cancel-async))))
 
 ;;;###autoload
 (defun hashcash-verify-payment (token &optional resource amount)
@@ -182,9 +282,11 @@
 	  (t nil))))
 
 ;;;###autoload
-(defun mail-add-payment (&optional arg)
+(defun mail-add-payment (&optional arg async)
   "Add X-Payment: and X-Hashcash: headers with a hashcash payment
-for each recipient address.  Prefix arg sets default payment temporarily."
+for each recipient address.  Prefix arg sets default payment temporarily.
+Set ASYNC to t to start asynchronous calculation.  (See
+`mail-add-payment-async')."
   (interactive "P")
   (let ((hashcash-default-payment (if arg (prefix-numeric-value arg)
 				    hashcash-default-payment))
@@ -206,10 +308,21 @@
 	  (when (and hashcash-in-news ng)
 	    (setq addrlist (nconc addrlist (split-string ng ",[ \t\n]*")))))
 	(when addrlist
-	  (mapcar #'hashcash-insert-payment addrlist))))) ; mapc
+	  (mapcar (if async
+		      #'hashcash-insert-payment-async
+		    #'hashcash-insert-payment)
+		  addrlist))))) ; mapc
   t)
 
 ;;;###autoload
+(defun mail-add-payment-async (&optional arg)
+  "Add X-Payment: and X-Hashcash: headers with a hashcash payment
+for each recipient address.  Prefix arg sets default payment temporarily.
+Calculation is asynchronous."
+  (interactive "P")
+  (mail-add-payment arg t))
+
+;;;###autoload
 (defun mail-check-payment (&optional arg)
   "Look for a valid X-Payment: or X-Hashcash: header.
 Prefix arg sets default accept amount temporarily."


--- orig/lisp/message.el
+++ mod/lisp/message.el
@@ -3760,10 +3760,11 @@
 	    message-posting-charset))
 	 (headers message-required-mail-headers))
     (when message-generate-hashcash
-      (save-restriction
-	(message-narrow-to-headers)
-	(message-remove-header "X-Hashcash"))
       (message "Generating hashcash...")
+      ;; Wait for calculations already started to finish...
+      (hashcash-wait-async)
+      ;; ...and do calculations not already done.  mail-add-payment
+      ;; will leave existing X-Hashcash headers alone.
       (mail-add-payment)
       (message "Generating hashcash...done"))
     (save-restriction
@@ -5582,6 +5583,9 @@
     (run-hooks 'message-header-setup-hook))
   (set-buffer-modified-p nil)
   (setq buffer-undo-list nil)
+  (when message-generate-hashcash
+    ;; Generate hashcash headers for recipients already known
+    (mail-add-payment-async))
   (run-hooks 'message-setup-hook)
   (message-position-point)
   (undo-boundary))


--- orig/texi/gnus.texi
+++ mod/texi/gnus.texi
@@ -22509,8 +22509,8 @@
 @item hashcash-default-payment
 @vindex hashcash-default-payment
 This variable indicates the default number of bits the hash collision
-should consist of.  By default this is 10, which is a rather low
-value.  Suggested useful values include 17 to 29.
+should consist of.  By default this is 20.  Suggested useful values
+include 17 to 29.
 
 @item hashcash-payment-alist
 @vindex hashcash-payment-alist




[-- Attachment #3: Type: text/plain, Size: 1092 bytes --]


After I implemented message-generate-hashcash, it turned out that the
manual needed almost no changes.

Here is the changelog:

2004-11-14  Magnus Henoch  <mange@freemail.hu>

	* hashcash.el (hashcash-default-payment): Change default to 20
	(hashcash-default-accept-payment): Change default to 20
	(hashcash-process-alist): New variable
	(hashcash-generate-payment-async): Add
	(hashcash-already-paid-p): Add
	(hashcash-insert-payment): Don't generate payments twice
	(hashcash-insert-payment-async): Add
	(hashcash-insert-payment-async-2): Add
	(hashcash-cancel-async): Add
	(hashcash-wait-async): Add
	(hashcash-processes-running-p): Add
	(hashcash-wait-or-cancel): Add
	(mail-add-payment): New optional argument.  Conditionally start
	asynchronous calculation.
	(mail-add-payment-async): Add

	* message.el (message-send-mail): Wait for asynchronous hashcash
	results.  Don't clobber existing X-Hashcash headers.
	(message-setup-1): Call mail-add-payment-async when
	message-generate-hashcash is non-nil.

	* gnus.texi (Hashcash): New default value of
	hashcash-default-payment.
	
Magnus

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 13:59     ` Magnus Henoch
@ 2004-11-14 14:28       ` Simon Josefsson
  2004-11-14 16:42         ` Simon Josefsson
  2004-11-15  3:26       ` Dan Christensen
  1 sibling, 1 reply; 26+ messages in thread
From: Simon Josefsson @ 2004-11-14 14:28 UTC (permalink / raw)


Magnus Henoch <mange@freemail.hu> writes:

> Simon Josefsson <jas@extundo.com> writes:
>
>> Magnus, do you have an updated version?  I'd be happy to install it.
>
> Yes, finally got around to do it... here it is:

Applied, thanks.




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 14:28       ` Simon Josefsson
@ 2004-11-14 16:42         ` Simon Josefsson
  2004-11-14 20:43           ` Magnus Henoch
  2004-11-14 23:02           ` Adam Sjøgren
  0 siblings, 2 replies; 26+ messages in thread
From: Simon Josefsson @ 2004-11-14 16:42 UTC (permalink / raw)


Simon Josefsson <jas@extundo.com> writes:

> Magnus Henoch <mange@freemail.hu> writes:
>
>> Simon Josefsson <jas@extundo.com> writes:
>>
>>> Magnus, do you have an updated version?  I'd be happy to install it.
>>
>> Yes, finally got around to do it... here it is:
>
> Applied, thanks.

It works.  Way cool.  I'm increasing my default payment to 23 now..

Btw, I realize hashcash isn't used for news.  For the gmane.org news
server it make sense to use it.  gmane.org seem to insert a
'Original-To' header.  Should Gnus generate hashcash cookies to that
address?




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 16:42         ` Simon Josefsson
@ 2004-11-14 20:43           ` Magnus Henoch
  2004-11-14 23:14             ` Simon Josefsson
  2004-11-14 23:02           ` Adam Sjøgren
  1 sibling, 1 reply; 26+ messages in thread
From: Magnus Henoch @ 2004-11-14 20:43 UTC (permalink / raw)


Simon Josefsson <jas@extundo.com> writes:

> Btw, I realize hashcash isn't used for news.  For the gmane.org news
> server it make sense to use it.  gmane.org seem to insert a
> 'Original-To' header.  Should Gnus generate hashcash cookies to that
> address?

Original-To isn't always the right address, e.g. for a mail sent to a
person and CCed to a mailing list.  List-Post is probably the best
header, though not all groups have it.  For those groups, Gnus already
sort of has that function, as after you have run
gnus-mailing-list-insinuate it will post to the mailing list,
bypassing Gmane.  (or you can set `to-list' manually)

I would be quite happy if this were combined with mailing list
administrators changing posting policy from "subscribers only" to
"subscribers and hashcash users".  Time to patch Mailman, I guess,
so the changes trickle down to the stable version with time.[1]

Maybe Gmane could add a List-Post header for those lists that don't
already have it.

Magnus

[1] Googling for this yielded positive and negative opinions:
http://www.freelists.org/archives/hashcash/03-2004/msg00094.html
http://freedom.gmsociety.org/pipermail/aswan/2001-January/000033.html




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 16:42         ` Simon Josefsson
  2004-11-14 20:43           ` Magnus Henoch
@ 2004-11-14 23:02           ` Adam Sjøgren
  2004-11-14 23:35             ` Simon Josefsson
  1 sibling, 1 reply; 26+ messages in thread
From: Adam Sjøgren @ 2004-11-14 23:02 UTC (permalink / raw)


On Sun, 14 Nov 2004 17:42:37 +0100, Simon wrote:

> Btw, I realize hashcash isn't used for news.

That is configurable, right? At least I've got:

 (setq hashcash-in-news t)

in my .gnus since I started using hashcash (which was recently).


  Best regards,

-- 
 "More than anything, I won't try"                            Adam Sjøgren
                                                         asjo@koldfront.dk




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 20:43           ` Magnus Henoch
@ 2004-11-14 23:14             ` Simon Josefsson
  2004-11-16 20:13               ` Reiner Steib
  0 siblings, 1 reply; 26+ messages in thread
From: Simon Josefsson @ 2004-11-14 23:14 UTC (permalink / raw)


Magnus Henoch <mange@freemail.hu> writes:

> Simon Josefsson <jas@extundo.com> writes:
>
>> Btw, I realize hashcash isn't used for news.  For the gmane.org news
>> server it make sense to use it.  gmane.org seem to insert a
>> 'Original-To' header.  Should Gnus generate hashcash cookies to that
>> address?
>
> Original-To isn't always the right address, e.g. for a mail sent to a
> person and CCed to a mailing list.  List-Post is probably the best
> header, though not all groups have it.  For those groups, Gnus already
> sort of has that function, as after you have run
> gnus-mailing-list-insinuate it will post to the mailing list,
> bypassing Gmane.  (or you can set `to-list' manually)

But I may not be allowed to post to the list directly, so it might be
better to go through gmane.org for posting.

> Maybe Gmane could add a List-Post header for those lists that don't
> already have it.

There is a problem with cross posts though.




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 23:02           ` Adam Sjøgren
@ 2004-11-14 23:35             ` Simon Josefsson
  2004-11-15 14:57               ` Adam Sjøgren
  0 siblings, 1 reply; 26+ messages in thread
From: Simon Josefsson @ 2004-11-14 23:35 UTC (permalink / raw)


asjo@koldfront.dk (Adam Sjøgren) writes:

> On Sun, 14 Nov 2004 17:42:37 +0100, Simon wrote:
>
>> Btw, I realize hashcash isn't used for news.
>
> That is configurable, right? At least I've got:
>
>  (setq hashcash-in-news t)
>
> in my .gnus since I started using hashcash (which was recently).

Ah, thanks, now enabled.  However, the cookie generated for this
message doesn't really make sense, does it?

I guess what I meant was that hashcash cookies aren't generated
properly for mailing lists gateway:ed into news.  The resource to mint
for should be the mailing list address, not the news group name, I
think.  Or am I missing something?




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 13:59     ` Magnus Henoch
  2004-11-14 14:28       ` Simon Josefsson
@ 2004-11-15  3:26       ` Dan Christensen
  2004-11-15  9:39         ` Reiner Steib
  2004-11-15 12:35         ` Simon Josefsson
  1 sibling, 2 replies; 26+ messages in thread
From: Dan Christensen @ 2004-11-15  3:26 UTC (permalink / raw)


Thanks a lot for implementing this.  It makes hashcash much more
usable.  I have a few comments/questions:

1) If I call mail-add-payment-async while a previous async payment is
   being calculated, I end up with redundant hashcash headers and
   wasted cpu time.  Could this function keep a list of calculations
   in progress, and not start redundant calculations (same # of bits
   and same key)?

2) Could a key binding ("C-c C-h"?) and menu item be created for
   mail-add-payment-async?

3) I'd like async payments to be calculated even for recipients I add
   to the To/Cc lists, without manually having to call
   mail-add-payment-async.  Any suggestions on how best to do this?

4) I think the documentation could say a bit more about how this
   works.  E.g. the section:

     If you wish to generate hashcash for each message you send, you can
     customize `message-generate-hashcash' (*note Mail Headers:
     (message)Mail Headers.), as in:
  
       (setq message-generate-hashcash t)
  
     You will need to set up some additional variables as well:

   could instead read:

     If you wish to generate hashcash ..., as in:     [no change here]
  
       (setq message-generate-hashcash t)

     This will cause Gnus to start asynchronously calculating hashcash
     payments for addresses that it put in the To and Cc lines while
     you compose your message.  If you add other addresses manually, a
     payment will be generated for them when you send the message.  If
     you wish to have payments generated asynchronously for these
     messages, you can manually invoke mail-add-payment-async
     (keystroke/menu...)   [New paragraph.]
  
     You may wish to set up some additional variables as well:
     [Note change to this phrasing.]
    
Thanks again!

Dan



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-15  3:26       ` Dan Christensen
@ 2004-11-15  9:39         ` Reiner Steib
  2004-11-15 12:35         ` Simon Josefsson
  1 sibling, 0 replies; 26+ messages in thread
From: Reiner Steib @ 2004-11-15  9:39 UTC (permalink / raw)


On Mon, Nov 15 2004, Dan Christensen wrote:

> 2) Could a key binding ("C-c C-h"?) and menu item be created for
>    mail-add-payment-async?

`C-c C-h' (aka `C-h f1') is supposed to show all key bindings starting
with `C-c'.

Bye, Reiner.
-- 
       ,,,
      (o o)
---ooO-(_)-Ooo---  |  PGP key available  |  http://rsteib.home.pages.de/




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-15  3:26       ` Dan Christensen
  2004-11-15  9:39         ` Reiner Steib
@ 2004-11-15 12:35         ` Simon Josefsson
  2004-11-15 14:03           ` Kai Grossjohann
  1 sibling, 1 reply; 26+ messages in thread
From: Simon Josefsson @ 2004-11-15 12:35 UTC (permalink / raw)


Dan Christensen <jdc@uwo.ca> writes:

> 2) Could a key binding ("C-c C-h"?) and menu item be created for
>    mail-add-payment-async?

C-c h?  C-c C-h is already taken.  I do wonder why C-h k for C-c C-h
says 'undefined' in message buffers, though.

Otherwise I agree with the rest of your comments.




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-15 12:35         ` Simon Josefsson
@ 2004-11-15 14:03           ` Kai Grossjohann
  0 siblings, 0 replies; 26+ messages in thread
From: Kai Grossjohann @ 2004-11-15 14:03 UTC (permalink / raw)


Simon Josefsson <jas@extundo.com> writes:

> Dan Christensen <jdc@uwo.ca> writes:
>
>> 2) Could a key binding ("C-c C-h"?) and menu item be created for
>>    mail-add-payment-async?
>
> C-c h?

This is reserved for users.

> C-c C-h is already taken.  I do wonder why C-h k for C-c C-h
> says 'undefined' in message buffers, though.

Because C-h is special.  It works after every prefix key.  Try C-x C-h.

Kai



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 23:35             ` Simon Josefsson
@ 2004-11-15 14:57               ` Adam Sjøgren
  2004-11-15 17:17                 ` Simon Josefsson
  0 siblings, 1 reply; 26+ messages in thread
From: Adam Sjøgren @ 2004-11-15 14:57 UTC (permalink / raw)


On Mon, 15 Nov 2004 00:35:16 +0100, Simon wrote:

> asjo@koldfront.dk (Adam Sjøgren) writes:

>> (setq hashcash-in-news t)

> Ah, thanks, now enabled. However, the cookie generated for this
> message doesn't really make sense, does it?

> I guess what I meant was that hashcash cookies aren't generated
> properly for mailing lists gateway:ed into news. The resource to
> mint for should be the mailing list address, not the news group
> name, I think. Or am I missing something?

I won't pretend to be trying to understand how these things fit
together the best... Perhaps gmane (c|w)ould use the hashcash-token
with the newsgroup-name as a clue as to whether a posting, being
posted via gmane, is spam or not.

Perhaps that doesn't make sense at all.

I'll stop not being of much help now :-)


  Best regards,

   Adam

-- 
 "More than anything, I won't try"                            Adam Sjøgren
                                                         asjo@koldfront.dk




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-15 14:57               ` Adam Sjøgren
@ 2004-11-15 17:17                 ` Simon Josefsson
  0 siblings, 0 replies; 26+ messages in thread
From: Simon Josefsson @ 2004-11-15 17:17 UTC (permalink / raw)


asjo@koldfront.dk (Adam Sjøgren) writes:

> On Mon, 15 Nov 2004 00:35:16 +0100, Simon wrote:
>
>> asjo@koldfront.dk (Adam Sjøgren) writes:
>
>>> (setq hashcash-in-news t)
>
>> Ah, thanks, now enabled. However, the cookie generated for this
>> message doesn't really make sense, does it?
>
>> I guess what I meant was that hashcash cookies aren't generated
>> properly for mailing lists gateway:ed into news. The resource to
>> mint for should be the mailing list address, not the news group
>> name, I think. Or am I missing something?
>
> I won't pretend to be trying to understand how these things fit
> together the best... Perhaps gmane (c|w)ould use the hashcash-token
> with the newsgroup-name as a clue as to whether a posting, being
> posted via gmane, is spam or not.

Ah, that's a possibility.  But typically hashcash on mailing lists are
minted to the mailing list address, so that 1) the mailing list
software itself can look at the hash coin, and 2) members of the
mailing list can also verify that the coin is minted for the mailing
list address.

So while gmane could use a hash coin for the news group name, gmane
could equally well use a hash coin for the mailing list address, which
would then also be usable in 1) and 2) above.

The to-list solution do work, but it makes posts go via mail instead
of via news.  Original-To might be unreliable.

Hm. What if gmane added a header with the e-mail address of all
mailing lists corresponding to the Newsgroups: header?  E.g.:

Newsgroups: gmane.emacs.gnus.general, gmane.emacs.devel
X-List-To: ding@gnus.org, emacs-devel@gnu.org

Then Gnus could mint a coin for those two lists, and everything will
work.

Perhaps there are simpler solutions... ideas welcome.




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-14 23:14             ` Simon Josefsson
@ 2004-11-16 20:13               ` Reiner Steib
  2004-11-16 20:50                 ` Simon Josefsson
  0 siblings, 1 reply; 26+ messages in thread
From: Reiner Steib @ 2004-11-16 20:13 UTC (permalink / raw)


On Mon, Nov 15 2004, Simon Josefsson wrote:

> But I may not be allowed to post to the list directly, so it might be
> better to go through gmane.org for posting.

Gmane isn't supposed to bypass the list owner's policy.  For
subcribers-only lists, you still need to subscribe even when posting
thru Gmane.

>> Maybe Gmane could add a List-Post header for those lists that don't
>> already have it.
>
> There is a problem with cross posts though.

AFAIK you cannot cross-post to two Gmane groups.  You have to send the
message to both list by mail (To/Cc).  But Gmane will add "Newsgroups:
foo,bar" headers when receiving the message back from the list(s).

Bye, Reiner.
-- 
       ,,,
      (o o)
---ooO-(_)-Ooo---  |  PGP key available  |  http://rsteib.home.pages.de/




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-16 20:13               ` Reiner Steib
@ 2004-11-16 20:50                 ` Simon Josefsson
  0 siblings, 0 replies; 26+ messages in thread
From: Simon Josefsson @ 2004-11-16 20:50 UTC (permalink / raw)


Reiner Steib <reinersteib+gmane@imap.cc> writes:

>>> Maybe Gmane could add a List-Post header for those lists that don't
>>> already have it.
>>
>> There is a problem with cross posts though.
>
> AFAIK you cannot cross-post to two Gmane groups.  You have to send the
> message to both list by mail (To/Cc).

Shouldn't gmane reject when I attempt to do so?  I recall (cross-)
posting several messages to both gmane.emacs.devel and
gmane.emacs.gnus.general recently.  Were they only delivered to one
list?

I have noticed that if I set a Followup-To when I cross-post on
gmane.org, I'm not permitted to post at all, there is some confusing
error message like "You are not entitled to post" or something.  So I
never specify Followup-To, and the post is accepted.




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-11-02 17:08 Asynchronous hashcash.el Magnus Henoch
  2004-11-02 21:11 ` Simon Josefsson
  2004-11-14  1:33 ` Dan Christensen
@ 2004-12-01  7:09 ` Graham Murray
  2004-12-01 10:23   ` Uwe Brauer
  2 siblings, 1 reply; 26+ messages in thread
From: Graham Murray @ 2004-12-01  7:09 UTC (permalink / raw)


Magnus Henoch <mange@freemail.hu> writes:

> Recommended hooks:
>
> (add-hook 'message-setup-hook 'mail-add-payment-async)
> (add-hook 'message-send-hook 'hashcash-wait-or-cancel)

I have set these hooks, but when composing mail (like this one),
multiple X-Hashcash lines are added as I am composing the message. The
longer I leave the message buffer open the more lines it generates.



^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-12-01  7:09 ` Graham Murray
@ 2004-12-01 10:23   ` Uwe Brauer
  2004-12-01 13:13     ` Simon Josefsson
  0 siblings, 1 reply; 26+ messages in thread
From: Uwe Brauer @ 2004-12-01 10:23 UTC (permalink / raw)


>>>>> "Graham" == Graham Murray <graham@gmurray.org.uk> writes:

    Graham> Magnus Henoch <mange@freemail.hu> writes:
    >> Recommended hooks:
    >> 
    >> (add-hook 'message-setup-hook 'mail-add-payment-async)
    >> (add-hook 'message-send-hook 'hashcash-wait-or-cancel)

    Graham> I have set these hooks, but when composing mail (like this one),
    Graham> multiple X-Hashcash lines are added as I am composing the message. The
    Graham> longer I leave the message buffer open the more lines it generates.


I just use 
(add-hook 'message-setup-hook 'mail-add-payment-async)

and have not found any problems so far.

Uwe Brauer 




^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: Asynchronous hashcash.el
  2004-12-01 10:23   ` Uwe Brauer
@ 2004-12-01 13:13     ` Simon Josefsson
  0 siblings, 0 replies; 26+ messages in thread
From: Simon Josefsson @ 2004-12-01 13:13 UTC (permalink / raw)


Uwe Brauer <oub@mat.ucm.es> writes:

>>>>>> "Graham" == Graham Murray <graham@gmurray.org.uk> writes:
>
>     Graham> Magnus Henoch <mange@freemail.hu> writes:
>     >> Recommended hooks:
>     >> 
>     >> (add-hook 'message-setup-hook 'mail-add-payment-async)
>     >> (add-hook 'message-send-hook 'hashcash-wait-or-cancel)
>
>     Graham> I have set these hooks, but when composing mail (like this one),
>     Graham> multiple X-Hashcash lines are added as I am composing the message. The
>     Graham> longer I leave the message buffer open the more lines it generates.
>
>
> I just use 
> (add-hook 'message-setup-hook 'mail-add-payment-async)
>
> and have not found any problems so far.

The simplest setting would be:

(setq message-generate-hashcash t)

It would be nice if the code removed X-hashcash lines for To/CC
recipients that I remove manually.




^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2004-12-01 13:13 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-02 17:08 Asynchronous hashcash.el Magnus Henoch
2004-11-02 21:11 ` Simon Josefsson
2004-11-03 14:54   ` Magnus Henoch
2004-11-04 14:36     ` Simon Josefsson
2004-11-09 15:48       ` Magnus Henoch
2004-11-09 15:56       ` Magnus Henoch
2004-11-14  1:33 ` Dan Christensen
2004-11-14  1:59   ` Simon Josefsson
2004-11-14 13:59     ` Magnus Henoch
2004-11-14 14:28       ` Simon Josefsson
2004-11-14 16:42         ` Simon Josefsson
2004-11-14 20:43           ` Magnus Henoch
2004-11-14 23:14             ` Simon Josefsson
2004-11-16 20:13               ` Reiner Steib
2004-11-16 20:50                 ` Simon Josefsson
2004-11-14 23:02           ` Adam Sjøgren
2004-11-14 23:35             ` Simon Josefsson
2004-11-15 14:57               ` Adam Sjøgren
2004-11-15 17:17                 ` Simon Josefsson
2004-11-15  3:26       ` Dan Christensen
2004-11-15  9:39         ` Reiner Steib
2004-11-15 12:35         ` Simon Josefsson
2004-11-15 14:03           ` Kai Grossjohann
2004-12-01  7:09 ` Graham Murray
2004-12-01 10:23   ` Uwe Brauer
2004-12-01 13:13     ` Simon Josefsson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).