The version of vichan running on lainchan.org
No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

153 líneas
4.0KB

  1. <?php
  2. /*
  3. * Copyright (c) 2016 vichan-devel
  4. */
  5. defined('TINYBOARD') or exit;
  6. function gen_msgid($board, $id) {
  7. global $config;
  8. $b = preg_replace("/[^0-9a-zA-Z$]/", 'x', $board);
  9. $salt = sha1($board . "|" . $id . "|" . $config['nntpchan']['salt']);
  10. $salt = substr($salt, 0, 7);
  11. $salt = base_convert($salt, 16, 36);
  12. return "<$b.$id.$salt@".$config['nntpchan']['domain'].">";
  13. }
  14. function gen_nntp($headers, $files) {
  15. if (count($files) == 0) {
  16. }
  17. else if (count($files) == 1 && $files[0]['type'] == 'text/plain') {
  18. $content = $files[0]['text'] . "\r\n";
  19. $headers['Content-Type'] = "text/plain; charset=UTF-8";
  20. }
  21. else {
  22. $boundary = sha1($headers['Message-Id']);
  23. $content = "";
  24. $headers['Content-Type'] = "multipart/mixed; boundary=$boundary";
  25. foreach ($files as $file) {
  26. $content .= "--$boundary\r\n";
  27. if (isset($file['name'])) {
  28. $file['name'] = preg_replace('/[\r\n\0"]/', '', $file['name']);
  29. $content .= "Content-Disposition: form-data; filename=\"$file[name]\"; name=\"attachment\"\r\n";
  30. }
  31. $type = explode('/', $file['type'])[0];
  32. if ($type == 'text') {
  33. $file['type'] .= '; charset=UTF-8';
  34. }
  35. $content .= "Content-Type: $file[type]\r\n";
  36. if ($type != 'text' && $type != 'message') {
  37. $file['text'] = base64_encode($file['text']);
  38. $content .= "Content-Transfer-Encoding: base64\r\n";
  39. }
  40. $content .= "\r\n";
  41. $content .= $file['text'];
  42. $content .= "\r\n";
  43. }
  44. $content .= "--$boundary--\r\n";
  45. $headers['Mime-Version'] = '1.0';
  46. }
  47. //$headers['Content-Length'] = strlen($content);
  48. $headers['Date'] = date('r', $headers['Date']);
  49. $out = "";
  50. foreach ($headers as $id => $val) {
  51. $val = str_replace("\n", "\n\t", $val);
  52. $out .= "$id: $val\r\n";
  53. }
  54. $out .= "\r\n";
  55. $out .= $content;
  56. return $out;
  57. }
  58. function nntp_publish($msg, $id) {
  59. global $config;
  60. $server = $config["nntpchan"]["server"];
  61. $s = fsockopen("tcp://$server");
  62. fgets($s);
  63. fputs($s, "MODE STREAM\r\n");
  64. fgets($s);
  65. fputs($s, "TAKETHIS $id\r\n");
  66. fputs($s, $msg);
  67. fputs($s, "\r\n.\r\n");
  68. fgets($s);
  69. fputs($s, "QUIT\r\n");
  70. fclose($s);
  71. }
  72. function post2nntp($post, $msgid) {
  73. global $config;
  74. $headers = array();
  75. $files = array();
  76. $headers['Message-Id'] = $msgid;
  77. $headers['Newsgroups'] = $config['nntpchan']['group'];
  78. $headers['Date'] = time();
  79. $headers['Subject'] = $post['subject'] ? $post['subject'] : "None";
  80. $headers['From'] = $post['name'] . " <poster@" . $config['nntpchan']['domain'] . ">";
  81. if ($post['email'] == 'sage') {
  82. $headers['X-Sage'] = true;
  83. }
  84. if (!$post['op']) {
  85. // Get muh parent
  86. $query = prepare("SELECT `message_id` FROM ``nntp_references`` WHERE `board` = :board AND `id` = :id");
  87. $query->bindValue(':board', $post['board']);
  88. $query->bindValue(':id', $post['thread']);
  89. $query->execute() or error(db_error($query));
  90. if ($result = $query->fetch(PDO::FETCH_ASSOC)) {
  91. $headers['References'] = $result['message_id'];
  92. }
  93. else {
  94. return false; // We don't have OP. Discarding.
  95. }
  96. }
  97. // Let's parse the body a bit.
  98. $body = trim($post['body_nomarkup']);
  99. $body = preg_replace('/\r?\n/', "\r\n", $body);
  100. $body = preg_replace_callback('@>>(>/([a-zA-Z0-9_+-]+)/)?([0-9]+)@', function($o) use ($post) {
  101. if ($o[1]) {
  102. $board = $o[2];
  103. }
  104. else {
  105. $board = $post['board'];
  106. }
  107. $id = $o[3];
  108. $query = prepare("SELECT `message_id_digest` FROM ``nntp_references`` WHERE `board` = :board AND `id` = :id");
  109. $query->bindValue(':board', $board);
  110. $query->bindValue(':id', $id);
  111. $query->execute() or error(db_error($query));
  112. if ($result = $query->fetch(PDO::FETCH_ASSOC)) {
  113. return ">>".substr($result['message_id_digest'], 0, 18);
  114. }
  115. else {
  116. return $o[0]; // Should send URL imo
  117. }
  118. }, $body);
  119. $body = preg_replace('/>>>>([0-9a-fA-F])+/', '>>\1', $body);
  120. $files[] = array('type' => 'text/plain', 'text' => $body);
  121. foreach ($post['files'] as $id => $file) {
  122. $fc = array();
  123. $fc['type'] = $file['type'];
  124. $fc['text'] = file_get_contents($file['file_path']);
  125. $fc['name'] = $file['name'];
  126. $files[] = $fc;
  127. }
  128. return array($headers, $files);
  129. }