ParseCTCP.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  1. /*
  2. * The contents of this file are subject to the Mozilla Public
  3. * License Version 1.1 (the "License"); you may not use this file
  4. * except in compliance with the License. You may obtain a copy of
  5. * the License at http://www.mozilla.org/MPL/
  6. *
  7. * Software distributed under the License is distributed on an "AS
  8. * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9. * implied. See the License for the specific language governing
  10. * rights and limitations under the License.
  11. *
  12. * The Original Code is Vision.
  13. *
  14. * The Initial Developer of the Original Code is The Vision Team.
  15. * Portions created by The Vision Team are
  16. * Copyright (C) 1999, 2000, 2001 The Vision Team. All Rights
  17. * Reserved.
  18. *
  19. * Contributor(s): Wade Majors <wade@ezri.org>
  20. * Rene Gollent
  21. * Todd Lair
  22. * Andrew Bazan
  23. * Jamie Wilkinson
  24. */
  25. #include <AppFileInfo.h>
  26. #include <sys/utsname.h>
  27. #include <stdlib.h>
  28. #include "Vision.h"
  29. #include "Utilities.h"
  30. #include "ServerAgent.h"
  31. void
  32. ServerAgent::ParseCTCP (BString theNick, BString theTarget, BString theMsg)
  33. {
  34. BString theCTCP (GetWord(theMsg.String(), 1).ToUpper()),
  35. theRest (RestOfString(theMsg.String(), 2));
  36. theCTCP.RemoveFirst ("\1");
  37. theCTCP.RemoveLast ("\1");
  38. if (theCTCP == "PING")
  39. {
  40. if (theMsg == "-9z99")
  41. return;
  42. BString tempString("NOTICE ");
  43. tempString += theNick;
  44. tempString += " :";
  45. tempString += theMsg;
  46. SendData (tempString.String());
  47. }
  48. else if ((theCTCP == "VERSION") || (theCTCP == "CLIENTINFO"))
  49. {
  50. BString sysInfoString;
  51. if (!vision_app->GetBool ("versionParanoid"))
  52. {
  53. system_info myInfo;
  54. get_system_info (&myInfo);
  55. cpu_topology_node_info* cpuInfo = NULL;
  56. uint32 infoCount = 0;
  57. uint64 clockSpeed = 0;
  58. get_cpu_topology_info(NULL, &infoCount);
  59. if (infoCount != 0) {
  60. cpuInfo = new cpu_topology_node_info[infoCount];
  61. get_cpu_topology_info(cpuInfo, &infoCount);
  62. for (uint32 i = 0; i < infoCount; i++) {
  63. if (cpuInfo[i].type == B_TOPOLOGY_CORE) {
  64. clockSpeed = cpuInfo[i].data.core.default_frequency;
  65. break;
  66. }
  67. }
  68. delete [] cpuInfo;
  69. }
  70. utsname sysname;
  71. uname(&sysname);
  72. BString revInfo = sysname.version;
  73. revInfo.Remove(revInfo.FindFirst(' '), revInfo.Length());
  74. sysInfoString = " : ";
  75. sysInfoString += sysname.sysname;
  76. sysInfoString += "/";
  77. sysInfoString += revInfo;
  78. sysInfoString += " (";
  79. sysInfoString << myInfo.cpu_count;
  80. sysInfoString += "x";
  81. sysInfoString << clockSpeed / 1000000;
  82. sysInfoString += "MHz) : ";
  83. }
  84. else
  85. sysInfoString = " : A bird in the bush usually has a friend in there with him : ";
  86. BString tempString ("NOTICE ");
  87. BString tempString2;
  88. vision_app->VisionVersion (VERSION_VERSION, tempString2);
  89. tempString += theNick;
  90. tempString += " :\1VERSION Vision-";
  91. tempString += tempString2;
  92. tempString += sysInfoString;
  93. tempString += "http://vision.sourceforge.net";
  94. tempString += '\1';
  95. SendData (tempString.String());
  96. }
  97. else if (theCTCP == "UPTIME")
  98. {
  99. BString uptime (DurationString(system_time()));
  100. BString expandedString;
  101. const char *expansions[1];
  102. expansions[0] = uptime.String();
  103. expandedString = ExpandKeyed (vision_app->GetCommand (CMD_UPTIME).String(), "U",
  104. expansions);
  105. expandedString.RemoveFirst ("\n");
  106. BString tempString ("NOTICE ");
  107. tempString += theNick;
  108. tempString += " :\1UPTIME ";
  109. tempString += expandedString;
  110. tempString += '\1';
  111. SendData (tempString.String());
  112. }
  113. else if ((theCTCP == "TIME") || (theCTCP == "DATE"))
  114. {
  115. time_t st (time (0));
  116. struct tm curTime;
  117. localtime_r (&st, &curTime);
  118. char str[47];
  119. strftime (str,47,"%A %b %d %Y %I:%M %p %Z",&curTime);
  120. BString tempString ("NOTICE ");
  121. tempString += theNick;
  122. tempString += " :\1TIME ";
  123. tempString += str;
  124. tempString += '\1';
  125. SendData (tempString.String());
  126. }
  127. else if(theCTCP == "DCC")
  128. {
  129. BString theType = GetWord(theMsg.String(), 2);
  130. if (theType == "SEND")
  131. {
  132. BString theFile,
  133. theIP,
  134. thePort,
  135. theSize;
  136. int32 startPos (0), endPos (0);
  137. if ((startPos = theMsg.FindFirst ('\"')) != B_ERROR)
  138. {
  139. endPos = theMsg.FindFirst ('\"', startPos + 1);
  140. theMsg.CopyInto (theFile, startPos + 1, endPos - (startPos + 1));
  141. BString rest;
  142. theMsg.CopyInto (rest, endPos+1, theMsg.Length() - (endPos + 1));
  143. theIP = GetWord (rest.String(), 2);
  144. thePort = GetWord (rest.String(), 3);
  145. theSize = GetWord (rest.String(), 4);
  146. }
  147. else
  148. {
  149. theFile = GetWord(theMsg.String(), 3);
  150. theIP = GetWord(theMsg.String(), 4);
  151. thePort = GetWord(theMsg.String(), 5);
  152. theSize = GetWord(theMsg.String(), 6);
  153. }
  154. theSize.RemoveLast ("\1"); // strip CTCP char
  155. DCCGetDialog (theNick, theFile, theSize, theIP, thePort);
  156. }
  157. if (theType == "CHAT")
  158. {
  159. BString theIP (GetWord(theMsg.String(), 4)),
  160. thePort (GetWord(theMsg.String(), 5));
  161. thePort.RemoveLast ("\1");
  162. DCCChatDialog(theNick, theIP, thePort);
  163. }
  164. else if (theType == "ACCEPT")
  165. {
  166. BString file (GetWord (theMsg.String(), 3)),
  167. port (GetWord (theMsg.String(), 4)),
  168. poss (GetWord (theMsg.String(), 5));
  169. poss.RemoveLast("\1");
  170. off_t pos (0LL);
  171. int32 i (0);
  172. for (i = 0; i < poss.Length(); ++i)
  173. pos = pos * 10 + poss[i] - '0';
  174. for (i = 0; i < fResumes.CountItems(); ++i)
  175. {
  176. ResumeData *data ((ResumeData *)fResumes.ItemAt (i));
  177. if (data->nick == theNick
  178. && data->pos == pos
  179. && data->port == port);
  180. {
  181. fResumes.RemoveItem (i);
  182. BMessage msg (M_DCC_ACCEPT);
  183. msg.AddString ("vision:nick", data->nick.String());
  184. msg.AddString ("vision:file", data->file.String());
  185. msg.AddString ("vision:size", data->size.String());
  186. msg.AddString ("vision:ip", data->ip.String());
  187. msg.AddString ("vision:port", data->port.String());
  188. msg.AddString ("path", data->path.String());
  189. msg.AddBool ("continue", true);
  190. fMsgr.SendMessage(&msg);
  191. delete data;
  192. break;
  193. }
  194. }
  195. }
  196. else if (theType == "RESUME")
  197. {
  198. BString file (GetWord (theMsg.String(), 3)),
  199. port (GetWord (theMsg.String(), 4)),
  200. poss (GetWord (theMsg.String(), 5));
  201. poss.RemoveLast("\1");
  202. off_t pos (0LL);
  203. for (int32 i = 0; i < poss.Length(); ++i)
  204. pos = pos * 10 + poss[i] - '0';
  205. // Have to tell the sender we can resume
  206. BString tempString("PRIVMSG ");
  207. tempString += theNick;
  208. tempString += " :\1DCC ACCEPT ";
  209. tempString += file;
  210. tempString += " ";
  211. tempString += port;
  212. tempString += " ";
  213. tempString += poss;
  214. tempString += "\1";
  215. SendData (tempString.String());
  216. BMessage bMsg (M_DCC_MESSENGER), bReply;
  217. be_app_messenger.SendMessage (&bMsg, &bReply);
  218. BMessenger msgr;
  219. bReply.FindMessenger ("msgr", &msgr);
  220. BMessage msg (M_ADD_RESUME_DATA), reply;
  221. msg.AddString ("vision:nick", theNick.String());
  222. msg.AddString ("vision:port", port.String());
  223. msg.AddString ("vision:file", file.String());
  224. msg.AddInt64 ("vision:pos", pos);
  225. // do sync.. we do not want to have the transfer
  226. // start before we tell it okay
  227. msgr.SendMessage (&msg, &reply);
  228. if (reply.HasBool ("hit")
  229. && reply.FindBool ("hit"))
  230. {
  231. BString buffer;
  232. buffer += "PRIVMSG ";
  233. buffer += theNick;
  234. buffer += " :\1DCC ACCEPT ";
  235. buffer += file;
  236. buffer += " ";
  237. buffer += port;
  238. buffer += " ";
  239. buffer += poss;
  240. buffer += "\1";
  241. SendData (buffer.String());
  242. }
  243. }
  244. }
  245. BMessage display (M_DISPLAY);
  246. BString buffer;
  247. buffer += "[";
  248. buffer += theNick;
  249. buffer += " ";
  250. if (theTarget != fMyNick)
  251. {
  252. buffer += theTarget;
  253. buffer += ":";
  254. }
  255. buffer << theCTCP;
  256. if (theCTCP == "PING" || theRest == "-9z99")
  257. buffer += "]\n";
  258. else
  259. {
  260. int32 theChars = theRest.Length();
  261. if (theRest[theChars - 1] == '\1')
  262. theRest.Truncate (theChars - 1);
  263. buffer += "] ";
  264. buffer += theRest;
  265. buffer += '\n';
  266. }
  267. PackDisplay (&display, buffer.String(), C_CTCP_REQ, C_BACKGROUND, F_SERVER);
  268. PostActive (&display);
  269. }
  270. void
  271. ServerAgent::ParseCTCPResponse (BString theNick, BString theMsg)
  272. {
  273. BString theResponse (theMsg);
  274. if (theResponse[0] == '\1')
  275. theResponse.Remove(0, 1);
  276. int32 theChars = theResponse.Length();
  277. if(theResponse[theChars - 1] == '\1')
  278. theResponse.Truncate (theChars - 1);
  279. BString firstWord = GetWord (theResponse.String(), 1).ToUpper();
  280. BString tempString;
  281. if (firstWord == "PING")
  282. {
  283. long curTime = time (NULL);
  284. long theSeconds = curTime - atoi (GetWord (theMsg.String(), 2).String());
  285. if (theSeconds > 10000) // catch possible conversion error(s)
  286. {
  287. theSeconds = curTime - atoi (GetWord (theMsg.String(), 2).String());
  288. if (theSeconds > 10000)
  289. {
  290. theSeconds = curTime - atoi (GetWord (theMsg.String(), 2).String());
  291. if (theSeconds > 10000)
  292. {
  293. theSeconds = curTime - atoi (GetWord (theMsg.String(), 2).String());
  294. }
  295. }
  296. }
  297. tempString += "[";
  298. tempString += theNick;
  299. tempString += " PING" S_PCTCP_RESPONSE "]: ";
  300. if (theSeconds != 1)
  301. {
  302. tempString << theSeconds;
  303. tempString += " " S_PCTCP_SECOND_PLURAL "\n";
  304. }
  305. else
  306. tempString += "1 " S_PCTCP_SECOND "\n";
  307. }
  308. else
  309. {
  310. BString theReply = RestOfString (theResponse.String(), 2);
  311. tempString += "[";
  312. tempString += theNick;
  313. tempString += " ";
  314. tempString += firstWord;
  315. tempString += S_PCTCP_RESPONSE "]: ";
  316. tempString += theReply;
  317. tempString += '\n';
  318. }
  319. BMessage display (M_DISPLAY);
  320. BString buffer;
  321. buffer << tempString.String();
  322. PackDisplay (&display, buffer.String(), C_CTCP_RPY, C_BACKGROUND, F_SERVER);
  323. PostActive (&display);
  324. }