ReactOS 0.4.15-dev-7934-g1dc8d80
io.c File Reference
#include "syshdrs.h"
Include dependency graph for io.c:

Go to the source code of this file.

Macros

#define ASCII_TRANSLATION   1
 
#define O_BINARY   0
 

Functions

static int WaitForRemoteInput (const FTPCIPtr cip)
 
static int WaitForRemoteOutput (const FTPCIPtr cip)
 
void FTPInitIOTimer (const FTPCIPtr cip)
 
void FTPStartIOTimer (const FTPCIPtr cip)
 
void FTPUpdateIOTimer (const FTPCIPtr cip)
 
void FTPStopIOTimer (const FTPCIPtr cip)
 
int FTPList (const FTPCIPtr cip, const int outfd, const int longMode, const char *const lsflag)
 
static void FTPRequestMlsOptions (const FTPCIPtr cip)
 
int FTPListToMemory2 (const FTPCIPtr cip, const char *const pattern, const LineListPtr llines, const char *const lsflags, const int blankLines, int *const tryMLSD)
 
static void AutomaticallyUseASCIIModeDependingOnExtension (const FTPCIPtr cip, const char *const pathName, int *const xtype)
 
static int FTPPutOneF (const FTPCIPtr cip, const char *const file, const char *volatile dstfile, int xtype, const int fdtouse, const int appendflag, const char *volatile tmppfx, const char *volatile tmpsfx, const int resumeflag, const int deleteflag, const ConfirmResumeUploadProc resumeProc)
 
int FTPPutOneFile3 (const FTPCIPtr cip, const char *const file, const char *const dstfile, const int xtype, const int fdtouse, const int appendflag, const char *const tmppfx, const char *const tmpsfx, const int resumeflag, const int deleteflag, const ConfirmResumeUploadProc resumeProc, int UNUSED(reserved))
 
int FTPPutFiles3 (const FTPCIPtr cip, const char *const pattern, const char *const dstdir1, const int recurse, const int doGlob, const int xtype, int appendflag, const char *const tmppfx, const char *const tmpsfx, const int resumeflag, const int deleteflag, const ConfirmResumeUploadProc resumeProc, int UNUSED(reserved))
 
static int FTPGetOneF (const FTPCIPtr cip, const char *const file, const char *dstfile, int xtype, const int fdtouse, longest_int expectedSize, time_t mdtm, const int resumeflag, const int appendflag, const int deleteflag, const ConfirmResumeDownloadProc resumeProc)
 
int FTPGetOneFile3 (const FTPCIPtr cip, const char *const file, const char *const dstfile, const int xtype, const int fdtouse, const int resumeflag, const int appendflag, const int deleteflag, const ConfirmResumeDownloadProc resumeProc, int UNUSED(reserved))
 
int FTPGetFiles3 (const FTPCIPtr cip, const char *pattern1, const char *const dstdir1, const int recurse, int doGlob, const int xtype, const int resumeflag, int appendflag, const int deleteflag, const int tarflag, const ConfirmResumeDownloadProc resumeProc, int UNUSED(reserved))
 
int FTPGetOneFile (const FTPCIPtr cip, const char *const file, const char *const dstfile)
 
int FTPGetOneFile2 (const FTPCIPtr cip, const char *const file, const char *const dstfile, const int xtype, const int fdtouse, const int resumeflag, const int appendflag)
 
int FTPGetFiles (const FTPCIPtr cip, const char *const pattern, const char *const dstdir, const int recurse, const int doGlob)
 
int 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)
 
int FTPGetOneFileAscii (const FTPCIPtr cip, const char *const file, const char *const dstfile)
 
int FTPGetFilesAscii (const FTPCIPtr cip, const char *const pattern, const char *const dstdir, const int recurse, const int doGlob)
 
int FTPPutOneFile (const FTPCIPtr cip, const char *const file, const char *const dstfile)
 
int FTPPutOneFile2 (const FTPCIPtr cip, const char *const file, const char *const dstfile, const int xtype, const int fdtouse, const int appendflag, const char *const tmppfx, const char *const tmpsfx)
 
int FTPPutFiles (const FTPCIPtr cip, const char *const pattern, const char *const dstdir, const int recurse, const int doGlob)
 
int FTPPutFiles2 (const FTPCIPtr cip, const char *const pattern, const char *const dstdir, const int recurse, const int doGlob, const int xtype, const int appendflag, const char *const tmppfx, const char *const tmpsfx)
 
int FTPPutOneFileAscii (const FTPCIPtr cip, const char *const file, const char *const dstfile)
 
int FTPPutFilesAscii (const FTPCIPtr cip, const char *const pattern, const char *const dstdir, const int recurse, const int doGlob)
 
int FTPListToMemory (const FTPCIPtr cip, const char *const pattern, const LineListPtr llines, const char *const lsflags)
 

Variables

static int gGotBrokenData = 0
 

Macro Definition Documentation

◆ ASCII_TRANSLATION

#define ASCII_TRANSLATION   1

Definition at line 17 of file io.c.

◆ O_BINARY

#define O_BINARY   0

Definition at line 41 of file io.c.

Function Documentation

◆ AutomaticallyUseASCIIModeDependingOnExtension()

static void AutomaticallyUseASCIIModeDependingOnExtension ( const FTPCIPtr  cip,
const char *const  pathName,
int *const  xtype 
)
static

Definition at line 565 of file io.c.

566{
567 if ((*xtype == kTypeBinary) && (cip->asciiFilenameExtensions != NULL)) {
569 /* Matched -- send this file in ASCII mode
570 * instead of binary since it's extension
571 * appears to be that of a text file.
572 */
573 *xtype = kTypeAscii;
574 }
575 }
576} /* AutomaticallyUseASCIIModeDependingOnExtension */
#define NULL
Definition: types.h:112
#define kTypeAscii
Definition: ncftp.h:353
int FilenameExtensionIndicatesASCII(const char *const pathName, const char *const extnList)
Definition: util.c:963
#define kTypeBinary
Definition: ncftp.h:354
const char * asciiFilenameExtensions
Definition: ncftp.h:246

Referenced by FTPGetOneF(), and FTPPutOneF().

◆ FTPGetFiles()

int FTPGetFiles ( const FTPCIPtr  cip,
const char *const  pattern,
const char *const  dstdir,
const int  recurse,
const int  doGlob 
)

Definition at line 2730 of file io.c.

2731{
2732 return (FTPGetFiles3(cip, pattern, dstdir, recurse, doGlob, kTypeBinary, kResumeNo, kAppendNo, kDeleteNo, kTarYes, (ConfirmResumeDownloadProc) 0, 0));
2733} /* FTPGetFiles */
GLubyte * pattern
Definition: glext.h:7787
int FTPGetFiles3(const FTPCIPtr cip, const char *pattern1, const char *const dstdir1, const int recurse, int doGlob, const int xtype, const int resumeflag, int appendflag, const int deleteflag, const int tarflag, const ConfirmResumeDownloadProc resumeProc, int UNUSED(reserved))
Definition: io.c:2486
#define kDeleteNo
Definition: ncftp.h:369
#define kTarYes
Definition: ncftp.h:370
#define kAppendNo
Definition: ncftp.h:365
int(* ConfirmResumeDownloadProc)(const char *volatile *localpath, volatile longest_int localsize, volatile time_t localmtime, const char *volatile remotepath, volatile longest_int remotesize, volatile time_t remotetime, volatile longest_int *volatile startPoint)
Definition: ncftp.h:431
#define kResumeNo
Definition: ncftp.h:367

◆ FTPGetFiles2()

int 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 
)

Definition at line 2739 of file io.c.

2740{
2741 return (FTPGetFiles3(cip, pattern, dstdir, recurse, doGlob, xtype, resumeflag, appendflag, kDeleteNo, kTarYes, (ConfirmResumeDownloadProc) 0, 0));
2742} /* FTPGetFiles2 */

◆ FTPGetFiles3()

int FTPGetFiles3 ( const FTPCIPtr  cip,
const char pattern1,
const char *const  dstdir1,
const int  recurse,
int  doGlob,
const int  xtype,
const int  resumeflag,
int  appendflag,
const int  deleteflag,
const int  tarflag,
const ConfirmResumeDownloadProc  resumeProc,
int   UNUSEDreserved 
)

Definition at line 2486 of file io.c.

2499{
2500 LineList globList;
2501 LinePtr itemPtr;
2502 FileInfoList files;
2503 FileInfoPtr filePtr;
2504 int batchResult;
2505 int result;
2506 char *ldir;
2507 char *cp;
2508 const char *dstdir;
2509 const char *pattern;
2510 char *pattern2, *dstdir2;
2511 char c;
2512 int recurse1;
2513 int errRc;
2514
2516 if (cip == NULL)
2517 return (kErrBadParameter);
2518 if (strcmp(cip->magic, kLibraryMagic))
2519 return (kErrBadMagic);
2520 if (pattern1 == NULL)
2521 return (kErrBadParameter);
2522
2523 dstdir2 = NULL;
2524 pattern2 = NULL;
2525
2526 if (dstdir1 == NULL) {
2527 dstdir = NULL;
2528 } else {
2529 dstdir2 = StrDup(dstdir1);
2530 if (dstdir2 == NULL) {
2531 errRc = kErrMallocFailed;
2532 goto return_err;
2533 }
2535 dstdir = dstdir2;
2536 }
2537
2538 pattern2 = StrDup(pattern1);
2539 if (pattern2 == NULL) {
2540 errRc = kErrMallocFailed;
2541 goto return_err;
2542 }
2543 StrRemoveTrailingSlashes(pattern2);
2544 pattern = pattern2;
2545
2546 if (pattern[0] == '\0') {
2547 if (recurse == kRecursiveNo) {
2548 errRc = kErrBadParameter;
2549 goto return_err;
2550 }
2551 pattern = ".";
2552 doGlob = kGlobNo;
2553 } else if (strcmp(pattern, ".") == 0) {
2554 if (recurse == kRecursiveNo) {
2555 errRc = kErrBadParameter;
2556 goto return_err;
2557 }
2558 doGlob = kGlobNo;
2559 }
2560 if (recurse == kRecursiveYes)
2561 appendflag = kAppendNo;
2562
2563 batchResult = FTPRemoteGlob(cip, &globList, pattern, doGlob);
2564 if (batchResult != kNoErr) {
2565 errRc = batchResult;
2566 goto return_err;
2567 }
2568
2569 cip->cancelXfer = 0; /* should already be zero */
2570
2571 for (itemPtr = globList.first; itemPtr != NULL; itemPtr = itemPtr->next) {
2572 if ((recurse == kRecursiveYes) && (FTPIsDir(cip, itemPtr->line) > 0)) {
2573#ifdef TAR
2574 if ((tarflag == kTarYes) && (xtype == kTypeBinary) && (appendflag == kAppendNo) && (deleteflag == kDeleteNo) && (FTPGetOneTarF(cip, itemPtr->line, dstdir) == kNoErr)) {
2575 /* Great! */
2576 continue;
2577 }
2578#endif /* TAR */
2579 (void) FTPRemoteRecursiveFileList1(cip, itemPtr->line, &files);
2580 (void) ComputeLNames(&files, itemPtr->line, dstdir, 1);
2581 recurse1 = recurse;
2582 } else {
2583 recurse1 = kRecursiveNo;
2584 (void) LineToFileInfoList(itemPtr, &files);
2585 (void) ComputeRNames(&files, ".", 0, 1);
2586 (void) ComputeLNames(&files, NULL, dstdir, 0);
2587 }
2588 if (cip->cancelXfer > 0) {
2590 break;
2591 }
2592
2593#if 0
2594 for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next) {
2595 PrintF(cip, " R=%s, L=%s, 2=%s, size=%d, mdtm=%u, type=%c\n",
2596 filePtr->rname,
2597 filePtr->lname,
2598 filePtr->rlinkto ? filePtr->rlinkto : "",
2599 filePtr->size,
2600 (unsigned int) filePtr->mdtm,
2601 filePtr->type
2602 );
2603 }
2604#endif
2605
2606
2607 for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next) {
2608 if (cip->connected == 0) {
2609 if (batchResult == kNoErr)
2610 batchResult = kErrRemoteHostClosedConnection;
2611 break;
2612 }
2613 if (filePtr->type == 'd') {
2614#if defined(WIN32) || defined(_WINDOWS)
2615 (void) MkDirs(filePtr->lname, 00777);
2616#else
2617 (void) mkdir(filePtr->lname, 00777);
2618#endif
2619 } else if (filePtr->type == 'l') {
2620 /* skip it -- we do that next pass. */
2621 } else if (recurse1 != kRecursiveYes) {
2622 result = FTPGetOneF(cip, filePtr->rname, filePtr->lname, xtype, -1, filePtr->size, filePtr->mdtm, resumeflag, appendflag, deleteflag, resumeProc);
2623 if (files.nFileInfos == 1) {
2624 if (result != kNoErr)
2625 batchResult = result;
2626 } else {
2628 batchResult = result;
2629 }
2630 if (result == kErrUserCanceled)
2631 cip->cancelXfer = 1;
2632 if (cip->cancelXfer > 0)
2633 break;
2634 } else {
2635 ldir = filePtr->lname;
2636 cp = StrRFindLocalPathDelim(ldir);
2637 if (cp != NULL) {
2638 while (cp > ldir) {
2639 if (! IsLocalPathDelim(*cp)) {
2640 ++cp;
2641 break;
2642 }
2643 --cp;
2644 }
2645 if (cp > ldir) {
2646 c = *cp;
2647 *cp = '\0';
2648 if (MkDirs(ldir, 00777) < 0) {
2649 Error(cip, kDoPerror, "Could not create local directory \"%s\"\n", ldir);
2650 batchResult = kErrGeneric;
2651 *cp = c;
2652 continue;
2653 }
2654 *cp = c;
2655 }
2656 }
2657 result = FTPGetOneF(cip, filePtr->rname, filePtr->lname, xtype, -1, filePtr->size, filePtr->mdtm, resumeflag, appendflag, deleteflag, resumeProc);
2658
2659 if (files.nFileInfos == 1) {
2660 if (result != kNoErr)
2661 batchResult = result;
2662 } else {
2664 batchResult = result;
2665 }
2666 if (result == kErrUserCanceled)
2667 cip->cancelXfer = 1;
2668 if (cip->cancelXfer > 0)
2669 break;
2670 }
2671 }
2672 if (cip->cancelXfer > 0) {
2674 break;
2675 }
2676
2677#ifdef HAVE_SYMLINK
2678 for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next) {
2679 if (filePtr->type == 'l') {
2680 (void) unlink(filePtr->lname);
2681 if (symlink(filePtr->rlinkto, filePtr->lname) < 0) {
2682 Error(cip, kDoPerror, "Could not symlink %s to %s\n", filePtr->rlinkto, filePtr->lname);
2683 /* Note: not worth setting batchResult */
2684 }
2685 }
2686 }
2687#endif /* HAVE_SYMLINK */
2688
2689
2691 }
2692
2693 DisposeLineListContents(&globList);
2694 if (batchResult < 0)
2695 cip->errNo = batchResult;
2696 errRc = batchResult;
2697
2698return_err:
2699 if (dstdir2 != NULL)
2700 free(dstdir2);
2701 if (pattern2 != NULL)
2702 free(pattern2);
2703 return (errRc);
2704} /* FTPGetFiles3 */
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define mkdir
Definition: acwin.h:101
BOOL Error
Definition: chkdsk.c:66
#define free
Definition: debug_ros.c:5
r reserved
Definition: btrfs.c:3006
const GLubyte * c
Definition: glext.h:8905
GLuint64EXT * result
Definition: glext.h:11304
int FTPRemoteRecursiveFileList1(FTPCIPtr cip, char *const rdir, FileInfoListPtr files)
Definition: glob.c:983
int FTPRemoteGlob(FTPCIPtr cip, LineListPtr fileList, const char *pattern, int doGlob)
Definition: glob.c:1341
#define c
Definition: ke_i.h:80
#define unlink
Definition: syshdrs.h:54
int ComputeLNames(FileInfoListPtr dst, const char *srcdir, const char *dstdir, int nochop)
Definition: linelist.c:663
int ComputeRNames(FileInfoListPtr dst, const char *dstdir, int pflag, int nochop)
Definition: linelist.c:579
int LineToFileInfoList(LinePtr lp, FileInfoListPtr dst)
Definition: linelist.c:775
void DisposeFileInfoListContents(FileInfoListPtr list)
Definition: linelist.c:152
void DisposeLineListContents(LineListPtr list)
Definition: linelist.c:33
POINT cp
Definition: magnifier.c:59
int FTPIsDir(const FTPCIPtr cip, const char *const dir)
Definition: cmds.c:1531
static int FTPGetOneF(const FTPCIPtr cip, const char *const file, const char *dstfile, int xtype, const int fdtouse, longest_int expectedSize, time_t mdtm, const int resumeflag, const int appendflag, const int deleteflag, const ConfirmResumeDownloadProc resumeProc)
Definition: io.c:1817
void PrintF(const FTPCIPtr cip, const char *const fmt,...)
Definition: util.c:340
#define kDoPerror
Definition: util.h:44
#define kGlobNo
Definition: ncftp.h:361
#define StrRFindLocalPathDelim(a)
Definition: ncftp.h:495
int MkDirs(const char *const, int mode1)
Definition: util.c:785
#define StrRemoveTrailingLocalPathDelim
Definition: ncftp.h:496
#define kLibraryMagic
Definition: ncftp.h:65
#define IsLocalPathDelim(c)
Definition: ncftp.h:497
#define kRecursiveNo
Definition: ncftp.h:363
void StrRemoveTrailingSlashes(char *dst)
Definition: util.c:768
#define kRecursiveYes
Definition: ncftp.h:362
#define LIBNCFTP_USE_VAR(a)
Definition: ncftp.h:521
#define kNoErr
Definition: ncftp_errno.h:9
#define kErrMallocFailed
Definition: ncftp_errno.h:40
#define kErrLocalFileNewer
Definition: ncftp_errno.h:93
#define kErrRemoteFileNewer
Definition: ncftp_errno.h:94
#define kErrBadMagic
Definition: ncftp_errno.h:55
#define kErrUserCanceled
Definition: ncftp_errno.h:112
#define kErrGeneric
Definition: ncftp_errno.h:13
#define kErrBadParameter
Definition: ncftp_errno.h:56
#define kErrLocalSameAsRemote
Definition: ncftp_errno.h:95
#define kErrRemoteHostClosedConnection
Definition: ncftp_errno.h:75
#define StrDup
Definition: shlwapi.h:1533
char magic[16]
Definition: ncftp.h:135
FileInfoPtr first
Definition: ncftp.h:265
int nFileInfos
Definition: ncftp.h:269
longest_int size
Definition: ncftp.h:260
int type
Definition: ncftp.h:258
char * lname
Definition: ncftp.h:256
char * rlinkto
Definition: ncftp.h:255
time_t mdtm
Definition: ncftp.h:259
FileInfoPtr next
Definition: ncftp.h:252
char * rname
Definition: ncftp.h:254
Definition: ncftp.h:84
LinePtr first
Definition: ncftp.h:85
Definition: ncftp.h:79
char * line
Definition: ncftp.h:81
LinePtr next
Definition: ncftp.h:80

Referenced by FTPGetFiles(), FTPGetFiles2(), FTPGetFilesAscii(), and GetCmd().

◆ FTPGetFilesAscii()

int FTPGetFilesAscii ( const FTPCIPtr  cip,
const char *const  pattern,
const char *const  dstdir,
const int  recurse,
const int  doGlob 
)

Definition at line 2757 of file io.c.

2758{
2759 return (FTPGetFiles3(cip, pattern, dstdir, recurse, doGlob, kTypeAscii, kResumeNo, kAppendNo, kDeleteNo, kTarNo, (ConfirmResumeDownloadProc) 0, 0));
2760} /* FTPGetFilesAscii */
#define kTarNo
Definition: ncftp.h:371

◆ FTPGetOneF()

static int FTPGetOneF ( const FTPCIPtr  cip,
const char *const  file,
const char dstfile,
int  xtype,
const int  fdtouse,
longest_int  expectedSize,
time_t  mdtm,
const int  resumeflag,
const int  appendflag,
const int  deleteflag,
const ConfirmResumeDownloadProc  resumeProc 
)
static

Definition at line 1817 of file io.c.

1829{
1830 char *buf;
1831 size_t bufSize;
1832 int tmpResult;
1833 volatile int result;
1834 int nread, nwrote;
1835 volatile int fd;
1836#if ASCII_TRANSLATION
1837 char *src, *srclim;
1838 char *dst, *dstlim;
1839 char outbuf[512];
1840#endif
1841 volatile longest_int startPoint = 0;
1842 struct utimbuf ut;
1843 struct Stat st;
1844#if !defined(NO_SIGNALS)
1845 volatile FTPSigProc osigpipe;
1846 volatile FTPCIPtr vcip;
1847 volatile int vfd, vfdtouse;
1848 int sj;
1849#endif /* NO_SIGNALS */
1850 volatile int created = 0;
1851 int zaction = kConfirmResumeProcSaidBestGuess;
1852 int statrc;
1853 int noMdtmCheck;
1854 time_t now;
1855
1856 if (cip->buf == NULL) {
1857 Error(cip, kDoPerror, "Transfer buffer not allocated.\n");
1858 cip->errNo = kErrNoBuf;
1859 return (cip->errNo);
1860 }
1861
1862 result = kNoErr;
1863 cip->usingTAR = 0;
1864
1865 if (fdtouse < 0) {
1866 /* Only ask for extended information
1867 * if we have the name of the file
1868 * and we didn't already have the
1869 * info.
1870 *
1871 * Always ask for the modification time,
1872 * because even if it was passed in it
1873 * may not be accurate. This is often
1874 * the case when it came from an ls
1875 * listing, in which the local time
1876 * zone could be a factor.
1877 *
1878 */
1879
1881 if (expectedSize == kSizeUnknown) {
1882 (void) FTPFileSizeAndModificationTime(cip, file, &expectedSize, xtype, &mdtm);
1883 } else {
1884 (void) FTPFileModificationTime(cip, file, &mdtm);
1885 }
1886
1887 /* For Get, we can't recover very well if it turns out restart
1888 * didn't work, so check beforehand.
1889 */
1890 if ((resumeflag == kResumeYes) || (resumeProc != NoConfirmResumeDownloadProc)) {
1893 if (SetStartOffset(cip, (longest_int) 1) == kNoErr) {
1894 /* Now revert -- we still may not end up
1895 * doing it.
1896 */
1897 SetStartOffset(cip, (longest_int) -1);
1898 }
1899 }
1900 }
1901
1902 if (appendflag == kAppendYes) {
1904 } else if (cip->hasREST == kCommandNotAvailable) {
1906 } else if (resumeflag == kResumeYes) {
1908 } else {
1910 }
1911
1912 statrc = Stat(dstfile, &st);
1913 if (statrc == 0) {
1914 if (resumeProc != NULL) {
1915 zaction = (*resumeProc)(
1916 &dstfile,
1917 (longest_int) st.st_size,
1918 st.st_mtime,
1919 file,
1920 expectedSize,
1921 mdtm,
1922 &startPoint
1923 );
1924 }
1925
1926 if (zaction == kConfirmResumeProcSaidBestGuess) {
1927 if (expectedSize != kSizeUnknown) {
1928 /* We know the size of the remote file,
1929 * and we have a local file too.
1930 *
1931 * Try and decide if we need to get
1932 * the entire file, or just part of it.
1933 */
1934
1935 startPoint = (longest_int) st.st_size;
1937
1938 /* If the local file exists and has a recent
1939 * modification time (< 12 hours) and
1940 * the remote file's modtime is not recent,
1941 * then heuristically conclude that the
1942 * local modtime should not be trusted
1943 * (i.e. user killed the process before
1944 * the local modtime could be preserved).
1945 */
1946 noMdtmCheck = 0;
1947 if (mdtm != kModTimeUnknown) {
1948 time(&now);
1949 if ((st.st_mtime > now) || (((now - st.st_mtime) < 46200) && ((now - mdtm) >= 46200)))
1950 noMdtmCheck = 1;
1951 }
1952
1953 if ((mdtm == kModTimeUnknown) || (noMdtmCheck != 0)) {
1954 /* Can't use the timestamps as an aid. */
1955 if (startPoint == expectedSize) {
1956 /* Don't go to all the trouble of downloading nothing. */
1958 if (deleteflag == kDeleteYes)
1960 return (cip->errNo);
1961 } else if (startPoint > expectedSize) {
1962 /* Panic; odds are the file we have
1963 * was a different file altogether,
1964 * since it is larger than the
1965 * remote copy. Re-do it all.
1966 */
1968 } /* else resume at startPoint */
1969 } else if ((mdtm == st.st_mtime) || (mdtm == (st.st_mtime - 1)) || (mdtm == (st.st_mtime + 1))) {
1970 /* File has the same time.
1971 * Note: Windows' file timestamps can be off by one second!
1972 */
1973 if (startPoint == expectedSize) {
1974 /* Don't go to all the trouble of downloading nothing. */
1976 if (deleteflag == kDeleteYes)
1978 return (cip->errNo);
1979 } else if (startPoint > expectedSize) {
1980 /* Panic; odds are the file we have
1981 * was a different file altogether,
1982 * since it is larger than the
1983 * remote copy. Re-do it all.
1984 */
1986 } else {
1987 /* We have a file by the same time,
1988 * but smaller start point. Leave
1989 * the startpoint as is since it
1990 * is most likely valid.
1991 */
1992 }
1993 } else if (mdtm < st.st_mtime) {
1994 /* Remote file is older than
1995 * local file. Don't overwrite
1996 * our file.
1997 */
1999 return (cip->errNo);
2000 } else /* if (mdtm > st.st_mtime) */ {
2001 /* File has a newer timestamp
2002 * altogether, assume the remote
2003 * file is an entirely new file
2004 * and replace ours with it.
2005 */
2007 }
2008 } else {
2010 }
2011 }
2012 } else {
2014 }
2015
2016 if (zaction == kConfirmResumeProcSaidCancel) {
2017 /* User wants to cancel this file and any
2018 * remaining in batch.
2019 */
2020 cip->errNo = kErrUserCanceled;
2021 return (cip->errNo);
2022 } else if (zaction == kConfirmResumeProcSaidSkip) {
2023 /* Nothing done, but not an error. */
2024 if (deleteflag == kDeleteYes)
2026 return (kNoErr);
2027 } else if (zaction == kConfirmResumeProcSaidResume) {
2028 /* Resume; proc set the startPoint. */
2029 if (startPoint == expectedSize) {
2030 /* Don't go to all the trouble of downloading nothing. */
2031 /* Nothing done, but not an error. */
2032 if (deleteflag == kDeleteYes)
2034 return (kNoErr);
2035 } else if (startPoint > expectedSize) {
2036 /* Cannot set start point past end of remote file */
2038 return (result);
2039 }
2040 fd = Open(dstfile, O_WRONLY|O_APPEND|O_BINARY, 00666);
2041 } else if (zaction == kConfirmResumeProcSaidAppend) {
2042 /* leave startPoint at zero, we will append everything. */
2043 startPoint = (longest_int) 0;
2044 fd = Open(dstfile, O_WRONLY|O_CREAT|O_APPEND|O_BINARY, 00666);
2045 } else /* if (zaction == kConfirmResumeProcSaidOverwrite) */ {
2046 created = 1;
2047 startPoint = (longest_int) 0;
2048 fd = Open(dstfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 00666);
2049 }
2050
2051 if (fd < 0) {
2052 Error(cip, kDoPerror, "Cannot open local file %s for writing.\n", dstfile);
2054 cip->errNo = kErrOpenFailed;
2055 return (result);
2056 }
2057
2058 if ((expectedSize == (longest_int) 0) && (startPoint <= (longest_int) 0) && (zaction != kConfirmResumeProcSaidOverwrite)) {
2059 /* Don't go to all the trouble of downloading nothing. */
2060#if defined(WIN32) || defined(_WINDOWS)
2061 /* Note: Windows doesn't allow zero-size files. */
2062 (void) write(fd, "\r\n", 2);
2063#endif
2064 (void) close(fd);
2065 if (mdtm != kModTimeUnknown) {
2066 cip->mdtm = mdtm;
2067 (void) time(&ut.actime);
2068 ut.modtime = mdtm;
2069 (void) utime(dstfile, &ut);
2070 }
2071 if (deleteflag == kDeleteYes)
2073 return (kNoErr);
2074 }
2075 } else {
2076 fd = fdtouse;
2077 }
2078
2079 if ((cip->numDownloads == 0) && (cip->dataSocketRBufSize > 0)) {
2080 /* If dataSocketSBufSize is non-zero, it means you
2081 * want to explicitly try to set the size of the
2082 * socket's I/O buffer.
2083 *
2084 * If it is zero, it means you want to just use the
2085 * TCP stack's default value, which is typically
2086 * between 8 and 64 kB.
2087 *
2088 * If you try to set the buffer larger than 64 kB,
2089 * the TCP stack should try to use RFC 1323 to
2090 * negotiate "TCP Large Windows" which may yield
2091 * significant performance gains.
2092 */
2094 (void) FTPCmd(cip, "SITE RETRBUFSIZE %lu", (unsigned long) cip->dataSocketRBufSize);
2095 else if (cip->hasRBUFSIZ == kCommandAvailable)
2096 (void) FTPCmd(cip, "SITE RBUFSIZ %lu", (unsigned long) cip->dataSocketRBufSize);
2097 else if (cip->hasRBUFSZ == kCommandAvailable)
2098 (void) FTPCmd(cip, "SITE RBUFSZ %lu", (unsigned long) cip->dataSocketRBufSize);
2099 else if (cip->hasBUFSIZE == kCommandAvailable)
2100 (void) FTPCmd(cip, "SITE BUFSIZE %lu", (unsigned long) cip->dataSocketSBufSize);
2101 }
2102
2103#ifdef NO_SIGNALS
2104#else /* NO_SIGNALS */
2105 vcip = cip;
2106 vfdtouse = fdtouse;
2107 vfd = fd;
2108 osigpipe = (volatile FTPSigProc) signal(SIGPIPE, BrokenData);
2109
2110 gGotBrokenData = 0;
2111 gCanBrokenDataJmp = 0;
2112
2113#ifdef HAVE_SIGSETJMP
2114 sj = sigsetjmp(gBrokenDataJmp, 1);
2115#else
2116 sj = setjmp(gBrokenDataJmp);
2117#endif /* HAVE_SIGSETJMP */
2118
2119 if (sj != 0) {
2120 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
2121 if (vfdtouse < 0) {
2122 (void) close(vfd);
2123 }
2124 FTPShutdownHost(vcip);
2126 return(vcip->errNo);
2127 }
2128 gCanBrokenDataJmp = 1;
2129#endif /* NO_SIGNALS */
2130
2131 tmpResult = FTPStartDataCmd(cip, kNetReading, xtype, startPoint, "RETR %s", file);
2132
2133 if (tmpResult < 0) {
2134 result = tmpResult;
2135 if (result == kErrGeneric)
2137 cip->errNo = result;
2138 if (fdtouse < 0) {
2139 (void) close(fd);
2140 if ((created != 0) && (appendflag == kAppendNo) && (cip->startPoint == 0))
2141 (void) unlink(dstfile);
2142 }
2143#if !defined(NO_SIGNALS)
2144 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
2145#endif /* NO_SIGNALS */
2146 return (result);
2147 }
2148
2149 if ((startPoint != 0) && (cip->startPoint == 0)) {
2150 /* Remote could not or would not set the start offset
2151 * to what we wanted.
2152 *
2153 * So now we have to undo our seek.
2154 */
2155 if (Lseek(fd, (off_t) 0, SEEK_SET) != (off_t) 0) {
2156 cip->errNo = kErrLseekFailed;
2157 if (fdtouse < 0) {
2158 (void) close(fd);
2159 }
2160#if !defined(NO_SIGNALS)
2161 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
2162#endif /* NO_SIGNALS */
2163 return (cip->errNo);
2164 }
2165 startPoint = 0;
2166 }
2167
2168 buf = cip->buf;
2169 bufSize = cip->bufSize;
2170
2171 FTPInitIOTimer(cip);
2172 cip->mdtm = mdtm;
2173 (void) time(&ut.actime);
2174 ut.modtime = mdtm;
2175 cip->expectedSize = expectedSize;
2176 cip->lname = dstfile; /* could be NULL */
2177 cip->rname = file;
2178 if (fdtouse >= 0)
2179 cip->useProgressMeter = 0;
2180 FTPStartIOTimer(cip);
2181
2182#if ASCII_TRANSLATION
2183 if (xtype == kTypeAscii) {
2184 /* Ascii */
2185 for (;;) {
2186 if (! WaitForRemoteInput(cip)) { /* could set cancelXfer */
2187 cip->errNo = result = kErrDataTimedOut;
2188 Error(cip, kDontPerror, "Remote read timed out.\n");
2189 break;
2190 }
2191 if (cip->cancelXfer > 0) {
2194 break;
2195 }
2196#ifdef TESTING_ABOR
2197 if (cip->bytesTransferred > 0) {
2198 cip->cancelXfer = 1;
2201 break;
2202 }
2203#endif /* TESTING_ABOR */
2204#ifdef NO_SIGNALS
2206 if (nread == kTimeoutErr) {
2207 cip->errNo = result = kErrDataTimedOut;
2208 Error(cip, kDontPerror, "Remote read timed out.\n");
2209 break;
2210 } else if (nread < 0) {
2211 if ((gGotBrokenData != 0) || (errno == EPIPE)) {
2213 errno = EPIPE;
2214 Error(cip, kDoPerror, "Lost data connection to remote host.\n");
2215 } else if (errno == EINTR) {
2216 continue;
2217 } else {
2218 Error(cip, kDoPerror, "Remote read failed.\n");
2221 }
2222 break;
2223 } else if (nread == 0) {
2224 break;
2225 }
2226#else
2227 gCanBrokenDataJmp = 1;
2228 if (cip->xferTimeout > 0)
2229 (void) alarm(cip->xferTimeout);
2230 nread = read(cip->dataSocket, buf, bufSize);
2231 if (nread < 0) {
2232 if ((gGotBrokenData != 0) || (errno == EPIPE)) {
2234 errno = EPIPE;
2235 Error(cip, kDoPerror, "Lost data connection to remote host.\n");
2236 (void) shutdown(cip->dataSocket, 2);
2237 } else if (errno == EINTR) {
2238 continue;
2239 } else {
2241 Error(cip, kDoPerror, "Remote read failed.\n");
2242 (void) shutdown(cip->dataSocket, 2);
2243 }
2244 break;
2245 } else if (nread == 0) {
2246 break;
2247 }
2248
2249 gCanBrokenDataJmp = 0;
2250#endif /* NO_SIGNALS */
2251
2252 src = buf;
2253 srclim = src + nread;
2254 dst = outbuf;
2255 dstlim = dst + sizeof(outbuf);
2256 while (src < srclim) {
2257 if (*src == '\r') {
2258 src++;
2259 continue;
2260 }
2261 if (dst >= dstlim) {
2262 nwrote = write(fd, outbuf, (size_t) (dst - outbuf));
2263 if (nwrote == (int) (dst - outbuf)) {
2264 /* Success. */
2265 dst = outbuf;
2266 } else if ((gGotBrokenData != 0) || (errno == EPIPE)) {
2268 cip->errNo = kErrWriteFailed;
2269 errno = EPIPE;
2270 (void) shutdown(cip->dataSocket, 2);
2271 goto brk;
2272 } else {
2273 Error(cip, kDoPerror, "Local write failed.\n");
2275 cip->errNo = kErrWriteFailed;
2276 (void) shutdown(cip->dataSocket, 2);
2277 goto brk;
2278 }
2279 }
2280 *dst++ = *src++;
2281 }
2282 if (dst > outbuf) {
2283 nwrote = write(fd, outbuf, (size_t) (dst - outbuf));
2284 if (nwrote != (int) (dst - outbuf)) {
2285 if ((gGotBrokenData != 0) || (errno == EPIPE)) {
2287 cip->errNo = kErrWriteFailed;
2288 errno = EPIPE;
2289 (void) shutdown(cip->dataSocket, 2);
2290 goto brk;
2291 } else {
2292 Error(cip, kDoPerror, "Local write failed.\n");
2294 cip->errNo = kErrWriteFailed;
2295 (void) shutdown(cip->dataSocket, 2);
2296 goto brk;
2297 }
2298 }
2299 }
2300
2301 if (mdtm != kModTimeUnknown) {
2302 (void) utime(dstfile, &ut);
2303 }
2304 cip->bytesTransferred += (longest_int) nread;
2305 FTPUpdateIOTimer(cip);
2306 }
2307 } else
2308#endif /* ASCII_TRANSLATION */
2309 {
2310 /* Binary */
2311 for (;;) {
2312 if (! WaitForRemoteInput(cip)) { /* could set cancelXfer */
2313 cip->errNo = result = kErrDataTimedOut;
2314 Error(cip, kDontPerror, "Remote read timed out.\n");
2315 break;
2316 }
2317 if (cip->cancelXfer > 0) {
2320 break;
2321 }
2322#ifdef TESTING_ABOR
2323 if (cip->bytesTransferred > 0) {
2324 cip->cancelXfer = 1;
2327 break;
2328 }
2329#endif /* TESTING_ABOR */
2330#ifdef NO_SIGNALS
2332 if (nread == kTimeoutErr) {
2333 cip->errNo = result = kErrDataTimedOut;
2334 Error(cip, kDontPerror, "Remote read timed out.\n");
2335 break;
2336 } else if (nread < 0) {
2337 if ((gGotBrokenData != 0) || (errno == EPIPE)) {
2339 errno = EPIPE;
2340 Error(cip, kDoPerror, "Lost data connection to remote host.\n");
2341 } else if (errno == EINTR) {
2342 continue;
2343 } else {
2344 Error(cip, kDoPerror, "Remote read failed.\n");
2347 }
2348 break;
2349 } else if (nread == 0) {
2350 break;
2351 }
2352#else
2353 gCanBrokenDataJmp = 1;
2354 if (cip->xferTimeout > 0)
2355 (void) alarm(cip->xferTimeout);
2356 nread = read(cip->dataSocket, buf, bufSize);
2357 if (nread < 0) {
2358 if ((gGotBrokenData != 0) || (errno == EPIPE)) {
2360 errno = EPIPE;
2361 Error(cip, kDoPerror, "Lost data connection to remote host.\n");
2362 } else if (errno == EINTR) {
2363 continue;
2364 } else {
2366 Error(cip, kDoPerror, "Remote read failed.\n");
2367 }
2368 (void) shutdown(cip->dataSocket, 2);
2369 break;
2370 } else if (nread == 0) {
2371 break;
2372 }
2373 gCanBrokenDataJmp = 0;
2374#endif /* NO_SIGNALS */
2375
2376 nwrote = write(fd, buf, nread);
2377 if (nwrote != nread) {
2378 if ((gGotBrokenData != 0) || (errno == EPIPE)) {
2380 cip->errNo = kErrWriteFailed;
2381 errno = EPIPE;
2382 } else {
2383 Error(cip, kDoPerror, "Local write failed.\n");
2385 cip->errNo = kErrWriteFailed;
2386 }
2387 (void) shutdown(cip->dataSocket, 2);
2388 break;
2389 }
2390
2391 /* Ugggh... do this after each write operation
2392 * so it minimizes the chance of a user killing
2393 * the process before we reset the timestamps.
2394 */
2395 if (mdtm != kModTimeUnknown) {
2396 (void) utime(dstfile, &ut);
2397 }
2398 cip->bytesTransferred += (longest_int) nread;
2399 FTPUpdateIOTimer(cip);
2400 }
2401 }
2402
2403#if ASCII_TRANSLATION
2404brk:
2405#endif
2406
2407#if !defined(NO_SIGNALS)
2408 if (cip->xferTimeout > 0)
2409 (void) alarm(0);
2410 gCanBrokenDataJmp = 0;
2411#endif /* NO_SIGNALS */
2412
2413 if (fdtouse < 0) {
2414 /* If they gave us a descriptor (fdtouse >= 0),
2415 * leave it open, otherwise we opened it, so
2416 * we need to close it.
2417 */
2418 (void) close(fd);
2419 fd = -1;
2420 }
2421
2422 tmpResult = FTPEndDataCmd(cip, 1);
2423 if ((tmpResult < 0) && (result == 0)) {
2425 cip->errNo = kErrRETRFailed;
2426 }
2427 FTPStopIOTimer(cip);
2428#if !defined(NO_SIGNALS)
2429 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
2430#endif /* NO_SIGNALS */
2431
2432 if ((mdtm != kModTimeUnknown) && (cip->bytesTransferred > 0)) {
2433 (void) utime(dstfile, &ut);
2434 }
2435
2436 if (result == kNoErr) {
2437 cip->numDownloads++;
2438
2439 if (deleteflag == kDeleteYes) {
2441 }
2442 }
2443
2444 return (result);
2445} /* FTPGetOneF */
#define EINTR
Definition: acclib.h:80
#define EPIPE
Definition: acclib.h:91
#define O_WRONLY
Definition: acwin.h:111
#define O_CREAT
Definition: acwin.h:110
#define read
Definition: acwin.h:96
#define close
Definition: acwin.h:98
#define write
Definition: acwin.h:97
#define O_TRUNC
Definition: acwin.h:112
#define setjmp
Definition: setjmp.h:209
#define SIGPIPE
Definition: signal.h:35
__kernel_time_t time_t
Definition: linux.h:252
__kernel_off_t off_t
Definition: linux.h:201
time_t now
Definition: finger.c:65
#define utime
Definition: getline.c:47
GLenum src
Definition: glext.h:6340
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLenum GLenum dst
Definition: glext.h:6340
GLuint GLsizei bufSize
Definition: glext.h:6040
#define O_APPEND
Definition: fcntl.h:37
#define SEEK_SET
Definition: jmemansi.c:26
#define Lseek(a, b, c)
Definition: syshdrs.h:96
#define Stat
Definition: syshdrs.h:78
#define Open
Definition: syshdrs.h:62
if(dx< 0)
Definition: linetemp.h:194
__u16 time
Definition: mkdosfs.c:8
int FTPFileSizeAndModificationTime(const FTPCIPtr cip, const char *const file, longest_int *const size, const int type, time_t *const mdtm)
Definition: cmds.c:1433
int FTPFileModificationTime(const FTPCIPtr cip, const char *const file, time_t *const mdtm)
Definition: cmds.c:649
int FTPDelete(const FTPCIPtr cip, const char *const pattern, const int recurse, const int doGlob)
Definition: cmds.c:195
int FTPSetTransferType(const FTPCIPtr cip, int type)
Definition: cmds.c:836
int SetStartOffset(const FTPCIPtr cip, longest_int restartPt)
Definition: ftp.c:853
static int WaitForRemoteInput(const FTPCIPtr cip)
Definition: io.c:1424
#define O_BINARY
Definition: io.c:41
void FTPInitIOTimer(const FTPCIPtr cip)
Definition: io.c:71
void FTPStartIOTimer(const FTPCIPtr cip)
Definition: io.c:93
static int gGotBrokenData
Definition: io.c:10
static void AutomaticallyUseASCIIModeDependingOnExtension(const FTPCIPtr cip, const char *const pathName, int *const xtype)
Definition: io.c:565
void FTPUpdateIOTimer(const FTPCIPtr cip)
Definition: io.c:104
void FTPStopIOTimer(const FTPCIPtr cip)
Definition: io.c:159
#define kDontPerror
Definition: util.h:45
#define kNoFirstSelect
Definition: sio.h:52
#define kFullBufferNotRequired
Definition: sio.h:49
int SRead(int, char *const, size_t, int, int)
Definition: SRead.c:118
#define kTimeoutErr
Definition: sio.h:58
int sigsetjmp(sigjmp_buf buf, int savesigs)
int FTPCmd(const FTPCIPtr cip, const char *const cmdspec,...)
Definition: rcmd.c:603
#define kNetReading
Definition: ncftp.h:303
#define kResumeYes
Definition: ncftp.h:366
void FTPShutdownHost(const FTPCIPtr cip)
Definition: open.c:564
#define kConfirmResumeProcSaidOverwrite
Definition: ncftp.h:426
void(* FTPSigProc)(int)
Definition: ncftp.h:76
#define kSizeUnknown
Definition: ncftp.h:376
int FTPEndDataCmd(const FTPCIPtr, int)
Definition: rcmd.c:933
#define kCommandAvailable
Definition: ncftp.h:380
#define kConfirmResumeProcSaidBestGuess
Definition: ncftp.h:428
#define kModTimeUnknown
Definition: ncftp.h:377
#define longest_int
Definition: ncftp.h:68
#define kConfirmResumeProcSaidSkip
Definition: ncftp.h:424
void FTPAbortDataTransfer(const FTPCIPtr cip)
Definition: rcmd.c:870
#define NoConfirmResumeDownloadProc
Definition: ncftp.h:451
#define kConfirmResumeProcSaidResume
Definition: ncftp.h:425
int FTPStartDataCmd(const FTPCIPtr, int, int, longest_int, const char *,...)
Definition: rcmd.c:763
#define kConfirmResumeProcSaidCancel
Definition: ncftp.h:429
#define kConfirmResumeProcSaidAppend
Definition: ncftp.h:427
#define kCommandAvailabilityUnknown
Definition: ncftp.h:379
#define kDeleteYes
Definition: ncftp.h:368
#define kCommandNotAvailable
Definition: ncftp.h:381
#define kAppendYes
Definition: ncftp.h:364
#define kErrSocketReadFailed
Definition: ncftp_errno.h:53
#define kErrWriteFailed
Definition: ncftp_errno.h:50
#define kErrOpenFailed
Definition: ncftp_errno.h:54
#define kErrRETRFailed
Definition: ncftp_errno.h:48
#define kErrSetStartPoint
Definition: ncftp_errno.h:34
#define kErrDataTransferAborted
Definition: ncftp_errno.h:86
#define kErrNoBuf
Definition: ncftp_errno.h:92
#define kErrDataTimedOut
Definition: ncftp_errno.h:111
#define kErrLseekFailed
Definition: ncftp_errno.h:85
#define errno
Definition: errno.h:18
int signal
Definition: except.c:82
static int fd
Definition: io.c:51
INT WSAAPI shutdown(IN SOCKET s, IN INT how)
Definition: sockctrl.c:506
int hasRETRBUFSIZE
Definition: ncftp.h:171
unsigned int xferTimeout
Definition: ncftp.h:141
time_t mdtm
Definition: ncftp.h:206
size_t dataSocketRBufSize
Definition: ncftp.h:230
int numDownloads
Definition: ncftp.h:234
longest_int startPoint
Definition: ncftp.h:159
int useProgressMeter
Definition: ncftp.h:199
const char * rname
Definition: ncftp.h:208
size_t dataSocketSBufSize
Definition: ncftp.h:231
const char * lname
Definition: ncftp.h:209
size_t bufSize
Definition: ncftp.h:187
longest_int expectedSize
Definition: ncftp.h:205
longest_int bytesTransferred
Definition: ncftp.h:197
char * buf
Definition: ncftp.h:186
Definition: fci.c:127

Referenced by FTPGetFiles3(), and FTPGetOneFile3().

◆ FTPGetOneFile()

int FTPGetOneFile ( const FTPCIPtr  cip,
const char *const  file,
const char *const  dstfile 
)

Definition at line 2712 of file io.c.

2713{
2715} /* FTPGetOneFile */
int FTPGetOneFile3(const FTPCIPtr cip, const char *const file, const char *const dstfile, const int xtype, const int fdtouse, const int resumeflag, const int appendflag, const int deleteflag, const ConfirmResumeDownloadProc resumeProc, int UNUSED(reserved))
Definition: io.c:2451

◆ FTPGetOneFile2()

int FTPGetOneFile2 ( const FTPCIPtr  cip,
const char *const  file,
const char *const  dstfile,
const int  xtype,
const int  fdtouse,
const int  resumeflag,
const int  appendflag 
)

Definition at line 2721 of file io.c.

2722{
2723 return (FTPGetOneFile3(cip, file, dstfile, xtype, fdtouse, resumeflag, appendflag, kDeleteNo, (ConfirmResumeDownloadProc) 0, 0));
2724} /* FTPGetOneFile2 */

Referenced by CatCmd(), and PageCmd().

◆ FTPGetOneFile3()

int FTPGetOneFile3 ( const FTPCIPtr  cip,
const char *const  file,
const char *const  dstfile,
const int  xtype,
const int  fdtouse,
const int  resumeflag,
const int  appendflag,
const int  deleteflag,
const ConfirmResumeDownloadProc  resumeProc,
int   UNUSEDreserved 
)

Definition at line 2451 of file io.c.

2462{
2463 int result;
2464
2466 if (cip == NULL)
2467 return (kErrBadParameter);
2468 if (strcmp(cip->magic, kLibraryMagic))
2469 return (kErrBadMagic);
2470
2471 if ((file == NULL) || (file[0] == '\0'))
2472 return (kErrBadParameter);
2473 if (fdtouse < 0) {
2474 if ((dstfile == NULL) || (dstfile[0] == '\0'))
2475 return (kErrBadParameter);
2476 }
2477
2478 result = FTPGetOneF(cip, file, dstfile, xtype, fdtouse, kSizeUnknown, kModTimeUnknown, resumeflag, appendflag, deleteflag, resumeProc);
2479 return (result);
2480} /* FTPGetOneFile3 */

Referenced by FTPGetOneFile(), FTPGetOneFile2(), FTPGetOneFileAscii(), and GetCmd().

◆ FTPGetOneFileAscii()

int FTPGetOneFileAscii ( const FTPCIPtr  cip,
const char *const  file,
const char *const  dstfile 
)

Definition at line 2748 of file io.c.

2749{
2751} /* FTPGetOneFileAscii */

◆ FTPInitIOTimer()

void FTPInitIOTimer ( const FTPCIPtr  cip)

Definition at line 71 of file io.c.

72{
75 cip->mdtm = kModTimeUnknown;
76 cip->rname = NULL;
77 cip->lname = NULL;
78 cip->kBytesPerSec = -1.0;
79 cip->percentCompleted = -1.0;
80 cip->sec = -1.0;
81 cip->secLeft = -1.0;
82 cip->nextProgressUpdate = 0;
83 cip->stalled = 0;
84 cip->dataTimedOut = 0;
85 cip->useProgressMeter = 1;
86 (void) gettimeofday(&cip->t0, NULL);
87} /* FTPInitIOTimer */
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
time_t nextProgressUpdate
Definition: ncftp.h:207
int dataTimedOut
Definition: ncftp.h:212
double percentCompleted
Definition: ncftp.h:204
double sec
Definition: ncftp.h:201
double kBytesPerSec
Definition: ncftp.h:203
double secLeft
Definition: ncftp.h:202
struct timeval t0
Definition: ncftp.h:210

Referenced by FTPGetOneF(), and FTPPutOneF().

◆ FTPList()

int FTPList ( const FTPCIPtr  cip,
const int  outfd,
const int  longMode,
const char *const  lsflag 
)

Definition at line 174 of file io.c.

175{
176 const char *cmd;
177 char line[512];
178 char secondaryBuf[768];
179#ifndef NO_SIGNALS
180 char *secBufPtr, *secBufLimit;
181 int nread;
182 volatile int result;
183#else /* NO_SIGNALS */
184 SReadlineInfo lsSrl;
185 int result;
186#endif /* NO_SIGNALS */
187
188 if (cip == NULL)
189 return (kErrBadParameter);
190 if (strcmp(cip->magic, kLibraryMagic))
191 return (kErrBadMagic);
192
193 cmd = (longMode != 0) ? "LIST" : "NLST";
194 if ((lsflag == NULL) || (lsflag[0] == '\0')) {
196 } else {
197 result = FTPStartDataCmd(cip, kNetReading, kTypeAscii, (longest_int) 0, "%s %s", cmd, lsflag);
198 }
199
200
201#ifdef NO_SIGNALS
202
203 if (result == 0) {
204 if (InitSReadlineInfo(&lsSrl, cip->dataSocket, secondaryBuf, sizeof(secondaryBuf), (int) cip->xferTimeout, 1) < 0) {
205 /* Not really fdopen, but close in what we're trying to do. */
207 cip->errNo = kErrFdopenR;
208 Error(cip, kDoPerror, "Could not fdopen.\n");
209 return (result);
210 }
211
212 for (;;) {
213 result = SReadline(&lsSrl, line, sizeof(line) - 2);
214 if (result == kTimeoutErr) {
215 /* timeout */
216 Error(cip, kDontPerror, "Could not directory listing data -- timed out.\n");
217 cip->errNo = kErrDataTimedOut;
218 return (cip->errNo);
219 } else if (result == 0) {
220 /* end of listing -- done */
221 cip->numListings++;
222 break;
223 } else if (result < 0) {
224 /* error */
225 Error(cip, kDoPerror, "Could not read directory listing data");
227 cip->errNo = kErrLISTFailed;
228 break;
229 }
230
231 (void) write(outfd, line, strlen(line));
232 }
233
234 DisposeSReadlineInfo(&lsSrl);
235 if (FTPEndDataCmd(cip, 1) < 0) {
237 cip->errNo = kErrLISTFailed;
238 }
239 } else if (result == kErrGeneric) {
241 cip->errNo = kErrLISTFailed;
242 }
243
244
245#else /* NO_SIGNALS */
246
247 if (result == 0) {
248 /* This line sets the buffer pointer so that the first thing
249 * BufferGets will do is reset and fill the buffer using
250 * real I/O.
251 */
252 secBufPtr = secondaryBuf + sizeof(secondaryBuf);
253 secBufLimit = (char *) 0;
254
255 for (;;) {
256 if (cip->xferTimeout > 0)
257 (void) alarm(cip->xferTimeout);
258 nread = BufferGets(line, sizeof(line), cip->dataSocket, secondaryBuf, &secBufPtr, &secBufLimit, sizeof(secondaryBuf));
259 if (nread <= 0) {
260 if (nread < 0)
261 break;
262 } else {
263 cip->bytesTransferred += (longest_int) nread;
264 (void) STRNCAT(line, "\n");
265 (void) write(outfd, line, strlen(line));
266 }
267 }
268 if (cip->xferTimeout > 0)
269 (void) alarm(0);
270 result = FTPEndDataCmd(cip, 1);
271 if (result < 0) {
273 cip->errNo = kErrLISTFailed;
274 }
275 result = kNoErr;
276 cip->numListings++;
277 } else if (result == kErrGeneric) {
279 cip->errNo = kErrLISTFailed;
280 }
281#endif /* NO_SIGNALS */
282 return (result);
283} /* FTPList */
#define STRNCAT(d, s)
Definition: Strn.h:48
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
void DisposeSReadlineInfo(SReadlineInfo *)
Definition: SReadline.c:57
int SReadline(SReadlineInfo *, char *const, size_t)
Definition: SReadline.c:76
int InitSReadlineInfo(SReadlineInfo *, int, char *, size_t, int, int)
Definition: SReadline.c:24
int BufferGets(char *, size_t, int, char *, char **, char **, size_t)
Definition: rcmd.c:978
#define kErrLISTFailed
Definition: ncftp_errno.h:47
#define kErrFdopenR
Definition: ncftp_errno.h:25
Definition: ftp_var.h:139
Definition: parser.c:49

◆ FTPListToMemory()

int FTPListToMemory ( const FTPCIPtr  cip,
const char *const  pattern,
const LineListPtr  llines,
const char *const  lsflags 
)

Definition at line 2819 of file io.c.

2820{
2821 return (FTPListToMemory2(cip, pattern, llines, lsflags, 1, (int *) 0));
2822} /* FTPListToMemory */
int FTPListToMemory2(const FTPCIPtr cip, const char *const pattern, const LineListPtr llines, const char *const lsflags, const int blankLines, int *const tryMLSD)
Definition: io.c:366

◆ FTPListToMemory2()

int FTPListToMemory2 ( const FTPCIPtr  cip,
const char *const  pattern,
const LineListPtr  llines,
const char *const  lsflags,
const int  blankLines,
int *const  tryMLSD 
)

Definition at line 366 of file io.c.

367{
368 char secondaryBuf[768];
369 char line[512];
370 char lsflags1[128];
371 const char *command = "NLST";
372 const char *scp;
373 char *dcp, *lim;
374#ifndef NO_SIGNALS
375 char *secBufPtr, *secBufLimit;
376 volatile FTPSigProc osigpipe;
377 volatile FTPCIPtr vcip;
378 int sj;
379 int nread;
380 volatile int result;
381#else /* NO_SIGNALS */
382 SReadlineInfo lsSrl;
383 int result;
384#endif /* NO_SIGNALS */
385
386 if (cip == NULL)
387 return (kErrBadParameter);
388 if (strcmp(cip->magic, kLibraryMagic))
389 return (kErrBadMagic);
390
391 if ((llines == NULL) || (pattern == NULL) || (lsflags == NULL))
392 return (kErrBadParameter);
393
394 if ((tryMLSD != (int *) 0) && (*tryMLSD != 0) && (cip->hasMLSD == kCommandAvailable)) {
395 command = "MLSD";
396 if ((lsflags[0] == '-') && (strchr(lsflags, 'd') != NULL) && (cip->hasMLST == kCommandAvailable))
397 command = "MLST";
398 lsflags1[0] = '\0';
400 } else {
401 /* Not using MLSD. */
402 if (tryMLSD != (int *) 0)
403 *tryMLSD = 0;
404 if (lsflags[0] == '-') {
405 /* See if we should use LIST instead. */
406 scp = lsflags + 1;
407 dcp = lsflags1;
408 lim = lsflags1 + sizeof(lsflags1) - 2;
409 for (; *scp != '\0'; scp++) {
410 if (*scp == 'l') {
411 /* do not add the 'l' */
412 command = "LIST";
413 } else if (dcp < lim) {
414 if (dcp == lsflags1)
415 *dcp++ = '-';
416 *dcp++ = *scp;
417 }
418 }
419 *dcp = '\0';
420 } else {
421 (void) STRNCPY(lsflags1, lsflags);
422 }
423 }
424
425 InitLineList(llines);
426
428 cip,
431 (longest_int) 0,
432 "%s%s%s%s%s",
433 command,
434 (lsflags1[0] == '\0') ? "" : " ",
435 lsflags1,
436 (pattern[0] == '\0') ? "" : " ",
437 pattern
438 );
439
440#ifdef NO_SIGNALS
441
442 if (result == 0) {
443 if (InitSReadlineInfo(&lsSrl, cip->dataSocket, secondaryBuf, sizeof(secondaryBuf), (int) cip->xferTimeout, 1) < 0) {
444 /* Not really fdopen, but close in what we're trying to do. */
446 cip->errNo = kErrFdopenR;
447 Error(cip, kDoPerror, "Could not fdopen.\n");
448 return (result);
449 }
450
451 for (;;) {
452 result = SReadline(&lsSrl, line, sizeof(line) - 1);
453 if (result == kTimeoutErr) {
454 /* timeout */
455 Error(cip, kDontPerror, "Could not directory listing data -- timed out.\n");
456 cip->errNo = kErrDataTimedOut;
457 return (cip->errNo);
458 } else if (result == 0) {
459 /* end of listing -- done */
460 cip->numListings++;
461 break;
462 } else if (result < 0) {
463 /* error */
464 Error(cip, kDoPerror, "Could not read directory listing data");
466 cip->errNo = kErrLISTFailed;
467 break;
468 }
469
470 if (line[result - 1] == '\n')
471 line[result - 1] = '\0';
472
473 if ((blankLines == 0) && (result <= 1))
474 continue;
475
476 /* Valid directory listing line of output */
477 if ((line[0] == '.') && ((line[1] == '\0') || ((line[1] == '.') && ((line[2] == '\0') || (iscntrl(line[2]))))))
478 continue; /* Skip . and .. */
479
480 (void) AddLine(llines, line);
481 }
482
483 DisposeSReadlineInfo(&lsSrl);
484 if (FTPEndDataCmd(cip, 1) < 0) {
486 cip->errNo = kErrLISTFailed;
487 }
488 } else if (result == kErrGeneric) {
490 cip->errNo = kErrLISTFailed;
491 }
492
493
494#else /* NO_SIGNALS */
495 vcip = cip;
496 osigpipe = (volatile FTPSigProc) signal(SIGPIPE, BrokenData);
497
498 gGotBrokenData = 0;
499 gCanBrokenDataJmp = 0;
500
501#ifdef HAVE_SIGSETJMP
502 sj = sigsetjmp(gBrokenDataJmp, 1);
503#else
504 sj = setjmp(gBrokenDataJmp);
505#endif /* HAVE_SIGSETJMP */
506
507 if (sj != 0) {
508 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
509 FTPShutdownHost(vcip);
511 return(vcip->errNo);
512 }
513 gCanBrokenDataJmp = 1;
514
515 if (result == 0) {
516 /* This line sets the buffer pointer so that the first thing
517 * BufferGets will do is reset and fill the buffer using
518 * real I/O.
519 */
520 secBufPtr = secondaryBuf + sizeof(secondaryBuf);
521 secBufLimit = (char *) 0;
522 memset(secondaryBuf, 0, sizeof(secondaryBuf));
523
524 for (;;) {
525 memset(line, 0, sizeof(line));
526 if (cip->xferTimeout > 0)
527 (void) alarm(cip->xferTimeout);
528 nread = BufferGets(line, sizeof(line), cip->dataSocket, secondaryBuf, &secBufPtr, &secBufLimit, sizeof(secondaryBuf));
529 if (nread <= 0) {
530 if (nread < 0)
531 break;
532 if (blankLines != 0)
533 (void) AddLine(llines, line);
534 } else {
535 cip->bytesTransferred += (longest_int) nread;
536
537 if ((line[0] == '.') && ((line[1] == '\0') || ((line[1] == '.') && ((line[2] == '\0') || (iscntrl(line[2]))))))
538 continue; /* Skip . and .. */
539
540 (void) AddLine(llines, line);
541 }
542 }
543 if (cip->xferTimeout > 0)
544 (void) alarm(0);
545 result = FTPEndDataCmd(cip, 1);
546 if (result < 0) {
548 cip->errNo = kErrLISTFailed;
549 }
550 result = kNoErr;
551 cip->numListings++;
552 } else if (result == kErrGeneric) {
554 cip->errNo = kErrLISTFailed;
555 }
556 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
557#endif /* NO_SIGNALS */
558 return (result);
559} /* FTPListToMemory2 */
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
_Check_return_ _CRTIMP int __cdecl iscntrl(_In_ int _C)
void InitLineList(LineListPtr list)
Definition: linelist.c:54
LinePtr AddLine(LineListPtr list, const char *buf1)
Definition: linelist.c:94
static void FTPRequestMlsOptions(const FTPCIPtr cip)
Definition: io.c:289
#define memset(x, y, z)
Definition: compat.h:39

Referenced by FTPFileExistsNlst(), FTPFileExistsStat(), FTPListToMemory(), FTPRemoteGlob(), FTPRemoteRecursiveFileList(), FTPRemoteRecursiveFileList1(), Ls(), and MlsCmd().

◆ FTPPutFiles()

int FTPPutFiles ( const FTPCIPtr  cip,
const char *const  pattern,
const char *const  dstdir,
const int  recurse,
const int  doGlob 
)

Definition at line 2784 of file io.c.

2785{
2786 return (FTPPutFiles3(cip, pattern, dstdir, recurse, doGlob, kTypeBinary, 0, NULL, NULL, kResumeNo, kDeleteNo, NoConfirmResumeUploadProc, 0));
2787} /* FTPPutFiles */
int FTPPutFiles3(const FTPCIPtr cip, const char *const pattern, const char *const dstdir1, const int recurse, const int doGlob, const int xtype, int appendflag, const char *const tmppfx, const char *const tmpsfx, const int resumeflag, const int deleteflag, const ConfirmResumeUploadProc resumeProc, int UNUSED(reserved))
Definition: io.c:1298
#define NoConfirmResumeUploadProc
Definition: ncftp.h:452

◆ FTPPutFiles2()

int FTPPutFiles2 ( const FTPCIPtr  cip,
const char *const  pattern,
const char *const  dstdir,
const int  recurse,
const int  doGlob,
const int  xtype,
const int  appendflag,
const char *const  tmppfx,
const char *const  tmpsfx 
)

Definition at line 2793 of file io.c.

2794{
2795 return (FTPPutFiles3(cip, pattern, dstdir, recurse, doGlob, xtype, appendflag, tmppfx, tmpsfx, kResumeNo, kDeleteNo, NoConfirmResumeUploadProc, 0));
2796} /* FTPPutFiles2 */

◆ FTPPutFiles3()

int FTPPutFiles3 ( const FTPCIPtr  cip,
const char *const  pattern,
const char *const  dstdir1,
const int  recurse,
const int  doGlob,
const int  xtype,
int  appendflag,
const char *const  tmppfx,
const char *const  tmpsfx,
const int  resumeflag,
const int  deleteflag,
const ConfirmResumeUploadProc  resumeProc,
int   UNUSEDreserved 
)

Definition at line 1298 of file io.c.

1312{
1313 LineList globList;
1314 FileInfoList files;
1315 FileInfoPtr filePtr;
1316 int batchResult;
1317 int result;
1318 const char *dstdir;
1319 char dstdir2[512];
1320
1322 if (cip == NULL)
1323 return (kErrBadParameter);
1324 if (strcmp(cip->magic, kLibraryMagic))
1325 return (kErrBadMagic);
1326
1327 if (dstdir1 == NULL) {
1328 dstdir = NULL;
1329 } else {
1330 dstdir = STRNCPY(dstdir2, dstdir1);
1332 }
1333
1334 (void) FTPLocalGlob(cip, &globList, pattern, doGlob);
1335 if (recurse == kRecursiveYes) {
1336 appendflag = kAppendNo;
1337 (void) FTPLocalRecursiveFileList(cip, &globList, &files);
1338 if (files.first == NULL) {
1341 }
1342 (void) ComputeRNames(&files, dstdir, 0, 1);
1343 } else {
1344 (void) LineListToFileInfoList(&globList, &files);
1345 (void) ComputeLNames(&files, NULL, NULL, 1);
1346 (void) ComputeRNames(&files, dstdir, 0, 0);
1347 }
1348 DisposeLineListContents(&globList);
1349
1350#if 0
1351 for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next) {
1352 PrintF(cip, " R=%s, L=%s, 2=%s, size=%d, mdtm=%u, type=%c\n",
1353 filePtr->rname,
1354 filePtr->lname,
1355 filePtr->rlinkto ? filePtr->rlinkto : "",
1356 filePtr->size,
1357 (unsigned int) filePtr->mdtm,
1358 filePtr->type
1359 );
1360 }
1361#endif
1362
1363 batchResult = kNoErr;
1364 for (filePtr = files.first; filePtr != NULL; filePtr = filePtr->next) {
1365 if (cip->connected == 0) {
1366 if (batchResult == kNoErr)
1367 batchResult = kErrRemoteHostClosedConnection;
1368 break;
1369 }
1370 if (filePtr->type == 'd') {
1371 /* mkdir */
1373 result = FTPMkdir(cip, filePtr->rname, kRecursiveNo);
1374 if (result != kNoErr)
1375 batchResult = result;
1376#ifdef HAVE_SYMLINK
1377 } else if (filePtr->type == 'l') {
1378 /* symlink */
1379 /* no RFC way to create the link, though. */
1380 if ((filePtr->rlinkto != NULL) && (filePtr->rlinkto[0] != '\0'))
1381 (void) FTPSymlink(cip, filePtr->rname, filePtr->rlinkto);
1382#endif
1383 } else if (recurse != kRecursiveYes) {
1384 result = FTPPutOneF(cip, filePtr->lname, filePtr->rname, xtype, -1, appendflag, tmppfx, tmpsfx, resumeflag, deleteflag, resumeProc);
1385 if (files.nFileInfos == 1) {
1386 if (result != kNoErr)
1387 batchResult = result;
1388 } else {
1390 batchResult = result;
1391 }
1392 if (result == kErrUserCanceled)
1393 cip->cancelXfer = 1;
1394 if (cip->cancelXfer > 0)
1395 break;
1396 } else {
1397 result = FTPPutOneF(cip, filePtr->lname, filePtr->rname, xtype, -1, appendflag, tmppfx, tmpsfx, resumeflag, deleteflag, resumeProc);
1398 if (files.nFileInfos == 1) {
1399 if (result != kNoErr)
1400 batchResult = result;
1401 } else {
1403 batchResult = result;
1404 }
1405 if (result == kErrUserCanceled)
1406 cip->cancelXfer = 1;
1407 if (cip->cancelXfer > 0)
1408 break;
1409 }
1410 }
1412 if (batchResult < 0)
1413 cip->errNo = batchResult;
1414 return (batchResult);
1415} /* FTPPutFiles3 */
int FTPLocalRecursiveFileList(FTPCIPtr cip, LineListPtr fileList, FileInfoListPtr files)
Definition: glob.c:1333
int FTPLocalGlob(FTPCIPtr cip, LineListPtr fileList, const char *pattern, int doGlob)
Definition: glob.c:1580
int LineListToFileInfoList(LineListPtr src, FileInfoListPtr dst)
Definition: linelist.c:758
int FTPSymlink(const FTPCIPtr cip, const char *const lfrom, const char *const lto)
Definition: cmds.c:1585
int FTPMkdir(const FTPCIPtr cip, const char *const newDir, const int recurse)
Definition: cmds.c:641
static int FTPPutOneF(const FTPCIPtr cip, const char *const file, const char *volatile dstfile, int xtype, const int fdtouse, const int appendflag, const char *volatile tmppfx, const char *volatile tmpsfx, const int resumeflag, const int deleteflag, const ConfirmResumeUploadProc resumeProc)
Definition: io.c:650
#define kErrNoValidFilesSpecified
Definition: ncftp_errno.h:91

Referenced by FTPPutFiles(), FTPPutFiles2(), FTPPutFilesAscii(), and PutCmd().

◆ FTPPutFilesAscii()

int FTPPutFilesAscii ( const FTPCIPtr  cip,
const char *const  pattern,
const char *const  dstdir,
const int  recurse,
const int  doGlob 
)

Definition at line 2811 of file io.c.

2812{
2813 return (FTPPutFiles3(cip, pattern, dstdir, recurse, doGlob, kTypeAscii, 0, NULL, NULL, kResumeNo, kDeleteNo, NoConfirmResumeUploadProc, 0));
2814} /* FTPPutFilesAscii */

◆ FTPPutOneF()

static int FTPPutOneF ( const FTPCIPtr  cip,
const char *const  file,
const char *volatile  dstfile,
int  xtype,
const int  fdtouse,
const int  appendflag,
const char *volatile  tmppfx,
const char *volatile  tmpsfx,
const int  resumeflag,
const int  deleteflag,
const ConfirmResumeUploadProc  resumeProc 
)
static

Definition at line 650 of file io.c.

662{
663 char *buf, *cp;
664 const char *cmd;
665 const char *odstfile;
666 size_t bufSize;
667 size_t l;
668 int tmpResult, result;
669 int nread, nwrote;
670 volatile int fd;
671 char dstfile2[512];
672#if ASCII_TRANSLATION
673 char *src, *srclim, *dst;
674 int ntowrite;
675 char inbuf[256];
676#endif
677 int fstatrc, statrc;
678 longest_int startPoint = 0;
679 struct Stat st;
680 time_t mdtm;
681#if !defined(NO_SIGNALS)
682 int sj;
683 volatile FTPSigProc osigpipe;
684 volatile FTPCIPtr vcip;
685 volatile int vfd, vfdtouse;
686#endif /* NO_SIGNALS */
687 volatile int vzaction;
689
690 if (cip->buf == NULL) {
691 Error(cip, kDoPerror, "Transfer buffer not allocated.\n");
692 cip->errNo = kErrNoBuf;
693 return (cip->errNo);
694 }
695
696 cip->usingTAR = 0;
697 if (fdtouse < 0) {
699 if (fd < 0) {
700 Error(cip, kDoPerror, "Cannot open local file %s for reading.\n", file);
701 cip->errNo = kErrOpenFailed;
702 return (cip->errNo);
703 }
704 } else {
705 fd = fdtouse;
706 }
707
708 fstatrc = Fstat(fd, &st);
709 if ((fstatrc == 0) && (S_ISDIR(st.st_mode))) {
710 if (fdtouse < 0) {
711 (void) close(fd);
712 }
713 Error(cip, kDontPerror, "%s is a directory.\n", (file != NULL) ? file : "that");
714 cip->errNo = kErrOpenFailed;
715 return (cip->errNo);
716 }
717
718 /* For Put, we can't recover very well if it turns out restart
719 * didn't work, so check beforehand.
720 */
723 if (SetStartOffset(cip, (longest_int) 1) == kNoErr) {
724 /* Now revert -- we still may not end up
725 * doing it.
726 */
727 SetStartOffset(cip, (longest_int) -1);
728 }
729 }
730
731 if (fdtouse < 0) {
733 (void) FTPFileSizeAndModificationTime(cip, dstfile, &startPoint, xtype, &mdtm);
734
735 if (appendflag == kAppendYes) {
737 } else if (
738 (cip->hasREST == kCommandNotAvailable) ||
739 (xtype != kTypeBinary) ||
740 (fstatrc < 0)
741 ) {
743 } else if (resumeflag == kResumeYes) {
745 } else {
747 }
748
749 statrc = -1;
750 if ((mdtm != kModTimeUnknown) || (startPoint != kSizeUnknown)) {
751 /* Then we know the file exists. We will
752 * ask the user what to do, if possible, below.
753 */
754 statrc = 0;
755 } else if ((resumeProc != NoConfirmResumeUploadProc) && (cip->hasMDTM != kCommandAvailable) && (cip->hasSIZE != kCommandAvailable)) {
756 /* We already checked if the file had a filesize
757 * or timestamp above, but if the server indicated
758 * it did not support querying those directly,
759 * we now need to try to determine if the file
760 * exists in a few other ways.
761 */
762 statrc = FTPFileExists2(cip, dstfile, 0, 0, 0, 1, 1);
763 }
764
765 if (
766 (resumeProc != NoConfirmResumeUploadProc) &&
767 (statrc == 0)
768 ) {
769 zaction = (*resumeProc)(file, (longest_int) st.st_size, st.st_mtime, &dstfile, startPoint, mdtm, &startPoint);
770 }
771
772 if (zaction == kConfirmResumeProcSaidCancel) {
773 /* User wants to cancel this file and any
774 * remaining in batch.
775 */
776 cip->errNo = kErrUserCanceled;
777 return (cip->errNo);
778 }
779
780 if (zaction == kConfirmResumeProcSaidBestGuess) {
781 if ((mdtm != kModTimeUnknown) && (st.st_mtime > (mdtm + 1))) {
782 /* Local file is newer than remote,
783 * overwrite the remote file instead
784 * of trying to resume it.
785 *
786 * Note: Add one second fudge factor
787 * for Windows' file timestamps being
788 * imprecise to one second.
789 */
791 } else if ((longest_int) st.st_size == startPoint) {
792 /* Already sent file, done. */
794 } else if ((startPoint != kSizeUnknown) && ((longest_int) st.st_size > startPoint)) {
796 } else {
798 }
799 }
800
801 if (zaction == kConfirmResumeProcSaidSkip) {
802 /* Nothing done, but not an error. */
803 if (fdtouse < 0) {
804 (void) close(fd);
805 }
806 if (deleteflag == kDeleteYes) {
807 if (unlink(file) < 0) {
809 return (cip->errNo);
810 }
811 }
812 return (kNoErr);
813 } else if (zaction == kConfirmResumeProcSaidResume) {
814 /* Resume; proc set the startPoint. */
815 if ((longest_int) st.st_size == startPoint) {
816 /* Already sent file, done. */
817 if (fdtouse < 0) {
818 (void) close(fd);
819 }
820
821 if (deleteflag == kDeleteYes) {
822 if (unlink(file) < 0) {
824 return (cip->errNo);
825 }
826 }
827 return (kNoErr);
828 } else if (Lseek(fd, (off_t) startPoint, SEEK_SET) != (off_t) -1) {
829 cip->startPoint = startPoint;
830 }
831 } else if (zaction == kConfirmResumeProcSaidAppend) {
832 /* append: leave startPoint at zero, we will append everything. */
833 cip->startPoint = startPoint = 0;
834 } else /* if (zaction == kConfirmResumeProcSaidOverwrite) */ {
835 /* overwrite: leave startPoint at zero */
836 cip->startPoint = startPoint = 0;
837 }
838 }
839
840 if ((cip->numUploads == 0) && (cip->dataSocketSBufSize > 0)) {
841 /* If dataSocketSBufSize is non-zero, it means you
842 * want to explicitly try to set the size of the
843 * socket's I/O buffer.
844 *
845 * If it is zero, it means you want to just use the
846 * TCP stack's default value, which is typically
847 * between 8 and 64 kB.
848 *
849 * If you try to set the buffer larger than 64 kB,
850 * the TCP stack should try to use RFC 1323 to
851 * negotiate "TCP Large Windows" which may yield
852 * significant performance gains.
853 */
855 (void) FTPCmd(cip, "SITE STORBUFSIZE %lu", (unsigned long) cip->dataSocketSBufSize);
856 else if (cip->hasSBUFSIZ == kCommandAvailable)
857 (void) FTPCmd(cip, "SITE SBUFSIZ %lu", (unsigned long) cip->dataSocketSBufSize);
858 else if (cip->hasSBUFSZ == kCommandAvailable)
859 (void) FTPCmd(cip, "SITE SBUFSZ %lu", (unsigned long) cip->dataSocketSBufSize);
860 /* At least one server implemenation has RBUFSZ but not
861 * SBUFSZ and instead uses RBUFSZ for both.
862 */
863 else if ((cip->hasSBUFSZ != kCommandAvailable) && (cip->hasRBUFSZ == kCommandAvailable))
864 (void) FTPCmd(cip, "SITE RBUFSZ %lu", (unsigned long) cip->dataSocketSBufSize);
865 else if (cip->hasBUFSIZE == kCommandAvailable)
866 (void) FTPCmd(cip, "SITE BUFSIZE %lu", (unsigned long) cip->dataSocketSBufSize);
867 }
868
869#ifdef NO_SIGNALS
870 vzaction = zaction;
871#else /* NO_SIGNALS */
872 vcip = cip;
873 vfdtouse = fdtouse;
874 vfd = fd;
875 vzaction = zaction;
876 osigpipe = (volatile FTPSigProc) signal(SIGPIPE, BrokenData);
877
878 gGotBrokenData = 0;
879 gCanBrokenDataJmp = 0;
880
881#ifdef HAVE_SIGSETJMP
882 sj = sigsetjmp(gBrokenDataJmp, 1);
883#else
884 sj = setjmp(gBrokenDataJmp);
885#endif /* HAVE_SIGSETJMP */
886
887 if (sj != 0) {
888 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
889 if (vfdtouse < 0) {
890 (void) close(vfd);
891 }
892 FTPShutdownHost(vcip);
894 return(vcip->errNo);
895 }
896 gCanBrokenDataJmp = 1;
897#endif /* NO_SIGNALS */
898
899 if (vzaction == kConfirmResumeProcSaidAppend) {
900 cmd = "APPE";
901 tmppfx = ""; /* Can't use that here. */
902 tmpsfx = "";
903 } else {
904 cmd = "STOR";
905 if (tmppfx == NULL)
906 tmppfx = "";
907 if (tmpsfx == NULL)
908 tmpsfx = "";
909 }
910
911 odstfile = dstfile;
912 if ((tmppfx[0] != '\0') || (tmpsfx[0] != '\0')) {
913 cp = strrchr(dstfile, '/');
914 if (cp == NULL)
915 cp = strrchr(dstfile, '\\');
916 if (cp == NULL) {
917 (void) STRNCPY(dstfile2, tmppfx);
918 (void) STRNCAT(dstfile2, dstfile);
919 (void) STRNCAT(dstfile2, tmpsfx);
920 } else {
921 cp++;
922 l = (size_t) (cp - dstfile);
923 (void) STRNCPY(dstfile2, dstfile);
924 dstfile2[l] = '\0'; /* Nuke stuff after / */
925 (void) STRNCAT(dstfile2, tmppfx);
926 (void) STRNCAT(dstfile2, cp);
927 (void) STRNCAT(dstfile2, tmpsfx);
928 }
929 dstfile = dstfile2;
930 }
931
932 tmpResult = FTPStartDataCmd(
933 cip,
935 xtype,
936 startPoint,
937 "%s %s",
938 cmd,
939 dstfile
940 );
941
942 if (tmpResult < 0) {
943 cip->errNo = tmpResult;
944 if (fdtouse < 0) {
945 (void) close(fd);
946 }
947#if !defined(NO_SIGNALS)
948 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
949#endif /* NO_SIGNALS */
950 return (cip->errNo);
951 }
952
953 if ((startPoint != 0) && (cip->startPoint == 0)) {
954 /* Remote could not or would not set the start offset
955 * to what we wanted.
956 *
957 * So now we have to undo our seek.
958 */
959 if (Lseek(fd, (off_t) 0, SEEK_SET) != (off_t) 0) {
960 cip->errNo = kErrLseekFailed;
961 if (fdtouse < 0) {
962 (void) close(fd);
963 }
964#if !defined(NO_SIGNALS)
965 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
966#endif /* NO_SIGNALS */
967 return (cip->errNo);
968 }
969 startPoint = 0;
970 }
971
972 result = kNoErr;
973 buf = cip->buf;
974 bufSize = cip->bufSize;
975
976 FTPInitIOTimer(cip);
977 if ((fstatrc == 0) && (S_ISREG(st.st_mode) != 0)) {
978 cip->expectedSize = (longest_int) st.st_size;
979 cip->mdtm = st.st_mtime;
980 }
981 cip->lname = file; /* could be NULL */
982 cip->rname = odstfile;
983 if (fdtouse >= 0)
984 cip->useProgressMeter = 0;
985 FTPStartIOTimer(cip);
986
987 /* Note: On Windows, we don't have to do anything special
988 * for ASCII mode, since Net ASCII's end-of-line sequence
989 * corresponds to the same thing used for DOS/Windows.
990 */
991
992#if ASCII_TRANSLATION
993 if (xtype == kTypeAscii) {
994 /* ascii */
995 for (;;) {
996#if !defined(NO_SIGNALS)
997 gCanBrokenDataJmp = 0;
998#endif /* NO_SIGNALS */
999 nread = read(fd, inbuf, sizeof(inbuf));
1000 if (nread < 0) {
1001 if (errno == EINTR) {
1002 continue;
1003 } else {
1005 cip->errNo = kErrReadFailed;
1006 Error(cip, kDoPerror, "Local read failed.\n");
1007 }
1008 break;
1009 } else if (nread == 0) {
1010 break;
1011 }
1012 cip->bytesTransferred += (longest_int) nread;
1013
1014#if !defined(NO_SIGNALS)
1015 gCanBrokenDataJmp = 1;
1016#endif /* NO_SIGNALS */
1017 src = inbuf;
1018 srclim = src + nread;
1019 dst = cip->buf; /* must be 2x sizeof inbuf or more. */
1020 while (src < srclim) {
1021 if (*src == '\n')
1022 *dst++ = '\r';
1023 *dst++ = *src++;
1024 }
1025 ntowrite = (size_t) (dst - cip->buf);
1026 cp = cip->buf;
1027
1028#if !defined(NO_SIGNALS)
1029 if (cip->xferTimeout > 0)
1030 (void) alarm(cip->xferTimeout);
1031#endif /* NO_SIGNALS */
1032 do {
1033 if (! WaitForRemoteOutput(cip)) { /* could set cancelXfer */
1034 cip->errNo = result = kErrDataTimedOut;
1035 Error(cip, kDontPerror, "Remote write timed out.\n");
1036 goto brk;
1037 }
1038 if (cip->cancelXfer > 0) {
1041 goto brk;
1042 }
1043
1044#ifdef NO_SIGNALS
1045 nwrote = SWrite(cip->dataSocket, cp, (size_t) ntowrite, (int) cip->xferTimeout, kNoFirstSelect);
1046 if (nwrote < 0) {
1047 if (nwrote == kTimeoutErr) {
1048 cip->errNo = result = kErrDataTimedOut;
1049 Error(cip, kDontPerror, "Remote write timed out.\n");
1050 } else if ((gGotBrokenData != 0) || (errno == EPIPE)) {
1052 errno = EPIPE;
1053 Error(cip, kDoPerror, "Lost data connection to remote host.\n");
1054 } else if (errno == EINTR) {
1055 continue;
1056 } else {
1058 Error(cip, kDoPerror, "Remote write failed.\n");
1059 }
1060 (void) shutdown(cip->dataSocket, 2);
1061 goto brk;
1062 }
1063#else /* NO_SIGNALS */
1064 nwrote = write(cip->dataSocket, cp, ntowrite);
1065 if (nwrote < 0) {
1066 if ((gGotBrokenData != 0) || (errno == EPIPE)) {
1068 errno = EPIPE;
1069 Error(cip, kDoPerror, "Lost data connection to remote host.\n");
1070 } else if (errno == EINTR) {
1071 continue;
1072 } else {
1074 Error(cip, kDoPerror, "Remote write failed.\n");
1075 }
1076 (void) shutdown(cip->dataSocket, 2);
1077 goto brk;
1078 }
1079#endif /* NO_SIGNALS */
1080 cp += nwrote;
1081 ntowrite -= nwrote;
1082 } while (ntowrite > 0);
1083 FTPUpdateIOTimer(cip);
1084 }
1085 } else
1086#endif /* ASCII_TRANSLATION */
1087 {
1088 /* binary */
1089 for (;;) {
1090#if !defined(NO_SIGNALS)
1091 gCanBrokenDataJmp = 0;
1092#endif /* NO_SIGNALS */
1093 cp = buf;
1094 nread = read(fd, cp, bufSize);
1095 if (nread < 0) {
1096 if (errno == EINTR) {
1097 continue;
1098 } else {
1100 cip->errNo = kErrReadFailed;
1101 Error(cip, kDoPerror, "Local read failed.\n");
1102 }
1103 break;
1104 } else if (nread == 0) {
1105 break;
1106 }
1107 cip->bytesTransferred += (longest_int) nread;
1108
1109#if !defined(NO_SIGNALS)
1110 gCanBrokenDataJmp = 1;
1111 if (cip->xferTimeout > 0)
1112 (void) alarm(cip->xferTimeout);
1113#endif /* NO_SIGNALS */
1114 do {
1115 if (! WaitForRemoteOutput(cip)) { /* could set cancelXfer */
1116 cip->errNo = result = kErrDataTimedOut;
1117 Error(cip, kDontPerror, "Remote write timed out.\n");
1118 goto brk;
1119 }
1120 if (cip->cancelXfer > 0) {
1123 goto brk;
1124 }
1125
1126#ifdef NO_SIGNALS
1127 nwrote = SWrite(cip->dataSocket, cp, (size_t) nread, (int) cip->xferTimeout, kNoFirstSelect);
1128 if (nwrote < 0) {
1129 if (nwrote == kTimeoutErr) {
1130 cip->errNo = result = kErrDataTimedOut;
1131 Error(cip, kDontPerror, "Remote write timed out.\n");
1132 } else if ((gGotBrokenData != 0) || (errno == EPIPE)) {
1134 errno = EPIPE;
1135 Error(cip, kDoPerror, "Lost data connection to remote host.\n");
1136 } else if (errno == EINTR) {
1137 continue;
1138 } else {
1140 Error(cip, kDoPerror, "Remote write failed.\n");
1141 }
1142 (void) shutdown(cip->dataSocket, 2);
1143 cip->dataSocket = -1;
1144 goto brk;
1145 }
1146#else /* NO_SIGNALS */
1147 nwrote = write(cip->dataSocket, cp, nread);
1148 if (nwrote < 0) {
1149 if ((gGotBrokenData != 0) || (errno == EPIPE)) {
1151 errno = EPIPE;
1152 Error(cip, kDoPerror, "Lost data connection to remote host.\n");
1153 } else if (errno == EINTR) {
1154 continue;
1155 } else {
1157 Error(cip, kDoPerror, "Remote write failed.\n");
1158 }
1159 (void) shutdown(cip->dataSocket, 2);
1160 cip->dataSocket = -1;
1161 goto brk;
1162 }
1163#endif /* NO_SIGNALS */
1164 cp += nwrote;
1165 nread -= nwrote;
1166 } while (nread > 0);
1167 FTPUpdateIOTimer(cip);
1168 }
1169 }
1170brk:
1171
1172 if (fdtouse < 0) {
1173 (void) Fstat(fd, &st);
1174 }
1175
1176 if (fdtouse < 0) {
1177 if (shutdown(fd, 1) == 0) {
1178 /* This looks very bizarre, since
1179 * we will be checking the socket
1180 * for readability here!
1181 *
1182 * The reason for this is that we
1183 * want to be able to timeout a
1184 * small put. So, we close the
1185 * write end of the socket first,
1186 * which tells the server we're
1187 * done writing. We then wait
1188 * for the server to close down
1189 * the whole socket, which tells
1190 * us that the file was completed.
1191 */
1192 (void) WaitForRemoteInput(cip); /* Close could block. */
1193 }
1194 }
1195
1196#if !defined(NO_SIGNALS)
1197 gCanBrokenDataJmp = 0;
1198 if (cip->xferTimeout > 0)
1199 (void) alarm(0);
1200#endif /* NO_SIGNALS */
1201 tmpResult = FTPEndDataCmd(cip, 1);
1202 if ((tmpResult < 0) && (result == kNoErr)) {
1203 cip->errNo = result = kErrSTORFailed;
1204 }
1205 FTPStopIOTimer(cip);
1206
1207 if (fdtouse < 0) {
1208 /* If they gave us a descriptor (fdtouse >= 0),
1209 * leave it open, otherwise we opened it, so
1210 * we need to dispose of it.
1211 */
1212 (void) close(fd);
1213 fd = -1;
1214 }
1215
1216 if (result == kNoErr) {
1217 /* The store succeeded; If we were
1218 * uploading to a temporary file,
1219 * move the new file to the new name.
1220 */
1221 cip->numUploads++;
1222
1223 if ((tmppfx[0] != '\0') || (tmpsfx[0] != '\0')) {
1224 if ((result = FTPRename(cip, dstfile, odstfile)) < 0) {
1225 /* May fail if file was already there,
1226 * so delete the old one so we can move
1227 * over it.
1228 */
1229 if (FTPDelete(cip, odstfile, kRecursiveNo, kGlobNo) == kNoErr) {
1230 result = FTPRename(cip, dstfile, odstfile);
1231 if (result < 0) {
1232 Error(cip, kDontPerror, "Could not rename %s to %s: %s.\n", dstfile, odstfile, FTPStrError(cip->errNo));
1233 }
1234 } else {
1235 Error(cip, kDontPerror, "Could not delete old %s, so could not rename %s to that: %s\n", odstfile, dstfile, FTPStrError(cip->errNo));
1236 }
1237 }
1238 }
1239
1240 if (FTPUtime(cip, odstfile, st.st_atime, st.st_mtime, st.st_ctime) != kNoErr) {
1241 if (cip->errNo != kErrUTIMENotAvailable)
1242 Error(cip, kDontPerror, "Could not preserve times for %s: %s.\n", odstfile, FTPStrError(cip->errNo));
1243 }
1244
1245 if (deleteflag == kDeleteYes) {
1246 if (unlink(file) < 0) {
1248 }
1249 }
1250 }
1251
1252#if !defined(NO_SIGNALS)
1253 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
1254#endif /* NO_SIGNALS */
1255 return (result);
1256} /* FTPPutOneF */
#define O_RDONLY
Definition: acwin.h:108
static int inbuf
Definition: adnsresfilter.c:73
#define S_ISDIR(mode)
Definition: various.h:18
#define S_ISREG(mode)
Definition: various.h:17
r l[0]
Definition: byte_order.h:168
__kernel_size_t size_t
Definition: linux.h:237
#define Fstat
Definition: syshdrs.h:79
int FTPUtime(const FTPCIPtr cip, const char *const file, time_t actime, time_t modtime, time_t crtime)
Definition: cmds.c:1649
int FTPFileExists2(const FTPCIPtr cip, const char *const file, const int tryMDTM, const int trySIZE, const int tryMLST, const int trySTAT, const int tryNLST)
Definition: cmds.c:1350
int FTPRename(const FTPCIPtr cip, const char *const oldname, const char *const newname)
Definition: cmds.c:703
const char * FTPStrError(int e)
Definition: errno.c:114
static int WaitForRemoteOutput(const FTPCIPtr cip)
Definition: io.c:585
int SWrite(int, const char *const, size_t, int, int)
Definition: SWrite.c:90
#define kNetWriting
Definition: ncftp.h:302
#define kErrLocalDeleteFailed
Definition: ncftp_errno.h:84
#define kErrSocketWriteFailed
Definition: ncftp_errno.h:52
#define kErrUTIMENotAvailable
Definition: ncftp_errno.h:82
#define kErrReadFailed
Definition: ncftp_errno.h:51
#define kErrSTORFailed
Definition: ncftp_errno.h:49
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
int hasSTORBUFSIZE
Definition: ncftp.h:174

Referenced by FTPPutFiles3(), and FTPPutOneFile3().

◆ FTPPutOneFile()

int FTPPutOneFile ( const FTPCIPtr  cip,
const char *const  file,
const char *const  dstfile 
)

Definition at line 2766 of file io.c.

2767{
2768 return (FTPPutOneFile3(cip, file, dstfile, kTypeBinary, -1, 0, NULL, NULL, kResumeNo, kDeleteNo, NoConfirmResumeUploadProc, 0));
2769} /* FTPPutOneFile */
int FTPPutOneFile3(const FTPCIPtr cip, const char *const file, const char *const dstfile, const int xtype, const int fdtouse, const int appendflag, const char *const tmppfx, const char *const tmpsfx, const int resumeflag, const int deleteflag, const ConfirmResumeUploadProc resumeProc, int UNUSED(reserved))
Definition: io.c:1262

◆ FTPPutOneFile2()

int FTPPutOneFile2 ( const FTPCIPtr  cip,
const char *const  file,
const char *const  dstfile,
const int  xtype,
const int  fdtouse,
const int  appendflag,
const char *const  tmppfx,
const char *const  tmpsfx 
)

Definition at line 2775 of file io.c.

2776{
2777 return (FTPPutOneFile3(cip, file, dstfile, xtype, fdtouse, appendflag, tmppfx, tmpsfx, kResumeNo, kDeleteNo, NoConfirmResumeUploadProc, 0));
2778} /* FTPPutOneFile2 */

◆ FTPPutOneFile3()

int FTPPutOneFile3 ( const FTPCIPtr  cip,
const char *const  file,
const char *const  dstfile,
const int  xtype,
const int  fdtouse,
const int  appendflag,
const char *const  tmppfx,
const char *const  tmpsfx,
const int  resumeflag,
const int  deleteflag,
const ConfirmResumeUploadProc  resumeProc,
int   UNUSEDreserved 
)

Definition at line 1262 of file io.c.

1275{
1276 int result;
1277
1279 if (cip == NULL)
1280 return (kErrBadParameter);
1281 if (strcmp(cip->magic, kLibraryMagic))
1282 return (kErrBadMagic);
1283
1284 if ((dstfile == NULL) || (dstfile[0] == '\0'))
1285 return (kErrBadParameter);
1286 if (fdtouse < 0) {
1287 if ((file == NULL) || (file[0] == '\0'))
1288 return (kErrBadParameter);
1289 }
1290 result = FTPPutOneF(cip, file, dstfile, xtype, fdtouse, appendflag, tmppfx, tmpsfx, resumeflag, deleteflag, resumeProc);
1291 return (result);
1292} /* FTPPutOneFile3 */

Referenced by FTPPutOneFile(), FTPPutOneFile2(), FTPPutOneFileAscii(), and PutCmd().

◆ FTPPutOneFileAscii()

int FTPPutOneFileAscii ( const FTPCIPtr  cip,
const char *const  file,
const char *const  dstfile 
)

Definition at line 2802 of file io.c.

2803{
2804 return (FTPPutOneFile3(cip, file, dstfile, kTypeAscii, -1, 0, NULL, NULL, kResumeNo, kDeleteNo, NoConfirmResumeUploadProc, 0));
2805} /* FTPPutOneFileAscii */

◆ FTPRequestMlsOptions()

static void FTPRequestMlsOptions ( const FTPCIPtr  cip)
static

Definition at line 289 of file io.c.

290{
291 int f;
292 char optstr[128];
293 size_t optstrlen;
294
295 if (cip->usedMLS == 0) {
296 /* First MLSD/MLST ? */
297 cip->usedMLS = 1;
298
300 optstr[0] = '\0';
301
302 /* TYPE */
303 if ((f & kMlsOptType) != 0) {
304 STRNCAT(optstr, "type;");
305 }
306
307 /* SIZE */
308 if ((f & kMlsOptSize) != 0) {
309 STRNCAT(optstr, "size;");
310 }
311
312 /* MODTIME */
313 if ((f & kMlsOptModify) != 0) {
314 STRNCAT(optstr, "modify;");
315 }
316
317 /* MODE */
318 if ((f & kMlsOptUNIXmode) != 0) {
319 STRNCAT(optstr, "UNIX.mode;");
320 }
321
322 /* PERM */
323 if ((f & kMlsOptPerm) != 0) {
324 STRNCAT(optstr, "perm;");
325 }
326
327 /* OWNER */
328 if ((f & kMlsOptUNIXowner) != 0) {
329 STRNCAT(optstr, "UNIX.owner;");
330 }
331
332 /* UID */
333 if ((f & kMlsOptUNIXuid) != 0) {
334 STRNCAT(optstr, "UNIX.uid;");
335 }
336
337 /* GROUP */
338 if ((f & kMlsOptUNIXgroup) != 0) {
339 STRNCAT(optstr, "UNIX.group;");
340 }
341
342 /* GID */
343 if ((f & kMlsOptUNIXgid) != 0) {
344 STRNCAT(optstr, "UNIX.gid;");
345 }
346
347 /* UNIQUE */
348 if ((f & kMlsOptUnique) != 0) {
349 STRNCAT(optstr, "unique;");
350 }
351
352 /* Tell the server what we prefer. */
353 optstrlen = strlen(optstr);
354 if (optstrlen > 0) {
355 if (optstr[optstrlen - 1] == ';')
356 optstr[optstrlen - 1] = '\0';
357 (void) FTPCmd(cip, "OPTS MLST %s", optstr);
358 }
359 }
360} /* FTPRequestMlsOptions */
GLfloat f
Definition: glext.h:7540
#define f
Definition: ke_i.h:83
#define kMlsOptUNIXgid
Definition: ncftp.h:409
#define kMlsOptUnique
Definition: ncftp.h:410
#define kMlsOptSize
Definition: ncftp.h:402
#define kMlsOptModify
Definition: ncftp.h:403
#define kMlsOptType
Definition: ncftp.h:401
#define kMlsOptUNIXgroup
Definition: ncftp.h:406
#define kPreferredMlsOpts
Definition: ncftp.h:399
#define kMlsOptPerm
Definition: ncftp.h:407
#define kMlsOptUNIXmode
Definition: ncftp.h:404
#define kMlsOptUNIXuid
Definition: ncftp.h:408
#define kMlsOptUNIXowner
Definition: ncftp.h:405

Referenced by FTPListToMemory2().

◆ FTPStartIOTimer()

void FTPStartIOTimer ( const FTPCIPtr  cip)

Definition at line 93 of file io.c.

94{
95 (void) gettimeofday(&cip->t0, NULL);
96 if (cip->progress != (FTPProgressMeterProc) 0)
97 (*cip->progress)(cip, kPrInitMsg);
98} /* FTPStartIOTimer */
#define kPrInitMsg
Definition: ncftp.h:290
void(* FTPProgressMeterProc)(const FTPCIPtr, int)
Definition: ncftp.h:125
FTPProgressMeterProc progress
Definition: ncftp.h:198

Referenced by FTPGetOneF(), and FTPPutOneF().

◆ FTPStopIOTimer()

void FTPStopIOTimer ( const FTPCIPtr  cip)

Definition at line 159 of file io.c.

160{
161 cip->nextProgressUpdate = 0; /* force last update */
162 FTPUpdateIOTimer(cip);
163 if (cip->progress != (FTPProgressMeterProc) 0)
164 (*cip->progress)(cip, kPrEndMsg);
165} /* FTPStopIOTimer */
#define kPrEndMsg
Definition: ncftp.h:292

Referenced by FTPGetOneF(), and FTPPutOneF().

◆ FTPUpdateIOTimer()

void FTPUpdateIOTimer ( const FTPCIPtr  cip)

Definition at line 104 of file io.c.

105{
106 double sec;
107 struct timeval *t0, t1;
108 time_t now;
109
110 (void) time(&now);
111 if (now < cip->nextProgressUpdate)
112 return;
113 now += 1;
114 cip->nextProgressUpdate = now;
115
116 (void) gettimeofday(&t1, NULL);
117 t0 = &cip->t0;
118
119 if (t0->tv_usec > t1.tv_usec) {
120 t1.tv_usec += 1000000;
121 t1.tv_sec--;
122 }
123 sec = ((double) (t1.tv_usec - t0->tv_usec) * 0.000001)
124 + (t1.tv_sec - t0->tv_sec);
125 if (sec > 0.0) {
126 cip->kBytesPerSec = ((double) cip->bytesTransferred) / (1024.0 * sec);
127 } else {
128 cip->kBytesPerSec = -1.0;
129 }
130 if (cip->expectedSize == kSizeUnknown) {
131 cip->percentCompleted = -1.0;
132 cip->secLeft = -1.0;
133 } else if (cip->expectedSize <= 0) {
134 cip->percentCompleted = 100.0;
135 cip->secLeft = 0.0;
136 } else {
137 cip->percentCompleted = ((double) (100.0 * (cip->bytesTransferred + cip->startPoint))) / ((double) cip->expectedSize);
138 if (cip->percentCompleted >= 100.0) {
139 cip->percentCompleted = 100.0;
140 cip->secLeft = 0.0;
141 } else if (cip->percentCompleted <= 0.0) {
142 cip->secLeft = 999.0;
143 }
144 if (cip->kBytesPerSec > 0.0) {
145 cip->secLeft = ((cip->expectedSize - cip->bytesTransferred - cip->startPoint) / 1024.0) / cip->kBytesPerSec;
146 if (cip->secLeft < 0.0)
147 cip->secLeft = 0.0;
148 }
149 }
150 cip->sec = sec;
151 if ((cip->progress != (FTPProgressMeterProc) 0) && (cip->useProgressMeter != 0))
152 (*cip->progress)(cip, kPrUpdateMsg);
153} /* FTPUpdateIOTimer */
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
#define kPrUpdateMsg
Definition: ncftp.h:291
unsigned long tv_sec
Definition: linux.h:1738
unsigned long tv_usec
Definition: linux.h:1739

Referenced by FTPGetOneF(), FTPPutOneF(), FTPStopIOTimer(), WaitForRemoteInput(), and WaitForRemoteOutput().

◆ WaitForRemoteInput()

static int WaitForRemoteInput ( const FTPCIPtr  cip)
static

Definition at line 1424 of file io.c.

1425{
1426 fd_set ss, ss2;
1427 struct timeval tv;
1428 int result;
1429 int fd;
1430 int wsecs;
1431 int xferTimeout;
1432 int ocancelXfer;
1433
1434 xferTimeout = cip->xferTimeout;
1435 if (xferTimeout < 1)
1436 return (1);
1437
1438 fd = cip->dataSocket;
1439 if (fd < 0)
1440 return (1);
1441
1442 ocancelXfer = cip->cancelXfer;
1443 wsecs = 0;
1444 cip->stalled = 0;
1445
1446 while ((xferTimeout <= 0) || (wsecs < xferTimeout)) {
1447 if ((cip->cancelXfer != 0) && (ocancelXfer == 0)) {
1448 /* leave cip->stalled -- could have been stalled and then canceled. */
1449 return (1);
1450 }
1451 FD_ZERO(&ss);
1452 FD_SET(fd, &ss);
1453 ss2 = ss;
1454 tv.tv_sec = 1;
1455 tv.tv_usec = 0;
1457 if (result == 1) {
1458 /* ready */
1459 cip->stalled = 0;
1460 return (1);
1461 } else if (result < 0) {
1462 if (result != EINTR) {
1463 perror("select");
1464 cip->stalled = 0;
1465 return (1);
1466 }
1467 } else {
1468 wsecs++;
1469 cip->stalled = wsecs;
1470 }
1471 FTPUpdateIOTimer(cip);
1472 }
1473
1474#if !defined(NO_SIGNALS)
1475 /* Shouldn't get here -- alarm() should have
1476 * went off by now.
1477 */
1478 (void) kill(getpid(), SIGALRM);
1479#endif /* NO_SIGNALS */
1480
1481 cip->dataTimedOut = 1;
1482 return (0); /* timed-out */
1483} /* WaitForRemoteInput */
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define ss
Definition: i386-dis.c:441
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define SELECT_TYPE_ARG234
Definition: wincfg.h:4
Definition: winsock.h:66
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
#define getpid
Definition: wintirpc.h:52

Referenced by FTPGetOneF(), and FTPPutOneF().

◆ WaitForRemoteOutput()

static int WaitForRemoteOutput ( const FTPCIPtr  cip)
static

Definition at line 585 of file io.c.

586{
587 fd_set ss, ss2;
588 struct timeval tv;
589 int result;
590 int fd;
591 int wsecs;
592 int xferTimeout;
593 int ocancelXfer;
594
595 xferTimeout = cip->xferTimeout;
596 if (xferTimeout < 1)
597 return (1);
598
599 fd = cip->dataSocket;
600 if (fd < 0)
601 return (1);
602
603 ocancelXfer = cip->cancelXfer;
604 wsecs = 0;
605 cip->stalled = 0;
606
607 while ((xferTimeout <= 0) || (wsecs < xferTimeout)) {
608 if ((cip->cancelXfer != 0) && (ocancelXfer == 0)) {
609 /* leave cip->stalled -- could have been stalled and then canceled. */
610 return (1);
611 }
612 FD_ZERO(&ss);
613 FD_SET(fd, &ss);
614 ss2 = ss;
615 tv.tv_sec = 1;
616 tv.tv_usec = 0;
618 if (result == 1) {
619 /* ready */
620 cip->stalled = 0;
621 return (1);
622 } else if (result < 0) {
623 if (errno != EINTR) {
624 perror("select");
625 cip->stalled = 0;
626 return (1);
627 }
628 } else {
629 wsecs++;
630 cip->stalled = wsecs;
631 }
632 FTPUpdateIOTimer(cip);
633 }
634
635#if !defined(NO_SIGNALS)
636 /* Shouldn't get here -- alarm() should have
637 * went off by now.
638 */
639 (void) kill(getpid(), SIGALRM);
640#endif /* NO_SIGNALS */
641
642 cip->dataTimedOut = 1;
643 return (0); /* timed-out */
644} /* WaitForRemoteOutput */

Referenced by FTPPutOneF().

Variable Documentation

◆ gGotBrokenData

int gGotBrokenData = 0
static

Definition at line 10 of file io.c.

Referenced by FTPGetOneF(), FTPListToMemory2(), and FTPPutOneF().