update page now
add a note

User Contributed Notes 4 notes

up
9
mbirth at webwriters dot de
17 years ago
To find out whether a file is hardlinked to another filename, check the number of links of the stat() output. If it is >1 there is another filename for that file.

To find out whether two filenames are pointing to the same file, check the inode number of those 2 filenames. If it is equal, the 2 filenames are hardlinked together.
up
10
PaulE
16 years ago
A workaround for Windows LNK files:

<?php

function _is_link($filename)
{
    if(is_link($filename))
        return true;

    $ext = substr(strrchr($filename, '.'), 1);
    if(strtolower($ext) == 'lnk')
    {
        return (_readlink($filename) ? true : false);
    }

    return false;
}

function _readlink($file)
{
    if(file_exists($file))
    {
        if(is_link($file))
        {
            return readlink($file);
        }

        // Get file content
        $handle = fopen($file, "rb");
        $buffer = array();

        while(!feof($handle))
        {
            $buffer[] = fread($handle, 1);
        }

        fclose($handle);

        // Test magic value and GUID
        if(count($buffer) < 20)
            return false;
        if($buffer[0] != 'L')
            return false;
        if((ord($buffer[4]) != 0x01) ||
           (ord($buffer[5]) != 0x14) ||
           (ord($buffer[6]) != 0x02) ||
           (ord($buffer[7]) != 0x00) ||
           (ord($buffer[8]) != 0x00) ||
           (ord($buffer[9]) != 0x00) ||
           (ord($buffer[10]) != 0x00) ||
           (ord($buffer[11]) != 0x00) ||
           (ord($buffer[12]) != 0xC0) ||
           (ord($buffer[13]) != 0x00) ||
           (ord($buffer[14]) != 0x00) ||
           (ord($buffer[15]) != 0x00) ||
           (ord($buffer[16]) != 0x00) ||
           (ord($buffer[17]) != 0x00) ||
           (ord($buffer[18]) != 0x00) ||
           (ord($buffer[19]) != 0x46))
        {
            return false;
        }

        $i = 20;
        if(count($buffer) < ($i + 4))
            return false;

        $flags = ord($buffer[$i]);
        $flags = $flags | (ord($buffer[++$i]) << 8);
        $flags = $flags | (ord($buffer[++$i]) << 16);
        $flags = $flags | (ord($buffer[++$i]) << 24);

        $hasShellItemIdList = ($flags & 0x00000001) ? true : false;
        $pointsToFileOrDir = ($flags & 0x00000002) ? true : false;

        if(!$pointsToFileOrDir)
            return false;

        if($hasShellItemIdList)
        {
            $i = 76;
            if(count($buffer) < ($i + 2))
                return false;

            $a = ord($buffer[$i]);
            $a = $a | (ord($buffer[++$i]) << 8);
            
        }

        $i = 78 + 4 + $a;
        if(count($buffer) < ($i + 4))
            return false;

        $b = ord($buffer[$i]);
        $b = $b | (ord($buffer[++$i]) << 8);
        $b = $b | (ord($buffer[++$i]) << 16);
        $b = $b | (ord($buffer[++$i]) << 24);

        $i = 78 + $a + $b;
        if(count($buffer) < ($i + 4))
            return false;

        $c = ord($buffer[$i]);
        $c = $c | (ord($buffer[++$i]) << 8);
        $c = $c | (ord($buffer[++$i]) << 16);
        $c = $c | (ord($buffer[++$i]) << 24);

        $i = 78 + $a + $b + $c;
        if(count($buffer) < ($i +1))
            return false;

        $linkedTarget = "";
        for(;$i < count($buffer); ++$i)
        {
            if(!ord($buffer[$i]))
                break;

            $linkedTarget .= $buffer[$i];
        }

        if(empty($linkedTarget))
            return false;

        
        return $linkedTarget;
    }

    return false;
}

if(_is_link('test.lnk'))
{
    echo _readlink('test.lnk');
}
?>
up
1
msaladna at apisnetworks dot com
8 years ago
Careful when using is_link() in thread-safe builds with the self-referential directory entry ".". On ZTS builds is_link("/home/symlink/.") will return true whereas it returns false on non-ZTS builds.
up
2
gggeek
12 years ago
On windows, take care that is_link returns false for Junctions.
Ways of telling apart a directory from a junction include doing both a stat() and and lstat() call and checking if there is any difference in the results
To Top