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