Page 1 of 1

symlinkcheck script for making sure the symlinks are correct

Posted: Wed Jul 13, 2005 12:58 am
by cordel
I have been awake way to long and the knogon has shut down I think.
Maybe someone else can catch my error. PHP function->

Code: Select all

function checklinks($path)
{
/*
It will return false if the path is not a dir or if it couldn't open the folder.
It will return an array with the name of the symlinks that for some reason couldn't be created.
It will return true if it was able to create all missing symlinks.

*/
        # Get from the database Monitors that are configured
        $sql = "select Id as MonitorId, Name as MonitorName from Monitors";
        $result = mysql_query( $sql ) or die(mysql_error());
        while($row = mysql_fetch_assoc( $result ))
        {
                $Monitor['id'][] = $row['MonitorId'];
                $Monitor['name'][] = $row['MonitorName'];
        }
        if(!is_dir($path)) return false;
        if(!($dir = opendir( $path ))) return false;
        while (false !== ($file = readdir($dir)))
        {
                #Get the symlinks
                if (is_link($file))
                {
                        $symlinks[] = $file;
                }
        }
        closedir($dir);
        foreach ($symlinks as $key=>$value)
        {
                if(!in_array($value,$Monitor['name']))
                {
                unlink("$path/$value");
                unset($symlinks[$key]);
                }
        }
        $diff = array_diff($Monitor['name'], $symlinks[$key]);
        if(!empty($diff))
        {
                foreach ($diff as $key=>$value)
                {
                        if (!symlink($path.'/'.$Monitor['id'][$key],$value))
                        #if(!symlink("$path/{$Monitor['id'][$key]}",$value))
                        {
                                $symlinks_not_created[] = $value;
                        }
                }
                if(empty($symlinks_not_created))
                {
                        return true;
                }
                else return $symlinks_not_created;
        }
}
Apache Error log wrote:PHP Warning: array_diff(): Argument #2 is not an array in /usr/lib/zm/html/zm_export_funcs.php on line 312, referer: http://192.168.10.20/index.php?view=export&eids[]=92315
I am hoping to have this done and tested by Wednesday night so this can go in the next release. Any input my be useful as I'm drawing a blank.
Cheers,
Cordel

Posted: Wed Jul 13, 2005 5:35 am
by cordel
Okay I have gotton around the above issue

Code: Select all

function checklinks($path)
{
/*
It will return false if the path is not a dir or if it couldn't open the folder.
It will return an array with the name of the symlinks that for some reason couldn't be created.
It will return true if it was able to create all missing symlinks.

*/
$symlinks=$Monitor['id']=$Monitor['name']=array();
        # Get from the database Monitors that are configured
        $sql = "select Id as MonitorId, Name as MonitorName from Monitors";
        $result = mysql_query( $sql ) or die(mysql_error());
        while($row = mysql_fetch_assoc( $result ))
        {
                $Monitor['id'][] = $row['MonitorId'];
                $Monitor['name'][] = $row['MonitorName'];
        }
        if(!is_dir($path)) return false;
        if(!($dir = opendir( $path ))) return false;
        while (false !== ($file = readdir($dir)))
        {
                #Get the symlinks
                if (is_link($file))
                {
                        $symlinks[] = $file;
                }
        }
#       closedir($dir);
        foreach ($symlinks as $key=>$value)
        {
                if(!in_array($value,$Monitor['name']))
                {
                unlink("$path/$value");
                unset($symlinks[$key]);
                }
        }
        $diff = array_diff($Monitor['name'], $symlinks);
        if(!empty($diff))
        {
                foreach ($diff as $key=>$value)
                {
                        #if(!symlink($path.'/'.$Monitor['id'][$key],$value))
                        if(!symlink("$path/{$Monitor['id'][$key]}",$value))
                        {
                                $symlinks_not_created[] = $value;
                        }
                }
                if(empty($symlinks_not_created))
                {
                        return true;
                }
                else return $symlinks_not_created;
        }
        closedir($dir);
}
Now I'm getting
Apache_Error_log wrote:[client 192.168.10.10] PHP Warning: symlink(): Permission denied in /usr/lib/zm/html/zm_export_funcs.php on line 319, referer: http://192.168.10.20/index.php

Posted: Thu Jul 14, 2005 3:12 am
by cordel
Okay, Figured it out and here it is.
The top portion is still broken as it is tring to use a full path I think and not relative to the web root as it needs to be.

Code: Select all

function checklinks($path)
{
/*
It will return false if the path is not a dir or if it couldn't open the folder.
It will return an array with the name of the symlinks that for some reason couldn't be created.
It will return true if it was able to create all missing symlinks.
*/
$symlinks=$Monitor['id']=$Monitor['name']=array();
       # Get from the database Monitors that are configured
       $sql = "select Id as MonitorId, Name as MonitorName from Monitors";
       $result = mysql_query( $sql ) or die(mysql_error());
       while($row = mysql_fetch_assoc( $result ))
       {
               $Monitor['id'][] = $row['MonitorId'];
               $Monitor['name'][] = $row['MonitorName'];
       }
       if(!is_dir($path)) return false;
       if(!($dir = opendir( $path ))) return false;
       while (false !== ($file = readdir($dir)))
       {
               #Get the symlinks
               if (is_link($file))
               {
                       $symlinks[] = $file;
               }
       }
       closedir($dir);
       foreach ($symlinks as $key=>$value)
       {
               if(!in_array($value,$Monitor['name']))
               {
               chdir( $path );
               unlink("$value");
               unset($symlinks[$key]);
               chdir( ".." );
               }
       }
       $diff = array_diff($Monitor['name'], $symlinks);
       if(!empty($diff))
       {
               foreach ($diff as $key=>$value)
               {
                       chdir( $path );
                       if(!symlink($Monitor['id'][$key],$value))
                       #if(!symlink("{$Monitor['id'][$key]}",$value))
                       {
                               $symlinks_not_created[] = $value;
                       }
               chdir( ".." );
               }
               if(empty($symlinks_not_created))
               {
                       return true;
               }
               else return $symlinks_not_created;
       }
}

Posted: Thu Jul 14, 2005 9:09 pm
by cordel
Here it is tested and working. Expect this in the next RPM 1.21.3-1

Code: Select all

function checklinks($path)
{
/*
It will return false if the path is not a dir or if it couldn't open the folder.
It will return an array with the name of the symlinks that for some reason couldn't be created.
It will return true if it was able to create all missing symlinks.
*/
$symlinks=$Monitor['id']=$Monitor['name']=array();
        # Get from the database Monitors that are configured
        $sql = "select Id as MonitorId, Name as MonitorName from Monitors";
        $result = mysql_query( $sql ) or die(mysql_error());
        while($row = mysql_fetch_assoc( $result ))
        {
                $Monitor['id'][] = $row['MonitorId'];
                $Monitor['name'][] = $row['MonitorName'];
        }
        # Get the symlinks currently in the directory
        if(!is_dir($path)) return false;
        chdir( $path );
        if(!($dir = opendir( '.' ))) return false;
        while (false !== ($file = readdir()))
        {
                #Get the symlinks
                if (is_link($file))
                {
                        $symlinks[] = $file;
                }
        }
        chdir( ".." );
        # Look for bad links and remove.
        foreach ($symlinks as $key=>$value)
        {
                if(!in_array($value,$Monitor['name']))
                {
                chdir( $path );
                unlink("$value");
                unset($symlinks[$key]);
                chdir( ".." );
                }
        }
        $diff = array_diff($Monitor['name'], $symlinks);
        if(!empty($diff))
        {
                foreach ($diff as $key=>$value)
                {
                        chdir( $path );
                        if(!symlink($Monitor['id'][$key],$value))
                        #if(!symlink("{$Monitor['id'][$key]}",$value))
                        {
                                $symlinks_not_created[] = $value;
                        }
                chdir( ".." );
                }
                if(empty($symlinks_not_created))
                {
                        return true;
                }
                else return $symlinks_not_created;
        }
}

Posted: Thu Jul 14, 2005 9:13 pm
by jameswilson
looks absolutly wonderful cordel but whats it for?

Posted: Thu Jul 14, 2005 9:42 pm
by cordel
When the symlinks function broke (at some point in previos version) the links that are used for using the monitor name were not updated when the name changed leaving behind the old and now incorrect link. This script querys the database to see what should exist, removes any rouge links, and creates any missing links :wink:
Since the problem was corrected in the latest 1.21.3 source and 1.21.2-3 rpm any new installs would not have an issue. but for some one that had changes the name of a monitor while it was broken and upgraded it would not be fixed. So this is a sanity check so that we're not up here on the board troubleshooting and walking folks how to fix it, and can spend time moving forward and dealing with other issues :)
Regards,
Cordel

PS This would be my first PHP script so feedback is welcome.

Posted: Thu Jul 14, 2005 9:50 pm
by jameswilson
well done looks great, thats about all i can tell you mate, dont even know what php stands for much less write my first one lol. Well done it will be usefull

James

Posted: Thu Jul 14, 2005 9:53 pm
by cordel
I'm kinda thinking I should have just done it in C and added it to zmfix now :?