/* Create a compression buffer. */ struct buffer * compress_buffer_initialize (struct buffer *buf, int input, int level, void (*memory) (struct buffer *)) { struct compress_buffer *n; int zstatus; n = xmalloc (sizeof *n); memset (n, 0, sizeof *n); n->buf = buf; n->level = level; if (input) zstatus = inflateInit (&n->zstr); else zstatus = deflateInit (&n->zstr, level); if (zstatus != Z_OK) compress_error (1, zstatus, &n->zstr, "compression initialization"); /* There may already be data buffered on BUF. For an output buffer, this is OK, because these routines will just use the buffer routines to append data to the (uncompressed) data already on BUF. An input buffer expects to handle a single buffer_data of buffered input to be uncompressed, so that is OK provided there is only one buffer. At present that is all there ever will be; if this changes, compress_buffer_input must be modified to handle multiple input buffers. */ assert (! input || buf->data == NULL || buf->data->next == NULL); return buf_initialize (input ? compress_buffer_input : NULL, input ? NULL : compress_buffer_output, input ? NULL : compress_buffer_flush, compress_buffer_block, compress_buffer_get_fd, (input ? compress_buffer_shutdown_input : compress_buffer_shutdown_output), memory, n); }
/* Create a multi-source buffer. This could easily be generalized to support * any number of source buffers, but for now only two are necessary. */ struct buffer * ms_buffer_initialize (void (*memory) (struct buffer *), struct buffer *buf, struct buffer *buf2/*, ...*/) { struct ms_buffer *mb = xmalloc (sizeof *mb); struct buffer *retbuf; Node *p; mb->block = false; mb->cur = buf; set_nonblock (buf); mb->bufs = getlist (); p = getnode (); p->data = buf2; p->delproc = delbuflist; addnode (mb->bufs, p); retbuf = buf_initialize (ms_buffer_input, NULL, NULL, ms_buffer_block, ms_buffer_get_fd, ms_buffer_shutdown, memory, mb); if (!buf_empty_p (buf)) buf_append_buffer (retbuf, buf); mb->buf = retbuf; return retbuf; }
/* Initialize a buffer structure which is not to be used for I/O. */ struct buffer * buf_nonio_initialize( void (*memory) (struct buffer *) ) { return buf_initialize (NULL, NULL, NULL, NULL, NULL, NULL, memory, NULL); }
struct buffer * log_buffer_initialize (struct buffer *buf, FILE *fp, # ifdef PROXY_SUPPORT bool fatal_errors, size_t max, # endif /* PROXY_SUPPORT */ bool input, void (*memory) (struct buffer *)) { struct log_buffer *lb = xmalloc (sizeof *lb); struct buffer *retbuf; lb->buf = buf; lb->log = fp; #ifdef PROXY_SUPPORT lb->back_fn = NULL; lb->fatal_errors = fatal_errors; lb->disabled = false; assert (size_in_bounds_p (max)); lb->max = max; lb->tofile = false; lb->back_buf = buf_nonio_initialize (memory); #endif /* PROXY_SUPPORT */ retbuf = buf_initialize (input ? log_buffer_input : NULL, input ? NULL : log_buffer_output, input ? NULL : log_buffer_flush, log_buffer_block, log_buffer_get_fd, log_buffer_shutdown, memory, lb); if (!buf_empty_p (buf)) { /* If our buffer already had data, copy it & log it if necessary. This * can happen, for instance, with a pserver, where we deliberately do * not instantiate the log buffer until after authentication so that * auth data does not get logged (the pserver data will not be logged * in this case, but any data which was left unused in the buffer by * the auth code will be logged and put in our new buffer). */ struct buffer_data *data; #ifdef PROXY_SUPPORT size_t total = 0; #endif /* PROXY_SUPPORT */ for (data = buf->data; data != NULL; data = data->next) { #ifdef PROXY_SUPPORT if (!lb->tofile) { total = xsum (data->size, total); if (total >= max) lb->tofile = true; } if (lb->tofile) { if (!lb->log) log_buffer_force_file (lb); if (lb->log) { #endif /* PROXY_SUPPORT */ if (fwrite (data->bufp, 1, data->size, lb->log) != (size_t) data->size) error ( #ifdef PROXY_SUPPORT fatal_errors, #else /* !PROXY_SUPPORT */ false, #endif /* PROXY_SUPPORT */ errno, "writing to log file"); fflush (lb->log); #ifdef PROXY_SUPPORT } } else /* Log to memory buffer. */ buf_copy_data (lb->back_buf, data, data); #endif /* PROXY_SUPPORT */ } buf_append_buffer (retbuf, buf); } return retbuf; }