ReactOS 0.4.15-dev-7942-gd23573b
open.c File Reference
#include "syshdrs.h"
Include dependency graph for open.c:

Go to the source code of this file.

Functions

static void FTPDeallocateHost (const FTPCIPtr cip)
 
static int FTPAllocateHost (const FTPCIPtr cip)
 
void FTPInitializeOurHostName (const FTPLIPtr lip)
 
void FTPInitializeAnonPassword (const FTPLIPtr lip)
 
int FTPLoginHost (const FTPCIPtr cip)
 
static void FTPExamineMlstFeatures (const FTPCIPtr cip, const char *features)
 
int FTPQueryFeatures (const FTPCIPtr cip)
 
int FTPCloseHost (const FTPCIPtr cip)
 
void FTPShutdownHost (const FTPCIPtr cip)
 
void URLCopyToken (char *dst, size_t dsize, const char *src, size_t howmuch)
 
int FTPDecodeURL (const FTPCIPtr cip, char *const url, LineListPtr cdlist, char *const fn, const size_t fnsize, int *const xtype, int *const wantnlst)
 
int FTPOpenHost (const FTPCIPtr cip)
 
int FTPOpenHostNoLogin (const FTPCIPtr cip)
 
int FTPInitConnectionInfo (const FTPLIPtr lip, const FTPCIPtr cip, size_t bufSize)
 
int FTPRebuildConnectionInfo (const FTPLIPtr lip, const FTPCIPtr cip)
 
int FTPInitLibrary (const FTPLIPtr lip)
 

Function Documentation

◆ FTPAllocateHost()

static int FTPAllocateHost ( const FTPCIPtr  cip)
static

Definition at line 39 of file open.c.

40{
41 char *buf;
42
43 /* Requires the cip->bufSize field set,
44 * and the cip->buf cleared if the
45 * buffer is not allocated.
46 */
47 if (cip->buf == NULL) {
48 buf = (char *) calloc((size_t) 1, cip->bufSize);
49 if (buf == NULL) {
50 Error(cip, kDontPerror, "Malloc failed.\n");
52 return (kErrMallocFailed);
53 }
54 cip->buf = buf;
55 }
56 return (kNoErr);
57} /* FTPAllocateHost */
BOOL Error
Definition: chkdsk.c:66
#define NULL
Definition: types.h:112
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define kDontPerror
Definition: util.h:45
#define kNoErr
Definition: ncftp_errno.h:9
#define kErrMallocFailed
Definition: ncftp_errno.h:40
#define calloc
Definition: rosglue.h:14
size_t bufSize
Definition: ncftp.h:187
char * buf
Definition: ncftp.h:186

Referenced by FTPOpenHost(), and FTPOpenHostNoLogin().

◆ FTPCloseHost()

int FTPCloseHost ( const FTPCIPtr  cip)

Definition at line 523 of file open.c.

524{
525 ResponsePtr rp;
526 int result;
527
528 if (cip == NULL)
529 return (kErrBadParameter);
530 if (strcmp(cip->magic, kLibraryMagic))
531 return (kErrBadMagic);
532
533 /* Data connection shouldn't be open normally. */
536
537 result = kNoErr;
538 if (cip->connected != 0) {
539 rp = InitResponse();
540 if (rp == NULL) {
541 cip->errNo = kErrMallocFailed;
542 result = cip->errNo;
543 } else {
544 rp->eofOkay = 1; /* We are expecting EOF after this cmd. */
545 cip->eofOkay = 1;
546 (void) RCmd(cip, rp, "QUIT");
547 DoneWithResponse(cip, rp);
548 }
549 }
550
552
553 /* Dispose dynamic data structures, so you won't leak
554 * if you OpenHost with this again.
555 */
557 return (result);
558} /* FTPCloseHost */
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
GLuint64EXT * result
Definition: glext.h:11304
void CloseControlConnection(const FTPCIPtr cip)
Definition: ftp.c:197
static void FTPDeallocateHost(const FTPCIPtr cip)
Definition: open.c:11
#define kClosedFileDescriptor
Definition: util.h:47
int RCmd(const FTPCIPtr, ResponsePtr, const char *,...)
Definition: rcmd.c:718
void DoneWithResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:114
void FTPAbortDataTransfer(const FTPCIPtr cip)
Definition: rcmd.c:870
#define kLibraryMagic
Definition: ncftp.h:65
ResponsePtr InitResponse(void)
Definition: rcmd.c:38
#define kErrBadMagic
Definition: ncftp_errno.h:55
#define kErrBadParameter
Definition: ncftp_errno.h:56
char magic[16]
Definition: ncftp.h:135
Definition: ncftp.h:89
int eofOkay
Definition: ncftp.h:94

Referenced by CloseHost(), and FTPOpenHost().

◆ FTPDeallocateHost()

static void FTPDeallocateHost ( const FTPCIPtr  cip)
static

Definition at line 11 of file open.c.

12{
13 /* Requires the cip->bufSize field set,
14 * and the cip->buf set if the
15 * buffer is allocated.
16 */
17 if (cip->buf != NULL) {
18 (void) memset(cip->buf, 0, cip->bufSize);
19 free(cip->buf);
20 cip->buf = NULL;
21 }
22
23 if (cip->startingWorkingDirectory != NULL) {
26 }
27
28#if USE_SIO
30#endif
32} /* FTPDeallocateHost */
#define free
Definition: debug_ros.c:5
void DisposeLineListContents(LineListPtr list)
Definition: linelist.c:33
void DisposeSReadlineInfo(SReadlineInfo *)
Definition: SReadline.c:57
#define memset(x, y, z)
Definition: compat.h:39
char * startingWorkingDirectory
Definition: ncftp.h:158
LineList lastFTPCmdResultLL
Definition: ncftp.h:215
SReadlineInfo ctrlSrl
Definition: ncftp.h:240

Referenced by FTPCloseHost(), and FTPShutdownHost().

◆ FTPDecodeURL()

int FTPDecodeURL ( const FTPCIPtr  cip,
char *const  url,
LineListPtr  cdlist,
char *const  fn,
const size_t  fnsize,
int *const  xtype,
int *const  wantnlst 
)

Definition at line 639 of file open.c.

648{
649 char *cp;
650 char *hstart, *hend;
651 char *h2start;
652 char *at1;
653 char portstr[32];
654 int port;
655 int sc;
656 char *lastslash;
657 char *parsestr;
658 char *tok;
659 char subdir[128];
660 char *semi;
661
662 InitLineList(cdlist);
663 *fn = '\0';
664 if (wantnlst != NULL)
665 *wantnlst = 0;
666 if (xtype != NULL)
667 *xtype = kTypeBinary;
668
669 cp = NULL; /* shut up warnings */
670#ifdef HAVE_STRCASECMP
671 if (strncasecmp(url, "<URL:ftp://", 11) == 0) {
672 cp = url + strlen(url) - 1;
673 if (*cp != '>')
674 return (kMalformedURL); /* missing closing > */
675 *cp = '\0';
676 cp = url + 11;
677 } else if (strncasecmp(url, "ftp://", 6) == 0) {
678 cp = url + 6;
679 } else {
680 return (-1); /* not a RFC 1738 URL */
681 }
682#else /* HAVE_STRCASECMP */
683 if (strncmp(url, "<URL:ftp://", 11) == 0) {
684 cp = url + strlen(url) - 1;
685 if (*cp != '>')
686 return (kMalformedURL); /* missing closing > */
687 *cp = '\0';
688 cp = url + 11;
689 } else if (strncmp(url, "ftp://", 6) == 0) {
690 cp = url + 6;
691 } else {
692 return (-1); /* not a RFC 1738 URL */
693 }
694#endif /* HAVE_STRCASECMP */
695
696 /* //<user>:<password>@<host>:<port>/<url-path> */
697
698 at1 = NULL;
699 for (hstart = cp; ; cp++) {
700 if (*cp == '@') {
701 if (at1 == NULL)
702 at1 = cp;
703 else
704 return (kMalformedURL);
705 } else if ((*cp == '\0') || (*cp == '/')) {
706 hend = cp;
707 break;
708 }
709 }
710
711 sc = *hend;
712 *hend = '\0';
713 if (at1 == NULL) {
714 /* no user or password */
715 h2start = hstart;
716 } else {
717 *at1 = '\0';
718 cp = strchr(hstart, ':');
719 if (cp == NULL) {
720 /* whole thing is the user name then */
721 URLCopyToken(cip->user, sizeof(cip->user), hstart, (size_t) (at1 - hstart));
722 } else if (strchr(cp + 1, ':') != NULL) {
723 /* Too many colons */
724 return (kMalformedURL);
725 } else {
726 URLCopyToken(cip->user, sizeof(cip->user), hstart, (size_t) (cp - hstart));
727 URLCopyToken(cip->pass, sizeof(cip->pass), cp + 1, (size_t) (at1 - (cp + 1)));
728 }
729 *at1 = '@';
730 h2start = at1 + 1;
731 }
732
733 cp = strchr(h2start, ':');
734 if (cp == NULL) {
735 /* whole thing is the host then */
736 URLCopyToken(cip->host, sizeof(cip->host), h2start, (size_t) (hend - h2start));
737 } else if (strchr(cp + 1, ':') != NULL) {
738 /* Too many colons */
739 return (kMalformedURL);
740 } else {
741 URLCopyToken(cip->host, sizeof(cip->host), h2start, (size_t) (cp - h2start));
742 URLCopyToken(portstr, sizeof(portstr), cp + 1, (size_t) (hend - (cp + 1)));
743 port = atoi(portstr);
744 if (port > 0)
745 cip->port = port;
746 }
747
748 *hend = (char) sc;
749 if ((*hend == '\0') || ((*hend == '/') && (hend[1] == '\0'))) {
750 /* no path, okay */
751 return (0);
752 }
753
754 lastslash = strrchr(hend, '/');
755 if (lastslash == NULL) {
756 /* no path, okay */
757 return (0);
758 }
759 *lastslash = '\0';
760
761 if ((semi = strchr(lastslash + 1, ';')) != NULL) {
762 *semi++ = '\0';
763#ifdef HAVE_STRCASECMP
764 if (strcasecmp(semi, "type=i") == 0) {
765 if (xtype != NULL)
766 *xtype = kTypeBinary;
767 } else if (strcasecmp(semi, "type=a") == 0) {
768 if (xtype != NULL)
769 *xtype = kTypeAscii;
770 } else if (strcasecmp(semi, "type=b") == 0) {
771 if (xtype != NULL)
772 *xtype = kTypeBinary;
773 } else if (strcasecmp(semi, "type=d") == 0) {
774 if (wantnlst != NULL) {
775 *wantnlst = 1;
776 if (xtype != NULL)
777 *xtype = kTypeAscii;
778 } else {
779 /* You didn't want these. */
780 return (kMalformedURL);
781 }
782 }
783#else /* HAVE_STRCASECMP */
784 if (strcmp(semi, "type=i") == 0) {
785 if (xtype != NULL)
786 *xtype = kTypeBinary;
787 } else if (strcmp(semi, "type=a") == 0) {
788 if (xtype != NULL)
789 *xtype = kTypeAscii;
790 } else if (strcmp(semi, "type=b") == 0) {
791 if (xtype != NULL)
792 *xtype = kTypeBinary;
793 } else if (strcmp(semi, "type=d") == 0) {
794 if (wantnlst != NULL) {
795 *wantnlst = 1;
796 if (xtype != NULL)
797 *xtype = kTypeAscii;
798 } else {
799 /* You didn't want these. */
800 return (kMalformedURL);
801 }
802 }
803#endif /* HAVE_STRCASECMP */
804 }
805 URLCopyToken(fn, fnsize, lastslash + 1, strlen(lastslash + 1));
806 for (parsestr = hend; (tok = strtok(parsestr, "/")) != NULL; parsestr = NULL) {
807 URLCopyToken(subdir, sizeof(subdir), tok, strlen(tok));
808 (void) AddLine(cdlist, subdir);
809 }
810 *lastslash = '/';
811 return (kNoErr);
812} /* FTPDecodeURL */
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
char * strchr(const char *String, int ch)
Definition: utclib.c:501
USHORT port
Definition: uri.c:228
unsigned char
Definition: typeof.h:29
#define strncasecmp
Definition: fake.h:10
#define strcasecmp
Definition: fake.h:9
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
void InitLineList(LineListPtr list)
Definition: linelist.c:54
LinePtr AddLine(LineListPtr list, const char *buf1)
Definition: linelist.c:94
POINT cp
Definition: magnifier.c:59
void URLCopyToken(char *dst, size_t dsize, const char *src, size_t howmuch)
Definition: open.c:598
static const WCHAR url[]
Definition: encode.c:1432
#define kTypeAscii
Definition: ncftp.h:353
#define kMalformedURL
Definition: ncftp.h:385
#define kTypeBinary
Definition: ncftp.h:354
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
char host[64]
Definition: ncftp.h:136
unsigned int port
Definition: ncftp.h:140
char pass[64]
Definition: ncftp.h:138
char user[64]
Definition: ncftp.h:137
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159

Referenced by DecodeDirectoryURL().

◆ FTPExamineMlstFeatures()

static void FTPExamineMlstFeatures ( const FTPCIPtr  cip,
const char features 
)
static

Definition at line 338 of file open.c.

339{
340 char buf[256], *feat;
341 int flags;
342
343 flags = 0;
344 STRNCPY(buf, features);
345 feat = strtok(buf, ";*");
346 while (feat != NULL) {
347 if (ISTRNEQ(feat, "OS.", 3))
348 feat += 3;
349 if (ISTREQ(feat, "type")) {
351 } else if (ISTREQ(feat, "size")) {
353 } else if (ISTREQ(feat, "modify")) {
355 } else if (ISTREQ(feat, "UNIX.mode")) {
357 } else if (ISTREQ(feat, "UNIX.owner")) {
359 } else if (ISTREQ(feat, "UNIX.group")) {
361 } else if (ISTREQ(feat, "perm")) {
363 } else if (ISTREQ(feat, "UNIX.uid")) {
365 } else if (ISTREQ(feat, "UNIX.gid")) {
367 } else if (ISTREQ(feat, "UNIX.gid")) {
369 }
370 feat = strtok(NULL, ";*");
371 }
372
373 cip->mlsFeatures = flags;
374} /* FTPExamineMlstFeatures */
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
GLbitfield flags
Definition: glext.h:7161
#define ISTREQ(a, b)
Definition: util.h:33
#define ISTRNEQ(a, b, s)
Definition: util.h:34
#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 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 FTPQueryFeatures().

◆ FTPInitConnectionInfo()

int FTPInitConnectionInfo ( const FTPLIPtr  lip,
const FTPCIPtr  cip,
size_t  bufSize 
)

Definition at line 984 of file open.c.

985{
986 size_t siz;
987
988 if ((lip == NULL) || (cip == NULL) || (bufSize == 0))
989 return (kErrBadParameter);
990
991 siz = sizeof(FTPConnectionInfo);
992 (void) memset(cip, 0, siz);
993
994 if (strcmp(lip->magic, kLibraryMagic))
995 return (kErrBadMagic);
996
997 cip->buf = NULL; /* denote that it needs to be allocated. */
998 cip->bufSize = bufSize;
999 cip->port = lip->defaultPort;
1000 cip->firewallPort = lip->defaultPort;
1011 cip->lip = lip;
1033 (void) STRNCPY(cip->user, "anonymous");
1034 return (kNoErr);
1035} /* FTPInitConnectionInfo */
GLuint GLsizei bufSize
Definition: glext.h:6040
#define kDefaultCtrlTimeout
Definition: ncftp.h:322
#define kDefaultMaxDials
Definition: ncftp.h:341
#define kFirewallNotInUse
Definition: ncftp.h:388
#define kDefaultRedialDelay
Definition: ncftp.h:342
#define kSendPortMode
Definition: ncftp.h:295
#define kDefaultConnTimeout
Definition: ncftp.h:321
#define kDefaultXferTimeout
Definition: ncftp.h:320
#define kCommandAvailabilityUnknown
Definition: ncftp.h:379
#define kDefaultAbortTimeout
Definition: ncftp.h:323
int firewallType
Definition: ncftp.h:221
unsigned int firewallPort
Definition: ncftp.h:220
int hasRETRBUFSIZE
Definition: ncftp.h:171
unsigned int xferTimeout
Definition: ncftp.h:141
unsigned int connTimeout
Definition: ncftp.h:142
int dataPortMode
Definition: ncftp.h:152
int NLSTfileParamWorks
Definition: ncftp.h:180
int hasSTORBUFSIZE
Definition: ncftp.h:174
unsigned int abortTimeout
Definition: ncftp.h:144
int STATfileParamWorks
Definition: ncftp.h:179
FTPLIPtr lip
Definition: ncftp.h:149
unsigned int ctrlTimeout
Definition: ncftp.h:143
char magic[16]
Definition: ncftp.h:114
unsigned int defaultPort
Definition: ncftp.h:117

Referenced by InitConnectionInfo().

◆ FTPInitializeAnonPassword()

void FTPInitializeAnonPassword ( const FTPLIPtr  lip)

Definition at line 81 of file open.c.

82{
83 if (lip == NULL)
84 return;
85 if (strcmp(lip->magic, kLibraryMagic))
86 return;
87
89
90 if (lip->defaultAnonPassword[0] == '\0') {
91#ifdef SPAM_PROBLEM_HAS_BEEN_SOLVED_FOREVER
93 (void) STRNCAT(lip->defaultAnonPassword, "@");
94
95 /* Default to the "user@" notation
96 * supported by NcFTPd and wu-ftpd.
97 */
98 if (lip->htried > 0)
100#else
101 (void) STRNCPY(lip->defaultAnonPassword, "NcFTP@");
102#endif
103 }
104} /* FTPInitializeAnonPassword */
#define STRNCAT(d, s)
Definition: Strn.h:48
void FTPInitializeOurHostName(const FTPLIPtr lip)
Definition: open.c:63
void GetUsrName(char *, size_t)
Definition: util.c:290
char defaultAnonPassword[80]
Definition: ncftp.h:121
char ourHostName[64]
Definition: ncftp.h:118
int htried
Definition: ncftp.h:120

Referenced by FTPLoginHost(), and PostInitPrefs().

◆ FTPInitializeOurHostName()

void FTPInitializeOurHostName ( const FTPLIPtr  lip)

Definition at line 63 of file open.c.

64{
65 if (lip == NULL)
66 return;
67 if (strcmp(lip->magic, kLibraryMagic))
68 return;
69
70 if (lip->htried == 0) {
71 (void) memset(lip->ourHostName, 0, sizeof(lip->ourHostName));
72 lip->hresult = GetOurHostName(lip->ourHostName, sizeof(lip->ourHostName));
73 }
74 lip->htried++;
75} /* FTPInitializeOurHostName */
int GetOurHostName(char *host, size_t siz)
Definition: ftp.c:81
int hresult
Definition: ncftp.h:119

Referenced by FTPInitializeAnonPassword(), LoadFirewallPrefs(), OpenTrace(), and WriteDefaultFirewallPrefs().

◆ FTPInitLibrary()

int FTPInitLibrary ( const FTPLIPtr  lip)

Definition at line 1110 of file open.c.

1111{
1112 struct servent *ftp;
1113
1114 if (lip == NULL)
1115 return (kErrBadParameter);
1116
1117 (void) memset(lip, 0, sizeof(FTPLibraryInfo));
1118 if ((ftp = getservbyname("ftp", "tcp")) == NULL)
1119 lip->defaultPort = (unsigned int) kDefaultFTPPort;
1120 else
1121 lip->defaultPort = (unsigned int) ntohs(ftp->s_port);
1122
1123 lip->init = 1;
1125
1126 /* We'll initialize the defaultAnonPassword field
1127 * later when we try the first anon ftp connection.
1128 */
1129
1130#ifdef HAVE_LIBSOCKS
1131 SOCKSinit("libncftp");
1132 lip->socksInit = 1;
1133#endif
1134 return (kNoErr);
1135} /* FTPInitLibrary */
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
PSERVENT WSAAPI getservbyname(IN const char FAR *name, IN const char FAR *proto)
Definition: getxbyxx.c:500
#define ntohs(x)
Definition: module.h:210
static WCHAR ftp[]
Definition: url.c:29
#define kDefaultFTPPort
Definition: ncftp.h:312
int socksInit
Definition: ncftp.h:116

Referenced by PreInit().

◆ FTPLoginHost()

int FTPLoginHost ( const FTPCIPtr  cip)

Definition at line 110 of file open.c.

111{
112 ResponsePtr rp;
114 int anonLogin;
115 int sentpass = 0;
116 int fwloggedin;
117 int firstTime;
118 char cwd[512];
119
120 if (cip == NULL)
121 return (kErrBadParameter);
123 return (kErrBadParameter);
124
125 if (strcmp(cip->magic, kLibraryMagic))
126 return (kErrBadMagic);
127
128 anonLogin = 0;
129 if (cip->user[0] == '\0')
130 (void) STRNCPY(cip->user, "anonymous");
131 if ((strcmp(cip->user, "anonymous") == 0) || (strcmp(cip->user, "ftp") == 0)) {
132 anonLogin = 1;
133 /* Try to get the email address if you didn't specify
134 * a password when the user is anonymous.
135 */
136 if (cip->pass[0] == '\0') {
138 (void) STRNCPY(cip->pass, cip->lip->defaultAnonPassword);
139 }
140 }
141
142 rp = InitResponse();
143 if (rp == NULL) {
145 cip->errNo = kErrMallocFailed;
146 goto done2;
147 }
148
149 for (firstTime = 1, fwloggedin = 0; ; ) {
150 /* Here's a mini finite-automaton for the login process.
151 *
152 * Originally, the FTP protocol was designed to be entirely
153 * implementable from a FA. It could be done, but I don't think
154 * it's something an interactive process could be the most
155 * effective with.
156 */
157
158 if (firstTime != 0) {
159 rp->code = 220;
160 firstTime = 0;
161 } else if (result < 0) {
162 goto done;
163 }
164
165 switch (rp->code) {
166 case 220: /* Welcome, ready for new user. */
167 if ((cip->firewallType == kFirewallNotInUse) || (fwloggedin != 0)) {
168 ReInitResponse(cip, rp);
169 result = RCmd(cip, rp, "USER %s", cip->user);
170 } else if (cip->firewallType == kFirewallUserAtSite) {
171 ReInitResponse(cip, rp);
172 result = RCmd(cip, rp, "USER %s@%s", cip->user, cip->host);
173 } else if (cip->firewallType == kFirewallUserAtUserPassAtPass) {
174 ReInitResponse(cip, rp);
175 result = RCmd(cip, rp, "USER %s@%s@%s", cip->user, cip->firewallUser, cip->host);
176 } else if (cip->firewallType == kFirewallUserAtSiteFwuPassFwp) {
177 ReInitResponse(cip, rp);
178 result = RCmd(cip, rp, "USER %s@%s %s", cip->user, cip->host, cip->firewallUser);
179 } else if (cip->firewallType == kFirewallFwuAtSiteFwpUserPass) {
180 /* only reached when !fwloggedin */
181 ReInitResponse(cip, rp);
182 result = RCmd(cip, rp, "USER %s@%s", cip->firewallUser, cip->host);
183 } else if (cip->firewallType > kFirewallNotInUse) {
184 ReInitResponse(cip, rp);
185 result = RCmd(cip, rp, "USER %s", cip->firewallUser);
186 } else {
187 goto unknown;
188 }
189 break;
190
191 case 230: /* 230 User logged in, proceed. */
192 case 231: /* User name accepted. */
193 case 202: /* Command not implemented, superfluous at this site. */
194 if ((cip->firewallType == kFirewallNotInUse) || (fwloggedin != 0))
195 goto okay;
196
197 /* Now logged in to the firewall. */
198 fwloggedin++;
199
201 ReInitResponse(cip, rp);
202 result = RCmd(cip, rp, "USER %s@%s", cip->user, cip->host);
203 } else if (cip->firewallType == kFirewallUserAtUserPassAtPass) {
204 goto okay;
205 } else if (cip->firewallType == kFirewallOpenSite) {
206 ReInitResponse(cip, rp);
207 result = RCmd(cip, rp, "OPEN %s", cip->host);
208 } else if (cip->firewallType == kFirewallSiteSite) {
209 ReInitResponse(cip, rp);
210 result = RCmd(cip, rp, "SITE %s", cip->host);
211 } else if (cip->firewallType == kFirewallFwuAtSiteFwpUserPass) {
212 /* only reached when !fwloggedin */
213 ReInitResponse(cip, rp);
214 result = RCmd(cip, rp, "USER %s", cip->user);
215 } else /* kFirewallUserAtSite */ {
216 goto okay;
217 }
218 break;
219
220 case 421: /* 421 Service not available, closing control connection. */
222 goto done;
223
224 case 331: /* 331 User name okay, need password. */
225 if ((cip->firewallType == kFirewallNotInUse) || (fwloggedin != 0)) {
226 if ((cip->pass[0] == '\0') && (cip->passphraseProc != NoGetPassphraseProc))
227 (*cip->passphraseProc)(cip, &rp->msg, cip->pass, sizeof(cip->pass));
228 ReInitResponse(cip, rp);
229 result = RCmd(cip, rp, "PASS %s", cip->pass);
230 } else if (cip->firewallType == kFirewallUserAtSite) {
231 ReInitResponse(cip, rp);
232 result = RCmd(cip, rp, "PASS %s", cip->pass);
233 } else if (cip->firewallType == kFirewallUserAtUserPassAtPass) {
234 ReInitResponse(cip, rp);
235 result = RCmd(cip, rp, "PASS %s@%s", cip->pass, cip->firewallPass);
236 } else if (cip->firewallType == kFirewallUserAtSiteFwuPassFwp) {
237 ReInitResponse(cip, rp);
238 result = RCmd(cip, rp, "PASS %s", cip->pass);
239 } else if (cip->firewallType == kFirewallFwuAtSiteFwpUserPass) {
240 /* only reached when !fwloggedin */
241 ReInitResponse(cip, rp);
242 result = RCmd(cip, rp, "PASS %s", cip->firewallPass);
243 } else if (cip->firewallType > kFirewallNotInUse) {
244 ReInitResponse(cip, rp);
245 result = RCmd(cip, rp, "PASS %s", cip->firewallPass);
246 } else {
247 goto unknown;
248 }
249 sentpass++;
250 break;
251
252 case 332: /* 332 Need account for login. */
253 case 532: /* 532 Need account for storing files. */
254 if ((cip->firewallType == kFirewallNotInUse) || (fwloggedin != 0)) {
255 ReInitResponse(cip, rp);
256 result = RCmd(cip, rp, "ACCT %s", cip->acct);
257 } else if (cip->firewallType == kFirewallUserAtSiteFwuPassFwp) {
258 ReInitResponse(cip, rp);
259 result = RCmd(cip, rp, "ACCT %s", cip->firewallPass);
260 } else {
261 /* ACCT not supported on firewall. */
262 goto unknown;
263 }
264 break;
265
266 case 530: /* Not logged in. */
268 goto done;
269
270 case 501: /* Syntax error in parameters or arguments. */
271 case 503: /* Bad sequence of commands. */
272 case 550: /* Can't set guest privileges. */
273 goto done;
274
275 default:
276 unknown:
277 if (rp->msg.first == NULL) {
278 Error(cip, kDontPerror, "Lost connection during login.\n");
279 } else {
280 Error(cip, kDontPerror, "Unexpected response: %s\n",
281 rp->msg.first->line
282 );
283 }
284 goto done;
285 }
286 }
287
288okay:
289 /* Do the application's connect message callback, if present. */
290 if (cip->onLoginMsgProc != 0)
291 (*cip->onLoginMsgProc)(cip, rp);
292 DoneWithResponse(cip, rp);
293 result = 0;
294 cip->loggedIn = 1;
295
296 /* Make a note of what our root directory is.
297 * This is often different from "/" when not
298 * logged in anonymously.
299 */
300 if (cip->startingWorkingDirectory != NULL) {
303 }
304 if ((cip->doNotGetStartingWorkingDirectory == 0) &&
305 (FTPGetCWD(cip, cwd, sizeof(cwd)) == kNoErr))
306 {
308 }
309
310 /* When a new site is opened, ASCII mode is assumed (by protocol). */
311 cip->curTransferType = 'A';
312 PrintF(cip, "Logged in to %s as %s.\n", cip->host, cip->user);
313
314 /* Don't leave cleartext password in memory. */
315 if ((anonLogin == 0) && (cip->leavePass == 0))
316 (void) memset(cip->pass, '*', strlen(cip->pass));
317
318 if (result < 0)
319 cip->errNo = result;
320 return result;
321
322done:
323 DoneWithResponse(cip, rp);
324
325done2:
326 /* Don't leave cleartext password in memory. */
327 if ((anonLogin == 0) && (cip->leavePass == 0))
328 (void) memset(cip->pass, '*', strlen(cip->pass));
329 if (result < 0)
330 cip->errNo = result;
331 return result;
332} /* FTPLoginHost */
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
int FTPGetCWD(const FTPCIPtr cip, char *const newCwd, const size_t newCwdSize)
Definition: cmds.c:254
void FTPInitializeAnonPassword(const FTPLIPtr lip)
Definition: open.c:81
void PrintF(const FTPCIPtr cip, const char *const fmt,...)
Definition: util.c:340
#define kFirewallUserAtSite
Definition: ncftp.h:389
#define kFirewallLoginThenUserAtSite
Definition: ncftp.h:390
#define kFirewallSiteSite
Definition: ncftp.h:391
#define kFirewallUserAtUserPassAtPass
Definition: ncftp.h:393
void ReInitResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:142
#define kFirewallFwuAtSiteFwpUserPass
Definition: ncftp.h:394
#define kFirewallUserAtSiteFwuPassFwp
Definition: ncftp.h:395
#define kFirewallOpenSite
Definition: ncftp.h:392
#define kFirewallLastType
Definition: ncftp.h:396
#define NoGetPassphraseProc
Definition: ncftp.h:453
#define kErrLoginFailed
Definition: ncftp_errno.h:73
#define kErrBadRemoteUser
Definition: ncftp_errno.h:71
#define kErrHostDisconnectedDuringLogin
Definition: ncftp_errno.h:70
#define kErrBadRemoteUserOrPassword
Definition: ncftp_errno.h:72
#define StrDup
Definition: shlwapi.h:1533
int curTransferType
Definition: ncftp.h:157
int doNotGetStartingWorkingDirectory
Definition: ncftp.h:237
char firewallPass[64]
Definition: ncftp.h:219
FTPGetPassphraseProc passphraseProc
Definition: ncftp.h:242
FTPLoginMessageProc onLoginMsgProc
Definition: ncftp.h:227
char firewallUser[64]
Definition: ncftp.h:218
char acct[64]
Definition: ncftp.h:139
LinePtr first
Definition: ncftp.h:85
char * line
Definition: ncftp.h:81
int code
Definition: ncftp.h:92
LineList msg
Definition: ncftp.h:90

Referenced by FTPOpenHost().

◆ FTPOpenHost()

int FTPOpenHost ( const FTPCIPtr  cip)

Definition at line 818 of file open.c.

819{
820 int result;
821 time_t t0, t1;
822 int elapsed;
823 int dials;
824
825 if (cip == NULL)
826 return (kErrBadParameter);
827 if (strcmp(cip->magic, kLibraryMagic))
828 return (kErrBadMagic);
829
830 if (cip->host[0] == '\0') {
831 cip->errNo = kErrBadParameter;
832 return (kErrBadParameter);
833 }
834
835 for ( result = kErrConnectMiscErr, dials = 0;
836 cip->maxDials < 0 || dials < cip->maxDials;
837 dials++)
838 {
839 /* Allocate (or if the host was closed, reallocate)
840 * the transfer data buffer.
841 */
842 result = FTPAllocateHost(cip);
843 if (result < 0)
844 return (result);
845
846 if (dials > 0)
847 PrintF(cip, "Retry Number: %d\n", dials);
848 if (cip->redialStatusProc != 0)
849 (*cip->redialStatusProc)(cip, kRedialStatusDialing, dials);
850 (void) time(&t0);
851 result = OpenControlConnection(cip, cip->host, cip->port);
852 (void) time(&t1);
853 if (result == kNoErr) {
854 /* We were hooked up successfully. */
855 PrintF(cip, "Connected to %s.\n", cip->host);
856
857 result = FTPLoginHost(cip);
858 if (result == kNoErr) {
859 (void) FTPQueryFeatures(cip);
860 break;
861 }
862
863 /* Close and try again. */
864 (void) FTPCloseHost(cip);
865
866 /* Originally we also stopped retyring if
867 * we got kErrBadRemoteUser and non-anonymous,
868 * but some FTP servers apparently do their
869 * max user check after the username is sent.
870 */
871 if (result == kErrBadRemoteUserOrPassword /* || (result == kErrBadRemoteUser) */) {
872 if (strcmp(cip->user, "anonymous") != 0) {
873 /* Non-anonymous login was denied, and
874 * retrying is not going to help.
875 */
876 break;
877 }
878 }
880 /* Irrecoverable error, so don't bother redialing.
881 * The error message should have already been printed
882 * from OpenControlConnection().
883 */
884 PrintF(cip, "Cannot recover from miscellaneous open error %d.\n", result);
885 return result;
886 }
887
888 /* Retryable error, wait and then redial. */
889 if (cip->redialDelay > 0) {
890 /* But don't sleep if this is the last loop. */
891 if ((cip->maxDials < 0) || (dials < (cip->maxDials - 1))) {
892 elapsed = (int) (t1 - t0);
893 if (elapsed < cip->redialDelay) {
894 PrintF(cip, "Sleeping %u seconds.\n",
895 (unsigned) cip->redialDelay - elapsed);
896 if (cip->redialStatusProc != 0)
897 (*cip->redialStatusProc)(cip, kRedialStatusSleeping, cip->redialDelay - elapsed);
898 (void) sleep((unsigned) cip->redialDelay - elapsed);
899 }
900 }
901 }
902 }
903 return (result);
904} /* FTPOpenHost */
__kernel_time_t time_t
Definition: linux.h:252
#define sleep
Definition: syshdrs.h:37
__u16 time
Definition: mkdosfs.c:8
int OpenControlConnection(const FTPCIPtr cip, char *host, unsigned int port)
Definition: ftp.c:347
int FTPQueryFeatures(const FTPCIPtr cip)
Definition: open.c:380
int FTPCloseHost(const FTPCIPtr cip)
Definition: open.c:523
static int FTPAllocateHost(const FTPCIPtr cip)
Definition: open.c:39
int FTPLoginHost(const FTPCIPtr cip)
Definition: open.c:110
#define kRedialStatusDialing
Definition: ncftp.h:346
#define kRedialStatusSleeping
Definition: ncftp.h:347
#define kErrConnectRetryableErr
Definition: ncftp_errno.h:36
#define kErrConnectMiscErr
Definition: ncftp_errno.h:35
#define kErrRemoteHostClosedConnection
Definition: ncftp_errno.h:75
#define kErrConnectRefused
Definition: ncftp_errno.h:37
FTPRedialStatusProc redialStatusProc
Definition: ncftp.h:225

Referenced by DoOpen().

◆ FTPOpenHostNoLogin()

int FTPOpenHostNoLogin ( const FTPCIPtr  cip)

Definition at line 910 of file open.c.

911{
912 int result;
913 time_t t0, t1;
914 int elapsed;
915 int dials;
916
917 if (cip == NULL)
918 return (kErrBadParameter);
919 if (strcmp(cip->magic, kLibraryMagic))
920 return (kErrBadMagic);
921
922 if (cip->host[0] == '\0') {
923 cip->errNo = kErrBadParameter;
924 return (kErrBadParameter);
925 }
926
927 for ( result = kErrConnectMiscErr, dials = 0;
928 cip->maxDials < 0 || dials < cip->maxDials;
929 dials++)
930 {
931
932 /* Allocate (or if the host was closed, reallocate)
933 * the transfer data buffer.
934 */
935 result = FTPAllocateHost(cip);
936 if (result < 0)
937 return (result);
938
939 if (dials > 0)
940 PrintF(cip, "Retry Number: %d\n", dials);
941 if (cip->redialStatusProc != 0)
942 (*cip->redialStatusProc)(cip, kRedialStatusDialing, dials);
943 (void) time(&t0);
944 result = OpenControlConnection(cip, cip->host, cip->port);
945 (void) time(&t1);
946 if (result == kNoErr) {
947 /* We were hooked up successfully. */
948 PrintF(cip, "Connected to %s.\n", cip->host);
949
950 /* Not logging in... */
951 if (result == kNoErr)
952 break;
954 /* Irrecoverable error, so don't bother redialing.
955 * The error message should have already been printed
956 * from OpenControlConnection().
957 */
958 PrintF(cip, "Cannot recover from miscellaneous open error %d.\n", result);
959 return result;
960 }
961
962 /* Retryable error, wait and then redial. */
963 if (cip->redialDelay > 0) {
964 /* But don't sleep if this is the last loop. */
965 if ((cip->maxDials < 0) || (dials < (cip->maxDials - 1))) {
966 elapsed = (int) (t1 - t0);
967 if (elapsed < cip->redialDelay) {
968 PrintF(cip, "Sleeping %u seconds.\n",
969 (unsigned) cip->redialDelay - elapsed);
970 if (cip->redialStatusProc != 0)
971 (*cip->redialStatusProc)(cip, kRedialStatusSleeping, cip->redialDelay - elapsed);
972 (void) sleep((unsigned) cip->redialDelay - elapsed);
973 }
974 }
975 }
976 }
977 return (result);
978} /* FTPOpenHostNoLogin */

◆ FTPQueryFeatures()

int FTPQueryFeatures ( const FTPCIPtr  cip)

Definition at line 380 of file open.c.

381{
382 ResponsePtr rp;
383 int result;
384 LinePtr lp;
385 char *cp, *p;
386
387 if (cip == NULL)
388 return (kErrBadParameter);
389 if (strcmp(cip->magic, kLibraryMagic))
390 return (kErrBadMagic);
391
392 if (cip->serverType == kServerTypeNetWareFTP) {
393 /* NetWare 5.00 server freaks out when
394 * you give it a command it doesn't
395 * recognize, so cheat here and return.
396 */
406 return (kNoErr);
407 }
408
409 rp = InitResponse();
410 if (rp == NULL) {
411 cip->errNo = kErrMallocFailed;
412 result = cip->errNo;
413 } else {
415 result = RCmd(cip, rp, "FEAT");
416 if (result < kNoErr) {
417 DoneWithResponse(cip, rp);
418 return (result);
419 } else if (result != 2) {
420 /* We cheat here and pre-populate some
421 * fields when the server is wu-ftpd.
422 * This server is very common and we
423 * know it has always had these.
424 */
425 if (cip->serverType == kServerTypeWuFTPd) {
431 } else if (cip->serverType == kServerTypeNcFTPd) {
437 }
438
439 /* Newer commands are only shown in FEAT,
440 * so we don't have to do the "try it,
441 * then save that it didn't work" thing.
442 */
445 } else {
447
448 for (lp = rp->msg.first; lp != NULL; lp = lp->next) {
449 /* If first character was not a space it is
450 * either:
451 *
452 * (a) The header line in the response;
453 * (b) The trailer line in the response;
454 * (c) A protocol violation.
455 */
456 cp = lp->line;
457 if (*cp++ != ' ')
458 continue;
459 if (ISTRNCMP(cp, "PASV", 4) == 0) {
461 } else if (ISTRNCMP(cp, "SIZE", 4) == 0) {
463 } else if (ISTRNCMP(cp, "MDTM", 4) == 0) {
465 } else if (ISTRNCMP(cp, "REST", 4) == 0) {
467 } else if (ISTRNCMP(cp, "UTIME", 5) == 0) {
469 } else if (ISTRNCMP(cp, "MLST", 4) == 0) {
472 FTPExamineMlstFeatures(cip, cp + 5);
473 } else if (ISTRNCMP(cp, "CLNT", 4) == 0) {
475 } else if (ISTRNCMP(cp, "Compliance Level: ", 18) == 0) {
476 /* Probably only NcFTPd will ever implement this.
477 * But we use it internally to differentiate
478 * between different NcFTPd implementations of
479 * IETF extensions.
480 */
481 cip->ietfCompatLevel = atoi(cp + 18);
482 }
483 }
484 }
485
486 ReInitResponse(cip, rp);
487 result = RCmd(cip, rp, "HELP SITE");
488 if (result == 2) {
489 for (lp = rp->msg.first; lp != NULL; lp = lp->next) {
490 cp = lp->line;
491 if (strstr(cp, "RETRBUFSIZE") != NULL)
493 if (strstr(cp, "RBUFSZ") != NULL)
495 /* See if RBUFSIZ matches (but not STORBUFSIZE) */
496 if (
497 ((p = strstr(cp, "RBUFSIZ")) != NULL) &&
498 (
499 (p == cp) ||
500 ((p > cp) && (!isupper(p[-1])))
501 )
502 )
504 if (strstr(cp, "STORBUFSIZE") != NULL)
506 if (strstr(cp, "SBUFSIZ") != NULL)
508 if (strstr(cp, "SBUFSZ") != NULL)
510 if (strstr(cp, "BUFSIZE") != NULL)
512 }
513 }
514 DoneWithResponse(cip, rp);
515 }
516
517 return (kNoErr);
518} /* FTPQueryFeatures */
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define isupper(c)
Definition: acclib.h:71
GLfloat GLfloat p
Definition: glext.h:8902
static void FTPExamineMlstFeatures(const FTPCIPtr cip, const char *features)
Definition: open.c:338
#define ISTRNCMP
Definition: util.h:29
#define kResponseNoPrint
Definition: ncftp.h:308
#define kServerTypeNcFTPd
Definition: ncftp.h:463
#define kCommandAvailable
Definition: ncftp.h:380
#define kServerTypeWuFTPd
Definition: ncftp.h:462
#define kServerTypeNetWareFTP
Definition: ncftp.h:472
#define kResponseNoSave
Definition: ncftp.h:309
#define kCommandNotAvailable
Definition: ncftp.h:381
int ietfCompatLevel
Definition: ncftp.h:233
Definition: ncftp.h:79
LinePtr next
Definition: ncftp.h:80
int printMode
Definition: ncftp.h:93

Referenced by FTPOpenHost().

◆ FTPRebuildConnectionInfo()

int FTPRebuildConnectionInfo ( const FTPLIPtr  lip,
const FTPCIPtr  cip 
)

Definition at line 1041 of file open.c.

1042{
1043 char *buf;
1044
1045 cip->lip = lip;
1046 cip->debugLog = NULL;
1047 cip->errLog = NULL;
1048 cip->debugLogProc = NULL;
1049 cip->errLogProc = NULL;
1050 cip->buf = NULL;
1051 cip->cin = NULL;
1052 cip->cout = NULL;
1053 cip->errNo = 0;
1054 cip->progress = NULL;
1055 cip->rname = NULL;
1056 cip->lname = NULL;
1057 cip->onConnectMsgProc = NULL;
1058 cip->redialStatusProc = NULL;
1059 cip->printResponseProc = NULL;
1060 cip->onLoginMsgProc = NULL;
1061 cip->passphraseProc = NULL;
1064
1065 (void) memset(&cip->lastFTPCmdResultLL, 0, sizeof(LineList));
1066
1067 /* Allocate a new buffer. */
1068 buf = (char *) calloc((size_t) 1, cip->bufSize);
1069 if (buf == NULL) {
1070 cip->errNo = kErrMallocFailed;
1071 return (kErrMallocFailed);
1072 }
1073 cip->buf = buf;
1074
1075 /* Reattach the FILE pointers for use with the Std I/O library
1076 * routines.
1077 */
1078 if ((cip->cin = _fdopen(cip->ctrlSocketR, "r")) == NULL) {
1079 cip->errNo = kErrFdopenR;
1082 return (kErrFdopenR);
1083 }
1084
1085 if ((cip->cout = _fdopen(cip->ctrlSocketW, "w")) == NULL) {
1086 CloseFile(&cip->cin);
1087 cip->errNo = kErrFdopenW;
1090 return (kErrFdopenW);
1091 }
1092
1093#if USE_SIO
1094 if (InitSReadlineInfo(&cip->ctrlSrl, cip->ctrlSocketR, cip->srlBuf, sizeof(cip->srlBuf), (int) cip->ctrlTimeout, 1) < 0) {
1095 cip->errNo = kErrFdopenW;
1096 CloseFile(&cip->cin);
1097 cip->errNo = kErrFdopenW;
1100 return (kErrFdopenW);
1101 }
1102#endif
1103 return (kNoErr);
1104} /* FTPRebuildConnectionInfo */
_Check_return_ _CRTIMP FILE *__cdecl _fdopen(_In_ int _FileHandle, _In_z_ const char *_Mode)
void CloseFile(FILE **f)
Definition: util.c:327
int InitSReadlineInfo(SReadlineInfo *, int, char *, size_t, int, int)
Definition: SReadline.c:24
#define kErrFdopenW
Definition: ncftp_errno.h:26
#define kErrFdopenR
Definition: ncftp_errno.h:25
FILE * cout
Definition: ncftp.h:189
FTPPrintResponseProc printResponseProc
Definition: ncftp.h:226
char srlBuf[768]
Definition: ncftp.h:239
FTPLogProc errLogProc
Definition: ncftp.h:148
FTPProgressMeterProc progress
Definition: ncftp.h:198
const char * asciiFilenameExtensions
Definition: ncftp.h:246
FTPConnectMessageProc onConnectMsgProc
Definition: ncftp.h:224
FILE * debugLog
Definition: ncftp.h:145
FILE * errLog
Definition: ncftp.h:146
const char * rname
Definition: ncftp.h:208
const char * lname
Definition: ncftp.h:209
FILE * cin
Definition: ncftp.h:188
FTPLogProc debugLogProc
Definition: ncftp.h:147
Definition: ncftp.h:84

◆ FTPShutdownHost()

void FTPShutdownHost ( const FTPCIPtr  cip)

Definition at line 564 of file open.c.

565{
566#ifdef SIGPIPE
567 FTPSigProc osigpipe;
568#endif
569
570 if (cip == NULL)
571 return;
572 if (strcmp(cip->magic, kLibraryMagic))
573 return;
574
575#ifdef SIGPIPE
576 osigpipe = signal(SIGPIPE, (FTPSigProc) SIG_IGN);
577#endif
578
579 /* Linger could cause close to block, so unset it. */
581 (void) SetLinger(cip, cip->dataSocket, 0);
582 CloseDataConnection(cip); /* Shouldn't be open normally. */
583
584 /* Linger should already be turned off for this. */
586
588
589#ifdef SIGPIPE
590 (void) signal(SIGPIPE, (FTPSigProc) osigpipe);
591#endif
592} /* FTPShutdownHost */
#define SIGPIPE
Definition: signal.h:35
#define SIG_IGN
Definition: signal.h:48
void CloseDataConnection(const FTPCIPtr cip)
Definition: ftp.c:831
int SetLinger(const FTPCIPtr cip, int sockfd, int onoff)
Definition: ftp.c:262
void(* FTPSigProc)(int)
Definition: ncftp.h:76
int signal
Definition: except.c:82

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

◆ URLCopyToken()

void URLCopyToken ( char dst,
size_t  dsize,
const char src,
size_t  howmuch 
)

Definition at line 598 of file open.c.

599{
600 char *dlim;
601 const char *slim;
602 unsigned int hc;
603 int c;
604 char h[4];
605
606 dlim = dst + dsize - 1; /* leave room for \0 */
607 slim = src + howmuch;
608 while (src < slim) {
609 c = *src++;
610 if (c == '\0')
611 break;
612 if (c == '%') {
613 /* hex representation */
614 if (src < slim + 2) {
615 h[0] = *src++;
616 h[1] = *src++;
617 h[2] = '\0';
618 hc = 0xeeff;
619 if ((sscanf(h, "%x", &hc) >= 0) && (hc != 0xeeff)) {
620 if (dst < dlim) {
621 *(unsigned char *)dst = (unsigned char) hc;
622 dst++;
623 }
624 }
625 } else {
626 break;
627 }
628 } else {
629 *dst++ = (char) c;
630 }
631 }
632 *dst = '\0';
633} /* URLCopyToken */
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLenum GLenum dst
Definition: glext.h:6340
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define c
Definition: ke_i.h:80

Referenced by FTPDecodeURL().