mime-printheader.cc (5049B)
1 /* -*- Mode: c++; -*- */ 2 /* -------------------------------------------------------------------- 3 * Filename: 4 * mime-printheader.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 //------------------------------------------------------------------------ 56 void Binc::MimePart::printHeader(int fd, 57 IO &output, vector<string> headers, bool includeheaders, 58 unsigned int startoffset, unsigned int length, string &store) const 59 { 60 if (crlffile != fd) { 61 crlffile = fd; 62 crlfoffset = 1; 63 crlfSeek(0); 64 } 65 66 crlfSeek(headerstartoffsetcrlf); 67 68 string name; 69 string content; 70 char cqueue[2]; 71 memset(cqueue, 0, sizeof(cqueue)); 72 73 bool quit = false; 74 char c = '\0'; 75 76 unsigned int wrotebytes = 0; 77 unsigned int processedbytes = 0; 78 bool hasHeaderSeparator = false; 79 80 while (!quit) { 81 // read name 82 while (1) { 83 // allow EOF to end the header 84 if (!crlfGetChar(c)) { 85 quit = true; 86 break; 87 } 88 89 // assume this character is part of the header name. 90 name += c; 91 92 // break on the first colon 93 if (c == ':') 94 break; 95 96 // break if a '\n' turned up. 97 if (c == '\n') { 98 // end of headers detected 99 if (name == "\r\n") { 100 hasHeaderSeparator = true; 101 quit = true; 102 break; 103 } 104 105 // put all data back in the buffer to the beginning of this 106 // line. 107 for (int i = name.length(); i >= 0; --i) 108 crlfUnGetChar(); 109 110 // abort printing of header. note that in this case, the 111 // headers will not end with a seperate \r\n. 112 quit = true; 113 name = ""; 114 break; 115 } 116 } 117 118 if (quit) break; 119 120 // at this point, we have a name, that is - the start of a 121 // header. we'll read until the end of the header. 122 while (!quit) { 123 // allow EOF to end the header. 124 if (!crlfGetChar(c)) { 125 quit = true; 126 break; 127 } 128 129 if (c == '\n') ++nlines; 130 131 // make a fifo queue of the last 4 characters. 132 cqueue[0] = cqueue[1]; 133 cqueue[1] = c; 134 135 // print header 136 if (cqueue[0] == '\n' && cqueue[1] != '\t' && cqueue[1] != ' ') { 137 // it wasn't a space, so put it back as it is most likely 138 // the start of a header name. in any case it terminates the 139 // content part of this header. 140 crlfUnGetChar(); 141 142 string lowername = name; 143 lowercase(lowername); 144 trim(lowername, ": \t"); 145 bool foundMatch = false; 146 for (vector<string>::const_iterator i = headers.begin(); 147 i != headers.end(); ++i) { 148 string nametmp = *i; 149 lowercase(nametmp); 150 if (nametmp == lowername) { 151 foundMatch = true; 152 break; 153 } 154 } 155 156 if (foundMatch == includeheaders || headers.size() == 0) { 157 string out = name + content; 158 for (string::const_iterator i = out.begin(); i != out.end(); ++i) 159 if (processedbytes >= startoffset && wrotebytes < length) { 160 if (processedbytes >= startoffset) { 161 store += *i; 162 ++wrotebytes; 163 } 164 } else 165 ++processedbytes; 166 } 167 168 // move on to the next header 169 content = ""; 170 name = ""; 171 break; 172 } 173 174 content += c; 175 } 176 } 177 178 if (name != "") { 179 string lowername = name; 180 lowercase(lowername); 181 trim(lowername, ": \t"); 182 bool foundMatch = false; 183 for (vector<string>::const_iterator i = headers.begin(); 184 i != headers.end(); ++i) { 185 string nametmp = *i; 186 lowercase(nametmp); 187 if (nametmp == lowername) { 188 foundMatch = true; 189 break; 190 } 191 } 192 193 if (hasHeaderSeparator || foundMatch == includeheaders || headers.size() == 0) { 194 string out = name + content; 195 for (string::const_iterator i = out.begin(); i != out.end(); ++i) 196 if (processedbytes >= startoffset && wrotebytes < length) { 197 store += *i; 198 ++wrotebytes; 199 } else 200 ++processedbytes; 201 } 202 } 203 }