--------------------------------------------------------------------------------------------------------------------------------------------------
Program Listing for:  myftpmain.cpp
Project:  ftpdll
Namespace:  c++
----------------------------------------------------------------------------------------------------------------------------------------------------

// myftpmain.cpp
// various projects 
// scott laing
//
// main file for ftp project, basically these are dll
// functions that use inet.lib stuff to send a file to a web
// site.  the default protocol is ftp, this could be changed.
// for help on windows inet.lib look up help on functions like
// InternetOpen()

#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>                                                                                     

// function prototypes - in this file for convenience since small project
extern "C" __declspec(dllexport) int SendFileFtp(char *sRemote, char *sLocal,
                                             char *writeName);

extern "C" __declspec(dllexport) int SendFileFtpPass(char *sRemote, char *sLocal,
                                             char *writeName, char *logName, char *logPass);

// actual function bodies
// note return value of 1 means success, negative return values correspond
// to the error type.  should add on more error friendly tracking at some
// point but this is quick and dirty.
extern "C" __declspec(dllexport) int SendFileFtp(char *sRemote, char *sLocal,
                                             char *writeName) 
{

         bool error = 0;
         int bret = 1;

         //CFile uploadFile;
         FILE *fpSendFile;

         HINTERNET hIS, hIC, hIF;
         DWORD dwBytes;
         long fsize;
         //CString writefile, write2;

         fpSendFile = fopen( sLocal, "rb");

         if (! fpSendFile )
         {
                  //MessageBox("Couldn't open local file!");
                  return -1;
         }
         if (fseek( fpSendFile, 0, SEEK_END)) {
                  return -20;
         }

         if ( (fsize = ftell( fpSendFile))  == -1L ) {
                  return -21;         
         }

         if (fseek( fpSendFile, 0, SEEK_SET )) {
                  return -20;
         }

         //if (! bUsingProxy)
         // new logic, test for direct, if not try proxy, then if problem quit
         // MFUPLOAD is just process name, could be anything, see function
         // help for more info.
         hIS = InternetOpen("MFUPLOAD", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);

         // direct failure, try proxy
         if (! hIS )
         {
                  hIS = InternetOpen("MFUPLOAD", INTERNET_OPEN_TYPE_PROXY, NULL, NULL, 0);
         }

         // proxy and direct connect failed, close file and abort
         if (! hIS)
         {
                  //MessageBox("Trouble opening Internet connection... Make sure you are on the net!");
                  fclose(fpSendFile);
                  return -2;
         }

         hIC = InternetConnect(hIS, sRemote, INTERNET_DEFAULT_FTP_PORT, NULL, NULL, INTERNET_SERVICE_FTP, 0, 0);
         if (! hIC)
         {
                  //MessageBox("Trouble creating Internet connection");
                  InternetCloseHandle(hIS);
                  fclose(fpSendFile);
                  return -3;
         }

         hIF = FtpOpenFile(hIC, writeName, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY, 0);
         if (! hIF)
         {
                  //MessageBox("Trouble creating server write file");
                  InternetCloseHandle(hIC);
                  InternetCloseHandle(hIS);
                  fclose(fpSendFile);
                  return -4;
         }

         char *pbuf;
         pbuf = new char[201];

         // put below in block to save memory...
         // nick says you can use blocks by themselves, so i gotta do it 
         // for fun at least once, nick is chess god friend in l.a., c guru
         {

                  int n;
                  long curpos;
                  long readnum;
                  long nBytesRead;
                  // setup progress bar stuff
                  int iquit = 0;

                  // loop through local file reading 200 bytes at a time
                  // and writing it to server file, with error checking
                  for (n=0;1;n++) {

                           curpos = n*200;
                           readnum = 200;

                           // 200 more would exceed file len, set readnum
                           // to a lesser amt
                           if (curpos + 200 > fsize ) {
                                    readnum = fsize - curpos;

                                    // we're already done if this true
                                    if (readnum == 0)
                                    {
                                             break;
                                    }
                                    // this is last chunk of file to read, set ending flag
                                    iquit = 1;
                           }

                           // shd never happen, i'm paranoid
                           if (readnum > 200)
                           {
                                    //MessageBox("Logic error, file not written, notify programmer");
                                    bret = -16;
                                    break;

                           }

                           // read in from local file readnum bytes
                           // this sizeof(char) shit is for unicode, I assume this is
                           // good old one for our example.  those modifying for japanese
                           // should look at size_t stuff see fread definition
                           nBytesRead = fread( pbuf, sizeof( char ), readnum, fpSendFile );

                           if (nBytesRead != readnum )
                           {
                                    //MessageBox("Trouble reading local data file, bytes missing!");
                                    bret = -17;
                                    break;
                           }

                           // write those bytes to target on server
                           if (! InternetWriteFile(hIF, pbuf, readnum, &dwBytes) )
                           {
                                    //MessageBox("Trouble writing data file, write file fx");
                                    bret = -18;
                                    break;
                           }
                           if (readnum != dwBytes )
                           {
                                    //MessageBox("Trouble writing data file, bytes not written fully!");
                                    bret = -19;
                                    break;
                           }

                           // one way out of loop, we've finished file
                           if (iquit) {
                                    break;
                           }

                  }

         }

         // close files
         InternetCloseHandle(hIF);
         fclose(fpSendFile);

         // ah, the wonders of c++
         delete [] pbuf;
         InternetCloseHandle(hIC);
         InternetCloseHandle(hIS);

         // success, if bret == 1
         return bret;

}

extern "C" __declspec(dllexport) int SendFileFtpPass(char *sRemote, char *sLocal,
                                             char *writeName, char *logName, char *logPass)

//int CMassfileDlg::SendFile(CString sLocal, CString sRemote)
{

         bool error = 0;
         int bret = 1;

         //CFile uploadFile;
         FILE *fpSendFile;

         HINTERNET hIS, hIC, hIF;
         DWORD dwBytes;
         long fsize;
         //CString writefile, write2;

         fpSendFile = fopen( sLocal, "rb");

         if (! fpSendFile )
         {
                  //MessageBox("Couldn't open local file!");
                  return -1;
         }
         if (fseek( fpSendFile, 0, SEEK_END)) {
                  return -20;
         }

         if ( (fsize = ftell( fpSendFile))  == -1L ) {
                  return -21;         
         }

         if (fseek( fpSendFile, 0, SEEK_SET )) {
                  return -20;
         }

         //if (! bUsingProxy)
         // new logic, test for direct, if not try proxy, then if problem quit
         // MFUPLOAD is just process name, could be anything, see function
         // help for more info.
         hIS = InternetOpen("MFUPLOAD", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);

         // direct failure, try proxy
         if (! hIS )
         {
                  hIS = InternetOpen("MFUPLOAD", INTERNET_OPEN_TYPE_PROXY, NULL, NULL, 0);
         }

         // proxy and direct connect failed, close file and abort
         if (! hIS)
         {
                  //MessageBox("Trouble opening Internet connection... Make sure you are on the net!");
                  fclose(fpSendFile);
                  return -2;
         }

         hIC = InternetConnect(hIS, sRemote, INTERNET_DEFAULT_FTP_PORT, logName, logPass, INTERNET_SERVICE_FTP, 0, 0);
         if (! hIC)
         {
                  //MessageBox("Trouble creating Internet connection");
                  InternetCloseHandle(hIS);
                  fclose(fpSendFile);
                  return -3;
         }

         hIF = FtpOpenFile(hIC, writeName, GENERIC_WRITE, FTP_TRANSFER_TYPE_BINARY, 0);
         if (! hIF)
         {
                  //MessageBox("Trouble creating server write file");
                  InternetCloseHandle(hIC);
                  InternetCloseHandle(hIS);
                  fclose(fpSendFile);
                  return -4;
         }

         char *pbuf;
         pbuf = new char[201];

         // put below in block to save memory...
         // nick says you can use blocks by themselves, so i gotta do it 
         // for fun at least once, nick is chess god friend in l.a., c guru
         {

                  int n;
                  long curpos;
                  long readnum;
                  long nBytesRead;
                  // setup progress bar stuff
                  int iquit = 0;

                  // loop through local file reading 200 bytes at a time
                  // and writing it to server file, with error checking
                  for (n=0;1;n++) {

                           curpos = n*200;
                           readnum = 200;

                           // 200 more would exceed file len, set readnum
                           // to a lesser amt
                           if (curpos + 200 > fsize ) {
                                    readnum = fsize - curpos;

                                    // we're already done if this true
                                    if (readnum == 0)
                                    {
                                             break;
                                    }
                                    // this is last chunk of file to read, set ending flag
                                    iquit = 1;
                           }

                           // shd never happen, i'm paranoid
                           if (readnum > 200)
                           {
                                    //MessageBox("Logic error, file not written, notify programmer");
                                    bret = -16;
                                    break;

                           }

                           // read in from local file readnum bytes
                           // this sizeof(char) shit is for unicode, I assume this is
                           // good old one for our example.  those modifying for japanese
                           // should look at size_t stuff see fread definition
                           nBytesRead = fread( pbuf, sizeof( char ), readnum, fpSendFile );

                           if (nBytesRead != readnum )
                           {
                                    //MessageBox("Trouble reading local data file, bytes missing!");
                                    bret = -17;
                                    break;
                           }

                           // write those bytes to target on server
                           if (! InternetWriteFile(hIF, pbuf, readnum, &dwBytes) )
                           {
                                    //MessageBox("Trouble writing data file, write file fx");
                                    bret = -18;
                                    break;
                           }
                           if (readnum != dwBytes )
                           {
                                    //MessageBox("Trouble writing data file, bytes not written fully!");
                                    bret = -19;
                                    break;
                           }

                           // one way out of loop, we've finished file
                           if (iquit) {
                                    break;
                           }

                  }

         }

         // close files
         InternetCloseHandle(hIF);
         fclose(fpSendFile);

         // ah, the wonders of c++
         delete [] pbuf;
         InternetCloseHandle(hIC);
         InternetCloseHandle(hIS);

         // success, if bret == 1
         return bret;

}