symlinkcheck script for making sure the symlinks are correct

If you've made a patch to quick fix a bug or to add a new feature not yet in the main tree then post it here so others can try it out.
Post Reply
User avatar
cordel
Posts: 5210
Joined: Fri Mar 05, 2004 4:47 pm
Location: /USA/Washington/Seattle

symlinkcheck script for making sure the symlinks are correct

Post 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
User avatar
cordel
Posts: 5210
Joined: Fri Mar 05, 2004 4:47 pm
Location: /USA/Washington/Seattle

Post 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
User avatar
cordel
Posts: 5210
Joined: Fri Mar 05, 2004 4:47 pm
Location: /USA/Washington/Seattle

Post 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;
       }
}
User avatar
cordel
Posts: 5210
Joined: Fri Mar 05, 2004 4:47 pm
Location: /USA/Washington/Seattle

Post 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;
        }
}
jameswilson
Posts: 5111
Joined: Wed Jun 08, 2005 8:07 pm
Location: Midlands UK

Post by jameswilson »

looks absolutly wonderful cordel but whats it for?
User avatar
cordel
Posts: 5210
Joined: Fri Mar 05, 2004 4:47 pm
Location: /USA/Washington/Seattle

Post 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.
jameswilson
Posts: 5111
Joined: Wed Jun 08, 2005 8:07 pm
Location: Midlands UK

Post 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
User avatar
cordel
Posts: 5210
Joined: Fri Mar 05, 2004 4:47 pm
Location: /USA/Washington/Seattle

Post by cordel »

I'm kinda thinking I should have just done it in C and added it to zmfix now :?
Post Reply