#include #include #include #include #include #include #ifndef NL #define NL APR_EOL_STR #endif #define IO_BUF_LEN (8092) #define MIN_LEN (81) typedef struct ctxt_t { apr_pool_t *p; apr_bucket_alloc_t *buckets; apr_bucket_brigade *bbin; apr_bucket_brigade *bbtmp; apr_file_t *outfile; } ctxt_t; static apr_status_t read_line(ctxt_t *ctxt) { char buf[IO_BUF_LEN]; apr_status_t rv; apr_size_t len = sizeof(buf); apr_size_t nbytes = 0; rv = apr_brigade_split_line(ctxt->bbtmp, ctxt->bbin, APR_NONBLOCK_READ, len); if (rv != APR_SUCCESS) { return rv; } rv = apr_brigade_flatten(ctxt->bbtmp, buf, &len); if (rv != APR_SUCCESS) { return rv; } if (len == 0) { return APR_EOF; } if (len < MIN_LEN) { return rv; } rv = apr_file_write_full(ctxt->outfile, buf, len, &nbytes); return rv; } int main(int argc, const char * const argv[]) { apr_status_t rv; apr_pool_t *p; apr_file_t *infile; ctxt_t ctxt; rv = apr_initialize(); if (rv != APR_SUCCESS) { fprintf(stderr, "Unable to Initialize APR!"NL); return EXIT_FAILURE; } atexit(apr_terminate); rv = apr_pool_create(&p, NULL); if (rv != APR_SUCCESS) { fprintf(stderr, "Unable to create Root Pool!"NL); return EXIT_FAILURE; } rv = apr_file_open_stdout(&ctxt.outfile, p); if (rv != APR_SUCCESS) { fprintf(stderr, "Unable to open stdout!"NL); return EXIT_FAILURE; } rv = apr_file_open_stdin(&infile, p); if (rv != APR_SUCCESS) { fprintf(stderr, "Unable to open stdin!"NL); return EXIT_FAILURE; } { apr_bucket *e; apr_pollset_t *pollset; apr_pollfd_t pollfd; ctxt.p = p; ctxt.buckets = apr_bucket_alloc_create(p); ctxt.bbin = apr_brigade_create(p, ctxt.buckets); ctxt.bbtmp = apr_brigade_create(p, ctxt.buckets); e = apr_bucket_pipe_create(infile, ctxt.buckets); APR_BRIGADE_INSERT_TAIL(ctxt.bbin, e); rv = apr_pollset_create(&pollset, 1, ctxt.p, 0); if (rv != APR_SUCCESS) { fprintf(stderr, "Unable to create pollset!"NL); return EXIT_FAILURE; } pollfd.desc_type = APR_POLL_FILE; pollfd.reqevents = APR_POLLIN; pollfd.desc.f = infile; pollfd.client_data = NULL; rv = apr_pollset_add(pollset, &pollfd); if (rv != APR_SUCCESS) { fprintf(stderr, "Unable to add input to pollset!"NL); return EXIT_FAILURE; } do { int lrv; const apr_pollfd_t *descs = NULL; rv = apr_pollset_poll(pollset, -1, &lrv, &descs); if (APR_STATUS_IS_EINTR(rv)) { continue; } else if (rv) { fprintf(stderr, "pollset failed!"NL); return EXIT_FAILURE; } if (!lrv) { continue; } do { rv = read_line(&ctxt); apr_brigade_cleanup(ctxt.bbtmp); } while(rv == APR_SUCCESS); if (rv && !APR_STATUS_IS_EAGAIN(rv)) { break; } rv = APR_SUCCESS; } while (1); apr_pollset_destroy(pollset); } return EXIT_SUCCESS; }