home *** CD-ROM | disk | FTP | other *** search
/ ftp.ncftp.com / ftp.ncftp.com.zip / ftp.ncftp.com / ncftp / older_versions / ncftp-3.2.2-src.tar.bz2 / ncftp-3.2.2-src.tar / ncftp-3.2.2 / libncftp / io_getfiles.c < prev    next >
C/C++ Source or Header  |  2008-07-13  |  8KB  |  302 lines

  1. /* io_getfiles.c
  2.  *
  3.  * Copyright (c) 1996-2005 Mike Gleason, NcFTP Software.
  4.  * All rights reserved.
  5.  *
  6.  */
  7.  
  8. #include "syshdrs.h"
  9. #ifdef PRAGMA_HDRSTOP
  10. #    pragma hdrstop
  11. #endif
  12.  
  13. #if (defined(WIN32) || defined(_WINDOWS)) && !defined(__CYGWIN__)
  14. #    define ASCII_TRANSLATION 0
  15. #endif
  16.  
  17. #ifndef ASCII_TRANSLATION
  18. #    define ASCII_TRANSLATION 1
  19. #endif
  20.  
  21. #ifndef NO_SIGNALS
  22. #    define NO_SIGNALS 1
  23. #endif
  24.  
  25. #ifndef O_BINARY
  26.     /* Needed for platforms using different EOLN sequence (i.e. DOS) */
  27. #    ifdef _O_BINARY
  28. #        define O_BINARY _O_BINARY
  29. #    else
  30. #        define O_BINARY 0
  31. #    endif
  32. #endif
  33.  
  34. int
  35. FTPGetFiles3(
  36.     const FTPCIPtr cip,
  37.     const char *pattern1,
  38.     const char *const dstdir1,
  39.     const int recurse,
  40.     int doGlob,
  41.     const int xtype,
  42.     const int resumeflag,
  43.     int appendflag,
  44.     const int deleteflag,
  45.     const int tarflag,
  46.     const FTPConfirmResumeDownloadProc resumeProc,
  47.     int UNUSED(reserved))
  48. {
  49.     FTPLineList globList;
  50.     FTPLinePtr itemPtr;
  51.     FTPFileInfoList files;
  52.     FTPFileInfoPtr filePtr;
  53.     int batchResult;
  54.     int result;
  55.     char *ldir;
  56.     char *cp;
  57.     const char *dstdir;
  58.     const char *pattern;
  59.     char *pattern2, *dstdir2;
  60.     char c;
  61.     int recurse1;
  62.     int errRc;
  63.  
  64.     LIBNCFTP_USE_VAR(reserved);
  65.     if (cip == NULL)
  66.         return (kErrBadParameter);
  67.     if (strcmp(cip->magic, kLibraryMagic))
  68.         return (kErrBadMagic);
  69.     if (pattern1 == NULL)
  70.         return (kErrBadParameter);
  71.  
  72.     dstdir2 = NULL;
  73.     pattern2 = NULL;
  74.  
  75.     if (dstdir1 == NULL) {
  76.         dstdir = NULL;
  77.     } else {
  78.         dstdir2 = StrDup(dstdir1);
  79.         if (dstdir2 == NULL) {
  80.             errRc = kErrMallocFailed;
  81.             goto return_err;
  82.         }
  83.         StrRemoveTrailingLocalPathDelim(dstdir2);
  84.         dstdir = dstdir2;
  85.     }
  86.  
  87.     pattern2 = StrDup(pattern1);
  88.     if (pattern2 == NULL) {
  89.         errRc = kErrMallocFailed;
  90.         goto return_err;
  91.     }
  92.     StrRemoveTrailingSlashes(pattern2);
  93.     pattern = pattern2;
  94.  
  95.     if (pattern[0] == '\0') {
  96.         if (recurse == kRecursiveNo) {
  97.             errRc = kErrBadParameter;
  98.             goto return_err;
  99.         }
  100.         pattern = ".";
  101.         doGlob = kGlobNo;
  102.     } else if (strcmp(pattern, ".") == 0) {
  103.         if (recurse == kRecursiveNo) {
  104.             errRc = kErrBadParameter;
  105.             goto return_err;
  106.         }
  107.         doGlob = kGlobNo;
  108.     } else if ((strcmp(pattern, "/") == 0) && ((dstdir == NULL) || (strcmp(dstdir, ".") == 0) || (dstdir[0] == '\0'))) {
  109.         /* Ick... but works around a problem we need to fix */
  110.         free(pattern2);
  111.         pattern2 = StrDup("/.");
  112.         pattern = pattern2;
  113.         /*
  114.         errRc = kErrKnownBug;
  115.         goto return_err;
  116.         */
  117.     }
  118.     if (recurse == kRecursiveYes)
  119.         appendflag = kAppendNo;
  120.  
  121.     batchResult = FTPRemoteGlob(cip, &globList, pattern, doGlob);
  122.     if (batchResult != kNoErr) {
  123.         errRc = batchResult;
  124.         goto return_err;
  125.     }
  126.  
  127.     cip->cancelXfer = 0;    /* should already be zero */
  128.  
  129.     for (itemPtr = globList.first; itemPtr != NULL; itemPtr = itemPtr->next) {
  130.         if ((recurse == kRecursiveYes) && (FTPIsDir(cip, itemPtr->line) > 0)) {
  131. #ifdef TAR
  132.             if ((tarflag == kTarYes) && (xtype == kTypeBinary) && (appendflag == kAppendNo) && (deleteflag == kDeleteNo) && (FTPGetOneTarF(cip, itemPtr->line, dstdir) == kNoErr)) {
  133.                 /* Great! */
  134.                 continue;
  135.             }
  136. #endif    /* TAR */
  137.             (void) FTPRemoteRecursiveFileList1(cip, itemPtr->line, &files);
  138.             (void) ComputeLNames(&files, itemPtr->line, dstdir, 1);
  139.             recurse1 = recurse;
  140.         } else {
  141.             recurse1 = kRecursiveNo;
  142.             (void) LineToFileInfoList(itemPtr, &files);
  143.             (void) ComputeRNames(&files, ".", 0, 1);
  144.             (void) ComputeLNames(&files, NULL, dstdir, 0);
  145.         }
  146.         if (cip->cancelXfer > 0) {
  147.             DisposeFileInfoListContents(&files);
  148.             break;
  149.         }
  150.  
  151. #if 0
  152.         for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next) {
  153.             PrintF(cip, "  R=%s, L=%s, 2=%s, size=%lld, mdtm=%u, type=%c\n",
  154.                 filePtr->rname,
  155.                 filePtr->lname,
  156.                 filePtr->rlinkto ? filePtr->rlinkto : "",
  157.                 (longest_int) filePtr->size,
  158.                 (unsigned int) filePtr->mdtm,
  159.                 filePtr->type
  160.             );
  161.         }
  162. #endif
  163.  
  164.  
  165.         for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next) {
  166.             if (cip->connected == 0) {
  167.                 if (batchResult == kNoErr)
  168.                     batchResult = kErrRemoteHostClosedConnection;
  169.                 break;
  170.             }
  171.             if (filePtr->type == 'd') {
  172.                 (void) MkDirs(filePtr->lname, 00777);
  173.             } else if (filePtr->type == 'l') {
  174.                 /* skip it -- we do that next pass. */
  175.             } else if (recurse1 != kRecursiveYes) {
  176.                 result = FTPGetOneF(cip, filePtr->rname, filePtr->lname, xtype, -1, filePtr->size, filePtr->mdtm, resumeflag, appendflag, deleteflag, resumeProc);
  177.                 if (files.nFileInfos == 1) {
  178.                     if (result != kNoErr)
  179.                         batchResult = result;
  180.                 } else {
  181.                     if ((result != kNoErr) && (result != kErrLocalFileNewer) && (result != kErrRemoteFileNewer) && (result != kErrLocalSameAsRemote))
  182.                         batchResult = result;
  183.                 }
  184.                 if (result == kErrUserCanceled)
  185.                     cip->cancelXfer = 1;
  186.                 if (cip->cancelXfer > 0)
  187.                     break;
  188.             } else {
  189.                 ldir = filePtr->lname;
  190.                 cp = StrRFindLocalPathDelim(ldir);
  191.                 if (cp != NULL) {
  192.                     while (cp >= ldir) {
  193.                         if (! IsLocalPathDelim(*cp)) {
  194.                             ++cp;
  195.                             break;
  196.                         }
  197.                         --cp;
  198.                     }
  199.                     if (cp > ldir) {
  200.                         c = *cp;
  201.                         *cp = '\0';
  202.                         if (MkDirs(ldir, 00777) < 0) {
  203.                             FTPLogError(cip, kDoPerror, "Could not create local directory \"%s\"\n", ldir);
  204.                             batchResult = kErrGeneric;
  205.                             *cp = c;
  206.                             continue;
  207.                         }
  208.                         *cp = c;
  209.                     }
  210.                 }
  211.                 if (xtype == kTypeAscii) {
  212.                     /* Make sure we got the SIZE from
  213.                      * a SIZE command, and not a
  214.                      * directory listing, which may
  215.                      * not have taken into the account
  216.                      * the required end-of-line format
  217.                      * for text files sent over FTP.
  218.                      */
  219.                     if ((resumeflag == kResumeYes) || (resumeProc != kNoFTPConfirmResumeDownloadProc)) {
  220.                         FTPCheckForRestartModeAvailability(cip); 
  221.                     }
  222.                     result = FTPSetTransferType(cip, xtype);
  223.                     if (result < 0)
  224.                         return (result);
  225.                     (void) FTPFileSize(cip, filePtr->rname, &filePtr->size, xtype);
  226.                 }
  227.                 result = FTPGetOneF(cip, filePtr->rname, filePtr->lname, xtype, -1, filePtr->size, filePtr->mdtm, resumeflag, appendflag, deleteflag, resumeProc);
  228.  
  229.                 if (files.nFileInfos == 1) {
  230.                     if (result != kNoErr)
  231.                         batchResult = result;
  232.                 } else {
  233.                     if ((result != kNoErr) && (result != kErrLocalFileNewer) && (result != kErrRemoteFileNewer) && (result != kErrLocalSameAsRemote))
  234.                         batchResult = result;
  235.                 }
  236.                 if (result == kErrUserCanceled)
  237.                     cip->cancelXfer = 1;
  238.                 if (cip->cancelXfer > 0)
  239.                     break;
  240.             }
  241.         }
  242.         if (cip->cancelXfer > 0) {
  243.             DisposeFileInfoListContents(&files);
  244.             break;
  245.         }
  246.  
  247. #ifdef HAVE_SYMLINK
  248.         for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next) {
  249.             if (filePtr->type == 'l') {
  250.                 (void) unlink(filePtr->lname);
  251.                 if (symlink(filePtr->rlinkto, filePtr->lname) < 0) {
  252.                     FTPLogError(cip, kDoPerror, "Could not symlink %s to %s\n", filePtr->rlinkto, filePtr->lname);
  253.                     /* Note: not worth setting batchResult */
  254.                 }
  255.             }
  256.         }
  257. #endif    /* HAVE_SYMLINK */
  258.  
  259.  
  260.         DisposeFileInfoListContents(&files);
  261.     }
  262.  
  263.     DisposeLineListContents(&globList);
  264.     if (batchResult < 0)
  265.         cip->errNo = batchResult;
  266.     errRc = batchResult;
  267.  
  268. return_err:
  269.     if (dstdir2 != NULL)
  270.         free(dstdir2);
  271.     if (pattern2 != NULL)
  272.         free(pattern2);
  273.     return (errRc);
  274. }    /* FTPGetFiles3 */
  275.  
  276.  
  277.  
  278.  
  279. int
  280. FTPGetFiles(const FTPCIPtr cip, const char *const pattern, const char *const dstdir, const int recurse, const int doGlob)
  281. {
  282.     return (FTPGetFiles3(cip, pattern, dstdir, recurse, doGlob, kTypeBinary, kResumeNo, kAppendNo, kDeleteNo, kTarYes, (FTPConfirmResumeDownloadProc) 0, 0));
  283. }    /* FTPGetFiles */
  284.  
  285.  
  286.  
  287.  
  288. int
  289. FTPGetFiles2(const FTPCIPtr cip, const char *const pattern, const char *const dstdir, const int recurse, const int doGlob, const int xtype, const int resumeflag, const int appendflag)
  290. {
  291.     return (FTPGetFiles3(cip, pattern, dstdir, recurse, doGlob, xtype, resumeflag, appendflag, kDeleteNo, kTarYes, (FTPConfirmResumeDownloadProc) 0, 0));
  292. }    /* FTPGetFiles2 */
  293.  
  294.  
  295.  
  296.  
  297. int
  298. FTPGetFilesAscii(const FTPCIPtr cip, const char *const pattern, const char *const dstdir, const int recurse, const int doGlob)
  299. {
  300.     return (FTPGetFiles3(cip, pattern, dstdir, recurse, doGlob, kTypeAscii, kResumeNo, kAppendNo, kDeleteNo, kTarNo, (FTPConfirmResumeDownloadProc) 0, 0));
  301. }    /* FTPGetFilesAscii */
  302.