From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Thu, 18 Mar 2004 08:21:48 +0200 From: "Kirill A. Shutemov" To: devel@altlinux.org Message-ID: <20040318062148.GA2545@localhost.localdomain> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="IiVenqGWf+H9Y6IX" Content-Disposition: inline User-Agent: Mutt/1.4.2.1i X-Spam: Not detected Cc: Subject: [devel] MySync X-BeenThere: devel@altlinux.ru X-Mailman-Version: 2.1.4 Precedence: list Reply-To: ALT Devel discussion list List-Id: ALT Devel discussion list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 18 Mar 2004 06:26:18 -0000 Archived-At: List-Archive: List-Post: --IiVenqGWf+H9Y6IX Content-Type: multipart/mixed; boundary="zhXaljGHf11kAtnf" Content-Disposition: inline --zhXaljGHf11kAtnf Content-Type: text/plain; charset=cp1251 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable =D2=F3=F2 =E4=EB=FF =F1=E5=E1=FF =ED=E0=EF=E8=F1=E0=EB =F1=EA=F0=E8=EF=F2= =E8=EA. =CC=EE=E6=E5=F2 =EA=EE=EC=F3 =E1=F3=E4=E5=F2 =E8=ED=F2=E5=F0=E5=F1= =ED=EE... =D7=F2=EE-=F2=EE =F2=E8=EF=E0 =EE=F4=F4=EB=E0=E9=ED=EE=E3=EE rsync'=E0 -- = =EF=EE=E7=E2=EE=EB=FF=E5=F2 =EF=EE=E1=ED=EE=E2=EB=FF=F2=FC =EE=E4=ED=EE =E4= =E5=F0=E5=E2=EE =F4=E0=E9=EB=EE=E2 =E4=EE =E4=F0=F3=E3=EE=E3=EE. =CF=F0=E5=E4=EF=EE=EB=EE=E3=E0=E5=F2=F1=FF = =E2=EE=E7=EC=EE=E6=ED=EE=F1=F2=FC =EF=E5=F0=E5=F2=E0=F1=EA=E8=E2=E0=F2=FC = =EE=E1=ED=EE=E2=EB=E5=ED=E8=FF =D1=E8=E7=E8=F4=E0=20 (=F1=EA=E0=E6=E5=EC, =F1 =F0=E0=E1=EE=F2=FB =E4=EE=EC=EE=E9), =EF=E5=EC=E5= =F0=ED=EE =F1=EB=E5=E4=F3=FE=F9=E5=E9 =EF=EE=F1=EB=E5=E4=EE=E2=E0=F2=E5=EB= =FC=ED=EE=F1=F2=FC=FE =EA=EE=EC=E0=ED=E4: =C4=EE=EC=E0: ./mysync -s =EA=E0=F2=E0=EB=EE=E3_=F1_=F1=E8=E7=E8=F4=EE=EC -= o Sisyphus.shot =DD=F2=EE =E4=EE=E2=EE=EB=FC=ED=EE =E4=EE=EB=E3=E8=E9 =EF=F0=EE=F6=E5=F1= =F1 - =F3 =EC=E5=ED=FF =ED=E0 =EC=E0=F8=E8=ED=E5(Cel-300A, 320Mb) ~20 =EC=E8=ED=F3=F2. =C4=E0=EB=E5=E5 =EE=F2=F1=FB=EB=E0=E5=EC =EF=EE=EB=F3= =F7=E5=ED=FB=E9 =F4=E0=E9=EB(=E2 bzip'=E5 ~400kb) =ED=E0 =F0=E0=E1=EE=F2=F3 =CD=E0 =F0=E0=E1=EE=F2=E5: ./mysync -c =EA=E0=F2=E0=EB=EE=E3_=F1_=F1=E8=E7= =E8=F4=EE=EC Sisyphus.shot -o Sisyphus.tar =C7=E0=EB=E5=E2=E0=E5=EC Sisypus.tar =ED=E0 =EA=EE=EC=EF=E0=EA=F2 =E8=EB= =E8 =E8=ED=EE=E9 =ED=EE=F1=E8=F2=E5=EB=FC, =ED=E5=F1=E5=EC =E4=EE=EC=EE=E9 =C4=EE=EC=E0: ./mysync -u -r Sisyphus.tar =EA=E0=F2=E0=EB=EE=E3_=F1_=F1=E8= =E7=E8=F4=EE=EC =C2=F3=E0=EB=FF... :) =C7=E0 =EF=EE=E4=F0=EE=E1=ED=EE=F1=F2=FF=EC=E8 =F1=EC=EE=F2=F0=E8=F2=E5 --h= elp. =C5=F1=EB=E8 =EA=EE=E3=EE-=ED=E8=F2=FC =FD=F2=E0 =EF=EE=E4=E5=EB=EA=E0 =E7= =E0=E8=ED=F2=E5=F0=E5=F1=EE=E2=E0=EB=E0 =EC=EE=E3=F3 =EF=EE=EB=EE=E6=E8=F2= =FC =E2 rpm. P.S. =D2=F0=E5=E1=F3=E5=F2 =ED=E0=EB=E8=F7=E8=E5 =E2 =F1=E8=F1=F2=E5=EC=E5 = ruby, tar, diff =E8 md5sum.=20 P.P.S. =C7=E0=EC=E5=ED=E0 =EF=EE=F1=EB=E5=E4=ED=E5=E3=EE =ED=E0 =F0=F3=E1= =B8=E2=FB=E9(=F1=EC. =E7=E0=EA=EE=EC=E5=ED=F7=E5=ED=FB=E9 =EA=EE=E4) =E2=FB= =E7=E2=E0=EB=E0 =F3=E2=E5=EB=E8=F7=E5=ED=E8=E5=20 =E2=F0=E5=EC=E5=ED=E8 =E2=FB=EF=EE=EB=ED=E5=ED=E8=FF =EF=E5=F0=E2=EE=E9 =EA= =EE=EC=E0=ED=E4=FB =E2 2 =F0=E0=E7=E0 =E8 =EF=F0=E8 =FD=F2=EE=EC =E7=E0=EF= =F0=EE=F1=F2=EE =F1=FA=E5=E4=E0=EB=E0=F1=FC =E2=F1=FF=20 =CE=CF + =EA=F3=F1=EE=EA =F1=E2=EE=EF=E0. =CC=EE=E6=E5=F2 =EA=F2=EE =EE=E1= =FA=FF=F1=ED=E8=F2 =EF=EE=F7=E5=EC=F3 =FD=F2=EE =EF=F0=EE=E8=F5=EE=E4=E8=F2? --=20 Kirill A. Shutemov E-mail: kirya85@mail.ru JID: kas@altlinux.org ICQ: 152302675 =CF=F0=E5=E4=FB=E4=F3=F9=E5=E5 (-alt3) =E8 =FD=F2=E8 =E8=E7=EC=E5=ED=E5=ED= =E8=FF =E8=F1=EF=F0=E0=E2=EB=FF=FE=F2 =EE=F8=E8=E1=EA=E8, =EA=EE=F2=EE=F0= =FB=E5, =ED=E0=F1=EA=EE=EB=FC=EA=EE =FF =EF=EE=ED=E8=EC=E0=FE, =E1=EB=E0=E3=EE=E4=E0=F0=FF =F2=E5=F5=ED=EE=EB=EE=E3= =E8=E8 PrivilegeSeparation =E2 =F5=F3=E4=F8=E5=EC =F1=EB=F3=F7=E0=E5 =EC=EE= =E3=F3=F2 =EF=F0=E8=E2=E5=F1=F2=E8 =EA =E2=EE=E7=EC=EE=E6=ED=EE=F1=F2=E8 =E8=F1=EF=EE= =EB=ED=E5=ED=E8=FF =EA=EE=E4=E0 =F1 =EF=F0=E0=E2=E0=EC=E8 =EF=F1=E5=E2=E4= =EE=EF=EE=EB=FC=E7=EE=E2=E0=F2=E5=EB=FF =E2 =EF=F3=F1=F2=EE=EC =F7=F0=F3=F2=E5. =CA =F2=EE=EC=F3 =E6=E5 =F7=F2=EE =E5= =F9=B8 =E8 =ED=E5 =E8=E7=E2=E5=F1=F2=ED=EE, =EC=EE=E3=F3=F2 =EB=E8. -- ldv in devel@ --zhXaljGHf11kAtnf Content-Type: text/plain; charset=cp1251 Content-Disposition: attachment; filename=mysync Content-Transfer-Encoding: quoted-printable #!/usr/bin/env ruby require 'find' require 'ftools' #require 'md5' require 'tempfile' $verbose =3D false $remove =3D false $exit_on_warning =3D false $exit_on_error =3D true def version=20 "0.1.0" end def fatal(msg) STDERR.puts("FATAL!: " + msg) exit(2) end def error(msg) STDERR.puts("ERROR!: " + msg) exit(1) if $exit_on_error end def warning(msg) STDERR.puts("WARNING!: " + msg) exit(1) if $exit_on_warning end def snapshot(path, output=3DSTDOUT) STDERR.puts "Generation snapshot for #{path}..." if $verbose=09 =20 fatal("#{path} isn't directory") unless FileTest.directory?(path) =20 output.puts("# MySync snapshot version #{version}", "# Date: #{Time.now= }") =20 arr =3D [] Find.find(path){|x| arr.push(x) } arr.sort! arr.shift =20 arr.each{|s| x =3D s.sub(/^#{path}\/?/, '') case File.lstat(s).ftype =20 when "directory" STDERR.puts x if $verbose=09 output.puts("D #{x}") when "file" # f =3D File.open(s) # output.puts("F #{x} #{MD5.md5(f.readlines.to_s)}") # f.close output.puts("F #{x} " + `md5sum #{s}`.sub(/ [^ ]+$/,'')) when "link" output.puts("L #{x} #{File.readlink(s)}") else warning("Not supported file type: #{s} - #{File.lstat(s).ftype}.") end output.flush } STDERR.puts "Generation snapshot for #{path} done." if $verbose=09 =20 return output end def diff(to, from, output=3DSTDOUT) STDERR.puts "Generation diff between #{from} and #{to}..." if $verbose= =09 =20 fatal("#{from} - no such file or directory.") unless FileTest.exist?(fr= om) =20 fatal("#{to} - no such file or directory.") unless FileTest.exist?(to) =20 output.puts("# MySync Diff version #{version}", "# Date: #{Time.now}") =20 if File.open(from).stat.directory? tf =3D Tempfile.new("from") snapshot(from, tf) from =3D tf.path end =20 if File.open(to).stat.directory? tf =3D Tempfile.new("to") snapshot(to, tf) to =3D tf.path end =20 arr =3D `diff -U 0 #{from} #{to}`.split(/\n/) arr.delete_if{|s| not s =3D~ /^[+-][FDL]/} =20 new =3D [] remove =3D [] change =3D [] =20 arr.each{|s| path =3D s.gsub(/[+-][FDL] ([^ ]+).*/, '\1') =09 if s=3D~/^\+/ new.push(path) else remove.push(s.gsub(/[+-][FDL] ([^ ]+).*/, '\1')) end } =20 remove.each{|s| change.push(s) if new.include?(s)} change.each{|s| new.delete(s) remove.delete(s) } change.each{|s| output.puts("C #{s}")} new.each{|s| output.puts("N #{s}")} remove.each{|s| output.puts("R #{s}")} =20 output.flush=09 STDERR.puts "Generation diff between #{from} and #{to} done" if $verbos= e=09 =20 return output end def create(to, from, output=3DSTDOUT) STDERR.puts "Generation tar with changes between #{from} and #{to}" if = $verbose=09 =20 fatal("#{from} - no such file or directory.") unless FileTest.exist?(fr= om) =20 fatal("#{to} isn't directory.") unless FileTest.directory?(to) =20 =20 to =3D File.expand_path(to) =20 tf =3D Tempfile.new(".mysync") =20 diff(to, from, tf) =20 arr =3D File.open(tf.path).readlines=09 =20 tar =3D "" arr.each{|s| tar +=3D " " + s.sub(/^[NC] (.*)\n$/, '\1') if s =3D~ /^[NC] / } =20 STDERR.puts "Packing tar #{from}" if $verbose=09 output.puts(`tar --no-recursion -c -C #{tf.path.gsub(/\/([^\/]+$)/,' \1= ')} -C #{to} #{tar} \ #{ $verbose ? '--verbose' : ''}`) output.flush =20 STDERR.puts "Generation tar with changes between #{from} and #{to} done= " if $verbose=09 =20 return output end def update(from, to) STDERR.puts "Updating #{to} from #{from}" if $verbose=09 =20 fatal("#{to} isn't directory.") unless FileTest.directory?(to) =20 from =3D File.expand_path(from) =20 if FileTest.directory?(from) tf =3D Tempfile.new("tar") create(from, to, tf) from =3D tf.path end =20 arr =3D `tar -O -xf #{from} ".mysync*"`.split("\n") pwd =3D Dir.pwd Dir.chdir(to) =20 remove =3D [] =20 arr.each{|s| a =3D /^([NCR]) (.*)$/.match(s).to_a =09 case a[1] when "N" error("File #{a[2]} labeled as new, but exist in the dir.") if FileTest.exist?(a[2]) when "C" warning("File #{a[2]} labeled as changed, but not exist in the dir.") = if !FileTest.exist?(a[2]) when "R" warning("File #{a[2]} labeled as removable, but not exist in the dir."= ) if !FileTest.exist?(a[2]) remove.push(a[2]) end } =20 STDERR.puts "Unpacking tar #{from}" if $verbose=09 =20 error("Untaring files failure.") unless=20 system("tar -xf #{from} #{ $verbose ? '--verbose' : ''}") =20 remove.reverse_each{|file| File.rm_f(file) or Dir.rmdir(file)} if $remo= ve Dir[".mysync*"].each{|file| File.rm_f(file)} Dir.chdir(pwd) =20 STDERR.puts "Updating #{to} from #{from} done" if $verbose=09 end if __FILE__ =3D=3D $0 require 'getoptlong' def show_usage puts "Usage: mysync -s [-o file] [-v] DIR" puts " or mysync -d [-o file] [-v] (NEWDIR|SNAPSHOT) (ORIGDIR|SNAPSHOT)" puts " or mysync -c [-o file] [-v] (NEWDIR) (ORIGDIR|SNAPSHOT)" puts " or mysync -u [-v] [-r] (SRCDIR|TAR) DSTDIR" puts " or mysync -h" puts puts "Options" puts " -s, --snapshot\t\tCreate snapshot of DIR" puts " -d, --diff\t\tCompare two directories or snapshots" puts " -c, --create\t\tCreate tar with changes between ORIGDIR or SNAPSHOT= and NEWDIR)" puts " -u, --update\t\tUpdate DSTDIR to SRCDIR or TAR(created by --create)" puts " -r, --remove\t\tRemove files in DSTDIR wich didn't exist in SRCDIR(= only with -u)" puts " -o, --output=3DFILE\tWrite output into FILE (not with --update)" puts " -v, --verbose\t\tBe verbose(very verbose %), print into stderr" puts " -w, --warning-exit\tExit on a WARNING" puts " -e, --error-continue\tDon't exit on ERROR" puts " -h, --help\t\tShow this usage" exit end opts =3D GetoptLong.new( [ "--snapshot", "-s", GetoptLong::NO_ARGUMENT], [ "--diff", "-d", GetoptLong::NO_ARGUMENT], [ "--create", "-c", GetoptLong::NO_ARGUMENT], [ "--update", "-u", GetoptLong::NO_ARGUMENT], [ "--remove", "-r", GetoptLong::NO_ARGUMENT], [ "--output", "-o", GetoptLong::REQUIRED_ARGUMENT], [ "--verbose", "-v", GetoptLong::NO_ARGUMENT], [ "--warning-exit", "-w", GetoptLong::NO_ARGUMENT], [ "--error-continue", "-e", GetoptLong::NO_ARGUMENT], [ "--help", "-h", GetoptLong::NO_ARGUMENT] ) mode =3D filename =3D "" opts.each{|opt,arg| case opt when "--help" show_usage when "--snapshot" fatal("You only can select one mode.") unless mode =3D=3D "" mode =3D "snapshot" when "--diff" fatal("You only can select one mode.") unless mode =3D=3D "" mode =3D "diff" when "--create" fatal("You only can select one mode.") unless mode =3D=3D "" mode =3D "create" when "--update" fatal("You only can select one mode.") unless mode =3D=3D "" mode =3D "update" when "--remove" $remove =3D true when "--output" filename =3D arg when "--verbose" $verbose =3D true when "--warning-exit" $exit_on_warning =3D true when "--error-continue" $exit_on_error =3D false end } error("--output can't be used with --update") if mode =3D=3D "update" a= nd filename !=3D "" error("--remove only can use with --update") if $remove and mode !=3D "= update" case mode when "snapshot" show_usage unless ARGV.size =3D=3D 1 if filename !=3D "" snapshot(ARGV[0], File.new(filename, File::CREAT|File::TRUNC|File::RDW= R)) else snapshot(ARGV[0]) end exit when "diff" show_usage unless ARGV.size =3D=3D 2 if filename !=3D "" diff(ARGV[0], ARGV[1], File.new(filename, File::CREAT|File::TRUNC|File::RDWR)) else diff(ARGV[0], ARGV[1]) end exit when "create" show_usage unless ARGV.size =3D=3D 2 if filename !=3D "" create(ARGV[0], ARGV[1], File.new(filename, File::CREAT|File::TRUNC|File::RDWR)) else create(ARGV[0], ARGV[1]) end exit =09 when "update" show_usage unless ARGV.size =3D=3D 2 update(ARGV[0], ARGV[1]) exit else show_usage end end --zhXaljGHf11kAtnf-- --IiVenqGWf+H9Y6IX Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.4 (GNU/Linux) iD8DBQFAWT/8bWYnhzC5v6oRApLcAKCKf0fnEk5ygq3F9Y9MD+HrarklHACZAaOJ AbiuKEhrHRHhGxjUtXnxbnA= =oYvl -----END PGP SIGNATURE----- --IiVenqGWf+H9Y6IX--