Logo
~Apps~
~Projects~
~Contact~


MetainfoSocket Class Reference

Sending and receiving end of metainfo file transfer. More...

#include <MetainfoSocket.h>

Collaboration diagram for MetainfoSocket:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 MetainfoSocket (ISocketHandler &)
 MetainfoSocket (ISocketHandler &, const std::string &filename)
 ~MetainfoSocket ()
void OnAccept ()
void OnConnect ()
void OnDelete ()
void OnRead ()

Private Types

enum  state_t { STATE_GET_LENGTH = 0, STATE_GET_FILE }

Private Member Functions

 MetainfoSocket (const MetainfoSocket &s)
MetainfoSocketoperator= (const MetainfoSocket &)
void InitSession ()

Private Attributes

int m_filenr
std::string m_filename
FILE * m_fil
state_t m_state
off_t m_sz
off_t m_sz_read

Static Private Attributes

static int m_nr = 0

Detailed Description

Sending and receiving end of metainfo file transfer.

File ......... MetainfoSocket.h Published .... 2005-06-14 Author ....... grymse@alhem.net

Definition at line 32 of file MetainfoSocket.h.


Member Enumeration Documentation

enum MetainfoSocket::state_t [private]

Enumerator:
STATE_GET_LENGTH 
STATE_GET_FILE 

Definition at line 34 of file MetainfoSocket.h.

00034                      {
00035                 STATE_GET_LENGTH = 0,
00036                 STATE_GET_FILE,
00037         };


Constructor & Destructor Documentation

MetainfoSocket::MetainfoSocket ( ISocketHandler &   ) 

Definition at line 50 of file MetainfoSocket.cpp.

References DEB.

00051 :TcpSocket(h)
00052 ,m_filenr(++m_nr)
00053 ,m_fil(NULL)
00054 ,m_state(STATE_GET_LENGTH)
00055 ,m_sz(0)
00056 ,m_sz_read(0)
00057 {
00058 DEB(printf("MetaInfoSocket()\n");)
00059 }

MetainfoSocket::MetainfoSocket ( ISocketHandler &  ,
const std::string &  filename 
)

Definition at line 62 of file MetainfoSocket.cpp.

References DEB.

00063 :TcpSocket(h)
00064 ,m_filenr(0)
00065 ,m_filename(filename)
00066 ,m_fil(NULL)
00067 ,m_state(STATE_GET_LENGTH)
00068 ,m_sz(0)
00069 ,m_sz_read(0)
00070 {
00071 DEB(printf("MetaInfoSocket()\n");)
00072 }

MetainfoSocket::~MetainfoSocket (  ) 

Definition at line 75 of file MetainfoSocket.cpp.

References DEB, and m_fil.

00076 {
00077 DEB(printf("~MetaInfoSocket()\n");)
00078         if (m_fil)
00079                 fclose(m_fil);
00080 }

MetainfoSocket::MetainfoSocket ( const MetainfoSocket s  )  [inline, private]

Definition at line 50 of file MetainfoSocket.h.

00050 : TcpSocket(s) {} // copy constructor


Member Function Documentation

void MetainfoSocket::OnAccept (  ) 

Definition at line 110 of file MetainfoSocket.cpp.

References DEB, m_fil, m_filename, m_filenr, m_state, and STATE_GET_LENGTH.

00111 {
00112 DEB(printf("MetainfoSocket::OnAccept\n");)
00113         m_filename = "metafile." + Utility::l2string(m_filenr);
00114         m_fil = fopen(m_filename.c_str(), "wb");
00115         m_state = STATE_GET_LENGTH;
00116 }

void MetainfoSocket::OnConnect (  ) 

Definition at line 83 of file MetainfoSocket.cpp.

References DEB, and m_filename.

00084 {
00085 DEB(printf("MetainfoSocket::OnConnect\n");)
00086         struct stat st;
00087         if (stat(m_filename.c_str(), &st) == -1)
00088         {
00089                 perror("stat failed");
00090                 SetCloseAndDelete();
00091                 return;
00092         }
00093         SendBuf( (char *)&st.st_size, sizeof(off_t));
00094         FILE *fil = fopen(m_filename.c_str(), "rb");
00095         if (fil)
00096         {
00097                 char buf[5000];
00098                 int n = fread(buf,1,5000,fil);
00099                 while (n > 0)
00100                 {
00101                         SendBuf(buf,n);
00102                         n = fread(buf,1,5000,fil);
00103                 }
00104                 fclose(fil);
00105         }
00106         SetCloseAndDelete();
00107 }

void MetainfoSocket::OnDelete (  ) 

Definition at line 159 of file MetainfoSocket.cpp.

References DEB, InitSession(), m_fil, m_sz, and m_sz_read.

00160 {
00161 DEB(printf("MetainfoSocket::OnDelete\n");)
00162         if (m_fil)
00163         {
00164                 fclose(m_fil);
00165                 m_fil = NULL;
00166                 if (m_sz_read == m_sz)
00167                 {
00168                         InitSession();
00169                 }
00170                 else
00171                 {
00172                         printf("Short metainfo file read - ignoring\n");
00173                 }
00174         }
00175 }

void MetainfoSocket::OnRead (  ) 

Definition at line 129 of file MetainfoSocket.cpp.

References DEB, m_fil, m_state, m_sz, m_sz_read, STATE_GET_FILE, and STATE_GET_LENGTH.

00130 {
00131         TcpSocket::OnRead();
00132         while (ibuf.GetLength())
00133         {
00134                 size_t l = ibuf.GetLength();
00135         
00136                 switch (m_state)
00137                 {
00138                 case STATE_GET_LENGTH:
00139                         if (l < sizeof(off_t))
00140                                 return;
00141                         ibuf.Read( (char *)&m_sz, sizeof(off_t));
00142                         m_state = STATE_GET_FILE;
00143                         DEB(printf("File length: %d bytes\n", m_sz);)
00144                         break;
00145                 case STATE_GET_FILE:
00146                         {
00147                                 char slask[TCP_BUFSIZE_READ];
00148                                 ibuf.Read( slask, l);
00149                                 if (m_fil)
00150                                         fwrite(slask,1,l,m_fil);
00151                                 m_sz_read += l;
00152                         }
00153                         break;
00154                 }
00155         }
00156 }

MetainfoSocket& MetainfoSocket::operator= ( const MetainfoSocket  )  [inline, private]

Definition at line 51 of file MetainfoSocket.h.

00051 { return *this; } // assignment operator

void MetainfoSocket::InitSession (  )  [private]

Definition at line 178 of file MetainfoSocket.cpp.

References DEB, BString::GetBTObject(), BString::GetHash(), BString::GetHashAsString(), BString::GetInteger(), BString::GetString(), Exception::GetText(), PeerHandler::GetTorrentDirectory(), m_filename, PeerHandler::mkpath(), BString::read_file(), PeerHandler::RegSession(), and PeerHandler::SessionExists().

Referenced by OnDelete().

00179 {
00180 DEB(printf("InitSession\n");)
00181         try
00182         {
00183                 FILE *fil = fopen(m_filename.c_str(), "rb");
00184                 if (fil)
00185                 {
00186                         PeerHandler& ref = static_cast<PeerHandler&>(Handler());
00187                         BString meta;
00188                         meta.read_file(fil);
00189                         fclose(fil);
00190                         std::string info_hash = meta.GetHashAsString("info");
00191                         // copy metainfo file
00192                         std::string copy_to = ref.GetTorrentDirectory() + "/" + info_hash + "/.metainfo";
00193                         ref.mkpath(copy_to);
00194                         fil = fopen(m_filename.c_str(), "rb");
00195                         if (fil)
00196                         {
00197                                 FILE *fil2 = fopen(copy_to.c_str(), "wb");
00198                                 char buf[1000];
00199                                 size_t n = fread(buf, 1, 1000, fil);
00200                                 while (n > 0)
00201                                 {
00202                                         fwrite(buf, 1, n, fil2);
00203                                         n = fread(buf, 1, 1000, fil);
00204                                 }
00205                                 fclose(fil2);
00206                                 fclose(fil);
00207                         }
00208                         if (ref.SessionExists(info_hash))
00209                         {
00210 DEB(printf("Session for hash %s already exists\n", info_hash.c_str());)
00211                         }
00212                         else
00213                         {
00214 DEB(printf("Hash: %s\n", info_hash.c_str());)
00215                                 Session *sess = new Session(Handler(), info_hash);
00216                                 ref.RegSession( sess );
00217                                 sess -> SetHash(meta.GetHash("info"));
00218                                 BTString *p;
00219                                 if ((p = meta.GetString("announce")) != NULL)
00220                                 {
00221                                         sess -> SetAnnounce(p -> GetValue());
00222                                 }
00223                                 std::string name;
00224                                 if ((p = meta.GetString("info.name")) != NULL)
00225                                 {
00226                                         sess -> SetName(name = p -> GetValue());
00227                                 }
00228                                 BTInteger *piecelength = meta.GetInteger("info.piece length");
00229                                 if (piecelength)
00230                                 {
00231                                         sess -> SetPieceLength(piecelength -> GetVal());
00232                                 }
00233                                 BTInteger *length = meta.GetInteger("info.length");
00234                                 if (length)
00235                                 {
00236                                         sess -> AddFile(length -> GetVal());
00237                                 }
00238                                 else // info.files
00239                                 {
00240                                         BTObject *p = meta.GetBTObject("info.files");
00241                                         BTList *files = dynamic_cast<BTList *>(p);
00242                                         if (files)
00243                                         {
00244                                                 btobject_v& ref = files -> GetList();
00245                                                 for (btobject_v::iterator it = ref.begin(); it != ref.end(); it++)
00246                                                 {
00247                                                         BTDictionary *p = dynamic_cast<BTDictionary *>(*it);
00248                                                         if (p)
00249                                                         {
00250                                                                 BTInteger *length = dynamic_cast<BTInteger *>(p -> Find("length"));
00251                                                                 BTList *path = dynamic_cast<BTList *>(p -> Find("path"));
00252                                                                 if (path && length)
00253                                                                 {
00254                                                                         btobject_v& ref = path -> GetList();
00255                                                                         std::string pathname = name;
00256                                                                         for (btobject_v::iterator it = ref.begin(); it != ref.end(); it++)
00257                                                                         {
00258                                                                                 BTString *p = dynamic_cast<BTString *>(*it);
00259                                                                                 if (p)
00260                                                                                         pathname += "/" + p -> GetValue();
00261                                                                         }
00262                                                                         sess -> AddFile(pathname, length -> GetVal());
00263                                                                 }
00264                                                         }
00265                                                 }
00266                                         }
00267                                 }
00268                                 // pieces checksum
00269                                 BTString *pieces = meta.GetString("info.pieces");
00270                                 if (pieces)
00271                                 {
00272                                         sess -> SetPieces( pieces -> GetValue() );
00273                                 }
00274                                 sess -> CreateFileManager();
00275                                 // restore session
00276                                 sess -> Load();
00277                                 //
00278 /*
00279 DEB(printf("Verifying existing files...\n");)
00280                                 sess -> Verify();
00281 DEB(printf("Verify finished\n");)
00282 */
00283                         }
00284                         //
00285                         unlink(m_filename.c_str());
00286                 }
00287         }
00288         catch (const Exception& e)
00289         {
00290                 Handler().LogError(this, "InitSession", 0, e.GetText(), LOG_LEVEL_ERROR);
00291         }
00292 }


Member Data Documentation

int MetainfoSocket::m_nr = 0 [static, private]

Definition at line 55 of file MetainfoSocket.h.

int MetainfoSocket::m_filenr [private]

Definition at line 56 of file MetainfoSocket.h.

Referenced by OnAccept().

std::string MetainfoSocket::m_filename [private]

Definition at line 57 of file MetainfoSocket.h.

Referenced by InitSession(), OnAccept(), and OnConnect().

FILE* MetainfoSocket::m_fil [private]

Definition at line 58 of file MetainfoSocket.h.

Referenced by OnAccept(), OnDelete(), OnRead(), and ~MetainfoSocket().

Definition at line 59 of file MetainfoSocket.h.

Referenced by OnAccept(), and OnRead().

off_t MetainfoSocket::m_sz [private]

Definition at line 60 of file MetainfoSocket.h.

Referenced by OnDelete(), and OnRead().

off_t MetainfoSocket::m_sz_read [private]

Definition at line 61 of file MetainfoSocket.h.

Referenced by OnDelete(), and OnRead().


The documentation for this class was generated from the following files:
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4