зеркало из https://github.com/mozilla/gecko-dev.git
Fixes 95590 FTP: SYST limitations. Intergrates Cyrus Patel LIST Parser. r=dougt, sr=darin@Netscape.com.
This commit is contained in:
Родитель
898f7454be
Коммит
c7a5ce8c32
|
@ -251,9 +251,7 @@ nsresult NS_NewHTTPCompressConv (nsHTTPCompressConv ** result);
|
||||||
nsresult NS_NewNSTXTToHTMLConv(nsTXTToHTMLConv** result);
|
nsresult NS_NewNSTXTToHTMLConv(nsTXTToHTMLConv** result);
|
||||||
nsresult NS_NewStreamConv(nsStreamConverterService **aStreamConv);
|
nsresult NS_NewStreamConv(nsStreamConverterService **aStreamConv);
|
||||||
|
|
||||||
#define FTP_UNIX_TO_INDEX "?from=text/ftp-dir-unix&to=application/http-index-format"
|
#define FTP_TO_INDEX "?from=text/ftp-dir&to=application/http-index-format"
|
||||||
#define FTP_NT_TO_INDEX "?from=text/ftp-dir-nt&to=application/http-index-format"
|
|
||||||
#define FTP_OS2_TO_INDEX "?from=text/ftp-dir-os2&to=application/http-index-format"
|
|
||||||
#define GOPHER_TO_INDEX "?from=text/gopher-dir&to=application/http-index-format"
|
#define GOPHER_TO_INDEX "?from=text/gopher-dir&to=application/http-index-format"
|
||||||
#define INDEX_TO_HTML "?from=application/http-index-format&to=text/html"
|
#define INDEX_TO_HTML "?from=application/http-index-format&to=text/html"
|
||||||
#define MULTI_MIXED_X "?from=multipart/x-mixed-replace&to=*/*"
|
#define MULTI_MIXED_X "?from=multipart/x-mixed-replace&to=*/*"
|
||||||
|
@ -281,9 +279,7 @@ static PRUint32 g_StreamConverterCount = 16;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char *const g_StreamConverterArray[] = {
|
static const char *const g_StreamConverterArray[] = {
|
||||||
FTP_UNIX_TO_INDEX,
|
FTP_TO_INDEX,
|
||||||
FTP_NT_TO_INDEX,
|
|
||||||
FTP_OS2_TO_INDEX,
|
|
||||||
GOPHER_TO_INDEX,
|
GOPHER_TO_INDEX,
|
||||||
INDEX_TO_HTML,
|
INDEX_TO_HTML,
|
||||||
MULTI_MIXED_X,
|
MULTI_MIXED_X,
|
||||||
|
@ -772,19 +768,7 @@ static const nsModuleComponentInfo gNetModuleInfo[] = {
|
||||||
// from netwerk/streamconv/converters:
|
// from netwerk/streamconv/converters:
|
||||||
{ "FTPDirListingConverter",
|
{ "FTPDirListingConverter",
|
||||||
NS_FTPDIRLISTINGCONVERTER_CID,
|
NS_FTPDIRLISTINGCONVERTER_CID,
|
||||||
NS_ISTREAMCONVERTER_KEY FTP_UNIX_TO_INDEX,
|
NS_ISTREAMCONVERTER_KEY FTP_TO_INDEX,
|
||||||
CreateNewFTPDirListingConv
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "FTPDirListingConverter",
|
|
||||||
NS_FTPDIRLISTINGCONVERTER_CID,
|
|
||||||
NS_ISTREAMCONVERTER_KEY FTP_NT_TO_INDEX,
|
|
||||||
CreateNewFTPDirListingConv
|
|
||||||
},
|
|
||||||
|
|
||||||
{ "FTPDirListingConverter",
|
|
||||||
NS_FTPDIRLISTINGCONVERTER_CID,
|
|
||||||
NS_ISTREAMCONVERTER_KEY FTP_OS2_TO_INDEX,
|
|
||||||
CreateNewFTPDirListingConv
|
CreateNewFTPDirListingConv
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1212,6 +1212,13 @@
|
||||||
<FILEKIND>Text</FILEKIND>
|
<FILEKIND>Text</FILEKIND>
|
||||||
<FILEFLAGS>Debug</FILEFLAGS>
|
<FILEFLAGS>Debug</FILEFLAGS>
|
||||||
</FILE>
|
</FILE>
|
||||||
|
<FILE>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
<FILEKIND>Text</FILEKIND>
|
||||||
|
<FILEFLAGS>Debug</FILEFLAGS>
|
||||||
|
</FILE>
|
||||||
<FILE>
|
<FILE>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
||||||
|
@ -1788,6 +1795,11 @@
|
||||||
<PATH>nsFTPDirListingConv.cpp</PATH>
|
<PATH>nsFTPDirListingConv.cpp</PATH>
|
||||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
</FILEREF>
|
</FILEREF>
|
||||||
|
<FILEREF>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
</FILEREF>
|
||||||
<FILEREF>
|
<FILEREF>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
||||||
|
@ -3234,6 +3246,13 @@
|
||||||
<FILEKIND>Text</FILEKIND>
|
<FILEKIND>Text</FILEKIND>
|
||||||
<FILEFLAGS>Debug</FILEFLAGS>
|
<FILEFLAGS>Debug</FILEFLAGS>
|
||||||
</FILE>
|
</FILE>
|
||||||
|
<FILE>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
<FILEKIND>Text</FILEKIND>
|
||||||
|
<FILEFLAGS>Debug</FILEFLAGS>
|
||||||
|
</FILE>
|
||||||
<FILE>
|
<FILE>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
||||||
|
@ -3810,6 +3829,11 @@
|
||||||
<PATH>nsFTPDirListingConv.cpp</PATH>
|
<PATH>nsFTPDirListingConv.cpp</PATH>
|
||||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
</FILEREF>
|
</FILEREF>
|
||||||
|
<FILEREF>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
</FILEREF>
|
||||||
<FILEREF>
|
<FILEREF>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
||||||
|
@ -5256,6 +5280,13 @@
|
||||||
<FILEKIND>Text</FILEKIND>
|
<FILEKIND>Text</FILEKIND>
|
||||||
<FILEFLAGS>Debug</FILEFLAGS>
|
<FILEFLAGS>Debug</FILEFLAGS>
|
||||||
</FILE>
|
</FILE>
|
||||||
|
<FILE>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
<FILEKIND>Text</FILEKIND>
|
||||||
|
<FILEFLAGS>Debug</FILEFLAGS>
|
||||||
|
</FILE>
|
||||||
<FILE>
|
<FILE>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
||||||
|
@ -5818,6 +5849,11 @@
|
||||||
<PATH>nsFTPDirListingConv.cpp</PATH>
|
<PATH>nsFTPDirListingConv.cpp</PATH>
|
||||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
</FILEREF>
|
</FILEREF>
|
||||||
|
<FILEREF>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
</FILEREF>
|
||||||
<FILEREF>
|
<FILEREF>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
||||||
|
@ -7254,6 +7290,13 @@
|
||||||
<FILEKIND>Text</FILEKIND>
|
<FILEKIND>Text</FILEKIND>
|
||||||
<FILEFLAGS>Debug</FILEFLAGS>
|
<FILEFLAGS>Debug</FILEFLAGS>
|
||||||
</FILE>
|
</FILE>
|
||||||
|
<FILE>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
<FILEKIND>Text</FILEKIND>
|
||||||
|
<FILEFLAGS>Debug</FILEFLAGS>
|
||||||
|
</FILE>
|
||||||
<FILE>
|
<FILE>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
||||||
|
@ -7816,6 +7859,11 @@
|
||||||
<PATH>nsFTPDirListingConv.cpp</PATH>
|
<PATH>nsFTPDirListingConv.cpp</PATH>
|
||||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
</FILEREF>
|
</FILEREF>
|
||||||
|
<FILEREF>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
</FILEREF>
|
||||||
<FILEREF>
|
<FILEREF>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
<PATH>mozTXTToHTMLConv.cpp</PATH>
|
||||||
|
@ -8568,6 +8616,12 @@
|
||||||
<PATH>nsFTPDirListingConv.cpp</PATH>
|
<PATH>nsFTPDirListingConv.cpp</PATH>
|
||||||
<PATHFORMAT>MacOS</PATHFORMAT>
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
</FILEREF>
|
</FILEREF>
|
||||||
|
<FILEREF>
|
||||||
|
<TARGETNAME>Necko.shlb</TARGETNAME>
|
||||||
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
<PATH>ParseFTPList.cpp</PATH>
|
||||||
|
<PATHFORMAT>MacOS</PATHFORMAT>
|
||||||
|
</FILEREF>
|
||||||
<FILEREF>
|
<FILEREF>
|
||||||
<TARGETNAME>Necko.shlb</TARGETNAME>
|
<TARGETNAME>Necko.shlb</TARGETNAME>
|
||||||
<PATHTYPE>Name</PATHTYPE>
|
<PATHTYPE>Name</PATHTYPE>
|
||||||
|
|
|
@ -1116,9 +1116,11 @@ nsFtpState::S_pass() {
|
||||||
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
|
nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
|
||||||
&passwd, &retval);
|
&passwd, &retval);
|
||||||
|
|
||||||
// we want to fail if the user canceled or didn't enter a password.
|
// we want to fail if the user canceled. Note here that if they want
|
||||||
if (!retval || (passwd && !*passwd) )
|
// a blank password, we will pass it along.
|
||||||
|
if (!retval)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
mPassword = passwd;
|
mPassword = passwd;
|
||||||
}
|
}
|
||||||
// XXX mPassword may contain non-ASCII characters! what do we do?
|
// XXX mPassword may contain non-ASCII characters! what do we do?
|
||||||
|
@ -1255,7 +1257,6 @@ nsFtpState::R_syst() {
|
||||||
// since we just alerted the user, clear mResponseMsg,
|
// since we just alerted the user, clear mResponseMsg,
|
||||||
// which is displayed to the user.
|
// which is displayed to the user.
|
||||||
mResponseMsg = "";
|
mResponseMsg = "";
|
||||||
|
|
||||||
return FTP_ERROR;
|
return FTP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1433,9 +1434,6 @@ nsFtpState::SetContentType()
|
||||||
switch (mListFormat) {
|
switch (mListFormat) {
|
||||||
case nsIDirectoryListing::FORMAT_RAW:
|
case nsIDirectoryListing::FORMAT_RAW:
|
||||||
{
|
{
|
||||||
nsAutoString fromStr(NS_LITERAL_STRING("text/ftp-dir-"));
|
|
||||||
SetDirMIMEType(fromStr);
|
|
||||||
|
|
||||||
contentType = NS_LITERAL_CSTRING("text/ftp-dir-");
|
contentType = NS_LITERAL_CSTRING("text/ftp-dir-");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2408,27 +2406,6 @@ nsFtpState::StopProcessing() {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
nsFtpState::SetDirMIMEType(nsString& aString) {
|
|
||||||
// the from content type is a string of the form
|
|
||||||
// "text/ftp-dir-SERVER_TYPE" where SERVER_TYPE represents the server we're talking to.
|
|
||||||
switch (mServerType) {
|
|
||||||
case FTP_UNIX_TYPE:
|
|
||||||
aString.Append(NS_LITERAL_STRING("unix"));
|
|
||||||
break;
|
|
||||||
case FTP_NT_TYPE:
|
|
||||||
aString.Append(NS_LITERAL_STRING("nt"));
|
|
||||||
break;
|
|
||||||
case FTP_OS2_TYPE:
|
|
||||||
aString.Append(NS_LITERAL_STRING("os2"));
|
|
||||||
break;
|
|
||||||
case FTP_VMS_TYPE:
|
|
||||||
aString.Append(NS_LITERAL_STRING("vms"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
aString.Append(NS_LITERAL_STRING("generic"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsFtpState::BuildStreamConverter(nsIStreamListener** convertStreamListener)
|
nsFtpState::BuildStreamConverter(nsIStreamListener** convertStreamListener)
|
||||||
|
@ -2446,8 +2423,8 @@ nsFtpState::BuildStreamConverter(nsIStreamListener** convertStreamListener)
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
nsAutoString fromStr(NS_LITERAL_STRING("text/ftp-dir-"));
|
nsAutoString fromStr(NS_LITERAL_STRING("text/ftp-dir"));
|
||||||
SetDirMIMEType(fromStr);
|
|
||||||
switch (mListFormat) {
|
switch (mListFormat) {
|
||||||
case nsIDirectoryListing::FORMAT_RAW:
|
case nsIDirectoryListing::FORMAT_RAW:
|
||||||
converterListener = listener;
|
converterListener = listener;
|
||||||
|
|
|
@ -157,7 +157,6 @@ private:
|
||||||
///////////////////////////////////
|
///////////////////////////////////
|
||||||
|
|
||||||
// internal methods
|
// internal methods
|
||||||
void SetDirMIMEType(nsString& aString);
|
|
||||||
void MoveToNextState(FTP_STATE nextState);
|
void MoveToNextState(FTP_STATE nextState);
|
||||||
nsresult Process();
|
nsresult Process();
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ EXPORTS = \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
|
ParseFTPList.cpp \
|
||||||
nsMultiMixedConv.cpp \
|
nsMultiMixedConv.cpp \
|
||||||
nsFTPDirListingConv.cpp \
|
nsFTPDirListingConv.cpp \
|
||||||
nsGopherDirListingConv.cpp \
|
nsGopherDirListingConv.cpp \
|
||||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,124 @@
|
||||||
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||||
|
/* ----- BEGIN LICENSE BLOCK -----
|
||||||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||||
|
*
|
||||||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||||||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
* http://www.mozilla.org/MPL/
|
||||||
|
*
|
||||||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||||
|
* for the specific language governing rights and limitations under the
|
||||||
|
* License.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* Cyrus Patel <cyp@fb14.uni-mainz.de>
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s): Doug Turner <dougt@netscape.com>
|
||||||
|
*
|
||||||
|
* Alternatively, the contents of this file may be used under the terms of
|
||||||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||||
|
* of those above. If you wish to allow use of your version of this file only
|
||||||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||||
|
* use your version of this file under the terms of the MPL, indicate your
|
||||||
|
* decision by deleting the provisions above and replace them with the notice
|
||||||
|
* and other provisions required by the LGPL or the GPL. If you do not delete
|
||||||
|
* the provisions above, a recipient may use your version of this file under
|
||||||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||||
|
*
|
||||||
|
* ----- END LICENSE BLOCK ----- */
|
||||||
|
#include "nspr.h"
|
||||||
|
|
||||||
|
/* ParseFTPList() parses lines from an FTP LIST command.
|
||||||
|
**
|
||||||
|
** Written July 2002 by Cyrus Patel <cyp@fb14.uni-mainz.de>
|
||||||
|
** with acknowledgements to squid, lynx, wget and ftpmirror.
|
||||||
|
**
|
||||||
|
** Arguments:
|
||||||
|
** 'line': line of FTP data connection output. The line is assumed
|
||||||
|
** to end at the first '\0' or '\n' or '\r\n'.
|
||||||
|
** 'state': a structure used internally to track state between
|
||||||
|
** lines. Needs to be bzero()'d at LIST begin.
|
||||||
|
** 'result': where ParseFTPList will store the results of the parse
|
||||||
|
** if 'line' is not a comment and is not junk.
|
||||||
|
**
|
||||||
|
** Returns one of the following:
|
||||||
|
** 'd' - LIST line is a directory entry ('result' is valid)
|
||||||
|
** 'f' - LIST line is a file's entry ('result' is valid)
|
||||||
|
** 'l' - LIST line is a symlink's entry ('result' is valid)
|
||||||
|
** '?' - LIST line is junk. (cwd, non-file/dir/link, etc)
|
||||||
|
** '"' - its not a LIST line (its a "comment")
|
||||||
|
**
|
||||||
|
** It may be advisable to let the end-user see "comments" (particularly when
|
||||||
|
** the listing results in ONLY such lines) because such a listing may be:
|
||||||
|
** - an unknown LIST format (NLST or "custom" format for example)
|
||||||
|
** - an error msg (EPERM,ENOENT,ENFILE,EMFILE,ENOTDIR,ENOTBLK,EEXDEV etc).
|
||||||
|
** - an empty directory and the 'comment' is a "total 0" line or similar.
|
||||||
|
** (warning: a "total 0" can also mean the total size is unknown).
|
||||||
|
**
|
||||||
|
** ParseFTPList() supports all known FTP LISTing formats:
|
||||||
|
** - '/bin/ls -l' and all variants (including Hellsoft FTP for NetWare);
|
||||||
|
** - EPLF (Easily Parsable List Format);
|
||||||
|
** - Windows NT's default "DOS-dirstyle";
|
||||||
|
** - OS/2 basic server format LIST format;
|
||||||
|
** - VMS (MultiNet, UCX, and CMU) LIST format (including multi-line format);
|
||||||
|
** - IBM VM/CMS, VM/ESA LIST format (two known variants);
|
||||||
|
** - SuperTCP FTP Server for Win16 LIST format;
|
||||||
|
** - NetManage Chameleon (NEWT) for Win16 LIST format;
|
||||||
|
** - '/bin/dls' (two known variants, plus multi-line) LIST format;
|
||||||
|
** If there are others, then I'd like to hear about them (send me a sample).
|
||||||
|
**
|
||||||
|
** NLSTings are not supported explicitely because they cannot be machine
|
||||||
|
** parsed consistantly: NLSTings do not have unique characteristics - even
|
||||||
|
** the assumption that there won't be whitespace on the line does not hold
|
||||||
|
** because some nlistings have more than one filename per line and/or
|
||||||
|
** may have filenames that have spaces in them. Moreover, distinguishing
|
||||||
|
** between an error message and an NLST line would require ParseList() to
|
||||||
|
** recognize all the possible strerror() messages in the world.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* #undef anything you don't want to support */
|
||||||
|
#define SUPPORT_LSL /* /bin/ls -l and dozens of variations therof */
|
||||||
|
#define SUPPORT_DLS /* /bin/dls format (very, Very, VERY rare) */
|
||||||
|
#define SUPPORT_EPLF /* Extraordinarily Pathetic List Format */
|
||||||
|
#define SUPPORT_DOS /* WinNT server in 'site dirstyle' dos */
|
||||||
|
#define SUPPORT_VMS /* VMS (all: MultiNet, UCX, CMU-IP) */
|
||||||
|
#define SUPPORT_CMS /* IBM VM/CMS,VM/ESA (z/VM and LISTING forms) */
|
||||||
|
#define SUPPORT_OS2 /* IBM TCP/IP for OS/2 - FTP Server */
|
||||||
|
#define SUPPORT_W16 /* win16 hosts: SuperTCP or NetManage Chameleon */
|
||||||
|
|
||||||
|
struct list_state
|
||||||
|
{
|
||||||
|
void *magic; /* to determine if previously initialized */
|
||||||
|
PRTime now_time; /* needed for year determination */
|
||||||
|
PRExplodedTime now_tm; /* needed for year determination */
|
||||||
|
PRInt32 lstyle; /* LISTing style */
|
||||||
|
PRInt32 parsed_one; /* returned anything yet? */
|
||||||
|
char carry_buf[84]; /* for VMS multiline */
|
||||||
|
PRUint32 carry_buf_len; /* length of name in carry_buf */
|
||||||
|
PRUint32 numlines; /* number of lines seen */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct list_result
|
||||||
|
{
|
||||||
|
PRInt32 fe_type; /* 'd'(dir) or 'l'(link) or 'f'(file) */
|
||||||
|
const char * fe_fname; /* pointer to filename */
|
||||||
|
PRUint32 fe_fnlen; /* length of filename */
|
||||||
|
const char * fe_lname; /* pointer to symlink name */
|
||||||
|
PRUint32 fe_lnlen; /* length of symlink name */
|
||||||
|
char fe_size[40]; /* size of file in bytes (<= (2^128 - 1)) */
|
||||||
|
PRExplodedTime fe_time; /* last-modified time */
|
||||||
|
PRInt32 fe_cinfs; /* file system is definitely case insensitive */
|
||||||
|
/* (converting all-upcase names may be desirable) */
|
||||||
|
};
|
||||||
|
|
||||||
|
int ParseFTPList(const char *line,
|
||||||
|
struct list_state *state,
|
||||||
|
struct list_result *result );
|
||||||
|
|
|
@ -55,15 +55,7 @@
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsMimeTypes.h"
|
#include "nsMimeTypes.h"
|
||||||
|
|
||||||
#define IS_LWS(c) (PL_strchr(" \t\r\n",c) != 0)
|
#include "ParseFTPList.h"
|
||||||
#define IS_FTYPE(c) (PL_strchr("-dlbcsp",c) != 0)
|
|
||||||
#define IS_RPERM(c) (PL_strchr("r-",c) != 0)
|
|
||||||
#define IS_WPERM(c) (PL_strchr("w-",c) != 0)
|
|
||||||
#define IS_SPERM(c) (PL_strchr("sSx-",c) != 0)
|
|
||||||
#define IS_TPERM(c) (PL_strchr("tTx-",c) != 0)
|
|
||||||
|
|
||||||
static NS_DEFINE_CID(kLocaleServiceCID, NS_LOCALESERVICE_CID);
|
|
||||||
static NS_DEFINE_CID(kDateTimeCID, NS_DATETIMEFORMAT_CID);
|
|
||||||
|
|
||||||
#if defined(PR_LOGGING)
|
#if defined(PR_LOGGING)
|
||||||
//
|
//
|
||||||
|
@ -87,111 +79,17 @@ NS_IMPL_THREADSAFE_ISUPPORTS3(nsFTPDirListingConv,
|
||||||
nsIStreamListener,
|
nsIStreamListener,
|
||||||
nsIRequestObserver);
|
nsIRequestObserver);
|
||||||
|
|
||||||
// Common code of Convert and AsyncConvertData function
|
|
||||||
|
|
||||||
static FTP_Server_Type
|
|
||||||
DetermineServerType (nsCString &fromMIMEString, const PRUnichar *aFromType)
|
|
||||||
{
|
|
||||||
fromMIMEString.AssignWithConversion(aFromType);
|
|
||||||
const char *from = fromMIMEString.get();
|
|
||||||
NS_ASSERTION(from, "nsCString/PRUnichar acceptance failed.");
|
|
||||||
|
|
||||||
from = PL_strstr(from, "/ftp-dir-");
|
|
||||||
if (!from) return ERROR_TYPE;
|
|
||||||
from += 9;
|
|
||||||
fromMIMEString = from;
|
|
||||||
|
|
||||||
if (-1 != fromMIMEString.Find("unix")) {
|
|
||||||
return UNIX;
|
|
||||||
} else if (-1 != fromMIMEString.Find("nt")) {
|
|
||||||
return NT;
|
|
||||||
} else if (-1 != fromMIMEString.Find("dcts")) {
|
|
||||||
return DCTS;
|
|
||||||
} else if (-1 != fromMIMEString.Find("ncsa")) {
|
|
||||||
return NCSA;
|
|
||||||
} else if (-1 != fromMIMEString.Find("peter_lewis")) {
|
|
||||||
return PETER_LEWIS;
|
|
||||||
} else if (-1 != fromMIMEString.Find("machten")) {
|
|
||||||
return MACHTEN;
|
|
||||||
} else if (-1 != fromMIMEString.Find("cms")) {
|
|
||||||
return CMS;
|
|
||||||
} else if (-1 != fromMIMEString.Find("tcpc")) {
|
|
||||||
return TCPC;
|
|
||||||
} else if (-1 != fromMIMEString.Find("os2")) {
|
|
||||||
return OS_2;
|
|
||||||
}
|
|
||||||
|
|
||||||
return GENERIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
// nsIStreamConverter implementation
|
// nsIStreamConverter implementation
|
||||||
|
|
||||||
#define CONV_BUF_SIZE (4*1024)
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFTPDirListingConv::Convert(nsIInputStream *aFromStream,
|
nsFTPDirListingConv::Convert(nsIInputStream *aFromStream,
|
||||||
const PRUnichar *aFromType,
|
const PRUnichar *aFromType,
|
||||||
const PRUnichar *aToType,
|
const PRUnichar *aToType,
|
||||||
nsISupports *aCtxt, nsIInputStream **_retval) {
|
nsISupports *aCtxt, nsIInputStream **_retval) {
|
||||||
nsresult rv;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
// set our internal state to reflect the server type
|
|
||||||
nsCString fromMIMEString;
|
|
||||||
|
|
||||||
mServerType = DetermineServerType(fromMIMEString, aFromType);
|
|
||||||
if (mServerType == ERROR_TYPE) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
char buffer[CONV_BUF_SIZE];
|
|
||||||
int i = 0;
|
|
||||||
while (i < CONV_BUF_SIZE) {
|
|
||||||
buffer[i] = '\0';
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
CBufDescriptor desc(buffer, PR_TRUE, CONV_BUF_SIZE);
|
|
||||||
nsCAutoString aBuffer(desc);
|
|
||||||
nsCString convertedData;
|
|
||||||
|
|
||||||
NS_ASSERTION(aCtxt, "FTP dir conversion needs the context");
|
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> uri(do_QueryInterface(aCtxt, &rv));
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
rv = GetHeaders(convertedData, uri);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
// build up the body
|
|
||||||
while (1) {
|
|
||||||
PRUint32 amtRead = 0;
|
|
||||||
|
|
||||||
rv = aFromStream->Read(buffer+aBuffer.Length(),
|
|
||||||
CONV_BUF_SIZE-aBuffer.Length(), &amtRead);
|
|
||||||
if (NS_FAILED(rv)) return rv;
|
|
||||||
|
|
||||||
if (!amtRead) {
|
|
||||||
// EOF
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
aBuffer = DigestBufferLines(buffer, convertedData);
|
|
||||||
}
|
|
||||||
// end body building
|
|
||||||
|
|
||||||
#ifndef DEBUG_valeski
|
|
||||||
PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG, ("::OnData() sending the following %d bytes...\n\n%s\n\n",
|
|
||||||
convertedData.Length(), convertedData.get()) );
|
|
||||||
#else
|
|
||||||
char *unescData = ToNewCString(convertedData);
|
|
||||||
nsUnescape(unescData);
|
|
||||||
printf("::OnData() sending the following %d bytes...\n\n%s\n\n", convertedData.Length(), unescData);
|
|
||||||
nsMemory::Free(unescData);
|
|
||||||
#endif // DEBUG_valeski
|
|
||||||
|
|
||||||
// send the converted data out.
|
|
||||||
return NS_NewCStringInputStream(_retval, convertedData);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Stream converter service calls this to initialize the actual stream converter (us).
|
// Stream converter service calls this to initialize the actual stream converter (us).
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsFTPDirListingConv::AsyncConvertData(const PRUnichar *aFromType, const PRUnichar *aToType,
|
nsFTPDirListingConv::AsyncConvertData(const PRUnichar *aFromType, const PRUnichar *aToType,
|
||||||
|
@ -204,13 +102,6 @@ nsFTPDirListingConv::AsyncConvertData(const PRUnichar *aFromType, const PRUnicha
|
||||||
mFinalListener = aListener;
|
mFinalListener = aListener;
|
||||||
NS_ADDREF(mFinalListener);
|
NS_ADDREF(mFinalListener);
|
||||||
|
|
||||||
// set our internal state to reflect the server type
|
|
||||||
nsCString fromMIMEString;
|
|
||||||
|
|
||||||
mServerType = DetermineServerType(fromMIMEString, aFromType);
|
|
||||||
if (mServerType == ERROR_TYPE) return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
|
|
||||||
// we need our own channel that represents the content-type of the
|
// we need our own channel that represents the content-type of the
|
||||||
// converted data.
|
// converted data.
|
||||||
NS_ASSERTION(aCtxt, "FTP dir listing needs a context (the uri)");
|
NS_ASSERTION(aCtxt, "FTP dir listing needs a context (the uri)");
|
||||||
|
@ -228,7 +119,7 @@ nsFTPDirListingConv::AsyncConvertData(const PRUnichar *aFromType, const PRUnicha
|
||||||
if (NS_FAILED(rv)) return rv;
|
if (NS_FAILED(rv)) return rv;
|
||||||
|
|
||||||
PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG,
|
PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG,
|
||||||
("nsFTPDirListingConv::AsyncConvertData() converting FROM raw %s, TO application/http-index-format\n", fromMIMEString.get()));
|
("nsFTPDirListingConv::AsyncConvertData() converting FROM raw, TO application/http-index-format\n"));
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
@ -268,11 +159,11 @@ nsFTPDirListingConv::OnDataAvailable(nsIRequest* request, nsISupports *ctxt,
|
||||||
mBuffer.Truncate();
|
mBuffer.Truncate();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef DEBUG_valeski
|
#ifndef DEBUG_dougt
|
||||||
PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG, ("::OnData() received the following %d bytes...\n\n%s\n\n", streamLen, buffer) );
|
PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG, ("::OnData() received the following %d bytes...\n\n%s\n\n", streamLen, buffer) );
|
||||||
#else
|
#else
|
||||||
printf("::OnData() received the following %d bytes...\n\n%s\n\n", streamLen, buffer);
|
printf("::OnData() received the following %d bytes...\n\n%s\n\n", streamLen, buffer);
|
||||||
#endif // DEBUG_valeski
|
#endif // DEBUG_dougt
|
||||||
|
|
||||||
nsCString indexFormat;
|
nsCString indexFormat;
|
||||||
if (!mSentHeading) {
|
if (!mSentHeading) {
|
||||||
|
@ -290,7 +181,7 @@ nsFTPDirListingConv::OnDataAvailable(nsIRequest* request, nsISupports *ctxt,
|
||||||
char *line = buffer;
|
char *line = buffer;
|
||||||
line = DigestBufferLines(line, indexFormat);
|
line = DigestBufferLines(line, indexFormat);
|
||||||
|
|
||||||
#ifndef DEBUG_valeski
|
#ifndef DEBUG_dougt
|
||||||
PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG, ("::OnData() sending the following %d bytes...\n\n%s\n\n",
|
PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG, ("::OnData() sending the following %d bytes...\n\n%s\n\n",
|
||||||
indexFormat.Length(), indexFormat.get()) );
|
indexFormat.Length(), indexFormat.get()) );
|
||||||
#else
|
#else
|
||||||
|
@ -298,7 +189,7 @@ nsFTPDirListingConv::OnDataAvailable(nsIRequest* request, nsISupports *ctxt,
|
||||||
nsUnescape(unescData);
|
nsUnescape(unescData);
|
||||||
printf("::OnData() sending the following %d bytes...\n\n%s\n\n", indexFormat.Length(), unescData);
|
printf("::OnData() sending the following %d bytes...\n\n%s\n\n", indexFormat.Length(), unescData);
|
||||||
nsMemory::Free(unescData);
|
nsMemory::Free(unescData);
|
||||||
#endif // DEBUG_valeski
|
#endif // DEBUG_dougt
|
||||||
|
|
||||||
// if there's any data left over, buffer it.
|
// if there's any data left over, buffer it.
|
||||||
if (line && *line) {
|
if (line && *line) {
|
||||||
|
@ -356,7 +247,6 @@ nsFTPDirListingConv::OnStopRequest(nsIRequest* request, nsISupports *ctxt,
|
||||||
nsFTPDirListingConv::nsFTPDirListingConv() {
|
nsFTPDirListingConv::nsFTPDirListingConv() {
|
||||||
NS_INIT_ISUPPORTS();
|
NS_INIT_ISUPPORTS();
|
||||||
mFinalListener = nsnull;
|
mFinalListener = nsnull;
|
||||||
mServerType = GENERIC;
|
|
||||||
mPartChannel = nsnull;
|
mPartChannel = nsnull;
|
||||||
mSentHeading = PR_FALSE;
|
mSentHeading = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
@ -416,368 +306,8 @@ nsFTPDirListingConv::GetHeaders(nsACString& headers,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
PRInt8
|
|
||||||
nsFTPDirListingConv::MonthNumber(const char *month) {
|
|
||||||
NS_ASSERTION(month && month[1] && month[2], "bad month");
|
|
||||||
if (!month || !month[0] || !month[1] || !month[2])
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
char c1 = month[1], c2 = month[2];
|
|
||||||
PRInt8 rv = -1;
|
|
||||||
|
|
||||||
//PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG, ("nsFTPDirListingConv::MonthNumber(month = %s) ", month) );
|
|
||||||
|
|
||||||
switch (*month) {
|
|
||||||
case 'f': case 'F':
|
|
||||||
rv = 1; break;
|
|
||||||
case 'm': case 'M':
|
|
||||||
// c1 == 'a' || c1 == 'A'
|
|
||||||
if (c2 == 'r' || c2 == 'R')
|
|
||||||
rv = 2;
|
|
||||||
else
|
|
||||||
// c2 == 'y' || c2 == 'Y'
|
|
||||||
rv = 4;
|
|
||||||
break;
|
|
||||||
case 'a': case 'A':
|
|
||||||
if (c1 == 'p' || c1 == 'P')
|
|
||||||
rv = 3;
|
|
||||||
else
|
|
||||||
// c1 == 'u' || c1 == 'U'
|
|
||||||
rv = 7;
|
|
||||||
break;
|
|
||||||
case 'j': case 'J':
|
|
||||||
if (c1 == 'u' || c1 == 'U') {
|
|
||||||
if (c2 == 'n' || c2 == 'N')
|
|
||||||
rv = 5;
|
|
||||||
else
|
|
||||||
// c2 == 'l' || c2 == 'L'
|
|
||||||
rv = 6;
|
|
||||||
} else {
|
|
||||||
// c1 == 'a' || c1 == 'A'
|
|
||||||
rv = 0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 's': case 'S':
|
|
||||||
rv = 8; break;
|
|
||||||
case 'o': case 'O':
|
|
||||||
rv = 9; break;
|
|
||||||
case 'n': case 'N':
|
|
||||||
rv = 10; break;
|
|
||||||
case 'd': case 'D':
|
|
||||||
rv = 11; break;
|
|
||||||
default:
|
|
||||||
rv = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
//PR_LOG(gFTPDirListConvLog, PR_LOG_DEBUG, ("returning %d\n", rv) );
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Return true if the string is of the form:
|
|
||||||
// "Sep 1 1990 " or
|
|
||||||
// "Sep 11 11:59 " or
|
|
||||||
// "Dec 12 1989 " or
|
|
||||||
// "FCv 23 1990 " ...
|
|
||||||
PRBool
|
|
||||||
nsFTPDirListingConv::IsLSDate(char *aCStr) {
|
|
||||||
|
|
||||||
/* must start with three alpha characters */
|
|
||||||
if (!nsCRT::IsAsciiAlpha(*aCStr++) || !nsCRT::IsAsciiAlpha(*aCStr++) || !nsCRT::IsAsciiAlpha(*aCStr++))
|
|
||||||
return PR_FALSE;
|
|
||||||
|
|
||||||
/* space */
|
|
||||||
if (*aCStr != ' ')
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* space or digit */
|
|
||||||
if ((*aCStr != ' ') && !nsCRT::IsAsciiDigit(*aCStr))
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* digit */
|
|
||||||
if (!nsCRT::IsAsciiDigit(*aCStr))
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* space */
|
|
||||||
if (*aCStr != ' ')
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* space or digit */
|
|
||||||
if ((*aCStr != ' ') && !nsCRT::IsAsciiDigit(*aCStr))
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* digit */
|
|
||||||
if (!nsCRT::IsAsciiDigit(*aCStr))
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* colon or digit */
|
|
||||||
if ((*aCStr != ':') && !nsCRT::IsAsciiDigit(*aCStr))
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* digit */
|
|
||||||
if (!nsCRT::IsAsciiDigit(*aCStr))
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* space or digit */
|
|
||||||
if ((*aCStr != ' ') && !nsCRT::IsAsciiDigit(*aCStr))
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
/* space */
|
|
||||||
if (*aCStr != ' ')
|
|
||||||
return PR_FALSE;
|
|
||||||
aCStr++;
|
|
||||||
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Converts a date string from 'ls -l' to a PRTime number
|
|
||||||
// "Sep 1 1990 " or
|
|
||||||
// "Sep 11 11:59 " or
|
|
||||||
// "Dec 12 1989 " or
|
|
||||||
// "FCv 23 1990 " ...
|
|
||||||
// Returns 0 on error.
|
|
||||||
PRBool
|
|
||||||
nsFTPDirListingConv::ConvertUNIXDate(char *aCStr, PRExplodedTime& outDate) {
|
|
||||||
|
|
||||||
PRExplodedTime curTime;
|
|
||||||
InitPRExplodedTime(curTime);
|
|
||||||
|
|
||||||
char *bcol = aCStr; /* Column begin */
|
|
||||||
char *ecol; /* Column end */
|
|
||||||
|
|
||||||
// MONTH
|
|
||||||
char tmpChar = bcol[3];
|
|
||||||
bcol[3] = '\0';
|
|
||||||
|
|
||||||
if ((curTime.tm_month = MonthNumber(bcol)) < 0)
|
|
||||||
return PR_FALSE;
|
|
||||||
bcol[3] = tmpChar;
|
|
||||||
|
|
||||||
// DAY
|
|
||||||
ecol = &bcol[3];
|
|
||||||
while (*(++ecol) == ' ') ;
|
|
||||||
while (*(++ecol) != ' ') ;
|
|
||||||
*ecol = '\0';
|
|
||||||
bcol = ecol+1;
|
|
||||||
while (*(--ecol) != ' ') ;
|
|
||||||
|
|
||||||
PRInt32 error;
|
|
||||||
nsCAutoString day(ecol);
|
|
||||||
curTime.tm_mday = day.ToInteger(&error, 10);
|
|
||||||
|
|
||||||
// YEAR
|
|
||||||
if ((ecol = PL_strchr(bcol, ':')) == NULL) {
|
|
||||||
nsCAutoString intStr(bcol);
|
|
||||||
curTime.tm_year = intStr.ToInteger(&error, 10);
|
|
||||||
} else {
|
|
||||||
// TIME
|
|
||||||
/* If the time is given as hh:mm, then the file is less than 1 year
|
|
||||||
* old, but we might shift calandar year. This is avoided by checking
|
|
||||||
* if the date parsed is future or not.
|
|
||||||
*/
|
|
||||||
*ecol = '\0';
|
|
||||||
nsCAutoString intStr(++ecol);
|
|
||||||
curTime.tm_min = intStr.ToInteger(&error, 10); // Right side of ':'
|
|
||||||
|
|
||||||
intStr = bcol;
|
|
||||||
curTime.tm_hour = intStr.ToInteger(&error, 10); // Left side of ':'
|
|
||||||
|
|
||||||
PRExplodedTime nowETime;
|
|
||||||
PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &nowETime);
|
|
||||||
curTime.tm_year = nowETime.tm_year;
|
|
||||||
|
|
||||||
PRBool thisCalendarYear = PR_FALSE;
|
|
||||||
if (nowETime.tm_month > curTime.tm_month) {
|
|
||||||
thisCalendarYear = PR_TRUE;
|
|
||||||
} else if (nowETime.tm_month == curTime.tm_month
|
|
||||||
&& nowETime.tm_mday > curTime.tm_mday) {
|
|
||||||
thisCalendarYear = PR_TRUE;
|
|
||||||
} else if (nowETime.tm_month == curTime.tm_month
|
|
||||||
&& nowETime.tm_mday == curTime.tm_mday
|
|
||||||
&& nowETime.tm_hour > curTime.tm_hour) {
|
|
||||||
thisCalendarYear = PR_TRUE;
|
|
||||||
} else if (nowETime.tm_month == curTime.tm_month
|
|
||||||
&& nowETime.tm_mday == curTime.tm_mday
|
|
||||||
&& nowETime.tm_hour == curTime.tm_hour
|
|
||||||
&& nowETime.tm_min >= curTime.tm_min) {
|
|
||||||
thisCalendarYear = PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!thisCalendarYear) curTime.tm_year--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the out param
|
|
||||||
outDate = curTime;
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsFTPDirListingConv::ConvertDOSDate(char *aCStr, PRExplodedTime& outDate) {
|
|
||||||
|
|
||||||
PRExplodedTime curTime, nowTime;
|
|
||||||
PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &nowTime);
|
|
||||||
PRInt16 currCentury = nowTime.tm_year / 100;
|
|
||||||
|
|
||||||
InitPRExplodedTime(curTime);
|
|
||||||
|
|
||||||
curTime.tm_month = ((aCStr[0]-'0')*10 + (aCStr[1]-'0')) - 1;
|
|
||||||
|
|
||||||
curTime.tm_mday = (((aCStr[3]-'0')*10) + aCStr[4]-'0');
|
|
||||||
curTime.tm_year = currCentury*100 + ((aCStr[6]-'0')*10) + aCStr[7]-'0';
|
|
||||||
// year is only 2-digit, so we've converted. If its in the future,
|
|
||||||
// it must have been last century
|
|
||||||
if (curTime.tm_year > nowTime.tm_year) {
|
|
||||||
curTime.tm_year -= 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
curTime.tm_hour = (((aCStr[10]-'0')*10) + aCStr[11]-'0');
|
|
||||||
|
|
||||||
if (aCStr[15] == 'P')
|
|
||||||
curTime.tm_hour += 12;
|
|
||||||
|
|
||||||
curTime.tm_min = (((aCStr[13]-'0')*10) + aCStr[14]-'0');
|
|
||||||
|
|
||||||
outDate = curTime;
|
|
||||||
return PR_TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsFTPDirListingConv::ParseLSLine(char *aLine, indexEntry *aEntry) {
|
|
||||||
|
|
||||||
PRInt32 base=1;
|
|
||||||
PRInt32 size_num=0;
|
|
||||||
char save_char;
|
|
||||||
char *ptr, *escName;
|
|
||||||
|
|
||||||
// insure that we have enough data to parse here
|
|
||||||
// using 27 for a minimal LIST line
|
|
||||||
if (PL_strlen(aLine) <= 27) {
|
|
||||||
NS_WARNING("ls -l is incorrectly formatted");
|
|
||||||
aEntry->mName.Adopt(nsEscape(aLine, url_Path));
|
|
||||||
// initialize the time struct to 0
|
|
||||||
InitPRExplodedTime(aEntry->mMDTM);
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ptr = &aLine[PL_strlen(aLine) - 1];
|
|
||||||
(ptr > aLine+13) && (!nsCRT::IsAsciiSpace(*ptr) || !IsLSDate(ptr-12)); ptr--)
|
|
||||||
; /* null body */
|
|
||||||
save_char = *ptr;
|
|
||||||
*ptr = '\0';
|
|
||||||
if (ptr > aLine+13) {
|
|
||||||
ConvertUNIXDate(ptr-12, aEntry->mMDTM);
|
|
||||||
} else {
|
|
||||||
// must be a dl listing
|
|
||||||
// unterminate the line
|
|
||||||
*ptr = save_char;
|
|
||||||
// find the first whitespace and terminate
|
|
||||||
for(ptr=aLine; *ptr != '\0'; ptr++)
|
|
||||||
if (nsCRT::IsAsciiSpace(*ptr)) {
|
|
||||||
*ptr = '\0';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
escName = nsEscape(aLine, url_Path);
|
|
||||||
aEntry->mName.Adopt(escName);
|
|
||||||
|
|
||||||
// initialize the time struct to 0 to be safe
|
|
||||||
InitPRExplodedTime(aEntry->mMDTM);
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
escName = nsEscape(ptr+1, url_Path);
|
|
||||||
aEntry->mName.Adopt(escName);
|
|
||||||
|
|
||||||
// parse size
|
|
||||||
if (ptr > aLine+15) {
|
|
||||||
ptr -= 14;
|
|
||||||
while (nsCRT::IsAsciiDigit(*ptr)) {
|
|
||||||
size_num += ((PRInt32) (*ptr - '0')) * base;
|
|
||||||
base *= 10;
|
|
||||||
ptr--;
|
|
||||||
}
|
|
||||||
|
|
||||||
aEntry->mContentLen = size_num;
|
|
||||||
}
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsFTPDirListingConv::InitPRExplodedTime(PRExplodedTime& aTime) {
|
|
||||||
aTime.tm_usec = 0;
|
|
||||||
aTime.tm_sec = 0;
|
|
||||||
aTime.tm_min = 0;
|
|
||||||
aTime.tm_hour = 0;
|
|
||||||
aTime.tm_mday = 0;
|
|
||||||
aTime.tm_month= 0;
|
|
||||||
aTime.tm_year = 0;
|
|
||||||
aTime.tm_wday = 0;
|
|
||||||
aTime.tm_yday = 0;
|
|
||||||
aTime.tm_params.tp_gmt_offset = 0;
|
|
||||||
aTime.tm_params.tp_dst_offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can this line possibly be a ls-l line?
|
|
||||||
* Ideally, one should parse the line into tokens, etc. but
|
|
||||||
* that's for later. At the moment, just test the line for
|
|
||||||
* length and examine the first token. An absolutely minimal
|
|
||||||
* line has the form
|
|
||||||
* -rwxrwxrwx 0 Dec 31 23:59 F
|
|
||||||
* which is 27 characters. If the line is at least 27 bytes
|
|
||||||
* long and the first token matches the regular expression
|
|
||||||
* [-dlbcps][r-][w-][sSx-][r-][w-][sSx-][r-][w-][tTx-]
|
|
||||||
* then accept the line *provided* there is another token on
|
|
||||||
* the line.
|
|
||||||
|
|
||||||
* As written, this function *assumes* leading whitespace has
|
|
||||||
* been removed. That's what the rest of the code assumes. It
|
|
||||||
* may not be a reasonable assumption.
|
|
||||||
|
|
||||||
* DigestBufferLines hints that the regular expression test should
|
|
||||||
* be done case insensitively. That would relax this test so it is
|
|
||||||
* *not* done. If definitive evidence exists of a server that does
|
|
||||||
* this, then it can be changed.
|
|
||||||
|
|
||||||
* This function uses a lot of macros for clarity. They probably
|
|
||||||
* should be improved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
PRBool
|
|
||||||
nsFTPDirListingConv::ls_lCandidate(const char *lsLine) {
|
|
||||||
|
|
||||||
const char *cp;
|
|
||||||
|
|
||||||
if (PL_strlen(lsLine) < 27) return PR_FALSE;
|
|
||||||
if (!IS_FTYPE(lsLine[0])) return PR_FALSE;
|
|
||||||
// shorter tests first
|
|
||||||
if (!IS_RPERM(lsLine[1])) return PR_FALSE;
|
|
||||||
if (!IS_WPERM(lsLine[2])) return PR_FALSE;
|
|
||||||
if (!IS_RPERM(lsLine[4])) return PR_FALSE;
|
|
||||||
if (!IS_WPERM(lsLine[5])) return PR_FALSE;
|
|
||||||
if (!IS_RPERM(lsLine[7])) return PR_FALSE;
|
|
||||||
if (!IS_WPERM(lsLine[8])) return PR_FALSE;
|
|
||||||
if (!IS_SPERM(lsLine[3])) return PR_FALSE;
|
|
||||||
if (!IS_SPERM(lsLine[6])) return PR_FALSE;
|
|
||||||
for (cp = &lsLine[10]; *cp; ++cp)
|
|
||||||
if (!IS_LWS(*cp)) return PR_TRUE;
|
|
||||||
return PR_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
nsFTPDirListingConv::DigestBufferLines(char *aBuffer, nsCString &aString) {
|
nsFTPDirListingConv::DigestBufferLines(char *aBuffer, nsCString &aString) {
|
||||||
nsresult rv;
|
|
||||||
char *line = aBuffer;
|
char *line = aBuffer;
|
||||||
char *eol;
|
char *eol;
|
||||||
PRBool cr = PR_FALSE;
|
PRBool cr = PR_FALSE;
|
||||||
|
@ -793,281 +323,53 @@ nsFTPDirListingConv::DigestBufferLines(char *aBuffer, nsCString &aString) {
|
||||||
*eol = '\0';
|
*eol = '\0';
|
||||||
cr = PR_FALSE;
|
cr = PR_FALSE;
|
||||||
}
|
}
|
||||||
indexEntry *thisEntry = nsnull;
|
|
||||||
NS_NEWXPCOM(thisEntry, indexEntry);
|
|
||||||
if (!thisEntry) return nsnull;
|
|
||||||
|
|
||||||
// XXX we need to handle comments in the raw stream.
|
list_state state;
|
||||||
|
list_result result;
|
||||||
|
|
||||||
// special case windows servers who masquerade as unix servers
|
int type = ParseFTPList(line, &state, &result );
|
||||||
if (NT == mServerType && !nsCRT::IsAsciiSpace(line[8]))
|
|
||||||
mServerType = UNIX;
|
|
||||||
|
|
||||||
// check for an eplf response
|
// if it is other than a directory, file, or link -OR- if it is a
|
||||||
if (line[0] == '+')
|
// directory named . or .., skip over this line.
|
||||||
mServerType = EPLF;
|
if ((type != 'd' && type != 'f' && type != 'l') ||
|
||||||
|
(result.fe_type == 'd' && result.fe_fname[0] == '.' &&
|
||||||
char *escName = nsnull;
|
(result.fe_fnlen == 1 || (result.fe_fnlen == 2 && result.fe_fname[1] == '.'))) )
|
||||||
switch (mServerType) {
|
|
||||||
|
|
||||||
case UNIX:
|
|
||||||
case PETER_LEWIS:
|
|
||||||
case MACHTEN:
|
|
||||||
{
|
{
|
||||||
// don't bother w/ these lines.
|
if (cr)
|
||||||
if (!PL_strncmp(line, "total ", 6)
|
line = eol+2;
|
||||||
|| !PL_strncmp(line, "ls: total", 9)
|
|
||||||
|| (PL_strstr(line, "Permission denied") != NULL)
|
|
||||||
|| (PL_strstr(line, "not available") != NULL)) {
|
|
||||||
NS_DELETEXPCOM(thisEntry);
|
|
||||||
if (cr)
|
|
||||||
line = eol+2;
|
|
||||||
else
|
|
||||||
line = eol+1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PRInt32 len = PL_strlen(line);
|
|
||||||
|
|
||||||
// check first character of ls -l output
|
|
||||||
// For example: "dr-x--x--x" is what we're starting with.
|
|
||||||
// sanity check for dir permission bits
|
|
||||||
if ((line[0] == 'D' || line[0] == 'd') && ls_lCandidate(line)) {
|
|
||||||
/* it's a directory */
|
|
||||||
thisEntry->mType = Dir;
|
|
||||||
thisEntry->mSupressSize = PR_TRUE;
|
|
||||||
} else if ((line[0] == 'L' || line[0] == 'l') && ls_lCandidate(line)) {
|
|
||||||
/**
|
|
||||||
* Dir Links are not displayed properly
|
|
||||||
* we need a more robust implementation
|
|
||||||
*/
|
|
||||||
thisEntry->mType = Link;
|
|
||||||
thisEntry->mSupressSize = PR_TRUE;
|
|
||||||
|
|
||||||
/* strip off " -> pathname" */
|
|
||||||
PRInt32 i;
|
|
||||||
for (i = len - 1; (i > 3) && (!nsCRT::IsAsciiSpace(line[i])
|
|
||||||
|| (line[i-1] != '>')
|
|
||||||
|| (line[i-2] != '-')
|
|
||||||
|| (line[i-3] != ' ')); i--)
|
|
||||||
; /* null body */
|
|
||||||
if (i > 3) {
|
|
||||||
line[i-3] = '\0';
|
|
||||||
len = i - 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = ParseLSLine(line, thisEntry);
|
|
||||||
if ( NS_FAILED(rv) || (thisEntry->mName.Equals("..")) || (thisEntry->mName.Equals(".")) ) {
|
|
||||||
NS_DELETEXPCOM(thisEntry);
|
|
||||||
if (cr)
|
|
||||||
line = eol+2;
|
|
||||||
else
|
|
||||||
line = eol+1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
break; // END UNIX, PETER_LEWIS, MACHTEN
|
|
||||||
}
|
|
||||||
|
|
||||||
case NCSA:
|
|
||||||
case TCPC:
|
|
||||||
{
|
|
||||||
escName = nsEscape(line, url_Path);
|
|
||||||
thisEntry->mName.Adopt(escName);
|
|
||||||
|
|
||||||
if (thisEntry->mName.Last() == '/') {
|
|
||||||
thisEntry->mType = Dir;
|
|
||||||
thisEntry->mName.Truncate(thisEntry->mName.Length()-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
break; // END NCSA, TCPC
|
|
||||||
}
|
|
||||||
|
|
||||||
case CMS:
|
|
||||||
{
|
|
||||||
escName = nsEscape(line, url_Path);
|
|
||||||
thisEntry->mName.Adopt(escName);
|
|
||||||
break; // END CMS
|
|
||||||
}
|
|
||||||
case NT:
|
|
||||||
{
|
|
||||||
// don't bother w/ these lines.
|
|
||||||
if (!PL_strncmp(line, "total ", 6)
|
|
||||||
|| !PL_strncmp(line, "ls: total", 9)
|
|
||||||
|| (PL_strstr(line, "Permission denied") != NULL)
|
|
||||||
|| (PL_strstr(line, "not available") != NULL)) {
|
|
||||||
NS_DELETEXPCOM(thisEntry);
|
|
||||||
if (cr)
|
|
||||||
line = eol+2;
|
|
||||||
else
|
|
||||||
line = eol+1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *date, *size_s, *name;
|
|
||||||
|
|
||||||
if (PL_strlen(line) > 37) {
|
|
||||||
date = line;
|
|
||||||
line[17] = '\0';
|
|
||||||
size_s = &line[18];
|
|
||||||
line[38] = '\0';
|
|
||||||
name = &line[39];
|
|
||||||
|
|
||||||
if (PL_strstr(size_s, "<DIR>")) {
|
|
||||||
thisEntry->mType = Dir;
|
|
||||||
} else {
|
|
||||||
nsCAutoString size(size_s);
|
|
||||||
size.StripWhitespace();
|
|
||||||
thisEntry->mContentLen = atol(size.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
ConvertDOSDate(date, thisEntry->mMDTM);
|
|
||||||
|
|
||||||
escName = nsEscape(name, url_Path);
|
|
||||||
thisEntry->mName.Adopt(escName);
|
|
||||||
} else {
|
|
||||||
escName = nsEscape(line, url_Path);
|
|
||||||
thisEntry->mName.Adopt(escName);
|
|
||||||
}
|
|
||||||
break; // END NT
|
|
||||||
}
|
|
||||||
case EPLF:
|
|
||||||
{
|
|
||||||
|
|
||||||
int flagcwd = 0;
|
|
||||||
int when = 0;
|
|
||||||
int flagsize = 0;
|
|
||||||
unsigned long size = 0;
|
|
||||||
PRBool processing = PR_TRUE;
|
|
||||||
while (*line && processing)
|
|
||||||
switch (*line) {
|
|
||||||
case '\t':
|
|
||||||
{
|
|
||||||
if (flagcwd) {
|
|
||||||
thisEntry->mType = Dir;
|
|
||||||
thisEntry->mContentLen = 0;
|
|
||||||
} else {
|
|
||||||
thisEntry->mType = File;
|
|
||||||
thisEntry->mContentLen = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
escName = nsEscape(line+1, url_Path);
|
|
||||||
thisEntry->mName.Adopt(escName);
|
|
||||||
thisEntry->mSupressSize = !flagsize;
|
|
||||||
|
|
||||||
// Mutiply what the last modification date to get usecs.
|
|
||||||
PRInt64 usecs = LL_Zero();
|
|
||||||
PRInt64 seconds = LL_Zero();
|
|
||||||
PRInt64 multiplier = LL_Zero();
|
|
||||||
LL_I2L(seconds, when);
|
|
||||||
LL_I2L(multiplier, PR_USEC_PER_SEC);
|
|
||||||
LL_MUL(usecs, seconds, multiplier);
|
|
||||||
PR_ExplodeTime(usecs, PR_LocalTimeParameters, &thisEntry->mMDTM);
|
|
||||||
|
|
||||||
processing = PR_FALSE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
flagsize = 1;
|
|
||||||
size = 0;
|
|
||||||
while (*++line && nsCRT::IsAsciiDigit(*line))
|
|
||||||
size = size * 10 + (*line - '0');
|
|
||||||
break;
|
|
||||||
case 'm':
|
|
||||||
while (*++line && nsCRT::IsAsciiDigit(*line))
|
|
||||||
when = when * 10 + (*line - '0');
|
|
||||||
break;
|
|
||||||
case '/':
|
|
||||||
flagcwd = 1;
|
|
||||||
default:
|
|
||||||
while (*line) if (*line++ == ',') break;
|
|
||||||
}
|
|
||||||
break; //END EPLF
|
|
||||||
}
|
|
||||||
|
|
||||||
case OS_2:
|
|
||||||
{
|
|
||||||
if (!PL_strncmp(line, "total ", 6)
|
|
||||||
|| (PL_strstr(line, "not authorized") != NULL)
|
|
||||||
|| (PL_strstr(line, "Path not found") != NULL)
|
|
||||||
|| (PL_strstr(line, "No Files") != NULL)) {
|
|
||||||
NS_DELETEXPCOM(thisEntry);
|
|
||||||
if (cr)
|
|
||||||
line = eol+2;
|
|
||||||
else
|
|
||||||
line = eol+1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *name;
|
|
||||||
nsCAutoString str;
|
|
||||||
|
|
||||||
if (PL_strstr(line, "DIR")) {
|
|
||||||
thisEntry->mType = Dir;
|
|
||||||
thisEntry->mSupressSize = PR_TRUE;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
thisEntry->mType = File;
|
line = eol+1;
|
||||||
|
|
||||||
PRInt32 error;
|
continue;
|
||||||
line[18] = '\0';
|
|
||||||
str = line;
|
|
||||||
str.StripWhitespace();
|
|
||||||
thisEntry->mContentLen = str.ToInteger(&error, 10);
|
|
||||||
|
|
||||||
InitPRExplodedTime(thisEntry->mMDTM);
|
|
||||||
line[37] = '\0';
|
|
||||||
str = &line[35];
|
|
||||||
thisEntry->mMDTM.tm_month = str.ToInteger(&error, 10) - 1;
|
|
||||||
|
|
||||||
line[40] = '\0';
|
|
||||||
str = &line[38];
|
|
||||||
thisEntry->mMDTM.tm_mday = str.ToInteger(&error, 10);
|
|
||||||
|
|
||||||
line[43] = '\0';
|
|
||||||
str = &line[41];
|
|
||||||
thisEntry->mMDTM.tm_year = str.ToInteger(&error, 10);
|
|
||||||
|
|
||||||
line[48] = '\0';
|
|
||||||
str = &line[46];
|
|
||||||
thisEntry->mMDTM.tm_hour = str.ToInteger(&error, 10);
|
|
||||||
|
|
||||||
line[51] = '\0';
|
|
||||||
str = &line[49];
|
|
||||||
thisEntry->mMDTM.tm_min = str.ToInteger(&error, 10);
|
|
||||||
|
|
||||||
name = &line[53];
|
|
||||||
escName = nsEscape(name, url_Path);
|
|
||||||
thisEntry->mName.Adopt(escName);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
escName = nsEscape(line, url_Path);
|
|
||||||
thisEntry->mName.Adopt(escName);
|
|
||||||
break; // END default (catches GENERIC, DCTS)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end switch (mServerType)
|
|
||||||
|
|
||||||
// blast the index entry into the indexFormat buffer as a 201: line.
|
// blast the index entry into the indexFormat buffer as a 201: line.
|
||||||
aString.Append("201: ");
|
aString.Append("201: ");
|
||||||
// FILENAME
|
// FILENAME
|
||||||
aString.Append(thisEntry->mName);
|
|
||||||
if (thisEntry->mType == Dir)
|
aString.Append(nsDependentCString(result.fe_fname, result.fe_fnlen));
|
||||||
|
|
||||||
|
/* Bug 143770
|
||||||
|
if (type == 'd')
|
||||||
aString.Append('/');
|
aString.Append('/');
|
||||||
|
*/
|
||||||
aString.Append(' ');
|
aString.Append(' ');
|
||||||
|
|
||||||
// CONTENT LENGTH
|
// CONTENT LENGTH
|
||||||
if (!thisEntry->mSupressSize) {
|
|
||||||
aString.AppendInt(thisEntry->mContentLen);
|
if (type == 'f')
|
||||||
} else {
|
{
|
||||||
aString.Append('0');
|
for (int i = 0; i < sizeof(result.fe_size); i++)
|
||||||
|
{
|
||||||
|
if (result.fe_size[i] != '\0')
|
||||||
|
aString.Append((const char*)&result.fe_size[i], 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
aString.Append(' ');
|
||||||
}
|
}
|
||||||
aString.Append(' ');
|
else
|
||||||
|
aString.Append("0 ");
|
||||||
|
|
||||||
|
|
||||||
// MODIFIED DATE
|
// MODIFIED DATE
|
||||||
char buffer[256] = "";
|
char buffer[256] = "";
|
||||||
|
@ -1075,40 +377,27 @@ nsFTPDirListingConv::DigestBufferLines(char *aBuffer, nsCString &aString) {
|
||||||
// the application/http-index-format specs
|
// the application/http-index-format specs
|
||||||
// viewers of such a format can then reformat this into the
|
// viewers of such a format can then reformat this into the
|
||||||
// current locale (or anything else they choose)
|
// current locale (or anything else they choose)
|
||||||
|
PR_FormatTimeUSEnglish(buffer, sizeof(buffer),
|
||||||
// make sure we don't have a null time struct
|
"%a, %d %b %Y %H:%M:%S", &result.fe_time );
|
||||||
if ((thisEntry->mMDTM.tm_month + thisEntry->mMDTM.tm_mday +
|
|
||||||
thisEntry->mMDTM.tm_year + thisEntry->mMDTM.tm_hour +
|
|
||||||
thisEntry->mMDTM.tm_min) != nsnull) {
|
|
||||||
PR_FormatTimeUSEnglish(buffer, sizeof(buffer),
|
|
||||||
"%a, %d %b %Y %H:%M:%S", &thisEntry->mMDTM );
|
|
||||||
}
|
|
||||||
|
|
||||||
char *escapedDate = nsEscape(buffer, url_Path);
|
char *escapedDate = nsEscape(buffer, url_Path);
|
||||||
|
|
||||||
aString.Append(escapedDate);
|
aString.Append(escapedDate);
|
||||||
nsMemory::Free(escapedDate);
|
nsMemory::Free(escapedDate);
|
||||||
aString.Append(' ');
|
aString.Append(' ');
|
||||||
|
|
||||||
|
|
||||||
// ENTRY TYPE
|
// ENTRY TYPE
|
||||||
switch (thisEntry->mType) {
|
if (type == 'd')
|
||||||
case Dir:
|
|
||||||
aString.Append("DIRECTORY");
|
aString.Append("DIRECTORY");
|
||||||
break;
|
else if (type == 'l')
|
||||||
case Link:
|
|
||||||
aString.Append("SYMBOLIC-LINK");
|
aString.Append("SYMBOLIC-LINK");
|
||||||
break;
|
else
|
||||||
default:
|
|
||||||
aString.Append("FILE");
|
aString.Append("FILE");
|
||||||
}
|
|
||||||
aString.Append(' ');
|
aString.Append(' ');
|
||||||
|
|
||||||
aString.Append(char(nsCRT::LF)); // complete this line
|
aString.Append(char(nsCRT::LF)); // complete this line
|
||||||
// END 201:
|
// END 201:
|
||||||
|
|
||||||
NS_DELETEXPCOM(thisEntry);
|
|
||||||
|
|
||||||
if (cr)
|
if (cr)
|
||||||
line = eol+2;
|
line = eol+2;
|
||||||
else
|
else
|
||||||
|
|
|
@ -53,62 +53,6 @@
|
||||||
}
|
}
|
||||||
static NS_DEFINE_CID(kFTPDirListingConverterCID, NS_FTPDIRLISTINGCONVERTER_CID);
|
static NS_DEFINE_CID(kFTPDirListingConverterCID, NS_FTPDIRLISTINGCONVERTER_CID);
|
||||||
|
|
||||||
// The nsFTPDirListingConv stream converter converts a stream of type "text/ftp-dir-SERVER_TYPE"
|
|
||||||
// (where SERVER_TYPE is one of the following):
|
|
||||||
//
|
|
||||||
// SERVER TYPES:
|
|
||||||
// generic
|
|
||||||
// unix
|
|
||||||
// dcts
|
|
||||||
// ncsa
|
|
||||||
// peter_lewis
|
|
||||||
// machten
|
|
||||||
// cms
|
|
||||||
// tcpc
|
|
||||||
// vms
|
|
||||||
// nt
|
|
||||||
// eplf
|
|
||||||
//
|
|
||||||
// nsFTPDirListingConv converts the raw ascii text directory generated via a FTP
|
|
||||||
// LIST or NLST command, to the application/http-index-format MIME-type.
|
|
||||||
// For more info see: http://www.area.com/~roeber/file_format.html
|
|
||||||
|
|
||||||
typedef enum _FTP_Server_Type {
|
|
||||||
GENERIC,
|
|
||||||
UNIX,
|
|
||||||
DCTS,
|
|
||||||
NCSA,
|
|
||||||
PETER_LEWIS,
|
|
||||||
MACHTEN,
|
|
||||||
CMS,
|
|
||||||
TCPC,
|
|
||||||
VMS,
|
|
||||||
NT,
|
|
||||||
EPLF,
|
|
||||||
OS_2,
|
|
||||||
ERROR_TYPE
|
|
||||||
} FTP_Server_Type;
|
|
||||||
|
|
||||||
typedef enum _FTPentryType {
|
|
||||||
Dir,
|
|
||||||
File,
|
|
||||||
Link
|
|
||||||
} FTPentryType;
|
|
||||||
|
|
||||||
|
|
||||||
// indexEntry is the data structure used to maintain directory entry information.
|
|
||||||
class indexEntry {
|
|
||||||
public:
|
|
||||||
indexEntry() { mContentLen = 0; mType = File; mSupressSize = PR_FALSE; };
|
|
||||||
|
|
||||||
nsCString mName; // the file or dir name
|
|
||||||
FTPentryType mType;
|
|
||||||
PRInt32 mContentLen; // length of the file
|
|
||||||
nsCString mContentType; // type of the file
|
|
||||||
PRExplodedTime mMDTM; // modified time
|
|
||||||
PRBool mSupressSize; // supress the size info from display
|
|
||||||
};
|
|
||||||
|
|
||||||
class nsFTPDirListingConv : public nsIStreamConverter {
|
class nsFTPDirListingConv : public nsIStreamConverter {
|
||||||
public:
|
public:
|
||||||
// nsISupports methods
|
// nsISupports methods
|
||||||
|
@ -128,53 +72,15 @@ public:
|
||||||
virtual ~nsFTPDirListingConv();
|
virtual ~nsFTPDirListingConv();
|
||||||
nsresult Init();
|
nsresult Init();
|
||||||
|
|
||||||
// For factory creation.
|
|
||||||
static NS_METHOD
|
|
||||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult) {
|
|
||||||
nsresult rv;
|
|
||||||
if (aOuter)
|
|
||||||
return NS_ERROR_NO_AGGREGATION;
|
|
||||||
|
|
||||||
nsFTPDirListingConv* _s = new nsFTPDirListingConv();
|
|
||||||
if (_s == nsnull)
|
|
||||||
return NS_ERROR_OUT_OF_MEMORY;
|
|
||||||
NS_ADDREF(_s);
|
|
||||||
rv = _s->Init();
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
delete _s;
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
rv = _s->QueryInterface(aIID, aResult);
|
|
||||||
NS_RELEASE(_s);
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Get the application/http-index-format headers
|
// Get the application/http-index-format headers
|
||||||
nsresult GetHeaders(nsACString& str, nsIURI* uri);
|
nsresult GetHeaders(nsACString& str, nsIURI* uri);
|
||||||
|
|
||||||
// util parsing methods
|
|
||||||
PRInt8 MonthNumber(const char *aCStr);
|
|
||||||
PRBool IsLSDate(char *aCStr);
|
|
||||||
|
|
||||||
// date conversion/parsing methods
|
|
||||||
PRBool ConvertUNIXDate(char *aCStr, PRExplodedTime& outDate);
|
|
||||||
PRBool ConvertDOSDate(char *aCStr, PRExplodedTime& outDate);
|
|
||||||
|
|
||||||
// line parsing methods
|
|
||||||
nsresult ParseLSLine(char *aLine, indexEntry *aEntry);
|
|
||||||
nsresult ParseVMSLine(char *aLine, indexEntry *aEntry);
|
|
||||||
|
|
||||||
void InitPRExplodedTime(PRExplodedTime& aTime);
|
|
||||||
PRBool ls_lCandidate(const char *aLine);
|
|
||||||
char* DigestBufferLines(char *aBuffer, nsCString &aString);
|
char* DigestBufferLines(char *aBuffer, nsCString &aString);
|
||||||
|
|
||||||
// member data
|
// member data
|
||||||
FTP_Server_Type mServerType; // what kind of server is the data coming from?
|
|
||||||
nsCAutoString mBuffer; // buffered data.
|
nsCAutoString mBuffer; // buffered data.
|
||||||
PRBool mSentHeading; // have we sent 100, 101, 200, and 300 lines yet?
|
PRBool mSentHeading; // have we sent 100, 101, 200, and 300 lines yet?
|
||||||
|
|
||||||
|
|
||||||
nsIStreamListener *mFinalListener; // this guy gets the converted data via his OnDataAvailable()
|
nsIStreamListener *mFinalListener; // this guy gets the converted data via his OnDataAvailable()
|
||||||
nsIChannel *mPartChannel; // the channel for the given part we're processing.
|
nsIChannel *mPartChannel; // the channel for the given part we're processing.
|
||||||
// one channel per part.
|
// one channel per part.
|
||||||
|
|
Загрузка…
Ссылка в новой задаче