Add LAST NEXT and article pointer support to server (rslight-lib.php)

This commit is contained in:
Retro_Guy 2020-12-25 21:39:50 -07:00
parent 4ef7a51070
commit bc9d355916
1 changed files with 170 additions and 127 deletions

View File

@ -1,7 +1,7 @@
<?php <?php
function interact($msgsock, $use_crypto=false) function interact($msgsock, $use_crypto=false)
{ {
global $logdir,$logfile,$installed_path,$config_path,$groupconfig,$workpath,$path, $spooldir,$nntp_group,$auth_ok,$user,$pass; global $logdir,$logfile,$installed_path,$config_path,$groupconfig,$workpath,$path, $spooldir,$nntp_group,$nntp_article,$auth_ok,$user,$pass;
$workpath=$spooldir."/"; $workpath=$spooldir."/";
$path=$workpath."articles/"; $path=$workpath."articles/";
@ -9,6 +9,7 @@
$logfile=$logdir.'/nntp.log'; $logfile=$logdir.'/nntp.log';
$nntp_group=""; $nntp_group="";
$nntp_article="";
/* CRYPTO */ /* CRYPTO */
stream_set_blocking($msgsock, true); stream_set_blocking($msgsock, true);
if($use_crypto) { if($use_crypto) {
@ -81,6 +82,16 @@ set_time_limit(0);
fwrite($msgsock, $msg, strlen($msg)); fwrite($msgsock, $msg, strlen($msg));
continue; continue;
} }
if ($command[0] == 'next') {
$msg = get_next($nntp_group);
fwrite($msgsock, $msg, strlen($msg));
continue;
}
if ($command[0] == 'last') {
$msg = get_last($nntp_group);
fwrite($msgsock, $msg, strlen($msg));
continue;
}
if ($command[0] == 'authinfo') { if ($command[0] == 'authinfo') {
if(!isset($command[2])) { if(!isset($command[2])) {
$command[2] = fgets($msgsock, 2048); $command[2] = fgets($msgsock, 2048);
@ -148,8 +159,8 @@ set_time_limit(0);
continue; continue;
} }
if ($command[0] == 'group') { if ($command[0] == 'group') {
$nntp_group=$command[1]; $change_group=$command[1];
$msg = get_group($nntp_group); $msg = get_group($change_group);
fwrite($msgsock, $msg, strlen($msg)); fwrite($msgsock, $msg, strlen($msg));
continue; continue;
} }
@ -359,29 +370,84 @@ function process_post($filename) {
return $response; return $response;
} }
function get_next($nntp_group) {
global $spooldir,$nntp_article;
if($nntp_group == "") {
$response = "412 Not in a newsgroup\r\n";
return $response;
}
$ok_article = get_article_list($nntp_group);
sort($ok_article);
$last = $ok_article[key(array_slice($ok_article, -1, 1, true))];
if(($nntp_article + 1) > $last) {
$response = "421 No next article to retrieve\r\n";
} else {
$nntp_article++;
$database = $spooldir.'/articles-overview.db3';
$table = 'overview';
$dbh = rslight_db_open($database, $table);
$stmt = $dbh->prepare("SELECT * FROM $table WHERE newsgroup=:newsgroup AND number=:number");
$stmt->bindParam(':newsgroup', $nntp_group);
$stmt->bindParam(':number', $nntp_article);
$stmt->execute();
while($found = $stmt->fetch()) {
$msgid = $found['msgid'];
break;
}
$dbh = null;
$response = "223 ".$nntp_article." ".$msgid." Article retrieved; request text separately\r\n";
}
return $response;
}
function get_last($nntp_group) {
global $spooldir,$nntp_article;
if($nntp_group == "") {
$response = "412 Not in a newsgroup\r\n";
return $response;
}
$ok_article = get_article_list($nntp_group);
rsort($ok_article);
$first = $ok_article[key(array_slice($ok_article, -1, 1, true))];
if(($nntp_article - 1) < $first || !isset($nntp_article)) {
$response = "422 No previous article to retrieve\r\n";
} else {
$nntp_article--;
$database = $spooldir.'/articles-overview.db3';
$table = 'overview';
$dbh = rslight_db_open($database, $table);
$stmt = $dbh->prepare("SELECT * FROM $table WHERE newsgroup=:newsgroup AND number=:number");
$stmt->bindParam(':newsgroup', $nntp_group);
$stmt->bindParam(':number', $nntp_article);
$stmt->execute();
while($found = $stmt->fetch()) {
$msgid = $found['msgid'];
break;
}
$dbh = null;
$response = "223 ".$nntp_article." ".$msgid." Article retrieved; request text separately\r\n";
}
return $response;
}
function get_xhdr($header, $articles) { function get_xhdr($header, $articles) {
global $config_dir,$spooldir,$nntp_group,$workpath,$path; global $config_dir,$spooldir,$nntp_group,$workpath,$path;
// By Message-ID // By Message-ID
$tmpgroup=$nntp_group; $tmpgroup=$nntp_group;
$mid=false; $mid=false;
if(!is_numeric($articles)) { if(!is_numeric($articles)) {
$menulist = file($config_dir."menu.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $database = $spooldir.'/articles-overview.db3';
foreach($menulist as $menu) { $table = 'overview';
if(($menu[0] == '#') || (trim($menu) == "")) { $dbh = rslight_db_open($database, $table);
continue; $stmt = $dbh->prepare("SELECT * FROM $table WHERE msgid like :terms");
} $stmt->bindParam(':terms', $article);
$name=explode(":", $menu); $stmt->execute();
$overviewdata = file($spooldir."/".$name[0]."-overview", FILE_IGNORE_NEW_LINES); while($found = $stmt->fetch()) {
foreach($overviewdata as $overviewline) { $nntp_group = $found['newsgroup'];
$articledata = preg_split("/(:#rsl#:|\t)/", $overviewline); $article = $found['number'];
if(!strcasecmp($articledata[2], $articles)) { break;
$tmpgroup=$articledata[0];
$mid=$articles;
$articles=$articledata[1];
break;
}
}
} }
$dbh = null;
} else { } else {
if($nntp_group == '') { if($nntp_group == '') {
$msg="412 no newsgroup selected\r\n"; $msg="412 no newsgroup selected\r\n";
@ -395,14 +461,8 @@ function get_xhdr($header, $articles) {
$last = $article_num[1]; $last = $article_num[1];
} else { } else {
if(strpos($articles, "-")) { if(strpos($articles, "-")) {
$articles = scandir($thisgroup); $ok_article = get_article_list($nntp_group);
$ok_article=array(); fclose($group_overviewfp);
foreach($articles as $article) {
if(!is_numeric($article)) {
continue;
}
$ok_article[]=$article;
}
sort($ok_article); sort($ok_article);
$last = $ok_article[key(array_slice($ok_article, -1, 1, true))]; $last = $ok_article[key(array_slice($ok_article, -1, 1, true))];
if(!is_numeric($last)) if(!is_numeric($last))
@ -465,11 +525,19 @@ function get_title($mode) {
} }
function get_xover($articles, $msgsock) { function get_xover($articles, $msgsock) {
global $nntp_group,$workpath,$path; global $nntp_group,$nntp_article,$workpath,$path;
if($nntp_group == '') { if($nntp_group == '') {
$msg="412 no newsgroup selected\r\n"; $msg="412 no newsgroup selected\r\n";
return $msg; return $msg;
} }
// Use article pointer
if(!isset($articles) && is_numeric($nntp_article)) {
$articles = $nntp_article;
}
if(!isset($articles)) {
$msg="420 no article(s) selected\r\n";
return $msg;
}
$overviewfile=$workpath.$nntp_group."-overview"; $overviewfile=$workpath.$nntp_group."-overview";
$article_num = explode('-', $articles); $article_num = explode('-', $articles);
$first = $article_num[0]; $first = $article_num[0];
@ -477,21 +545,13 @@ function get_xover($articles, $msgsock) {
$last = $article_num[1]; $last = $article_num[1];
else { else {
if(strpos($articles, "-")) { if(strpos($articles, "-")) {
$thisgroup = $path."/".preg_replace('/\./', '/', $nntp_group); $ok_article = get_article_list($nntp_group);
$articles = scandir($thisgroup); sort($ok_article);
$ok_article=array(); $last = $ok_article[key(array_slice($ok_article, -1, 1, true))];
foreach($articles as $article) { if(!is_numeric($last))
if(!is_numeric($article)) { $last = 0;
continue;
}
$ok_article[]=$article;
}
sort($ok_article);
$last = $ok_article[key(array_slice($ok_article, -1, 1, true))];
if(!is_numeric($last))
$last = 0;
} else { } else {
$last = $first; $last = $first;
} }
} }
$output="224 Overview information follows for articles ".$first." through ".$last."\r\n"; $output="224 Overview information follows for articles ".$first." through ".$last."\r\n";
@ -511,11 +571,15 @@ function get_xover($articles, $msgsock) {
} }
function get_stat($article) { function get_stat($article) {
global $nntp_group,$workpath,$path; global $nntp_group,$nntp_article,$workpath,$path;
if($nntp_group == '') { if($nntp_group == '') {
$msg="412 Not in a newsgroup\r\n"; $msg="412 Not in a newsgroup\r\n";
return $msg; return $msg;
} }
// Use article pointer
if(!isset($article) && is_numeric($nntp_article)) {
$article = $nntp_article;
}
if(!is_numeric($article)) { if(!is_numeric($article)) {
$msg="423 No article number selected\r\n"; $msg="423 No article number selected\r\n";
return $msg; return $msg;
@ -541,27 +605,26 @@ function get_stat($article) {
} }
function get_article($article, $nntp_group) { function get_article($article, $nntp_group) {
global $config_dir,$path,$groupconfig,$config_name,$spooldir; global $config_dir,$path,$groupconfig,$config_name,$spooldir,$nntp_article;
$msg2=""; $msg2="";
// By Message-ID // By Message-ID
// Use article pointer
if(!isset($article) && is_numeric($nntp_article)) {
$article = $nntp_article;
}
if(!is_numeric($article)) { if(!is_numeric($article)) {
$menulist = file($config_dir."menu.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $database = $spooldir.'/articles-overview.db3';
foreach($menulist as $menu) { $table = 'overview';
if(($menu[0] == '#') || (trim($menu) == "")) { $dbh = rslight_db_open($database, $table);
continue; $stmt = $dbh->prepare("SELECT * FROM $table WHERE msgid like :terms");
} $stmt->bindParam(':terms', $article);
$name=explode(":", $menu); $stmt->execute();
$overviewdata = file($spooldir."/".$name[0]."-overview", FILE_IGNORE_NEW_LINES); while($found = $stmt->fetch()) {
foreach($overviewdata as $overviewline) { $nntp_group = $found['newsgroup'];
// Remove :#rsl#: in 0.6.6 and only use tab $article = $found['number'];
$articledata = preg_split("/(:#rsl#:|\t)/", $overviewline); break;
if(!strcasecmp($articledata[2], $article)) {
$nntp_group=$articledata[0];
$article=$articledata[1];
break;
}
}
} }
$dbh = null;
} else { } else {
// By article number // By article number
if($nntp_group === "") { if($nntp_group === "") {
@ -586,31 +649,31 @@ function get_article($article, $nntp_group) {
$msg2.=$thisline."\r\n"; $msg2.=$thisline."\r\n";
} }
$msg="220 ".$article." ".$mid[1]." article retrieved - head and body follow\r\n"; $msg="220 ".$article." ".$mid[1]." article retrieved - head and body follow\r\n";
$nntp_article = $article;
return $msg.$msg2; return $msg.$msg2;
} }
function get_header($article, $nntp_group) { function get_header($article, $nntp_group) {
global $config_dir,$path,$groupconfig,$config_name,$spooldir; global $nntp_article,$config_dir,$path,$groupconfig,$config_name,$spooldir;
$msg2=""; $msg2="";
// Use article pointer
if(!isset($article) && is_numeric($nntp_article)) {
$article = $nntp_article;
}
// By Message-ID // By Message-ID
if(!is_numeric($article)) { if(!is_numeric($article)) {
$menulist = file($config_dir."menu.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $database = $spooldir.'/articles-overview.db3';
foreach($menulist as $menu) { $table = 'overview';
if(($menu[0] == '#') || (trim($menu) == "")) { $dbh = rslight_db_open($database, $table);
continue; $stmt = $dbh->prepare("SELECT * FROM $table WHERE msgid like :terms");
} $stmt->bindParam(':terms', $article);
$name=explode(":", $menu); $stmt->execute();
$overviewdata = file($spooldir."/".$name[0]."-overview", FILE_IGNORE_NEW_LINES); while($found = $stmt->fetch()) {
foreach($overviewdata as $overviewline) { $nntp_group = $found['newsgroup'];
// Remove :#rsl#: in 0.6.6 and only use tab $article = $found['number'];
$articledata = preg_split("/(:#rsl#:|\t)/", $overviewline); break;
if(!strcasecmp($articledata[2], $article)) {
$nntp_group=$articledata[0];
$article=$articledata[1];
break;
}
}
} }
$dbh = null;
} else { } else {
// By article number // By article number
if($nntp_group === "") { if($nntp_group === "") {
@ -712,16 +775,9 @@ function get_listgroup($nntp_group, $msgsock) {
break; break;
} }
} }
$group_overviewfp=fopen($spooldir."/".$nntp_group."-overview", 'r'); $ok_article = get_article_list($nntp_group);
$ok_article=array();
while($line = fgets($group_overviewfp)) {
$art=explode("\t", $line);
if(is_numeric($art[0])) {
$ok_article[] = $art[0];
$count++;
}
}
fclose($group_overviewfp); fclose($group_overviewfp);
$count = count($ok_article);
sort($ok_article); sort($ok_article);
$last = $ok_article[key(array_slice($ok_article, -1, 1, true))]; $last = $ok_article[key(array_slice($ok_article, -1, 1, true))];
$first = $ok_article[0]; $first = $ok_article[0];
@ -739,30 +795,27 @@ function get_listgroup($nntp_group, $msgsock) {
return $msg; return $msg;
} }
function get_group($nntp_group) { function get_group($change_group) {
global $spooldir,$path,$nntp_group,$groupconfig; global $spooldir,$path,$nntp_group,$nntp_article,$groupconfig;
$grouplist = file($groupconfig, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); $grouplist = file($groupconfig, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$ok_group=false; $ok_group=false;
$count=0; $count=0;
foreach($grouplist as $findgroup) { foreach($grouplist as $findgroup) {
$name = preg_split("/( |\t)/", $findgroup, 2); $name = preg_split("/( |\t)/", $findgroup, 2);
$name[0]=strtolower($name[0]); $name[0]=strtolower($name[0]);
$nntp_group=strtolower($nntp_group); $change_group=strtolower($change_group);
if(!strcmp($name[0], $nntp_group)) { if(!strcmp($name[0], $change_group)) {
$ok_group=true; $ok_group=true;
break; break;
} }
} }
$group_overviewfp=fopen($spooldir."/".$nntp_group."-overview", 'r'); if($ok_group == false) {
$ok_article=array(); $response = "411 No such group ".$change_group.";\r\n";
while($line = fgets($group_overviewfp)) { return $response;
$art=explode("\t", $line);
if(is_numeric($art[0])) {
$ok_article[] = $art[0];
$count++;
}
} }
fclose($group_overviewfp); $nntp_group = $change_group;
$ok_article = get_article_list($nntp_group);
$count = count($ok_article);
sort($ok_article); sort($ok_article);
$last = $ok_article[key(array_slice($ok_article, -1, 1, true))]; $last = $ok_article[key(array_slice($ok_article, -1, 1, true))];
$first = $ok_article[0]; $first = $ok_article[0];
@ -770,7 +823,7 @@ function get_group($nntp_group) {
$last = 0; $last = 0;
if(!is_numeric($first)) if(!is_numeric($first))
$first = 0; $first = 0;
// $count = ($last - $first) + 1; $nntp_article = $first;
$msg="211 ".$count." ".$first." ".$last." ".$nntp_group."\r\n"; $msg="211 ".$count." ".$first." ".$last." ".$nntp_group."\r\n";
return $msg; return $msg;
} }
@ -786,15 +839,7 @@ function get_newgroups($mode) {
$name = preg_split("/( |\t)/", $findgroup, 2); $name = preg_split("/( |\t)/", $findgroup, 2);
if($name[0][0] === ':') if($name[0][0] === ':')
continue; continue;
$thisgroup = $path."/".preg_replace('/\./', '/', $name[0]); $ok_article = get_article_list($nntp_group);
$articles = scandir($thisgroup);
$ok_article=array();
foreach($articles as $article) {
if(!is_numeric($article)) {
continue;
}
$ok_article[]=$article;
}
sort($ok_article); sort($ok_article);
$last = $ok_article[key(array_slice($ok_article, -1, 1, true))]; $last = $ok_article[key(array_slice($ok_article, -1, 1, true))];
$first = $ok_article[0]; $first = $ok_article[0];
@ -842,15 +887,7 @@ function get_list($mode) {
$name = preg_split("/( |\t)/", $findgroup, 2); $name = preg_split("/( |\t)/", $findgroup, 2);
if($name[0][0] === ':') if($name[0][0] === ':')
continue; continue;
$thisgroup = $path."/".preg_replace('/\./', '/', $name[0]); $ok_article = get_article_list($nntp_group);
$articles = scandir($thisgroup);
$ok_article=array();
foreach($articles as $article) {
if(!is_numeric($article)) {
continue;
}
$ok_article[]=$article;
}
sort($ok_article); sort($ok_article);
$last = $ok_article[key(array_slice($ok_article, -1, 1, true))]; $last = $ok_article[key(array_slice($ok_article, -1, 1, true))];
$first = $ok_article[0]; $first = $ok_article[0];
@ -930,15 +967,7 @@ $date_i,$mid_i,$references_i,$bytes_i,$lines_i,$xref_i) {
if (is_numeric($name[1])) if (is_numeric($name[1]))
$local = $name[1]; $local = $name[1];
else { else {
$thisgroup = $grouppath; $ok_article = get_article_list($nntp_group);
$articles = scandir($thisgroup);
$ok_article=array();
foreach($articles as $this_article) {
if(!is_numeric($this_article)) {
continue;
}
$ok_article[]=$this_article;
}
sort($ok_article); sort($ok_article);
$local = $ok_article[key(array_slice($ok_article, -1, 1, true))]; $local = $ok_article[key(array_slice($ok_article, -1, 1, true))];
if(!is_numeric($local)) if(!is_numeric($local))
@ -1044,4 +1073,18 @@ function nntp2_open($nserver=0,$nport=0) {
} }
return $ns; return $ns;
} }
function get_article_list($thisgroup) {
global $spooldir;
$group_overviewfp=fopen($spooldir."/".$thisgroup."-overview", 'r');
$ok_article=array();
while($line = fgets($group_overviewfp)) {
$art=explode("\t", $line);
if(is_numeric($art[0])) {
$ok_article[] = $art[0];
}
}
fclose($group_overviewfp);
return($ok_article);
}
?> ?>