functions.php 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208
  1. <?php
  2. if (defined('E_DEPRECATED')) {
  3. error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
  4. } else {
  5. error_reporting(E_ALL & ~E_NOTICE);
  6. }
  7. mb_internal_encoding("UTF-8");
  8. require_once "config.php";
  9. require_once "version.php";
  10. require_once "message_types.php";
  11. require_once "db-prefs.php";
  12. define('SINGLE_USER_MODE', false);
  13. if (DB_TYPE == 'mysql') {
  14. define('DB_KEY_FIELD', 'param');
  15. } else {
  16. define('DB_KEY_FIELD', 'key');
  17. }
  18. if (DB_TYPE == "pgsql") {
  19. define('SUBSTRING_FOR_DATE', 'SUBSTRING_FOR_DATE');
  20. } else {
  21. define('SUBSTRING_FOR_DATE', 'SUBSTRING');
  22. }
  23. function get_translations() {
  24. $tr = array(
  25. "auto" => "Detect automatically",
  26. "en_US" => "English",
  27. "es_MX" => "Spanish (Mexican)",
  28. "fr_FR" => "Français",
  29. "xx_XX" => "Bork bork bork!");
  30. return $tr;
  31. }
  32. if (ENABLE_TRANSLATIONS == true) { // If translations are enabled.
  33. require_once "lib/accept-to-gettext.php";
  34. require_once "lib/gettext/gettext.inc";
  35. function startup_gettext() {
  36. # Get locale from Accept-Language header
  37. $lang = al2gt(array_keys(get_translations()), "text/html");
  38. if (defined('_TRANSLATION_OVERRIDE_DEFAULT')) {
  39. $lang = _TRANSLATION_OVERRIDE_DEFAULT;
  40. }
  41. if ($_COOKIE["ttirc_lang"] && $_COOKIE["ttirc_lang"] != "auto") {
  42. $lang = $_COOKIE["ttirc_lang"];
  43. }
  44. /* In login action of mobile version */
  45. if ($_POST["language"] && defined('MOBILE_VERSION')) {
  46. $lang = $_POST["language"];
  47. $_COOKIE["ttirc_lang"] = $lang;
  48. }
  49. if ($lang) {
  50. if (defined('LC_MESSAGES')) {
  51. _setlocale(LC_MESSAGES, $lang);
  52. } else if (defined('LC_ALL')) {
  53. _setlocale(LC_ALL, $lang);
  54. } else {
  55. die("can't setlocale(): please set ENABLE_TRANSLATIONS to false in config.php");
  56. }
  57. if (defined('MOBILE_VERSION')) {
  58. _bindtextdomain("messages", "../locale");
  59. } else {
  60. _bindtextdomain("messages", "locale");
  61. }
  62. _textdomain("messages");
  63. _bind_textdomain_codeset("messages", "UTF-8");
  64. }
  65. }
  66. startup_gettext();
  67. } else { // If translations are enabled.
  68. function __($msg) {
  69. return $msg;
  70. }
  71. function startup_gettext() {
  72. // no-op
  73. return true;
  74. }
  75. } // If translations are enabled.
  76. require_once "errors.php";
  77. function init_connection($link) {
  78. if (!$link) {
  79. if (DB_TYPE == "mysql") {
  80. print mysql_error();
  81. }
  82. // PG seems to display its own errors just fine by default.
  83. die("Connection failed.");
  84. }
  85. if (DB_TYPE == "pgsql") {
  86. pg_query($link, "set client_encoding = 'UTF-8'");
  87. pg_set_client_encoding("UNICODE");
  88. pg_query($link, "set datestyle = 'ISO, european'");
  89. pg_query($link, "set time zone '".DB_TIMEZONE."'");
  90. } else {
  91. if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) {
  92. db_query($link, "SET NAMES " . MYSQL_CHARSET);
  93. // db_query($link, "SET CHARACTER SET " . MYSQL_CHARSET);
  94. }
  95. }
  96. }
  97. function login_sequence($link, $mobile = false) {
  98. $_SESSION["prefs_cache"] = array();
  99. if (!SINGLE_USER_MODE) {
  100. $login_action = $_POST["login_action"];
  101. # try to authenticate user if called from login form
  102. if ($login_action == "do_login") {
  103. $login = $_POST["login"];
  104. $password = $_POST["password"];
  105. $remember_me = $_POST["remember_me"];
  106. if (authenticate_user($link, $login, $password)) {
  107. $_POST["password"] = "";
  108. $_SESSION["language"] = $_POST["language"];
  109. $_SESSION["ref_schema_version"] = get_schema_version($link, true);
  110. $_SESSION["bw_limit"] = !!$_POST["bw_limit"];
  111. header("Location: " . $_SERVER["REQUEST_URI"]);
  112. exit;
  113. return;
  114. } else {
  115. $_SESSION["login_error_msg"] = __("Incorrect username or password");
  116. }
  117. }
  118. if (!$_SESSION["uid"] || !validate_session($link)) {
  119. header('Cache-Control: public');
  120. render_login_form($link, $mobile);
  121. //header("Location: login.php");
  122. exit;
  123. } else {
  124. /* bump login timestamp */
  125. if (get_schema_version($link) >= 3) {
  126. db_query($link, "UPDATE ttirc_users SET last_login = NOW() WHERE id = " .
  127. $_SESSION["uid"]);
  128. }
  129. if ($_SESSION["language"] && SESSION_COOKIE_LIFETIME > 0) {
  130. setcookie("ttirc_lang", $_SESSION["language"],
  131. time() + SESSION_COOKIE_LIFETIME);
  132. }
  133. /* Enable automatic connections */
  134. db_query($link, "UPDATE ttirc_connections SET enabled = true
  135. WHERE auto_connect = true AND owner_uid = " . $_SESSION["uid"]);
  136. initialize_user_prefs($link, $_SESSION["uid"]);
  137. /* $tmp_result = db_query($link, "SELECT id FROM ttirc_connections
  138. WHERE status != ".CS_DISCONNECTED." AND owner_uid = " .
  139. $_SESSION["uid"]);
  140. while ($conn = db_fetch_assoc($tmp_result)) {
  141. push_message($link, $conn['id'], "---",
  142. "Accepted connection from " . $_SERVER["REMOTE_ADDR"],
  143. true);
  144. } */
  145. }
  146. } else {
  147. return authenticate_user($link, "admin", null);
  148. }
  149. }
  150. function render_login_form($link, $mobile = 0) {
  151. switch ($mobile) {
  152. case 0:
  153. require_once "login_form.php";
  154. break;
  155. case 1:
  156. require_once "mobile/login_form.php";
  157. break;
  158. case 2:
  159. require_once "mobile/classic/login_form.php";
  160. }
  161. }
  162. function print_select($id, $default, $values, $attributes = "") {
  163. print "<select name=\"$id\" id=\"$id\" $attributes>";
  164. foreach ($values as $v) {
  165. if ($v == $default)
  166. $sel = " selected";
  167. else
  168. $sel = "";
  169. print "<option$sel>$v</option>";
  170. }
  171. print "</select>";
  172. }
  173. function print_select_hash($id, $default, $values, $attributes = "") {
  174. print "<select name=\"$id\" id='$id' $attributes>";
  175. foreach (array_keys($values) as $v) {
  176. if ($v == $default)
  177. $sel = 'selected="selected"';
  178. else
  179. $sel = "";
  180. print "<option $sel value=\"$v\">".$values[$v]."</option>";
  181. }
  182. print "</select>";
  183. }
  184. function encrypt_password($pass, $salt = '', $mode2 = false) {
  185. if ($salt && $mode2) {
  186. return "MODE2:" . hash('sha256', $salt . $pass);
  187. } else if ($salt) {
  188. return "SHA1X:" . sha1("$salt:$pass");
  189. } else {
  190. return "SHA1:" . sha1($pass);
  191. }
  192. } // function encrypt_password
  193. function authenticate_user($link, $login, $password, $force_auth = false) {
  194. if (!SINGLE_USER_MODE) {
  195. $pwd_hash1 = encrypt_password($password);
  196. $pwd_hash2 = encrypt_password($password, $login);
  197. $login = db_escape_string($login);
  198. if (defined('ALLOW_REMOTE_USER_AUTH') && ALLOW_REMOTE_USER_AUTH
  199. && $_SERVER["REMOTE_USER"] && $login != "admin") {
  200. $login = db_escape_string($_SERVER["REMOTE_USER"]);
  201. $query = "SELECT id,login,access_level,pwd_hash
  202. FROM ttirc_users WHERE
  203. login = '$login'";
  204. } else if (get_schema_version($link) > 6) {
  205. $result = db_query($link, "SELECT salt FROM ttirc_users WHERE
  206. login = '$login'");
  207. $salt = db_fetch_result($result, 0, "salt");
  208. if ($salt == "") {
  209. $query = "SELECT id,login,access_level,pwd_hash
  210. FROM ttirc_users WHERE
  211. login = '$login' AND (pwd_hash = '$pwd_hash1' OR
  212. pwd_hash = '$pwd_hash2')";
  213. // verify and upgrade password to new salt base
  214. $result = db_query($link, $query);
  215. if (db_num_rows($result) == 1) {
  216. // upgrade password to MODE2
  217. $salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
  218. $pwd_hash = encrypt_password($password, $salt, true);
  219. db_query($link, "UPDATE ttirc_users SET
  220. pwd_hash = '$pwd_hash', salt = '$salt' WHERE login = '$login'");
  221. $query = "SELECT id,login,access_level,pwd_hash
  222. FROM ttirc_users WHERE
  223. login = '$login' AND pwd_hash = '$pwd_hash'";
  224. } else {
  225. return false;
  226. }
  227. } else {
  228. $pwd_hash = encrypt_password($password, $salt, true);
  229. $query = "SELECT id,login,access_level,pwd_hash
  230. FROM ttirc_users WHERE
  231. login = '$login' AND pwd_hash = '$pwd_hash'";
  232. }
  233. } else {
  234. $query = "SELECT id,login,access_level,pwd_hash
  235. FROM ttirc_users WHERE
  236. login = '$login' AND (pwd_hash = '$pwd_hash1' OR
  237. pwd_hash = '$pwd_hash2')";
  238. }
  239. $result = db_query($link, $query);
  240. if (db_num_rows($result) == 1) {
  241. $_SESSION["uid"] = db_fetch_result($result, 0, "id");
  242. $_SESSION["name"] = db_fetch_result($result, 0, "login");
  243. $_SESSION["access_level"] = db_fetch_result($result, 0, "access_level");
  244. db_query($link, "UPDATE ttirc_users SET last_login = NOW() WHERE id = " .
  245. $_SESSION["uid"]);
  246. $_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"];
  247. $_SESSION["pwd_hash"] = db_fetch_result($result, 0, "pwd_hash");
  248. initialize_user_prefs($link, $_SESSION["uid"]);
  249. return true;
  250. }
  251. return false;
  252. } else {
  253. $_SESSION["uid"] = 1;
  254. $_SESSION["name"] = "admin";
  255. $_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"];
  256. initialize_user_prefs($link, $_SESSION["uid"]);
  257. return true;
  258. }
  259. }
  260. function get_schema_version($link, $nocache = false) {
  261. if (!$_SESSION["schema_version"] || $nocache) {
  262. $result = db_query($link, "SELECT schema_version FROM ttirc_version");
  263. $version = db_fetch_result($result, 0, "schema_version");
  264. $_SESSION["schema_version"] = $version;
  265. return $version;
  266. } else {
  267. return $_SESSION["schema_version"];
  268. }
  269. }
  270. function validate_session($link) {
  271. if (SINGLE_USER_MODE) {
  272. return true;
  273. }
  274. if (SESSION_CHECK_ADDRESS && $_SESSION["uid"]) {
  275. if ($_SESSION["ip_address"]) {
  276. if ($_SESSION["ip_address"] != $_SERVER["REMOTE_ADDR"]) {
  277. $_SESSION["login_error_msg"] = __("Session failed to validate (incorrect IP)");
  278. return false;
  279. }
  280. }
  281. }
  282. if ($_SESSION["ref_schema_version"] != get_schema_version($link, true)) {
  283. return false;
  284. }
  285. if ($_SESSION["uid"]) {
  286. $result = db_query($link,
  287. "SELECT pwd_hash FROM ttirc_users WHERE id = '".$_SESSION["uid"]."'");
  288. $pwd_hash = db_fetch_result($result, 0, "pwd_hash");
  289. if ($pwd_hash != $_SESSION["pwd_hash"]) {
  290. return false;
  291. }
  292. }
  293. return true;
  294. }
  295. function get_script_dt_add() {
  296. return time();
  297. }
  298. function theme_image($link, $filename) {
  299. if ($link) {
  300. $theme_path = get_user_theme_path($link);
  301. if ($theme_path && is_file($theme_path.$filename)) {
  302. return $theme_path.$filename;
  303. } else {
  304. return $filename;
  305. }
  306. } else {
  307. return $filename;
  308. }
  309. }
  310. function get_user_theme($link) {
  311. $theme_name = get_pref($link, "USER_THEME");
  312. if (is_dir("themes/$theme_name")) {
  313. return $theme_name;
  314. } else {
  315. return '';
  316. }
  317. }
  318. function get_user_theme_path($link) {
  319. $theme_name = get_pref($link, "USER_THEME");
  320. if ($theme_name && is_dir("themes/$theme_name")) {
  321. $theme_path = "themes/$theme_name/";
  322. } else {
  323. $theme_name = '';
  324. }
  325. return $theme_path;
  326. }
  327. function get_all_themes() {
  328. $themes = glob("themes/*");
  329. asort($themes);
  330. $rv = array();
  331. foreach ($themes as $t) {
  332. if (is_file("$t/theme.ini")) {
  333. $ini = parse_ini_file("$t/theme.ini", true);
  334. if ($ini['theme']['version'] && !$ini['theme']['disabled']) {
  335. $entry = array();
  336. $entry["path"] = $t;
  337. $entry["base"] = basename($t);
  338. $entry["name"] = $ini['theme']['name'];
  339. $entry["version"] = $ini['theme']['version'];
  340. $entry["author"] = $ini['theme']['author'];
  341. $entry["options"] = $ini['theme']['options'];
  342. array_push($rv, $entry);
  343. }
  344. }
  345. }
  346. return $rv;
  347. }
  348. function logout_user() {
  349. session_destroy();
  350. if (isset($_COOKIE[session_name()])) {
  351. setcookie(session_name(), '', time()-42000, '/');
  352. }
  353. }
  354. function format_warning($msg, $id = "") {
  355. global $link;
  356. return "<div class=\"warning\" id=\"$id\">
  357. <img src=\"".theme_image($link, "images/sign_excl.png")."\">$msg</div>";
  358. }
  359. function format_notice($msg) {
  360. global $link;
  361. return "<div class=\"notice\" id=\"$id\">
  362. <img src=\"".theme_image($link, "images/sign_info.png")."\">$msg</div>";
  363. }
  364. function format_error($msg) {
  365. global $link;
  366. return "<div class=\"error\" id=\"$id\">
  367. <img src=\"".theme_image($link, "images/sign_excl.png")."\">$msg</div>";
  368. }
  369. function print_notice($msg) {
  370. return print format_notice($msg);
  371. }
  372. function print_warning($msg) {
  373. return print format_warning($msg);
  374. }
  375. function print_error($msg) {
  376. return print format_error($msg);
  377. }
  378. function T_sprintf() {
  379. $args = func_get_args();
  380. return vsprintf(__(array_shift($args)), $args);
  381. }
  382. function _debug($msg) {
  383. $ts = strftime("%H:%M:%S", time());
  384. if (function_exists('posix_getpid')) {
  385. $ts = "$ts/" . posix_getpid();
  386. }
  387. print "[$ts] $msg\n";
  388. } // function _debug
  389. # TODO return actual nick, not hardcoded one
  390. function get_nick($link, $connection_id) {
  391. $result = db_query($link, "SELECT active_nick FROM ttirc_connections
  392. WHERE id ='$connection_id'");
  393. if (db_num_rows($result) == 1) {
  394. return db_fetch_result($result, 0, "active_nick");
  395. } else {
  396. return "?UNKNOWN?";
  397. }
  398. }
  399. function handle_command($link, $connection_id, $channel, $message) {
  400. $keywords = array();
  401. preg_match("/^\/([^ ]+) ?(.*)$/", $message, $keywords);
  402. $command = trim(strtolower($keywords[1]));
  403. $arguments = trim($keywords[2]);
  404. if ($command == "j") $command = "join";
  405. if ($command == "me") {
  406. $command = "action";
  407. push_message($link, $connection_id, $channel,
  408. "$arguments", true, MSGT_ACTION);
  409. }
  410. if ($command == "notice") {
  411. list ($nick, $message) = explode(" ", $arguments, 2);
  412. push_message($link, $connection_id, $channel,
  413. "$message", false, MSGT_NOTICE, $nick);
  414. }
  415. switch ($command) {
  416. case "query":
  417. db_query($link, "BEGIN");
  418. $result = db_query($link, "SELECT id FROM ttirc_channels WHERE
  419. channel = '$arguments' AND connection_id = '$connection_id'");
  420. if (db_num_rows($result) == 0) {
  421. db_query($link, "INSERT INTO ttirc_channels
  422. (channel, connection_id, chan_type) VALUES
  423. ('$arguments', '$connection_id', '".CT_PRIVATE."')");
  424. }
  425. db_query($link, "COMMIT");
  426. break;
  427. case "part":
  428. if (!$arguments) $arguments = $channel;
  429. db_query($link, "BEGIN");
  430. $result = db_query($link, "SELECT chan_type FROM ttirc_channels WHERE
  431. channel = '$arguments' AND connection_id = '$connection_id'");
  432. if (db_num_rows($result) != 0) {
  433. $chan_type = db_fetch_result($result, 0, "chan_type");
  434. if ($chan_type == CT_PRIVATE) {
  435. db_query($link, "DELETE FROM ttirc_channels WHERE
  436. channel = '$arguments' AND connection_id = '$connection_id'");
  437. } else {
  438. push_message($link, $connection_id, $channel,
  439. "$command:$arguments", false, MSGT_COMMAND);
  440. }
  441. }
  442. db_query($link, "COMMIT");
  443. break;
  444. default:
  445. push_message($link, $connection_id, $channel,
  446. "$command:$arguments", false, MSGT_COMMAND);
  447. break;
  448. }
  449. return $last_id;
  450. }
  451. function push_message($link, $connection_id, $channel, $message,
  452. $incoming = false, $message_type = MSGT_PRIVMSG, $from_nick = false) {
  453. if ($message === "") return false;
  454. $incoming = bool_to_sql_bool($incoming);
  455. if ($channel != "---") {
  456. $my_nick = get_nick($link, $connection_id);
  457. } else {
  458. $my_nick = "---";
  459. }
  460. if ($from_nick) $my_nick = $from_nick;
  461. //$message = db_escape_string($message);
  462. $result = db_query($link, "INSERT INTO ttirc_messages
  463. (incoming, connection_id, channel, sender, message, message_type, ts) VALUES
  464. ($incoming, $connection_id, '$channel', '$my_nick', '$message',
  465. '$message_type', NOW())");
  466. }
  467. function get_initial_last_id($link) {
  468. $result = db_query($link, "SELECT ttirc_messages.id
  469. FROM ttirc_messages, ttirc_connections
  470. WHERE
  471. owner_uid = ".$_SESSION["uid"]." AND
  472. connection_id = ttirc_connections.id
  473. ORDER BY id DESC LIMIT 1 OFFSET 50");
  474. if (db_num_rows($result) != 0) {
  475. return db_fetch_result($result, 0, "id");
  476. } else {
  477. return 0;
  478. }
  479. }
  480. function num_new_lines($link, $last_id) {
  481. if (!$last_id) $last_id = get_initial_last_id($link);
  482. $result = db_query($link, "SELECT COUNT(*) AS cl
  483. FROM ttirc_messages, ttirc_connections WHERE
  484. connection_id = ttirc_connections.id AND
  485. message_type != ".MSGT_COMMAND." AND
  486. ttirc_messages.id > '$last_id' AND
  487. owner_uid = ".$_SESSION["uid"]." LIMIT 50");
  488. return db_fetch_result($result, 0, "cl");
  489. }
  490. function get_new_lines($link, $last_id) {
  491. if (!$last_id) $last_id = get_initial_last_id($link);
  492. $result = db_query($link, "SELECT ttirc_messages.id,
  493. message_type, sender, channel, connection_id, incoming,
  494. message, ".SUBSTRING_FOR_DATE."(ts,1,19) AS ts
  495. FROM ttirc_messages, ttirc_connections WHERE
  496. connection_id = ttirc_connections.id AND
  497. message_type != ".MSGT_COMMAND." AND
  498. ttirc_messages.id > '$last_id' AND
  499. owner_uid = ".$_SESSION["uid"]." ORDER BY id LIMIT 50");
  500. $lines = array();
  501. while ($line = db_fetch_assoc($result)) {
  502. $line["sender_color"] = color_of($line["sender"]);
  503. $line["incoming"] = sql_bool_to_bool($line["incoming"]);
  504. array_push($lines, $line);
  505. }
  506. return $lines;
  507. }
  508. function get_chan_data($link, $active_chan = false) {
  509. if ($active_chan && $active_chan != "---") {
  510. $active_chan_qpart = "channel = '$active_chan' AND";
  511. } else {
  512. $active_chan_qpart = "";
  513. }
  514. $result = db_query($link, "SELECT nicklist,channel,connection_id,
  515. chan_type,topic,
  516. topic_owner,".SUBSTRING_FOR_DATE."(topic_set,1,16) AS topic_set
  517. FROM ttirc_channels, ttirc_connections
  518. WHERE connection_id = ttirc_connections.id AND
  519. $active_chan_qpart
  520. owner_uid = ".$_SESSION["uid"]);
  521. $rv = array();
  522. while ($line = db_fetch_assoc($result)) {
  523. $chan = $line["channel"];
  524. $re = array();
  525. $re["chan_type"] = $line["chan_type"];
  526. $re["users"] = sort_nicklist(json_decode($line["nicklist"]));
  527. $re["topic"] = array(
  528. $line["topic"], $line["topic_owner"], $line["topic_set"]);
  529. $rv[$line["connection_id"]][$chan] = $re;
  530. }
  531. return $rv;
  532. }
  533. function get_conn_info($link) {
  534. $result = db_query($link, "SELECT id,active_server,active_nick,status,
  535. title,userhosts
  536. FROM ttirc_connections
  537. WHERE visible = true AND owner_uid = ".$_SESSION["uid"] . "
  538. ORDER BY id");
  539. $conn = array();
  540. while ($line = db_fetch_assoc($result)) {
  541. if ($line['userhosts']) $line['userhosts'] = json_decode($line['userhosts']);
  542. array_push($conn, $line);
  543. }
  544. return $conn;
  545. }
  546. function sql_bool_to_string($s) {
  547. if ($s == "t" || $s == "1") {
  548. return "true";
  549. } else {
  550. return "false";
  551. }
  552. }
  553. function sql_bool_to_bool($s) {
  554. if ($s == "t" || $s == "1") {
  555. return true;
  556. } else {
  557. return false;
  558. }
  559. }
  560. function bool_to_sql_bool($s) {
  561. if ($s) {
  562. return "true";
  563. } else {
  564. return "false";
  565. }
  566. }
  567. function sanity_check($link) {
  568. global $ERRORS;
  569. $error_code = 0;
  570. $schema_version = get_schema_version($link);
  571. if ($schema_version != SCHEMA_VERSION) {
  572. $error_code = 5;
  573. }
  574. if (DB_TYPE == "mysql") {
  575. $result = db_query($link, "SELECT true", false);
  576. if (db_num_rows($result) != 1) {
  577. $error_code = 10;
  578. }
  579. }
  580. if (db_escape_string("testTEST") != "testTEST") {
  581. $error_code = 12;
  582. }
  583. $result = db_query($link, "SELECT value FROM ttirc_system WHERE
  584. ".DB_KEY_FIELD." = 'MASTER_RUNNING'");
  585. $master_running = db_fetch_result($result, 0, "value") == "true";
  586. if (!$master_running) {
  587. $error_code = 13;
  588. }
  589. if ($error_code != 0) {
  590. print json_encode(array("error" => $error_code,
  591. "errormsg" => $ERRORS[$error_code]));
  592. return false;
  593. } else {
  594. return true;
  595. }
  596. }
  597. function get_random_server($link, $connection_id) {
  598. $result = db_query($link, "SELECT * FROM ttirc_servers WHERE
  599. connection_id = '$connection_id' ORDER BY RANDOM() LIMIT 1");
  600. if (db_num_rows($result) != 0) {
  601. return db_fetch_assoc($result);
  602. } else {
  603. return false;
  604. }
  605. }
  606. // shamelessly stolen from xchat source code
  607. function color_of($name) {
  608. $rcolors = array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  609. 13, 14, 15 );
  610. $i = 0;
  611. $sum = 0;
  612. for ($i = 0; $i < strlen($name); $i++) {
  613. $sum += ord($name{$i});
  614. }
  615. $sum %= count($rcolors);
  616. return $rcolors[$sum];
  617. }
  618. function purge_old_lines($link) {
  619. db_query($link, "DELETE FROM ttirc_messages WHERE
  620. ts < NOW() - INTERVAL '3 hours'");
  621. }
  622. function update_heartbeat($link) {
  623. if (time() - $_SESSION["heartbeat_last"] > 120) {
  624. $result = db_query($link, "UPDATE ttirc_users SET heartbeat = NOW()
  625. WHERE id = " . $_SESSION["uid"]);
  626. $_SESSION["heartbeat_last"] = time();
  627. }
  628. }
  629. function initialize_user_prefs($link, $uid, $profile = false) {
  630. $uid = db_escape_string($uid);
  631. if (!$profile) {
  632. $profile = "NULL";
  633. $profile_qpart = "AND profile IS NULL";
  634. } else {
  635. $profile_qpart = "AND profile = '$profile'";
  636. }
  637. db_query($link, "BEGIN");
  638. $result = db_query($link, "SELECT pref_name,def_value FROM ttirc_prefs");
  639. $u_result = db_query($link, "SELECT pref_name
  640. FROM ttirc_user_prefs WHERE owner_uid = '$uid' $profile_qpart");
  641. $active_prefs = array();
  642. while ($line = db_fetch_assoc($u_result)) {
  643. array_push($active_prefs, $line["pref_name"]);
  644. }
  645. while ($line = db_fetch_assoc($result)) {
  646. if (array_search($line["pref_name"], $active_prefs) === FALSE) {
  647. // print "adding " . $line["pref_name"] . "<br>";
  648. if (get_schema_version($link) < 63) {
  649. db_query($link, "INSERT INTO ttirc_user_prefs
  650. (owner_uid,pref_name,value) VALUES
  651. ('$uid', '".$line["pref_name"]."','".$line["def_value"]."')");
  652. } else {
  653. db_query($link, "INSERT INTO ttirc_user_prefs
  654. (owner_uid,pref_name,value, profile) VALUES
  655. ('$uid', '".$line["pref_name"]."','".$line["def_value"]."', $profile)");
  656. }
  657. }
  658. }
  659. db_query($link, "COMMIT");
  660. }
  661. function valid_connection($link, $id) {
  662. $result = db_query($link, "SELECT id FROM ttirc_connections
  663. WHERE id = '$id' AND owner_uid = " . $_SESSION["uid"]);
  664. return db_num_rows($result) == 1;
  665. }
  666. function make_password($length = 8) {
  667. $password = "";
  668. $possible = "0123456789abcdfghjkmnpqrstvwxyzABCDFGHJKMNPQRSTVWXYZ";
  669. $i = 0;
  670. while ($i < $length) {
  671. $char = substr($possible, mt_rand(0, strlen($possible)-1), 1);
  672. if (!strstr($password, $char)) {
  673. $password .= $char;
  674. $i++;
  675. }
  676. }
  677. return $password;
  678. }
  679. function get_user_login($link, $id) {
  680. $result = db_query($link, "SELECT login FROM ttirc_users WHERE id = '$id'");
  681. if (db_num_rows($result) == 1) {
  682. return db_fetch_result($result, 0, "login");
  683. } else {
  684. return false;
  685. }
  686. }
  687. function get_iconv_encodings() {
  688. return explode("\n", file_get_contents("lib/iconv.txt"));
  689. }
  690. function print_theme_select($link) {
  691. $user_theme = get_pref($link, "USER_THEME");
  692. $themes = get_all_themes();
  693. print "<select name=\"theme\">";
  694. print "<option value=''>".__('Default')."</option>";
  695. print "<option disabled>--------</option>";
  696. foreach ($themes as $t) {
  697. $base = $t['base'];
  698. $name = $t['name'];
  699. if ($base == $user_theme) {
  700. $selected = "selected=\"1\"";
  701. } else {
  702. $selected = "";
  703. }
  704. print "<option $selected value='$base'>$name</option>";
  705. }
  706. print "</select>";
  707. }
  708. function print_user_css($link) {
  709. $user_css = get_pref($link, "USER_STYLESHEET");
  710. if ($user_css) {
  711. print "<style type=\"text/css\">$user_css</style>";
  712. }
  713. }
  714. function get_misc_params($link, $uniqid = false) {
  715. if (!$uniqid) $uniqid = uniqid();
  716. $notify_on = json_decode(get_pref($link, "NOTIFY_ON"));
  717. if (!is_array($notify_on)) $notify_on = array();
  718. $notify_events = array();
  719. foreach ($notify_on as $no) {
  720. $notify_events[$no] = true;
  721. }
  722. $result = db_query($link, "SELECT hide_join_part FROM ttirc_users
  723. WHERE id = " . $_SESSION["uid"]);
  724. $hide_join_part = sql_bool_to_bool(db_fetch_result($result, 0, "hide_join_part"));
  725. $rv = array(
  726. "hide_join_part" => $hide_join_part,
  727. "uniqid" => $uniqid,
  728. "disable_image_preview" => get_pref($link, "DISABLE_IMAGE_PREVIEW"),
  729. "highlight_on" => explode(",", get_pref($link, "HIGHLIGHT_ON")),
  730. "notify_events" => $notify_events);
  731. return $rv;
  732. }
  733. function get_self_url_prefix() {
  734. $url_path = "";
  735. if ($_SERVER['HTTPS'] != "on") {
  736. $url_path = "http://";
  737. } else {
  738. $url_path = "https://";
  739. }
  740. $url_path .= $_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
  741. return $url_path;
  742. }
  743. function create_snippet($link, $text) {
  744. $text = db_escape_string($text);
  745. $key = db_escape_string(sha1(uniqid(rand(), true)));
  746. $result = db_query($link, "INSERT INTO ttirc_snippets (snippet, owner_uid, created, ".DB_KEY_FIELD.")
  747. VALUES ('$text', '".$_SESSION['uid']."', NOW(), '$key')");
  748. return $key;
  749. }
  750. function truncate_string($str, $max_len) {
  751. if (mb_strlen($str, "utf-8") > $max_len - 3) {
  752. return trim(mb_substr($str, 0, $max_len, "utf-8")) . "...";
  753. } else {
  754. return $str;
  755. }
  756. }
  757. function get_random_bytes($length) {
  758. if (function_exists('openssl_random_pseudo_bytes')) {
  759. return openssl_random_pseudo_bytes($length);
  760. } else {
  761. $output = "";
  762. for ($i = 0; $i < $length; $i++)
  763. $output .= chr(mt_rand(0, 255));
  764. return $output;
  765. }
  766. }
  767. function cleanup_session_cache() {
  768. if (is_array($_SESSION["cache"])) {
  769. foreach (array_keys($_SESSION["cache"]) as $uniqid) {
  770. if (time() - $_SESSION["cache"][$uniqid]["last"] > 120) {
  771. unset($_SESSION["cache"][$uniqid]);
  772. }
  773. }
  774. }
  775. }
  776. function get_emoticons_map() {
  777. $ini = @parse_ini_file("emoticons/emoticons.ini");
  778. if (!$ini) return array();
  779. $tmp = array();
  780. foreach ($ini as $k => $v) {
  781. $tmp[$k] = explode(",", $v);
  782. }
  783. return $tmp;
  784. }
  785. function render_emoticons_full() {
  786. ?>
  787. <html>
  788. <head>
  789. <title>Tiny Tiny IRC</title>
  790. <?php echo stylesheet_tag("tt-irc.css") ?>
  791. </head>
  792. <body id="emoticons_list">
  793. <div id="emoticons_long">
  794. <?php
  795. $emoticons_map = get_emoticons_map();
  796. foreach ($emoticons_map as $k => $e) {
  797. print "<div class=\"tile\"><div class=\"wrapper\">";
  798. print "<img onclick=\"window.opener.inject_text('$k')\" title=\"$k\" src=\"emoticons/$e[0]\">";
  799. print "</div>$k";
  800. print "</div>";
  801. }
  802. ?>
  803. </div>
  804. </body>
  805. </html>
  806. <?php
  807. }
  808. function render_emoticons($link) {
  809. $emoticons_map = get_emoticons_map();
  810. $tmp = "";
  811. $result = db_query($link, "SELECT emoticon FROM ttirc_emoticons_popcon
  812. WHERE owner_uid = " . $_SESSION["uid"] . " ORDER BY times_used DESC LIMIT 30");
  813. $num_favs = 0;
  814. while ($line = db_fetch_assoc($result)) {
  815. ++$num_favs;
  816. $k = $line["emoticon"];
  817. $e = $emoticons_map[$k][0];
  818. $tmp .= "<div class=\"wrapper\"><img onclick=\"inject_text('$k')\" title=\"$k\" src=\"emoticons/$e\"></div>";
  819. }
  820. $num_more = count($emoticons_map) - $num_favs;
  821. if ($num_more > 0) {
  822. $tmp .= "<br clear='both'><p><a href=\"#\" onclick=\"return emoticons_popup()\">$num_more more...</a></p>";
  823. }
  824. return $tmp;
  825. }
  826. function stylesheet_tag($filename) {
  827. $timestamp = filemtime($filename);
  828. echo "<link media=\"screen\" rel=\"stylesheet\" type=\"text/css\" href=\"$filename?$timestamp\"/>\n";
  829. }
  830. function javascript_tag($filename) {
  831. $query = "";
  832. if (!(strpos($filename, "?") === FALSE)) {
  833. $query = substr($filename, strpos($filename, "?")+1);
  834. $filename = substr($filename, 0, strpos($filename, "?"));
  835. }
  836. $timestamp = filemtime($filename);
  837. if ($query) $timestamp .= "&$query";
  838. echo "<script type=\"text/javascript\" charset=\"utf-8\" src=\"$filename?$timestamp\"></script>\n";
  839. }
  840. function get_minified_js($files) {
  841. require_once 'lib/jshrink/Minifier.php';
  842. $rv = '';
  843. foreach ($files as $js) {
  844. if (!isset($_GET['debug'])) {
  845. $cached_file = "cache/js/$js.js";
  846. if (file_exists($cached_file) &&
  847. is_readable($cached_file) &&
  848. filemtime($cached_file) >= filemtime("js/$js.js")) {
  849. $rv .= file_get_contents($cached_file);
  850. } else {
  851. $minified = JShrink\Minifier::minify(file_get_contents("js/$js.js"));
  852. file_put_contents($cached_file, $minified);
  853. $rv .= $minified;
  854. }
  855. } else {
  856. $rv .= file_get_contents("js/$js.js");
  857. }
  858. }
  859. return $rv;
  860. }
  861. function init_js_translations() {
  862. print 'var T_messages = new Object();
  863. function __(msg) {
  864. if (T_messages[msg]) {
  865. return T_messages[msg];
  866. } else {
  867. return msg;
  868. }
  869. }
  870. function ngettext(msg1, msg2, n) {
  871. return (parseInt(n) > 1) ? msg2 : msg1;
  872. }';
  873. if (ENABLE_TRANSLATIONS == true) { // If translations are enabled.
  874. $l10n = _get_reader();
  875. for ($i = 0; $i < $l10n->total; $i++) {
  876. $orig = $l10n->get_original_string($i);
  877. $translation = __($orig);
  878. print T_js_decl($orig, $translation);
  879. }
  880. }
  881. }
  882. function strip_prefix($nick) {
  883. return preg_replace("/^[\+\@]/", "", $nick);
  884. }
  885. function nicklist_sort_callback($o1, $o2) {
  886. $c1 = $o1[0];
  887. $c2 = $o2[0];
  888. if ($c1 == '@' && $c2 != '@') {
  889. return -1;
  890. }
  891. if ($c1 != '@' && $c2 == '@') {
  892. return 1;
  893. }
  894. if ($c1 == '+' && $c2 != '+') {
  895. return -1;
  896. }
  897. if ($c1 != '+' && $c2 == '+') {
  898. return 1;
  899. }
  900. return strip_prefix($o1) < strip_prefix($o2) ? -1 : 1;
  901. }
  902. function sort_nicklist($nicklist) {
  903. if (is_array($nicklist)) usort($nicklist, "nicklist_sort_callback");
  904. return $nicklist;
  905. }
  906. ?>