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) |