#!/usr/bin/perl -w #use strict; use vars qw/$AUTOLOAD/; package Smbclient; sub new { my $class = shift; my $fullshare = shift; my %options = @_; chomp $fullshare; if(!defined($fullshare)) { warn "No share!\n"; return; } my $self = {} ; bless $self, ref $class || $class ; $self->fullshare($fullshare); foreach my $key ( keys %options ) { $lkey = lc($key); $self->$lkey( $options{$key} ); } return $self; } sub AUTOLOAD { my $self = shift; my $var = shift; my $method = $AUTOLOAD; $method =~ s{^.*::}{}; if ( defined($var) ) { $self->{data}{$method} = $var; } return $self->{data}{$method}; } sub computer() { my $self = shift; my @comp = split /\//, $self->fullshare(); return $comp[2]; } sub share() { my $self = shift; my @comp = split /\//, $self->fullshare(); return $comp[3]; } sub directory() { my $self = shift; my @comp = split /\//, $self->fullshare(); @comp = splice @comp, 4, -1; my $str = "/"; $str .= $_."/" for(@comp); return $str; } sub localfilename() { my $self = shift; my $str = $self->target(); $str =~ s/'//g; return $str; } sub target() { my $self = shift; my @comp = split /\//, $self->fullshare(); return $comp[ $#comp ]; } sub check() { my $self = shift; } sub smbclient() { my $self = shift; my $command = shift; my $directory = shift; if (!defined($directory)) { $directory = ""; } if ( defined($self->{cache}{smbclient}{$command.$directory}) ) { return @{ $self->{cache}{smbclient}{$command.$directory} }; } my $share = "\"//".$self->computer()."/"; if ( defined($self->share()) ) { $share .= $self->share(); } $share .= "\""; my @commands ; push @commands, "smbclient"; push @commands, $share; push @commands, $self->password if defined($self->password()); if ( $directory ne "" ) { push @commands, "-D \"".$directory."\""; } else { push @commands, "-D \"".$self->directory()."\""; } push @commands, "-I ".$self->ip() if defined($self->ip()); push @commands, "-U ".$self->username() if defined($self->username()); push @commands, "-N", if !defined($self->password()); push @commands, $command; print STDERR "\e[31m\n","@commands","\e[0m\n" if $self->verbose() ; $self->{status}{smb_running} = 1; @result = qx/@commands/; $self->{status}{smb_running} = 0; @{ $self->{cache}{smbclient}{$command.$directory} } = @result; return @result; } sub printDebug() { my $self = shift; foreach my $key ( keys %{ $self->{data} } ) { print $key,"\t",$self->{data}{$key},"\n"; } print "Computer:\t",$self->computer(),"\n"; print "Share:\t\t",$self->share(),"\n"; print "Directory:\t",$self->directory(),"\n"; print "Target:\t\t",$self->target(),"\n"; } sub parseListing { my $self = shift; my @lines = (@_); my @files = (); LOOP: foreach (@lines) { my $item; if ( m/^ ([\S ]*\S|\.+) {5,}([HDRSA]+) +(\d+) (\S[\S ]+\S)$/ || m/^ ([\S ]*\S|[\.]+) {6,}()([0-9]+) (\S[\S ]+\S)$/ ) { $item->{name} = $1; $item->{attr} = $2; $item->{size} = $3; $item->{date} = $4; } elsif ( m/^\s+([\S ]+\S)\s+Disk\s+(([\S ]+\S)|)$/ ) { if ( $1 =~ /\$$/ ) { next LOOP; } $item->{name} = $1; $item->{attr} = "S"; $item->{size} = "0"; $item->{date} = "unknown"; } else { next LOOP; } push @files, $item; } return @files; } sub online() { my $self = shift; my $item = $self->listself(); return defined($item); } sub listself() { my $self = shift; if ( defined($self->{cache}{selflist}) ) { return $self->{cache}{selflist}; } my @list = $self->smbclient("-c 'ls'",$self->directory() ); my @files = $self->parseListing( @list ); LOOP: foreach my $file (@files) { if ( $file->{name} eq $self->target() ) { $self->{cache}{selflist} = $file; last LOOP; } } return $self->{cache}{selflist}; } sub type() { my $self = shift; my $item = $self->listself(); if ( defined($item) ) { if ( $item->{attr} =~ /D/ ) { return "directory"; } elsif ( $item->{attr} =~ /Service/ ) { return "service"; } else { return "file"; } } } sub list() { my $self = shift; if ( defined($self->share()) ) { my $dir = $self->directory(); if ( $self->type() eq "directory" ) { $dir .= $self->target(); } @files = $self->smbclient("-c ls", $dir); } else { @files = $self->smbclient("-L ".$self->computer(), ""); } my @files = $self->parseListing(@result); return @files; } sub size() { my $self = shift; if ( $self->type() eq "directory" ) { return $self->recursive_size(); } else { my $item = $self->listself(); return $item->{size}; } } sub recursive_size() { my $self = shift; my $dir = $self->directory.$self->target(); my @output = $self->smbclient("-c 'recurse;ls'", $dir); my @files = $self->parseListing(@output); my $sum = 0; foreach (@files) { $sum += $_->{size}; } return $sum; } sub get() { my $self = shift; my $target = $self->target(); my @output; $target =~ s/'/'\\''/g; if ( $self->type() eq "directory" ) { @output = $self->smbclient("-c 'recurse; prompt; mget \"$target\"'"); } else { @output = $self->smbclient("-c 'get \"$target\"'"); } $self->parseGetOutput(@output); } sub parseGetOutput() { my $self = shift; my @output = (@_); $self->{lastdownload}{completed} = 1; print $_ for (@output); } sub tar() { my $self = shift; my $filename = shift; my $target = $self->target(); if ( !defined($filename) ) { $filename = $self->localfilename().".tar"; } $directory = $self->directory(); if ($self->type() eq "directory") { $directory .= $self->target(); } @output = $self->smbclient("-Tc \"$filename\"", $directory); print $_ for (@output); } sub showcache() { my $self = shift; foreach my $key ( keys %{ $self->{cache} } ) { print "Cache for $key:\n"; foreach my $key2 ( keys %{ $self->{cache}{$key} } ) { print "\t$key2\t",$self->{cache}{$key}{$key2},"\n" ; } } } sub download_completed() { my $self = shift; return defined($self->{lastdownload}{completed}); } sub speed() { my $self = shift; warn "speed() Not implemented\n"; return 0.0; } 1;