/** A running CRC24 of the data we've seen. */
        long crc24;
        /** The function to output a character. */
-       int (*putchar_func)(void *ctx, size_t count, void *c);
+       size_t (*putchar_func)(void *ctx, size_t count, void *c);
        /** Context for putchar_func. */
        void *ctx;
 };
 }
 
 
-static int armor_putchar(void *ctx, size_t count, void *c)
+static size_t armor_putchar(void *ctx, size_t count, void *c)
 {
        int i;
 
        for (i = 0; i < count; i++) {
                armor_putchar_int(ctx, ((char *) c)[i]);
        }
-       
-       return 0;
+
+       return count;
 }
 
 /**
        /** A running CRC24 of the data we've seen. */
        long crc24;
        /** The function to get the next character. */
-       int (*getchar_func)(void *ctx, size_t count, void *c);
+       size_t (*getchar_func)(void *ctx, size_t count, void *c);
        /** Context for getchar_func. */
        void *ctx;
 };
        return (tmpc == 64);
 }
 
-static int dearmor_getchar_c(void *ctx, size_t count, void *c)
+static size_t dearmor_getchar_c(void *ctx, size_t count, void *c)
 {
        int i, rc = 0;
 
                rc = dearmor_getchar(ctx, &((unsigned char *) c)[i]);
        }
 
-       return rc;
+       return (rc == 0) ? i : 0;
 }
 
-int armor_openpgp_stream(int (*putchar_func)(void *ctx, size_t count,
+int armor_openpgp_stream(size_t (*putchar_func)(void *ctx, size_t count,
                                                void *c),
                                void *ctx,
                                struct openpgp_packet_list *packets)
        return 0;
 }
 
-int dearmor_openpgp_stream(int (*getchar_func)(void *ctx, size_t count,
+int dearmor_openpgp_stream(size_t (*getchar_func)(void *ctx, size_t count,
                                                void *c),
                                void *ctx,
                                struct openpgp_packet_list **packets)
         * with :s in them, then a blank line, then the data.
         */
        state = 1;
-       while (state != 4 && !getchar_func(ctx, 1, &curchar)) {
+       while (state != 4 && getchar_func(ctx, 1, &curchar) == 1) {
                switch (state) {
                        case 0:
                                if (curchar == '\n') {
 
  * This function ASCII armors a list of OpenPGP packets and outputs it
  * using putchar_func.
  */
-int armor_openpgp_stream(int (*putchar_func)(void *ctx, size_t count,
+int armor_openpgp_stream(size_t (*putchar_func)(void *ctx, size_t count,
                                                void *c),
                                void *ctx,
                                struct openpgp_packet_list *packets);
  * armored OpenPGP stream and outputs the data as a linked list of
  * packets.
  */
-int dearmor_openpgp_stream(int (*getchar_func)(void *ctx, size_t count,
+int dearmor_openpgp_stream(size_t (*getchar_func)(void *ctx, size_t count,
                                        void *c),
                                void *ctx,
                                struct openpgp_packet_list **packets);
 
        }
 
        hashes = (uint8_t **) unmarshal_array(buffer_fetchchar, &cgipostbuf,
-                       (void * (*)(int (*)(void *, size_t,  void *), void *))
+                       (void * (*)(size_t (*)(void *, size_t,  void *), void *))
                                unmarshal_skshash, &count);
 
        free(cgipostbuf.buffer);
 
        puts("Content-Type: pgp/keys\n");
        marshal_array(stdout_putchar, NULL,
-                       (void (*)(int (*)(void *, size_t,  void *),
+                       (void (*)(size_t (*)(void *, size_t,  void *),
                                        void *, const void *))
                                marshal_publickey, (void **) keys, found);
        printf("\n");
 
  *     @count: The number of characters to get from the buffer.
  *     @c: Where to put the characters retrieved.
  */
-int buffer_fetchchar(void *ctx, size_t count, void *c)
+size_t buffer_fetchchar(void *ctx, size_t count, void *c)
 {
        struct buffer_ctx *buf = NULL;
        
        buf = (struct buffer_ctx *) ctx;
 
        if (buf->offset + count > buf->size) {
-               return 1;
+               count = buf->size - buf->offset;
        }
-       
+
        memcpy(c, &buf->buffer[buf->offset], count);
        buf->offset += count;
 
-       return 0;
+       return count;
 }
 
 /*
  *     fill it then we double the size of the current buffer and then add the
  *     rest.
  */
-int buffer_putchar(void *ctx, size_t count, void *c)
+size_t buffer_putchar(void *ctx, size_t count, void *c)
 {
        struct buffer_ctx *buf = NULL;
        size_t newsize = 0;
        memcpy(&buf->buffer[buf->offset], c, count);
        buf->offset += count;
        
-       return 1;
+       return count;
 }
 
 /*
  * Fetches a char from a file.
  */
-int file_fetchchar(void *fd, size_t count, void *c)
+size_t file_fetchchar(void *fd, size_t count, void *c)
 {
-       return !(read( *(int *) fd, c, count));
+       ssize_t ret = read( *(int *) fd, c, count);
+
+       return (ret > 0) ? ret : 0;
 }
 
 /*
  * Puts a char to a file.
  */
-int file_putchar(void *fd, size_t count, void *c)
+size_t file_putchar(void *fd, size_t count, void *c)
 {
-       return !(write( *(int *) fd, c, count));
+       size_t ret = write( *(int *) fd, c, count);
+
+       return (ret > 0) ? ret : 0;
 }
 
 /*
  * Gets a char from stdin.
  */
-int stdin_getchar(__unused void *ctx, size_t count, void *c)
+size_t stdin_getchar(__unused void *ctx, size_t count, void *c)
 {
-       return (fread(c, 1, count, stdin) != count);
+       return fread(c, 1, count, stdin);
 }
 
 /*
  * Puts a char to stdout.
  */
-int stdout_putchar(__unused void *ctx, size_t count, void *c)
+size_t stdout_putchar(__unused void *ctx, size_t count, void *c)
 {
-       return (fwrite(c, 1, count, stdout) != count);
+       return fwrite(c, 1, count, stdout);
 }
 
  * @param count The number of characters to get from the buffer.
  * @param c Where to put the characters retrieved.
  */
-int buffer_fetchchar(void *ctx, size_t count, void *c);
+size_t buffer_fetchchar(void *ctx, size_t count, void *c);
 
 /**
  * @brief Puts a char to a buffer.
  * fill it then we double the size of the current buffer and then add the
  * rest.
  */
-int buffer_putchar(void *ctx, size_t count, void *c);
+size_t buffer_putchar(void *ctx, size_t count, void *c);
 
 /**
  * @brief Fetches a char from a file.
  */
-int file_fetchchar(void *fd, size_t count, void *c);
+size_t file_fetchchar(void *fd, size_t count, void *c);
 
 /**
  * @brief Puts a char to a file.
  */
-int file_putchar(void *fd, size_t count, void *c);
+size_t file_putchar(void *fd, size_t count, void *c);
 
 /**
  * @brief Gets a char from stdin.
  */
-int stdin_getchar(void *ctx, size_t count, void *c);
+size_t stdin_getchar(void *ctx, size_t count, void *c);
 
 /**
  * @brief Puts a char to stdout.
  */
-int stdout_putchar(void *ctx, size_t count, void *c);
+size_t stdout_putchar(void *ctx, size_t count, void *c);
 
 #endif /* __CHARFUNCS_H__ */
 
 /**
  *     keydb_fetchchar - Fetches a char from a file.
  */
-static int keydb_fetchchar(void *_ctx, size_t count, void *c)
+static size_t keydb_fetchchar(void *_ctx, size_t count, void *c)
 {
+       int ret;
+
        struct pg_fc_ctx *ctx = (struct pg_fc_ctx *) _ctx;
 
-       return (!lo_read(ctx->dbconn, ctx->fd, (char *) c, count));
+       ret = lo_read(ctx->dbconn, ctx->fd, (char *) c, count);
+
+       return (ret > 0) ? ret : 0;
 }
 
 /**
  *     keydb_putchar - Puts a char to a file.
  */
-static int keydb_putchar(void *_ctx, size_t count, void *c)
+static size_t keydb_putchar(void *_ctx, size_t count, void *c)
 {
        struct pg_fc_ctx *ctx = (struct pg_fc_ctx *) _ctx;
+       int ret;
+
+       ret = lo_write(ctx->dbconn, ctx->fd, (char *) c, count);
 
-       return !(lo_write(ctx->dbconn, ctx->fd, (char *) c, count));
+       return (ret > 0) ? ret : 0;
 }
 
 /**
 
 #include "mem.h"
 #include "parsekey.h"
 
-void marshal_publickey(int (*putchar_func)(void *ctx, size_t count,
+void marshal_publickey(size_t (*putchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
                                const struct openpgp_publickey *key)
        free_packet_list(packets);
 }
 
-void marshal_skshash(int (*putchar_func)(void *ctx, size_t count,
+void marshal_skshash(size_t (*putchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
                                const struct skshash *hash)
        putchar_func(ctx, sizeof(hash->hash), (void *) hash->hash);
 }
 
-struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count,
+struct skshash *unmarshal_skshash(size_t (*getchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx)
 {
        uint32_t len;
        struct skshash *hash;
 
-       if (getchar_func(ctx, sizeof(len), &len)) {
+       if (getchar_func(ctx, sizeof(len), &len) != sizeof(len)) {
                return NULL;
        }
        len = ntohl(len);
                return NULL;
        }
        hash = calloc(sizeof(struct skshash), 1);
-       if (getchar_func(ctx, len, hash->hash)) {
+       if (getchar_func(ctx, len, hash->hash) != len) {
                free(hash);
                return NULL;
        }
        return hash;
 }
 
-void marshal_string(int (*putchar_func)(void *ctx, size_t count,
+void marshal_string(size_t (*putchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
                                const char *string)
        putchar_func(ctx, len, &string);
 }
 
-char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count,
+char *unmarshal_string(size_t (*getchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx)
 {
        uint32_t len;
        char *string;
 
-       if (getchar_func(ctx, sizeof(len), &len)) {
+       if (getchar_func(ctx, sizeof(len), &len) != sizeof(len)) {
                return NULL;
        }
        len = ntohl(len);
        string = malloc(len + 1);
-       if (getchar_func(ctx, len, string)) {
+       if (getchar_func(ctx, len, string) != len) {
                free(string);
                return NULL;
        }
        return string;
 }
 
-void marshal_array(int (*putchar_func)(void *ctx, size_t count,
+void marshal_array(size_t (*putchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
-                               void (*marshal_func)(int
+                               void (*marshal_func)(size_t
                                        (*putchar_func)(void *ctx,
                                                size_t count, void *c),
                                        void *ctx, const void *item),
        }
 }
 
-void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count,
+void **unmarshal_array(size_t (*getchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
-                               void *(*unmarshal_func)(int
+                               void *(*unmarshal_func)(size_t
                                        (*getchar_func)(void *ctx,
                                                size_t count, void *c),
                                        void *ctx),
        void **array;
        int i;
 
-       if (getchar_func(ctx, sizeof(len), &len)) {
+       if (getchar_func(ctx, sizeof(len), &len) != sizeof(len)) {
                return NULL;
        }
        *size = ntohl(len);
 
  *     a 32 bit size of the forthcoming data in network byte order and
  *     then the flattened byte representation of the key.
  */
-void marshal_publickey(int (*putchar_func)(void *ctx, size_t count,
+void marshal_publickey(size_t (*putchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
                                const struct openpgp_publickey *key);
  *     Returns an OpenPGP structure which is the unmarshalled result of
  *     the input byte stream - ie the inverse of marshal_publickey.
  */
-struct openpgp_publickey *unmarshal_publickey(int (*getchar_func)(void *ctx,
+struct openpgp_publickey *unmarshal_publickey(size_t (*getchar_func)(void *ctx,
                                size_t count,
                                void *c),
                                void *ctx);
  *     a 32 bit size of the forthcoming data (16 bytes) in network byte order
  *     and then the byte representation of the hash.
  */
-void marshal_skshash(int (*putchar_func)(void *ctx, size_t count,
+void marshal_skshash(size_t (*putchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
                                const struct skshash *hash);
  *     Returns an SKS hash structure which is the unmarshalled result of
  *     the input byte stream - ie the inverse of marshal_skshash.
  */
-struct skshash *unmarshal_skshash(int (*getchar_func)(void *ctx, size_t count,
+struct skshash *unmarshal_skshash(size_t (*getchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx);
 
  *     Takes a string and marshals it to a byte stream - writes a 32 bit size
  *     of the forthcoming data in network byte order and then the string.
  */
-void marshal_string(int (*putchar_func)(void *ctx, size_t count,
+void marshal_string(size_t (*putchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
                                const char *string);
  *     Returns a string which is the unmarshalled result of the input byte
  *     stream - ie the inverse of marshal_string.
  */
-char *unmarshal_string(int (*getchar_func)(void *ctx, size_t count,
+char *unmarshal_string(size_t (*getchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx);
 
  *     calls marshal_func for each element in the array to provide the
  *     marshalled contents.
  */
-void marshal_array(int (*putchar_func)(void *ctx, size_t count,
+void marshal_array(size_t (*putchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
-                               void (*marshal_func)(int
+                               void (*marshal_func)(size_t
                                        (*putchar_func)(void *ctx,
                                                size_t count, void *c),
                                        void *ctx, const void *item),
  *     as determined by the supplied unmarshal_func function. ie the reverse
  *     of marshal_array.
  */
-void **unmarshal_array(int (*getchar_func)(void *ctx, size_t count,
+void **unmarshal_array(size_t (*getchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
-                               void *(*unmarshal_func)(int
+                               void *(*unmarshal_func)(size_t
                                        (*getchar_func)(void *ctx,
                                                size_t count, void *c),
                                        void *ctx),
 
  *     packet stream and reads the packets into a linked list of packets
  *     ready for parsing as a public key or whatever.
  */
-onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count,
+onak_status_t read_openpgp_stream(size_t (*getchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
                                struct openpgp_packet_list **packets,
        }
 
        while (rc == ONAK_E_OK && (maxnum == 0 || keys < maxnum) &&
-                       !getchar_func(ctx, 1, &curchar)) {
+                       (getchar_func(ctx, 1, &curchar) == 1)) {
                if (curchar & 0x80) {
                        /*
                         * New packet. Allocate memory for it.
                         */
                        if (curpacket->packet->newformat) {
                                curpacket->packet->tag = (curchar & 0x3F);
-                               if (getchar_func(ctx, 1, &curchar)) {
+                               if (getchar_func(ctx, 1, &curchar) == 0) {
                                        rc = ONAK_E_INVALID_PKT;
                                        break;
                                }
                                curpacket->packet->length = curchar;
                                if (curpacket->packet->length > 191 &&
                                        curpacket->packet->length < 224) {
-                                       rc = getchar_func(ctx, 1, &curchar);
+                                       rc = getchar_func(ctx, 1, &curchar) ? ONAK_E_OK : ONAK_E_IO_ERROR;
                                        curpacket->packet->length -= 192;
                                        curpacket->packet->length <<= 8;
                                        curpacket->packet->length += curchar;
                                        rc = ONAK_E_UNSUPPORTED_FEATURE;
                                } else if (curpacket->packet->length == 255) {
                                        /*
-                                        * 5 byte length; ie 255 followed by 3
+                                        * 5 byte length; ie 255 followed by 4
                                         * bytes of MSB length.
                                         */
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length = curchar;
                                        curpacket->packet->length <<= 8;
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length += curchar;
                                        curpacket->packet->length <<= 8;
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length += curchar;
                                        curpacket->packet->length <<= 8;
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                curpacket->packet->tag = (curchar & 0x3C) >> 2;
                                switch (curchar & 3) {
                                case 0:
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length = curchar;
                                        break;
                                case 1:
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length = curchar;
                                        curpacket->packet->length <<= 8;
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length += curchar;
                                        break;
                                case 2:
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length = 
                                                ((unsigned) curchar << 24);
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length +=
                                                (curchar << 16);
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                        curpacket->packet->length +=
                                                (curchar << 8);
-                                       if (getchar_func(ctx, 1, &curchar)) {
+                                       if (getchar_func(ctx, 1, &curchar) != 1) {
                                                rc = ONAK_E_INVALID_PKT;
                                                break;
                                        }
                                } else {
                                        rc = getchar_func(ctx,
                                                curpacket->packet->length,
-                                               curpacket->packet->data);
+                                               curpacket->packet->data) ?
+                                               ONAK_E_OK : ONAK_E_IO_ERROR;
                                }
                        }
                } else {
  *     This function uses putchar_func to write characters to an OpenPGP
  *     packet stream from a linked list of packets.
  */
-onak_status_t write_openpgp_stream(int (*putchar_func)(void *ctx, size_t count,
+onak_status_t write_openpgp_stream(size_t (*putchar_func)(void *ctx, size_t count,
                                                void *c),
                                void *ctx,
                                struct openpgp_packet_list *packets)
 
  *     then only the public key component of the last key will be returned,
  *     none of the other packets of the key will be read.
  */
-onak_status_t read_openpgp_stream(int (*getchar_func)(void *ctx, size_t count,
+onak_status_t read_openpgp_stream(size_t (*getchar_func)(void *ctx, size_t count,
                                void *c),
                                void *ctx,
                                struct openpgp_packet_list **packets,
  *     This function uses putchar_func to write characters to an OpenPGP
  *     packet stream from a linked list of packets.
  */
-onak_status_t write_openpgp_stream(int (*putchar_func)(void *ctx, size_t count,
+onak_status_t write_openpgp_stream(size_t (*putchar_func)(void *ctx, size_t count,
                                                void *c),
                                void *ctx,
                                struct openpgp_packet_list *packets);
 
 #include "parsekey.h"
 #include "sendsync.h"
 
-int fd_putchar(void *ctx, size_t count, void *c)
+size_t fd_putchar(void *ctx, size_t count, void *c)
 {
-       fwrite(c, sizeof(char), count, ctx);
-
-       return 0;
+       return fwrite(c, sizeof(char), count, ctx);
 }
 
 /**