home *** CD-ROM | disk | FTP | other *** search
- // FtpGet.cpp : implementation file
- //
-
-
- #include "stdafx.h"
- #include "afxinet.h"
-
- #include <direct.h> // for _mkdir()
- #include <errno.h>
- #include <time.h>
-
- #include "ftp.h"
- #include "FtpView.h"
- #include "FtpGet.h"
-
-
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
-
- /////////////////////////////////////////////////////////////////////////////
- // CFtpGet
-
- CFtpGet::CFtpGet()
- {
- }
- CFtpGet::CFtpGet(CFtpView* pView, CString& Server, CString& FileTypes, CString& Path, CString& LocalRoot, CString& Gateway, int CopyType)
- {
- m_ftp= NULL;
- m_TotalFileSize= 0;
-
- m_strServer= Server;
- m_strFileTypes= FileTypes;
- m_strPath= Path;
- m_strLocalRoot= LocalRoot;
- m_strGateway= Gateway;
- m_CopyType= CopyType;
-
- m_pView= pView;
- }
-
- CFtpGet::~CFtpGet()
- {
- }
-
- /////////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////////
- // DoFtpTransfer()
- // Initiate an FTP session, perform the operation, close up.
- void CFtpGet::DoFtpTransfer()
- {
- try
- {
- //
- // 1) Create an Internet session
- //
- m_pView->AddToView("Creating session...");
- CInternetSession session;
-
- //
- // 2) Establish FTP connection
- //
- m_pView->AddToView("Getting ftp connection...");
- // Heuristic: If no gateway is specified then use server name directly,
- // otherwise use gateway as proxy server.
- if (m_strGateway.IsEmpty())
- {
- m_ftp= session.GetFtpConnection(m_strServer);
- }
- else
- {
- m_ftp= session.GetFtpConnection(
- m_strGateway,
- "anonymous@" + m_strServer,
- "YourName@YourCom.com"
- );
- }
- m_pView->AddToView("Connection made.");
-
- //
- // 3) Some miscellaneous initialization
- //
- // If no server path specified, make a "wildcard path".
- if (m_strPath.IsEmpty())
- {
- m_strPath= "*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\";
- if (m_CopyType==FC_LEAFFILES)
- {
- m_CopyType= FC_ALL;
- }
- }
- // Split path string up and place into string arrays, one for each path element.
- PathToArray(m_strPath, m_arrStaticPath); // original path as user entered.
- PathToArray(m_strPath, m_arrDynamicPath); // path with wildcard characters
- m_count= 0; // total files found.
- // replaced with matched directories.
- //
- // 4) Begin file transfer starting at root of FTP server.
- //
- CopyDirectory(0);
-
- //
- // 5) Close things up
- //
- m_ftp->Close();
- delete m_ftp;
- session.Close();
- m_pView->AddToView("Connection closed.");
- }
- catch (CInternetException* pIE)
- {
- CString err;
- err.Format("Error: %d", pIE->m_dwError);
- AfxMessageBox(err);
- m_pView->AddToView(err);
- pIE->Delete();
- }
- catch (CException* pIE)
- {
- char msg[255];
- pIE->GetErrorMessage(msg, 255);
- AfxMessageBox(msg);
- m_pView->AddToView(msg);
- pIE->Delete();
- }
-
- }
-
- ///////////////////////////////////////////////////////////////////////
- // CopyDirectory()
- // Main function to do the copy of matched filenames.
- // Return FALSE if there was a failure somewhere.
- //
- BOOL CFtpGet::CopyDirectory(int PathLevel)
- {
-
- //
- // 0) Initialization
- //
-
- // Set source directory at ftp site.
- // A level of 0 is the server root, 1 is first sub-dir, etc
- if (!SetFtpDirectory(PathLevel))
- {
- m_pView->AddToView("Cannot set ftp directory");
- return FALSE;
- }
-
-
- // Set a flag to determine whether or not this is a dir to copy.
- BOOL bCopy= (m_CopyType==FC_ALL) ||
- ((m_CopyType==FC_LEAFFILES)&&(PathLevel == m_arrDynamicPath.GetSize()));
-
- //
- // 1) Find desired files for current directory and copy.
- //
-
- CFtpFileFind ff(m_ftp);
- BOOL success= ff.FindFile(m_strFileTypes);
- while (success==TRUE)
- {
- {
- // Need to call FindNextFile before doing any attribute methods.
- success=ff.FindNextFile();
-
- CString strFilename= ff.GetFileName();
- if (!ff.IsDirectory())
- {
- // Get destination directory, create if needed.
- CString DestinationDir;
- if (GetLocalDirectory(PathLevel, DestinationDir))
- {
- CString FullName= DestinationDir + strFilename;
- // Do the copy.
- if (bCopy) {
- if (!m_ftp->GetFile(strFilename,FullName)) {
- CString msg;
- msg.Format("Cannot put to local directory, error: %d", ::GetLastError());
- m_pView->AddToView(msg);
- }
- }
- // Output file information.
- DWORD filesize= ff.GetLength();
- m_TotalFileSize += filesize;
- CString msg;
- msg.Format("%ld: size %ld (total %ld) To %s", ++m_count, filesize, m_TotalFileSize, FullName);
- m_pView->AddToView(msg);
- }
- else
- {
- m_pView->AddToView("Cannot access local directory");
- return FALSE;
- }
- }
- }
- }
- // Call Close to reset the search.
- ff.Close();
-
- //
- // 2) Terminate here if at end of path specification.
- //
-
- if (PathLevel >= m_arrDynamicPath.GetSize())
- {
- return TRUE;
- }
- else if (!strchr(m_arrStaticPath[PathLevel],'*') && !strchr(m_arrStaticPath[PathLevel],'?'))
- {
-
- // Just go down into path if no wildcards
-
- if (CopyDirectory(PathLevel+1)==FALSE)
- return FALSE;
-
- }
- else
- {
-
- //
- // 3) Start a new search looking for sub-directory names only.
- //
-
- CStringArray arrSubDirNames;
- success= ff.FindFile(m_arrStaticPath[PathLevel]);
- while (success==TRUE)
- {
- {
- // Need to call FindNextFile before doing any attribute methods.
- success=ff.FindNextFile();
- // Only concerned with sub-directories.
- if (ff.IsDirectory())
- {
- CString strFilename= ff.GetFileName();
- // Ignore special directory names, "." and "..".
- if (!ff.IsDots())
- {
- // Save matching sub-directory names.
- arrSubDirNames.Add(strFilename);
- }
- }
- }
- }
- // Call Close to reset the search.
- ff.Close();
-
- //
- // 4) Recursively copy matching sub-directories.
- //
-
- for (int idx= 0; idx< arrSubDirNames.GetSize(); idx++)
- {
- // Replace wildcard name with matching name.
- m_arrDynamicPath[PathLevel]= arrSubDirNames[idx];
- // Recursive call for new sub-directory, end copy if any errors are encountered.
- if (CopyDirectory(PathLevel+1) == FALSE)
- return FALSE;
- }
- } // end of else
-
- return TRUE;
- }
- ///////////////////////////////////////////////////////////////////////
- //
- // Utility functions
- //
- ///////////////////////////////////////////////////////////////////////
- // PathToArray()
- // Split path string into an array of strings, one per path element.
- void CFtpGet::PathToArray(CString& path, CStringArray& strArray)
- {
- char* pSep= "\\/"; // either works as a separator.
- // copy path string into a char array for strtok.
- char* pStr= new char[path.GetLength()+1];
- strcpy(pStr, path);
- // Get first path element.
- char* pPtr= strtok(pStr,pSep);
- // Extract path elements until there are no more.
- while (pPtr != NULL) {
- strArray.Add(pPtr);
- pPtr= strtok(NULL, pSep);
- }
- delete pStr;
- }
- ///////////////////////////////////////////////////////////////////////
- // BuildPath()
- // Given a level, build up a path from string array of path elements.
- // Note: level 0 means append zero elements
- void CFtpGet::BuildPath(int level, CString& path, CString& sep)
- {
- ASSERT(level<=m_arrDynamicPath.GetSize());
- for (int idx= 0; idx < level; idx++)
- {
- path += m_arrDynamicPath[idx];
- path += sep;
- }
- }
- ///////////////////////////////////////////////////////////////////////
- // CreateLocalDirectory()
- // Create a directory path on local filesystem.
- // The passed path string is appended to the local root directory string.
- BOOL CFtpGet::CreateLocalDirectory(CString& path, CString& FullDir)
- {
- CString msg;
- // Attempt to create destination dir if not existing
- if (_chdir(m_strLocalRoot)!=0)
- {
- msg.Format("Create %s?", m_strLocalRoot);
- if (AfxMessageBox(msg, MB_OKCANCEL) == IDOK)
- {
- if (_mkdir(m_strLocalRoot)!=0)
- {
- CString err;
- err.Format("Failed to create %s", m_strLocalRoot);
- m_pView->AddToView(err);
- return FALSE;
- }
- }
- else
- return FALSE;
- }
-
- CStringArray strArray;
- // Separate path name into path elements.
- PathToArray(path, strArray);
- // Start with the local root directory.
- FullDir= m_strLocalRoot;
- for (int idx=0; idx< strArray.GetSize(); idx++)
- {
- FullDir += strArray[idx];
- FullDir += "\\";
- if (_mkdir(FullDir)!=0)
- {
- if (errno != EEXIST)
- { // continue only if directory exists.
- CString err;
- err.Format("mkdir error on %s: %d", FullDir, errno);
- m_pView->AddToView(err);
- return FALSE;
- }
- }
- else
- {
- msg.Format("Creating new directory: %s", FullDir);
- m_pView->AddToView(msg);
- }
- }
- return TRUE;
- }
-
- ///////////////////////////////////////////////////////////////////////
- // SetFtpDirectory()
- // Set remote FTP directory based upon given level.
- BOOL CFtpGet::SetFtpDirectory(int level)
- {
- CString strPath("/");
- CString sep("/");
- BuildPath(level, strPath, sep);
- CString msg;
- msg.Format("Searching Dir: %s", strPath);
- m_pView->AddToView(msg);
- return m_ftp->SetCurrentDirectory(strPath);
- }
- ///////////////////////////////////////////////////////////////////////
- // GetLocalDirectory()
- // Given level, return string of local path.
- // Create path on filesytem if it does not exists.
- BOOL CFtpGet::GetLocalDirectory(int level, CString& FullDir)
- {
- CString strPath;
- CString sep("\\");
- BuildPath(level, strPath, sep);
- // Create it if necessary.
- if (!CreateLocalDirectory(strPath, FullDir))
- {
- return FALSE;
- }
- return TRUE;
- }
-