PROGS = add lookup gpgwww onak
 OBJS = armor.o parsekey.o keydb_$(DBTYPE).o merge.o keyid.o md5.o sha.o \
-       getcgi.o keyindex.o mem.o stats.o ll.o hash.o onak-conf.o charfuncs.o
+       getcgi.o keyindex.o mem.o stats.o ll.o hash.o onak-conf.o charfuncs.o \
+       sendsync.o
 SRCS = armor.c parsekey.c merge.c keyid.c md5.c sha.c main.c getcgi.c stats.c \
        keyindex.c mem.c lookup.c add.c keydb_$(DBTYPE).c ll.c hash.c \
-       gpgwww.c onak-conf.c charfuncs.c
+       gpgwww.c onak-conf.c charfuncs.c sendsync.c
 
 all: $(PROGS) testparse maxpath
 
                charfuncs.o $(LIBS)
 
 add: add.o getcgi.o armor.o parsekey.o keydb_$(DBTYPE).o keyid.o sha.o mem.o \
-               keyindex.o ll.o hash.o merge.o onak-conf.o charfuncs.o
+       keyindex.o ll.o hash.o merge.o onak-conf.o charfuncs.o sendsync.o
        $(CC) -o add add.o getcgi.o armor.o parsekey.o keydb_$(DBTYPE).o \
                keyid.o sha.o mem.o keyindex.o ll.o hash.o merge.o onak-conf.o \
-               charfuncs.o $(LIBS)
+               charfuncs.o sendsync.o $(LIBS)
 
 onak: onak.o merge.o keyid.o sha.o armor.o parsekey.o ll.o charfuncs.o \
                keydb_$(DBTYPE).o mem.o keyindex.o hash.o getcgi.o onak-conf.o
 
 #include "getcgi.h"
 #include "keydb.h"
 #include "keystructs.h"
+#include "mem.h"
+#include "merge.h"
 #include "onak-conf.h"
 #include "parsekey.h"
-#include "merge.h"
+#include "sendsync.h"
 
 int main(int argc, char *argv[])
 {
                        initdb();
                        printf("Got %d new keys.\n",
                                        update_keys(&keys, false));
+                       if (keys != NULL) {
+                               sendkeysync(keys);
+                               free_publickey(keys);
+                               keys = NULL;
+                       }
                        cleanupdb();
                } else {
                        puts("No OpenPGP packets found in input.");
 
                                } else {
                                        prev->next = curkey->next;
                                        prev = curkey->next;
+                                       curkey->next = NULL;
+                                       free_publickey(curkey);
                                }
                        } else {
                                prev = curkey;
                                if (verbose) {
-                                       fprintf(stderr, "Merged key; storing updated key.\n");
+                                       fprintf(stderr,
+                                       "Merged key; storing updated key.\n");
                                }
                                store_key(oldkey, intrans, true);
                        }
                        oldkey = NULL;
                } else {
                        if (verbose) {
-                               fprintf(stderr, "Storing completely new key.\n");
+                               fprintf(stderr,
+                                       "Storing completely new key.\n");
                        }
                        store_key(curkey, intrans, false);
                        newkeys++;
 
        my (@errors, @mergedata);
 
        open3(\*MERGEIN, \*MERGEOUT, \*MERGEERR,
-               "/home/noodles/onak-0.0.3/onak", "add");
+               "/home/noodles/onak-0.0.3/onak", "-u", "add");
 
        print MERGEIN @data;
        close MERGEIN;
        @mergedata = <MERGEOUT>;
 
        open (LOG, ">>/home/noodles/onak-0.0.3/keyadd.log");
-       print LOG @errors;
+       print LOG "[".localtime(time)."] ", @errors;
        close LOG;
 
        return @mergedata;
 }
 
-my ($inheader, %syncsites, $subject, $from, $replyto, @body, @syncmail);
+my ($inheader, %seenby, $subject, $from, $replyto, @body, @syncmail);
 
 $inheader = 1;
 $subject = "";
                if (/^Subject:\s*(.*)\s*$/i) {
                        $subject = $1;
                } elsif (/^X-KeyServer-Sent:\s*(.*)\s*$/i) {
-                       $syncsites{$1} = 1;
+                       $seenby{$1} = 1;
                } elsif (/^From:\s*(.*)\s*$/i) {
                        $from = $1;
                } elsif (/^Reply-To:\s*(.*)\s*$/i) {
 # LAST <days>
 
 if ($subject =~ /^INCREMENTAL$/i) {
-       submitupdate(@body);
+       my $site;
+       my $count;
+       my $i;
+       my @newupdate = submitupdate(@body);
+
+       $count = 0;
+       foreach $i (@{$config{'syncsites'}}) {
+               if (! defined($seenby{$i})) {
+                       $count++;
+               }
+       }
+
+       open (LOG, ">>/home/noodles/logs/keyadd.log");
+       print LOG "[".localtime(time)."] Syncing with $count sites.\n";
+       close LOG;
+
+       if ($newupdate[0] eq '') {
+               open (LOG, ">>/home/noodles/logs/keyadd.log");
+               print LOG "[".localtime(time)."] Nothing to sync.\n";
+               close LOG;
+               $count = 0;
+       }
+
+       if ($count > 0) {
+               open(MAIL, "|$config{mta}");
+               print MAIL "From: $config{adminemail}\n";
+               print MAIL "To: ";
+               foreach $i (@{$config{'syncsites'}}) {
+                       if (! defined($seenby{$i})) {
+                               print MAIL "$i";
+                               $count--;
+                               if ($count > 0) {
+                                       print MAIL ", ";
+                               }
+                       }
+               }
+               print MAIL "\n";
+               print MAIL "Subject: incremental\n";
+               foreach $site (keys %seenby) {
+                       print MAIL "X-KeyServer-Sent: $site\n";
+               }
+               print MAIL "X-KeyServer-Sent: $config{thissite}\n";
+               print MAIL "Precedence: list\n";
+               print MAIL "MIME-Version: 1.0\n";
+               print MAIL "Content-Type: application/pgp-keys\n";
+               print MAIL "\n";
+               print @newupdate;
+               close MAIL;
+       }
 }
 
        uint64_t                         keyid = 0;
        bool                             ishex = false;
        bool                             verbose = false;
+       bool                             update = false;
        bool                             binary = false;
        int                              optchar;
 
 
-       while ((optchar = getopt(argc, argv, "bv")) != -1 ) {
+       while ((optchar = getopt(argc, argv, "buv")) != -1 ) {
                switch (optchar) {
                case 'b': 
                        binary = true;
                        break;
+               case 'u': 
+                       update = true;
+                       break;
                case 'v': 
                        verbose = true;
                        break;
                        initdb();
                        fprintf(stderr, "Got %d new keys.\n",
                                        update_keys(&keys, verbose));
+                       if (keys != NULL && update) {
+                               flatten_publickey(keys,
+                                       &packets,
+                                       &list_end);
+                               armor_openpgp_stream(stdout_putchar,
+                                       NULL,
+                                       packets);
+                               free_packet_list(packets);
+                               packets = NULL;
+                       }
                        cleanupdb();
                } else {
                        rc = 1;
                                armor_openpgp_stream(stdout_putchar,
                                                NULL,
                                                packets);
+                               free_packet_list(packets);
+                               packets = NULL;
                        } else {
                                puts("Key not found");
                        }
 
--- /dev/null
+/*
+ * sendsync.c - Routines to send a key sync mail.
+ *
+ * Jonathan McDowell <noodles@earth.li>
+ *
+ * Copyright 1999, 2002 Project Purple
+*/
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "armor.h"
+#include "keystructs.h"
+#include "ll.h"
+#include "mem.h"
+#include "onak-conf.h"
+#include "parsekey.h"
+#include "sendsync.h"
+
+int fd_putchar(void *ctx, size_t count, unsigned char *c)
+{
+       int i;
+
+       for (i = 0; i < count; i++) {
+               fputc(c[i], ctx);
+       }
+       return 0;
+}
+
+/**
+ *     sendkeysync - Send a key sync mail to our peers.
+ *     keys: The list of keys to send.
+ *
+ *     Takes a list of keys and sends out a keysync mail to all our peers.
+ */
+int sendkeysync(struct openpgp_publickey *keys)
+{
+       FILE                       *fd = NULL;
+       struct ll                  *cursite = NULL;
+       struct openpgp_packet_list *packets = NULL;
+       struct openpgp_packet_list *list_end = NULL;
+
+       if (config.syncsites != NULL &&
+                       (fd=popen("sendmail -t", "w")) != NULL) {
+               fprintf(fd, "From: %s\n", config.adminemail);
+
+               fprintf(fd, "To: ");
+               for (cursite = config.syncsites; cursite != NULL;
+                               cursite = cursite->next) {
+                       fprintf(fd, "%s", (char *) cursite->object);
+                       if (cursite->next != NULL) {
+                               fprintf(fd, ", ");
+                       }
+               }
+               fprintf(fd, "\n");
+
+               fprintf(fd, "Subject: incremental\n");
+               fprintf(fd, "X-Keyserver-Sent: %s\n", config.thissite);
+               fprintf(fd, "Precedence: list\n");
+               fprintf(fd, "MIME-Version: 1.0\n");
+               fprintf(fd, "Content-Type: application/pgp-keys\n\n");
+
+               flatten_publickey(keys,
+                               &packets,
+                               &list_end);
+               armor_openpgp_stream(fd_putchar,
+                               fd,
+                               packets);
+               free_packet_list(packets);
+               packets = NULL;
+
+               pclose(fd);
+       } else return 0;
+
+       return 1;
+}
 
--- /dev/null
+/*
+ * sendsync.c - Routines to send a key sync mail.
+ *
+ * Jonathan McDowell <noodles@earth.li>
+ *
+ * Copyright 1999, 2002 Project Purple
+*/
+
+#ifndef __SENDSYNC_H_
+#define __SENDSYNC_H_
+
+#include "keystructs.h"
+
+/**
+ *     sendkeysync - Send a key sync mail to our peers.
+ *     keys: The list of keys to send.
+ *
+ *     Takes a list of keys and sends out a keysync mail to all our peers.
+ */
+int sendkeysync(struct openpgp_publickey *keys);
+
+#endif /* __SENDSYNC_H */