+/**
+ * Function to start the session and store the cookie with the session_id as
+ * HttpOnly cookie which means that the cookie isn't accessible by javascript
+ * (IE6 only)
+ * Note that as sqsession_is_active() no longer discriminates as to when
+ * it calls this function, session_start() has to have E_NOTICE suppression
+ * (thus the @ sign).
+ */
+function sqsession_start() {
+ global $base_uri;
+
+ @session_start();
+ $session_id = session_id();
+
+ // session_starts sets the sessionid cookie buth without the httponly var
+ // setting the cookie again sets the httponly cookie attribute
+ sqsetcookie(session_name(),$session_id,false,$base_uri);
+}
+
+
+/**
+ * Set a cookie
+ * @param string $sName The name of the cookie.
+ * @param string $sValue The value of the cookie.
+ * @param int $iExpire The time the cookie expires. This is a Unix timestamp so is in number of seconds since the epoch.
+ * @param string $sPath The path on the server in which the cookie will be available on.
+ * @param string $sDomain The domain that the cookie is available.
+ * @param boolean $bSecure Indicates that the cookie should only be transmitted over a secure HTTPS connection.
+ * @param boolean $bHttpOnly Disallow JS to access the cookie (IE6 only)
+ * @return void
+ */
+function sqsetcookie($sName,$sValue='deleted',$iExpire=0,$sPath="",$sDomain="",$bSecure=false,$bHttpOnly=true) {
+ // if we have a secure connection then limit the cookies to https only.
+ if ($sName && isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) {
+ $bSecure = true;
+ }
+
+ // admin config can override the restriction of secure-only cookies
+ global $only_secure_cookies;
+ if (!$only_secure_cookies)
+ $bSecure = false;
+
+ if (false && check_php_version(5,2)) {
+ // php 5 supports the httponly attribute in setcookie, but because setcookie seems a bit
+ // broken we use the header function for php 5.2 as well. We might change that later.
+ //setcookie($sName,$sValue,(int) $iExpire,$sPath,$sDomain,$bSecure,$bHttpOnly);
+ } else {
+ if (!empty($sDomain)) {
+ // Fix the domain to accept domains with and without 'www.'.
+ if (strtolower(substr($sDomain, 0, 4)) == 'www.') $sDomain = substr($sDomain, 4);
+ $sDomain = '.' . $sDomain;
+
+ // Remove port information.
+ $Port = strpos($sDomain, ':');
+ if ($Port !== false) $sDomain = substr($sDomain, 0, $Port);
+ }
+ if (!$sValue) $sValue = 'deleted';
+ header('Set-Cookie: ' . rawurlencode($sName) . '=' . rawurlencode($sValue)
+ . (empty($iExpire) ? '' : '; expires=' . gmdate('D, d-M-Y H:i:s', $iExpire) . ' GMT')
+ . (empty($sPath) ? '' : '; path=' . $sPath)
+ . (empty($sDomain) ? '' : '; domain=' . $sDomain)
+ . (!$bSecure ? '' : '; secure')
+ . (!$bHttpOnly ? '' : '; HttpOnly'), false);
+ }
+}
+
+/**
+ * session_regenerate_id replacement for PHP < 4.3.2
+ *
+ * This code is borrowed from Gallery, session.php version 1.53.2.1
+ */
+if (!function_exists('session_regenerate_id')) {
+ function make_seed() {
+ list($usec, $sec) = explode(' ', microtime());
+ return (float)$sec + ((float)$usec * 100000);
+ }
+
+ function php_combined_lcg() {
+ mt_srand(make_seed());
+ $tv = gettimeofday();
+ $lcg['s1'] = $tv['sec'] ^ (~$tv['usec']);
+ $lcg['s2'] = mt_rand();
+ $q = (int) ($lcg['s1'] / 53668);
+ $lcg['s1'] = (int) (40014 * ($lcg['s1'] - 53668 * $q) - 12211 * $q);
+ if ($lcg['s1'] < 0) {
+ $lcg['s1'] += 2147483563;
+ }
+ $q = (int) ($lcg['s2'] / 52774);
+ $lcg['s2'] = (int) (40692 * ($lcg['s2'] - 52774 * $q) - 3791 * $q);
+ if ($lcg['s2'] < 0) {
+ $lcg['s2'] += 2147483399;
+ }
+ $z = (int) ($lcg['s1'] - $lcg['s2']);
+ if ($z < 1) {
+ $z += 2147483562;
+ }
+ return $z * 4.656613e-10;
+ }
+
+ function session_regenerate_id() {
+ global $base_uri;
+ $tv = gettimeofday();
+ sqgetGlobalVar('REMOTE_ADDR',$remote_addr,SQ_SERVER);
+ $buf = sprintf("%.15s%ld%ld%0.8f", $remote_addr, $tv['sec'], $tv['usec'], php_combined_lcg() * 10);
+ session_id(md5($buf));
+ if (ini_get('session.use_cookies')) {
+ // at a later stage we use sqsetcookie. At this point just do
+ // what session_regenerate_id would do
+ setcookie(session_name(), session_id(), NULL, $base_uri);
+ }
+ return TRUE;
+ }
+}
+
+
+/**
+ * php_self
+ *
+ * Creates an URL for the page calling this function, using either the PHP global
+ * REQUEST_URI, or the PHP global PHP_SELF with QUERY_STRING added. Before 1.5.1
+ * function was stored in function/strings.php.
+ *
+ * @return string the complete url for this page
+ * @since 1.2.3
+ */
+function php_self () {
+ if ( sqgetGlobalVar('REQUEST_URI', $req_uri, SQ_SERVER) && !empty($req_uri) ) {
+ return $req_uri;
+ }
+
+ if ( sqgetGlobalVar('PHP_SELF', $php_self, SQ_SERVER) && !empty($php_self) ) {
+
+ // need to add query string to end of PHP_SELF to match REQUEST_URI
+ //
+ if ( sqgetGlobalVar('QUERY_STRING', $query_string, SQ_SERVER) && !empty($query_string) ) {
+ $php_self .= '?' . $query_string;
+ }
+
+ return $php_self;
+ }
+
+ return '';
+}
+
+
+/**
+ * Find files and/or directories in a given directory optionally
+ * limited to only those with the given file extension. If the
+ * directory is not found or cannot be opened, no error is generated;
+ * only an empty file list is returned.
+FIXME: do we WANT to throw an error or a notice or... or return FALSE?
+ *
+ * @param string $directory_path The path (relative or absolute)
+ * to the desired directory.
+ * @param mixed $extension The file extension filter - either
+ * an array of desired extension(s),
+ * or a comma-separated list of same
+ * (optional; default is to return
+ * all files (dirs).
+ * @param boolean $return_filenames_only When TRUE, only file/dir names
+ * are returned, otherwise the
+ * $directory_path string is
+ * prepended to each file/dir in
+ * the returned list (optional;
+ * default is filename/dirname only)
+ * @param boolean $include_directories When TRUE, directories are
+ * included (optional; default
+ * DO include directories).
+ * @param boolean $directories_only When TRUE, ONLY directories
+ * are included (optional; default
+ * is to include files too).
+ * @param boolean $separate_files_and_directories When TRUE, files and
+ * directories are returned
+ * in separate lists, so
+ * the return value is
+ * formatted as a two-element
+ * array with the two keys
+ * "FILES" and "DIRECTORIES",
+ * where corresponding values
+ * are lists of either all
+ * files or all directories
+ * (optional; default do not
+ * split up return array).
+ * @param boolean $only_sm When TRUE, a security check will
+ * limit directory access to only
+ * paths within the SquirrelMail
+ * installation currently being used
+ * (optional; default TRUE)
+ *
+ * @return array The requested file/directory list(s).
+ *
+ * @since 1.5.2
+ *
+ */
+function list_files($directory_path, $extensions='', $return_filenames_only=TRUE,
+ $include_directories=TRUE, $directories_only=FALSE,
+ $separate_files_and_directories=FALSE, $only_sm=TRUE) {
+
+ $files = array();
+ $directories = array();
+
+
+ // make sure requested path is under SM_PATH if needed
+ //
+ if ($only_sm) {
+ if (strpos(realpath($directory_path), realpath(SM_PATH)) !== 0) {
+ //plain_error_message(_("Illegal filesystem access was requested"));
+ echo _("Illegal filesystem access was requested");
+ exit;
+ }