chat.c 54 KB

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