version 0.3.33
[fms.git] / src / freenet / frostmessagexml.cpp
1 #include "../../include/freenet/frostmessagexml.h"\r
2 \r
3 const std::string FrostMessageXML::FrostMakeFileName(const std::string &input) const\r
4 {\r
5         std::string output;\r
6         std::string::size_type strpos;\r
7         std::string invalidchars="/\\?*<>\":|#&";\r
8 \r
9         output=input;\r
10 \r
11         std::transform(input.begin(),input.end(),output.begin(),tolower);\r
12 \r
13         if(output.size()>0 && output[0]=='.')\r
14         {\r
15                 output[0]='_';\r
16         }\r
17 \r
18         strpos=output.find_first_of(invalidchars);\r
19         while(strpos!=std::string::npos)\r
20         {\r
21                 output.at(strpos)='_';\r
22                 strpos=output.find_first_of(invalidchars,strpos);\r
23         }\r
24 \r
25         return output;\r
26 }\r
27 \r
28 const std::string FrostMessageXML::GetSignableContentV2() const\r
29 {\r
30         char separator='|';\r
31         std::string temp;\r
32         long i;\r
33 \r
34         temp=GetFrostDate()+separator+GetFrostTime()+separator;\r
35 \r
36         temp+=GetFrostBoard()+separator;\r
37         temp+=GetFrostAuthor()+separator;\r
38         temp+=GetFrostMessageID()+separator;\r
39         if(GetFrostInReplyTo()!="")\r
40         {\r
41                 temp+=GetFrostInReplyTo()+separator;\r
42         }\r
43         // recipient goes here - private messages ??\r
44 \r
45         // add id info even if it is -1\r
46         {\r
47                 std::string tempval="";\r
48                 StringFunctions::Convert(GetFrostIDLinePos(),tempval);\r
49                 temp+=tempval+separator;\r
50                 StringFunctions::Convert(GetFrostIDLineLen(),tempval);\r
51                 temp+=tempval+separator;\r
52         }\r
53 \r
54 \r
55         temp+=GetFrostSubject()+separator+GetBody()+separator;\r
56 \r
57         std::vector<FrostMessageXML::frostboardattachment> boards=GetFrostBoardAttachments();\r
58         for(i=0; i<boards.size(); i++)\r
59         {\r
60                 temp+=FrostMakeFileName(boards[i].m_name)+separator;\r
61                 if(boards[i].m_publickey!="")\r
62                 {\r
63                         temp+=boards[i].m_publickey+separator;\r
64                 }\r
65                 if(boards[i].m_privatekey!="")\r
66                 {\r
67                         temp+=boards[i].m_privatekey+separator;\r
68                 }\r
69         }\r
70 \r
71         std::vector<FrostMessageXML::frostfileattachment> files=GetFrostFileAttachments();\r
72         for(i=0; i<files.size(); i++)\r
73         {\r
74                 temp+=files[i].m_name+separator;\r
75                 temp+=files[i].m_key+separator;\r
76         }\r
77 \r
78         return temp;\r
79 }\r
80 \r
81 std::string FrostMessageXML::GetXML()\r
82 {\r
83         return std::string("");\r
84 }\r
85 \r
86 void FrostMessageXML::Initialize()\r
87 {\r
88         MessageXML::Initialize();\r
89         m_frostidlinepos=0;\r
90         m_frostidlinelen=0;\r
91         m_frostdate="";\r
92         m_frosttime="";\r
93         m_frostauthor="";\r
94         m_frostsubject="";\r
95         m_frostmessageid="";\r
96         m_frostboard="";\r
97         m_frostpublickey="";\r
98         m_frostsignature="";\r
99         m_frostsignaturev2="";\r
100 }\r
101 \r
102 const bool FrostMessageXML::ParseXML(const std::string &xml)\r
103 {\r
104         /*\r
105                 FrostMessage\r
106                         MessageId       - CDATA\r
107                         InReplyTo       - CDATA\r
108                         IdLinePos       - long\r
109                         IdLenLen        - long\r
110                         From            - CDATA\r
111                         Subject         - CDATA\r
112                         Date            - YYYY.MM.DD\r
113                         Time            - HH:MM:SSGMT\r
114                         Body            - CDATA\r
115                         Board           - CDATA\r
116                         pubKey          - CDATA\r
117                         Signature       - CDATA\r
118                         AttachmentList\r
119                                 Attachment type="file"\r
120                                         File\r
121                                                 name    - CDATA\r
122                                                 size    - long\r
123                                                 key             - key without filename\r
124         */\r
125 \r
126         bool parsed=false;\r
127         Poco::XML::DOMParser dp;\r
128 \r
129         Initialize();\r
130 \r
131         try\r
132         {\r
133                 Poco::AutoPtr<Poco::XML::Document> doc=dp.parseString(FixCDATA(xml));\r
134                 Poco::XML::Element *root=XMLGetFirstChild(doc,"FrostMessage");\r
135                 Poco::XML::Element *txt=0;\r
136 \r
137                 txt=XMLGetFirstChild(root,"Date");\r
138                 if(txt)\r
139                 {\r
140                         if(txt->firstChild())\r
141                         {\r
142                                 m_frostdate=txt->firstChild()->getNodeValue();\r
143                                 m_date=SanitizeSingleString(m_frostdate);\r
144                                 m_date=StringFunctions::Replace(m_date,".","-");\r
145                                 if(m_date.size()<10)\r
146                                 {\r
147                                         std::vector<std::string> dateparts;\r
148                                         StringFunctions::Split(m_date,"-",dateparts);\r
149                                         if(dateparts.size()==3)\r
150                                         {\r
151                                                 m_date=dateparts[0]+"-";\r
152                                                 if(dateparts[1].size()==1)\r
153                                                 {\r
154                                                         m_date+="0";\r
155                                                 }\r
156                                                 m_date+=dateparts[1]+"-";\r
157                                                 if(dateparts[2].size()==1)\r
158                                                 {\r
159                                                         m_date+="0";\r
160                                                 }\r
161                                                 m_date+=dateparts[2];\r
162                                         }\r
163                                 }\r
164                         }\r
165                 }\r
166                 txt=XMLGetFirstChild(root,"Time");\r
167                 if(txt)\r
168                 {\r
169                         if(txt->firstChild())\r
170                         {\r
171                                 m_frosttime=txt->firstChild()->getNodeValue();\r
172                                 m_time=SanitizeSingleString(m_frosttime);\r
173                                 m_time=StringFunctions::Replace(m_time,"GMT","");\r
174                         }\r
175                 }\r
176                 txt=XMLGetFirstChild(root,"From");\r
177                 if(txt)\r
178                 {\r
179                         if(txt->firstChild())\r
180                         {\r
181                                 m_frostauthor=txt->firstChild()->getNodeValue();\r
182                         }\r
183                 }\r
184                 txt=XMLGetFirstChild(root,"Subject");\r
185                 if(txt)\r
186                 {\r
187                         if(txt->firstChild())\r
188                         {\r
189                                 m_frostsubject=txt->firstChild()->getNodeValue();\r
190                                 m_subject=SanitizeSingleString(m_frostsubject);\r
191                         }\r
192                 }\r
193                 txt=XMLGetFirstChild(root,"MessageId");\r
194                 if(txt)\r
195                 {\r
196                         if(txt->firstChild())\r
197                         {\r
198                                 // we have to append an @frost (or anything really) to the message ID, otherwise someone could insert valid FMS UUIDs here\r
199                                 m_frostmessageid=txt->firstChild()->getNodeValue();\r
200                                 m_messageid=SanitizeSingleString(m_frostmessageid)+"@frost";\r
201                         }\r
202                 }\r
203                 txt=XMLGetFirstChild(root,"Board");\r
204                 if(txt)\r
205                 {\r
206                         if(txt->firstChild())\r
207                         {\r
208                                 m_frostboard=txt->firstChild()->getNodeValue();\r
209                                 std::string boardname=SanitizeSingleString(m_frostboard);\r
210                                 StringFunctions::LowerCase(boardname,boardname);\r
211                                 if(boardname.size()>40)\r
212                                 {\r
213                                         boardname.erase(40);\r
214                                 }\r
215                                 m_replyboard=boardname;\r
216                                 m_boards.push_back(boardname);\r
217                         }\r
218                 }\r
219                 txt=XMLGetFirstChild(root,"Body");\r
220                 if(txt)\r
221                 {\r
222                         if(txt->firstChild())\r
223                         {\r
224                                 m_body=txt->firstChild()->getNodeValue();\r
225                         }\r
226                 }\r
227                 txt=XMLGetFirstChild(root,"pubKey");\r
228                 if(txt)\r
229                 {\r
230                         if(txt->firstChild())\r
231                         {\r
232                                 m_frostpublickey=txt->firstChild()->getNodeValue();\r
233                         }\r
234                 }\r
235                 txt=XMLGetFirstChild(root,"Signature");\r
236                 if(txt)\r
237                 {\r
238                         if(txt->firstChild())\r
239                         {\r
240                                 m_frostsignature=txt->firstChild()->getNodeValue();\r
241                         }\r
242                 }\r
243                 txt=XMLGetFirstChild(root,"SignatureV2");\r
244                 if(txt)\r
245                 {\r
246                         if(txt->firstChild())\r
247                         {\r
248                                 m_frostsignaturev2=txt->firstChild()->getNodeValue();\r
249                         }\r
250                 }\r
251                 txt=XMLGetFirstChild(root,"IdLinePos");\r
252                 if(txt)\r
253                 {\r
254                         if(txt->firstChild())\r
255                         {\r
256                                 std::string temp=txt->firstChild()->getNodeValue();\r
257                                 StringFunctions::Convert(temp,m_frostidlinepos);\r
258                         }\r
259                 }\r
260                 txt=XMLGetFirstChild(root,"IdLineLen");\r
261                 if(txt)\r
262                 {\r
263                         if(txt->firstChild())\r
264                         {\r
265                                 std::string temp=txt->firstChild()->getNodeValue();\r
266                                 StringFunctions::Convert(temp,m_frostidlinelen);\r
267                         }\r
268                 }\r
269                 Poco::XML::Element *inreplyto=XMLGetFirstChild(root,"InReplyTo");\r
270                 if(inreplyto)\r
271                 {\r
272                         if(inreplyto->firstChild())\r
273                         {\r
274                                 int order=0;\r
275                                 m_frostinreplyto=inreplyto->firstChild()->getNodeValue();\r
276                                 std::vector<std::string> inreplytoids;\r
277                                 StringFunctions::Split(m_frostinreplyto,",",inreplytoids);\r
278                                 for(std::vector<std::string>::reverse_iterator i=inreplytoids.rbegin(); i!=inreplytoids.rend(); i++)\r
279                                 {\r
280                                         m_inreplyto[order++]=(*i)+"@frost";\r
281                                 }\r
282                         }\r
283                 }\r
284                 Poco::XML::Element *attachments=XMLGetFirstChild(root,"AttachmentList");\r
285                 if(attachments)\r
286                 {\r
287                         Poco::XML::Element *file=XMLGetFirstChild(attachments,"Attachment");\r
288                         while(file)\r
289                         {\r
290                                 if(file->getAttribute("type")=="file")\r
291                                 {\r
292                                         Poco::XML::Element *keyel=XMLGetFirstChild(file,"key");\r
293                                         Poco::XML::Element *sizeel=XMLGetFirstChild(file,"size");\r
294                                         Poco::XML::Element *nameel=XMLGetFirstChild(file,"name");\r
295 \r
296                                         if(keyel && keyel->firstChild() && sizeel && sizeel->firstChild() && nameel && nameel->firstChild())\r
297                                         {\r
298                                                 int size=-1;\r
299                                                 std::string key="";\r
300                                                 \r
301                                                 StringFunctions::Convert(sizeel->firstChild()->getNodeValue(),size);\r
302                                                 key=keyel->firstChild()->getNodeValue();\r
303                                                 key+="/"+nameel->firstChild()->getNodeValue();\r
304 \r
305                                                 if(size!=-1 && key!="")\r
306                                                 {\r
307                                                         m_fileattachments.push_back(fileattachment(key,size));\r
308                                                 }\r
309 \r
310                                                 m_frostfileattachments.push_back(frostfileattachment(keyel->firstChild()->getNodeValue(),size,nameel->firstChild()->getNodeValue()));\r
311                                         }\r
312                                 }\r
313                                 else if(file->getAttribute("type")=="board")\r
314                                 {\r
315                                         Poco::XML::Element *nameel=XMLGetFirstChild(file,"Name");\r
316                                         Poco::XML::Element *descel=XMLGetFirstChild(file,"description");\r
317                                         Poco::XML::Element *pubel=XMLGetFirstChild(file,"pubKey");\r
318                                         Poco::XML::Element *privel=XMLGetFirstChild(file,"privKey");\r
319                                         std::string name="";\r
320                                         std::string desc="";\r
321                                         std::string pubkey="";\r
322                                         std::string privkey="";\r
323 \r
324                                         if(nameel && nameel->firstChild())\r
325                                         {\r
326                                                 name=nameel->firstChild()->getNodeValue();\r
327                                         }\r
328                                         if(descel && descel->firstChild())\r
329                                         {\r
330                                                 desc=descel->firstChild()->getNodeValue();\r
331                                         }\r
332                                         if(pubel && pubel->firstChild())\r
333                                         {\r
334                                                 pubkey=pubel->firstChild()->getNodeValue();\r
335                                         }\r
336                                         if(privel && privel->firstChild())\r
337                                         {\r
338                                                 privkey=privel->firstChild()->getNodeValue();\r
339                                         }\r
340 \r
341                                         m_frostboardattachments.push_back(frostboardattachment(name,desc,pubkey,privkey));\r
342 \r
343                                 }\r
344 \r
345                                 file=static_cast<Poco::XML::Element *>(file->nextSibling());\r
346 \r
347                         }\r
348                 }\r
349 \r
350                 parsed=true;\r
351 \r
352         }\r
353         catch(...)\r
354         {\r
355         }\r
356 \r
357         return parsed;\r
358 \r
359 }\r