JunkBox_Lib  1.10.2
mime_tool.c
Go to the documentation of this file.
1 
8 #include "protocol.h"
9 #include "mime_tool.h"
10 
11 
13 //
14 
28 {
29  int i;
30  char* str;
31  char* pp;
32  Buffer buf;
33 
35  if (buf.buf==NULL) return NULL;
36  pp = (char*)buf.buf;
37 
38  pp += strlen(MIME_BOUNDARY_LINE);
39  if (*pp=='\"') pp++;
40 
41  str = (char*)malloc(strlen((const char*)pp)+3);
42  memset(str, 0, strlen((const char*)pp)+3);
43  str[0] = '-';
44  str[1] = '-';
45  strncpy(str+2, pp, strlen((const char*)pp));
46 
47  i = 2;
48  while (str[i]!='\0' && str[i]!='\"') i++;
49  str[i] = '\0';
50 
51  free_Buffer(&buf);
52  return str;
53 }
54 
55 
67 tList* get_mime_filename(FILE* fp, char* bndry)
68 {
69  tList* lp = NULL;
70  tList* ln = NULL;
71  char* pt;
72  Buffer mime, buf;
73 
74 
75  fseek(fp, 0, SEEK_SET);
76 
77  buf = make_Buffer(LBUF);
78  fgets_Buffer(&buf, fp);
79 
80  // ファイルから MIMEヘッダを抽出
81  while (!feof(fp)) {
82  if (!strcmp((char*)buf.buf, bndry)) { // mime boundary を見つけた
83  fgets_Buffer(&buf, fp);
84  while(!feof(fp)) {
85  ln = lp;
87  fgets_Buffer(&buf, fp);
88  if (ln==lp) break;
89  }
90  }
91  else {
92  fgets_Buffer(&buf, fp);
93  }
94  }
95  free_Buffer(&buf);
96  lp = find_tList_top(lp);
97 
98  mime = init_Buffer();
99 
100  // MIME_CONTEMT_LINE を取り出す.
101  if (lp!=NULL) {
102  int i, nn = 1;
103  tList* lt = NULL;
104  ln = NULL;
105 
106  Loop {
107  mime = search_protocol_header(lp, (char*)MIME_CONTENT_LINE, nn);
108  if (mime.buf==NULL) break;
109 
110  pt = strstrcase((char*)mime.buf, MIME_NAMEEQ_LINE); // name=
111  if (pt!=NULL) {
112  pt += strlen(MIME_NAMEEQ_LINE);
113  }
114  else {
115  pt = strstrcase((char*)mime.buf, MIME_FILENAMESTAR_LINE); // filename*
116  if (pt!=NULL) {
117  i = 0;
118  while(pt[i]!='\0' && pt[i]!='=') i++;
119  if (pt[i]=='=') pt += i + 1;
120  }
121  }
122 
123  if (pt!=NULL) {
124  pt = decode_mime_string(pt); // デコード
125  if (pt!=NULL) { // リストに格納
126  lt = add_tList_node_str(lt, pt, NULL);
127  if (ln==NULL) ln = lt;
128  free(pt);
129  }
130  }
131 
132  nn++;
133  free_Buffer(&mime);
134  }
135  }
136 
137  del_all_tList(&lp);
138  return ln;
139 }
140 
141 
153 tList* get_mime_filenameffn(char* fname, char* bndry)
154 {
155  tList* lp;
156  FILE* fp;
157 
158  if (bndry==NULL) return NULL;
159 
160  fp = fopen(fname, "rb");
161  if (fp==NULL) return NULL;
162 
163  lp = get_mime_filename(fp, bndry);
164  fclose(fp);
165 
166  return lp;
167 }
168 
169 
181 char* decode_mime_rfc2047(char* mime)
182 {
183  char* buf;
184  char* ppb;
185  char* dec;
186  char* ppd;
187  char* str;
188  char* ret;
189  int i, j, len, decf=0, sz;
190 
191  if (mime==NULL) return NULL;
192 
193  buf = ppb = (char*)malloc(strlen((const char*)mime)+1);
194  if (buf==NULL) return NULL;
195  memcpy(buf, mime, strlen(mime));
196  buf[strlen(mime)] = '\0';
197 
198  dec = ppd = (char*)malloc(strlen((const char*)mime)+1);
199  if (dec==NULL) {
200  free(buf);
201  return NULL;
202  }
203  memset(dec, 0, strlen((const char*)mime)+1);
204 
205  if (ppb[0]=='"') ppb++;
206  i = 0;
207  while(ppb[i]!='\0' && ppb[i]!='"') i++;
208  ppb[i] = '\0';
209 
210  while (ppb[0]!='\0') {
211  str = awk(ppb, '?', 1);
212  len = strlen((const char*)str);
213  if (str[len-1]=='=') { // エンコードの開始地点 =?
214  len--;
215  str[len] = '\0';
216  for (i=0, j=0; i<len; i++) {
217  if (str[i]!=CHAR_CR && str[i]!=CHAR_LF) ppd[j++] = str[i];
218  }
219  ppd += j;
220  ppb += len + 2;
221 
222  free(str);
223  str = awk(ppb, '?', 1);
224  if (str==NULL) {
225  free(dec);
226  free(buf);
227  return NULL;
228  }
229  if (strcasecmp(MIME_ISO2022JP_LINE, str)) {
230  free(str);
231  free(dec);
232  free(buf);
233  return NULL;
234  }
235  ppb += strlen(MIME_ISO2022JP_LINE) + 1;
236 
237  i++;
238  free(str);
239  str = awk(ppb, '?', 1);
240  if (str==NULL) {
241  free(dec);
242  free(buf);
243  return NULL;
244  }
245  if (!strcasecmp("B", str)) decf = 1; // Base64
246  else if (!strcasecmp("Q", str)) decf = 2; // Quoted Printable
247  else {
248  free(str);
249  free(dec);
250  free(buf);
251  return NULL;
252  }
253  ppb += 2;
254 
255  i++;
256  free(str);
257  str = awk(ppb, '?', 1);
258  if (str==NULL) {
259  free(dec);
260  free(buf);
261  return NULL;
262  }
263  len = strlen((const char*)str);
264  if (ppb[len+1]!='=') { // エンコード終了地点でない ?=
265  free(str);
266  free(dec);
267  free(buf);
268  return NULL;
269  }
270  ppb += len + 2;
271 
272  ret = NULL;
273  if (decf==1) ret = (char*)decode_base64((unsigned char*)str, &sz);
274  else if (decf==2) ret = (char*)decode_quoted_printable((unsigned char*)str, &sz);
275  if (ret==NULL) {
276  free(str);
277  free(dec);
278  free(buf);
279  return NULL;
280  }
281  memcpy(ppd, ret, sz);
282  ppd += sz;
283 
284  free(str);
285  free(ret);
286  decf = 0;
287  }
288  else {
289  if (len==0) break;
290  for (i=0, j=0; i<len; i++) {
291  if (str[i]!=CHAR_CR && str[i]!=CHAR_LF) ppd[j++] = str[i];
292  }
293  ppd += j;
294  ppb += len;
295  }
296  }
297  return dec;
298 }
299 
300 
312 char* decode_mime_rfc2231(char* mime)
313 {
314  char* buf;
315  char* dec;
316  int i, j, sz;
317 
318  if (mime==NULL) return NULL;
319 
320  buf = awk(mime, '\'', 1);
321  if (buf==NULL) return NULL;
322  if (strcasecmp(MIME_ISO2022JP_LINE, buf)) {
323  free(buf);
324  return NULL;
325  }
326  mime += strlen(MIME_ISO2022JP_LINE) + 1;
327  free(buf);
328 
329  buf = awk(mime, '\'', 1);
330  if (buf==NULL) return NULL;
331  if (strcasecmp("JA", buf)) {
332  return NULL;
333  }
334  mime += strlen("JA") + 1;
335  free(buf);
336 
337  buf = (char*)malloc(strlen((const char*)mime)+1);
338  if (buf==NULL) return NULL;
339  memset(buf, 0, strlen((const char*)mime)+1);
340 
341  i = j = 0;
342  while(mime[i]!='\0') {
343  if (mime[i]!=' ' && mime[i]!=';' && mime[i]!=CHAR_CR && mime[i]!=CHAR_LF) buf[j++] = mime[i];
344  i++;
345  }
346 
347  dec = (char*)decode_urlenc((unsigned char*)buf, &sz);
348  if (dec!=NULL) dec[sz] = '\0';
349  free(buf);
350 
351  return dec;
352 }
353 
354 
361 char* decode_mime_string(char* mime)
362 {
363  int kind;
364  char* buf=NULL;
365 
366  kind = get_mime_enckind(mime);
367  if (kind==MIME_ERR_ENCODE) return NULL;
368 
369  if (kind==MIME_UNKNOWN_ENCODE) {
370  int i, j, len;
371  char* str;
372 
373  len = strlen((const char*)mime);
374  str = (char*)malloc(len+1);
375  if (str==NULL) return NULL;
376  memset(str, 0, len+1);
377 
378  i = j = 0;
379  while(mime[i]!='\0') {
380  if (mime[i]!=CHAR_CR && mime[i]!=CHAR_LF) str[j++] = mime[i];
381  i++;
382  }
383  str[j] = '\0';
384 
385  len = strlen(str);
386  buf = (char*)malloc(len+1);
387  if (buf==NULL) {
388  free(str);
389  return NULL;
390  }
391  memset(buf, 0, len+1);
392 
393  if (str[0]=='\"' && str[len-1]=='\"' && str[len-2]!='\\') {
394  memcpy(buf, str+1, len-2);
395  buf[len-2] = '\0';
396  }
397  else {
398  memcpy(buf, str, len);
399  buf[len] = '\0';
400  }
401  free(str);
402  }
403  //
404  else if (kind==MIME_BASE64_ENCODE || kind==MIME_QUTDPRNTBL_ENCODE) {
405  buf = decode_mime_rfc2047(mime);
406  }
407  //
408  else if (kind==MIME_URL_ENCODE) {
409  int i, j;
410  char* str;
411 
412  str = (char*)malloc(strlen(mime)+1);
413  if (str!=NULL) {
414  memset(str, 0, strlen(mime)+1);
415  i = j = 0;
416  while(mime[i]!='\0') {
417  str[j++] = mime[i];
418  if (mime[i]==CHAR_LF) {
419  while(mime[i]!='\0' && mime[i]!='=') i++;
420  if (mime[i]=='=') i++;
421  }
422  else i++;
423  }
424  buf = decode_mime_rfc2231(str);
425  free(str);
426  }
427  }
428  return buf;
429 }
430 
431 
444 char* encode_mime_string(char* str, int kind)
445 {
446  char* buf;
447  Buffer mime;
448 
449  mime = make_Buffer(LBUF);
450  if (mime.buf==NULL) return NULL;
451 
452  if (kind==MIME_BASE64_ENCODE) {
453  buf = (char*)encode_base64((unsigned char*)str, -1);
454  if (buf==NULL) {
455  free_Buffer(&mime);
456  return NULL;
457  }
458  copy_s2Buffer(MIME_BASE64, &mime);
459  cat_s2Buffer(buf, &mime);
460  cat_s2Buffer("?=", &mime);
461  free(buf);
462  }
463  //
464  else if (kind==MIME_QUTDPRNTBL_ENCODE) {
465  buf = (char*)encode_quoted_printable((unsigned char*)str, -1);
466  if (buf==NULL) {
467  free_Buffer(&mime);
468  return NULL;
469  }
471  cat_s2Buffer(buf, &mime);
472  cat_s2Buffer("?=", &mime);
473  free(buf);
474  }
475  //
476  else if (kind==MIME_URL_ENCODE) {
477  buf = (char*)encode_urlenc((unsigned char*)str, -1);
478  if (buf==NULL) {
479  free_Buffer(&mime);
480  return NULL;
481  }
482  copy_s2Buffer(MIME_RFC2231, &mime);
483  cat_s2Buffer(buf, &mime);
484  free(buf);
485  }
486  //
487  else {
488  copy_s2Buffer(str, &mime);
489  }
490 
491  return (char*)mime.buf;
492 }
493 
494 
512 int get_mime_enckind(char* mime)
513 {
514  unsigned char* ps;
515  unsigned char* pe;
516 
517  if (mime==NULL) return MIME_ERR_ENCODE;
518 
519  if ((ps=(unsigned char*)strstrcase((const char*)mime, MIME_BASE64))!=NULL) {
520  if ((pe=(unsigned char*)strstr((const char*)mime, "?="))!=NULL) {
521  if (pe>ps+strlen(MIME_BASE64)) {
522  return MIME_BASE64_ENCODE;
523  }
524  }
525  }
526 
527  if (strstrcase(mime, MIME_QUTDPRNTBL)!=NULL) {
528  return MIME_QUTDPRNTBL_ENCODE;
529  }
530 
531  if (strstrcase(mime, MIME_RFC2231)!=NULL) {
532  return MIME_URL_ENCODE;
533  }
534 
535  return MIME_UNKNOWN_ENCODE;
536 }
537 
Buffer make_Buffer(int sz)
Buffer型変数のバッファ部をつくり出す.
Definition: buffer.c:71
int fgets_Buffer(Buffer *str, FILE *fp)
拡張fgets.文字列の読み込みに使用する.改行コードは削除する
Definition: buffer.c:1402
void free_Buffer(Buffer *buf)
Buffer型変数のバッファ部を解放する
Definition: buffer.c:128
Buffer init_Buffer()
初期化したBuffer型変数を返す.
Definition: buffer.c:47
#define copy_s2Buffer(src, dst)
copy_b2Buffer()
Definition: buffer.h:108
#define cat_s2Buffer(src, dst)
cat_b2Buffer()
Definition: buffer.h:122
#define Loop
Definition: common.h:256
#define LBUF
Definition: common.h:146
#define FALSE
Definition: common.h:223
unsigned char ** buf
Definition: jpeg_tool.h:96
unsigned char unsigned long * len
Definition: jpeg_tool.h:96
char * encode_mime_string(char *str, int kind)
Definition: mime_tool.c:444
char * get_mime_boundary(tList *list)
Definition: mime_tool.c:27
tList * get_mime_filenameffn(char *fname, char *bndry)
Definition: mime_tool.c:153
char * decode_mime_rfc2231(char *mime)
Definition: mime_tool.c:312
char * decode_mime_rfc2047(char *mime)
Definition: mime_tool.c:181
char * decode_mime_string(char *mime)
Definition: mime_tool.c:361
int get_mime_enckind(char *mime)
Definition: mime_tool.c:512
tList * get_mime_filename(FILE *fp, char *bndry)
Definition: mime_tool.c:67
MIMEツール ヘッダ
#define MIME_CONTENT_LINE
Definition: mime_tool.h:13
#define MIME_ISO2022JP_LINE
Definition: mime_tool.h:20
#define MIME_BASE64_ENCODE
Definition: mime_tool.h:28
#define MIME_UNKNOWN_ENCODE
Definition: mime_tool.h:27
#define MIME_BOUNDARY_LINE
Definition: mime_tool.h:19
#define MIME_FILENAMESTAR_LINE
Definition: mime_tool.h:18
#define MIME_URL_ENCODE
Definition: mime_tool.h:30
#define MIME_QUTDPRNTBL
Definition: mime_tool.h:22
#define MIME_BASE64
Definition: mime_tool.h:21
#define MIME_RFC2231
Definition: mime_tool.h:23
#define MIME_QUTDPRNTBL_ENCODE
Definition: mime_tool.h:29
#define MIME_ERR_ENCODE
Definition: mime_tool.h:26
#define MIME_CONTENTTYPE_LINE
Definition: mime_tool.h:14
#define MIME_NAMEEQ_LINE
Definition: mime_tool.h:16
Buffer search_protocol_header(tList *list, char *key, int no)
Definition: protocol.c:372
tList * get_protocol_header_list_seq(tList *lp, Buffer buf, char deli, int fstline, int rcntnt)
Definition: protocol.c:181
Buffer search_protocol_header_value(tList *list, char *key, char *data, int no)
Definition: protocol.c:436
プロトコル解析ライブラリ ヘッダ
Definition: buffer.h:35
unsigned char * buf
バッファの先頭へのポインタ.str[bufsz]は必ず 0x00となる.
Definition: buffer.h:39
void del_all_tList(tList **pp)
リストの全ノードの削除.ポインタ ppのノードを含むリスト全体を削除する.
Definition: tlist.c:769
tList * find_tList_top(tList *pl)
リストの最初のノードを探す.
Definition: tlist.c:1002
#define add_tList_node_str(p, k, v)
add_tList_node_bystr()
Definition: tlist.h:142
unsigned char * decode_quoted_printable(unsigned char *buf, int *sz)
buf を quoted printableからデコードする.要 free()
Definition: tools.c:3030
char * awk(char *buf, char cc, int n)
ccを区切り記号として, strのバッファ内の n番目の項目を返す.要 free()
Definition: tools.c:567
unsigned char * decode_urlenc(unsigned char *buf, int *sz)
buf を URLエンコードからデコードする.要 free()
Definition: tools.c:2933
char * strstrcase(const char *buf, const char *nd)
文字列 bufの中に文字列 ndがあるかどうかをチェックする.大文字小文字は区別しない.
Definition: tools.c:736
unsigned char * encode_quoted_printable(unsigned char *buf, int sz)
バイナリデータ bufを quoted printable にエンコードする.要 free()
Definition: tools.c:3075
unsigned char * encode_urlenc(unsigned char *buf, int sz)
バイナリデータ bufを URLエンコードする.要 free()
Definition: tools.c:2980
unsigned char * decode_base64(unsigned char *buf, int *sz)
bufを base64からデコードする.要 free()
Definition: tools.c:2787
unsigned char * encode_base64(unsigned char *buf, int sz)
バイナリデータ bufを base64にエンコードする.要 free()
Definition: tools.c:2849
#define CHAR_CR
改行
Definition: tools.h:78
#define CHAR_LF
ラインフィード
Definition: tools.h:79