svn_error_t * foo (svn_stream_t* s, apr_pool_t *pool) { unsigned char digest[APR_MD5_DIGESTSIZE]; svn_stream_t *stream = svn_stream_checksummed (s, digest, NULL, pool); return SVN_NO_ERROR; } /* MD5 checked stream support */ struct md5_stream_baton { apr_md5_ctx_t read_ctx, write_ctx; unsigned char *read_digest; unsigned char *write_digest; svn_stream_t *proxy; }; static svn_error_t * close_handler_md5 (void *baton) { struct md5_stream_baton *btn = baton; unsigned char digest[APR_MD5_DIGESTSIZE]; if (btn->read_digest) { apr_md5_final (digest, &btn->read_ctx); memcpy (btn->read_digest, digest, sizeof (digest)); } if (btn->write_digest) { apr_md5_final (digest, &btn->write_ctx); memcpy (btn->write_digest, digest, sizeof (digest)); } return SVN_NO_ERROR; } svn_stream_t * svn_stream_checksummed (svn_stream_t *stream, unsigned char *read_digest, unsigned char *write_digest, apr_pool_t *pool) { svn_stream_t *s; struct md5_stream_baton *baton; if (! read_digest && ! write_digest) return stream; baton = apr_palloc (pool, sizeof (*baton)); apr_md5_init (&baton->read_ctx); apr_md5_init (&baton->write_ctx); baton->read_digest = read_digest; baton->write_digest = write_digest; baton->proxy = stream; s = svn_stream_create (baton, pool); svn_stream_set_read (s, read_handler_md5); svn_stream_set_write (s, write_handler_md5); svn_stream_set_close (s, close_handler_md5); return s; }