2023-09-03 16:32:21 +02:00
< ? php
/*
* This script allows importing a group . db3 file from a backup
* or another rslight site , and other features .
*
* Use - help to see other features .
*
* To import a group db3 file :
* Place the article database file group . name - articles . db3 in
* your spool directory , and change user / group to your web user .
2024-07-02 08:50:31 +02:00
* Run this script as your web user :
2023-09-22 12:48:43 +02:00
* php $config_dir / scripts / maintenance - import group . name
2023-09-03 16:32:21 +02:00
*
* This will create the overview files necessary to import the group
* into your site .
* Next : Add the group to the groups . txt file of the section you wish
* it to appear :
* $config_dir /< section >/ groups . txt
*/
2024-10-03 14:13:03 +02:00
include ( " paths.inc.php " );
2024-07-01 11:12:12 +02:00
chdir ( $spoolnews_path );
2023-09-03 16:32:21 +02:00
include " config.inc.php " ;
2024-10-03 14:13:03 +02:00
include ( " $file_newsportal " );
2024-11-15 16:13:10 +01:00
include " spool-lib.php " ;
2023-09-03 16:32:21 +02:00
2024-11-15 00:38:09 +01:00
if ( ! isset ( $argv [ 1 ])) {
$argv [ 1 ] = " -help " ;
}
2024-10-03 14:13:03 +02:00
if ( $argv [ 1 ] != '-newsection' ) {
2024-11-29 19:14:11 +01:00
$processUser = posix_getpwuid ( posix_geteuid ());
echo " You are running as user: " . $processUser [ 'name' ] . " \n " ;
2024-10-03 14:13:03 +02:00
// Change to webserver user if root
$uinfo = posix_getpwnam ( $CONFIG [ 'webserver_user' ]);
/* Change to non root user */
change_identity ( $uinfo [ " uid " ], $uinfo [ " gid " ]);
$processUser = posix_getpwuid ( posix_geteuid ());
2024-12-12 13:53:25 +01:00
2024-10-03 14:13:03 +02:00
if ( $processUser [ 'name' ] != $CONFIG [ 'webserver_user' ]) {
2024-11-29 19:14:11 +01:00
echo " You are running as user: " . $processUser [ 'name' ] . " \n " ;
echo 'Please run this script as: ' . $CONFIG [ 'webserver_user' ] . " \n " ;
2024-10-03 14:13:03 +02:00
exit ();
}
/* Everything below runs as $CONFIG['webserver_user'] */
2024-11-15 16:13:10 +01:00
echo " You are running as user: " . $processUser [ 'name' ] . " \n " ;
2024-07-26 17:31:40 +02:00
2024-10-03 14:13:03 +02:00
$processUser = posix_getpwuid ( posix_geteuid ());
if ( $processUser [ 'name' ] != $CONFIG [ 'webserver_user' ]) {
2024-11-29 19:14:11 +01:00
echo " You are running as user: " . $processUser [ 'name' ] . " \n " ;
echo 'Please run this script as: ' . $CONFIG [ 'webserver_user' ] . " \n " ;
2024-10-03 14:13:03 +02:00
exit ();
}
2024-07-01 11:12:12 +02:00
2024-12-12 15:51:28 +01:00
if ( isset ( $argv [ 2 ])) {
2024-12-12 13:53:25 +01:00
$config_name = get_section_by_group ( $argv [ 2 ]);
} else {
$config_name = null ;
}
2024-11-30 08:16:10 +01:00
$logfile = $logdir . '/spoolnews.log' ;
2024-10-03 14:13:03 +02:00
$lockfile = $lockdir . '/' . $config_name . '-spoolnews.lock' ;
2023-09-17 14:56:24 +02:00
2024-10-03 14:13:03 +02:00
$pid = file_get_contents ( $lockfile );
if ( posix_getsid ( $pid ) === false || ! is_file ( $lockfile )) {
2024-12-12 15:51:28 +01:00
print " Starting... \n " ;
2024-10-03 14:13:03 +02:00
file_put_contents ( $lockfile , getmypid ()); // create lockfile
} else {
2024-11-29 19:14:11 +01:00
print " Spoolnews currently running \n " ;
2024-10-03 14:13:03 +02:00
exit ();
}
2024-11-29 19:14:11 +01:00
} else {
$processUser = posix_getpwuid ( posix_geteuid ());
echo " You are running as user: " . $processUser [ 'name' ] . " \n " ;
2023-09-03 16:32:21 +02:00
}
if ( $argv [ 1 ][ 0 ] == '-' ) {
switch ( $argv [ 1 ]) {
case " -version " :
echo 'Version ' . $rslight_version . " \n " ;
break ;
2024-11-15 16:13:10 +01:00
case " -clear-diskcache " :
clear_disk_cache ();
break ;
case " -refill " :
if ( ! isset ( $argv [ 2 ]) || ! isset ( $argv [ 3 ])) {
echo " Please provide a group name followed by number of articles to poll \n " ;
exit ;
}
echo " Refilling: " . $argv [ 2 ] . " going back " . $argv [ 3 ] . " articles \n " ;
refill_group ( $argv [ 2 ], $argv [ 3 ]);
break ;
2023-09-03 16:32:21 +02:00
case " -remove " :
echo " Removing: " . $argv [ 2 ] . " \n " ;
remove_articles ( $argv [ 2 ]);
reset_group ( $argv [ 2 ], 1 );
break ;
case " -reset " :
echo " Reset: " . $argv [ 2 ] . " \n " ;
remove_articles ( $argv [ 2 ]);
reset_group ( $argv [ 2 ], 0 );
break ;
2024-11-15 00:38:09 +01:00
case " -reset-section " :
if ( ! isset ( $argv [ 2 ])) {
echo " Please provide a section name \n " ;
exit ;
}
echo " Reset Section: " . $argv [ 2 ] . " \n " ;
reset_section ( $argv [ 2 ]);
break ;
2023-09-03 16:32:21 +02:00
case " -import " :
if ( isset ( $argv [ 2 ])) {
import ( $argv [ 2 ]);
} else {
import ();
}
break ;
2024-10-03 14:13:03 +02:00
case " -newsection " :
if ( ! isset ( $argv [ 2 ])) {
echo " Please provide a section name \n " ;
exit ;
}
echo " Creating section: " . $argv [ 2 ] . " \n " ;
echo create_section ( $argv [ 2 ]);
break ;
2024-12-12 13:53:25 +01:00
case " -import-mbox-to-articles " :
if ( ! isset ( $argv [ 2 ]) || ! isset ( $argv [ 3 ])) {
echo " Please provide a group name followed by full path to mbox file \n " ;
exit ;
}
2024-12-12 15:51:28 +01:00
if ( ! isset ( $config_name )) {
2024-12-12 13:53:25 +01:00
echo " Please add " . $argv [ 2 ] . " to groups.txt for a section \n " ;
exit ;
}
mbox_import_articles ( $argv [ 2 ], $argv [ 3 ]);
break ;
2023-09-03 16:32:21 +02:00
case " -clean " :
clean_spool ();
break ;
default :
echo " -help: This help page \n " ;
echo " -version: Display version \n " ;
2024-06-11 12:22:21 +02:00
echo " ******************* IMPORTANT ************************** \n " ;
echo " *** PLEASE DISABLE cron.php WHEN RUNNING THIS SCRIPT *** \n " ;
echo " ******************************************************** \n " ;
2023-09-03 16:32:21 +02:00
echo " -clean: Remove extraneous group db3 files \n " ;
2024-11-15 16:13:10 +01:00
echo " -clear-diskcache: Remove all cache files if using Disk Caching \n " ;
2023-09-03 16:32:21 +02:00
echo " -import: Import articles from a .db3 file (-import alt.test-articles) \n " ;
echo " You must first add group name to <config_dir>/<section>/groups.txt manually \n " ;
2024-12-12 13:53:25 +01:00
echo " -import-mbox-to-articles: Import articles from a mbox file \n " ;
echo " -import-mbox-to-articles alt.test /path/to/file/alt.test.mbox \n " ;
echo " You must first add group name to <config_dir>/<section>/groups.txt manually \n " ;
2024-10-03 14:13:03 +02:00
echo " -newsection: Create a new section for groups \n " ;
2024-11-15 16:13:10 +01:00
echo " -refill: Go back x articles and retrieve missing from remote server \n " ;
echo " -refill alt.test 3000 will retrive missing articles for alt.test \n " ;
echo " starting 3000 articles earlier than latest remote article number \n " ;
2023-09-03 16:32:21 +02:00
echo " -remove: Remove all data for a group (-remove alt.test) \n " ;
echo " You must also remove group name from <config_dir>/<section>/groups.txt manually \n " ;
echo " -reset: Reset a group to restart from zero messages (-reset alt.test) \n " ;
2024-11-15 00:38:09 +01:00
echo " -reset-section: Reset ALL GROUPS in a Section to restart from zero messages \n " ;
echo " (-reset-section rocksolid) THIS CAN TAKE A LOT OF TIME TO RUN \n " ;
2023-09-03 16:32:21 +02:00
break ;
}
exit ();
} else {
exit ();
}
2024-11-15 16:13:10 +01:00
function clear_disk_cache ()
{
global $config_dir ;
if ( file_exists ( $config_dir . '/cache.inc.php' )) {
include $config_dir . '/cache.inc.php' ;
} else {
echo " Disk Cache not configured in " . $config_dir . '/cache.inc.php' . " \n " ;
exit ;
}
if ( $enable_cache != 'diskcache' || ! isset ( $cache_dir )) {
echo " Disk Cache not configured in " . $config_dir . '/cache.inc.php' . " \n " ;
exit ;
}
echo " Clearing Disk Cache in " . $cache_dir . " \n " ;
foreach ( glob ( $cache_dir . " /* " ) as $filename ) {
if ( is_file ( $filename )) {
echo " Deleting " . $filename . " \n " ;
unlink ( $filename );
} else {
echo " NOT Deleting: " . $filename . " \n " ;
}
}
}
2024-10-03 14:13:03 +02:00
function create_section ( $section = false )
{
global $spooldir , $config_dir , $spoolnews_path , $CONFIG ;
$menufile = $config_dir . '/menu.conf' ;
if ( ! isset ( $section )) {
return " Please include a section name \n " ;
}
$uinfo = posix_getpwnam ( $CONFIG [ 'webserver_user' ]);
$spoolsection = $spooldir . '/' . $section ;
$configsection = $config_dir . '/' . $section ;
$websectionarray = explode ( '/' , $spoolnews_path );
$websectionpath = substr ( $spoolnews_path , 0 , strlen ( $spoolnews_path ) - 9 );
$websection = $websectionpath . $section ;
$websection = $websectionpath . '/' . $section ;
if ( ! file_exists ( $websection . '/newsportal.php' )) {
echo " Creating symlinks " . $websection . " \n " ;
mkdir ( $websection );
exec ( " ln -s " . $websectionpath . '/rocksolid/*' . ' ' . $websection );
}
if ( ! file_exists ( $configsection . '/groups.txt' )) {
mkdir ( $configsection );
echo 'Creating ' . $configsection . '/groups.txt' . " \n " ;
touch ( $configsection . '/groups.txt' );
}
$menuexists = false ;
$menudata = file ( $config_dir . '/menu.conf' );
2024-10-14 11:40:42 +02:00
$newmenu = array ();
2024-10-03 14:13:03 +02:00
foreach ( $menudata as $menuentry ) {
2024-11-15 16:13:10 +01:00
if ( trim ( $menuentry ) == '' ) {
2024-10-14 11:40:42 +02:00
continue ;
}
2024-10-03 14:13:03 +02:00
if ( strpos ( $menuentry , $section ) !== false ) {
2024-10-14 11:40:42 +02:00
echo " Menu entry already exists for: " . $section . " \n " ;
2024-10-03 14:13:03 +02:00
$menuexists = true ;
break ;
}
2024-10-14 11:40:42 +02:00
$newmenu [] = $menuentry ;
2024-10-03 14:13:03 +02:00
}
if ( ! $menuexists ) {
2024-10-14 11:40:42 +02:00
echo " Adding menu entry to " . $config_dir . " menu.conf \n " ;
2024-10-14 11:42:25 +02:00
$newmenu [] = $section . " :1:1 \n " ;
2024-10-14 11:40:42 +02:00
$newmenu = implode ( $newmenu );
file_put_contents ( $config_dir . 'menu.conf' , $newmenu );
2024-10-03 14:13:03 +02:00
}
echo 'Please now edit ' . $configsection . " /groups.txt to add groups to this section \n " ;
}
2023-09-03 16:32:21 +02:00
function clean_spool ()
{
global $logfile , $workpath , $spooldir ;
$workpath = $spooldir . " / " ;
$path = $workpath . " articles/ " ;
$group_list = get_group_list ();
$group = trim ( $group );
$group_files = scandir ( $workpath );
foreach ( $group_files as $this_file ) {
if ( strpos ( $this_file , '-articles.db3' ) === false ) {
continue ;
}
$group = preg_replace ( '/-articles.db3/' , '' , $this_file );
if ( in_array ( $group , $group_list )) {
continue ;
} else {
echo " Removing: " . $this_file . " \n " ;
remove_articles ( $group );
reset_group ( $group , 1 );
}
}
echo " \n Import Done \r \n " ;
}
function import ( $group = '' )
{
global $logfile , $workpath , $spooldir ;
$workpath = $spooldir . " / " ;
$path = $workpath . " articles/ " ;
$group_list = get_group_list ();
$group = trim ( $group );
if ( $group == '' ) {
$group_files = scandir ( $workpath );
foreach ( $group_files as $this_file ) {
if ( strpos ( $this_file , '-articles.db3' ) === false ) {
continue ;
}
$group = preg_replace ( '/-articles.db3/' , '' , $this_file );
if ( in_array ( $group , $group_list )) {
echo " Importing: " . $group . " \n " ;
import_articles ( $group );
} else {
echo " Removing: " . $group . " \n " ;
remove_articles ( $group );
reset_group ( $group , 1 );
}
}
} else {
echo " Importing: " . $group . " \n " ;
import_articles ( $group );
}
echo " \n Import Done \r \n " ;
}
function get_group_list ()
{
global $config_dir ;
$grouplist = array ();
$menulist = file ( $config_dir . " menu.conf " , FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
foreach ( $menulist as $menu ) {
if ( $menu [ 0 ] == '#' ) {
continue ;
}
$menuitem = explode ( ':' , $menu );
if ( $menuitem [ 2 ] == '0' ) {
continue ;
}
$glist = file ( $config_dir . $menuitem [ 0 ] . " /groups.txt " );
foreach ( $glist as $gl ) {
if ( $gl [ 0 ] == ':' ) {
continue ;
}
$group_name = preg_split ( " /( | \t )/ " , $gl , 2 );
$grouplist [] = trim ( $group_name [ 0 ]);
}
}
return $grouplist ;
}
2024-11-15 16:13:10 +01:00
function refill_group ( $group , $start )
{
2024-11-30 08:16:10 +01:00
global $spooldir , $config_dir , $logfile , $remote_groups_array_file , $workpath , $CONFIG , $config_name , $path ;
2024-11-15 16:13:10 +01:00
$workpath = $spooldir . " / " ;
$path = $workpath . " articles/ " ;
$config_name = get_section_by_group ( $group );
if ( file_exists ( $config_dir . $config_name . '.inc.php' )) {
$config_file = $config_dir . $config_name . '.inc.php' ;
} else {
$config_file = $config_dir . 'rslight.inc.php' ;
}
$CONFIG = include ( $config_file );
$remote_groups_array_file = $spooldir . " / " . $config_name . " / " . $CONFIG [ 'remote_server' ] . " : " . $CONFIG [ 'remote_port' ] . " -remote_groups.dat " ;
if ( file_exists ( $remote_groups_array_file )) {
$remote_groups_array = unserialize ( file_get_contents ( $remote_groups_array_file ));
} else {
$remote_groups_array = array ();
}
foreach ( $remote_groups_array as $key => $value ) {
if ( $key == $group ) {
$newarray [ $key ] = $remote_groups_array [ $key ] - $start ;
} else {
$newarray [ $key ] = $remote_groups_array [ $key ];
}
}
file_put_contents ( $remote_groups_array_file , serialize ( $newarray ));
$ns = nntp2_open ( $CONFIG [ 'remote_server' ], $CONFIG [ 'remote_port' ]);
if ( $ns == false ) {
file_put_contents ( $logfile , " \n " . format_log_date () . " " . $config_name . " Failed to connect to " . $CONFIG [ 'remote_server' ] . " : " . $CONFIG [ 'remote_port' ], FILE_APPEND );
exit ();
}
echo " Finding missing articles from Remote Server for: " . $group . " starting - " . $start . " articles \n " ;
get_articles ( $ns , $group , $start );
}
function reset_section ( $section = " " )
{
2024-11-15 00:38:09 +01:00
global $config_dir ;
$section = trim ( $section );
$gldata = file ( $config_dir . $section . " /groups.txt " );
2024-11-15 16:13:10 +01:00
foreach ( $gldata as $gl ) {
if (( $gl [ 0 ] == ':' ) || ( trim ( $gl ) == " " )) {
continue ;
2024-11-15 00:38:09 +01:00
}
2024-11-15 16:13:10 +01:00
$group_name = preg_split ( " /( | \t )/ " , $gl , 2 );
$group = trim ( $group_name [ 0 ]);
echo " START Reset " . $group . " \n " ;
remove_articles ( $group );
reset_group ( $group , 0 );
}
2024-11-15 00:38:09 +01:00
}
2023-09-03 16:32:21 +02:00
function reset_group ( $group , $remove = 0 )
{
global $config_dir , $spooldir ;
$group = trim ( $group );
if ( ! $section = get_section_by_group ( $group )) {
return false ;
}
$config_location = $spooldir . '/' . $section ;
$config_files = array_diff ( scandir ( $config_location ), array (
'..' ,
2024-06-11 12:22:21 +02:00
'.' ,
'outgoing'
2023-09-03 16:32:21 +02:00
));
foreach ( $config_files as $config_file ) {
2024-10-08 13:57:01 +02:00
if ( ! str_ends_with ( $config_file , '_groups.dat' )) {
continue ;
}
$groups_array = unserialize ( file_get_contents ( $config_location . '/' . $config_file ));
if ( isset ( $groups_array [ $group ])) {
echo " Current group pointer for " . $group . " : " . $groups_array [ $group ] . " \n " ;
$groups_array [ $group ] = '1' ;
echo " New group pointer for " . $group . " : " . $groups_array [ $group ] . " \n " ;
2023-09-03 16:32:21 +02:00
}
2024-10-08 13:57:01 +02:00
file_put_contents ( $config_location . '/' . $config_file , serialize ( $groups_array ));
2023-09-03 16:32:21 +02:00
}
}
function remove_articles ( $group )
{
global $spooldir , $CONFIG , $workpath , $path , $config_name , $logfile ;
$group = trim ( $group );
# Overview
2024-06-11 12:22:21 +02:00
$overview_dbh = overview_db_open ( $spooldir . '/articles-overview.db3' );
2023-09-03 16:32:21 +02:00
2024-06-11 12:22:21 +02:00
$fetch_stmt = $overview_dbh -> prepare ( " SELECT msgid FROM overview WHERE newsgroup=:group " );
$fetch_stmt -> bindParam ( ':group' , $group );
$fetch_stmt -> execute ();
$del_array = array ();
while ( $row = $fetch_stmt -> fetch ()) {
if ( isset ( $row [ 'msgid' ])) {
$del_array [] = $row [ 'msgid' ];
}
}
$overview_dbh = null ;
2024-10-03 14:13:03 +02:00
foreach ( $del_array as $delme ) {
2024-06-11 12:22:21 +02:00
delete_message ( $delme , $group );
echo " Deleting " . $delme . " from " . $group . " \n " ;
}
2023-09-03 16:32:21 +02:00
2024-06-11 14:28:56 +02:00
# History
$history_dbh = history_db_open ( $spooldir . '/history.db3' );
$clear_stmt = $history_dbh -> prepare ( " DELETE FROM history WHERE newsgroup=:group " );
$clear_stmt -> bindParam ( ':group' , $group );
$clear_stmt -> execute ();
$history_dbh = null ;
2024-10-03 14:13:03 +02:00
2024-10-08 13:57:01 +02:00
@ rename ( $spooldir . '/' . $group . '-articles.db3' , $spooldir . '/' . $group . '-articles.db3-removed' );
@ unlink ( $spooldir . '/' . $group . '-data.db3' );
@ unlink ( $spooldir . '/' . $group . '-info.txt' );
@ unlink ( $spooldir . '/' . $group . '-cache.txt' );
@ unlink ( $spooldir . '/' . $group . '-lastarticleinfo.dat' );
@ unlink ( $spooldir . '/' . $group . '-overboard.dat' );
2023-09-03 16:32:21 +02:00
}
2024-12-12 13:53:25 +01:00
function mbox_import_articles ( $group , $mbox )
{
global $spooldir , $CONFIG , $workpath , $path , $config_name , $logfile ;
# Prepare databases
$database = $spooldir . '/' . $group . '-articles.db3' ;
if ( file_exists ( $database )) {
echo $database . ' already exists. Please "-remove ' . $group . '" to import this mbox data' . " \n " ;
echo " Exiting... \n " ;
exit ;
}
$new_article_dbh = article_db_open ( $database );
if ( ! file_exists ( $mbox )) {
echo 'Cannot open ' . $mbox . " \n " ;
echo " Exiting... \n " ;
exit ;
}
$article = 0 ;
$mbox_article = array ();
$file = fopen ( $mbox , 'r' );
while (( $mbox_line = fgets ( $file )) !== false ) {
if ( $article == 0 && trim ( $mbox_line == '' )) {
continue ;
}
if ( preg_match ( " /^From / " , $mbox_line )) {
if ( $article > 0 ) {
mbox_get_one_article ( $group , $mbox_article );
2024-12-12 15:51:28 +01:00
echo " \n Retrieving " . $article ;
2024-12-12 13:53:25 +01:00
$mbox_article = array ();
}
$article ++ ;
continue ;
}
$mbox_article [] = rtrim ( $mbox_line );
}
fclose ( $file );
mbox_get_one_article ( $group , $mbox_article );
echo " Retrieving " . $article . " \n " ;
exit ;
}
// GET INDIVIDUAL ARTICLE
function mbox_get_one_article ( $group , $article_array )
{
global $CONFIG , $config_name , $rslight_gpg , $spooldir , $logfile , $debug_log ;
$grouppath = $spooldir . '/articles/' . preg_replace ( '/\./' , '/' , $group );
if ( ! is_dir ( $grouppath )) {
mkdir ( $grouppath , 0777 , 'recursive' );
}
// $banned_names = file($user_ban_file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$msgid_filter = get_config_value ( 'header_filters.conf' , 'Message-ID' );
$subject_filter = get_config_value ( 'header_filters.conf' , 'Subject' );
$from_filter = get_config_value ( 'header_filters.conf' , 'From' );
$path_filter = get_config_value ( 'header_filters.conf' , 'Path' );
// Create array for article, then send to insert_article_from_array()
if ( isset ( $current_article )) {
unset ( $current_article );
$current_article = array ();
}
$local = get_next_article_number ( $group );
$articleHandle = $grouppath . " / " . $local ;
2024-12-12 15:51:28 +01:00
if ( file_exists ( $articleHandle )) {
unlink ( $articleHandle );
}
2024-12-12 13:53:25 +01:00
unset ( $references );
$lines = 0 ;
$bytes = 0 ;
$ref = 0 ;
$sub = 0 ;
$ng = 0 ;
$supersedes = false ;
$boundary = false ;
$banned = false ;
$integrity = false ;
$is_header = 1 ;
$body = " " ;
$content_transfer_encoding = null ;
foreach ( $article_array as $response ) {
$is_xref = false ;
$bytes = $bytes + mb_strlen ( $response , '8bit' );
if ( trim ( $response ) == " " && $lines > 0 ) {
if ( $is_header == 1 ) {
file_put_contents ( $articleHandle , $current_article [ 'xref' ] . " \n " , FILE_APPEND );
}
$is_header = 0 ;
}
if ( $is_header == 1 ) {
$response = str_replace ( " \t " , " " , $response );
if ( strpos ( $response , ': ' ) !== false ) {
$ref = 0 ;
$sub = 0 ;
$ng = 0 ;
}
// Find article date
if ( stripos ( $response , " Date: " ) === 0 ) {
$finddate = explode ( ': ' , $response , 2 );
$artdate = strtotime ( $finddate [ 1 ]);
}
if ( stripos ( $response , " Injection-Date: " ) === 0 ) {
$finddate = explode ( ': ' , $response , 2 );
$injectiondate = strtotime ( $finddate [ 1 ]);
}
if ( stripos ( $response , " Supersedes: " ) === 0 ) {
$supersedes = explode ( ': ' , $response , 2 );
$supersedes = $supersedes [ 1 ];
}
// Get overview data
if ( stripos ( $response , " Message-ID: " ) === 0 ) {
$mid = explode ( ': ' , $response , 2 );
2024-12-12 15:51:28 +01:00
if ( $msgid_filter != false ) {
if ( preg_match ( $msgid_filter , $mid [ 1 ])) {
$banned = " msgid_filter " ;
}
2024-12-12 13:53:25 +01:00
}
}
if ( stripos ( $response , " From: " ) === 0 ) {
$from = explode ( ': ' , $response , 2 );
2024-12-12 15:51:28 +01:00
if ( $from_filter != false ) {
if ( preg_match ( $from_filter , $from [ 1 ])) {
$banned = " from_filter " ;
}
2024-12-12 13:53:25 +01:00
}
}
if ( stripos ( $response , " Path: " ) === 0 ) {
2024-12-12 15:51:28 +01:00
if ( $path_filter != false ) {
$msgpath = explode ( ': ' , $response , 2 );
if ( preg_match ( $path_filter , $msgpath [ 1 ])) {
$banned = " path_filter " ;
}
2024-12-12 13:53:25 +01:00
}
}
if ( stripos ( $response , " Subject: " ) === 0 ) {
$this_subject = explode ( 'Subject: ' , $response , 2 );
$subject = $this_subject [ 1 ];
$sub = 1 ;
2024-12-12 15:51:28 +01:00
if ( $subject_filter != false ) {
if ( preg_match ( $subject_filter , $subject )) {
$banned = " subject_filter " ;
}
2024-12-12 13:53:25 +01:00
}
}
// Transfer encoding
if ( stripos ( $response , " Content-Transfer-Encoding: " ) === 0 ) {
$enco = explode ( ': ' , $response , 2 );
$content_transfer_encoding = $enco [ 1 ];
}
if ( stripos ( $response , " Newsgroups: " ) === 0 ) {
$response = str_ireplace ( $group , $group , $response );
// Identify each group name for xref
$groupnames = explode ( " Newsgroups: " , $response );
$allgroups = preg_split ( " / \ | \ ,/ " , $groupnames [ 1 ]);
// Create Xref: header
$current_article [ 'xref' ] = " Xref: " . $CONFIG [ 'pathhost' ];
foreach ( $allgroups as $agroup ) {
$agroup = trim ( $agroup );
if (( ! testGroup ( $agroup )) || $agroup == '' ) {
continue ;
}
if ( $group == $agroup ) {
$artnum = $local ;
} else {
$artnum = get_next_article_number ( $agroup );
}
if ( $artnum > 0 ) {
$current_article [ 'xref' ] .= ' ' . $agroup . ':' . $artnum ;
}
}
$ng = 1 ;
}
if ( stripos ( $response , " Xref: " ) === 0 ) {
if ( isset ( $CONFIG [ 'enable_nntp' ]) && $CONFIG [ 'enable_nntp' ] == true ) {
$is_xref = true ;
}
$xref = $response ;
}
if ( stripos ( $response , " Content-Type: " ) === 0 ) {
preg_match ( '/.*charset=.*/' , $response , $te );
$content_type = explode ( " Content-Type: text/plain; charset= " , $te [ 0 ]);
if ( preg_match ( '/.*boundary=.*/' , $response , $be )) {
$boundary = explode ( " boundary= " , $response , 2 );
$boundary = trim ( $boundary [ 1 ], '\";' );
}
}
if ( stripos ( $response , " References: " ) === 0 ) {
$this_references = explode ( 'References: ' , $response );
$references = $this_references [ 1 ];
$ref = 1 ;
}
if ( preg_match ( '/^\s/' , $response ) && $ng == 1 ) {
$addgroups = preg_split ( " / \ | \ ,/ " , trim ( $response ));
$allgroups = array_merge ( $allgroups , $addgroups );
}
if ( preg_match ( '/^\s/' , $response ) && $ref == 1 ) {
$references = $references . $response ;
}
if ( preg_match ( '/^\s/' , $response ) && $sub == 1 ) {
$subject = $subject . $response ;
}
} else {
$body .= $response . " \n " ;
}
if ( ! $is_xref ) {
file_put_contents ( $articleHandle , $response . " \n " , FILE_APPEND );
}
$response = str_replace ( " \n " , " " , str_replace ( " \r " , " " , $response ));
$lines ++ ;
}
file_put_contents ( $articleHandle , $response . " \n " , FILE_APPEND );
$lines = $lines - 1 ;
$bytes = $bytes + ( $lines * 2 );
// Prefer Injection-Date to Date header
// Some newsreaders (PiaoHong) produce a Date header that php does not like
if ( isset ( $injectiondate )) {
$artdate = $injectiondate ;
file_put_contents ( $debug_log , " \n " . format_log_date () . " " . $config_name . " Used Injection-Date " . $artdate . " for: " . $mid [ 1 ], FILE_APPEND );
} else {
file_put_contents ( $debug_log , " \n " . format_log_date () . " " . $config_name . " Used Date " . $artdate . " for: " . $mid [ 1 ], FILE_APPEND );
}
// Check if date matches exactly another article and handle else sorting doesn't like it
while ( isset ( $dates_used [ $artdate ])) {
$artdate = $artdate + 1 ;
$finddate [ 1 ] = date ( " D, j M Y G:i:s (T) " , $artdate );
file_put_contents ( $debug_log , " \n " . format_log_date () . " " . $config_name . " Rewrote date to: " . $artdate . " " . $finddate [ 1 ] . " for " . $group . " : " . $local , FILE_APPEND );
}
$article_date = $artdate ;
$dates_used [ $article_date ] = true ;
// Don't spool article if $banned or fails integrity test
$integrity = check_article_integrity ( file ( $articleHandle ), $artdate );
if (( $banned !== false ) || ( $integrity !== false )) {
unlink ( $articleHandle );
if ( $integrity ) {
file_put_contents ( $logfile , " \n " . format_log_date () . " " . $integrity , FILE_APPEND );
} elseif ( $banned ) {
file_put_contents ( $spamlog , " \n " . format_log_date () . " " . $banned . " : \t SPAM \t " . $mid [ 1 ] . " \t " . $groupnames [ 1 ] . " \t " . $from [ 1 ], FILE_APPEND );
}
$article ++ ;
} else {
if (( strpos ( $CONFIG [ 'nocem_groups' ], $group ) !== false ) && ( $CONFIG [ 'enable_nocem' ] == true )) {
if ( strpos ( $subject , $nocem_check ) !== false ) {
$is_from = address_decode ( $from [ 1 ], 'nowhere' );
$nocem_file = tempnam ( $spooldir . " /nocem " , $is_from [ 0 ][ 'mailbox' ] . " @ " . $is_from [ 0 ][ 'host' ] . " [ " . date ( " Y.m.d.H.i.s " ) . " ] " );
copy ( $articleHandle , $nocem_file );
chmod ( $nocem_file , 0644 );
if ( $save_nocem_messages == true ) {
$saved_nocem_file = tempnam ( $nocem_dir , $is_from [ 0 ][ 'mailbox' ] . " @ " . $is_from [ 0 ][ 'host' ] . " [ " . date ( " Y.m.d.H.i.s " ) . " ]- " );
copy ( $articleHandle , $saved_nocem_file );
}
}
}
2024-12-12 15:51:28 +01:00
if ( isset ( $rslight_gpg [ 'nntp_group' ]) && (( strpos ( $rslight_gpg [ 'nntp_group' ], $group ) !== false ) && ( $rslight_gpg [ 'enable' ] == '1' ))) {
2024-12-12 13:53:25 +01:00
if ( strpos ( $subject , $bbsmail_check ) !== false ) {
$bbsmail_file = preg_replace ( '/@@RSL /' , '' , $subject );
$bbsmail_filename = $spooldir . " /bbsmail/in/bbsmail- " . $bbsmail_file ;
copy ( $articleHandle , $bbsmail_filename );
}
}
$this_article = file_get_contents ( $articleHandle );
if ( $CONFIG [ 'article_database' ] == '1' ) {
unlink ( $articleHandle );
// CREATE SEARCH SNIPPET
if ( $boundary !== false ) {
$body_array = explode ( " \n " , $body );
$found = false ;
$start = false ;
foreach ( $body_array as $line ) {
if ( $found === false ) {
if ( strpos ( $line , $boundary ) !== false ) {
$found = true ;
continue ;
} else {
continue ;
}
}
if ( trim ( $line != '' ) && $start === false ) {
continue ;
} else {
if ( $start === false ) {
$start = true ;
continue ;
}
}
$newbody .= $line . " \n " ;
}
file_put_contents ( $debug_log , " \n " . format_log_date () . " Created snippet from multipart article: " . $mid [ 1 ], FILE_APPEND );
} else {
$newbody = $body ;
}
2024-12-12 15:51:28 +01:00
if ( isset ( $content_type [ 1 ])) {
$this_snippet = get_search_snippet ( $newbody , $content_type [ 1 ], $content_transfer_encoding );
} else {
$this_snippet = get_search_snippet ( $newbody , '' , $content_transfer_encoding );
}
2024-12-12 13:53:25 +01:00
unset ( $newbody );
} else {
touch ( $articleHandle , $article_date );
}
$current_article [ 'mid' ] = $mid [ 1 ];
$current_article [ 'epochdate' ] = $article_date ;
$current_article [ 'stringdate' ] = $finddate [ 1 ];
$current_article [ 'from' ] = $from [ 1 ];
$current_article [ 'subject' ] = $subject ;
2024-12-12 15:51:28 +01:00
if ( isset ( $references )) {
$current_article [ 'references' ] = $references ;
}
2024-12-12 13:53:25 +01:00
$current_article [ 'bytes' ] = $bytes ;
$current_article [ 'lines' ] = $lines ;
$current_article [ 'article' ] = $this_article ;
$current_article [ 'snippet' ] = $this_snippet ;
// Check Spam
$res = 0 ;
if ( isset ( $CONFIG [ 'spamassassin' ]) && ( $CONFIG [ 'spamassassin' ] == true ) && ( $OVERRIDES [ 'disable_spamassassin_spooling' ] !== true )) {
$spam_result_array = check_spam ( $subject , $from [ 1 ], $groupnames [ 1 ], $references , $this_article , $mid [ 1 ]);
$res = $spam_result_array [ 'res' ];
$spamresult = $spam_result_array [ 'spamresult' ];
$spamcheckerversion = $spam_result_array [ 'spamcheckerversion' ];
$spamlevel = $spam_result_array [ 'spamlevel' ];
}
if ( $res === 1 ) {
unlink ( $articleHandle );
file_put_contents ( $logfile , " \n " . format_log_date () . " " . $config_name . " Skipping: " . $CONFIG [ 'remote_server' ] . " " . $group . " : " . $mid [ 1 ] . " Exceeds Spam Score " , FILE_APPEND );
// $orig_newsgroups = $newsgroups;
// $newsgroups = $CONFIG['spamgroup'];
// $group = $newsgroups;
$local -- ;
} else {
$pass = false ;
foreach ( $allgroups as $agroup ) {
$agroup = trim ( $agroup );
if (( ! testGroup ( $agroup )) || $agroup == '' ) {
continue ;
}
$current_article [ 'group' ] = $agroup ;
if ( $group == $agroup ) {
$current_article [ 'local' ] = $local ;
} else {
$current_article [ 'local' ] = get_next_article_number ( $agroup );
}
file_put_contents ( $logfile , " \n " . format_log_date () . " " . $config_name . " Preparing to spool " . $group . " : " . $mid [ 1 ], FILE_APPEND );
$tmp = insert_article_from_array ( $current_article , false );
2024-12-12 15:51:28 +01:00
if ( $tmp && $tmp [ 0 ] != " 4 " ) {
2024-12-12 13:53:25 +01:00
$pass = true ;
}
2024-12-12 15:51:28 +01:00
file_put_contents ( $logfile , " \n " . format_log_date () . " " . $config_name . " " . rtrim ( $tmp ), FILE_APPEND );
2024-12-12 13:53:25 +01:00
}
}
$local ++ ;
}
if ( $supersedes !== false ) {
if ( isset ( $OVERRIDES [ 'enable_supersedes_support' ]) && $OVERRIDES [ 'enable_supersedes_support' ] == true ) {
file_put_contents ( $debug_log , " \n " . format_log_date () . " Found Supersedes: " . $mid [ 1 ] . " for: " . $supersedes , FILE_APPEND );
if ( ! check_remote_for_msgid ( $supersedes )) {
file_put_contents ( $debug_log , " \n " . format_log_date () . " Will delete: " . $supersedes , FILE_APPEND );
delete_message ( $supersedes );
}
}
}
}
2023-09-03 16:32:21 +02:00
function import_articles ( $group )
{
global $spooldir , $CONFIG , $workpath , $path , $config_name , $logfile ;
# Prepare databases
// Overview db
$new_article_dbh = article_db_open ( $spooldir . '/' . $group . '-articles.db3-new' );
$new_article_sql = 'INSERT OR IGNORE INTO articles(newsgroup, number, msgid, date, name, subject, article, search_snippet) VALUES(?,?,?,?,?,?,?,?)' ;
$new_article_stmt = $new_article_dbh -> prepare ( $new_article_sql );
$database = $spooldir . '/articles-overview.db3' ;
$table = 'overview' ;
2023-11-15 12:55:08 +01:00
$overview_dbh = overview_db_open ( $database , $table );
$clear_stmt = $overview_dbh -> prepare ( " DELETE FROM overview WHERE newsgroup=:group " );
2023-09-03 16:32:21 +02:00
$clear_stmt -> bindParam ( ':group' , $group );
$clear_stmt -> execute ();
clear_history_by_group ( $group );
2023-11-15 12:55:08 +01:00
$overview_sql = 'INSERT OR IGNORE INTO overview(newsgroup, number, msgid, date, datestring, name, subject, refs, bytes, lines, xref) VALUES(?,?,?,?,?,?,?,?,?,?,?)' ;
$overview_stmt = $overview_dbh -> prepare ( $overview_sql );
2023-09-03 16:32:21 +02:00
// Incoming db
$article_dbh = article_db_open ( $spooldir . '/' . $group . '-articles.db3' );
$article_stmt = $article_dbh -> query ( 'SELECT DISTINCT * FROM articles' );
while ( $row = $article_stmt -> fetch ()) {
$local = $row [ 'number' ];
$this_article = preg_split ( " / \r \n | \n | \r / " , $row [ 'article' ]);
$lines = 0 ;
$bytes = 0 ;
$ref = 0 ;
$banned = 0 ;
$is_header = 1 ;
$body = " " ;
foreach ( $this_article as $response ) {
$bytes = $bytes + mb_strlen ( $response , '8bit' );
if ( trim ( $response ) == " " || $lines > 0 ) {
$is_header = 0 ;
2024-10-03 14:13:03 +02:00
$lines ++ ;
2023-09-03 16:32:21 +02:00
}
if ( $is_header == 1 ) {
$response = str_replace ( " \t " , " " , $response );
2024-01-03 22:57:27 +01:00
if ( strpos ( $response , ': ' ) !== false ) {
$ref = 0 ;
}
2023-09-03 16:32:21 +02:00
// Find article date
if ( stripos ( $response , " Date: " ) === 0 ) {
$finddate = explode ( ': ' , $response , 2 );
}
// Get overview data
$mid [ 1 ] = $row [ 'msgid' ];
$from [ 1 ] = $row [ 'name' ];
$subject [ 1 ] = $row [ 'subject' ];
$article_date = $row [ 'date' ];
if ( stripos ( $response , " Content-Type: " ) === 0 ) {
preg_match ( '/.*charset=.*/' , $response , $te );
2024-10-03 14:13:03 +02:00
if ( isset ( $te [ 0 ])) {
$content_type = explode ( " Content-Type: text/plain; charset= " , $te [ 0 ]);
}
2023-09-03 16:32:21 +02:00
}
if ( stripos ( $response , " References: " ) === 0 ) {
$this_references = explode ( 'References: ' , $response );
$references = $this_references [ 1 ];
$ref = 1 ;
}
2024-01-03 22:57:27 +01:00
if ( preg_match ( '/^\s/' , $response ) && $ref == 1 ) {
$references = $references . $response ;
2023-09-03 16:32:21 +02:00
}
$response = str_replace ( " \n " , " " , str_replace ( " \r " , " " , $response ));
} else {
$body .= $response . " \n " ;
}
}
$lines = $lines - 1 ;
$bytes = $bytes + ( $lines * 2 );
// add to database
// CREATE SEARCH SNIPPET
$this_snippet = get_search_snippet ( $body , $content_type [ 1 ]);
2024-10-03 14:13:03 +02:00
$xref = create_xref_from_msgid ( $mid [ 1 ], $group , $local );
2023-09-03 16:32:21 +02:00
$new_article_stmt -> execute ([
$group ,
$local ,
$mid [ 1 ],
$article_date ,
$from [ 1 ],
$subject [ 1 ],
$row [ 'article' ],
$this_snippet
]);
2023-11-15 12:55:08 +01:00
$overview_stmt -> execute ([
2023-09-03 16:32:21 +02:00
$group ,
$local ,
$mid [ 1 ],
$article_date ,
$finddate [ 1 ],
$from [ 1 ],
$subject [ 1 ],
$references ,
$bytes ,
$lines ,
$xref
]);
$status = " respooled " ;
$statusdate = time ();
$statusreason = " repair " ;
2024-10-03 14:13:03 +02:00
$statusnotes = '' ;
2023-09-03 16:32:21 +02:00
add_to_history ( $group , $local , $mid [ 1 ], $status , $statusdate , $statusreason , $statusnotes );
echo " \n Imported: " . $group . " " . $local ;
file_put_contents ( $logfile , " \n " . format_log_date () . " " . $config_name . " Imported: " . $group . " : " . $local , FILE_APPEND );
2024-10-03 14:13:03 +02:00
$i ++ ;
2023-09-03 16:32:21 +02:00
$references = " " ;
}
$new_article_dbh = null ;
$article_dbh = null ;
2023-11-15 12:55:08 +01:00
$overview_dbh = null ;
2023-09-03 16:32:21 +02:00
unlink ( $spooldir . '/' . $group . '-articles.db3' );
rename ( $spooldir . '/' . $group . '-articles.db3-new' , $spooldir . '/' . $group . '-articles.db3' );
unlink ( $spooldir . '/' . $group . '-info.txt' );
unlink ( $spooldir . '/' . $group . '-cache.txt' );
unlink ( $spooldir . '/' . $group . '-lastarticleinfo.dat' );
unlink ( $spooldir . '/' . $group . '-overboard.dat' );
reset_group ( $group );
}