Skip to content

Instantly share code, notes, and snippets.

@gadhra
Created April 14, 2011 20:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gadhra/920483 to your computer and use it in GitHub Desktop.
Save gadhra/920483 to your computer and use it in GitHub Desktop.
This file, written in PHP 4, parsed qmail messages piped to it via a procmail rule (if I remember correctly). The script will parse anything sent to it via stdin.
<?php
/**
* @note Qmail popper::PHP4::qmail-popper-php
* @author Stefan Antonowicz
*
* This file parses out the mails sent to qmail via stdin.
*
* @author Stefan Antonowicz
*/
error_reporting(E_ERROR | E_WARNING | E_PARSE);
/* Set constants and variables */
$mime_types = array( 'image/jpeg'=>'.jpg', 'image/jpg'=>'.jpg', 'image/gif'=>'.gif', 'image/png'=>'.png' );
$x_scale = 189;
define( 'ATTACH_DEST', '/home/foo/bar' );
define( 'ATTACH_TMP', '/tmp' );
/*
* A file name can be passed in instead i.e. `which php` qmail_popper.php -f foo.txt
*/
if( $argv[1] == '-f' ) {
$fp = fopen( $argv[2], 'r' );
} else {
$fp = fopen( "php://stdin", "r" );
}
if(! $fp ) exit( 0 );
$mail = '';
while(! feof( $fp ) ) {
$line = fread( $fp, 1024 );
$mail .= $line;
}
fclose( $fp );
/*
* Time to start parsing out the headers, body, and attachments. Some of this
* borrowed from the PEAR mimeDecode class.
*/
$mail = preg_replace( "/\r?\n/", "\r\n", $mail );
$mail = preg_replace( "/\r\n(\t| )+/", ' ', $mail );
$mail_array = explode( "\r\n", trim( $mail ) );
foreach( $mail_array as $elem ) {
$elem = trim( $elem );
$name = substr( $elem, 0, $pos = strpos( $elem, ':' ) );
$value = substr( $elem, $pos + 1 );
/* These are because PHP4 doesn't have stripos */
$lower_name = strtolower( $name );
$lower_elem = strtolower( $elem );
$lower_value = strtolower( $value );
/* Catch FROM and TO addresses in <foo@example.org> format */
if( preg_match( "/<(.*)>/sU", $value, $match ) ) $value = $match[1];
$value = trim( $value );
if( $name ) {
if( strpos( $lower_name, 'content-type' ) !== FALSE ) {
/* get attachment type and set it as key. Also see if header is in the "forbidden" list */
preg_match( '/(.*)($|;)/sU', $value, $key );
preg_match( '/;.*=(.*)$/sU', $value, $mime_name );
/* some systems put quotes around the mime name, others don't */
if( $mime_name[1] ) $mime_name = str_replace( '"', '', $mime_name[1] );
if( in_array( $mime_name, $bad_attach ) ) continue;
$headers[$name][] = $value;
$curname = trim( $key[1] );
} else {
$headers[$name] = $value;
}
} elseif( $elem && strpos( $lower_elem, '_part_' ) === FALSE && strpos( $lower_elem, 'dngr' ) == FALSE ) {
$body[$curname][] = $elem;
}
}
$msg_array = $body['text/plain'] ? $body['text/plain'] : strip_tags( $body['text/html'] );
/*
* NOTE: I submitted the message to the database and got a unique id for it, identified
* as $msgid. I also tried to determine the user information and parse any
* messages the user sent via SMS, which aren't important for this demonstration
*/
if(! $msgid ) exit( 0 );
$image_file = "img_" . time( ) . "_" . $msgid;
/*
* IMAGE HANDLING
*/
foreach( $mime_types as $type=>$ext ) {
if( array_key_exists( $type, $body ) ) {
$image_file .= $ext;
$attach = implode( "\n", $body[$type] );
$check_type = $type;
}
}
if( ! $attach ) exit( 0 );
$payload = ATTACH_TMP. $image_file;
$h = fopen( $payload, 'w' );
fwrite( $h, base64_decode( $attach ) );
fclose( $h );
if( class_exists( 'finfo' ) ) {
$finfo = new finfo( FILEINFO_MIME, MIME_DB ); // return mime type ala mimetype extension
$mtype = $finfo->file( $payload );
} else {
$mtype = trim( exec( 'file -bi ' . escapeshellarg( $payload ) ) );
}
if( $mtype != $check_type ) {
unlink( $payload );
exit( 0 );
}
/*
* Here I would pull the name of the last image submitted by the user, which would be $last_image
*/
$last_image = $game->lastImage( );
if(! $last_image || md5( file_get_contents( $payload ) ) != md5( file_get_contents( $last_image ) ) ) {
unlink( $payload );
exit( 0 );
}
/*
* Looking good - make directories and move the file over. This requires a user id generated earlier
*/
$dest_dir = ATTACH_DEST . $user->id;
$thumb_dir = ATTACH_DEST . $user->id . '/thumbs';
$destination = $dest_dir . '/' . $image_file;
if(! is_dir( $dest_dir ) )
@mkdir( $dest_dir, 0777 );
if(! is_dir( $thumb_dir ) )
@mkdir( $thumb_dir, 0777 );
rename( $payload, $destination );
exit( 0 );
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment