Updated init script.
[dtbartle/bnbt.git] / tracker_comments.cpp
1 /***\r
2 *\r
3 * BNBT Beta 8.0 - A C++ BitTorrent Tracker\r
4 * Copyright (C) 2003-2004 Trevor Hogan\r
5 *\r
6 * CBTT variations (C) 2003-2005 Harold Feit\r
7 *\r
8 * This library is free software; you can redistribute it and/or\r
9 * modify it under the terms of the GNU Lesser General Public\r
10 * License as published by the Free Software Foundation; either\r
11 * version 2.1 of the License, or (at your option) any later version.\r
12 *\r
13 * This library is distributed in the hope that it will be useful,\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
16 * Lesser General Public License for more details.\r
17 *\r
18 * You should have received a copy of the GNU Lesser General Public\r
19 * License along with this library; if not, write to the Free Software\r
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA\r
21 *\r
22 ***/\r
23 \r
24 #include "bnbt.h"\r
25 #include "atom.h"\r
26 #include "tracker.h"\r
27 #include "util.h"\r
28 \r
29 void CTracker :: serverResponseComments( struct request_t *pRequest, struct response_t *pResponse, user_t user )\r
30 {\r
31         struct bnbttv btv = UTIL_CurrentTime( );\r
32 \r
33         if( !m_pAllowed || !m_bAllowComments )\r
34         {\r
35                 pResponse->strCode = "403 Forbidden";\r
36 \r
37                 return;\r
38         }\r
39 \r
40         pResponse->strCode = "200 OK";\r
41 \r
42         pResponse->mapHeaders.insert( pair<string, string>( "Content-Type", string( "text/html; charset=" ) + gstrCharSet ) );\r
43 \r
44         pResponse->strContent += "<html>\n";\r
45         pResponse->strContent += "<head>\n";\r
46         if ( !gstrTrackerTitle.empty( ) )\r
47                 pResponse->strContent += "<title>" + gstrTrackerTitle + " - Torrent Comments</title>\n";\r
48         else\r
49                 pResponse->strContent += "<title>BNBT Torrent Comments</title>\n"; \r
50 \r
51         if( !gstrStyle.empty( ) )\r
52                 pResponse->strContent += "<link rel=stylesheet type=\"text/css\" href=\"" + gstrStyle + "\">\n";\r
53 \r
54         pResponse->strContent += "</head>\n";\r
55 \r
56         // assorted scripts (thanks SA)\r
57 \r
58         pResponse->strContent += "<script language=\"javascript\">\n";\r
59         pResponse->strContent += "function validate( theform ) {\n";\r
60         pResponse->strContent += "if( theform.comment.value == \"\" ) {\n";\r
61         pResponse->strContent += "      alert( \"You must fill in all the fields.\" );\n";\r
62         pResponse->strContent += "      return false; }\n";\r
63         pResponse->strContent += "if( theform.comment.value.length > " + CAtomInt( m_iCommentLength ).toString( ) + " ) {\n";\r
64         pResponse->strContent += "      alert( \"Your message is too long.\\nReduce your message to " + CAtomInt( m_iCommentLength ).toString( ) + " characters.\\nIt is currently \" + theform.comment.value.length + \" characters long.\" );\n";\r
65         pResponse->strContent += "      return false; }\n";\r
66         pResponse->strContent += "else { return true; }\n";\r
67         pResponse->strContent += "}\n";\r
68         pResponse->strContent += "function checklength( theform ) {\n";\r
69         pResponse->strContent += "alert( \"Your message is \" + theform.comment.value.length + \" characters long.\" );\n";\r
70         pResponse->strContent += "}\n";\r
71         pResponse->strContent += "</script>\n";\r
72         pResponse->strContent += "<body>\n";\r
73 \r
74         if( !m_bDisableLogon )\r
75         {\r
76                 if( user.strLogin.empty( ) )\r
77                         pResponse->strContent += "<p class=\"login1_index\">You are not logged in. Click <a href=\"/login.html\">here</a> to login.</p>\n";\r
78                 else\r
79                         pResponse->strContent += "<p class=\"login2_index\">You are logged in as <span class=\"username\">" + UTIL_RemoveHTML( user.strLogin ) + "</span>. Click <a href=\"/login.html?logout=1\">here</a> to logout.</p>\n";\r
80         }\r
81 \r
82         if ( !gstrTrackerTitle.empty( ) )\r
83                 pResponse->strContent += "<title>" + gstrTrackerTitle + " - Torrent Comments</title>\n";\r
84         else\r
85                 pResponse->strContent += "<title>BNBT Torrent Comments</title>\n";\r
86 \r
87         // The Trinity Edition - Addition Begins\r
88         // The following adds an RTT link to the User Comments page\r
89         // when VIEWING comments.\r
90 \r
91         pResponse->strContent += "<p><a href=\"/index.html\">Return to Tracker</a></p>\n";\r
92 \r
93         // ------------------------------------------------- End of Addition\r
94 \r
95         if( user.iAccess & ACCESS_VIEW )\r
96         {\r
97                 string strHashString = pRequest->mapParams["info_hash"];\r
98                 string strHash = UTIL_StringToHash( strHashString );\r
99 \r
100                 if( !strHash.empty( ) )\r
101                 {\r
102                         //\r
103                         // delete comment\r
104                         //\r
105 \r
106                         if( user.iAccess & ACCESS_EDIT )\r
107                         {\r
108                                 string strDelAll = pRequest->mapParams["delall"];\r
109                                 string strDel = pRequest->mapParams["del"];\r
110 \r
111                                 if( strDelAll == "1" )\r
112                                 {\r
113                                         m_pComments->delItem( strHash );\r
114 \r
115                                         saveComments( );\r
116 \r
117                                         pResponse->strContent += "<p>Deleted all comments. Click <a href=\"/comments.html?info_hash=" + strHashString + "\">here</a> to return to the comments page.</p>\n";\r
118 \r
119                                         if( m_bGen )\r
120                                                 pResponse->strContent += "<p class=\"gen\">Generated in " + UTIL_ElapsedTimeStr( btv, UTIL_CurrentTime( ) ) + " seconds.</p>\n";\r
121 \r
122                                         pResponse->strContent += "</body>\n";\r
123                                         pResponse->strContent += "</html>\n";\r
124 \r
125                                         return;\r
126                                 }\r
127                                 else if( !strDel.empty( ) )\r
128                                 {\r
129                                         int iDel = atoi( strDel.c_str( ) ) - 1;\r
130 \r
131                                         CAtom *pComments = m_pComments->getItem( strHash );\r
132 \r
133                                         if( pComments && pComments->isList( ) )\r
134                                         {\r
135                                                 vector<CAtom *> vecComments = ( (CAtomList *)pComments )->getValue( );\r
136 \r
137                                                 if( iDel >= 0 && (unsigned int)iDel < vecComments.size( ) )\r
138                                                 {\r
139                                                         ( (CAtomList *)pComments )->delItem( vecComments[iDel] );\r
140 \r
141                                                         saveComments( );\r
142 \r
143                                                         pResponse->strContent += "<p>Deleted comment " + strDel + ". Click <a href=\"/comments.html?info_hash=" + strHashString + "\">here</a> to return to the comments page.</p>\n";\r
144 \r
145                                                         if( m_bGen )\r
146                                                                 pResponse->strContent += "<p class=\"gen\">Generated in " + UTIL_ElapsedTimeStr( btv, UTIL_CurrentTime( ) ) + " seconds.</p>\n";\r
147 \r
148                                                         pResponse->strContent += "</body>\n";\r
149                                                         pResponse->strContent += "</html>\n";\r
150 \r
151                                                         return;\r
152                                                 }\r
153                                                 else\r
154                                                 {\r
155                                                         pResponse->strContent += "<p>Unable to delete comment " + strDel + ". The comment number is invalid. Click <a href=\"/comments.html?info_hash=" + strHashString + "\">here</a> to return to the comments page.</p>\n";\r
156 \r
157                                                         if( m_bGen )\r
158                                                                 pResponse->strContent += "<p class=\"gen\">Generated in " + UTIL_ElapsedTimeStr( btv, UTIL_CurrentTime( ) ) + " seconds.</p>\n";\r
159 \r
160                                                         pResponse->strContent += "</body>\n";\r
161                                                         pResponse->strContent += "</html>\n";\r
162 \r
163                                                         return;\r
164                                                 }\r
165                                         }\r
166                                 }\r
167                         }\r
168 \r
169                         // display torrent information list\r
170 \r
171                         if( m_pAllowed )\r
172                         {\r
173                                 CAtom *pTorrent = m_pAllowed->getItem( strHash );\r
174 \r
175                                 if( pTorrent && pTorrent->isList( ) )\r
176                                 {\r
177                                         vector<CAtom *> vecTorrent = ( (CAtomList *)pTorrent )->getValue( );\r
178 \r
179                                         if( vecTorrent.size( ) == 6 )\r
180                                         {\r
181                                                 CAtom *pName = vecTorrent[1];\r
182                                                 CAtom *pAdded = vecTorrent[2];\r
183                                                 CAtom *pSize = vecTorrent[3];\r
184                                                 CAtom *pFiles = vecTorrent[4];\r
185                                                 CAtom *pComment = vecTorrent[5];\r
186 \r
187                                                 pResponse->strContent += "<p>File Information</p>\n";\r
188                                                 pResponse->strContent += "<ul>\n";\r
189 \r
190                                                 if( pName )\r
191                                                         pResponse->strContent += "<li><strong>Name:</strong> " + UTIL_RemoveHTML( pName->toString( ) ) + "</li>\n";\r
192 \r
193                                                 pResponse->strContent += "<li><strong>Info Hash:</strong> " + strHashString + "</li>\n";\r
194 \r
195                                                 if( pAdded )\r
196                                                         pResponse->strContent += "<li><strong>Added:</strong> " + pAdded->toString( ) + "</li>\n";\r
197 \r
198                                                 if( pSize && dynamic_cast<CAtomLong *>( pSize ) )\r
199                                                         pResponse->strContent += "<li><strong>Size:</strong> " + UTIL_BytesToString( dynamic_cast<CAtomLong *>( pSize )->getValue( ) ) + "</li>\n";\r
200 \r
201                                                 if( pFiles && dynamic_cast<CAtomInt *>( pFiles ) )\r
202                                                         pResponse->strContent += "<li><strong>Files:</strong> " + pFiles->toString( ) + "</li>\n";\r
203 \r
204                                                 pResponse->strContent += "</ul>\n";\r
205 \r
206                                                 if( pComment )\r
207                                                 {\r
208                                                         if( m_bShowFileComment )\r
209                                                         {\r
210                                                                 pResponse->strContent += "<p>File Comment</p>\n";\r
211                                                                 pResponse->strContent += "<table summary=\"file comment\">\n";\r
212                                                                 pResponse->strContent += "<tr><td class=\"com_body\"><code>" + UTIL_RemoveHTML( pComment->toString( ) ) + "</code></td></tr>\n";\r
213                                                                 pResponse->strContent += "</table>\n";\r
214                                                         }\r
215                                                 }\r
216                                         }\r
217                                 }\r
218                         }\r
219 \r
220                         if( !m_pComments->getItem( strHash ) )\r
221                                 m_pComments->setItem( strHash, new CAtomList( ) );\r
222 \r
223                         CAtom *pComments = m_pComments->getItem( strHash );\r
224 \r
225                         if( pComments && pComments->isList( ) )\r
226                         {\r
227                                 if( user.iAccess & ACCESS_COMMENTS )\r
228                                 {\r
229                                         if( pRequest->mapParams.find( "comment" ) != pRequest->mapParams.end( ) )\r
230                                         {\r
231                                                 string strComment = pRequest->mapParams["comment"].substr( 0, m_iCommentLength );\r
232 \r
233                                                 if( strComment.empty( ) )\r
234                                                 {\r
235                                                         pResponse->strContent += "<p>You must fill in all the fields. Click <a href=\"/comments.html?info_hash=" + strHashString + "\">here</a> to return to the comments page.</p>\n";\r
236 \r
237                                                         if( m_bGen )\r
238                                                                 pResponse->strContent += "<p class=\"gen\">Generated in " + UTIL_ElapsedTimeStr( btv, UTIL_CurrentTime( ) ) + " seconds.</p>\n";\r
239 \r
240                                                         pResponse->strContent += "</body>\n";\r
241                                                         pResponse->strContent += "</html>\n";\r
242 \r
243                                                         return;\r
244                                                 }\r
245 \r
246                                                 CAtomDicti *pNew = new CAtomDicti( );\r
247 \r
248                                                 pNew->setItem( "ip", new CAtomString( inet_ntoa( pRequest->sin.sin_addr ) ) );\r
249 \r
250                                                 if( !user.strLogin.empty( ) )\r
251                                                         pNew->setItem( "name", new CAtomString( user.strLogin ) );\r
252 \r
253                                                 pNew->setItem( "comment", new CAtomString( strComment ) );\r
254 \r
255                                                 time_t tNow = time( NULL );\r
256                                                 char *szTime = asctime( localtime( &tNow ) );\r
257                                                 szTime[strlen( szTime ) - 1] = '\0';\r
258 \r
259                                                 pNew->setItem( "time", new CAtomString( szTime ) );\r
260 \r
261                                                 ( (CAtomList *)pComments )->addItem( pNew );\r
262 \r
263                                                 saveComments( );\r
264 \r
265                                                 pResponse->strContent += "<p>Your comment has been posted. DO NOT REFRESH THIS PAGE OR YOUR COMMENT WILL BE POSTED TWICE. Click <a href=\"/comments.html?info_hash=" + strHashString + "\">here</a> to return to the comments page.</p>\n";\r
266 \r
267                                                 if( m_bGen )\r
268                                                         pResponse->strContent += "<p class=\"gen\">Generated in " + UTIL_ElapsedTimeStr( btv, UTIL_CurrentTime( ) ) + " seconds.</p>\n";\r
269 \r
270                                                 pResponse->strContent += "</body>\n";\r
271                                                 pResponse->strContent += "</html>\n";\r
272 \r
273                                                 return;\r
274                                         }\r
275                                 }\r
276 \r
277                                 vector<CAtom *> *pvecList = ( (CAtomList *)pComments )->getValuePtr( );\r
278 \r
279                                 bool bFound = false;\r
280 \r
281                                 unsigned long i = 0;\r
282 \r
283                                 for( vector<CAtom *> :: iterator it = pvecList->begin( ); it != pvecList->end( ); it++ )\r
284                                 {\r
285                                         if( (*it)->isDicti( ) )\r
286                                         {\r
287                                                 CAtomDicti *pCommentDicti = (CAtomDicti *)(*it);\r
288 \r
289                                                 CAtom *pIP = pCommentDicti->getItem( "ip" );\r
290                                                 CAtom *pName = pCommentDicti->getItem( "name" );\r
291                                                 CAtom *pComText = pCommentDicti->getItem( "comment" );\r
292                                                 CAtom *pTime = pCommentDicti->getItem( "time" );\r
293 \r
294                                                 if( pIP && pComText && pTime )\r
295                                                 {\r
296                                                         if( !bFound )\r
297                                                         {\r
298                                                                 pResponse->strContent += "<p>Comments";\r
299 \r
300                                                                 if( user.iAccess & ACCESS_EDIT )\r
301                                                                         pResponse->strContent += " [<a href=\"/comments.html?info_hash=" + strHashString + "&delall=1\">Delete All</a>]";\r
302 \r
303                                                                 pResponse->strContent += "</p>\n";\r
304                                                                 pResponse->strContent += "<table summary=\"comments\">\n";\r
305 \r
306                                                                 bFound = true;\r
307                                                         }\r
308 \r
309                                                         string strIP = pIP->toString( );\r
310                                                         string strName;\r
311 \r
312                                                         if( pName )\r
313                                                                 strName = pName->toString( );\r
314 \r
315                                                         string strComText = pComText->toString( );\r
316                                                         string strTime = pTime->toString( );\r
317 \r
318                                                         if( strName.empty( ) )\r
319                                                         {\r
320                                                                 // strip ip\r
321 \r
322                                                                 string :: size_type iStart = strIP.rfind( "." );\r
323 \r
324                                                                 if( iStart != string :: npos )\r
325                                                                 {\r
326                                                                         // don't strip ip for mods\r
327 \r
328                                                                         if( !( user.iAccess & ACCESS_EDIT ) )\r
329                                                                                 strIP = strIP.substr( 0, iStart + 1 ) + "xxx";\r
330                                                                 }\r
331                                                         }\r
332                                                         else\r
333                                                         {\r
334                                                                 if( !( user.iAccess & ACCESS_EDIT ) )\r
335                                                                         strIP = "HIDDEN";\r
336                                                         }\r
337 \r
338                                                         //\r
339                                                         // header\r
340                                                         //\r
341 \r
342                                                         pResponse->strContent += "<tr class=\"com_header\"><td class=\"com_header\"><code>Comment " + CAtomInt( i + 1 ).toString( ) + " posted by ";\r
343 \r
344                                                         if( !strName.empty( ) )\r
345                                                                 pResponse->strContent += "<strong>" + UTIL_RemoveHTML( strName ) + "</strong> (";\r
346 \r
347                                                         pResponse->strContent += strIP;\r
348 \r
349                                                         if( !strName.empty( ) )\r
350                                                                 pResponse->strContent += ")";\r
351 \r
352                                                         pResponse->strContent += " on " + strTime;\r
353 \r
354                                                         if( user.iAccess & ACCESS_EDIT )\r
355                                                                 pResponse->strContent += " [<a href=\"/comments.html?info_hash=" + strHashString + "&del=" + CAtomInt( i + 1 ).toString( ) + "\">Delete</a>]";\r
356 \r
357                                                         pResponse->strContent += "</code></td></tr>\n";\r
358 \r
359                                                         //\r
360                                                         // body\r
361                                                         //\r
362 \r
363                                                         pResponse->strContent += "<tr class=\"com_body\"><td class=\"com_body\"><code>" + UTIL_RemoveHTML( strComText ) + "</code></td></tr>\n";\r
364                                                 }\r
365                                         }\r
366 \r
367                                         i++;\r
368                                 }\r
369 \r
370                                 if( bFound )\r
371                                         pResponse->strContent += "</table>\n";\r
372                                 else\r
373                                         pResponse->strContent += "<p>No Comments Posted</p>\n";\r
374                         }\r
375 \r
376                         if( user.iAccess & ACCESS_COMMENTS )\r
377                         {\r
378                                 pResponse->strContent += "<p>Post A Comment</p>\n";\r
379                                 pResponse->strContent += "<form method=\"get\" action=\"/comments.html\" name=\"form\" onSubmit=\"return validate( this )\">\n";\r
380                                 pResponse->strContent += "<ul>\n";\r
381                                 pResponse->strContent += "<li>Comments must be less than " + CAtomInt( m_iCommentLength ).toString( ) + " characters long</li>\n";\r
382                                 pResponse->strContent += "<li>No HTML</li>\n";\r
383                                 pResponse->strContent += "</ul>\n";\r
384                                 pResponse->strContent += "<input name=\"info_hash\" type=hidden value=\"" + strHashString + "\">\n";\r
385                                 pResponse->strContent += "<textarea name=\"comment\" rows=8 cols=64></textarea><br><br>\n";\r
386                                 pResponse->strContent += "<a href=\"javascript:checklength( document.form );\">[check message length]</a><br><br>\n";\r
387                                 pResponse->strContent += "<input type=submit value=\"Submit\">\n";\r
388                                 pResponse->strContent += "</form>\n";\r
389                         }\r
390                         else\r
391                                 pResponse->strContent += "<p class=\"denied\">You are not authorized to post comments.</p>\n";\r
392                 }\r
393         }\r
394         else\r
395                 pResponse->strContent += "<p class=\"denied\">You are not authorized to view this page.</p>\n";\r
396 \r
397         if( m_bGen )\r
398                 pResponse->strContent += "<p class=\"gen\">Generated in " + UTIL_ElapsedTimeStr( btv, UTIL_CurrentTime( ) ) + " seconds.</p>\n";\r
399 \r
400         pResponse->strContent += "</body>\n";\r
401         pResponse->strContent += "</html>\n";\r
402 }\r