/* kdechunk.c * チャンク形式データ用デコーダ */ #define USAGE "Usage: kdechunk " #include /* strtol */ #include "apr_general.h" #include "apr_file_io.h" #include "apr_strings.h" #include "apr_buckets.h" #include "mystab.h" #include "mybb.h" int apr_my_main (int ac, char **av, apr_file_t * astdin, apr_file_t * astdout, apr_file_t * astderr, apr_pool_t * pool) { apr_status_t rv; char error_buf[256]; apr_finfo_t finfo; apr_file_t *fpin = NULL; apr_file_t *fpout = NULL; char *infilename = NULL; char *outfilename = NULL; apr_bucket_alloc_t *ba = NULL; apr_bucket_brigade *bb = NULL; if (ac < 2) { apr_file_printf(astderr, "%s\n", USAGE); goto _ERROR_; } infilename = av[1]; outfilename = av[2]; ba = apr_bucket_alloc_create(pool); bb = apr_brigade_create(pool, ba); if (APR_SUCCESS != (rv = apr_file_open(&fpin, infilename, APR_FOPEN_READ|APR_FOPEN_BINARY, APR_OS_DEFAULT, pool))) { apr_file_printf(astderr, "ERROR: apr_file_open: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); goto _ERROR_; } if (APR_SUCCESS != (rv = apr_file_info_get(&finfo, APR_FINFO_MIN, fpin))) { apr_file_printf(astderr, "ERROR: apr_file_info_get: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); goto _ERROR_; } if (APR_SUCCESS != (rv = apr_file_open(&fpout, outfilename, APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE|APR_FOPEN_BINARY, APR_OS_DEFAULT, pool))) { apr_file_printf(astderr, "ERROR: apr_file_open: %s\n", apr_strerror(rv, error_buf, sizeof(error_buf))); goto _ERROR_; } /* 入力ファイルをストリームに挿入 */ if (fpin && bb) { apr_brigade_insert_file(bb, fpin, 0, finfo.size, pool); } if (bb && ba) { apr_bucket_brigade *bb2 = apr_brigade_create(pool, ba); /* ヘッダの読み出し。読み出すのみ。 */ if (read_entity_header_CRLF(bb) == 0) { apr_file_printf(astderr, "ERROR: read_entity_header_CRLF\n"); goto _ERROR_; } /* チャンク形式のボディをデコード。デコード結果はストリーム bb2 に格納。 */ if (decode_chunked_body (bb, bb2) < 0) { apr_file_printf(astderr, "ERROR: decode_chunked_body\n"); goto _ERROR_; } /* デコード結果のストリームをファイルに書き込み。 */ write_from_bb_to_fp (bb2, fpout); } apr_file_printf(astdout, "\ndone.\n"); if (bb) { apr_brigade_destroy(bb); bb = NULL; } if (ba) { apr_bucket_alloc_destroy(ba); ba = NULL; } if (fpin) { apr_file_close(fpin); fpin = NULL; } if (fpout) { apr_file_close(fpout); fpout = NULL; } return 0; /* 正常終了 */ _ERROR_: if (bb) { apr_brigade_destroy(bb); bb = NULL; } if (ba) { apr_bucket_alloc_destroy(ba); ba = NULL; } if (fpin) { apr_file_close(fpin); fpin = NULL; } if (fpout) { apr_file_close(fpout); fpout = NULL; } apr_file_printf(astderr, "\nfailed.\n"); return 1; /* 異常終了 */ }