LinuxQuestions.org
Register a domain and help support LQ
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 09-12-2007, 09:29 PM   #1
joangopan
LQ Newbie
 
Registered: Aug 2007
Location: Mexico DF
Distribution: Debian and Fedora
Posts: 21

Rep: Reputation: 15
Modify Perl script to work with txt - Permissions script


I need modify this code to work, with ls -shalR / result in a txt

How start???

What read or what need...
Code:
#!/usr/bin/perl

# Allrights- A perl tool for making backups of file permissions

# Copyright (C) 2005 Norbert Klein <norbert@acodedb.com>

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

# Version 1.02


# Change log

# From 1.01 to 1.02
# -----------------
# 2005-12-18 
# Fixed: File names with only one character are ignored

# From 1.0 to 1.01
# ---------------- 
# 2005-12-16 
# Many thanks to Marc Mims who found and fixed 3 bugs:
# Fixed: No support for file names with single quotes
# Fixed: Misinterpretation of file names starting with dashes
# Fixed: Restore crashes if executed on non-existing directories   



use strict;
use warnings;
use diagnostics;
use Cwd;
use File::Spec::Functions;


my $error="";
my $startdir="";

if ($ARGV[0]){
  #help text if argument is passed to script
  if ($ARGV[0] =~ /^(\?|help|-h|--help)$/) {
print <<'END';
  
  This script allows you to backup and restore file properties. It backups the 
  permissions, owners and groups of all files and folders including all subfolders. 
  IT DOES NOT BACKUP THE FILES AND FOLDERS THEMSELVES !!!

  Usage: ./allrights.pl  [DIR | OPTION]

  Examples: ./allrights.pl
            ./allrights.pl --help
            ./allrights.pl /folder1/folder2
            ./allrights.pl ./folder2

  DIR: 
  Directory were to start the backup (starting point of recursive descend)
  
  OPTIONS: 
  ?, help, -help, --help will display this help text
  
  Without parameter the starting point for the backup will be the current working directory    
    
    
  BACKUP
  ------
  Run the script including the path to the directory you want to backup or run it inside this
  directory without paramters. Two executable files will be created within this folder:
  
  permissions_backup.sh
  ownergroup_backup.sh
 
  Both are simple shell scripts which do not need Perl and can be run independently. 
  The program backups hidden files and hidden folders also. But note that symbolic links 
  will be ignored. If a symbolic link points to a file outside of the saved directory tree, 
  this file will remain unchanged too. 
  If a user name or group name does not exist any more in /etc/passwd or /etc/group the uid or 
  gid itself will be written into the backup files instead of the names. This happens if
  a group or user has been deleted, but files with these ids still exist.
    
    
  RESTORE
  -------
  You can run the two backup scripts independently. If you want to restore permissions 
  and owner/group just run both. In case you have removed some files since the last 
  backup, the script output will show you which files couldn't be found. 
  
  
  Author: norbert@acodedb.com
  Have fun !
  
END
  exit();
  }else{
    #if user passes relative path, change to absolute path
    if (substr($ARGV[0],0,1) eq "/"){
      $startdir=$ARGV[0];
    }else{
      $startdir=cwd() . "/" . $ARGV[0];
      $startdir =~ s|^//|/|;
    }   
  }  
}else{
  $startdir=cwd();
}

#first line in every output shall be empty
printf "\n";

#check if folder passed by user exists
if (!-e $startdir) {
  $error=" The folder $startdir does not exist";
  &finish();
}


#get content from /etc/passwd and /etc/group for uid/gid -> username/groupname translation
my %unames=();
my %gnames=();

#the script will produce a correct backup, also if etc/passwd cannot be opened
if (!open(FILE,"/etc/passwd")){
  $error=" The file \"/etc/passwd\" could not be opened\n";
  $error.=" This means that your backup scripts (.sh) have been created with UIDs instead of names (just a matter of clearness)\n";
  $error.=" Your backup has been created successfully\n";
  $error.=" You can restore your permissions and owners/groups by running \"./permissions_backup.sh\" and/or \"./ownergroup_backup.sh\"";
}else {
  my $uname="";
  my $uid="";
  while (<FILE>) {
    #skip comments
    if($_=~/^\s*#/){ next; }
    my @l=split(":",$_);
    $uname=$l[0];
    $uid=$l[2];
    $unames{$uid}=$uname;
  }
}
close(FILE);

#the script will produce a correct backup, also if /etc/group cannot be opened
if (!open(FILE,"/etc/group")){
  $error=" The file \"/etc/group\" could not be opened\n";
  $error.=" This means that your backup scripts (.sh) have been created with GIDs instead of names (just a matter of clearness)\n";
  $error.=" Your backup has been created successfully\n";
  $error.=" You can restore your permissions and owners/groups by running \"./permissions_backup.sh\" and/or \"./ownergroup_backup.sh\"";
}else {
  my $gname="";
  my $gid="";
  while (<FILE>) {
    #skip comments
    if($_=~/^\s*#/){ next; } 
    my @l=split(":",$_);
    $gname=$l[0];
    $gid=$l[2];
    $gnames{$gid}=$gname;
  }
} 
close(FILE);


#check if backupfiles already exists
if (-e "permissions_backup.sh"){
  $error= " The backup file \"permissions_backup.sh\" already exists\n";
  $error.=" Please rename or remove it as previous backup files will not be overwritten";
  &finish();
}
if (-e "ownergroup_backup.sh"){
  $error= " The backup file \"ownergroup_backup.sh\" already exists\n";
  $error.=" Please rename or remove it as previous backup files will not be overwritten";
  &finish();
}




printf " Preparing backup files \"permissions_backup.sh\" and \"ownergroup_backup.sh\"\n";


system("touch permissions_backup.sh");

if (!open FILE, "+< permissions_backup.sh"){
  $error= " The file \"permissions_backup.sh\" could not be opened";
  &finish();
}
seek FILE,0,0;

#permission backup
sub recdirs_p($);    #prototype needed before
print FILE "#!/bin/bash\n";
print FILE "#THE RESTORATION OF PERMISSIONS STARTS HERE: $startdir\n";
print FILE "#START > ---------------\n";
print FILE "\necho\necho \" Restoring, this may take a while...\"\n";

&recdirs_p($startdir,"");
print FILE "\necho \" Completed\"\necho\n";
print FILE "\n#END < ---------------\n";

#make executable bash script out of it
system ("chmod 00711 permissions_backup.sh");  
close (FILE);

printf " Shell script \"permissions_backup.sh\" created\n";




system("touch ownergroup_backup.sh");

if (!open FILE, "+< ownergroup_backup.sh"){
  $error= " The file \"ownergroup_backup.sh\" could not be opened";
  &finish();
}
seek FILE,0,0;

#owner, group backkup
sub recdirs_og($);    #prototype needed before
print FILE "#!/bin/bash\n";
print FILE "#THE RESTORATION OF OWNERS/GROUPS STARTS HERE: $startdir\n";
print FILE "#START > ---------------\n";
print FILE "\necho\necho \" Restoring, this may take a while...\"\n";

&recdirs_og($startdir,"");
print FILE "\necho \" Completed\"\necho\n";
print FILE "\n#END < ---------------\n";

#make executable bash script out of it 
system ("chmod 00711 ownergroup_backup.sh");  
close(FILE);

printf " Shell script \"ownergroup_backup.sh\" created\n";



&finish();


#functions ------------------------------------------------------------------------------------------------

sub finish(){
  #error output
  if ($error ne "") { 
    printf(" Error(s) occurred:\n%s\n",$error);
  }else{
    printf " Backup completed\n\n";
    printf " You can restore your permissions and owners/groups by running \"./permissions_backup.sh\" and \"./ownergroup_backup.sh\"\n";
  }
  printf "\n";
  #cleanup
  exit();
}


sub recdirs_p($){
  my $path=$_[0];
  if(opendir(DIR, $path)) {
    #get all objects besides . and ..
    my @obj=grep!/^\.$|^\.\.$/,readdir(DIR);  
 
    #all
    my $mode="";
    my $file="";    
    my $full_path="";
    foreach(@obj){
      $file=$path . "/" . $_;
      #ignore softlinks 
      if (-l $file) { next; }
      
      $mode=(stat($file))[2];        
      $mode=sprintf("0%o ", $mode & 07777);
      #if necessary fill with leading zeros 
      if (length($mode) < 5){ $mode = '0' x (5 - length($mode)) . $mode; }
      #support for file names with quotes
      $full_path = shell_escape(catfile($path, $_));
      print FILE qq{chmod $mode -- "$full_path"\n};
    }  
 
    #directories
    foreach(@obj) {
      #(-d "file") also recognizes symbolic links, if they point to a directory
      if((-d "$path/$_") && (!-l "$path/$_")) {
        &recdirs_p("$path/$_");
      }
   }
   close DIR;
 }
}


sub recdirs_og($){
  my $path=$_[0];
  if(opendir(DIR, $path)) {
  my @obj=grep!/^\.$|^\.\.$/,readdir(DIR);
 
    my $uname="";
    my $gname="";
    my $file="";
    my $full_path="";
    foreach(@obj){
      $file=$path . "/" . $_;
      if (-l $file) { next; }
      #get username/groupname for uid/gid. if username/groupname don't exist keep uid/gid 
      if (!defined($uname=$unames{((stat($file))[4])})) { $uname=(stat($file))[4]; }    
      if (!defined($gname=$gnames{((stat($file))[5])})) { $gname=(stat($file))[5]; }    
      $full_path = shell_escape(catfile($path, $_));
      print FILE qq{chown $uname:$gname -- "$full_path"\n};
    }  
 
  foreach(@obj) {
    if((-d "$path/$_") && (!-l "$path/$_")) {
      &recdirs_og("$path/$_");
    }
   }
   close DIR;
 }
}


sub shell_escape($){
    my $string = $_[0];
    $string =~ s/([\$"`\\])/\\$1/g;
    return $string;
}

# end of code ----------------------------------------------------------------------------------------------
I need your help... some one say me i need a parser... but where read about??

Thanks for your time
 
Old 09-13-2007, 12:27 PM   #2
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 231Reputation: 231Reputation: 231
That has got to be one of best formatted & commented programs I have ever read. Nice work.

Unfortunately, however, I think that Perl is the wrong thing to use on the the output of a CLI tool like ls.

I think the essence of what you are trying to do is something like this:
Code:
# save the starting point
DIR0=`pwd`

# I would make these script names MUCH shorter
MOD_SH="permissions_backup.sh"
OWN_SH="ownergroup_backup.sh"

MOD_PERM='711'
OWN_PERM='711'

# these format strings are key to using the stat command
MOD_STAT="%a"
#OWN_STAT="%U:%O"    # this fails on deleted names
OWN_STAT="%u:%o"
# given that their names are longer than their values, 
# defining them may be pointless, but it's safer

# qualify $1
if [ -d $1 ] 
then cd $1 
else echo "$1 is not a directory" ; exit 1
fi
# add more code if this isn't enough

cd $1
DIRS=`ls -R  | grep -o '^[.][^:]*'`
for D in "$DIRS"
do
   cd "$D"

   # set up restore scripts
   echo '' > $MOD_SH
   chmod $MOD_PERM $MOD_SH
   echo '' > $OWN_SH
   chmod $OWN_PERM $OWN_SH
   # I don't check for or try to rename earlier files

   for F in `ls -A` 
   do
      echo "chmod `stat -c "$MOD_STAT" "$F"` >> $MOD_SH
      echo "chmod `stat -c "$OWN_STAT" "$F"` >> $OWN_SH
   done
done

cd $DIR0
Warnings & Disclaimers

I have not been able to test all my code, only some key elements.

In spite of your fine efforts, I don't read Perl easily, so I may may missed some features you included.

I especially think you have more elaborate processing of deleted users & groups, I have made no provision for detecting those.

I don't understand why you used the "-a" option in ls. I think "-A" is better because I can't see re-processing the '.' & '..' directory entries. This may mean I am seriously missing something you are trying to do.

I also don't understand why you used the "-s" & "-h" options at all. Again, I may be missing something, but I thought all you are interested in are the ownership & permissions.

As the comment says:
"# I don't check for or try to rename earlier files".
I think that rather than exiting it would be friendlier to make sequentially numbered backups of any earlier scripts.

Although you mentioned a "txt" in your actual Q, I chose not to make a file listing either the flies or directories processed. That could easily be changed.

Even if you continue developing this in Perl, I hope
stat & ls -A will be useful to you.
 
Old 09-13-2007, 05:09 PM   #3
joangopan
LQ Newbie
 
Registered: Aug 2007
Location: Mexico DF
Distribution: Debian and Fedora
Posts: 21

Original Poster
Rep: Reputation: 15
Not exactly

I have .txt file result of ls -shalR i need... adapt the code i publish... for work with this result (txt)

Some one say me i need parser... or something like that...

I preciate your time and help, i don't write the script is from someone else...

Very good code no??? i am really happy for this programmers share your code for others can learn.
 
Old 09-14-2007, 07:15 PM   #4
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 231Reputation: 231Reputation: 231
Sorry, I don't do Perl -- can't help further, good luck.
 
Old 09-14-2007, 09:20 PM   #5
joangopan
LQ Newbie
 
Registered: Aug 2007
Location: Mexico DF
Distribution: Debian and Fedora
Posts: 21

Original Poster
Rep: Reputation: 15
Thanks!!!

No problem men, i really preciate your comment and help, i need to think and start to learn to solve this problem but!!! thanks thanks for real
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
A Perl script doesn't properly work Hirszu Programming 4 11-29-2005 01:02 AM
perl script, users and permissions djgerbavore Programming 1 12-29-2004 12:41 PM
Converting a Windows Perl script to a Linux Perl script. rubbercash Programming 2 07-19-2004 10:22 AM
Perl Script Reading a txt file and generate html to be published! kofi Linux - Software 1 09-22-2003 05:12 PM
Perl script for website won't work klintonray Programming 5 07-27-2003 06:04 AM


All times are GMT -5. The time now is 05:39 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration