/? # see server.conf for various directory configuration # # Matching rules: # Always look in the cache first (you need to delete a file in the cache # if it's source in the picture library has changed) # Try to find an exact match (input number matches file name) first, then # translate the number and check again # If multiple files with same number but different format exist in library, # this is the precedence used: # 1. PNG, # 2. JPG, # 3. GIF ############################################################################# ############################################################################# # PHP customization for warnings ############################################################################# error_reporting(E_ERROR | E_PARSE); ############################################################################# # Private functions ############################################################################# function getvar_safe($var_name,$default='',$method='GET') { eval('$return = (isset($_'.$method.'["'.$var_name.'"])) ? htmlentities(html_entity_decode(stripslashes((trim($_'.$method.'["'.$var_name.'"]))),ENT_QUOTES),ENT_QUOTES) : $default;'); return $return; } function decode_HTTP_header() { Global $TEST; # Debug mode if($TEST) { # Calculate fake mac address suffix based on client's source address $fake_mac_suffix = strtoupper(substr(md5(getvar_safe('REMOTE_ADDR','','SERVER')),0,6)); $array=array( 'model'=>'Aastra57i', 'mac'=>'00085D'.$fake_mac_suffix, 'firmware'=>'2.5.3.26', 'ip'=>getvar_safe('REMOTE_ADDR','','SERVER'), 'language'=>'en', 'rp'=>False ); return($array); } # User Agent $user_agent=getvar_safe('HTTP_USER_AGENT','','SERVER'); if(stristr($user_agent,'Aastra')) { $value=preg_split('/ MAC:/',$user_agent); $fin=preg_split('/ /',$value[1]); $value[1]=preg_replace('/\-/','',$fin[0]); $value[2]=preg_replace('/V:/','',$fin[1]); } else { $value[0]='MSIE'; $value[1]='NA'; $value[2]='NA'; } # Modification for RP phones $rp=False; if(strstr($value[0],'RP')) { $rp=True; $value[0]=preg_replace(array('/67/','/ RP/'),array('',''),$value[0]); } # Modules $module[1]=getvar_safe('HTTP_X_AASTRA_EXPMOD1','','SERVER'); $module[2]=getvar_safe('HTTP_X_AASTRA_EXPMOD2','','SERVER'); $module[3]=getvar_safe('HTTP_X_AASTRA_EXPMOD3','','SERVER'); # Create array $array=array('model'=>$value[0],'mac'=>$value[1],'firmware'=>$value[2],'ip'=>getvar_safe('REMOTE_ADDR','','SERVER'),'module'=>$module,'language'=>getvar_safe('HTTP_ACCEPT_LANGUAGE','','SERVER'),'rp'=>$rp); return($array); } function is_square($header=NULL) { # True by default $return=False; # Get header info if needed if(!$header) $header=decode_HTTP_header(); # Test the model switch($header['model']) { case 'Aastra6867i': case 'Aastra6869i': case 'Aastra6873i': $return=True; break; } # Return Result return($return); } function is_white($header=NULL) { # True by default $return=False; # Get header info if needed if(!$header) $header=decode_HTTP_header(); # Test the model switch($header['model']) { case 'Aastra6867i': case 'Aastra6869i': case 'Aastra6873i': $return=True; break; } # Return Result return($return); } function readINIfile ($filename, $commentchar, $delim) { # Get file content with a shared lock to avoid race conditions $array1 = array(); $handle = @fopen($filename, 'r'); if ($handle) { if (flock($handle, LOCK_SH)) { while (!feof($handle)) $array1[] = fgets($handle); flock($handle, LOCK_UN); } fclose($handle); } $section=''; $array2=NULL; foreach($array1 as $filedata) { $dataline=trim($filedata); $firstchar=substr($dataline, 0, 1); if ($firstchar!=$commentchar && $dataline!='') { #It's an entry (not a comment and not a blank line) if ($firstchar == '[' && substr($dataline, -1, 1) == ']') { #It's a section $section = substr($dataline, 1, -1); } else { #It's a key... $delimiter = strpos($dataline, $delim); if ($delimiter > 0) { #...with a value $key = strtolower(trim(substr($dataline, 0, $delimiter))); $value = trim(substr($dataline, $delimiter + 1)); if (substr($value, 1, 1) == '"' && substr($value, -1, 1) == '"') { $value = substr($value, 1, -1); } $array2[$section][$key] = stripcslashes($value); } else { #...without a value $array2[$section][strtolower(trim($dataline))]=''; } } } else { #It's a comment or blank line. Ignore. } } # Return array with data return $array2; } function getImageFromLibrary($library_path, $number) { # 1st check for a .png or .PNG image $filename=$library_path.'/'.$number.'.png'; if(file_exists($filename)) return @imagecreatefrompng($filename); $filename = $library_path.'/'.$number.'.PNG'; if(file_exists($filename)) return @imagecreatefrompng($filename); # 2nd check for a .jpg or .JPG image $filename = $library_path.'/'.$number.'.jpg'; if (file_exists($filename)) return @imagecreatefromjpeg($filename); $filename = $library_path.'/'.$number.'.JPG'; if (file_exists($filename)) return @imagecreatefromjpeg($filename); $filename = $library_path.'/'.$number.'.jpeg'; if (file_exists($filename)) return @imagecreatefromjpeg($filename); $filename = $library_path.'/'.$number.'.JPEG'; if (file_exists($filename)) return @imagecreatefromjpeg($filename); # 3rd check for a .gif or .GIF image $filename = $library_path.'/'.$number.'.gif'; if (file_exists($filename)) return @imagecreatefromgif($filename); $filename = $library_path.'/'.$number.'.GIF'; if (file_exists($filename)) return @imagecreatefromgif($filename); # No match return null; } function scaleImage($im, $blowup) { Global $SQUARE; Global $WHITE; # Image size depends on the target if($SQUARE) { $target_width=200; $target_height=200; } else { $target_width=150; $target_height=200; } # Create emtpy output image. use true color to avoid color palette problems $im_output = imagecreatetruecolor($target_width, $target_height); # White background if needed if($WHITE) { $white = imagecolorallocate($im_output, 255, 255, 255); imagefill($im_output, 0, 0, $white); } # Get size of input image $im_width=imagesx($im); $im_height=imagesy($im); # Check if image is smaller than requested size and if "blow up" of images is disabled if(($im_width < $target_width) && ($im_height < $target_height) && !$blowup) { # Simply copy the image in the center of the output image. no scaling. imagecopy($im_output, $im, (($target_width-$im_width)/2) ,(($target_width-$im_height)/2), 0, 0, $im_width, $im_height); } else { if($SQUARE) { # Check aspect ratio of source image if ($im_width / $im_height <= 1) { # "Portrait" image. scale to 200 pixel height and center horizontally $new_im_width = $im_width * ($target_height / $im_height); imagecopyresized($im_output, $im, (($target_width-$new_im_width)/2), 0, 0, 0, $new_im_width, $target_height, $im_width, $im_height); } else { # "Landscape" image. scale to 200 pixel width and center vertically $new_im_height = $im_height * ($target_width / $im_width); imagecopyresized($im_output, $im, 0, (($target_width-$new_im_height)/2), 0, 0, $target_width, $new_im_height, $im_width, $im_height); } } else { # Check aspect ratio of source image if ($im_width / $im_height <= 0.75) { # "Portrait" image. scale to 200 pixel height and center horizontally $new_im_width = $im_width * ($target_height / $im_height); imagecopyresized($im_output, $im, (($target_width-$new_im_width)/2), 0, 0, 0, $new_im_width, $target_height, $im_width, $im_height); } else { # "Landscape" image. scale to 150 pixel width and center vertically $new_im_height = $im_height * ($target_width / $im_width); imagecopyresized($im_output, $im, 0, (($target_height-$new_im_height)/2), 0, 0, $target_width, $new_im_height, $im_width, $im_height); } } } # Return new image return($im_output); } function customImage($im,$complement) { Global $SQUARE; # Image size depends on the target if($SQUARE) { $target_width=200; $target_height=200; } else { $target_width=150; $target_height=200; } # Define the font if(strpos(strtolower(PHP_OS), 'win') === false) $font='fonts/DejaVuSans-Bold'; else $font=realpath('./fonts/').'\\DejaVuSans-Bold.ttf'; # Split complement $array_complement=explode('|',$complement); # Label is 0 $array_complement[0]=str_replace("\"",'',$array_complement[0]); # Y position is 1 if(($array_complement[1]>0) and ($array_complement[1]<200)) $y=$array_complement[1]; else $y=100; # Font Size is 4 (default 10) if(($array_complement[4]>=8) and ($array_complement[4]<=24)) $size=$array_complement[4]; else $size=10; # Alignment is 2 switch($array_complement[2]) { case 'left': $x=10; break; case 'right': $array_text=imagettfbbox($size,0,$font,$array_complement[0]); $width=$array_text[4]-$array_text[6]; $x=$target_width-10-$width; break; default: $array_text=imagettfbbox($size,0,$font,$array_complement[0]); $width=$array_text[4]-$array_text[6]; $x=intval(($target_width-$width)/2); break; } # Color is 3 switch($array_complement[3]) { case 'yellow': $color=imagecolorallocate($im,0xFF,0xFF,0); break; case 'orange': $color=imagecolorallocate($im,0xFF,0xA5,0); break; case 'pink': $color=imagecolorallocate($im,0xFF,0xC0,0xCB); break; case 'purple': $color=imagecolorallocate($im,0xA0,0x20,0xF0); break; case 'black': $color=imagecolorallocate($im,0,0,0); break; case 'grey': $color=imagecolorallocate($im,0xBE,0xBE,0xBE); break; case 'red': $color=imagecolorallocate($im,0xFF,0,0); break; case 'brown': $color=imagecolorallocate($im,0xA5,0x2A,0x2A); break; case 'tan': $color=imagecolorallocate($im,0xD2,0xB4,0x8C); break; case 'magenta': $color=imagecolorallocate($im,0xFF,0,0xFF); break; case 'blue': $color=imagecolorallocate($im,0,0,0xFF); break; case 'green': $color=imagecolorallocate($im,0,0xFF,0); break; default: $color=imagecolorallocate($im,0xFF,0xFF,0xFF); break; } # Display text imagettftext($im,$size,0,$x,$y,$color,$font,$array_complement[0]); # Return customized image return($im); } function send404() { Global $DEFAULT_IMAGE; $send=True; # Default image if($DEFAULT_IMAGE[0]!='') { if(check_number($DEFAULT_IMAGE[0],$DEFAULT_IMAGE[1])) $send=False; } # Send 404 if($send) { # Send an HTTP 404 header('HTTP/1.0 404 Not Found'); print('

HTTP 404 - Image Not Found

'); } } function check_number($number,$complement='') { Global $CACHE_DIR; Global $PICTURES_DIR; Global $BLOWUP; # Not found by default $return=False; # Look in the cache directory $filename=$CACHE_DIR.'/'.$number.'.png'; if(file_exists($filename)) { # Retrieve image $im=@imagecreatefrompng($filename); # Modify image if needed if($complement!='') $im=customImage($im,$complement); # Send image in the HTTP response header ('Content-type: image/png'); imagepng($im); # Destroy image imagedestroy($im); # Found $return=True; } # Not found if(!$return) { # Look in the cache $im=getImageFromLibrary($PICTURES_DIR,$number); # Image found if(!empty($im)) { # Found $return=True; # Scale image to the right size $im=scaleImage($im,$BLOWUP); # Save image to cache directory. use same number in filename as in original file in the library. $filename = $CACHE_DIR.'/'.$number.'.png'; @imagepng($im,$filename); # Modify image if needed if($complement!='') $im=customImage($im,$complement); # Send image in the HTTP response header ('Content-type: image/png'); imagepng($im); # Destroy image imagedestroy($im); } } # Return result return($return); } function remove_prefix($number,$dialplan,$type) { # Depending on type switch($type) { # Local prefix case 'local': # Remove local prefixes $local_prefixes_array=explode(',',$dialplan['local']); # At least one prefix if(is_array($local_prefixes_array)) { # Check each prefix foreach($local_prefixes_array as $prefix) { # Empty prefix skip $prefix=trim($prefix); if($prefix=='') continue; # Number starts with prefix if(strpos($number,$prefix)===0) { # Remove prefix $number=str_replace($prefix,'',$number); break; } # Number starts with "external prefix + prefix" if(strpos($number,$external_prefix.$prefix)===0) { # Remove prefix $number=str_replace($dialplan['outgoing'].$prefix,'',$number); break; } } } break; # External case 'external': # Remove external prefix if(isset($dialplan['outgoing'])) { # External prefix if (strpos($number,$dialplan['outgoing'])===0) { # Remove prefix $number=substr($number,strlen($dialplan['outgoing'])); } } break; # International case 'international': # Remove external/international prefix if(isset($dialplan['international'])) { # External prefix if(strpos($number,$dialplan['outgoing'].$dialplan['international'])===0) { # Remove prefix $number=substr($number,strlen($dialplan['outgoing'].$dialplan['international'])); } } break; } # Return transformed number return($number); } function transform_mapping($number,$dialplan,$array_mapping,$type) { # Not found yet $found=False; $complement=''; # Check if number is in mapping file. if(count($array_mapping)>0) { # Local variables $len_outgoing=strlen($dialplan['outgoing']); $len_international=strlen($dialplan['international']); # Process each entry foreach($array_mapping as $keys=>$values) { # Get all entries $array_keys=explode(',',$keys); # Get number $array_values=explode(',',$values,2); $value=$array_values[0]; # Process all entries foreach($array_keys as $key) { # Not a prefix if(substr($key,0,1)!='p') { # Return mapped number as found in mapping file. if($type=='1') { if (($number == $key) || ($number == $dialplan['outgoing'].$key) || ($number == $dialplan['outgoing'].$dialplan['international'].$key) || ($number == $dialplan['international'].$key)) { $found=True; $number=$value; $complement=$array_values[1]; break; } } } else { # Return mapped number as found in mapping file. if($type=='2') { # Remove the P $compare=substr($key,1); $array_pattern=array(); $array_pattern[]=$compare; if(!in_array($dialplan['outgoing'].$compare,$array_pattern)) $array_pattern[]=$dialplan['outgoing'].$compare; if(!in_array($dialplan['outgoing'].$dialplan['international'].$compare,$array_pattern)) $array_pattern[]=$dialplan['outgoing'].$dialplan['international'].$compare; if(!in_array($dialplan['international'].$compare,$array_pattern))$array_pattern[]=$dialplan['international'].$compare; # Return mapped number as found in mapping file. if (check_pattern($number,$array_pattern)) { $found=True; $number=$value; $complement=$array_values[1]; break; } } } # Break the loop if found if($found) break; } } } # Return mapping number return(array($number,$complement)); } function check_pattern($number,$patterns) { # Not found by default $found=False; # Process each pattern foreach($patterns as $pattern) { # Valid by default $valid=True; # Store lengths $len_pattern=strlen($pattern); $len_number=strlen($number); # Check if unlimted string if(strstr($pattern,'.')) { $explode=explode('.',$pattern); $pattern=$explode[0].'.'; $test=True; } else $test=($len_pattern==$len_number); # Do the test if($test and $valid) { for($i=0;($i<$len_pattern) and $valid;$i++) { switch($pattern[$i]) { case 'x': if(($number[$i]<0) or ($number[$i]>9)) $valid=False; break; case 'z': if(($number[$i]<1) or ($number[$i]>9)) $valid=False; break; case 'n': if(($number[$i]<2) or ($number[$i]>9)) $valid=False; break; case '.': $i=$len_pattern; break; default: if($number[$i]!=$pattern[$i]) $valid=False; break; } } } else $valid=False; if($valid) { $found=True; break; } } # Return result; return($found); } ############################################################################# # Body ############################################################################# # Variables $found=False; # Script was called with query string ?number=xxxx $number_original=preg_replace('/[^0-9]/','',$_GET['number']); # Script was called with query string ?/xxxx.png or similar match xxxx.png pattern in the query string if(empty($number_original)) { if(preg_match('/([0-9*#]+)\.png/',$_SERVER['QUERY_STRING'],$matches)) $number_original = $matches[1]; } # Retrieve image format and color $SQUARE=is_square(); $WHITE=is_white(); # No number if(empty($number_original)) { # Send a 404 and exit send404(); exit; } # Retrieve directory configuration $array_config=readINIfile('pictureID.conf','#','='); # Absolute or relative path to the cache directory. Must be writable by the Web server. if($array_config['General']['cache']!='') $CACHE_DIR=$array_config['General']['cache']; else $CACHE_DIR='cache'; # Absolute or relative path to the picture library directory. This is read-only. if($array_config['General']['pictures']!='') $PICTURES_DIR=$array_config['General']['pictures']; else $PICTURES_DIR='pictures'; # Rescale image smaller than expected size $BLOWUP=False; if($array_config['General']['blowup']=='1') $BLOWUP=True; # Default image $DEFAULT_IMAGE=array(); if($array_config['General']['default']!='') $DEFAULT_IMAGE=explode(',',$array_config['General']['default']); # Check original number if(!$found) $found=check_number($number_original); # Remove local prefixes if(!$found) { $number_transformed=remove_prefix($number_original,$array_config['Dialplan'],'local'); if($number_transformed!=$number_original) $found=check_number($number_transformed); } # Check basic mapping if(!$found) { $array_number=transform_mapping($number_original,$array_config['Dialplan'],$array_config['Numbers'],'1'); if($array_number[0]!=$number_original) $found=check_number($array_number[0],$array_number[1]); } # Check advanced mapping if(!$found) { $array_number=transform_mapping($number_original,$array_config['Dialplan'],$array_config['Numbers'],'2'); if($array_number[0]!=$number_original) $found=check_number($array_number[0],$array_number[1]); } # Remove external prefix if(!$found) { $number_transformed=remove_prefix($number_original,$array_config['Dialplan'],'external'); if($number_transformed!=$number_original) $found=check_number($number_transformed); } # Remove international prefix if(!$found) { $number_transformed=remove_prefix($number_original,$array_config['Dialplan'],'international'); if($number_transformed!=$number_original) $found=check_number($number_transformed); } # No number if(!$found) { # Send a 404 send404(); } # Clean exit exit; ?>