'._("Failed to create").' '.$astsnd.'custom'.'
'; + } + } else { + // can't rename a file from one partition to another, must use mv or cp + // rename($recordings_save_path."{$dest}ivrrecording.wav",$recordings_astsnd_path."custom/{$filename}.wav"); + if (!file_exists($recordings_save_path."{$dest}ivrrecording.$suffix")) { + echo ""._("[ERROR] The Recorded File Does Not exists:")."
"; + echo $recordings_save_path."{$dest}ivrrecording.$suffix"; + echo "make sure you uploaded or recorded a file with the entered extension
"; + } else { + exec("cp " . $recordings_save_path . "{$dest}ivrrecording.$suffix " . $astsnd."custom/{$filename}.$suffix 2>&1", $outarray, $ret); + if (!$ret) { + $isok = recordings_add($rname, "custom/{$filename}.$suffix"); + } else { + echo "
"._("[ERROR] SAVING RECORDING:")."
"; + foreach ($outarray as $line) { + echo "$line"; + } + echo _("Make sure you have entered a proper name"); + echo "
"; + } + exec("rm " . $recordings_save_path . "{$dest}ivrrecording.$suffix ", $outarray, $ret); + if ($ret) { + echo "
"._("[ERROR] REMOVING TEMPORARY RECORDING:")."
"; + foreach ($outarray as $line) { + echo "$line"; + } + echo _("Make sure Asterisk is not running as root "); + echo "
"; + } + } + + recording_sidebar(null, $usersnum); + recording_addpage($usersnum); + if ($isok) + echo '
'._("System Recording").' "'.$rname.'" '._("Saved").'!
'; + } + break; + + case "edit": + $arr = recordings_get($id); + $filename=$arr['filename']; + // Check all possibilities of uploaded file types. + $valid = Array("au","g723","g723sf","g729","gsm","h263","ilbc","mp3","ogg","pcm","alaw","ulaw","al","ul","mu","sln","raw","vox","WAV","wav","wav49"); + $fileexists = false; + if (strpos($filename, '&') === false) { + foreach ($valid as $xtn) { + $checkfile = $recordings_astsnd_path.$filename.".".$xtn; + if (file_exists($checkfile)) { + $suffix = substr(strrchr($filename, "."), 1); + copy($checkfile, $recordings_save_path."{$dest}ivrrecording.".$suffix); + $fileexists = true; + } + } + if ($fileexists === false) { + echo ''._("Unable to locate").' '.$recordings_astsnd_path.$filename.' '._("with a a valid suffix").'
'; + } + } + + recording_sidebar($id, $usersnum); + recording_editpage($id, $usersnum); + break; + + case "edited": + recordings_update($id, $rname, $notes, $_REQUEST, $fcode, $fcode_pass); + recording_sidebar($id, $usersnum); + recording_editpage($id, $usersnum); + echo ''._("System Recording").' "'.$rname.'" '._("Updated").'!
Error reading Recording ID $id - Aborting
".$label.""; + } + } else { + $delURL = "config.php?display=recordings&action=delete&usersnum=".urlencode($num)."&id=$id"; + $tlabel = _("Remove Recording"); + $label = '
-
+
- +
- +"; + echo ""; + $dispname = $tresult[1]; + while (strlen($dispname) > (1+$wrapat)) { + $part = substr($dispname, 0, $wrapat); + echo htmlspecialchars($part); + $dispname = substr($dispname, $wrapat); + if ($dispname != '') + echo "
"; + } + echo htmlspecialchars($dispname); + echo ""; + echo "\n"; + } + } + echo "

Unable to add ".$recordings_astsnd_path.$filename." - Can not read file!
"; + return false; + } + $fname = preg_replace("/\.(au|g723|g723sf|g726-\d\d|g729|gsm|h263|ilbc|mp3|ogg|pcm|[au]law|[au]l|mu|sln|raw|vox|WAV|wav|wav49)$/", "", $filename); + + } else { + $fname = $filename; + } + $description = ($description != '') ? $db->escapeSimple($description) : _("No long description available"); + $displayname = $db->escapeSimple($displayname); + sql("INSERT INTO recordings (displayname, filename, description) VALUES ( '$displayname', '$fname', '$description')"); + + return true; + +} + +function recordings_update($id, $rname, $descr, $_REQUEST, $fcode=0, $fcode_pass='') { + global $db; + + // Update the descriptive fields + $fcode_pass = preg_replace("/[^0-9*]/" ,"", trim($fcode_pass)); + $results = sql("UPDATE recordings SET displayname = '".$db->escapeSimple($rname)."', description = '".$db->escapeSimple($descr)."', fcode='$fcode', fcode_pass='".$fcode_pass."' WHERE id = '$id'"); + + // Build the file list from _REQUEST + $astsnd = isset($asterisk_conf['astvarlibdir'])?$asterisk_conf['astvarlibdir']:'/var/lib/asterisk'; + $astsnd .= "/sounds/"; + $recordings = Array(); + + // Set the file names from the submitted page, sysrec[N] + // We don't set if feature code was selected, we use what was already there + // because the fields will have been disabled and won't be accessible in the + // $_REQUEST array anyhow + // + if ($fcode != 1) { + // delete the feature code if it existed + // + $fcc = new featurecode('recordings', 'edit-recording-'.$id); + $fcc->delete(); + unset($fcc); + foreach ($_REQUEST as $key => $val) { + $res = strpos($key, 'sysrec'); + if ($res !== false) { + // strip out any relative paths, since this is coming from a URL + str_replace('..','',$val); + + $recordings[substr($key,6)]=$val; + } + } + + // Stick the filename in the database + recordings_set_file($id, implode('&', $recordings)); + } else { + // Add the feature code if it is needed + // + $fcc = new featurecode('recordings', 'edit-recording-'.$id); + $fcc->setDescription("Edit Recording: $rname"); + $fcc->setDefault('*29'.$id); + $fcc->setProvideDest(); + $fcc->update(); + unset($fcc); + } + + // In _REQUEST there are also various actions (possibly) + // up[N] - Move file id N up one place + // down[N] - Move fid N down one place + // del[N] - Delete fid N + + foreach ($_REQUEST as $key => $val) { + if (strpos($key,"_") == 0) { + $up = strpos($key, "up"); + + $down = strpos($key, "down"); + $del = strpos($key, "del"); + } + if ( $up !== false ) { + $up = substr($key, 2); + recordings_move_file_up($id, $up); + } + if ($del !== false ) { + $del = substr($key,3); + recordings_delete_file($id, $del); + } + if ($down !== false ) { + $down = substr($key,4); + recordings_move_file_down($id, $down); + } + } +} + +function recordings_move_file_up($id, $src) { + $files = recordings_get_file($id); + if ($src === 0 || $src < 0) { return false; } // Should never happen, up shouldn't appear whten fid=0 + $tmparr = explode('&', $files); + $tmp = $tmparr[$src-1]; + $tmparr[$src-1] = $tmparr[$src]; + $tmparr[$src] = $tmp; + recordings_set_file($id, implode('&', $tmparr)); +} +function recordings_move_file_down($id, $src) { + $files = recordings_get_file($id); + $tmparr = explode('&', $files); + $tmp = $tmparr[$src+1]; + $tmparr[$src+1] = $tmparr[$src]; + $tmparr[$src] = $tmp; + recordings_set_file($id, implode('&', $tmparr)); +} +function recordings_delete_file($id, $src) { + $files = recordings_get_file($id); + $tmparr = explode('&', $files); + $tmp = Array(); + $counter = 0; + foreach ($tmparr as $file) { + if ($counter != $src) { $tmp[] = $file; } + $counter++; + } + recordings_set_file($id, implode('&', $tmp)); +} + + +function recordings_del($id) { + $results = sql("DELETE FROM recordings WHERE id = \"$id\""); + + // delete the feature code if it existed + $fcc = new featurecode('recordings', 'edit-recording-'.$id); + $fcc->delete(); + unset($fcc); +} + +function recordings_set_file($id, $filename) { + global $db; + // Strip off any dangling &'s on the end: + $filename = rtrim($filename, '&'); + $results = sql("UPDATE recordings SET filename = '".$db->escapeSimple($filename)."' WHERE id = '$id'"); +} + + + +function recordings_readdir($snddir) { + $files = recordings_getdir($snddir); + $ptr = 0; + foreach ($files as $fnam) { + $files[$ptr] = substr($fnam, strlen($snddir)+1); + $ptr++; + } + // Strip off every possible file extension + $flist = preg_replace("/\.(au|g723|g723sf|g726-\d\d|g729|gsm|h263|ilbc|mp3|ogg|pcm|[au]law|[au]l|mu|sln|raw|vox|WAV|wav|wav49)$/", "", $files); + sort($flist); + return array_unique($flist); +} + +function recordings_getdir($snddir) { + $dir = opendir($snddir); + $files = Array(); + while ($fn = readdir($dir)) { + if ($fn == '.' || $fn == '..') { continue; } + if (is_dir($snddir.'/'.$fn)) { + $files = array_merge(recordings_getdir($snddir.'/'.$fn), $files); + continue; + } + $files[] = $snddir.'/'.$fn; + } + return $files; +} + +function recordings_list_usage($id) { + global $active_modules; + $full_usage_arr = array(); + + foreach(array_keys($active_modules) as $mod) { + $function = $mod."_recordings_usage"; + if (function_exists($function)) { + if (isset($_COOKIE['lang']) && is_dir("./modules/$mod/i18n/".$_COOKIE['lang'])) { + $prev_domain = textdomain(NULL); + bindtextdomain($mod,"./modules/$mod/i18n"); + bind_textdomain_codeset($mod, 'utf8'); + textdomain($mod); + $recordings_usage = $function($id); + textdomain($prev_domain); + } else { + $recordings_usage = $function($id); + } + if (!empty($recordings_usage)) { + $full_usage_arr = array_merge($full_usage_arr, $recordings_usage); + } + } + } + return $full_usage_arr; +} + +?> Index: /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/audio.php =================================================================== --- /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/audio.php (revision 6404) +++ /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/audio.php (revision 6404) @@ -0,0 +1,53 @@ +decrypt($opath,$REC_CRYPT_PASSWORD); + + // Gather relevent info about file + $size = filesize($path); + $name = basename($path); + $extension = strtolower(substr(strrchr($name,"."),1)); + + // This will set the Content-Type to the appropriate setting for the file + $ctype =''; + switch( $extension ) { + case "mp3": $ctype="audio/mpeg"; break; + case "wav": $ctype="audio/x-wav"; break; + case "Wav": $ctype="audio/x-wav"; break; + case "WAV": $ctype="audio/x-wav"; break; + case "gsm": $ctype="audio/x-gsm"; break; + + // not downloadable + default: die_freepbx("404 File not found! foo"); break ; + } + + // need to check if file is mislabeled or a liar. + $fp=fopen($path, "rb"); + if ($size && $ctype && $fp) { + header("Pragma: public"); + header("Expires: 0"); + header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); + header("Cache-Control: public"); + header("Content-Description: wav file"); + header("Content-Type: " . $ctype); + header("Content-Disposition: attachment; filename=" . $name); + header("Content-Transfer-Encoding: binary"); + header("Content-length: " . $size); + fpassthru($fp); + } +} + +?> Index: /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/crypt.php =================================================================== --- /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/crypt.php (revision 6417) +++ /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/crypt.php (revision 6417) @@ -0,0 +1,81 @@ + 0) { + $iv .= chr(mt_rand() & 0xff); + } + return $iv; + } + + /** + * Encrypts string + * - From php.net docs + * + * @param $str + * string to encrypt + * @param $salt + * password to use for encryption + * @param $iv_len + * length of random number + */ + function encrypt($str, $salt, $iv_len = 16) { + + $str .= "\x13"; + $n = strlen($str); + if ($n % 16) $str .= str_repeat("\0", 16 - ($n % 16)); + $i = 0; + $enc_text = $this->getRndIV($iv_len); + $iv = substr($salt ^ $enc_text, 0, 512); + while ($i < $n) { + $block = substr($str, $i, 16) ^ pack('H*', md5($iv)); + $enc_text .= $block; + $iv = substr($block . $iv, 0, 512) ^ $salt; + $i += 16; + } + return base64_encode($enc_text); + } + + /** + * Decrypts string + * - From php.net docs + * + * @param $enc + * encrypted string to decrypt + * @param $salt + * password to use for encryption + * @param $iv_len + * length of random number + */ + function decrypt($enc, $salt, $iv_len = 16) { + + $enc = base64_decode($enc); + $n = strlen($enc); + $i = $iv_len; + $str = ''; + $iv = substr($salt ^ substr($enc, 0, $iv_len), 0, 512); + while ($i < $n) { + $block = substr($enc, $i, 16); + $str .= $block ^ pack('H*', md5($iv)); + $iv = substr($block . $iv, 0, 512) ^ $salt; + $i += 16; + } + return preg_replace('/\\x13\\x00*$/', '', $str); + } +} + + +?> Index: /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/popup.php =================================================================== --- /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/popup.php (revision 6479) +++ /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/popup.php (revision 6479) @@ -0,0 +1,62 @@ + + + + + +".sprintf(_("No compatible wav, mp3 or gsm format found to play:
%s"),$ufile)."
"); + exit; + } + + $file = urlencode($crypt->encrypt($path,$REC_CRYPT_PASSWORD)); + + if (isset($file)) { + echo("
"); + echo("
"); + echo("
playing: $ufile
"); + } +?> + + + Index: /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/install.php =================================================================== --- /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/install.php (revision 11664) +++ /freepbx/tags/2.10.0beta1/amp_conf/htdocs/admin/modules/recordings/install.php (revision 11664) @@ -0,0 +1,140 @@ +setDescription('Save Recording'); +$fcc->setDefault('*77'); +$fcc->update(); +unset($fcc); + +$fcc = new featurecode('recordings', 'record_check'); +$fcc->setDescription('Check Recording'); +$fcc->setDefault('*99'); +$fcc->update(); +unset($fcc); + +// Make sure table exists +if ($amp_conf["AMPDBENGINE"] == 'sqlite3') { + $sql = "CREATE TABLE IF NOT EXISTS recordings ( + `id` integer NOT NULL PRIMARY KEY AUTOINCREMENT, + displayname VARCHAR(50) , filename BLOB, description + VARCHAR(254)) + ;"; +} else { + $sql = "CREATE TABLE IF NOT EXISTS recordings ( + id INTEGER NOT NULL PRIMARY KEY $autoincrement, + displayname VARCHAR(50) , + filename BLOB, + description VARCHAR(254)) + ;"; +} +$result = $db->query($sql); +if(DB::IsError($result)) { + die_freepbx($result->getDebugInfo()); +} + +// load up any recordings that might be in the directory +$recordings_directory = $recordings_astsnd_path."custom/"; + +if (!file_exists($recordings_directory)) { + mkdir ($recordings_directory); +} +if (!is_writable($recordings_directory)) { + print "
Error
I can not access the directory $recordings_directory. "; + print "Please make sure that it exists, and is writable by the web server."; + return false; +} +$sql = "SELECT * FROM recordings where displayname = '__invalid'"; +$results = $db->getRow($sql, DB_FETCHMODE_ASSOC); +if (!isset($results['filename'])) { + sql("INSERT INTO recordings (displayname, filename, description) VALUES ( '__invalid', 'install done', '');" ); + $dh = opendir($recordings_directory); + while (false !== ($file = readdir($dh))) { // http://au3.php.net/readdir + if ($file[0] != "." && $file != "CVS" && $file != "svn" && !is_dir("$recordings_directory/$file")) { + // Ignore the suffix.. + $fname = str_replace(array('.wav','.gsm'), array('',''), $file); + if (recordings_get_id("custom/$fname") == null) + recordings_add($fname, "custom/$file"); + } + } +} + +global $db; + +// Upgrade to recordings 3.0 +// Change filename from VARCHAR(80) to BLOB +// Upgrade to recordings 3.0 +// Change filename from VARCHAR(80) to BLOB +// no need to add this if we are on sqlite, since the initial tables will +// include the correct columns already. +if (($amp_conf["AMPDBENGINE"] != "sqlite") && ($amp_conf["AMPDBENGINE"] != "sqlite3")) +{ + $sql = 'ALTER TABLE recordings CHANGE filename filename BLOB'; + $result = $db->query($sql); + if(DB::IsError($result)) { + die($result->getDebugInfo()); + } + } + + // Version 2.5 upgrade + outn(_("checking for fcode field..")); + $sql = "SELECT `fcode` FROM recordings"; + $check = $db->getRow($sql, DB_FETCHMODE_ASSOC); + if(DB::IsError($check)) { + // add new field + $sql = "ALTER TABLE recordings ADD `fcode` TINYINT( 1 ) DEFAULT 0 ;"; + $result = $db->query($sql); + if(DB::IsError($result)) { + die_freepbx($result->getDebugInfo()); + } + out(_("OK")); + } else { + out(_("already exists")); + } + outn(_("checking for fcode_pass field..")); + $sql = "SELECT `fcode_pass` FROM recordings"; + $check = $db->getRow($sql, DB_FETCHMODE_ASSOC); + if(DB::IsError($check)) { + // add new field + $sql = "ALTER TABLE recordings ADD `fcode_pass` VARCHAR( 20 ) NULL ;"; + $result = $db->query($sql); + if(DB::IsError($result)) { + die_freepbx($result->getDebugInfo()); + } + out(_("OK")); + } else { + out(_("already exists")); + } + +$freepbx_conf =& freepbx_conf::create(); + + // AMPPLAYKEY + // + $set['value'] = ''; + $set['defaultval'] =& $set['value']; + $set['readonly'] = 0; + $set['hidden'] = 0; + $set['level'] = 3; + $set['module'] = 'recordings'; + $set['category'] = 'System Setup'; + $set['emptyok'] = 1; + $set['name'] = 'Recordings Crypt Key'; + $set['description'] = 'Crypt key used by this recordings module when accessing the recording files. Change from the default of "moufdsuu3nma0" if desired.'; + $set['type'] = CONF_TYPE_TEXT; + $freepbx_conf->define_conf_setting('AMPPLAYKEY',$set,true); +