📄 open.c
字号:
if ((semi = strchr(lastslash + 1, ';')) != NULL) {
*semi++ = '\0';
#ifdef HAVE_STRCASECMP
if (strcasecmp(semi, "type=i") == 0) {
if (xtype != NULL)
*xtype = kTypeBinary;
} else if (strcasecmp(semi, "type=a") == 0) {
if (xtype != NULL)
*xtype = kTypeAscii;
} else if (strcasecmp(semi, "type=b") == 0) {
if (xtype != NULL)
*xtype = kTypeBinary;
} else if (strcasecmp(semi, "type=d") == 0) {
if (wantnlst != NULL) {
*wantnlst = 1;
if (xtype != NULL)
*xtype = kTypeAscii;
} else {
/* You didn't want these. */
return (kMalformedURL);
}
}
#else /* HAVE_STRCASECMP */
if (strcmp(semi, "type=i") == 0) {
if (xtype != NULL)
*xtype = kTypeBinary;
} else if (strcmp(semi, "type=a") == 0) {
if (xtype != NULL)
*xtype = kTypeAscii;
} else if (strcmp(semi, "type=b") == 0) {
if (xtype != NULL)
*xtype = kTypeBinary;
} else if (strcmp(semi, "type=d") == 0) {
if (wantnlst != NULL) {
*wantnlst = 1;
if (xtype != NULL)
*xtype = kTypeAscii;
} else {
/* You didn't want these. */
return (kMalformedURL);
}
}
#endif /* HAVE_STRCASECMP */
}
URLCopyToken(fn, fnsize, lastslash + 1, strlen(lastslash + 1));
for (parsestr = hend; (tok = strtok(parsestr, "/")) != NULL; parsestr = NULL) {
URLCopyToken(subdir, sizeof(subdir), tok, strlen(tok));
(void) AddLine(cdlist, subdir);
}
*lastslash = '/';
return (kNoErr);
} /* FTPDecodeURL */
int
FTPOpenHost(const FTPCIPtr cip)
{
int result;
time_t t0, t1;
int elapsed;
int dials;
if (cip == NULL)
return (kErrBadParameter);
if (strcmp(cip->magic, kLibraryMagic))
return (kErrBadMagic);
if (cip->host[0] == '\0') {
cip->errNo = kErrBadParameter;
return (kErrBadParameter);
}
for ( result = kErrConnectMiscErr, dials = 0;
cip->maxDials < 0 || dials < cip->maxDials;
dials++)
{
/* Allocate (or if the host was closed, reallocate)
* the transfer data buffer.
*/
result = FTPAllocateHost(cip);
if (result < 0)
return (result);
if (dials > 0)
PrintF(cip, "Retry Number: %d\n", dials);
if (cip->redialStatusProc != 0)
(*cip->redialStatusProc)(cip, kRedialStatusDialing, dials);
(void) time(&t0);
result = OpenControlConnection(cip, cip->host, cip->port);
(void) time(&t1);
if (result == kNoErr) {
/* We were hooked up successfully. */
PrintF(cip, "Connected to %s.\n", cip->host);
result = FTPLoginHost(cip);
if (result == kNoErr) {
(void) FTPQueryFeatures(cip);
break;
}
/* Close and try again. */
(void) FTPCloseHost(cip);
/* Originally we also stopped retyring if
* we got kErrBadRemoteUser and non-anonymous,
* but some FTP servers apparently do their
* max user check after the username is sent.
*/
if (result == kErrBadRemoteUserOrPassword /* || (result == kErrBadRemoteUser) */) {
if (strcmp(cip->user, "anonymous") != 0) {
/* Non-anonymous login was denied, and
* retrying is not going to help.
*/
break;
}
}
} else if ((result != kErrConnectRetryableErr) && (result != kErrConnectRefused) && (result != kErrRemoteHostClosedConnection)) {
/* Irrecoverable error, so don't bother redialing.
* The error message should have already been printed
* from OpenControlConnection().
*/
PrintF(cip, "Cannot recover from miscellaneous open error %d.\n", result);
return result;
}
/* Retryable error, wait and then redial. */
if (cip->redialDelay > 0) {
/* But don't sleep if this is the last loop. */
if ((cip->maxDials < 0) || (dials < (cip->maxDials - 1))) {
elapsed = (int) (t1 - t0);
if (elapsed < cip->redialDelay) {
PrintF(cip, "Sleeping %u seconds.\n",
(unsigned) cip->redialDelay - elapsed);
if (cip->redialStatusProc != 0)
(*cip->redialStatusProc)(cip, kRedialStatusSleeping, cip->redialDelay - elapsed);
(void) sleep((unsigned) cip->redialDelay - elapsed);
}
}
}
}
return (result);
} /* FTPOpenHost */
int
FTPOpenHostNoLogin(const FTPCIPtr cip)
{
int result;
time_t t0, t1;
int elapsed;
int dials;
if (cip == NULL)
return (kErrBadParameter);
if (strcmp(cip->magic, kLibraryMagic))
return (kErrBadMagic);
if (cip->host[0] == '\0') {
cip->errNo = kErrBadParameter;
return (kErrBadParameter);
}
for ( result = kErrConnectMiscErr, dials = 0;
cip->maxDials < 0 || dials < cip->maxDials;
dials++)
{
/* Allocate (or if the host was closed, reallocate)
* the transfer data buffer.
*/
result = FTPAllocateHost(cip);
if (result < 0)
return (result);
if (dials > 0)
PrintF(cip, "Retry Number: %d\n", dials);
if (cip->redialStatusProc != 0)
(*cip->redialStatusProc)(cip, kRedialStatusDialing, dials);
(void) time(&t0);
result = OpenControlConnection(cip, cip->host, cip->port);
(void) time(&t1);
if (result == kNoErr) {
/* We were hooked up successfully. */
PrintF(cip, "Connected to %s.\n", cip->host);
/* Not logging in... */
if (result == kNoErr)
break;
} else if ((result != kErrConnectRetryableErr) && (result != kErrConnectRefused) && (result != kErrRemoteHostClosedConnection)) {
/* Irrecoverable error, so don't bother redialing.
* The error message should have already been printed
* from OpenControlConnection().
*/
PrintF(cip, "Cannot recover from miscellaneous open error %d.\n", result);
return result;
}
/* Retryable error, wait and then redial. */
if (cip->redialDelay > 0) {
/* But don't sleep if this is the last loop. */
if ((cip->maxDials < 0) || (dials < (cip->maxDials - 1))) {
elapsed = (int) (t1 - t0);
if (elapsed < cip->redialDelay) {
PrintF(cip, "Sleeping %u seconds.\n",
(unsigned) cip->redialDelay - elapsed);
if (cip->redialStatusProc != 0)
(*cip->redialStatusProc)(cip, kRedialStatusSleeping, cip->redialDelay - elapsed);
(void) sleep((unsigned) cip->redialDelay - elapsed);
}
}
}
}
return (result);
} /* FTPOpenHostNoLogin */
int
FTPInitConnectionInfo(const FTPLIPtr lip, const FTPCIPtr cip, size_t bufSize)
{
size_t siz;
if ((lip == NULL) || (cip == NULL) || (bufSize == 0))
return (kErrBadParameter);
siz = sizeof(FTPConnectionInfo);
(void) memset(cip, 0, siz);
if (strcmp(lip->magic, kLibraryMagic))
return (kErrBadMagic);
cip->buf = NULL; /* denote that it needs to be allocated. */
cip->bufSize = bufSize;
cip->port = lip->defaultPort;
cip->firewallPort = lip->defaultPort;
cip->maxDials = kDefaultMaxDials;
cip->redialDelay = kDefaultRedialDelay;
cip->xferTimeout = kDefaultXferTimeout;
cip->connTimeout = kDefaultConnTimeout;
cip->ctrlTimeout = kDefaultCtrlTimeout;
cip->abortTimeout = kDefaultAbortTimeout;
cip->ctrlSocketR = kClosedFileDescriptor;
cip->ctrlSocketW = kClosedFileDescriptor;
cip->dataPortMode = kSendPortMode;
cip->dataSocket = kClosedFileDescriptor;
cip->lip = lip;
cip->hasPASV = kCommandAvailabilityUnknown;
cip->hasSIZE = kCommandAvailabilityUnknown;
cip->hasMDTM = kCommandAvailabilityUnknown;
cip->hasREST = kCommandAvailabilityUnknown;
cip->hasNLST_d = kCommandAvailabilityUnknown;
cip->hasUTIME = kCommandAvailabilityUnknown;
cip->hasFEAT = kCommandAvailabilityUnknown;
cip->hasMLSD = kCommandAvailabilityUnknown;
cip->hasMLST = kCommandAvailabilityUnknown;
cip->hasCLNT = kCommandAvailabilityUnknown;
cip->hasRETRBUFSIZE = kCommandAvailabilityUnknown;
cip->hasRBUFSIZ = kCommandAvailabilityUnknown;
cip->hasRBUFSZ = kCommandAvailabilityUnknown;
cip->hasSTORBUFSIZE = kCommandAvailabilityUnknown;
cip->hasSBUFSIZ = kCommandAvailabilityUnknown;
cip->hasSBUFSZ = kCommandAvailabilityUnknown;
cip->STATfileParamWorks = kCommandAvailabilityUnknown;
cip->NLSTfileParamWorks = kCommandAvailabilityUnknown;
cip->firewallType = kFirewallNotInUse;
cip->startingWorkingDirectory = NULL;
(void) STRNCPY(cip->magic, kLibraryMagic);
(void) STRNCPY(cip->user, "anonymous");
return (kNoErr);
} /* FTPInitConnectionInfo */
int
FTPRebuildConnectionInfo(const FTPLIPtr lip, const FTPCIPtr cip)
{
char *buf;
cip->lip = lip;
cip->debugLog = NULL;
cip->errLog = NULL;
cip->debugLogProc = NULL;
cip->errLogProc = NULL;
cip->buf = NULL;
cip->cin = NULL;
cip->cout = NULL;
cip->errNo = 0;
cip->progress = NULL;
cip->rname = NULL;
cip->lname = NULL;
cip->onConnectMsgProc = NULL;
cip->redialStatusProc = NULL;
cip->printResponseProc = NULL;
cip->onLoginMsgProc = NULL;
cip->passphraseProc = NULL;
cip->startingWorkingDirectory = NULL;
cip->asciiFilenameExtensions = NULL;
(void) memset(&cip->lastFTPCmdResultLL, 0, sizeof(LineList));
/* Allocate a new buffer. */
buf = (char *) calloc((size_t) 1, cip->bufSize);
if (buf == NULL) {
cip->errNo = kErrMallocFailed;
return (kErrMallocFailed);
}
cip->buf = buf;
/* Reattach the FILE pointers for use with the Std I/O library
* routines.
*/
if ((cip->cin = fdopen(cip->ctrlSocketR, "r")) == NULL) {
cip->errNo = kErrFdopenR;
cip->ctrlSocketR = kClosedFileDescriptor;
cip->ctrlSocketW = kClosedFileDescriptor;
return (kErrFdopenR);
}
if ((cip->cout = fdopen(cip->ctrlSocketW, "w")) == NULL) {
CloseFile(&cip->cin);
cip->errNo = kErrFdopenW;
cip->ctrlSocketR = kClosedFileDescriptor;
cip->ctrlSocketW = kClosedFileDescriptor;
return (kErrFdopenW);
}
#if USE_SIO
if (InitSReadlineInfo(&cip->ctrlSrl, cip->ctrlSocketR, cip->srlBuf, sizeof(cip->srlBuf), (int) cip->ctrlTimeout, 1) < 0) {
cip->errNo = kErrFdopenW;
CloseFile(&cip->cin);
cip->errNo = kErrFdopenW;
cip->ctrlSocketR = kClosedFileDescriptor;
cip->ctrlSocketW = kClosedFileDescriptor;
return (kErrFdopenW);
}
#endif
return (kNoErr);
} /* FTPRebuildConnectionInfo */
int
FTPInitLibrary(const FTPLIPtr lip)
{
struct servent *ftp;
if (lip == NULL)
return (kErrBadParameter);
(void) memset(lip, 0, sizeof(FTPLibraryInfo));
if ((ftp = getservbyname("ftp", "tcp")) == NULL)
lip->defaultPort = (unsigned int) kDefaultFTPPort;
else
lip->defaultPort = (unsigned int) ntohs(ftp->s_port);
lip->init = 1;
(void) STRNCPY(lip->magic, kLibraryMagic);
/* We'll initialize the defaultAnonPassword field
* later when we try the first anon ftp connection.
*/
#ifdef HAVE_LIBSOCKS
SOCKSinit("libncftp");
lip->socksInit = 1;
#endif
return (kNoErr);
} /* FTPInitLibrary */
/* Open.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -