kdechunk2.c
最終更新:2009/11/7
001: /* kdechunk2.c 002: * チャンク形式データ用デコーダ 003: */ 004: 005: #define USAGE "Usage: kdechunk2 <chunk-encoded-filename> <out-filename>" 006: 007: #include "mystab.h" 008: 009: #include "myio_apr.h" 010: #include "myio_chunk.h" 011: 012: /* 013: * 文字列 s 中に最初ぶ文字 c が現れた位置へのポインタを返す関数 014: * (strchr 相当) 015: */ 016: char * mystrchr (const char *s, char c) { 017: const char *p = s; 018: if (p) 019: for (; *p; p++) 020: if (*p == c) 021: return (char*)p; 022: 023: return NULL; 024: } 025: 026: /* entity-header が "Transfer-Encoding" ヘッダの時に、 027: * ヘッダの値が "chunked" か調べるコールバック関数 028: */ 029: 030: void lookup_te_chunked ( 031: const char *line 032: , void *ctx 033: ) { 034: char *name = NULL; 035: char *value = NULL; 036: char *pos = NULL; 037: int *seen_chunked = (int*)ctx; 038: 039: if (!line || !ctx) 040: return; 041: 042: name = (char*)line; 043: 044: pos = mystrchr(line, ':'); 045: 046: if (!pos) 047: return; /* ':' が見つからなかった時は何もしない。 */ 048: 049: /* ':' の前の空白を検査していないが、本来はすべきだろう。 */ 050: 051: if (strncasecmp(name, "transfer-encoding", pos-name)) { 052: return; 053: } 054: 055: /* ':' の後の空白のスキップ */ 056: 057: pos++; 058: while(*pos && (*pos == ' ' || *pos == '\t')) 059: pos++; 060: 061: value = pos; 062: 063: if (!strcmp(value, "chunked")) { 064: *seen_chunked = 1; 065: if(0)printf("#T-E chunked found.\n"); 066: } 067: } 068: 069: 070: int apr_my_main ( 071: int ac 072: , char **av 073: , apr_file_t * astdin 074: , apr_file_t * astdout 075: , apr_file_t * astderr 076: , apr_pool_t * pool 077: ) { 078: int error_flag = 0; 079: 080: MYIO *in = NULL; 081: MYIO *out = NULL; 082: 083: char *infilename = NULL; 084: char *outfilename = NULL; 085: 086: int chunked = 0; 087: 088: if (ac < 2) { 089: apr_file_printf(astderr, "%s\n", USAGE); 090: goto _FINALLY_; 091: } 092: 093: infilename = av[1]; 094: outfilename = av[2]; 095: 096: 097: in = MYIO_fp_open(infilename, APR_FOPEN_READ|APR_FOPEN_BINARY, APR_OS_DEFAULT, pool); 098: if (! in) { 099: apr_file_printf(astderr, "ERROR: MYIO_fp_open: %s ", infilename); 100: error_flag = 1; 101: goto _FINALLY_; 102: } 103: out = MYIO_fp_open(outfilename, 104: APR_FOPEN_WRITE|APR_FOPEN_CREATE|APR_FOPEN_TRUNCATE|APR_FOPEN_BINARY, 105: APR_OS_DEFAULT, pool); 106: if (! out) { 107: apr_file_printf(astderr, "ERROR: MYIO_fp_open: %s ", outfilename); 108: error_flag = 1; 109: goto _FINALLY_; 110: } 111: 112: 113: /* ヘッダの読み出し。T-E が "chunked" かチェックする。 */ 114: 115: if (MYIO_read_entity_headers_CRLF_do(in, lookup_te_chunked, &chunked) == 0) { 116: apr_file_printf(astderr, "ERROR: MYIO_read_entity_headers_CRLF_do "); 117: error_flag = 1; 118: goto _FINALLY_; 119: } 120: 121: if (chunked) { 122: 123: /* チャンク形式のボディをデコード。デコード結果はストリーム out へ */ 124: 125: if (MYIO_decode_chunked_body (in, out) < 0) { 126: apr_file_printf(astderr, "ERROR: MYIO_decode_chunked_body "); 127: error_flag = 1; 128: goto _FINALLY_; 129: } 130: 131: } 132: 133: _FINALLY_: 134: 135: if (in) { 136: MYIO_fp_close(in); 137: in = NULL; 138: } 139: 140: if (out) { 141: MYIO_fp_close(out); 142: out = NULL; 143: } 144: 145: if (error_flag) { 146: apr_file_printf(astderr, "failed.\n"); 147: return 1; /* 異常終了 */ 148: } 149: 150: apr_file_printf(astdout, "done.\n"); 151: return 0; /* 正常終了 */ 152: 153: }
KAKU PROJECT (2009) |