channel.c 29 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346
  1. /*
  2. * ngIRCd -- The Next Generation IRC Daemon
  3. * Copyright (c)2001-2014 Alexander Barton (alex@barton.de) and Contributors.
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. * Please read the file COPYING, README and AUTHORS for more information.
  10. */
  11. #define __channel_c__
  12. #include "portab.h"
  13. /**
  14. * @file
  15. * Channel management
  16. */
  17. #include <assert.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <errno.h>
  21. #include <stdio.h>
  22. #include <strings.h>
  23. #include <time.h>
  24. #include "conn-func.h"
  25. #include "channel.h"
  26. #include "irc-write.h"
  27. #include "conf.h"
  28. #include "hash.h"
  29. #include "log.h"
  30. #include "messages.h"
  31. #include "match.h"
  32. #define REMOVE_PART 0
  33. #define REMOVE_QUIT 1
  34. #define REMOVE_KICK 2
  35. static CHANNEL *My_Channels;
  36. static CL2CHAN *My_Cl2Chan;
  37. static CL2CHAN *Get_Cl2Chan PARAMS(( CHANNEL *Chan, CLIENT *Client ));
  38. static CL2CHAN *Add_Client PARAMS(( CHANNEL *Chan, CLIENT *Client ));
  39. static bool Remove_Client PARAMS(( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const char *Reason, bool InformServer ));
  40. static CL2CHAN *Get_First_Cl2Chan PARAMS(( CLIENT *Client, CHANNEL *Chan ));
  41. static CL2CHAN *Get_Next_Cl2Chan PARAMS(( CL2CHAN *Start, CLIENT *Client, CHANNEL *Chan ));
  42. static void Delete_Channel PARAMS(( CHANNEL *Chan ));
  43. static void Free_Channel PARAMS(( CHANNEL *Chan ));
  44. static void Set_KeyFile PARAMS((CHANNEL *Chan, const char *KeyFile));
  45. GLOBAL void
  46. Channel_Init( void )
  47. {
  48. My_Channels = NULL;
  49. My_Cl2Chan = NULL;
  50. } /* Channel_Init */
  51. GLOBAL struct list_head *
  52. Channel_GetListBans(CHANNEL *c)
  53. {
  54. assert(c != NULL);
  55. return &c->list_bans;
  56. }
  57. GLOBAL struct list_head *
  58. Channel_GetListExcepts(CHANNEL *c)
  59. {
  60. assert(c != NULL);
  61. return &c->list_excepts;
  62. }
  63. GLOBAL struct list_head *
  64. Channel_GetListInvites(CHANNEL *c)
  65. {
  66. assert(c != NULL);
  67. return &c->list_invites;
  68. }
  69. /**
  70. * Generate predefined persistent channels and &SERVER
  71. */
  72. GLOBAL void
  73. Channel_InitPredefined( void )
  74. {
  75. CHANNEL *new_chan;
  76. const struct Conf_Channel *conf_chan;
  77. const char *c;
  78. size_t i, channel_count = array_length(&Conf_Channels, sizeof(*conf_chan));
  79. conf_chan = array_start(&Conf_Channels);
  80. assert(channel_count == 0 || conf_chan != NULL);
  81. for (i = 0; i < channel_count; i++, conf_chan++) {
  82. if (!conf_chan->name[0])
  83. continue;
  84. if (!Channel_IsValidName(conf_chan->name)) {
  85. Log(LOG_ERR,
  86. "Can't create pre-defined channel: invalid name: \"%s\"",
  87. conf_chan->name);
  88. continue;
  89. }
  90. new_chan = Channel_Search(conf_chan->name);
  91. if (new_chan) {
  92. Log(LOG_INFO,
  93. "Can't create pre-defined channel \"%s\": name already in use.",
  94. conf_chan->name);
  95. Set_KeyFile(new_chan, conf_chan->keyfile);
  96. continue;
  97. }
  98. new_chan = Channel_Create(conf_chan->name);
  99. if (!new_chan) {
  100. Log(LOG_ERR, "Can't create pre-defined channel \"%s\"!",
  101. conf_chan->name);
  102. continue;
  103. }
  104. Log(LOG_INFO, "Created pre-defined channel \"%s\".",
  105. conf_chan->name);
  106. Channel_ModeAdd(new_chan, 'P');
  107. if (conf_chan->topic[0])
  108. Channel_SetTopic(new_chan, NULL, conf_chan->topic);
  109. c = conf_chan->modes;
  110. while (*c)
  111. Channel_ModeAdd(new_chan, *c++);
  112. Channel_SetKey(new_chan, conf_chan->key);
  113. Channel_SetMaxUsers(new_chan, conf_chan->maxusers);
  114. Set_KeyFile(new_chan, conf_chan->keyfile);
  115. }
  116. if (channel_count)
  117. array_free(&Conf_Channels);
  118. /* Make sure the local &SERVER channel exists */
  119. if (!Channel_Search("&SERVER")) {
  120. new_chan = Channel_Create("&SERVER");
  121. if (new_chan) {
  122. Channel_SetModes(new_chan, "mnPt");
  123. Channel_SetTopic(new_chan, Client_ThisServer(),
  124. "Server Messages");
  125. } else
  126. Log(LOG_ERR, "Failed to create \"&SERVER\" channel!");
  127. } else
  128. LogDebug("Required channel \"&SERVER\" already exists, ok.");
  129. } /* Channel_InitPredefined */
  130. static void
  131. Free_Channel(CHANNEL *chan)
  132. {
  133. array_free(&chan->topic);
  134. array_free(&chan->keyfile);
  135. Lists_Free(&chan->list_bans);
  136. Lists_Free(&chan->list_excepts);
  137. Lists_Free(&chan->list_invites);
  138. free(chan);
  139. }
  140. GLOBAL void
  141. Channel_Exit( void )
  142. {
  143. CHANNEL *c, *c_next;
  144. CL2CHAN *cl2chan, *cl2chan_next;
  145. /* free struct Channel */
  146. c = My_Channels;
  147. while (c) {
  148. c_next = c->next;
  149. Free_Channel(c);
  150. c = c_next;
  151. }
  152. /* Free Channel allocation table */
  153. cl2chan = My_Cl2Chan;
  154. while (cl2chan) {
  155. cl2chan_next = cl2chan->next;
  156. free(cl2chan);
  157. cl2chan = cl2chan_next;
  158. }
  159. } /* Channel_Exit */
  160. /**
  161. * Join Channel
  162. * This function lets a client join a channel. First, the function
  163. * checks that the specified channel name is valid and that the client
  164. * isn't already a member. If the specified channel doesn't exist,
  165. * a new channel is created. Client is added to channel by function
  166. * Add_Client().
  167. */
  168. GLOBAL bool
  169. Channel_Join( CLIENT *Client, const char *Name )
  170. {
  171. CHANNEL *chan;
  172. assert(Client != NULL);
  173. assert(Name != NULL);
  174. /* Check that the channel name is valid */
  175. if (! Channel_IsValidName(Name)) {
  176. IRC_WriteErrClient(Client, ERR_NOSUCHCHANNEL_MSG,
  177. Client_ID(Client), Name);
  178. return false;
  179. }
  180. chan = Channel_Search(Name);
  181. if(chan) {
  182. /* Check if the client is already in the channel */
  183. if (Get_Cl2Chan(chan, Client))
  184. return false;
  185. } else {
  186. /* If the specified channel does not exist, the channel
  187. * is now created */
  188. chan = Channel_Create(Name);
  189. if (!chan)
  190. return false;
  191. }
  192. /* Add user to Channel */
  193. if (! Add_Client(chan, Client))
  194. return false;
  195. return true;
  196. } /* Channel_Join */
  197. /**
  198. * Part client from channel.
  199. * This function lets a client part from a channel. First, the function checks
  200. * if the channel exists and the client is a member of it and sends out
  201. * appropriate error messages if not. The real work is done by the function
  202. * Remove_Client().
  203. */
  204. GLOBAL bool
  205. Channel_Part(CLIENT * Client, CLIENT * Origin, const char *Name, const char *Reason)
  206. {
  207. CHANNEL *chan;
  208. assert(Client != NULL);
  209. assert(Name != NULL);
  210. assert(Reason != NULL);
  211. /* Check that specified channel exists */
  212. chan = Channel_Search(Name);
  213. if (!chan) {
  214. IRC_WriteErrClient(Client, ERR_NOSUCHCHANNEL_MSG,
  215. Client_ID(Client), Name);
  216. return false;
  217. }
  218. /* Check that the client is in the channel */
  219. if (!Get_Cl2Chan(chan, Client)) {
  220. IRC_WriteErrClient(Client, ERR_NOTONCHANNEL_MSG,
  221. Client_ID(Client), Name);
  222. return false;
  223. }
  224. if (Conf_MorePrivacy)
  225. Reason = "";
  226. /* Part client from channel */
  227. if (!Remove_Client(REMOVE_PART, chan, Client, Origin, Reason, true))
  228. return false;
  229. else
  230. return true;
  231. } /* Channel_Part */
  232. /**
  233. * Kick user from Channel
  234. */
  235. GLOBAL void
  236. Channel_Kick(CLIENT *Peer, CLIENT *Target, CLIENT *Origin, const char *Name,
  237. const char *Reason )
  238. {
  239. CHANNEL *chan;
  240. bool can_kick = false;
  241. assert(Peer != NULL);
  242. assert(Target != NULL);
  243. assert(Origin != NULL);
  244. assert(Name != NULL);
  245. assert(Reason != NULL);
  246. /* Check that channel exists */
  247. chan = Channel_Search( Name );
  248. if (!chan) {
  249. IRC_WriteErrClient(Origin, ERR_NOSUCHCHANNEL_MSG,
  250. Client_ID(Origin), Name);
  251. return;
  252. }
  253. if (Client_Type(Peer) != CLIENT_SERVER &&
  254. Client_Type(Origin) != CLIENT_SERVICE) {
  255. /* Check that user is on the specified channel */
  256. if (!Channel_IsMemberOf(chan, Origin)) {
  257. IRC_WriteErrClient(Origin, ERR_NOTONCHANNEL_MSG,
  258. Client_ID(Origin), Name);
  259. return;
  260. }
  261. }
  262. /* Check that the client to be kicked is on the specified channel */
  263. if (!Channel_IsMemberOf(chan, Target)) {
  264. IRC_WriteErrClient(Origin, ERR_USERNOTINCHANNEL_MSG,
  265. Client_ID(Origin), Client_ID(Target), Name );
  266. return;
  267. }
  268. if(Client_Type(Peer) == CLIENT_USER) {
  269. /* Channel mode 'Q' and user mode 'q' on target: nobody but
  270. * IRC Operators and servers can kick the target user */
  271. if ((Channel_HasMode(chan, 'Q')
  272. || Client_HasMode(Target, 'q')
  273. || Client_Type(Target) == CLIENT_SERVICE)
  274. && !Client_HasMode(Origin, 'o')) {
  275. IRC_WriteErrClient(Origin, ERR_KICKDENY_MSG,
  276. Client_ID(Origin), Name,
  277. Client_ID(Target));
  278. return;
  279. }
  280. /* Check if client has the rights to kick target */
  281. /* Owner can kick everyone */
  282. if (Channel_UserHasMode(chan, Peer, 'q'))
  283. can_kick = true;
  284. /* Admin can't kick owner */
  285. else if (Channel_UserHasMode(chan, Peer, 'a') &&
  286. !Channel_UserHasMode(chan, Target, 'q'))
  287. can_kick = true;
  288. /* Op can't kick owner | admin */
  289. else if (Channel_UserHasMode(chan, Peer, 'o') &&
  290. !Channel_UserHasMode(chan, Target, 'q') &&
  291. !Channel_UserHasMode(chan, Target, 'a'))
  292. can_kick = true;
  293. /* Half Op can't kick owner | admin | op */
  294. else if (Channel_UserHasMode(chan, Peer, 'h') &&
  295. !Channel_UserHasMode(chan, Target, 'q') &&
  296. !Channel_UserHasMode(chan, Target, 'a') &&
  297. !Channel_UserHasMode(chan, Target, 'o'))
  298. can_kick = true;
  299. /* IRC operators & IRCd with OperCanMode enabled
  300. * can kick anyways regardless of privilege */
  301. else if(Client_HasMode(Origin, 'o') && Conf_OperCanMode)
  302. can_kick = true;
  303. if(!can_kick) {
  304. IRC_WriteErrClient(Origin, ERR_CHANOPPRIVTOOLOW_MSG,
  305. Client_ID(Origin), Name);
  306. return;
  307. }
  308. }
  309. /* Kick Client from channel */
  310. Remove_Client( REMOVE_KICK, chan, Target, Origin, Reason, true);
  311. } /* Channel_Kick */
  312. GLOBAL void
  313. Channel_Quit( CLIENT *Client, const char *Reason )
  314. {
  315. CHANNEL *c, *next_c;
  316. assert( Client != NULL );
  317. assert( Reason != NULL );
  318. if (Conf_MorePrivacy)
  319. Reason = "";
  320. IRC_WriteStrRelatedPrefix( Client, Client, false, "QUIT :%s", Reason );
  321. c = My_Channels;
  322. while( c )
  323. {
  324. next_c = c->next;
  325. Remove_Client( REMOVE_QUIT, c, Client, Client, Reason, false );
  326. c = next_c;
  327. }
  328. } /* Channel_Quit */
  329. /**
  330. * Get number of channels this server knows and that are "visible" to
  331. * the given client. If no client is given, all channels will be counted.
  332. *
  333. * @param Client The client to check or NULL.
  334. * @return Number of channels visible to the client.
  335. */
  336. GLOBAL unsigned long
  337. Channel_CountVisible (CLIENT *Client)
  338. {
  339. CHANNEL *c;
  340. unsigned long count = 0;
  341. c = My_Channels;
  342. while(c) {
  343. if (Client) {
  344. if (!Channel_HasMode(c, 's')
  345. || Channel_IsMemberOf(c, Client))
  346. count++;
  347. } else
  348. count++;
  349. c = c->next;
  350. }
  351. return count;
  352. }
  353. GLOBAL unsigned long
  354. Channel_MemberCount( CHANNEL *Chan )
  355. {
  356. CL2CHAN *cl2chan;
  357. unsigned long count = 0;
  358. assert( Chan != NULL );
  359. cl2chan = My_Cl2Chan;
  360. while( cl2chan )
  361. {
  362. if( cl2chan->channel == Chan ) count++;
  363. cl2chan = cl2chan->next;
  364. }
  365. return count;
  366. } /* Channel_MemberCount */
  367. GLOBAL int
  368. Channel_CountForUser( CLIENT *Client )
  369. {
  370. /* Count number of channels a user is member of. */
  371. CL2CHAN *cl2chan;
  372. int count = 0;
  373. assert( Client != NULL );
  374. cl2chan = My_Cl2Chan;
  375. while( cl2chan )
  376. {
  377. if( cl2chan->client == Client ) count++;
  378. cl2chan = cl2chan->next;
  379. }
  380. return count;
  381. } /* Channel_CountForUser */
  382. GLOBAL const char *
  383. Channel_Name( const CHANNEL *Chan )
  384. {
  385. assert( Chan != NULL );
  386. return Chan->name;
  387. } /* Channel_Name */
  388. GLOBAL char *
  389. Channel_Modes( CHANNEL *Chan )
  390. {
  391. assert( Chan != NULL );
  392. return Chan->modes;
  393. } /* Channel_Modes */
  394. GLOBAL bool
  395. Channel_HasMode( CHANNEL *Chan, char Mode )
  396. {
  397. assert( Chan != NULL );
  398. return strchr( Chan->modes, Mode ) != NULL;
  399. } /* Channel_HasMode */
  400. GLOBAL char *
  401. Channel_Key( CHANNEL *Chan )
  402. {
  403. assert( Chan != NULL );
  404. return Chan->key;
  405. } /* Channel_Key */
  406. GLOBAL unsigned long
  407. Channel_MaxUsers( CHANNEL *Chan )
  408. {
  409. assert( Chan != NULL );
  410. return Chan->maxusers;
  411. } /* Channel_MaxUsers */
  412. GLOBAL CHANNEL *
  413. Channel_First( void )
  414. {
  415. return My_Channels;
  416. } /* Channel_First */
  417. GLOBAL CHANNEL *
  418. Channel_Next( CHANNEL *Chan )
  419. {
  420. assert( Chan != NULL );
  421. return Chan->next;
  422. } /* Channel_Next */
  423. GLOBAL CHANNEL *
  424. Channel_Search( const char *Name )
  425. {
  426. /* Search channel structure */
  427. CHANNEL *c;
  428. UINT32 search_hash;
  429. assert( Name != NULL );
  430. search_hash = Hash( Name );
  431. c = My_Channels;
  432. while( c )
  433. {
  434. if( search_hash == c->hash )
  435. {
  436. /* hash hit */
  437. if( strcasecmp( Name, c->name ) == 0 ) return c;
  438. }
  439. c = c->next;
  440. }
  441. return NULL;
  442. } /* Channel_Search */
  443. GLOBAL CL2CHAN *
  444. Channel_FirstMember( CHANNEL *Chan )
  445. {
  446. assert( Chan != NULL );
  447. return Get_First_Cl2Chan( NULL, Chan );
  448. } /* Channel_FirstMember */
  449. GLOBAL CL2CHAN *
  450. Channel_NextMember( CHANNEL *Chan, CL2CHAN *Cl2Chan )
  451. {
  452. assert( Chan != NULL );
  453. assert( Cl2Chan != NULL );
  454. return Get_Next_Cl2Chan( Cl2Chan->next, NULL, Chan );
  455. } /* Channel_NextMember */
  456. GLOBAL CL2CHAN *
  457. Channel_FirstChannelOf( CLIENT *Client )
  458. {
  459. assert( Client != NULL );
  460. return Get_First_Cl2Chan( Client, NULL );
  461. } /* Channel_FirstChannelOf */
  462. GLOBAL CL2CHAN *
  463. Channel_NextChannelOf( CLIENT *Client, CL2CHAN *Cl2Chan )
  464. {
  465. assert( Client != NULL );
  466. assert( Cl2Chan != NULL );
  467. return Get_Next_Cl2Chan( Cl2Chan->next, Client, NULL );
  468. } /* Channel_NextChannelOf */
  469. GLOBAL CLIENT *
  470. Channel_GetClient( CL2CHAN *Cl2Chan )
  471. {
  472. assert( Cl2Chan != NULL );
  473. return Cl2Chan->client;
  474. } /* Channel_GetClient */
  475. GLOBAL CHANNEL *
  476. Channel_GetChannel( CL2CHAN *Cl2Chan )
  477. {
  478. assert( Cl2Chan != NULL );
  479. return Cl2Chan->channel;
  480. } /* Channel_GetChannel */
  481. GLOBAL bool
  482. Channel_IsValidName( const char *Name )
  483. {
  484. assert( Name != NULL );
  485. #ifdef STRICT_RFC
  486. if (strlen(Name) <= 1)
  487. return false;
  488. #endif
  489. if (strchr("#&+", Name[0]) == NULL)
  490. return false;
  491. if (strlen(Name) >= CHANNEL_NAME_LEN)
  492. return false;
  493. return Name[strcspn(Name, " ,:\007")] == 0;
  494. } /* Channel_IsValidName */
  495. GLOBAL bool
  496. Channel_ModeAdd( CHANNEL *Chan, char Mode )
  497. {
  498. /* set Mode.
  499. * If the channel already had this mode, return false.
  500. * If the channel mode was newly set return true.
  501. */
  502. char x[2];
  503. assert( Chan != NULL );
  504. x[0] = Mode; x[1] = '\0';
  505. if( ! Channel_HasMode( Chan, x[0] ))
  506. {
  507. /* Channel does not have this mode yet, set it */
  508. strlcat( Chan->modes, x, sizeof( Chan->modes ));
  509. return true;
  510. }
  511. else return false;
  512. } /* Channel_ModeAdd */
  513. GLOBAL bool
  514. Channel_ModeDel( CHANNEL *Chan, char Mode )
  515. {
  516. /* Delete mode.
  517. * if the mode was removed return true.
  518. * if the channel did not have the mode, return false.
  519. */
  520. char *p;
  521. assert( Chan != NULL );
  522. p = strchr( Chan->modes, Mode );
  523. if( ! p ) return false;
  524. /* Channel has mode -> delete */
  525. while( *p )
  526. {
  527. *p = *(p + 1);
  528. p++;
  529. }
  530. return true;
  531. } /* Channel_ModeDel */
  532. GLOBAL bool
  533. Channel_UserModeAdd( CHANNEL *Chan, CLIENT *Client, char Mode )
  534. {
  535. /* Set Channel-User-Mode.
  536. * if mode was newly set, return true.
  537. * if the User already had this channel-mode, return false.
  538. */
  539. CL2CHAN *cl2chan;
  540. char x[2];
  541. assert( Chan != NULL );
  542. assert( Client != NULL );
  543. cl2chan = Get_Cl2Chan( Chan, Client );
  544. assert( cl2chan != NULL );
  545. x[0] = Mode; x[1] = '\0';
  546. if( ! strchr( cl2chan->modes, x[0] ))
  547. {
  548. /* mode not set, -> set it */
  549. strlcat( cl2chan->modes, x, sizeof( cl2chan->modes ));
  550. return true;
  551. }
  552. else return false;
  553. } /* Channel_UserModeAdd */
  554. GLOBAL bool
  555. Channel_UserModeDel( CHANNEL *Chan, CLIENT *Client, char Mode )
  556. {
  557. /* Delete Channel-User-Mode.
  558. * If Mode was removed, return true.
  559. * If User did not have the Channel-Mode, return false.
  560. */
  561. CL2CHAN *cl2chan;
  562. char *p;
  563. assert( Chan != NULL );
  564. assert( Client != NULL );
  565. cl2chan = Get_Cl2Chan( Chan, Client );
  566. assert( cl2chan != NULL );
  567. p = strchr( cl2chan->modes, Mode );
  568. if( ! p ) return false;
  569. /* Client has Mode -> delete */
  570. while( *p )
  571. {
  572. *p = *(p + 1);
  573. p++;
  574. }
  575. return true;
  576. } /* Channel_UserModeDel */
  577. GLOBAL char *
  578. Channel_UserModes( CHANNEL *Chan, CLIENT *Client )
  579. {
  580. /* return Users' Channel-Modes */
  581. CL2CHAN *cl2chan;
  582. assert( Chan != NULL );
  583. assert( Client != NULL );
  584. cl2chan = Get_Cl2Chan( Chan, Client );
  585. assert( cl2chan != NULL );
  586. return cl2chan->modes;
  587. } /* Channel_UserModes */
  588. GLOBAL bool
  589. Channel_UserHasMode( CHANNEL *Chan, CLIENT *Client, char Mode )
  590. {
  591. return strchr(Channel_UserModes(Chan, Client), Mode) != NULL;
  592. } /* Channel_UserHasMode */
  593. GLOBAL bool
  594. Channel_IsMemberOf( CHANNEL *Chan, CLIENT *Client )
  595. {
  596. /* Test if Client is on Channel Chan */
  597. assert( Chan != NULL );
  598. assert( Client != NULL );
  599. return Get_Cl2Chan(Chan, Client) != NULL;
  600. } /* Channel_IsMemberOf */
  601. GLOBAL char *
  602. Channel_Topic( CHANNEL *Chan )
  603. {
  604. char *ret;
  605. assert( Chan != NULL );
  606. ret = array_start(&Chan->topic);
  607. return ret ? ret : "";
  608. } /* Channel_Topic */
  609. #ifndef STRICT_RFC
  610. GLOBAL unsigned int
  611. Channel_TopicTime(CHANNEL *Chan)
  612. {
  613. assert(Chan != NULL);
  614. return (unsigned int) Chan->topic_time;
  615. } /* Channel_TopicTime */
  616. GLOBAL char *
  617. Channel_TopicWho(CHANNEL *Chan)
  618. {
  619. assert(Chan != NULL);
  620. return Chan->topic_who;
  621. } /* Channel_TopicWho */
  622. GLOBAL unsigned int
  623. Channel_CreationTime(CHANNEL *Chan)
  624. {
  625. assert(Chan != NULL);
  626. return (unsigned int) Chan->creation_time;
  627. } /* Channel_CreationTime */
  628. #endif
  629. GLOBAL void
  630. Channel_SetTopic(CHANNEL *Chan, CLIENT *Client, const char *Topic)
  631. {
  632. size_t len;
  633. assert( Chan != NULL );
  634. assert( Topic != NULL );
  635. len = strlen(Topic);
  636. if (len < array_bytes(&Chan->topic))
  637. array_free(&Chan->topic);
  638. if (len >= COMMAND_LEN || !array_copyb(&Chan->topic, Topic, len+1))
  639. Log(LOG_WARNING, "could not set new Topic \"%s\" on %s: %s",
  640. Topic, Chan->name, strerror(errno));
  641. #ifndef STRICT_RFC
  642. Chan->topic_time = time(NULL);
  643. if (Client != NULL && Client_Type(Client) != CLIENT_SERVER)
  644. strlcpy(Chan->topic_who, Client_ID(Client),
  645. sizeof Chan->topic_who);
  646. else
  647. strlcpy(Chan->topic_who, DEFAULT_TOPIC_ID,
  648. sizeof Chan->topic_who);
  649. #else
  650. (void) Client;
  651. #endif
  652. } /* Channel_SetTopic */
  653. GLOBAL void
  654. Channel_SetModes( CHANNEL *Chan, const char *Modes )
  655. {
  656. assert( Chan != NULL );
  657. assert( Modes != NULL );
  658. strlcpy( Chan->modes, Modes, sizeof( Chan->modes ));
  659. } /* Channel_SetModes */
  660. GLOBAL void
  661. Channel_SetKey( CHANNEL *Chan, const char *Key )
  662. {
  663. assert( Chan != NULL );
  664. assert( Key != NULL );
  665. strlcpy( Chan->key, Key, sizeof( Chan->key ));
  666. LogDebug("Channel %s: Key is now \"%s\".", Chan->name, Chan->key );
  667. } /* Channel_SetKey */
  668. GLOBAL void
  669. Channel_SetMaxUsers(CHANNEL *Chan, unsigned long Count)
  670. {
  671. assert( Chan != NULL );
  672. Chan->maxusers = Count;
  673. LogDebug("Channel %s: Member limit is now %lu.", Chan->name, Chan->maxusers );
  674. } /* Channel_SetMaxUsers */
  675. /**
  676. * Check if a client is allowed to send to a specific channel.
  677. *
  678. * @param Chan The channel to check.
  679. * @param From The client that wants to send.
  680. * @return true if the client is allowed to send, false otherwise.
  681. */
  682. static bool
  683. Can_Send_To_Channel(CHANNEL *Chan, CLIENT *From)
  684. {
  685. bool is_member, has_voice, is_halfop, is_op, is_chanadmin, is_owner;
  686. is_member = has_voice = is_halfop = is_op = is_chanadmin = is_owner = false;
  687. /* The server itself always can send messages :-) */
  688. if (Client_ThisServer() == From)
  689. return true;
  690. if (Channel_IsMemberOf(Chan, From)) {
  691. is_member = true;
  692. if (Channel_UserHasMode(Chan, From, 'v'))
  693. has_voice = true;
  694. if (Channel_UserHasMode(Chan, From, 'h'))
  695. is_halfop = true;
  696. if (Channel_UserHasMode(Chan, From, 'o'))
  697. is_op = true;
  698. if (Channel_UserHasMode(Chan, From, 'a'))
  699. is_chanadmin = true;
  700. if (Channel_UserHasMode(Chan, From, 'q'))
  701. is_owner = true;
  702. }
  703. /*
  704. * Is the client allowed to write to channel?
  705. *
  706. * If channel mode n set: non-members cannot send to channel.
  707. * If channel mode m set: need voice.
  708. */
  709. if (Channel_HasMode(Chan, 'n') && !is_member)
  710. return false;
  711. if (Channel_HasMode(Chan, 'M') && !Client_HasMode(From, 'R')
  712. && !Client_HasMode(From, 'o'))
  713. return false;
  714. if (has_voice || is_halfop || is_op || is_chanadmin || is_owner)
  715. return true;
  716. if (Channel_HasMode(Chan, 'm'))
  717. return false;
  718. if (Lists_Check(&Chan->list_excepts, From))
  719. return true;
  720. return !Lists_Check(&Chan->list_bans, From);
  721. }
  722. GLOBAL bool
  723. Channel_Write(CHANNEL *Chan, CLIENT *From, CLIENT *Client, const char *Command,
  724. bool SendErrors, const char *Text)
  725. {
  726. if (!Can_Send_To_Channel(Chan, From)) {
  727. if (! SendErrors)
  728. return CONNECTED; /* no error, see RFC 2812 */
  729. if (Channel_HasMode(Chan, 'M'))
  730. return IRC_WriteErrClient(From, ERR_NEEDREGGEDNICK_MSG,
  731. Client_ID(From), Channel_Name(Chan));
  732. else
  733. return IRC_WriteErrClient(From, ERR_CANNOTSENDTOCHAN_MSG,
  734. Client_ID(From), Channel_Name(Chan));
  735. }
  736. if (Client_Conn(From) > NONE)
  737. Conn_UpdateIdle(Client_Conn(From));
  738. IRC_WriteStrChannelPrefix(Client, Chan, From, true, "%s %s :%s",
  739. Command, Channel_Name(Chan), Text);
  740. return CONNECTED;
  741. }
  742. GLOBAL CHANNEL *
  743. Channel_Create( const char *Name )
  744. {
  745. /* Create new CHANNEL structure and add it to linked list */
  746. CHANNEL *c;
  747. assert( Name != NULL );
  748. c = (CHANNEL *)malloc( sizeof( CHANNEL ));
  749. if( ! c )
  750. {
  751. Log( LOG_EMERG, "Can't allocate memory! [New_Chan]" );
  752. return NULL;
  753. }
  754. memset( c, 0, sizeof( CHANNEL ));
  755. strlcpy( c->name, Name, sizeof( c->name ));
  756. c->hash = Hash( c->name );
  757. c->next = My_Channels;
  758. #ifndef STRICT_RFC
  759. c->creation_time = time(NULL);
  760. #endif
  761. My_Channels = c;
  762. LogDebug("Created new channel structure for \"%s\".", Name);
  763. return c;
  764. } /* Channel_Create */
  765. static CL2CHAN *
  766. Get_Cl2Chan( CHANNEL *Chan, CLIENT *Client )
  767. {
  768. CL2CHAN *cl2chan;
  769. assert( Chan != NULL );
  770. assert( Client != NULL );
  771. cl2chan = My_Cl2Chan;
  772. while( cl2chan )
  773. {
  774. if(( cl2chan->channel == Chan ) && ( cl2chan->client == Client )) return cl2chan;
  775. cl2chan = cl2chan->next;
  776. }
  777. return NULL;
  778. } /* Get_Cl2Chan */
  779. static CL2CHAN *
  780. Add_Client( CHANNEL *Chan, CLIENT *Client )
  781. {
  782. CL2CHAN *cl2chan;
  783. assert( Chan != NULL );
  784. assert( Client != NULL );
  785. /* Create new CL2CHAN structure */
  786. cl2chan = (CL2CHAN *)malloc( sizeof( CL2CHAN ));
  787. if( ! cl2chan )
  788. {
  789. Log( LOG_EMERG, "Can't allocate memory! [Add_Client]" );
  790. return NULL;
  791. }
  792. cl2chan->channel = Chan;
  793. cl2chan->client = Client;
  794. strcpy( cl2chan->modes, "" );
  795. /* concatenate */
  796. cl2chan->next = My_Cl2Chan;
  797. My_Cl2Chan = cl2chan;
  798. LogDebug("User \"%s\" joined channel \"%s\".", Client_Mask(Client), Chan->name);
  799. return cl2chan;
  800. } /* Add_Client */
  801. static bool
  802. Remove_Client( int Type, CHANNEL *Chan, CLIENT *Client, CLIENT *Origin, const char *Reason, bool InformServer )
  803. {
  804. CL2CHAN *cl2chan, *last_cl2chan;
  805. CHANNEL *c;
  806. assert( Chan != NULL );
  807. assert( Client != NULL );
  808. assert( Origin != NULL );
  809. assert( Reason != NULL );
  810. /* Do not inform other servers if the channel is local to this server,
  811. * regardless of what the caller requested! */
  812. if(InformServer)
  813. InformServer = !Channel_IsLocal(Chan);
  814. last_cl2chan = NULL;
  815. cl2chan = My_Cl2Chan;
  816. while( cl2chan )
  817. {
  818. if(( cl2chan->channel == Chan ) && ( cl2chan->client == Client )) break;
  819. last_cl2chan = cl2chan;
  820. cl2chan = cl2chan->next;
  821. }
  822. if( ! cl2chan ) return false;
  823. c = cl2chan->channel;
  824. assert( c != NULL );
  825. /* maintain cl2chan list */
  826. if( last_cl2chan ) last_cl2chan->next = cl2chan->next;
  827. else My_Cl2Chan = cl2chan->next;
  828. free( cl2chan );
  829. switch( Type )
  830. {
  831. case REMOVE_QUIT:
  832. /* QUIT: other servers have already been notified,
  833. * see Client_Destroy(); so only inform other clients
  834. * in same channel. */
  835. assert( InformServer == false );
  836. LogDebug("User \"%s\" left channel \"%s\" (%s).",
  837. Client_Mask( Client ), c->name, Reason );
  838. break;
  839. case REMOVE_KICK:
  840. /* User was KICKed: inform other servers (public
  841. * channels) and all users in the channel */
  842. if( InformServer )
  843. IRC_WriteStrServersPrefix( Client_NextHop( Origin ),
  844. Origin, "KICK %s %s :%s", c->name, Client_ID( Client ), Reason);
  845. IRC_WriteStrChannelPrefix(Client, c, Origin, false, "KICK %s %s :%s",
  846. c->name, Client_ID( Client ), Reason );
  847. if ((Client_Conn(Client) > NONE) &&
  848. (Client_Type(Client) == CLIENT_USER))
  849. {
  850. IRC_WriteStrClientPrefix(Client, Origin, "KICK %s %s :%s",
  851. c->name, Client_ID( Client ), Reason);
  852. }
  853. LogDebug("User \"%s\" has been kicked off \"%s\" by \"%s\": %s.",
  854. Client_Mask( Client ), c->name, Client_ID(Origin), Reason);
  855. break;
  856. default: /* PART */
  857. if (Conf_MorePrivacy)
  858. Reason = "";
  859. if (InformServer)
  860. IRC_WriteStrServersPrefix(Origin, Client, "PART %s :%s", c->name, Reason);
  861. IRC_WriteStrChannelPrefix(Origin, c, Client, false, "PART %s :%s",
  862. c->name, Reason);
  863. if ((Client_Conn(Origin) > NONE) &&
  864. (Client_Type(Origin) == CLIENT_USER))
  865. {
  866. IRC_WriteStrClientPrefix( Origin, Client, "PART %s :%s", c->name, Reason);
  867. LogDebug("User \"%s\" left channel \"%s\" (%s).",
  868. Client_Mask(Client), c->name, Reason);
  869. }
  870. }
  871. /* When channel is empty and is not pre-defined, delete */
  872. if( ! Channel_HasMode( Chan, 'P' ))
  873. {
  874. if( ! Get_First_Cl2Chan( NULL, Chan )) Delete_Channel( Chan );
  875. }
  876. return true;
  877. } /* Remove_Client */
  878. GLOBAL bool
  879. Channel_AddBan(CHANNEL *c, const char *mask, const char *who )
  880. {
  881. struct list_head *h = Channel_GetListBans(c);
  882. LogDebug("Adding \"%s\" to \"%s\" ban list", mask, Channel_Name(c));
  883. return Lists_Add(h, mask, time(NULL), who, false);
  884. }
  885. GLOBAL bool
  886. Channel_AddExcept(CHANNEL *c, const char *mask, const char *who )
  887. {
  888. struct list_head *h = Channel_GetListExcepts(c);
  889. LogDebug("Adding \"%s\" to \"%s\" exception list", mask, Channel_Name(c));
  890. return Lists_Add(h, mask, time(NULL), who, false);
  891. }
  892. GLOBAL bool
  893. Channel_AddInvite(CHANNEL *c, const char *mask, bool onlyonce, const char *who )
  894. {
  895. struct list_head *h = Channel_GetListInvites(c);
  896. LogDebug("Adding \"%s\" to \"%s\" invite list", mask, Channel_Name(c));
  897. return Lists_Add(h, mask, time(NULL), who, onlyonce);
  898. }
  899. static bool
  900. ShowChannelList(struct list_head *head, CLIENT *Client, CHANNEL *Channel,
  901. char *msg, char *msg_end)
  902. {
  903. struct list_elem *e;
  904. assert (Client != NULL);
  905. assert (Channel != NULL);
  906. e = Lists_GetFirst(head);
  907. while (e) {
  908. if (!IRC_WriteStrClient(Client, msg, Client_ID(Client),
  909. Channel_Name(Channel),
  910. Lists_GetMask(e),
  911. Lists_GetReason(e),
  912. Lists_GetValidity(e)))
  913. return DISCONNECTED;
  914. e = Lists_GetNext(e);
  915. }
  916. return IRC_WriteStrClient(Client, msg_end, Client_ID(Client),
  917. Channel_Name(Channel));
  918. }
  919. GLOBAL bool
  920. Channel_ShowBans( CLIENT *Client, CHANNEL *Channel )
  921. {
  922. struct list_head *h;
  923. assert( Channel != NULL );
  924. h = Channel_GetListBans(Channel);
  925. return ShowChannelList(h, Client, Channel, RPL_BANLIST_MSG,
  926. RPL_ENDOFBANLIST_MSG);
  927. }
  928. GLOBAL bool
  929. Channel_ShowExcepts( CLIENT *Client, CHANNEL *Channel )
  930. {
  931. struct list_head *h;
  932. assert( Channel != NULL );
  933. h = Channel_GetListExcepts(Channel);
  934. return ShowChannelList(h, Client, Channel, RPL_EXCEPTLIST_MSG,
  935. RPL_ENDOFEXCEPTLIST_MSG);
  936. }
  937. GLOBAL bool
  938. Channel_ShowInvites( CLIENT *Client, CHANNEL *Channel )
  939. {
  940. struct list_head *h;
  941. assert( Channel != NULL );
  942. h = Channel_GetListInvites(Channel);
  943. return ShowChannelList(h, Client, Channel, RPL_INVITELIST_MSG,
  944. RPL_ENDOFINVITELIST_MSG);
  945. }
  946. /**
  947. * Log a message to the local &SERVER channel, if it exists.
  948. */
  949. GLOBAL void
  950. Channel_LogServer(const char *msg)
  951. {
  952. CHANNEL *sc;
  953. CLIENT *c;
  954. assert(msg != NULL);
  955. sc = Channel_Search("&SERVER");
  956. if (!sc)
  957. return;
  958. c = Client_ThisServer();
  959. Channel_Write(sc, c, c, "PRIVMSG", false, msg);
  960. } /* Channel_LogServer */
  961. GLOBAL bool
  962. Channel_CheckKey(CHANNEL *Chan, CLIENT *Client, const char *Key)
  963. {
  964. char *file_name, line[COMMAND_LEN], *nick, *pass;
  965. FILE *fd;
  966. assert(Chan != NULL);
  967. assert(Client != NULL);
  968. assert(Key != NULL);
  969. if (!Channel_HasMode(Chan, 'k'))
  970. return true;
  971. if (*Key == '\0')
  972. return false;
  973. if (strcmp(Chan->key, Key) == 0)
  974. return true;
  975. file_name = array_start(&Chan->keyfile);
  976. if (!file_name)
  977. return false;
  978. fd = fopen(file_name, "r");
  979. if (!fd) {
  980. Log(LOG_ERR, "Can't open channel key file \"%s\" for %s: %s",
  981. file_name, Chan->name, strerror(errno));
  982. return false;
  983. }
  984. while (fgets(line, (int)sizeof(line), fd) != NULL) {
  985. ngt_TrimStr(line);
  986. if (! (nick = strchr(line, ':')))
  987. continue;
  988. *nick++ = '\0';
  989. if (!Match(line, Client_User(Client)))
  990. continue;
  991. if (! (pass = strchr(nick, ':')))
  992. continue;
  993. *pass++ = '\0';
  994. if (!Match(nick, Client_ID(Client)))
  995. continue;
  996. if (strcmp(Key, pass) != 0)
  997. continue;
  998. fclose(fd);
  999. return true;
  1000. }
  1001. fclose(fd);
  1002. return false;
  1003. } /* Channel_CheckKey */
  1004. static CL2CHAN *
  1005. Get_First_Cl2Chan( CLIENT *Client, CHANNEL *Chan )
  1006. {
  1007. return Get_Next_Cl2Chan( My_Cl2Chan, Client, Chan );
  1008. } /* Get_First_Cl2Chan */
  1009. static CL2CHAN *
  1010. Get_Next_Cl2Chan( CL2CHAN *Start, CLIENT *Client, CHANNEL *Channel )
  1011. {
  1012. CL2CHAN *cl2chan;
  1013. assert( Client != NULL || Channel != NULL );
  1014. cl2chan = Start;
  1015. while( cl2chan )
  1016. {
  1017. if(( Client ) && ( cl2chan->client == Client )) return cl2chan;
  1018. if(( Channel ) && ( cl2chan->channel == Channel )) return cl2chan;
  1019. cl2chan = cl2chan->next;
  1020. }
  1021. return NULL;
  1022. } /* Get_Next_Cl2Chan */
  1023. /**
  1024. * Remove a channel and free all of its data structures.
  1025. */
  1026. static void
  1027. Delete_Channel(CHANNEL *Chan)
  1028. {
  1029. CHANNEL *chan, *last_chan;
  1030. last_chan = NULL;
  1031. chan = My_Channels;
  1032. while (chan) {
  1033. if (chan == Chan)
  1034. break;
  1035. last_chan = chan;
  1036. chan = chan->next;
  1037. }
  1038. assert(chan != NULL);
  1039. if (!chan)
  1040. return;
  1041. /* maintain channel list */
  1042. if (last_chan)
  1043. last_chan->next = chan->next;
  1044. else
  1045. My_Channels = chan->next;
  1046. LogDebug("Freed channel structure for \"%s\".", Chan->name);
  1047. Free_Channel(Chan);
  1048. } /* Delete_Channel */
  1049. static void
  1050. Set_KeyFile(CHANNEL *Chan, const char *KeyFile)
  1051. {
  1052. size_t len;
  1053. assert(Chan != NULL);
  1054. assert(KeyFile != NULL);
  1055. len = strlen(KeyFile);
  1056. if (len < array_bytes(&Chan->keyfile)) {
  1057. Log(LOG_INFO, "Channel key file of %s removed.", Chan->name);
  1058. array_free(&Chan->keyfile);
  1059. }
  1060. if (len < 1)
  1061. return;
  1062. if (!array_copyb(&Chan->keyfile, KeyFile, len+1))
  1063. Log(LOG_WARNING,
  1064. "Could not set new channel key file \"%s\" for %s: %s",
  1065. KeyFile, Chan->name, strerror(errno));
  1066. else
  1067. Log(LOG_INFO|LOG_snotice,
  1068. "New local channel key file \"%s\" for %s activated.",
  1069. KeyFile, Chan->name);
  1070. } /* Set_KeyFile */
  1071. /* -eof- */