more graceful exit on event on no emails in inbox ($pop3->quit) * - Added work around for email addresses with exta <> in field (ie: instead of blade@lasmash.com * - Added some ===basic=== enriched text support * - Updated readme file for easier install * - Easy modify of globals (such as PHOTOSDIR and FILESDIR) * - Cleaned up some pear stuff in install * * Version 0.1 - 2004-06 * First release -= Begin Program =- **/ if($argc==2) { $mailblog=$wpblog=$argv[1]; echo $mailblog; } //Load up some usefull libraries $ROOTDIR = dirname(__FILE__); //area where blogmail is, i.e. /var/www/blogmail require($ROOTDIR . '/bm-config.php'); require_once ($ROOTDIR . '/mimedecode.php'); // require_once ('bm-admin/admin.php'); // require_once ('bm-admin/admin-header.php'); wpmu_clear_cache(); /* USER VARIABLES */ //global vars you can change, but dont unless you know what you're doing. :) $PHOTOSDIR = "/bm-content/blogs/".$mailblog."/images/"; //BLOGMAIL was /images/ $FILESDIR = "/bm-content/blogs/".$mailblog."/files/"; //BLOGMAIL was /bm-filez/ //if you don't want to add a subject in the email then you assign a default $DEFAULT_TITLE = '(Sin asunto)'; //What protocol are we using? Just leave it default if you don't know $input_protocol = '1'; //0 = pop3, 1 = smtp //Delete mail on successful download? Setting FALSE for debuging $delete_email = TRUE; //Time difference - tweak to suit, ie (10 for Brisbane, Australia) $time_difference = get_settings('gmt_offset'); //drop Sigature, Everything after -- is deleted in the text msg. $DROP_SIGNATURE = TRUE; // Use thumbnails? will be used in ver 0.4 // $THUMBNAILS = TRUE; // Photo maximum thumbnail size for Height // $PHOTO_MAXHEIGHT = 200; // maximum height /* END OF USER VARIABLES */ //some variables error_reporting(2037); //Retreive emails switch ( $input_protocol ) { case '1': //smtp - direct $fd = fopen("php://stdin", "r"); $input = ""; while (!feof($fd)) { $input .= fread($fd, 1024); } fclose($fd); $emails[0] = $input; break; default: //pop3 $emails = pop3_retr( $delete_email ); } //loop through messages foreach ($emails as $email) { //sanity check to see if there is any info in the message if ($email == NULL ) { print 'Dang, message is empty!'; $check_plugins = get_settings('active_plugins'); echo '
Plugins activados:
'; //$active_plugins = array_values($check_plugins); //echo $active_plugins; foreach ($check_plugins as $key=> $val) { echo $val."
"; if ($val == 'mailwoman.php') { echo "si"; } } die; } //decode the mime $params['include_bodies'] = true; $params['decode_bodies'] = false; $params['decode_headers'] = true; $params['input'] = $email; $mailmime=new Mail_mimeDecode($email); // $structure=$mailmime->decode($params); //$structure = Mail_mimeDecode::decode($params); # print_r ($structure); //assign the default title/subject if ( $structure->headers['subject'] == NULL ) { $subject = $DEFAULT_TITLE; } else { $subject = htmlentities($structure->headers['subject'], ENT_COMPAT, "UTF-8"); //$subject = $structure->headers['subject']; } $ddate = trim($structure->headers['date']); $from = trim($structure->headers['from']); $from1 = trim($structure->headers['from']); // BLOGMAIL para extraer el Nick $post_to = trim($structure->headers['to']); // BLOGMAIL para extraer el to $post_cc = trim($structure->headers['cc']); // BLOGMAIL para extraer el CC $post_bcc = trim($structure->headers['bcc']); // BLOGMAIL para extraer el BCC $post_spam = trim($structure->headers['x-spam-flag']); $post_message_id = trim($structure->headers['message-id']); $post_in_reply_to = trim($structure->headers['in-reply-to']); $from_list = trim($structure->headers['x-list-administrivia']); $post_headers = $mailmime->_header; $userlevel = getuserlevel ($from); //Check poster to see if a valid person $poster = checkuserposter($from); //default ping/comment status for sanity $comment_status = get_settings('default_comment_status'); $ping_status = get_settings('default_ping_status'); // BLOGMAIL $user_data = get_userdatabylogin($mailblog); $post_status = $user_data->user_status; //work around for users with extra <> in email address if (preg_match('/^[^<>]+<([^<>]+)>$/',$from,$matches)) { $from = $matches[1]; } $content = get_content($structure); //date reformating $post_date = date('Y-m-d H:i:s', time($ddate) ); // $post_date = gmdate('Y-m-d H:i:s', time($now) + ($time_difference * 3600)); $post_date_gmt = gmdate('Y-m-d H:i:s', time($ddate) ); //remove signature if ( $DROP_SIGNATURE ) { $content = removesig($content); } //decode ubb $content = ubb2html($content); //filter new lines $content = filternewlines($content); //only for test pourposes //$content = $post_spam; /* //try and determine category $post_spam if ( preg_match('/(.+): (.*)/', $subject, $matches) OR preg_match('/\[(.+)\] (.*)/', $subject, $matches) ) { $post_categories[0] = trim($matches[1]); # esto es lo que causa problemas: #$subject = trim($matches[2]); //Work on the category search to see if we can determine the cat_id //check the database to see if their is a category similar $sql_name = 'SELECT cat_ID FROM ' . $tablecategories . ' WHERE cat_name=\'' . addslashes($post_categories[0]) . '\''; $sql_id = 'SELECT cat_ID FROM ' . $tablecategories . ' WHERE cat_ID=\'' . addslashes($post_categories[0]) . '\''; if ( $post_categories[0] = $wpdb->get_var($sql_name) ) { //then category is a named and found } elseif ( $post_categories[0] = $wpdb->get_var($sql_id) ) { //then cateogry was an ID and found } else { if ($post_spam=='YES') $post_categories[0] = -1; else //then there was no found category so use default $post_categories[0] = get_settings('default_email_category'); } } else {*/ //mover esto $check_plugins = get_settings('active_plugins'); foreach ($check_plugins as $key=> $val) {}; if ($post_spam=='YES') { $post_categories[0] = -1; //spam category $post_status = 'private'; } else { if (ereg("(mailer_daemon|mailer-daemon|postmaster|bounces)",strtolower($from1))) { $post_categories[0] = 4; // admin category $post_status = 'private'; } else { if ($from_list=='yes') { $post_categories[0] = 5; // from list category $post_status = 'private'; } else { if ($userlevel<3 && $val == 'mailwoman.php') { $post_categories[0] = 6; // to moderate category $post_status = 'private'; } else { $post_categories[0] = get_settings('default_email_category'); // default category (inbox) $post_status = $user_data->user_status; } } } } // Report // print '

Mail Format: ' . $mailformat . '

' . "\n"; print '

From: ' . $from . '
' . "\n"; print 'Date: ' . $post_date . '
' . "\n"; print 'Date GMT: ' . $post_date_gmt . '
' . "\n"; print 'Category: ' . $post_categories[0] . '
' . "\n"; print 'Subject: ' . $subject . '
' . "\n"; print 'Posted content:


' . $content . '
'; $details = array( 'post_author' => $poster, 'post_date' => $post_date, 'post_date_gmt' => $post_date_gmt, 'post_content' => $content, 'post_title' => $subject, 'post_modified' => $post_date, 'post_modified_gmt' => $post_date_gmt, 'ping_status' => $ping_status, 'post_status' => $post_status, // BLOGMAIL 'post_to' => $post_to, // BLOGMAIL 'post_cc' => $post_cc, // BLOGMAIL 'post_bcc' => $post_bcc, // BLOGMAIL 'post_headers' => $post_headers, // BLOGMAIL 'menu_order' => $post_message_id, 'post_parent' => $post_in_reply_to ); //generate sql for insertion $sql = 'INSERT INTO '.$tableposts.' ('. implode(',',array_keys($details)) .') VALUES (\''. implode('\',\'',array_map('addslashes',$details)) . '\')'; echo "
".$sql; $result = $wpdb->query($sql); echo "resultado: ".$result; echo mysql_error(); $post_ID = $wpdb->insert_id; do_action('publish_post', $post_ID); do_action('publish_phone', $post_ID); pingback($content, $post_ID); // BLOGMAIL $post_guid = get_permalink($post_ID); $post_name = sanitize_title($subject,$post_ID); $sql = "UPDATE $tableposts set guid='$post_guid', post_name='$post_name' where ID=$post_ID"; $result = $wpdb->query($sql); // BLOGMAIL foreach ($post_categories as $post_category) { $post_category = intval($post_category); // Double check it's not there already $exists = $wpdb->get_row("SELECT * FROM $tablepost2cat WHERE post_id = $post_ID AND category_id = $post_category"); if (!$exists && $result) { $sqlstring=" INSERT INTO $tablepost2cat (post_id, category_id) VALUES ($post_ID, $post_category) "; echo $sqlstring; $wpdb->query($sqlstring); } } } // end looping over messages exit(0); /* END PROGRAM */ /** FUNCTIONS **/ //retrieve POP3 mail function pop3_retr ( $delete_email=TRUE ) { global $mailblog; require_once(ABSPATH.WPINC.'/class-pop3.php'); $pop3 = new POP3(); $user_data = get_userdatabylogin($mailblog); // redefining user_login ensures we return the right case in the email $user_login = $user_data->user_login; #$user_pass = $user_data->user_pass; $user_pass = get_settings('mailserver_pass'); if (!$pop3->connect(localhost, 110)) : echo "Ooops $pop3->ERROR
\n"; exit; endif; echo $user_login; //Check to see if there is any mail, if not die $msg_count = $pop3->login($user_login, $user_pass); if (0 == $msg_count) { $pop3->quit(); die(__('There does not seem to be any new mail.')); } // loop through messages for ($i=1; $i <= $msg_count; $i++) { $emails[$i] = implode ('',$pop3->get($i)); // BLOGMAIL: if ( $delete_email == TRUE && checkuserposter($emails[$i]) ) { if ( $delete_email == TRUE ) //BLOGMAIL: sin chequeo de usuarios { if( !$pop3->delete($i) ) { echo '

Oops '.$pop3->ERROR.'

'; $pop3->reset(); exit; } else { echo "Mission complete, message $i deleted."; } } } //clean up $pop3->quit(); return $emails; } //tear apart the meta part for useful information function get_content ($part) { global $PHOTOSDIR,$FILESDIR,$THUMBNAILS,$ROOTDIR; $URLPHOTOSDIR = get_settings('siteurl') . $PHOTOSDIR; $REALPHOTOSDIR = $ROOTDIR . $PHOTOSDIR; $URLFILESDIR = get_settings('siteurl') . $FILESDIR; $REALFILESDIR = $ROOTDIR . $FILESDIR; //fixes switch ( strtolower($part->ctype_primary) ) { case 'multipart': $meta_return = ''; foreach ($part->parts as $section) { $meta_return .= get_content($section); } break; case 'text': $part = base64check($part); $part = quoted_printable_check($part); $part = charsetcheck($part); //go through each sub-section if ($part->ctype_secondary=='enriched') { //convert enriched text to html $meta_return = etf2html($part->body ) . "\n"; } elseif ($part->ctype_secondary=='html') //check for html encoding { //strip excess html $meta_return = html2html($part->body ) . "\n"; } else { //regular text, so just strip the pgp signature $meta_return = htmlentities( $part->body, ENT_COMPAT, "UTF-8") . "\n"; //$meta_return = strip_pgp($meta_return); // $meta_return = $part->body; } break; case 'image': $part = base64check($part); // $filename = $part->ctype_primary . '.' . $part->ctype_secondary; $filename = rand() . '.' . $part->ctype_secondary; $file = $REALPHOTOSDIR . $filename; $fp = fopen($file, 'w'); fwrite($fp, $part->body); fclose($fp); @exec ('chmod 755 ' . $file); $meta_return .= '' . $part->ctype_parameters['name'] . '' . "\n"; break; case 'application': //pgp signature - then forget it $part = base64check($part); if ( $part->ctype_secondary == 'pgp-signature' ) {break;} //other attachments save to $FILESDIR $filename = $part->ctype_parameters['name']; $file = $REALFILESDIR . $filename; $fp = fopen($file, 'w'); fwrite($fp, $part->body ); fclose($fp); @exec ('chmod 755 ' . $file); $meta_return .= '' . $part->ctype_parameters['name'] . '' . "\n"; break; } return $meta_return; } function ubb2html($text) { // Array of tags with opening and closing $tagArray['img'] = array('open'=>''); $tagArray['b'] = array('open'=>'','close'=>''); $tagArray['i'] = array('open'=>'','close'=>''); $tagArray['u'] = array('open'=>'','close'=>''); $tagArray['url'] = array('open'=>'\\1'); $tagArray['email'] = array('open'=>'\\1'); $tagArray['url=(.*)'] = array('open'=>'\\2'); $tagArray['email=(.*)'] = array('open'=>'\\2'); $tagArray['color=(.*)'] = array('open'=>'\\2'); $tagArray['size=(.*)'] = array('open'=>'\\2'); $tagArray['font=(.*)'] = array('open'=>'\\2'); // Array of tags with only one part $sTagArray['br'] = array('tag'=>'
'); $sTagArray['hr'] = array('tag'=>'
'); foreach($tagArray as $tagName=>$replace) { $tagEnd=preg_replace('/\W/Ui','',$tagName); $text = preg_replace("|\[$tagName\](.*)\[/$tagEnd\]|Ui","$replace[open]\\1$replace[close]",$text); } foreach($sTagArray as $tagName=>$replace) { $text= preg_replace("|\[$tagName\]|Ui","$replace[tag]",$text); } return $text; } // This function turns Enriched Text into something similar to html // Very basic at the moment, only supports some functionality and dumps the rest // FIXME: fix colours: FFFF,C2FE,0374some text function etf2html ( $content ) { $search = array( '//', '/<\/bold>/', '//', '/<\/underline>/', '//', '/<\/italic>/', '/.*<\/param>/', '/<\/fontfamily>/', '//', '/<\/x-tad-bigger>/', '//', '/', '//', '/<\/color>/', '/.+<\/param>/' ); $replace = array ( '', '', '', '', '', '', '', '', '', '', '', '', '', '', '' ); // strip extra line breaks $content = preg_replace($search,$replace,$content); return trim($content); } // This function cleans up HTML in the e-mail function html2html ( $content ) { $search = array( '//', '/<\/html>/', '//', '/<\/title>/', '/<body.*>/', '/<\/body>/', '/<head>/', '/<\/head>/', '/<meta content=.*>/', '/<!DOCTYPE.*>/', '/<img src=".*>/' // '/<img src="cid:(.*)" .*>/' ); $replace = array ( '', '', '', '', '', '', '', '', '', '', '', '' ); // strip extra line breaks $content = preg_replace($search,$replace,trim($content)); return ($content); } //see if sender is a valid sender from the wp database function checkuserposter ( $from ) { global $wpdb,$tableusers; //sanity check to see if there is any info in the message /* if ($from == NULL ) { print 'Dang, message is empty!'; die; } //decode the mime $params['include_bodies'] = true; $params['decode_bodies'] = false; $params['decode_headers'] = true; $params['input'] = $email; $structure = Mail_mimeDecode::decode($params); $from = trim($structure->headers['from']); */ //work around for users with extra <> in email address if (preg_match('/^[^<>]+<([^<>]+)>$/',$from,$matches)) { $from = $matches[1]; } // BLOGMAIL: if ( empty($from) ) { echo '<h1> Invalid Sender - Emtpy! </h1>'; die;} $sql = 'SELECT id FROM '.$tableusers.' WHERE user_email=\'' . addslashes($from) . '\''; if (!$poster = $wpdb->get_var($sql)) { // BLOGMAIL: si no existe el autor, lo creas global $from1; global $post_spam; $from_a = str_replace($from,'',$from1); $from_a = str_replace('<>','',$from_a); // BLOGMAIL: si el autor es un spammer, su nivel de usuario es 0 /*$params['include_bodies'] = true; /$params['decode_bodies'] = false; $params['decode_headers'] = true; $params['input'] = $email; $structure=$mailmime->decode($params); $post_spam = trim($structure->headers['x-spam-flag']);*/ if ($post_spam=='YES') $add = "INSERT INTO $tableusers (user_login,user_nickname,user_nicename,user_email,user_level,user_idmode,user_status) VALUES ('$from','$from_a','$from_a','$from',0,'','publish')"; // BLOGMAIL: en los demas casos, su nivel de usuario es 1 else $add = "INSERT INTO $tableusers (user_login,user_nickname,user_nicename,user_email,user_level,user_idmode,user_status) VALUES ('$from','$from_a','$from_a','$from',1,'','publish')"; $result = $wpdb->query($add); $result = $wpdb->insert_id; $poster = $wpdb->get_var($sql); } $poster = $wpdb->get_var($sql); return $poster; // BLOGMAIL } function getuserlevel ( $from ) { global $wpdb,$tableusers; if (preg_match('/^[^<>]+<([^<>]+)>$/',$from,$matches)) { $from = $matches[1]; } $sql = 'SELECT user_level FROM '.$tableusers.' WHERE user_email=\'' . addslashes($from) . '\''; $userlevel = $wpdb->get_var($sql); return $userlevel; } //function mailwoman $check_plugins = get_settings('active_plugins'); // foreach ($check_plugins as $key=> $val) { // echo $val."<br />"; // if ($val == 'mailwoman.php') { // echo "si"; // } // } // Keeps content until finds a line with '--' or '- --' // This effectively removes signatures function removesig ( $content ) { $arrcontent = explode("\n", $content); $append = TRUE; $i = 0; for ($i = 0; $i<=count($arrcontent); $i++) { $line = $arrcontent[$i]; $nextline = $arrcontent[$i+1]; if ( preg_match('/^--$/',trim($line)) OR preg_match('/^- --$/',$line) ) { $append = FALSE; } if ( $append == TRUE ) { // if ($line != NULL && $nextline == NULL ) //{ $strcontent .= $line ."</br>\n";; //check if there are null lines \n //} elseif ($line == NULL && $nextline == NULL) { $strcontent .= '</br>'; //}else { $strcontent .= $line ."\n"; } } return $strcontent; } //filter content for new lines function filternewlines ( $content ) { $search = array ( '/ (\n|\r\n|\r)/', '/(\n|\r\n|\r)/' ); $replace = array ( ' ', "\n" ); // strip extra line breaks $return = preg_replace($search,$replace,$content); return $return; } //strip pgp stuff function strip_pgp ( $content ) { $search = array ( '/-----BEGIN PGP SIGNED MESSAGE-----/', '/Hash: SHA1/' ); $replace = array ( ' ', '' ); // strip extra line breaks $return = preg_replace($search,$replace,$content); return $return; } // This function checks if the content is base64 function base64check ( $part ) { // if ($part->headers['content-transfer-encoding'] != 'base64') // { if ( strtolower($part->headers['content-transfer-encoding']) == 'base64' ) { $part->body = base64_decode($part->body); } // } return $part; } function quoted_printable_check ($part) { if ( strtolower($part->headers['content-transfer-encoding']) == 'quoted-printable' ) { $part->body = quoted_printable_decode($part->body); } // } return $part; } function charsetcheck ( $part ) { /* if ( strtolower($part->ctype_parameters['charset']) == 'utf-8') { $part->body = utf8_decode($part->body); }*/ if ( strtolower($part->ctype_parameters['charset']) != 'utf-8') { $part->body = iconv($part->ctype_parameters['charset'], 'utf-8', $part->body); } return $part; } // end of script ?>