User Control Panel
Advertisements

HELP US, HELP YOU!

File Transfers

 
Post new topic   Reply to topic    Bot Depot Forum Index -> MSN.pm Development
View unanswered posts
Author Message
Keenie
Almost An Agent
Almost An Agent


Joined: 31 Oct 2003
Posts: 1071

Reputation: 52.4

PostPosted: Thu Apr 01, 2004 8:55 pm    Post subject: Reply with quote

lets see if this will post this time, i lost my whole last post.

Since I've been taking a while with this, and havn't got much done and integrating it (ive been having problems) I thought I'd post how I got file transfers working, so at least you guys can see it, and do something with it. (maybe even one of you guys will get around to adding it into msn.pm for me Smile )

couple of issues with this code:
1. It loops through the whole file sending it, will be bad for big files as it will take over.
2. doesnt always get the ip, testing locally it didnt get my real ip just my routers
3. i was coding this to make it work, not be pretty, or effective. I've learnt a bit about some new stuff, eg syswrite and sysread in the process, but its still terrible. I couldnt think of ways to make things work how i wanted, i ended up even using select for one socket, since i couldnt think of how to know when it was ready.

First thing I added to msn.pm (this is based off msn.pm 1.3.8 i think) is a method to send the file.

I had to hardcode the filesize, because stat wouldnt work for me.

Code:
=head2 sendfile<br /><br />sends a file to the user<br /><br />=cut<br /><br />sub sendfile<br />{<br />    my $self = shift || croak(strMethodOnly);;<br />    my $path = shift;<br />    <br />    my $filesize = (stat($path))[7]; #<---- Didn't ever get the filesize for me, probably path problem.<br /><br />    my $cookie = int(rand(1553692604)) + 1;<br />    <br />    my $header = qq{MIME-Version: 1.0\nContent-Type: text/x-msmsgsinvite; charset=UTF-8\n\n} .<br />    qq{Application-Name: File Transfer\n} .<br />    qq{Application-GUID: {5D3E02AB-6190-11d3-BBBB-00C04F795683}\n} .<br />    qq{Invitation-Command: INVITE\n} .<br />    qq{Invitation-Cookie: $cookie\n} .<br />    qq{Application-File: $path\n} .<br />    qq{Application-FileSize: 7\n}; #<---- FileSize in bytes<br />    #qq{Connectivity: N\n};<br />    <br />    $header =~ s/\n/\*lazy*\n/gs;<br /><br />    $self->sendraw('MSG', 'N ' . length($header) . "\*lazy*\n" . $header);<br />}


Second is 2 events (which will need to be coded directly into msn.pm eventually). I also left out the application name, i forgot about it, but its in the one below it, nothing big to add.

Code:
elsif ($header->{'Content-Type'} =~ /text\/x-msmsgsinvite/)<br />      {<br />        my $settings = { map { split(/\: /,$_) } split (/\n/, $msg) };<br />      <br /><br />                if ($settings->{'Invitation-Command'} eq "ACCEPT" && exists $settings->{'IP-Address'})<br />                {<br />                    $self->call_event("FileConnect",<br />                                                      $settings->{'IP-Address'},<br />                                                      $settings->{'Port'},<br />                                                      $settings->{'AuthCookie'},<br />                                                      $settings->{'Invitation-Cookie'});<br />                }<br />                elsif ($settings->{'Invitation-Command'} eq "ACCEPT" && !exists $settings->{'IP-Address'})<br />                {    <br />                   <br />                   my $ip = $self->{Socket}->sockhost();<br />                   my $AuthCookie = int(rand(1553692604)) + 1;<br /><br />                   my $header = qq{MIME-Version: 1.0\nContent-Type: text/x-msmsgsinvite; charset=UTF-8\n\n} .<br />                   qq{Invitation-Command: ACCEPT\n} .<br />                   qq{Invitation-Cookie: $settings->{'Invitation-Cookie'}\n} .<br />                   qq{IP-Address: $ip\n} .<br />                   qq{Port: 6891\n} .<br />                   qq{AuthCookie: $AuthCookie\n} .<br />                   qq{Launch-Application: FALSE\n} .<br />                   qq{Request-Data: IP-Address:\n};<br />    <br />                  $header =~ s/\n/\*lazy*\n/gs;<br />                  <br />                  $self->sendraw('MSG', 'N ' . length($header) . "\*lazy*\n" . $header);<br />                  $self->call_event("FileListen",<br />                                                $AuthCookie,<br />                                                $settings->{'Invitation-Cookie'});<br />                  <br />                 <br />                }<br />}


FileConnect, is for when you need to connect to them
FileListen, is when you need to listen.

(I put this together in peices, so it was easiest to add them this way)

next is the handlers for these events where most of the work currently takes place.

These are kinda bad, but work.

FileListen handler

Code:
sub Listen<br />{<br />   my ($self,$AuthCookie,$InviteCookie) = @_;<br />   $self->sendmsg('listening for connections');<br />   <br />   my $client = IO::Socket::INET->new(Listen    => 1,<br />                                 Reuse     => 1,<br />                                 LocalAddr => $self->{Socket}->sockhost(),<br />                                 LocalPort => 6891,<br />                                 Proto     => 'tcp') or $self->sendmsg($!);<br />   <br />   my $select = IO::Select->new($client);<br /><br />   my @ready;<br /><br />   while(@ready = $select->can_read) <br />   {<br />       my $socket;<br />       <br />       for $socket (@ready) <br />       {<br />          if($socket == $client) <br />          {<br />     my $new = $client->accept;<br />            $select->add($new);<br />            $select->remove($client);<br />            $self->sendmsg( $new->fileno . ": connected\n" );<br />          }<br />          else<br />          {<br />            my $data = $socket->getline();<br />         <br />            if ($data =~ /^VER/i)<br />            {<br />               my $stuff = "VER MSNFTP\*lazy*\n";<br />               syswrite( $socket, $stuff, length($stuff) );<br />            }<br />            elsif ($data =~ /^USR/i)<br />            {<br />               $stuff = "FIL 7\*lazy*\n"; #<--- 7 is the file size again.<br />               syswrite( $socket, $stuff, length($stuff) );<br />            }<br />            elsif($data =~ /TFR/i)<br />            {<br />               &SendData($socket,"./lib/FileTransferTest.txt"); #<-- Sub to send the data<br />               close $socket;<br />               $select->remove($socket);<br />            }<br /><br />          }<br />       }<br />    }<br />}


then when you connect to them

Code:
sub Accept<br />{<br />   my ($self,$ip,$port,$AuthCookie,$InviteCookie) = @_;<br />   warn "ACCEPTED: $ip $port $AuthCookie $InviteCookie\n";<br />   <br />   <br />   my $client = IO::Socket::INET->new(<br />       PeerAddr => $ip,<br />       PeerPort => $port,<br />       Proto    => 'tcp'<br />       ) or $self->sendmsg( "$ip:$port - Connection Failed: $!" );<br />   <br />   if ($client)<br />   {<br />      <br />      $client->blocking(0);<br />      $client->autoflush(1);<br /><br />      while ($client)<br />      {<br />         my $data = $client->getline();<br />         <br />         if ($data =~ /^VER/i)<br />         {<br />            my $stuff = "VER MSNFTP\*lazy*\n";<br />            syswrite( $client, $stuff, length($stuff) );<br />         }<br />         elsif ($data =~ /^USR/i)<br />         {<br />            $stuff = "FIL 7\*lazy*\n"; #<-- filesize.. -sigh-<br />            syswrite( $client, $stuff, length($stuff) );<br />         }<br />         elsif($data =~ /TFR/i)<br />         {<br />            &SendData($client,"./lib/FileTransferTest.txt");<br />            close $client;<br />            undef $client;<br />         }<br />      }<br />   }<br />}


as i did them at seperate times, alot of the code is duplicate, it could have been combined to make it cleaner (altho nothing in this code is clean anyways Wink )

and then theres the sub to send the actual data from the file. Which basically reads in the whole file and sends it until its done, which is not very nice!

Code:
sub SendData <br />{<br />   my ($client,$file) = @_;<br />   <br />   my $data;<br />   <br />   open (FILE, $file);<br />   binmode FILE;<br />   while(<FILE>) <br />   {<br />      $data .= $_;   <br />   }<br />   close(FILE);<br /><br />   my $offset = 1;<br />   <br />   while( $offset < length($data) )<br />   {<br />      my $part = substr($data, $offset-1, 65535);<br />      $offset += length($part);  <br />   <br />      $client->send(chr(0).chr(length($part)%256).chr(int(length($part)/256)).$part);<br />   }<br />}




anyways, now i dont have to worry so much about getting everything together for you guys to be able to see it.
Back to top
eric256
The Keymaker
The Keymaker


Joined: 03 May 2006
Posts: 2292
Location: Colorado
Reputation: 47Reputation: 47Reputation: 47Reputation: 47Reputation: 47

PostPosted: Fri Apr 02, 2004 7:44 pm    Post subject: Reply with quote

I'm pretty lost on most of that. lol. Now that we have MSN cleaned up alot though we can move to haveing a SB module an NS module and now a FileSend module. Then it cna just register its socket that it creates with the Main object just like conversations do now. Its realy just a conversation with different events. Smile

BTW Siebe is joining the development team! He has good experience with P2P and stuff so maybe we can get some cool features going.

_________________
Eric256
Proud previous owner and current admin of Bot-depot.com
Back to top
Display posts from previous:   
Post new topic   Reply to topic    Bot Depot Forum Index -> MSN.pm Development All times are GMT
Page 1 of 1

 



Protected by phpBB Security phpBB-TweakS
phpBB Security Has Blocked 9 Exploit Attempts.
Antispam Captcha Mod by phpbb-security.com
Powered by phpBB © 2001, 2005 phpBB Group