Read user home directory from PHP - php

I cannot find a way to get the user's home directory (e.g. /home/jack; whatever ~ in bash points to) in PHP using CGI (suPHP). The $_ENV array is empty, and getenv('HOME') returns nothing.
The reason I want to do this is that in absense of configuration saying otherwise, I want to find variable files used by my application in /home/user/.myappnamehere, as most Linux applications do.
I've built something, but it's not the best; While it works, it assumes a lot about the system (e.g. the presence of /etc/passwd)
$usr = get_current_user();
$passwd = file('/etc/passwd');
$var = false;
foreach ($passwd as $line) {
if (strstr($line, $usr) !== false) {
$parts = explode(':', $line);
$var = realpath($parts[5].'/.report');
break;
}
}

I think you want the result of either:
http://us.php.net/manual/en/function.getmyuid.php or
http://us.php.net/manual/en/function.posix-getuid.php sent to
http://us.php.net/manual/en/function.posix-getpwuid.php

If safemode is disabled, try this one
$homedir = `cd ~ && pwd`;

Related

Accessing Windows Objects with PHP?

I made a tool to organize file content in a specific way. These files are located all over my pc which runs on Windows 7. The tool is made up of two parts: 1 the interface holding a form. 2 the script to do the work.
Instead of having to manually write the full path to a certain directory to the main script, I'd rather have the tool search for it and retrieve it seamlessly. I'm thinking of maybe adding a textfield and a button, in which I can enter the directory's name I'm looking for and after clicking the button, retrieve the directory's full pathname, print it to the same textfield and then pass it along to the program itself.
I've searched for several day for ways to have PHP interact with Windows (maybe with window's search object), but all I've found is very looong documentation on the COM and then on the NET. These however seem to strictly deal with accessing Office objects, since most of the available examples are about Excel or Word objects.
How can I accomplish the functionality I want to add to my interface?
To avoid further confusion, this is the image of the Window's object I'm referring to > Windows Starup Search Field
Use this handy function - just point it to the root of your filesystem and it will return an array with all the matching files - I mean, matched by the regular expression pattern you provide to the function.
// PREG_FIND_RECURSIVE - go into subdirectorys looking for more files
// PREG_FIND_DIRMATCH - return directorys that match the pattern also
// PREG_FIND_DIRONLY - return only directorys that match the pattern (no files)
// PREG_FIND_FULLPATH - search for the pattern in the full path (dir+file)
// PREG_FIND_NEGATE - return files that don't match the pattern
// PREG_FIND_RETURNASSOC - Instead of just returning a plain array of matches,
// return an associative array with file stats
// to use more than one simply seperate them with a | character
define('PREG_FIND_RECURSIVE', 1);
define('PREG_FIND_DIRMATCH', 2);
define('PREG_FIND_FULLPATH', 4);
define('PREG_FIND_NEGATE', 8);
define('PREG_FIND_DIRONLY', 16);
define('PREG_FIND_RETURNASSOC', 32);
function preg_find($pattern, $start_dir='.', $args=NULL)
{
$files_matched = array();
$fh = #opendir($start_dir);
if($fh)
{
while (($file = readdir($fh)) !== false)
{
if (strcmp($file, '.')==0 || strcmp($file, '..')==0) continue;
$filepath = $start_dir . '/' . $file;
if (preg_match($pattern, ($args & PREG_FIND_FULLPATH) ? $filepath : $file))
{
$doadd = is_file($filepath)
|| (is_dir($filepath) && ($args & PREG_FIND_DIRMATCH))
|| (is_dir($filepath) && ($args & PREG_FIND_DIRONLY));
if ($args & PREG_FIND_DIRONLY && $doadd && !is_dir($filepath)) $doadd = false;
if ($args & PREG_FIND_NEGATE) $doadd = !$doadd;
if ($doadd)
{
if ($args & PREG_FIND_RETURNASSOC) // return more than just the filenames
{
$fileres = array();
if (function_exists('stat'))
{
$fileres['stat'] = stat($filepath);
$fileres['du'] = $fileres['stat']['blocks'] * 512;
}
//if (function_exists('fileowner')) $fileres['uid'] = fileowner($filepath);
//if (function_exists('filegroup')) $fileres['gid'] = filegroup($filepath);
//if (function_exists('filetype')) $fileres['filetype'] = filetype($filepath);
//if (function_exists('mime_content_type')) $fileres['mimetype'] = mime_content_type($filepath);
if (function_exists('dirname')) $fileres['dirname'] = dirname($filepath);
if (function_exists('basename')) $fileres['basename'] = basename($filepath);
//if (isset($fileres['uid']) && function_exists('posix_getpwuid ')) $fileres['owner'] = posix_getpwuid ($fileres['uid']);
$files_matched[$filepath] = $fileres;
}
else array_push($files_matched, $filepath);
}
}
if ( is_dir($filepath) && ($args & PREG_FIND_RECURSIVE) ) $files_matched = array_merge($files_matched, preg_find($pattern, $filepath, $args));
}
closedir($fh);
}
return $files_matched;
}
Example usage:
$arr = preg_find('/./','z:\temp');
var_dump($arr);
Example output:
Another example:
$arr = preg_find('/\.tmp$/i','z:\temp',PREG_FIND_RECURSIVE | PREG_FIND_DIRMATCH);
var_dump($arr);
On the first place, thanks to #IVO GELOV for the handy script you generously shared with me.
In cases someone else needs this info.
After much searching, I found out that I only needed to use Tkinter to navigate through directories. It offers a Dialog Box with two methods: one to get the full path to a file and the other to a directory, which was what I needed. The path can be stored in a variable.
Thanks to all for the input.

Warning: Creating default object from empty value in

I have a script which tests the connection speed. When I moved it to another server I got the following warning:
Warning: Creating default object from empty value in /home/speed/public_html/common.php on line 26
Here is an excerpt from my code:
## Read through the config file and assign items to the global $config variable
function ReadConfig($config_file) {
global $config;
$lines = file($config_file);
foreach ($lines as $line_num => $line) {
$line = rtrim(preg_replace("/#.*/","",$line));
if(preg_match("/\[.*\]/", $line, $parts)) {
$section = $parts[0];
$section = preg_replace("/[\[\]]/","",$section);
} elseif (preg_match("/=/",$line)) {
list($var,$value) = split('=',$line);
$var = preg_replace('/ $/','',$var);
$value = preg_replace('/^ +/','',$value);
$config->{$section}->{$var} = $value; # here
}
}
}
I am currently running PHP 5.5, the other server runs a newer version of PHP.
Prefix line 26 with this check:
if (!isset($config->{$section}))
$config->{$section} = new Stdclass;
and it should work without generating warning
#Sjon provides the answer to get rid of the warning, I will just explain why you see the warning now.
Since you moved your code to another server, there is most probably another php ini file and thus, different settings. On your "old" server, you had the errors and warnings most likely switched off so you did not see them, on the "new" server they are switched on by default.
Instead of displaying errors you can log them so you do not see them while browsing:
display_errors(false);
// you definitely wanna log any occurring
log_errors(true);

PHP hidden directories - Windows

I'm attempting to add a feature to our intranet, which will allow users to log onto the intranet, and access documents stored within a Windows network SAN.
At the moment, I've successfully retrieved all the file and folder names within a specified users 'My Documents'.
I'm having difficulty removing hidden files and folders from the array.
At the moment, I can remove all folders and files starting with ..
However on Windows, they're being marked as 'hidden' in the properties. I've googled and found lots of resources about how to mark a file as hidden, and how to hide files that start with a ., but none on how to remove hidden windows files / folders. One post on stackoverflow mentions to use DirectoryIterator, but at the moment, but haven't explained at all how to use it to check if a files marked as hidden.
We have over 1000 users, with approximately 500MB - 1GB of documents, with multiple layers of directories, so It needs to be relatively fast.
For clarification:
During a recursive iteration on a Windows system, how can I find out whether a directory is hidden or not, without relying on a prepended . symbol?
Ok, so worked it out, with help from the exec() function, so use with care!
I'm using CodeIgniter, so I've modified the directory_helper.php function slightly, as its installed on a windows box, it'll always need to check for the hidden files, but it should also work for non-codeigniter sites:
function directory_map($source_dir, $directory_depth = 0, $hidden = FALSE)
{
if ($fp = #opendir($source_dir))
{
if(!$hidden)
{
$exclude = array();
exec('dir "' . $source_dir . '" /ah /B', $exclude);
}
$filedata = array();
$new_depth = $directory_depth - 1;
$source_dir = rtrim($source_dir, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
while (FALSE !== ($file = readdir($fp)))
{
// Remove '.', '..', and hidden files [optional]
if ( ! trim($file, '.') OR ($hidden == FALSE && $file[0] == '.') OR ($hidden === FALSE && in_array($file, $exclude)))
{
continue;
}
if (($directory_depth < 1 OR $new_depth > 0) && #is_dir($source_dir.$file))
{
$filedata[$file] = directory_map($source_dir.$file.DIRECTORY_SEPARATOR, $new_depth, $hidden);
}
else
{
$filedata[] = $file;
}
}
closedir($fp);
return $filedata;
}
return FALSE;
}
This scanned 2207 files, and 446 folders in approx 11 seconds (Ages I know, but the best I could do). Tested it on 500 folders and 200 files, and did it in around 3 seconds.
Its a recursive function which will scan each non-hidden directory. The first thing it does is scan the current directory for all hidden files and folders using the exec('dir *directory* /ah /B') function.
It will then store the results in an array and make sure that the current file/directory being read isn't in that array.

Safety on 404 error doc

I am working on my 404 error doc, and I was thinking instead of just giving a sitemap, one could suggest to the user the website he might have looked for based on what actually exists on the server.
Example: if the person typed in "www.example.com/foldr/site.html", the 404 page could output:
Did you mean "www.example.com/folder/site.html"?
For this, I wrote the following code which works for me very well. My question now is: is it "safe" to use this? As basically someone could detect all files on the server by trying all kind of combinations. Or a hacker could even use a script that loops through and lists all types of valid URLs.
Should I limit the directories this script can detect and propose? With an array of "OK"-locations, or by file type?
Had anyone else already got an idea like this?
PHP:
// get incorrect URL that was entered
$script = explode("/",$_SERVER['SCRIPT_NAME']);
$query = $_SERVER['QUERY_STRING'];
// create vars
$match = array();
$matched = "../";
// loop through the given URL folder by folder to find the suggested location
foreach ($script as $dir) {
if (!$dir) {
continue;
}
if ($handle = opendir($matched)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
similar_text($dir, $entry, $perc);
if ($perc > 80) {
$match[$entry] = $perc;
}
}
}
closedir($handle);
if ($match) {
arsort($match);
reset($match);
$matched .= key($match)."/";
} else {
$matched = false;
break;
}
$match = array();
}
}
// trim and echo the result that had the highest match
$matched = trim(ltrim(rtrim($matched,"/"),"."));
echo "proposed URL: ".$_SERVER["SERVER_NAME"].$matched;
Yup, you can see it as this:
Imagine a house with only glass walls on the outside, but it's night. You're a thief (hacker) and you want to check the house for worthfull loot (files with passwords, db connections etc).
If you don't protect (certain) files, you would be putting the lights on in every part of the house. The thief would look through the windows and see that you have loot - now the only the he would have to do is get in and take it.
If you do protect the files, the thief won't even be able to know that there was any loot in the house, and thus would the thief have a higher chance of moving on to the next house.

Small help saving to txt file

Hello there so I just setup this basic poll, I inspired myself from something I found out there, and it's just a basic ajax poll that waves the results in a text file.
Although I was wondering, since I do not want the user to simply mass-click to advantage / disadvantage the results, i thought about adding a new text file that could simply save the IP, one on each line, and then checks if it's already logged, if yes, display the results, if not, show the poll.
My lines of code to save the result are:
<?php
$vote = $_REQUEST['vote'];
$filename = "votes.txt";
$content = file($filename);
$array = explode("-", $content[0]);
$yes = $array[0];
$no = $array[1];
if ($vote == 0)
{
$yes = $yes + 1;
}
if ($vote == 1)
{
$no = $no + 1;
}
$insert = $yes."-".$no;
$fp = fopen($filename,"w");
fputs($fp,$insert);
fclose($fp);
?>
So I'd like to know how I could check out the IPs, in the same way it does basically.
And I'm not interested in database, even for security measures, I'm alright with what Ive got.
Thanks to any help!
To stop multiple votes, I'd set a cookie once a user has voted. If the user reloads the page with the voting form on it and has a cookie, you could show just the results, or a "You have already voted." message. Note that this will not stop craftier people from double-voting - all they would have to do is remove the saved cookie, and they could re-vote.
Keep in mind though that IPs can be shared so your idea of storing IPs might backfire - people on a shared external-facing IP won't be able to vote, as your system will have registered a previous vote from someone at the same IP address.
easiest way is to write data to file is
file_put_contents($filename, $data)
and to read data from file
file_get_contents($filename);
To get IP Address of the user
$_SERVER['REMOTE_ADDR']
See php manual for file_put_contents for more information and file_get_contents
Here is sample code
<?php
// File path
$file = 'votedips.txt';
// Get User's IP Address
$ip = $_SERVER['REMOTE_ADDR'];
// Get data from file (if it exists) or initialize to empty string
$votedIps = file_exists($file) ? file_get_contents($file) : '';
//
$ips = explode("\n", $votedIps);
if (array_search($ip, $ips)) {
// USER VOTED
} else {
$ips[] = $ip;
}
// Write data to file
$data = implode("\n", $ips);
file_put_contents($file, $data);
?>
You can use file_get_contents to save the file's content into a variable and then use the strpos function to check if the IP exists in that variable.
For example:
$ipfile=file_get_contents('ip.txt');
if (strpos($ipfile, $_SERVER['REMOTE_ADDR'])!==FALSE) // show the results
else // show the poll
Be careful with storing IPs in a text file, and then using file_get_contents() and similar functions for loading the data/parseing. As an absolute worst case, assuming that every possible IP address used your system to vote, you'd end up with a text file in the many many gigabytes in size, and you'd exceed PHP's memory_limit very quickly.

Categories