1 /* -*- Mode: c++; -*- */
2 /*  --------------------------------------------------------------------
3  *  Filename:
4  *    mime-parseonlyheader.cc
5  *
6  *  Description:
7  *    Implementation of main mime parser components
8  *
9  *  Authors:
10  *    Andreas Aardal Hanssen <andreas-binc curly bincimap spot org>
11  *
12  *  Bugs:
13  *
14  *  ChangeLog:
15  *
16  *  --------------------------------------------------------------------
17  *  Copyright 2002-2005 Andreas Aardal Hanssen
18  *
19  *  This program is free software; you can redistribute it and/or modify
20  *  it under the terms of the GNU General Public License as published by
21  *  the Free Software Foundation; either version 2 of the License, or
22  *  (at your option) any later version.
23  *
24  *  This program is distributed in the hope that it will be useful,
25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  *  GNU General Public License for more details.
28  *
29  *  You should have received a copy of the GNU General Public License
30  *  along with this program; if not, write to the Free Software
31  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
32  *  --------------------------------------------------------------------
33  */
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37 
38 #include "mime.h"
39 #include "mime-utils.h"
40 #include "convert.h"
41 #include "io.h"
42 #include <string>
43 #include <vector>
44 #include <map>
45 #include <exception>
46 #include <iostream>
47 
48 #include <string.h>
49 #include <ctype.h>
50 #include <stdio.h>
51 #include <errno.h>
52 
53 using namespace ::std;
54 
55 //------------------------------------------------------------------------
parseOnlyHeader(int fd) const56 void Binc::MimeDocument::parseOnlyHeader(int fd) const
57 {
58   if (allIsParsed || headerIsParsed)
59     return;
60 
61   headerIsParsed = true;
62 
63   crlffile = fd;
64   crlfReset();
65 
66   headerstartoffsetcrlf = 0;
67   headerlength = 0;
68   bodystartoffsetcrlf = 0;
69   bodylength = 0;
70   messagerfc822 = false;
71   multipart = false;
72 
73   nlines = 0;
74   nbodylines = 0;
75 
76   MimePart::parseOnlyHeader("");
77 }
78 
79 //------------------------------------------------------------------------
parseOnlyHeader(const string & toboundary) const80 int Binc::MimePart::parseOnlyHeader(const string &toboundary) const
81 {
82   string name;
83   string content;
84   char cqueue[4];
85   memset(cqueue, 0, sizeof(cqueue));
86 
87   headerstartoffsetcrlf = crlfoffset;
88 
89   bool quit = false;
90   char c = '\0';
91 
92   while (!quit) {
93     // read name
94     while (1) {
95       if (!crlfGetChar(c)) {
96 	quit = true;
97 	break;
98       }
99 
100       if (c == '\n') ++nlines;
101       if (c == ':') break;
102       if (c == '\n') {
103 	for (int i = name.length() - 1; i >= 0; --i)
104 	  crlfUnGetChar();
105 
106 	quit = true;
107 	name = "";
108 	break;
109       }
110 
111       name += c;
112 
113       if (name.length() == 2 && name.substr(0, 2) == "\r\n") {
114 	name = "";
115 	quit = true;
116 	break;
117       }
118     }
119 
120     if (name.length() == 1 && name[0] == '\r') {
121       name = "";
122       break;
123     }
124 
125     if (quit) break;
126 
127     while (!quit) {
128       if (!crlfGetChar(c)) {
129 	quit = true;
130 	break;
131       }
132 
133       if (c == '\n') ++nlines;
134 
135       for (int i = 0; i < 3; ++i)
136 	cqueue[i] = cqueue[i + 1];
137       cqueue[3] = c;
138 
139       if (strncmp(cqueue, "\r\n\r\n", 4) == 0) {
140 	quit = true;
141 	break;
142       }
143 
144       if (cqueue[2] == '\n') {
145 
146 	// guess the mime rfc says what can not appear on the beginning
147 	// of a line.
148 	if (!isspace(cqueue[3])) {
149 	  if (content.length() > 2)
150 	    content.resize(content.length() - 2);
151 
152 	  trim(content);
153 	  h.add(name, content);
154 
155 	  name = c;
156 	  content = "";
157 	  break;
158 	}
159       }
160 
161       content += c;
162     }
163   }
164 
165   if (name != "") {
166     if (content.length() > 2)
167       content.resize(content.length() - 2);
168     h.add(name, content);
169   }
170 
171   headerlength = crlfoffset - headerstartoffsetcrlf;
172 
173   return 1;
174 }
175