chat.c 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564
  1. /******************************************************************************
  2. * This file is part of TinTin++ *
  3. * *
  4. * Copyright 2004-2019 Igor van den Hoven *
  5. * *
  6. * TinTin++ is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * *
  17. * You should have received a copy of the GNU General Public License *
  18. * along with TinTin++. If not, see https://www.gnu.org/licenses. *
  19. ******************************************************************************/
  20. /******************************************************************************
  21. * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t *
  22. * *
  23. * coded by Sean Butler 1998 *
  24. * recoded by Igor van den Hoven 2005 *
  25. ******************************************************************************/
  26. #include "tintin.h"
  27. #include <sys/types.h>
  28. #include <sys/stat.h>
  29. #include <sys/socket.h>
  30. #include <netdb.h>
  31. #include <netinet/in.h>
  32. #include <arpa/inet.h>
  33. #include <fcntl.h>
  34. #ifdef HAVE_PTHREAD_H
  35. #include <pthread.h>
  36. #endif
  37. #define CALL_TIMEOUT 5
  38. #define BLOCK_SIZE 500
  39. #define DEFAULT_PORT 4050
  40. DO_COMMAND(do_chat)
  41. {
  42. char cmd[BUFFER_SIZE], arg1[BUFFER_SIZE], arg2[BUFFER_SIZE];
  43. int cnt;
  44. arg = get_arg_in_braces(ses, arg, cmd, GET_ONE);
  45. if (*cmd == 0)
  46. {
  47. tintin_header(ses, " CHAT COMMANDS ");
  48. for (cnt = 0 ; *chat_table[cnt].name != 0 ; cnt++)
  49. {
  50. tintin_printf2(ses, " [%-13s] %s", chat_table[cnt].name, chat_table[cnt].desc);
  51. }
  52. tintin_header(ses, "");
  53. return ses;
  54. }
  55. for (cnt = 0 ; *chat_table[cnt].name != 0 ; cnt++)
  56. {
  57. if (!is_abbrev(cmd, chat_table[cnt].name))
  58. {
  59. continue;
  60. }
  61. if (chat_table[cnt].fun != chat_initialize && gtd->chat == NULL)
  62. {
  63. tintin_printf(NULL, "\e[1;31m<CHAT> You must initialize a chat port first.");
  64. return ses;
  65. }
  66. arg = sub_arg_in_braces(ses, arg, arg1, chat_table[cnt].lval, SUB_VAR|SUB_FUN);
  67. arg = sub_arg_in_braces(ses, arg, arg2, chat_table[cnt].rval, SUB_VAR|SUB_FUN);
  68. return ses;
  69. }
  70. do_chat(ses, "");
  71. return ses;
  72. }
  73. DO_CHAT(chat_initialize)
  74. {
  75. struct sockaddr_in sa;
  76. struct linger ld;
  77. int sock, port, optval = 0;
  78. if (gtd->chat)
  79. {
  80. chat_printf("Already initialised");
  81. return;
  82. }
  83. port = atoi(arg1) ? atoi(arg1) : DEFAULT_PORT;
  84. sa.sin_family = AF_INET;
  85. sa.sin_port = htons(port);
  86. sa.sin_addr.s_addr = INADDR_ANY;
  87. sock = socket(AF_INET, SOCK_STREAM, 0);
  88. if (sock < 0)
  89. {
  90. syserr_printf(gtd->ses, "chat_initialize: socket");
  91. return;
  92. }
  93. if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(int)) == -1)
  94. {
  95. syserr_printf(gtd->ses, "chat_initialize: setsockopt");
  96. }
  97. ld.l_onoff = 0;
  98. ld.l_linger = 100;
  99. setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *) &ld, sizeof(ld));
  100. if (fcntl(sock, F_SETFL, O_NDELAY|O_NONBLOCK) == -1)
  101. {
  102. syserr_printf(gtd->ses, "chat_initialize: fcntl O_NDELAY|O_NONBLOCK");
  103. }
  104. if (bind(sock, (struct sockaddr *) &sa, sizeof(sa)) < 0)
  105. {
  106. tintin_printf(NULL, "Port %d is already in use, cannot initiate chat.", port);
  107. close(sock);
  108. return;
  109. }
  110. if (listen(sock, 50) == -1)
  111. {
  112. syserr_printf(gtd->ses, "chat_initialize: listen");
  113. close(sock);
  114. return;
  115. }
  116. gtd->chat = (struct chat_data *) calloc(1, sizeof(struct chat_data));
  117. gtd->chat->fd = sock;
  118. gtd->chat->port = port;
  119. gtd->chat->color = strdup("\e[0;1;31m");
  120. gtd->chat->download = strdup("");
  121. gtd->chat->ip = strdup("<Unknown>");
  122. gtd->chat->name = strdup("TinTin");
  123. gtd->chat->reply = strdup("");
  124. gtd->chat->prefix = strdup("<CHAT> ");
  125. chat_printf("Initialized chat on port %d.", gtd->chat->port);
  126. }
  127. DO_CHAT(chat_uninitialize)
  128. {
  129. int port = gtd->chat->port;
  130. while (gtd->chat->next)
  131. {
  132. close_chat(gtd->chat->next, TRUE);
  133. }
  134. close_chat(gtd->chat, FALSE);
  135. gtd->chat = NULL;
  136. tintin_printf(NULL, "#OK: Uninitialized chat on port %d.", port);
  137. }
  138. int chat_new(int s)
  139. {
  140. struct chat_data *new_buddy;
  141. struct sockaddr_in sock;
  142. socklen_t i;
  143. int fd;
  144. i = sizeof(sock);
  145. getsockname(s, (struct sockaddr *) &sock, &i);
  146. if ((fd = accept(s, (struct sockaddr *) &sock, &i)) < 0)
  147. {
  148. syserr_printf(gtd->ses, "chat_new: accept");
  149. return -1;
  150. }
  151. if (fcntl(fd, F_SETFL, O_NDELAY|O_NONBLOCK) == -1)
  152. {
  153. syserr_printf(gtd->ses, "chat_new: fcntl O_NDELAY|O_NONBLOCK");
  154. }
  155. if (HAS_BIT(gtd->chat->flags, CHAT_FLAG_DND))
  156. {
  157. close(fd);
  158. return -1;
  159. }
  160. new_buddy = (struct chat_data *) calloc(1, sizeof(struct chat_data));
  161. new_buddy->fd = fd;
  162. new_buddy->download = strdup("");
  163. new_buddy->group = strdup("");
  164. new_buddy->ip = strdup(inet_ntoa(sock.sin_addr));
  165. new_buddy->name = strdup("Unknown");
  166. new_buddy->version = strdup("");
  167. new_buddy->timeout = gtd->time + CALL_TIMEOUT;
  168. LINK(new_buddy, gtd->chat->next, gtd->chat->prev);
  169. chat_printf("New connection: %s D%d.", new_buddy->ip, new_buddy->fd);
  170. return 0;
  171. }
  172. // getaddrinfo should be universally supported anno 2019, if not, let me know.
  173. void *threaded_chat_call(void *arg)
  174. {
  175. int sock, error;
  176. char host[BUFFER_SIZE], port[BUFFER_SIZE], name[BUFFER_SIZE];
  177. struct addrinfo *address;
  178. static struct addrinfo hints;
  179. struct chat_data *new_buddy;
  180. struct timeval to;
  181. fd_set wds, rds;
  182. chat_printf("Attempting to call %s ...", arg);
  183. to.tv_sec = CALL_TIMEOUT;
  184. to.tv_usec = 0;
  185. arg = (void *) get_arg_in_braces(gtd->ses, (char *) arg, host, GET_ONE);
  186. arg = (void *) get_arg_in_braces(gtd->ses, (char *) arg, port, GET_ONE);
  187. if (*port == 0)
  188. {
  189. sprintf(port, "%d", DEFAULT_PORT);
  190. }
  191. hints.ai_family = AF_INET;
  192. hints.ai_protocol = IPPROTO_TCP;
  193. hints.ai_socktype = SOCK_STREAM;
  194. error = getaddrinfo(host, port, &hints, &address);
  195. switch (error)
  196. {
  197. case 0:
  198. break;
  199. case -2:
  200. chat_printf("Failed to call %s, unknown host.", host);
  201. return NULL;
  202. default:
  203. chat_printf("Failed to call %s.", host);
  204. return NULL;
  205. }
  206. sock = socket(address->ai_family, address->ai_socktype, address->ai_protocol);
  207. if (sock < 0)
  208. {
  209. syserr_printf(gtd->ses, "threaded_chat_call: socket");
  210. freeaddrinfo(address);
  211. return NULL;
  212. }
  213. switch (address->ai_family)
  214. {
  215. case AF_INET:
  216. inet_ntop(address->ai_family, &((struct sockaddr_in *)address->ai_addr)->sin_addr, host, address->ai_addrlen);
  217. break;
  218. case AF_INET6:
  219. inet_ntop(address->ai_family, &((struct sockaddr_in6 *)address->ai_addr)->sin6_addr, host, address->ai_addrlen);
  220. break;
  221. }
  222. if (connect(sock, address->ai_addr, address->ai_addrlen) != 0)
  223. {
  224. chat_printf("Failed to connect to %s:%s", host, port);
  225. close(sock);
  226. freeaddrinfo(address);
  227. return NULL;
  228. }
  229. FD_ZERO(&wds);
  230. FD_SET(sock, &wds);
  231. if (select(FD_SETSIZE, NULL, &wds, NULL, &to) == -1)
  232. {
  233. chat_printf("Failed to connect to %s %s", host, port);
  234. close(sock);
  235. freeaddrinfo(address);
  236. return NULL;
  237. }
  238. if (!FD_ISSET(sock, &wds))
  239. {
  240. chat_printf("Connection timed out.");
  241. close(sock);
  242. freeaddrinfo(address);
  243. return NULL;
  244. }
  245. new_buddy = calloc(1, sizeof(struct chat_data));
  246. new_buddy->fd = sock;
  247. new_buddy->port = atoi(port);
  248. new_buddy->group = strdup("");
  249. new_buddy->ip = strdup(host);
  250. new_buddy->name = strdup("");
  251. new_buddy->version = strdup("");
  252. new_buddy->download = strdup("");
  253. strip_vt102_codes(gtd->chat->name, name);
  254. chat_socket_printf(new_buddy, "CHAT:%s\n%s%-5u", name, gtd->chat->ip, gtd->chat->port);
  255. chat_printf("Socket connected, negotiating protocol...");
  256. FD_ZERO(&rds);
  257. FD_SET(sock, &rds);
  258. to.tv_sec = CALL_TIMEOUT;
  259. to.tv_usec = 0;
  260. if (select(FD_SETSIZE, &rds, NULL, NULL, &to) == -1)
  261. {
  262. close_chat(new_buddy, FALSE);
  263. freeaddrinfo(address);
  264. return NULL;
  265. }
  266. if (process_chat_input(new_buddy) == -1)
  267. {
  268. FD_CLR(new_buddy->fd, &rds);
  269. close_chat(new_buddy, FALSE);
  270. freeaddrinfo(address);
  271. return NULL;
  272. }
  273. if (gtd->chat == NULL || *new_buddy->name == 0)
  274. {
  275. close_chat(new_buddy, FALSE);
  276. }
  277. else
  278. {
  279. if (fcntl(sock, F_SETFL, O_NDELAY|O_NONBLOCK) == -1)
  280. {
  281. syserr_printf(gtd->ses, "chat_new: fcntl O_NDELAY|O_NONBLOCK");
  282. }
  283. #ifdef HAVE_LIBPTHREAD
  284. while (gtd->chat->update)
  285. {
  286. chat_printf("Blocking the linking of %s.", new_buddy->name);
  287. usleep(1000);
  288. continue;
  289. }
  290. #endif
  291. LINK(new_buddy, gtd->chat->next, gtd->chat->prev);
  292. chat_printf("Connection made to %s.", new_buddy->name);
  293. }
  294. freeaddrinfo(address);
  295. return NULL;
  296. }
  297. /*
  298. void *threaded_chat_call(void *arg)
  299. {
  300. int sock, dig;
  301. char host[BUFFER_SIZE], port[BUFFER_SIZE], name[BUFFER_SIZE];
  302. struct sockaddr_in dest_addr;
  303. struct chat_data *new_buddy;
  304. struct timeval to;
  305. fd_set wds, rds;
  306. chat_printf("Attempting to call %s ...", arg);
  307. to.tv_sec = CALL_TIMEOUT;
  308. to.tv_usec = 0;
  309. arg = (void *) get_arg_in_braces(gtd->ses, (char *) arg, host, GET_ONE);
  310. arg = (void *) get_arg_in_braces(gtd->ses, (char *) arg, port, GET_ONE);
  311. if (*port == 0)
  312. {
  313. sprintf(port, "%d", DEFAULT_PORT);
  314. }
  315. if (sscanf(host, "%d.%d.%d.%d", &dig, &dig, &dig, &dig) == 4)
  316. {
  317. dest_addr.sin_addr.s_addr = inet_addr(host);
  318. }
  319. else
  320. {
  321. struct hostent *hp;
  322. int addr, address[4];
  323. if ((hp = gethostbyname(host)) == NULL)
  324. {
  325. chat_printf("Failed to call %s, unknown host.", host);
  326. return NULL;
  327. }
  328. memcpy((char *)&dest_addr.sin_addr, hp->h_addr, sizeof(dest_addr.sin_addr));
  329. addr = ntohl(dest_addr.sin_addr.s_addr);
  330. address[0] = ( addr >> 24 ) & 0xFF ;
  331. address[1] = ( addr >> 16 ) & 0xFF ;
  332. address[2] = ( addr >> 8 ) & 0xFF ;
  333. address[3] = ( addr ) & 0xFF ;
  334. sprintf(host, "%d.%d.%d.%d", address[0], address[1], address[2], address[3]);
  335. }
  336. if (is_number(port))
  337. {
  338. dest_addr.sin_port = htons(atoi(port));
  339. }
  340. else
  341. {
  342. chat_printf("The port should be a number.");
  343. return NULL;
  344. }
  345. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  346. {
  347. syserr_printf(gtd->ses, "old_threaded_chat_call: socket");
  348. return NULL;
  349. }
  350. dest_addr.sin_family = AF_INET;
  351. if (connect(sock, (struct sockaddr *)&dest_addr, sizeof(dest_addr)) != 0)
  352. {
  353. chat_printf("Failed to connect to %s:%s", host, port);
  354. close(sock);
  355. return NULL;
  356. }
  357. FD_ZERO(&wds);
  358. FD_SET(sock, &wds);
  359. if (select(FD_SETSIZE, NULL, &wds, NULL, &to) == -1)
  360. {
  361. chat_printf("Failed to connect to %s %s", host, port);
  362. close(sock);
  363. return NULL;
  364. }
  365. if (!FD_ISSET(sock, &wds))
  366. {
  367. chat_printf("Connection timed out.");
  368. close(sock);
  369. return NULL;
  370. }
  371. new_buddy = (struct chat_data *) calloc(1, sizeof(struct chat_data));
  372. new_buddy->fd = sock;
  373. new_buddy->port = atoi(port);
  374. new_buddy->download = strdup("");
  375. new_buddy->group = strdup("");
  376. new_buddy->ip = strdup(host);
  377. new_buddy->name = strdup("");
  378. new_buddy->version = strdup("");
  379. strip_vt102_codes(gtd->chat->name, name);
  380. chat_socket_printf(new_buddy, "CHAT:%s\n%s%-5u", name, gtd->chat->ip, gtd->chat->port);
  381. chat_printf("Socket connected, negotiating protocol...");
  382. FD_ZERO(&rds);
  383. FD_SET(sock, &rds);
  384. to.tv_sec = CALL_TIMEOUT;
  385. to.tv_usec = 0;
  386. if (select(FD_SETSIZE, &rds, NULL, NULL, &to) == -1)
  387. {
  388. close_chat(new_buddy, FALSE);
  389. return NULL;
  390. }
  391. if (process_chat_input(new_buddy) == -1)
  392. {
  393. FD_CLR(new_buddy->fd, &rds);
  394. close_chat(new_buddy, FALSE);
  395. return NULL;
  396. }
  397. if (gtd->chat == NULL || *new_buddy->name == 0)
  398. {
  399. close_chat(new_buddy, FALSE);
  400. }
  401. else
  402. {
  403. if (fcntl(sock, F_SETFL, O_NDELAY|O_NONBLOCK) == -1)
  404. {
  405. syserr_printf(gtd->ses, "chat_new: fcntl O_NDELAY|O_NONBLOCK");
  406. }
  407. LINK(new_buddy, gtd->chat->next, gtd->chat->prev);
  408. chat_printf("Connection made to %s.", new_buddy->name);
  409. }
  410. return NULL;
  411. }
  412. */
  413. #ifdef HAVE_LIBPTHREAD
  414. DO_CHAT(chat_call)
  415. {
  416. static char buf[100][200];
  417. static int i;
  418. pthread_t thread;
  419. if (strlen(arg1) + strlen(arg2) + 5 >= 200)
  420. {
  421. chat_printf("The call arguments {%s} and {%s} exceed the maximum length of 200 characters.", arg1, arg2);
  422. return;
  423. }
  424. sprintf(buf[i], "{%s} {%s}", arg1, arg2);
  425. pthread_create(&thread, NULL, threaded_chat_call, (void *) buf[i]);
  426. if (++i > 99)
  427. {
  428. i = 0;
  429. }
  430. }
  431. #else
  432. DO_CHAT(chat_call)
  433. {
  434. char buf[BUFFER_SIZE];
  435. sprintf(buf, "{%s} {%s}", arg1, arg2);
  436. threaded_chat_call((void *) buf);
  437. }
  438. #endif
  439. void close_chat(struct chat_data *buddy, int unlink)
  440. {
  441. buddy->flags = 0;
  442. if (buddy == gtd->chat->update)
  443. {
  444. gtd->chat->update = buddy->next;
  445. }
  446. if (unlink)
  447. {
  448. UNLINK(buddy, gtd->chat->next, gtd->chat->prev);
  449. }
  450. if (buddy != gtd->chat)
  451. {
  452. if (*buddy->name == 0)
  453. {
  454. chat_printf("Closing connection to %s D%d", buddy->ip, buddy->fd);
  455. }
  456. else
  457. {
  458. chat_printf("Closing connection to %s@%s.", buddy->name, buddy->ip);
  459. }
  460. }
  461. close(buddy->fd);
  462. free(buddy->download);
  463. free(buddy->group);
  464. free(buddy->ip);
  465. free(buddy->name);
  466. free(buddy->version);
  467. free(buddy);
  468. }
  469. void process_chat_connections(fd_set *read_set, fd_set *write_set, fd_set *exc_set)
  470. {
  471. struct chat_data *buddy;
  472. push_call("process_chat_connections(%p,%p,%p)",read_set,write_set,exc_set);
  473. if (FD_ISSET(gtd->chat->fd, read_set))
  474. {
  475. chat_new(gtd->chat->fd);
  476. }
  477. for (buddy = gtd->chat->next ; buddy ; buddy = gtd->chat->update)
  478. {
  479. gtd->chat->update = buddy->next;
  480. if (HAS_BIT(buddy->flags, CHAT_FLAG_LINKLOST) || FD_ISSET(buddy->fd, exc_set))
  481. {
  482. FD_CLR(buddy->fd, write_set);
  483. FD_CLR(buddy->fd, read_set);
  484. close_chat(buddy, TRUE);
  485. }
  486. else if (FD_ISSET(buddy->fd, read_set) && process_chat_input(buddy) < 0)
  487. {
  488. FD_CLR(buddy->fd, write_set);
  489. FD_CLR(buddy->fd, read_set);
  490. close_chat(buddy, TRUE);
  491. }
  492. }
  493. pop_call();
  494. return;
  495. }
  496. void chat_socket_printf(struct chat_data *buddy, char *format, ...)
  497. {
  498. char buf[BUFFER_SIZE];
  499. va_list args;
  500. va_start(args, format);
  501. vsnprintf(buf, BUFFER_SIZE / 3, format, args);
  502. va_end(args);
  503. if (!HAS_BIT(buddy->flags, CHAT_FLAG_LINKLOST))
  504. {
  505. if (write(buddy->fd, buf, strlen(buf)) < 0)
  506. {
  507. chat_printf("%s went link lost.", buddy->name);
  508. SET_BIT(buddy->flags, CHAT_FLAG_LINKLOST);
  509. }
  510. }
  511. }
  512. void chat_printf(char *format, ...)
  513. {
  514. struct chat_data *buddy;
  515. char buf[STRING_SIZE], tmp[STRING_SIZE];
  516. va_list args;
  517. va_start(args, format);
  518. vsnprintf(buf, BUFFER_SIZE / 3, format, args);
  519. va_end(args);
  520. if (strncmp(buf, gtd->chat->prefix, strlen(gtd->chat->prefix)))
  521. {
  522. sprintf(tmp, "%s%s", gtd->chat->prefix, buf);
  523. }
  524. else
  525. {
  526. sprintf(tmp, "%s", buf);
  527. }
  528. strip_vt102_codes_non_graph(tmp, buf);
  529. sprintf(tmp, "%c%s%c", CHAT_SNOOP_DATA, buf, CHAT_END_OF_COMMAND);
  530. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  531. {
  532. if (HAS_BIT(buddy->flags, CHAT_FLAG_FORWARD) && !HAS_BIT(buddy->flags, CHAT_FLAG_FORWARDALL))
  533. {
  534. chat_socket_printf(buddy, "%s", tmp);
  535. }
  536. }
  537. sprintf(tmp, "%s%s%s", gtd->chat->color, buf, "\e[0m");
  538. check_all_events(gtd->ses, SUB_ARG|SUB_SEC, 0, 2, "CHAT MESSAGE", tmp, buf);
  539. if (!check_all_events(gtd->ses, SUB_ARG|SUB_SEC, 0, 2, "CATCH CHAT MESSAGE", tmp, buf))
  540. {
  541. tintin_puts(NULL, tmp);
  542. }
  543. }
  544. int process_chat_input(struct chat_data *buddy)
  545. {
  546. struct chat_data *node;
  547. char buf[BUFFER_SIZE], name[BUFFER_SIZE], temp[BUFFER_SIZE], ip[BUFFER_SIZE], *sep;
  548. int size;
  549. push_call("process_chat_input(%p)",buddy);
  550. size = read(buddy->fd, buf, BUFFER_SIZE / 3);
  551. if (size <= 0)
  552. {
  553. pop_call();
  554. return -1;
  555. }
  556. buf[size] = 0;
  557. if (!strncmp(buf, "CHAT:", 5))
  558. {
  559. if ((sep = strchr(buf, '\n')) != NULL)
  560. {
  561. *sep = 0;
  562. strcpy(temp, &buf[5]);
  563. strcpy(ip, &sep[1]);
  564. if (strlen(ip) >= 5)
  565. {
  566. buddy->port = atoi(ip + strlen(ip) - 5);
  567. }
  568. strip_vt102_codes(temp, name);
  569. RESTRING(buddy->name, name);
  570. buddy->timeout = 0;
  571. if (strlen(buddy->name) > 20)
  572. {
  573. chat_socket_printf(buddy, "%c\n%s has refused your connection because your name is too long.\n%c", CHAT_MESSAGE, gtd->chat->name, name, CHAT_END_OF_COMMAND);
  574. chat_printf("Refusing connection from %.21s:%d, name too long. (%d characters)", buddy->ip, buddy->port, strlen(buddy->name));
  575. pop_call();
  576. return -1;
  577. }
  578. for (node = gtd->chat ; node ; node = node->next)
  579. {
  580. if (node != buddy && !strcasecmp(name, node->name))
  581. {
  582. if (!strcmp(buddy->ip, node->ip))
  583. {
  584. close_chat(node, TRUE);
  585. break;
  586. }
  587. else
  588. {
  589. chat_socket_printf(buddy, "%c\n%s is already connected to someone named %s.\n%c", CHAT_MESSAGE, gtd->chat->name, name, CHAT_END_OF_COMMAND);
  590. chat_printf("Refusing connection from %s:%d, already connected to someone named %s.", buddy->ip, buddy->port, name);
  591. pop_call();
  592. return -1;
  593. }
  594. }
  595. }
  596. if (!strcasecmp(buddy->name, "ALL"))
  597. {
  598. chat_socket_printf(buddy, "%c\n%s is an invalid name.\n%c", CHAT_MESSAGE, name, CHAT_END_OF_COMMAND);
  599. chat_printf("Refusing connection from %s:%d, %s is an invalid name.", buddy->ip, buddy->port, name);
  600. pop_call();
  601. return -1;
  602. }
  603. }
  604. strip_vt102_codes(gtd->chat->name, name);
  605. chat_socket_printf(buddy, "YES:%s\n", name);
  606. chat_printf("Connected to %s@%s:%d", buddy->name, buddy->ip, buddy->port);
  607. pop_call();
  608. return 1;
  609. }
  610. if (!strncmp(buf, "YES:", 4))
  611. {
  612. if ((sep = strchr(buf, '\n')) != NULL)
  613. {
  614. *sep++ = 0;
  615. strcpy(temp, buf);
  616. strip_vt102_codes(&temp[4], name);
  617. RESTRING(buddy->name, name);
  618. chat_socket_printf(buddy, "%c%s %s%c", CHAT_VERSION, CLIENT_NAME, CLIENT_VERSION, CHAT_END_OF_COMMAND);
  619. get_chat_commands(buddy, sep, size - strlen(temp) - 1);
  620. pop_call();
  621. return 0;
  622. }
  623. else
  624. {
  625. chat_printf("Error in processing connection negotiation with %s@%s", buddy->name, buddy->ip);
  626. pop_call();
  627. return -1;
  628. }
  629. }
  630. if (!strncmp(buf, "NO", 2))
  631. {
  632. chat_printf("Connection negotation refused by %s@%s", buddy->name, buddy->ip);
  633. pop_call();
  634. return -1;
  635. }
  636. get_chat_commands(buddy, buf, size);
  637. pop_call();
  638. return 0;
  639. }
  640. void get_chat_commands(struct chat_data *buddy, char *buf, int len)
  641. {
  642. char txt[BUFFER_SIZE];
  643. unsigned char *pto, *pti, ptc;
  644. int size;
  645. push_call("get_chat_commands(%s,%d,%s)",buddy->name,len,buf);
  646. pti = (unsigned char *) buf;
  647. pto = (unsigned char *) txt;
  648. while (*pti == CHAT_FILE_BLOCK || gtd->chat->file_block_patch)
  649. {
  650. if (gtd->chat->file_block_patch)
  651. {
  652. size = receive_block(pti, buddy, len);
  653. len -= size;
  654. pti += size;
  655. }
  656. else
  657. {
  658. len--;
  659. pti++;
  660. size = receive_block(pti, buddy, len);
  661. len -= size;
  662. pti += size;
  663. if (len <= 0)
  664. {
  665. pop_call();
  666. return;
  667. }
  668. }
  669. }
  670. while (*pti && buddy)
  671. {
  672. ptc = *pti++;
  673. pto = (unsigned char *) txt;
  674. while (isspace(*pti))
  675. {
  676. pti++;
  677. }
  678. while (*pti != CHAT_END_OF_COMMAND)
  679. {
  680. if (*pti == 0)
  681. {
  682. chat_printf("Unterminated command: %d %s", ptc, buf);
  683. pop_call();
  684. return;
  685. }
  686. *pto++ = *pti++;
  687. }
  688. *pto-- = 0;
  689. while (isspace(*pto))
  690. {
  691. *pto-- = 0;
  692. }
  693. switch (ptc)
  694. {
  695. case CHAT_NAME_CHANGE:
  696. chat_name_change(buddy, txt);
  697. break;
  698. case CHAT_REQUEST_CONNECTIONS:
  699. request_response(buddy);
  700. break;
  701. case CHAT_CONNECTION_LIST:
  702. parse_requested_connections(buddy, txt);
  703. break;
  704. case CHAT_TEXT_EVERYBODY:
  705. chat_receive_text_everybody(buddy, txt);
  706. break;
  707. case CHAT_TEXT_PERSONAL:
  708. chat_receive_text_personal(buddy, txt);
  709. break;
  710. case CHAT_TEXT_GROUP:
  711. chat_receive_text_group(buddy, txt);
  712. break;
  713. case CHAT_MESSAGE:
  714. chat_receive_message(buddy, txt);
  715. break;
  716. case CHAT_DO_NOT_DISTURB:
  717. chat_printf("%s has enabled DND.", buddy->name);
  718. break;
  719. case CHAT_SEND_ACTION:
  720. case CHAT_SEND_ALIAS:
  721. case CHAT_SEND_VARIABLE:
  722. case CHAT_SEND_EVENT:
  723. case CHAT_SEND_GAG:
  724. case CHAT_SEND_HIGHLIGHT:
  725. case CHAT_SEND_LIST:
  726. case CHAT_SEND_ARRAY:
  727. case CHAT_SEND_BARITEM:
  728. chat_socket_printf(buddy, "%c%s%c", CHAT_MESSAGE, "\nTintin++ does not support this.\n", CHAT_END_OF_COMMAND);
  729. break;
  730. case CHAT_VERSION:
  731. if (*buddy->version == 0 && *txt != 0)
  732. {
  733. chat_socket_printf(buddy, "%c%s %s%c", CHAT_VERSION, CLIENT_NAME, CLIENT_VERSION, CHAT_END_OF_COMMAND);
  734. RESTRING(buddy->version, txt);
  735. }
  736. break;
  737. case CHAT_FILE_START:
  738. chat_receive_file(txt, buddy);
  739. break;
  740. case CHAT_FILE_DENY:
  741. file_denied(buddy, txt);
  742. break;
  743. case CHAT_FILE_BLOCK_REQUEST:
  744. send_block(buddy);
  745. break;
  746. case CHAT_FILE_END:
  747. chat_printf("File transfer completion acknowledged.");
  748. break;
  749. case CHAT_FILE_CANCEL:
  750. chat_printf("File cancel request received.");
  751. file_cleanup(buddy);
  752. break;
  753. case CHAT_PING_REQUEST:
  754. chat_socket_printf(buddy, "%c%s%c", CHAT_PING_RESPONSE, txt, CHAT_END_OF_COMMAND);
  755. break;
  756. case CHAT_PING_RESPONSE:
  757. ping_response(buddy, txt);
  758. break;
  759. case CHAT_PEEK_CONNECTIONS:
  760. peek_response(buddy);
  761. break;
  762. case CHAT_PEEK_LIST:
  763. parse_peeked_connections(buddy, txt);
  764. break;
  765. case CHAT_SNOOP_START:
  766. break;
  767. case CHAT_SNOOP_DATA:
  768. SET_BIT(buddy->flags, CHAT_FLAG_FORWARDBY);
  769. DEL_BIT(buddy->flags, CHAT_FLAG_FORWARD);
  770. DEL_BIT(buddy->flags, CHAT_FLAG_FORWARDALL);
  771. chat_receive_snoop_data(buddy, txt);
  772. break;
  773. default:
  774. chat_printf("get_chat_commands: unknown option [%d] from %s@%s:%d (%s)", ptc, buddy->name, buddy->ip, buddy->port, txt);
  775. break;
  776. }
  777. pti++;
  778. }
  779. pop_call();
  780. return;
  781. }
  782. void chat_name_change(struct chat_data *buddy, char *txt)
  783. {
  784. char temp[BUFFER_SIZE], name[BUFFER_SIZE];
  785. struct chat_data *node;
  786. strip_vt102_codes(txt, name);
  787. if (strlen(name) > 20)
  788. {
  789. chat_socket_printf(buddy, "%c\n%s has refused your name change because your name is too long.\n%c", CHAT_MESSAGE, gtd->chat->name, name, CHAT_END_OF_COMMAND);
  790. chat_printf("Refusing connection from %.21s:%d, name too long. (%d characters)", buddy->ip, buddy->port, strlen(name));
  791. close_chat(buddy, TRUE);
  792. return;
  793. }
  794. for (node = gtd->chat ; node ; node = node->next)
  795. {
  796. if (node != buddy && !strcmp(name, node->name))
  797. {
  798. chat_socket_printf(buddy, "%c\n%s is already connected to someone named %s.\n%c", CHAT_MESSAGE, gtd->chat->name, name, CHAT_END_OF_COMMAND);
  799. chat_printf("Refusing name change from %s@%s:%d, already connected to someone named %s.", buddy->name, buddy->ip, buddy->port, name);
  800. close_chat(buddy, TRUE);
  801. return;
  802. }
  803. }
  804. if (!strcasecmp(name, "ALL"))
  805. {
  806. chat_socket_printf(buddy, "%c\n%s is an invalid name.\n%c", CHAT_MESSAGE, name, CHAT_END_OF_COMMAND);
  807. chat_printf("Refusing name change from %s@%s:%d, %s is an invalid name.", buddy->name, buddy->ip, buddy->port, name);
  808. close_chat(buddy, TRUE);
  809. return;
  810. }
  811. if (strcmp(name, buddy->name))
  812. {
  813. strcpy(temp, buddy->name);
  814. RESTRING(buddy->name, name);
  815. chat_printf("%s is now %s.", temp, txt);
  816. }
  817. }
  818. void chat_receive_text_everybody(struct chat_data *buddy, char *txt)
  819. {
  820. struct chat_data *node;
  821. if (HAS_BIT(buddy->flags, CHAT_FLAG_IGNORE))
  822. {
  823. return;
  824. }
  825. chat_printf("%s", txt);
  826. if (HAS_BIT(buddy->flags, CHAT_FLAG_SERVE))
  827. {
  828. for (node = gtd->chat->next ; node ; node = node->next)
  829. {
  830. if (node != buddy)
  831. {
  832. chat_socket_printf(node, "%c\n%s %s[Served By %s%s]\n%c", CHAT_MESSAGE, txt, gtd->chat->color, gtd->chat->name, gtd->chat->color, CHAT_END_OF_COMMAND);
  833. }
  834. }
  835. }
  836. else
  837. {
  838. for (node = gtd->chat->next ; node ; node = node->next)
  839. {
  840. if (HAS_BIT(node->flags, CHAT_FLAG_SERVE))
  841. {
  842. chat_socket_printf(node, "%c\n%s %s[Served By %s%s]\n%c", CHAT_MESSAGE, txt, gtd->chat->color, gtd->chat->name, gtd->chat->color, CHAT_END_OF_COMMAND);
  843. }
  844. }
  845. }
  846. }
  847. void chat_receive_text_personal(struct chat_data *buddy, char *txt)
  848. {
  849. if (HAS_BIT(buddy->flags, CHAT_FLAG_IGNORE))
  850. {
  851. return;
  852. }
  853. RESTRING(gtd->chat->reply, buddy->name);
  854. chat_printf("%s", txt);
  855. }
  856. void chat_receive_text_group(struct chat_data *buddy, char *txt)
  857. {
  858. if (HAS_BIT(buddy->flags, CHAT_FLAG_IGNORE))
  859. {
  860. return;
  861. }
  862. if (strlen(txt) > 16)
  863. {
  864. chat_printf("%s", &txt[16]);
  865. }
  866. }
  867. void chat_receive_message(struct chat_data *buddy, char *txt)
  868. {
  869. if (HAS_BIT(buddy->flags, CHAT_FLAG_IGNORE))
  870. {
  871. return;
  872. }
  873. chat_printf("%s", txt);
  874. }
  875. void chat_receive_snoop_data(struct chat_data *buddy, char *txt)
  876. {
  877. if (HAS_BIT(buddy->flags, CHAT_FLAG_IGNORE))
  878. {
  879. return;
  880. }
  881. chat_printf("%s", txt);
  882. }
  883. void peek_response(struct chat_data *peeker)
  884. {
  885. struct chat_data *buddy;
  886. char buf[BUFFER_SIZE];
  887. for (buf[0] = 0, buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  888. {
  889. if (!HAS_BIT(buddy->flags, CHAT_FLAG_PRIVATE))
  890. {
  891. cat_sprintf(buf, "%s~%d~%s~", buddy->ip, buddy->port, buddy->name);
  892. }
  893. }
  894. chat_socket_printf(peeker, "%c%s%c", CHAT_PEEK_LIST, buf, CHAT_END_OF_COMMAND);
  895. return;
  896. }
  897. void parse_peeked_connections(struct chat_data *buddy, char *txt)
  898. {
  899. char *comma, ip[BUFFER_SIZE], port[BUFFER_SIZE], name[BUFFER_SIZE];
  900. if (*txt == 0)
  901. {
  902. chat_printf("%s has no public connections.", buddy->name);
  903. return;
  904. }
  905. ip[0] = port[0] = name[0] = 0;
  906. comma = txt;
  907. chat_printf(" %-15s %-15s %-5s", "Name", "Address", "Port");
  908. chat_printf(" --------------- --------------- ----- ");
  909. while (comma)
  910. {
  911. comma = strchr(txt, '~');
  912. if (comma)
  913. {
  914. *comma = 0;
  915. }
  916. if (*ip == 0)
  917. {
  918. strcpy(ip, txt);
  919. }
  920. else if (*port == 0)
  921. {
  922. strcpy(port, txt);
  923. }
  924. else
  925. {
  926. strcpy(name, txt);
  927. }
  928. if (comma)
  929. {
  930. txt += strlen(txt) + 1;
  931. }
  932. if (*ip && *port && *name)
  933. {
  934. chat_printf(" %-15s %-15s %-5s", name, ip, port);
  935. *port = 0;
  936. *ip = 0;
  937. *name = 0;
  938. }
  939. }
  940. return;
  941. }
  942. void ping_response(struct chat_data *ch, char *time)
  943. {
  944. chat_printf("Ping response time for %s: %lld ms", ch->name, (utime() - atoll(time)) / 1000);
  945. }
  946. void request_response(struct chat_data *requester)
  947. {
  948. struct chat_data *buddy;
  949. char buf[BUFFER_SIZE], tmp[BUFFER_SIZE];
  950. chat_printf("%s has requested your public connections.", requester->name);
  951. for (buf[0] = 0, buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  952. {
  953. if (buddy != requester && !HAS_BIT(buddy->flags, CHAT_FLAG_PRIVATE))
  954. {
  955. sprintf(tmp, "%s,%-5u", buddy->ip, buddy->port);
  956. if (*buf)
  957. {
  958. strcat(buf, ",");
  959. }
  960. strcat(buf, tmp);
  961. }
  962. }
  963. chat_socket_printf(requester, "%c%s%c", CHAT_CONNECTION_LIST, buf, CHAT_END_OF_COMMAND);
  964. return;
  965. }
  966. void parse_requested_connections(struct chat_data *buddy, char *txt)
  967. {
  968. struct chat_data *node;
  969. char *comma, ip[BUFFER_SIZE], port[BUFFER_SIZE];
  970. if (!HAS_BIT(buddy->flags, CHAT_FLAG_REQUEST))
  971. {
  972. chat_printf("%s tried to force your client to connect to: %s.", buddy->name, txt);
  973. return;
  974. }
  975. ip[0] = 0;
  976. port[0] = 0;
  977. comma = txt;
  978. while (comma)
  979. {
  980. comma = strchr(txt, ',');
  981. if (comma)
  982. {
  983. *comma = 0;
  984. }
  985. if (*ip == 0)
  986. {
  987. strcpy(ip, txt);
  988. }
  989. else
  990. {
  991. strcpy(port, txt);
  992. }
  993. if (comma)
  994. {
  995. txt += strlen(txt) + 1;
  996. }
  997. if (*ip && *port)
  998. {
  999. for (node = gtd->chat->next ; node ; node = node->next)
  1000. {
  1001. if (!strcmp(ip, node->ip) && atoi(port) == node->port)
  1002. {
  1003. chat_printf("skipping known address: %s port %s", ip, port);
  1004. break;
  1005. }
  1006. }
  1007. if (node == NULL)
  1008. {
  1009. chat_call(ip, port);
  1010. }
  1011. *port = 0;
  1012. *ip = 0;
  1013. }
  1014. }
  1015. DEL_BIT(buddy->flags, CHAT_FLAG_REQUEST);
  1016. return;
  1017. }
  1018. DO_CHAT(chat_downloaddir)
  1019. {
  1020. char dir[BUFFER_SIZE];
  1021. sprintf(dir, "%s%s", arg1, !str_suffix(arg1, "/") ? "" : "/");
  1022. RESTRING(gtd->chat->download, dir);
  1023. chat_printf("Download directory set to '%s'", gtd->chat->download);
  1024. }
  1025. DO_CHAT(chat_emote)
  1026. {
  1027. struct chat_data *buddy;
  1028. substitute(gtd->ses, arg2, arg2, SUB_COL|SUB_ESC);
  1029. if (!strcasecmp(arg1, "ALL"))
  1030. {
  1031. chat_printf("You emote to everyone: %s %s", gtd->chat->name, arg2);
  1032. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1033. {
  1034. chat_socket_printf(buddy, "%c\n%s %s\n%c", CHAT_TEXT_EVERYBODY, gtd->chat->name, arg2, CHAT_END_OF_COMMAND);
  1035. }
  1036. }
  1037. else
  1038. {
  1039. if ((buddy = find_buddy(arg1)) != NULL)
  1040. {
  1041. chat_printf("You emote to %s: %s %s", buddy->name, gtd->chat->name, arg2);
  1042. chat_socket_printf(buddy, "%c\n%s %s\n%c", CHAT_TEXT_PERSONAL, gtd->chat->name, arg2, CHAT_END_OF_COMMAND);
  1043. }
  1044. else if (find_group(arg1) != NULL)
  1045. {
  1046. chat_printf("You emote to %s: %s", arg1, arg2);
  1047. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1048. {
  1049. if (!strcmp(buddy->group, arg1))
  1050. {
  1051. chat_socket_printf(buddy, "%c%-15s\n%s %s\n%c", CHAT_TEXT_GROUP, buddy->group, gtd->chat->name, arg2, CHAT_END_OF_COMMAND);
  1052. }
  1053. }
  1054. }
  1055. else
  1056. {
  1057. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1058. }
  1059. }
  1060. }
  1061. DO_CHAT(chat_info)
  1062. {
  1063. tintin_printf2(NULL, "Name : %s", gtd->chat->name);
  1064. tintin_printf2(NULL, "IP Address : %s", gtd->chat->ip);
  1065. tintin_printf2(NULL, "Chat Port : %d", gtd->chat->port);
  1066. tintin_printf2(NULL, "Download Dir : %s", gtd->chat->download);
  1067. tintin_printf2(NULL, "Reply : %s", gtd->chat->reply);
  1068. tintin_printf2(NULL, "Prefix : %s", gtd->chat->prefix);
  1069. tintin_printf2(NULL, "Color : %s", str_convert_meta(gtd->chat->color, TRUE));
  1070. tintin_printf2(NULL, "DND : %s", HAS_BIT(gtd->chat->flags, CHAT_FLAG_DND) ? "Yes" : "No");
  1071. }
  1072. DO_CHAT(chat_ip)
  1073. {
  1074. RESTRING(gtd->chat->ip, arg1);
  1075. chat_printf("IP changed to %s", gtd->chat->ip);
  1076. }
  1077. DO_CHAT(chat_message)
  1078. {
  1079. struct chat_data *buddy;
  1080. substitute(gtd->ses, arg2, arg2, SUB_COL|SUB_ESC);
  1081. if (!strcasecmp(arg1, "ALL"))
  1082. {
  1083. chat_printf("You chat to everyone, '%s'", arg2);
  1084. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1085. {
  1086. chat_socket_printf(buddy, "%c\n%s chats to everyone, '%s'\n%c", CHAT_TEXT_EVERYBODY, gtd->chat->name, arg2, CHAT_END_OF_COMMAND);
  1087. }
  1088. }
  1089. else
  1090. {
  1091. if ((buddy = find_buddy(arg1)) != NULL)
  1092. {
  1093. chat_printf("You chat to %s, '%s'", buddy->name, arg2);
  1094. chat_socket_printf(buddy, "%c\n%s chats to you, '%s'\n%c", CHAT_TEXT_PERSONAL, gtd->chat->name, arg2, CHAT_END_OF_COMMAND);
  1095. }
  1096. else if (find_group(arg1) != NULL)
  1097. {
  1098. chat_printf("You chat to %s, '%s'", arg1, arg2);
  1099. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1100. {
  1101. if (!strcmp(buddy->group, arg1))
  1102. {
  1103. chat_socket_printf(buddy, "%c%-15s\n%s chats to the group, '%s'\n%c", CHAT_TEXT_GROUP, buddy->group, gtd->chat->name, arg2, CHAT_END_OF_COMMAND);
  1104. }
  1105. }
  1106. }
  1107. else
  1108. {
  1109. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1110. }
  1111. }
  1112. }
  1113. DO_CHAT(chat_name)
  1114. {
  1115. struct chat_data *buddy;
  1116. substitute(gtd->ses, arg1, arg1, SUB_COL|SUB_ESC);
  1117. if (!strcmp(gtd->chat->name, arg1))
  1118. {
  1119. chat_printf("Your name is already set to %s.", gtd->chat->name);
  1120. return;
  1121. }
  1122. if (strip_vt102_strlen(gtd->ses, arg1) > 20)
  1123. {
  1124. chat_printf("Your name cannot be longer than 20 characters.");
  1125. return;
  1126. }
  1127. RESTRING(gtd->chat->name, arg1);
  1128. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1129. {
  1130. chat_socket_printf(buddy, "%c%s%c", CHAT_NAME_CHANGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1131. }
  1132. chat_printf("Name changed to %s.", gtd->chat->name);
  1133. }
  1134. DO_CHAT(chat_paste)
  1135. {
  1136. struct chat_data *buddy;
  1137. char temp[BUFFER_SIZE + 2], name[BUFFER_SIZE], *arg;
  1138. if (arg1 == NULL)
  1139. {
  1140. if (strlen(gtd->input_buf))
  1141. {
  1142. sprintf(temp, "%s\n%s", gtd->chat->paste_buf, gtd->input_buf);
  1143. RESTRING(gtd->chat->paste_buf, temp);
  1144. cursor_clear_line(gtd->ses, "");
  1145. }
  1146. arg = get_arg_in_braces(gtd->ses, gtd->chat->paste_buf, name, GET_ONE);
  1147. sprintf(temp, "%s\n<078>======================================================================", arg);
  1148. substitute(gtd->ses, temp, temp, SUB_COL|SUB_ESC);
  1149. RESTRING(gtd->chat->paste_buf, temp);
  1150. if (!strcasecmp(name, "ALL"))
  1151. {
  1152. chat_printf("You paste to everyone:\n%s", gtd->chat->paste_buf);
  1153. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1154. {
  1155. chat_socket_printf(buddy, "%c\n%s pastes to everyone:\n%s\n%c", CHAT_TEXT_EVERYBODY, gtd->chat->name, gtd->chat->paste_buf, CHAT_END_OF_COMMAND);
  1156. }
  1157. }
  1158. else
  1159. {
  1160. if ((buddy = find_buddy(name)) != NULL)
  1161. {
  1162. chat_printf("You paste to %s:\n%s", buddy->name, gtd->chat->paste_buf);
  1163. chat_socket_printf(buddy, "%c\n%s pastes to you:\n%s\n%c", CHAT_TEXT_EVERYBODY, gtd->chat->name, gtd->chat->paste_buf, CHAT_END_OF_COMMAND);
  1164. }
  1165. else if (find_group(name) != NULL)
  1166. {
  1167. chat_printf("You paste to %s:\n%s", name, gtd->chat->paste_buf);
  1168. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1169. {
  1170. if (!strcmp(buddy->group, name))
  1171. {
  1172. chat_socket_printf(buddy, "%c%-15s\n%s pastes to the group:\n%s\n%c", CHAT_TEXT_GROUP, buddy->group, gtd->chat->name, gtd->chat->paste_buf, CHAT_END_OF_COMMAND);
  1173. }
  1174. }
  1175. }
  1176. else
  1177. {
  1178. chat_printf("You are not connected to anyone named '%s'.", name);
  1179. }
  1180. }
  1181. if (IS_SPLIT(gtd->ses))
  1182. {
  1183. erase_toeol();
  1184. }
  1185. gtd->chat->paste_time = 0;
  1186. return;
  1187. }
  1188. if (gtd->chat->paste_time)
  1189. {
  1190. sprintf(temp, "%s\n%s", gtd->chat->paste_buf, arg1);
  1191. RESTRING(gtd->chat->paste_buf, temp);
  1192. gtd->chat->paste_time = 200000LL + utime();
  1193. return;
  1194. }
  1195. gtd->chat->paste_time = 400000LL + utime();
  1196. sprintf(temp, "{%s}<078>======================================================================\n<068>%s", arg1, arg2);
  1197. RESTRING(gtd->chat->paste_buf, temp);
  1198. }
  1199. DO_CHAT(chat_peek)
  1200. {
  1201. struct chat_data *buddy;
  1202. if ((buddy = find_buddy(arg1)) == NULL)
  1203. {
  1204. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1205. return;
  1206. }
  1207. chat_socket_printf(buddy, "%c%c", CHAT_PEEK_CONNECTIONS, CHAT_END_OF_COMMAND);
  1208. }
  1209. DO_CHAT(chat_ping)
  1210. {
  1211. struct chat_data *buddy;
  1212. if ((buddy = find_buddy(arg1)) == NULL)
  1213. {
  1214. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1215. return;
  1216. }
  1217. chat_socket_printf(buddy, "%c%lld%c", CHAT_PING_REQUEST, utime(), CHAT_END_OF_COMMAND);
  1218. chat_printf("Ping request sent to %s.", buddy->name);
  1219. }
  1220. DO_CHAT(chat_prefix)
  1221. {
  1222. RESTRING(gtd->chat->prefix, arg1);
  1223. chat_printf("Prefix set to '%s'", gtd->chat->prefix);
  1224. }
  1225. DO_CHAT(chat_reply)
  1226. {
  1227. struct chat_data *buddy;
  1228. substitute(gtd->ses, arg1, arg1, SUB_COL|SUB_ESC);
  1229. if ((buddy = find_buddy(gtd->chat->reply)) != NULL)
  1230. {
  1231. chat_printf("You reply to %s, '%s'", buddy->name, arg1);
  1232. chat_socket_printf(buddy, "%c\n%s replies to you, '%s'\n%c", CHAT_TEXT_PERSONAL, gtd->chat->name, arg1, CHAT_END_OF_COMMAND);
  1233. }
  1234. else
  1235. {
  1236. chat_printf("You are not connected to anyone named '%s'.", gtd->chat->reply);
  1237. }
  1238. }
  1239. DO_CHAT(chat_request)
  1240. {
  1241. struct chat_data *buddy;
  1242. if ((buddy = find_buddy(arg1)) == NULL)
  1243. {
  1244. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1245. return;
  1246. }
  1247. chat_socket_printf(buddy, "%c%c", CHAT_REQUEST_CONNECTIONS, CHAT_END_OF_COMMAND);
  1248. chat_printf("You request %s's public connections.", buddy->name);
  1249. SET_BIT(buddy->flags, CHAT_FLAG_REQUEST);
  1250. return;
  1251. }
  1252. DO_CHAT(chat_send)
  1253. {
  1254. struct chat_data *buddy;
  1255. substitute(gtd->ses, arg2, arg2, SUB_COL|SUB_ESC);
  1256. if (!strcasecmp(arg1, "ALL"))
  1257. {
  1258. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1259. {
  1260. chat_socket_printf(buddy, "%s", arg2);
  1261. }
  1262. }
  1263. else
  1264. {
  1265. if ((buddy = find_buddy(arg1)) != NULL)
  1266. {
  1267. chat_socket_printf(buddy, "%s", arg2);
  1268. }
  1269. else if (find_group(arg1) != NULL)
  1270. {
  1271. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1272. {
  1273. if (!strcmp(buddy->group, arg1))
  1274. {
  1275. chat_socket_printf(buddy, "%s", arg2);
  1276. }
  1277. }
  1278. }
  1279. else
  1280. {
  1281. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1282. }
  1283. }
  1284. }
  1285. DO_CHAT(chat_serve)
  1286. {
  1287. struct chat_data *buddy;
  1288. if ((buddy = find_buddy(arg1)) == NULL)
  1289. {
  1290. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1291. return;
  1292. }
  1293. TOG_BIT(buddy->flags, CHAT_FLAG_SERVE);
  1294. if (HAS_BIT(buddy->flags, CHAT_FLAG_SERVE))
  1295. {
  1296. chat_printf("You are now chat serving %s.", buddy->name);
  1297. chat_socket_printf(buddy, "%c\n%s is now chat serving you.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1298. }
  1299. else
  1300. {
  1301. chat_printf("You are no longer chat serving %s.", buddy->name);
  1302. chat_socket_printf(buddy, "%c\n%s is no longer chat serving you.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1303. }
  1304. }
  1305. DO_CHAT(chat_who)
  1306. {
  1307. struct chat_data *buddy;
  1308. int cnt = 1;
  1309. tintin_printf(NULL, " %-15s %-5s %-20s %-5s %-15s", "Name", "Flags", "Address", "Port", "Client");
  1310. tintin_printf(NULL, " =============== ===== ==================== ===== ==================== ");
  1311. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1312. {
  1313. tintin_printf(NULL, " %03d %-15s %s%s%s%s%s %-20s %-5u %-20s",
  1314. cnt++,
  1315. buddy->name,
  1316. HAS_BIT(buddy->flags, CHAT_FLAG_PRIVATE) ? "P" : " ",
  1317. HAS_BIT(buddy->flags, CHAT_FLAG_IGNORE) ? "I" : " ",
  1318. HAS_BIT(buddy->flags, CHAT_FLAG_SERVE) ? "S" : " ",
  1319. HAS_BIT(buddy->flags, CHAT_FLAG_FORWARD) ? "F" :
  1320. HAS_BIT(buddy->flags, CHAT_FLAG_FORWARDBY) ? "f" : " ",
  1321. " ",
  1322. buddy->ip,
  1323. buddy->port,
  1324. buddy->version);
  1325. }
  1326. tintin_printf(NULL, " =============== ===== ==================== ===== ==================== ");
  1327. }
  1328. DO_CHAT(chat_zap)
  1329. {
  1330. struct chat_data *buddy;
  1331. if (!strcasecmp(arg1, "ALL"))
  1332. {
  1333. while (gtd->chat->next)
  1334. {
  1335. close_chat(gtd->chat->next, TRUE);
  1336. }
  1337. }
  1338. else
  1339. {
  1340. if ((buddy = find_buddy(arg1)))
  1341. {
  1342. close_chat(buddy, TRUE);
  1343. }
  1344. else
  1345. {
  1346. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1347. }
  1348. }
  1349. }
  1350. // file transfer
  1351. DO_CHAT(chat_accept)
  1352. {
  1353. int cnt;
  1354. struct chat_data *buddy;
  1355. char path[BUFFER_SIZE];
  1356. cnt = 1;
  1357. if (*arg2)
  1358. {
  1359. cnt = get_number(gtd->ses, arg2);
  1360. if (cnt < 1 || cnt > 1000)
  1361. {
  1362. chat_printf("ERROR: File transfer boost must be between 1 and 1000.");
  1363. return;
  1364. }
  1365. }
  1366. if ((buddy = find_buddy(arg1)) == NULL)
  1367. {
  1368. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1369. return;
  1370. }
  1371. if (buddy->file_name == NULL)
  1372. {
  1373. chat_printf("ERROR: You don't have a file transfer in progress with %s.", buddy->name);
  1374. return;
  1375. }
  1376. if (buddy->file_start_time)
  1377. {
  1378. chat_printf("ERROR: You already have a file transfer in progress with %s.", buddy->name);
  1379. return;
  1380. }
  1381. if (*arg2)
  1382. {
  1383. cnt = get_number(gtd->ses, arg2);
  1384. if (cnt <= 0 || cnt >= 1000)
  1385. {
  1386. chat_printf("ERROR: File transfer boost (%s) must be between 1 and 1000.", arg2);
  1387. return;
  1388. }
  1389. if (cnt > buddy->file_size / (BLOCK_SIZE * 10))
  1390. {
  1391. cnt = UMAX(1, buddy->file_size / (BLOCK_SIZE * 10));
  1392. }
  1393. }
  1394. sprintf(path, "%s%s", gtd->chat->download, buddy->file_name);
  1395. if ((buddy->file_pt = fopen(path, "w")) == NULL)
  1396. {
  1397. deny_file(buddy, "\nCould not create that file on receiver's end.\n");
  1398. chat_printf("ERROR: Could not create the file '%s' on your end.", buddy->file_name);
  1399. file_cleanup(buddy);
  1400. return;
  1401. }
  1402. buddy->file_start_time = utime();
  1403. chat_printf("Started file transfer from %s, file: %s, size: %lld, boost: %d", buddy->name, buddy->file_name, buddy->file_size, cnt);
  1404. while (cnt--)
  1405. {
  1406. chat_socket_printf(buddy, "%c%c", CHAT_FILE_BLOCK_REQUEST, CHAT_END_OF_COMMAND);
  1407. }
  1408. }
  1409. DO_CHAT(chat_decline)
  1410. {
  1411. struct chat_data *buddy;
  1412. if ((buddy = find_buddy(arg1)) == NULL)
  1413. {
  1414. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1415. return;
  1416. }
  1417. if (buddy->file_pt == NULL)
  1418. {
  1419. chat_printf("You don't have a file transfer in progress with %s.", buddy->name);
  1420. return;
  1421. }
  1422. if (buddy->file_start_time)
  1423. {
  1424. chat_printf("You already have a file transfer in progress with %s.", buddy->name);
  1425. return;
  1426. }
  1427. deny_file(buddy, "\nYour file transfer was rejected.\n");
  1428. }
  1429. DO_CHAT(chat_sendfile)
  1430. {
  1431. struct chat_data *buddy;
  1432. if (*arg1 == 0 || *arg2 == 0)
  1433. {
  1434. chat_printf("USAGE: #sendfile <person> <filename>");
  1435. return;
  1436. }
  1437. if ((buddy = find_buddy(arg1)) == NULL)
  1438. {
  1439. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1440. return;
  1441. }
  1442. if (buddy->file_pt)
  1443. {
  1444. chat_printf("ERROR: You already have a file transfer in progress with that person.");
  1445. return;
  1446. }
  1447. buddy->file_block_cnt = 0;
  1448. buddy->file_block_tot = 0;
  1449. buddy->file_name = strdup(fix_file_name(arg2));
  1450. if ((buddy->file_pt = fopen(arg2, "r")) == NULL)
  1451. {
  1452. chat_printf("ERROR: No such file.");
  1453. file_cleanup(buddy);
  1454. return;
  1455. }
  1456. if ((buddy->file_size = get_file_size(arg2)) == 0)
  1457. {
  1458. chat_printf("Cannot send an empty file.");
  1459. file_cleanup(buddy);
  1460. return;
  1461. }
  1462. buddy->file_block_tot = buddy->file_size / BLOCK_SIZE + (buddy->file_size % BLOCK_SIZE ? 1 : 0);
  1463. if (*buddy->file_name == 0)
  1464. {
  1465. chat_printf("Must be a file, directories not accepted.");
  1466. file_cleanup(buddy);
  1467. return;
  1468. }
  1469. buddy->file_start_time = utime();
  1470. chat_socket_printf(buddy, "%c%s,%lld%c", CHAT_FILE_START, buddy->file_name, buddy->file_size, CHAT_END_OF_COMMAND);
  1471. chat_printf("Sending file to: %s, File: %s, Size: %lld", buddy->name, buddy->file_name, buddy->file_size);
  1472. return;
  1473. }
  1474. void chat_receive_file(char *arg, struct chat_data *buddy)
  1475. {
  1476. char path[BUFFER_SIZE], *comma;
  1477. push_call("chat_receive_file(%p,%p)",arg,buddy);
  1478. if (buddy->file_pt)
  1479. {
  1480. deny_file(buddy, "\nThere is a transfer already in progress.\n");
  1481. pop_call();
  1482. return;
  1483. }
  1484. buddy->file_block_cnt = 0;
  1485. buddy->file_block_tot = 0;
  1486. buddy->file_size = 0;
  1487. if ((comma = strchr(arg, ',')) == NULL)
  1488. {
  1489. deny_file(buddy, "\nFile protocol error. (no file size was transmitted)\n");
  1490. pop_call();
  1491. return;
  1492. }
  1493. *comma = 0;
  1494. buddy->file_name = strdup(arg);
  1495. buddy->file_size = atoll(&comma[1]);
  1496. if (strcmp(fix_file_name(buddy->file_name), buddy->file_name))
  1497. {
  1498. deny_file(buddy, "\nFilename sent with directory info. (rejected)\n");
  1499. file_cleanup(buddy);
  1500. pop_call();
  1501. return;
  1502. }
  1503. if (buddy->file_size == 0)
  1504. {
  1505. deny_file(buddy, "\nFile protocol error. (no file size was transmitted)\n");
  1506. file_cleanup(buddy);
  1507. pop_call();
  1508. return;
  1509. }
  1510. buddy->file_block_tot = buddy->file_size / BLOCK_SIZE + (buddy->file_size % BLOCK_SIZE ? 1 : 0);
  1511. sprintf(path, "%s%s", gtd->chat->download, buddy->file_name);
  1512. chat_printf("File transfer from %s, file: %s, size: %d.", buddy->name, buddy->file_name, buddy->file_size);
  1513. chat_printf("Use %cchat <accept|decline> %s [boost] to proceed.", gtd->tintin_char, buddy->name);
  1514. if ((buddy->file_pt = fopen(path, "r")) != NULL)
  1515. {
  1516. chat_printf("Warning, the file already exists on your end.");
  1517. fclose(buddy->file_pt);
  1518. buddy->file_pt = NULL;
  1519. }
  1520. buddy->file_start_time = 0;
  1521. pop_call();
  1522. return;
  1523. }
  1524. void send_block(struct chat_data *buddy)
  1525. {
  1526. unsigned char block[BUFFER_SIZE], *pto;
  1527. int i, c;
  1528. if (buddy->file_pt == NULL)
  1529. {
  1530. return;
  1531. }
  1532. if (buddy->file_block_cnt == 0)
  1533. {
  1534. buddy->file_start_time = utime();
  1535. chat_printf("%s started a file transfer, file: %s, size: %lld", buddy->name, buddy->file_name, buddy->file_size);
  1536. }
  1537. pto = block;
  1538. *pto++ = CHAT_FILE_BLOCK;
  1539. for (i = 0; i < BLOCK_SIZE; i++)
  1540. {
  1541. c = fgetc(buddy->file_pt);
  1542. if (c == EOF)
  1543. {
  1544. break;
  1545. }
  1546. *pto++ = (unsigned char) c;
  1547. }
  1548. write(buddy->fd, block, 501);
  1549. buddy->file_block_cnt++;
  1550. if (i < BLOCK_SIZE)
  1551. {
  1552. chat_printf("File transfer: %s, to %s completed at %lld.%lld KB/s.",
  1553. buddy->file_name,
  1554. buddy->name,
  1555. 1000LL * buddy->file_size / (utime() - buddy->file_start_time),
  1556. 10000LL * buddy->file_size / (utime() - buddy->file_start_time) % 10);
  1557. chat_socket_printf(buddy, "%c%c", CHAT_FILE_END, CHAT_END_OF_COMMAND);
  1558. file_cleanup(buddy);
  1559. }
  1560. }
  1561. // Last block is BLOCK_SIZE bytes as well, but don't write filler bytes.
  1562. int receive_block(unsigned char *str, struct chat_data *buddy, int len)
  1563. {
  1564. static unsigned char file_block_buf[1000];
  1565. int size;
  1566. if (buddy->file_pt == NULL)
  1567. {
  1568. return UMIN(len, BLOCK_SIZE);
  1569. }
  1570. if (gtd->chat->file_block_patch == 0 && len < BLOCK_SIZE)
  1571. {
  1572. chat_printf("receive_block %04d: packet length %03d: fragmentation detected.", buddy->file_block_cnt, len);
  1573. gtd->chat->file_block_patch = len;
  1574. memcpy(file_block_buf, str, len);
  1575. return len;
  1576. }
  1577. buddy->file_block_cnt++;
  1578. // Should be safe to assume there won't be more than 1 fragmentation per packet.
  1579. if (gtd->chat->file_block_patch)
  1580. {
  1581. len = BLOCK_SIZE - gtd->chat->file_block_patch;
  1582. memcpy(file_block_buf + gtd->chat->file_block_patch, str, len);
  1583. str = file_block_buf;
  1584. gtd->chat->file_block_patch = 0;
  1585. size = BLOCK_SIZE;
  1586. }
  1587. else
  1588. {
  1589. len = size = BLOCK_SIZE;
  1590. }
  1591. if (buddy->file_block_cnt == buddy->file_block_tot)
  1592. {
  1593. size = buddy->file_size % BLOCK_SIZE;
  1594. fwrite(str, 1, size, buddy->file_pt);
  1595. chat_printf("Transfer of %s completed, size: %lld, speed: %lld.%lld KB/s.",
  1596. buddy->file_name,
  1597. buddy->file_size,
  1598. 1000LL * buddy->file_size / (utime() - buddy->file_start_time),
  1599. 10000LL * buddy->file_size / (utime() - buddy->file_start_time) % 10);
  1600. file_cleanup(buddy);
  1601. }
  1602. else
  1603. {
  1604. fwrite(str, 1, size, buddy->file_pt);
  1605. chat_socket_printf(buddy, "%c%c", CHAT_FILE_BLOCK_REQUEST, CHAT_END_OF_COMMAND);
  1606. }
  1607. return len;
  1608. }
  1609. void deny_file(struct chat_data *ch, char *arg)
  1610. {
  1611. chat_socket_printf(ch, "%c%s%c", CHAT_FILE_DENY, arg, CHAT_END_OF_COMMAND);
  1612. }
  1613. void file_denied(struct chat_data *buddy, char *txt)
  1614. {
  1615. chat_printf("%s", txt);
  1616. file_cleanup(buddy);
  1617. }
  1618. void file_cleanup(struct chat_data *buddy)
  1619. {
  1620. if (buddy->file_pt)
  1621. {
  1622. fclose(buddy->file_pt);
  1623. buddy->file_pt = NULL;
  1624. }
  1625. if (buddy->file_name)
  1626. {
  1627. FREE(buddy->file_name);
  1628. }
  1629. }
  1630. DO_CHAT(chat_cancelfile)
  1631. {
  1632. struct chat_data *buddy;
  1633. if ((buddy = find_buddy(arg1)) == NULL)
  1634. {
  1635. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1636. return;
  1637. }
  1638. if (buddy->file_pt == NULL)
  1639. {
  1640. return;
  1641. }
  1642. fclose(buddy->file_pt);
  1643. buddy->file_pt = NULL;
  1644. chat_printf("Okay, file transfer canceled");
  1645. chat_socket_printf(buddy, "%c%c", CHAT_FILE_CANCEL, CHAT_END_OF_COMMAND);
  1646. }
  1647. DO_CHAT(chat_color)
  1648. {
  1649. if (*arg1 == 0 || get_highlight_codes(gtd->ses, arg1, arg2) == FALSE)
  1650. {
  1651. chat_printf("Valid colors are:\n\nreset, bold, dim, light, dark, underscore, blink, reverse, black, red, green, yellow, blue, magenta, cyan, white, b black, b red, b green, b yellow, b blue, b magenta, b cyan, b white");
  1652. return;
  1653. }
  1654. RESTRING(gtd->chat->color, arg2);
  1655. chat_printf("Color has been set to %s", arg1);
  1656. }
  1657. DO_CHAT(chat_dnd)
  1658. {
  1659. TOG_BIT(gtd->chat->flags, CHAT_FLAG_DND);
  1660. if (HAS_BIT(gtd->chat->flags, CHAT_FLAG_DND))
  1661. {
  1662. chat_printf("New connections are no longer accepted.");
  1663. }
  1664. else
  1665. {
  1666. chat_printf("New connections are accepted.");
  1667. }
  1668. }
  1669. DO_CHAT(chat_filestat)
  1670. {
  1671. struct chat_data *buddy;
  1672. if ((buddy = find_buddy(arg1)) == NULL)
  1673. {
  1674. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1675. return;
  1676. }
  1677. if (buddy->file_pt == NULL)
  1678. {
  1679. chat_printf("You have no file transfer in progress with %s.", buddy->name);
  1680. return;
  1681. }
  1682. tintin_printf(NULL, " Contact: %s", buddy->name);
  1683. tintin_printf(NULL, " Filename: %s", buddy->file_name);
  1684. tintin_printf(NULL, " Filesize: %lld", buddy->file_size);
  1685. tintin_printf(NULL, " Received: %d", buddy->file_block_cnt * BLOCK_SIZE);
  1686. tintin_printf(NULL, " Speed: %lld KB/s", (1000 * buddy->file_block_cnt * BLOCK_SIZE) / (utime() - buddy->file_start_time));
  1687. }
  1688. DO_CHAT(chat_group)
  1689. {
  1690. struct chat_data *buddy;
  1691. int cnt = 0;
  1692. if (*arg1 == 0)
  1693. {
  1694. tintin_printf(NULL, " %-15s %-20s %-5s %-15s", "Name", "Address", "Port", "Group");
  1695. tintin_printf(NULL, " =============== ==================== ===== ==================== ");
  1696. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1697. {
  1698. tintin_printf(NULL, " %03d %-15s %-20s %-5u %-20s",
  1699. cnt++,
  1700. buddy->name,
  1701. buddy->ip,
  1702. buddy->port,
  1703. buddy->group);
  1704. }
  1705. tintin_printf(NULL, " =============== ==================== ===== ==================== ");
  1706. }
  1707. else if (!strcasecmp(arg1, "ALL"))
  1708. {
  1709. chat_printf("You set everyone's group to '%s'", arg2);
  1710. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1711. {
  1712. RESTRING(buddy->group, arg2);
  1713. }
  1714. }
  1715. else
  1716. {
  1717. if ((buddy = find_buddy(arg1)) != NULL)
  1718. {
  1719. RESTRING(buddy->group, arg2);
  1720. chat_printf("You set %s's group to '%s'", buddy->name, arg2);
  1721. }
  1722. else
  1723. {
  1724. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1725. }
  1726. }
  1727. }
  1728. DO_CHAT(chat_forward)
  1729. {
  1730. struct chat_data *buddy;
  1731. if ((buddy = find_buddy(arg1)) == NULL)
  1732. {
  1733. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1734. return;
  1735. }
  1736. TOG_BIT(buddy->flags, CHAT_FLAG_FORWARD);
  1737. if (HAS_BIT(buddy->flags, CHAT_FLAG_FORWARD))
  1738. {
  1739. chat_socket_printf(buddy, "%c\n%s is now forwarding to you.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1740. chat_printf("You are now forwarding to %s.", buddy->name);
  1741. }
  1742. else
  1743. {
  1744. chat_socket_printf(buddy, "%c\n%s is no longer forwarding to you.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1745. chat_printf("You are no longer forwarding to %s.", buddy->name);
  1746. }
  1747. }
  1748. DO_CHAT(chat_forwardall)
  1749. {
  1750. struct chat_data *buddy;
  1751. if ((buddy = find_buddy(arg1)) == NULL)
  1752. {
  1753. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1754. return;
  1755. }
  1756. TOG_BIT(buddy->flags, CHAT_FLAG_FORWARDALL);
  1757. if (HAS_BIT(buddy->flags, CHAT_FLAG_FORWARDALL))
  1758. {
  1759. chat_socket_printf(buddy, "%c\n%s is now forwarding session output to you.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1760. chat_printf("You are now forwarding session output to %s.", buddy->name);
  1761. }
  1762. else
  1763. {
  1764. chat_socket_printf(buddy, "%c\n%s is no longer forwarding session output to you.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1765. chat_printf("You are no longer forwarding session output to %s.", buddy->name);
  1766. }
  1767. }
  1768. void chat_forward_session(struct session *ses, char *linelog)
  1769. {
  1770. char tmp[BUFFER_SIZE];
  1771. struct chat_data *buddy;
  1772. if (ses != gtd->ses)
  1773. {
  1774. return;
  1775. }
  1776. sprintf(tmp, "%c%s%c", CHAT_SNOOP_DATA, linelog, CHAT_END_OF_COMMAND);
  1777. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1778. {
  1779. if (HAS_BIT(buddy->flags, CHAT_FLAG_FORWARDALL))
  1780. {
  1781. chat_socket_printf(buddy, "%s", tmp);
  1782. }
  1783. }
  1784. }
  1785. DO_CHAT(chat_ignore)
  1786. {
  1787. struct chat_data *buddy;
  1788. if ((buddy = find_buddy(arg1)) == NULL)
  1789. {
  1790. chat_printf("You are not connected to anyone named '%s'.", arg1);
  1791. return;
  1792. }
  1793. TOG_BIT(buddy->flags, CHAT_FLAG_IGNORE);
  1794. if (HAS_BIT(buddy->flags, CHAT_FLAG_IGNORE))
  1795. {
  1796. // chat_socket_printf(buddy, "%c\n%s is now ignoring you.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1797. chat_printf("You are now ignoring %s.", buddy->name);
  1798. }
  1799. else
  1800. {
  1801. // chat_socket_printf(buddy, "%c\n%s is no longer ignoring you.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1802. chat_printf("You are no longer ignoring %s.", buddy->name);
  1803. }
  1804. }
  1805. DO_CHAT(chat_private)
  1806. {
  1807. struct chat_data *buddy;
  1808. if (!strcasecmp(arg1, "ALL"))
  1809. {
  1810. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1811. {
  1812. if (!HAS_BIT(buddy->flags, CHAT_FLAG_PRIVATE))
  1813. {
  1814. chat_socket_printf(buddy, "%c\n%s marked your connection private.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1815. chat_printf("Your connection with %s is now private.", buddy->name);
  1816. SET_BIT(buddy->flags, CHAT_FLAG_PRIVATE);
  1817. }
  1818. }
  1819. }
  1820. else
  1821. {
  1822. if ((buddy = find_buddy(arg1)) != NULL)
  1823. {
  1824. if (!HAS_BIT(buddy->flags, CHAT_FLAG_PRIVATE))
  1825. {
  1826. chat_socket_printf(buddy, "%c\n%s marked your connection private.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1827. chat_printf("Your connection with %s is now private.", buddy->name);
  1828. SET_BIT(buddy->flags, CHAT_FLAG_PRIVATE);
  1829. }
  1830. else
  1831. {
  1832. chat_printf("Your connection with %s is already private.", buddy->name);
  1833. }
  1834. }
  1835. }
  1836. }
  1837. DO_CHAT(chat_public)
  1838. {
  1839. struct chat_data *buddy;
  1840. if (!strcasecmp(arg1, "ALL"))
  1841. {
  1842. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1843. {
  1844. if (HAS_BIT(buddy->flags, CHAT_FLAG_PRIVATE))
  1845. {
  1846. chat_socket_printf(buddy, "%c\n%s marked your connection public.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1847. chat_printf("Your connection with %s is now public.", buddy->name);
  1848. DEL_BIT(buddy->flags, CHAT_FLAG_PRIVATE);
  1849. }
  1850. }
  1851. }
  1852. else
  1853. {
  1854. if ((buddy = find_buddy(arg1)) != NULL)
  1855. {
  1856. if (HAS_BIT(buddy->flags, CHAT_FLAG_PRIVATE))
  1857. {
  1858. chat_socket_printf(buddy, "%c\n%s marked your connection public.\n%c", CHAT_MESSAGE, gtd->chat->name, CHAT_END_OF_COMMAND);
  1859. chat_printf("Your connection with %s is now public.", buddy->name);
  1860. DEL_BIT(buddy->flags, CHAT_FLAG_PRIVATE);
  1861. }
  1862. else
  1863. {
  1864. chat_printf("Your connection with %s is already public.", buddy->name);
  1865. }
  1866. }
  1867. }
  1868. }
  1869. int get_file_size(char *fpath)
  1870. {
  1871. struct stat statbuf;
  1872. if (stat(fpath, &statbuf) == -1)
  1873. {
  1874. return 0;
  1875. }
  1876. return statbuf.st_size;
  1877. }
  1878. struct chat_data *find_buddy(char *arg)
  1879. {
  1880. struct chat_data *buddy;
  1881. int cnt = 1;
  1882. if (*arg == 0)
  1883. {
  1884. return NULL;
  1885. }
  1886. if (is_number(arg))
  1887. {
  1888. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1889. {
  1890. if (atoi(arg) == cnt++)
  1891. {
  1892. return buddy;
  1893. }
  1894. }
  1895. }
  1896. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1897. {
  1898. if (!strcmp(arg, buddy->ip))
  1899. {
  1900. return buddy;
  1901. }
  1902. }
  1903. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1904. {
  1905. if (is_abbrev(arg, buddy->name))
  1906. {
  1907. return buddy;
  1908. }
  1909. }
  1910. return NULL;
  1911. }
  1912. struct chat_data *find_group(char *arg)
  1913. {
  1914. struct chat_data *buddy;
  1915. if (*arg == 0)
  1916. {
  1917. return NULL;
  1918. }
  1919. for (buddy = gtd->chat->next ; buddy ; buddy = buddy->next)
  1920. {
  1921. if (!strcmp(arg, buddy->group))
  1922. {
  1923. return buddy;
  1924. }
  1925. }
  1926. return NULL;
  1927. }
  1928. char *fix_file_name(char *name)
  1929. {
  1930. int len;
  1931. for (len = strlen(name) ; len > 0 ; len--)
  1932. {
  1933. switch (name[len])
  1934. {
  1935. case '/':
  1936. case '\\':
  1937. case ':':
  1938. return &name[len + 1];
  1939. }
  1940. }
  1941. return name;
  1942. }