+ wxString code;
+
+ // m_lastResult will contain the entire server response, possibly on
+ // multiple lines
+ m_lastResult.clear();
+
+ // we handle multiline replies here according to RFC 959: it says that a
+ // reply may either be on 1 line of the form "xyz ..." or on several lines
+ // in whuch case it looks like
+ // xyz-...
+ // ...
+ // xyz ...
+ // and the intermeidate lines may start with xyz or not
+ bool badReply = FALSE;
+ bool firstLine = TRUE;
+ bool endOfReply = FALSE;
+ while ( !endOfReply && !badReply )
+ {
+ wxString line;
+ m_lastError = ReadLine(line);
+ if ( m_lastError )
+ return 0;
+
+ if ( !m_lastResult.empty() )
+ {
+ // separate from last line
+ m_lastResult += _T('\n');
+ }
+
+ m_lastResult += line;
+
+ // unless this is an intermediate line of a multiline reply, it must
+ // contain the code in the beginning and '-' or ' ' following it
+ if ( line.Len() < LEN_CODE + 1 )
+ {
+ if ( firstLine )
+ {
+ badReply = TRUE;
+ }
+ else
+ {
+ wxLogTrace(_T("ftp"), _T("<== %s %s"),
+ code.c_str(), line.c_str());
+ }
+ }
+ else // line has at least 4 chars
+ {
+ // this is the char which tells us what we're dealing with
+ wxChar chMarker = line.GetChar(LEN_CODE);
+
+ if ( firstLine )
+ {
+ code = wxString(line, LEN_CODE);
+ wxLogTrace(_T("ftp"), _T("<== %s %s"),
+ code.c_str(), line.c_str() + LEN_CODE + 1);
+
+ switch ( chMarker )
+ {
+ case _T(' '):
+ endOfReply = TRUE;
+ break;
+
+ case _T('-'):
+ firstLine = FALSE;
+ break;
+
+ default:
+ // unexpected
+ badReply = TRUE;
+ }
+ }
+ else // subsequent line of multiline reply
+ {
+ if ( wxStrncmp(line, code, LEN_CODE) == 0 )
+ {
+ if ( chMarker == _T(' ') )
+ {
+ endOfReply = TRUE;
+ }
+
+ wxLogTrace(_T("ftp"), _T("<== %s %s"),
+ code.c_str(), line.c_str() + LEN_CODE + 1);
+ }
+ else
+ {
+ // just part of reply
+ wxLogTrace(_T("ftp"), _T("<== %s %s"),
+ code.c_str(), line.c_str());
+ }
+ }
+ }
+ }
+
+ if ( badReply )
+ {
+ wxLogDebug(_T("Broken FTP server: '%s' is not a valid reply."),
+ m_lastResult.c_str());
+
+ m_lastError = wxPROTO_PROTERR;
+
+ return 0;
+ }
+
+ // if we got here we must have a non empty code string
+ return code[0u];
+}