⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftpdirectoryparser.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 4 页
字号:
/* * Copyright (C) 2002 Cyrus Patel <cyp@fb14.uni-mainz.de> *           (C) 2007 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License 2.1 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB.  If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */// This was originally Mozilla code, titled ParseFTPList.cpp// Original version of this file can currently be found at: http://mxr.mozilla.org/mozilla1.8/source/netwerk/streamconv/converters/ParseFTPList.cpp#include "config.h"#if ENABLE(FTPDIR)#include "FTPDirectoryParser.h"#if PLATFORM(QT)#include <QDateTime>// On Windows, use the threadsafe *_r functions provided by pthread.#elif PLATFORM(WIN_OS) && (USE(PTHREADS) || HAVE(PTHREAD_H))#include <pthread.h>#endif#include <wtf/ASCIICType.h>#include <stdio.h>using namespace WTF;namespace WebCore {#if PLATFORM(QT) && defined(Q_WS_WIN32)// Defined in FTPDirectoryDocument.cpp.struct tm gmtimeQt(const QDateTime &input);static struct tm *gmtimeQt(const time_t *const timep, struct tm *result){    const QDateTime dt(QDateTime::fromTime_t(*timep));    *result = WebCore::gmtimeQt(dt);    return result;}#define gmtime_r(x, y) gmtimeQt(x, y)#elif PLATFORM(WIN_OS) && !defined(gmtime_r)#define gmtime_r(x, y) gmtime_s((y), (x))#endifFTPEntryType parseOneFTPLine(const char* line, ListState& state, ListResult& result){  result.clear();      if (!line)    return FTPJunkEntry;  state.numLines++;  /* carry buffer is only valid from one line to the next */  unsigned int carry_buf_len = state.carryBufferLength;  state.carryBufferLength = 0;  unsigned linelen = 0;  /* strip leading whitespace */  while (*line == ' ' || *line == '\t')    line++;    /* line is terminated at first '\0' or '\n' */  const char* p = line;  while (*p && *p != '\n')    p++;  linelen = p - line;  if (linelen > 0 && *p == '\n' && *(p-1) == '\r')    linelen--;  /* DON'T strip trailing whitespace. */  if (linelen > 0)  {    static const char *month_names = "JanFebMarAprMayJunJulAugSepOctNovDec";    const char *tokens[16]; /* 16 is more than enough */    unsigned int toklen[(sizeof(tokens)/sizeof(tokens[0]))];    unsigned int linelen_sans_wsp;  // line length sans whitespace    unsigned int numtoks = 0;    unsigned int tokmarker = 0; /* extra info for lstyle handler */    unsigned int month_num = 0;    char tbuf[4];    int lstyle = 0;    if (carry_buf_len) /* VMS long filename carryover buffer */    {      tokens[0] = state.carryBuffer;      toklen[0] = carry_buf_len;      numtoks++;    }    unsigned int pos = 0;    while (pos < linelen && numtoks < (sizeof(tokens)/sizeof(tokens[0])) )    {      while (pos < linelen &&             (line[pos] == ' ' || line[pos] == '\t' || line[pos] == '\r'))        pos++;      if (pos < linelen)      {        tokens[numtoks] = &line[pos];        while (pos < linelen &&            (line[pos] != ' ' && line[pos] != '\t' && line[pos] != '\r'))          pos++;        if (tokens[numtoks] != &line[pos])        {          toklen[numtoks] = (&line[pos] - tokens[numtoks]);          numtoks++;          }      }    }        linelen_sans_wsp = &(tokens[numtoks-1][toklen[numtoks-1]]) - tokens[0];    if (numtoks == (sizeof(tokens)/sizeof(tokens[0])) )    {      pos = linelen;      while (pos > 0 && (line[pos-1] == ' ' || line[pos-1] == '\t'))        pos--;      linelen_sans_wsp = pos;    }    /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */#if defined(SUPPORT_EPLF)    /* EPLF handling must come somewhere before /bin/dls handling. */    if (!lstyle && (!state.listStyle || state.listStyle == 'E'))    {      if (*line == '+' && linelen > 4 && numtoks >= 2)      {        pos = 1;        while (pos < (linelen-1))        {          p = &line[pos++];          if (*p == '/')             result.type = FTPDirectoryEntry; /* its a dir */          else if (*p == 'r')            result.type = FTPFileEntry; /* its a file */          else if (*p == 'm')          {            if (isASCIIDigit(line[pos]))            {              while (pos < linelen && isASCIIDigit(line[pos]))                pos++;              if (pos < linelen && line[pos] == ',')              {                unsigned long long seconds = 0;                sscanf(p + 1, "%llu", &seconds);                time_t t = static_cast<time_t>(seconds);                                // FIXME: This code has the year 2038 bug                gmtime_r(&t, &result.modifiedTime);                result.modifiedTime.tm_year += 1900;              }            }          }          else if (*p == 's')          {            if (isASCIIDigit(line[pos]))            {              while (pos < linelen && isASCIIDigit(line[pos]))                pos++;              if (pos < linelen && line[pos] == ',')                result.fileSize = String(p + 1, &line[pos] - p + 1);            }          }          else if (isASCIIAlpha(*p)) /* 'i'/'up' or unknown "fact" (property) */          {            while (pos < linelen && *++p != ',')              pos++;          }          else if (*p != '\t' || (p+1) != tokens[1])          {            break; /* its not EPLF after all */          }          else          {            state.parsedOne = true;            state.listStyle = lstyle = 'E';            p = &(line[linelen_sans_wsp]);            result.filename = tokens[1];            result.filenameLength = p - tokens[1];            if (!result.type) /* access denied */            {              result.type = FTPFileEntry; /* is assuming 'f'ile correct? */              return FTPJunkEntry;            /* NO! junk it. */            }            return result.type;          }          if (pos >= (linelen-1) || line[pos] != ',')            break;          pos++;        } /* while (pos < linelen) */        result.clear();      } /* if (*line == '+' && linelen > 4 && numtoks >= 2) */    } /* if (!lstyle && (!state.listStyle || state.listStyle == 'E')) */#endif /* SUPPORT_EPLF */    /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */#if defined(SUPPORT_VMS)    if (!lstyle && (!state.listStyle || state.listStyle == 'V'))    {                          /* try VMS Multinet/UCX/CMS server */      /*       * Legal characters in a VMS file/dir spec are [A-Z0-9$.-_~].       * '$' cannot begin a filename and `-' cannot be used as the first        * or last character. '.' is only valid as a directory separator        * and <file>.<type> separator. A canonical filename spec might look        * like this: DISK$VOL:[DIR1.DIR2.DIR3]FILE.TYPE;123       * All VMS FTP servers LIST in uppercase.       *       * We need to be picky about this in order to support       * multi-line listings correctly.      */      if (!state.parsedOne &&          (numtoks == 1 || (numtoks == 2 && toklen[0] == 9 &&                            memcmp(tokens[0], "Directory", 9)==0 )))      {        /* If no dirstyle has been detected yet, and this line is a          * VMS list's dirname, then turn on VMS dirstyle.         * eg "ACA:[ANONYMOUS]", "DISK$FTP:[ANONYMOUS]", "SYS$ANONFTP:"         */        p = tokens[0];        pos = toklen[0];        if (numtoks == 2)        {          p = tokens[1];          pos = toklen[1];        }        pos--;        if (pos >= 3)        {          while (pos > 0 && p[pos] != '[')          {            pos--;            if (p[pos] == '-' || p[pos] == '$')            {              if (pos == 0 || p[pos-1] == '[' || p[pos-1] == '.' ||                  (p[pos] == '-' && (p[pos+1] == ']' || p[pos+1] == '.')))                break;            }            else if (p[pos] != '.' && p[pos] != '~' &&                      !isASCIIDigit(p[pos]) && !isASCIIAlpha(p[pos]))              break;            else if (isASCIIAlpha(p[pos]) && p[pos] != toASCIIUpper(p[pos]))              break;          }          if (pos > 0)          {            pos--;            if (p[pos] != ':' || p[pos+1] != '[')              pos = 0;          }        }        if (pos > 0 && p[pos] == ':')        {          while (pos > 0)          {            pos--;            if (p[pos] != '$' && p[pos] != '_' && p[pos] != '-' &&                p[pos] != '~' && !isASCIIDigit(p[pos]) && !isASCIIAlpha(p[pos]))              break;            else if (isASCIIAlpha(p[pos]) && p[pos] != toASCIIUpper(p[pos]))              break;          }          if (pos == 0)          {              state.listStyle = 'V';            return FTPJunkEntry; /* its junk */          }        }        /* fallthrough */       }      else if ((tokens[0][toklen[0]-1]) != ';')      {        if (numtoks == 1 && (state.listStyle == 'V' && !carry_buf_len))          lstyle = 'V';        else if (numtoks < 4)          ;        else if (toklen[1] >= 10 && memcmp(tokens[1], "%RMS-E-PRV", 10) == 0)          lstyle = 'V';        else if ((&line[linelen] - tokens[1]) >= 22 &&                  memcmp(tokens[1], "insufficient privilege", 22) == 0)          lstyle = 'V';        else if (numtoks != 4 && numtoks != 6)          ;        else if (numtoks == 6 && (                 toklen[5] < 4 || *tokens[5] != '(' ||        /* perms */                           (tokens[5][toklen[5]-1]) != ')'  ))          ;        else if (  (toklen[2] == 10 || toklen[2] == 11) &&                              (tokens[2][toklen[2]-5]) == '-' &&                        (tokens[2][toklen[2]-9]) == '-' &&        (((toklen[3]==4 || toklen[3]==5 || toklen[3]==7 || toklen[3]==8) &&                        (tokens[3][toklen[3]-3]) == ':' ) ||         ((toklen[3]==10 || toklen[3]==11 ) &&                        (tokens[3][toklen[3]-3]) == '.' )        ) &&  /* time in [H]H:MM[:SS[.CC]] format */                                    isASCIIDigit(*tokens[1]) && /* size */                                    isASCIIDigit(*tokens[2]) && /* date */                                    isASCIIDigit(*tokens[3])    /* time */                )        {          lstyle = 'V';        }        if (lstyle == 'V')        {          /*           * MultiNet FTP:          *   LOGIN.COM;2                 1   4-NOV-1994 04:09 [ANONYMOUS] (RWE,RWE,,)          *   PUB.DIR;1                   1  27-JAN-1994 14:46 [ANONYMOUS] (RWE,RWE,RE,RWE)          *   README.FTP;1        %RMS-E-PRV, insufficient privilege or file protection violation          *   ROUSSOS.DIR;1               1  27-JAN-1994 14:48 [CS,ROUSSOS] (RWE,RWE,RE,R)          *   S67-50903.JPG;1           328  22-SEP-1998 16:19 [ANONYMOUS] (RWED,RWED,,)          * UCX FTP:           *   CII-MANUAL.TEX;1  213/216  29-JAN-1996 03:33:12  [ANONYMOU,ANONYMOUS] (RWED,RWED,,)          * CMU/VMS-IP FTP          *   [VMSSERV.FILES]ALARM.DIR;1 1/3 5-MAR-1993 18:09          * TCPware FTP          *   FOO.BAR;1 4 5-MAR-1993 18:09:01.12          * Long filename example:          *   THIS-IS-A-LONG-VMS-FILENAME.AND-THIS-IS-A-LONG-VMS-FILETYPE\r\n          *                    213[/nnn]  29-JAN-1996 03:33[:nn]  [ANONYMOU,ANONYMOUS] (RWED,RWED,,)          */          tokmarker = 0;          p = tokens[0];          pos = 0;          if (*p == '[' && toklen[0] >= 4) /* CMU style */          {            if (p[1] != ']')             {              p++;              pos++;            }            while (lstyle && pos < toklen[0] && *p != ']')            {              if (*p != '$' && *p != '.' && *p != '_' && *p != '-' &&                  *p != '~' && !isASCIIDigit(*p) && !isASCIIAlpha(*p))                              lstyle = 0;              pos++;              p++;            }            if (lstyle && pos < (toklen[0]-1) && *p == ']')            {              pos++;              p++;              tokmarker = pos; /* length of leading "[DIR1.DIR2.etc]" */            }          }          while (lstyle && pos < toklen[0] && *p != ';')          {            if (*p != '$' && *p != '.' && *p != '_' && *p != '-' &&                *p != '~' && !isASCIIDigit(*p) && !isASCIIAlpha(*p))              lstyle = 0;            else if (isASCIIAlpha(*p) && *p != toASCIIUpper(*p))              lstyle = 0;            p++;            pos++;          }          if (lstyle && *p == ';')          {            if (pos == 0 || pos == (toklen[0]-1))              lstyle = 0;            for (pos++;lstyle && pos < toklen[0];pos++)            {              if (!isASCIIDigit(tokens[0][pos]))                lstyle = 0;            }          }          pos = (p - tokens[0]); /* => fnlength sans ";####" */          pos -= tokmarker;      /* => fnlength sans "[DIR1.DIR2.etc]" */          p = &(tokens[0][tokmarker]); /* offset of basename */          if (!lstyle || pos > 80) /* VMS filenames can't be longer than that */          {            lstyle = 0;          }          else if (numtoks == 1)          {             /* if VMS has been detected and there is only one token and that              * token was a VMS filename then this is a multiline VMS LIST entry.            */            if (pos >= (sizeof(state.carryBuffer)-1))              pos = (sizeof(state.carryBuffer)-1); /* shouldn't happen */            memcpy( state.carryBuffer, p, pos );            state.carryBufferLength = pos;            return FTPJunkEntry; /* tell caller to treat as junk */          }          else if (isASCIIDigit(*tokens[1])) /* not no-privs message */          {            for (pos = 0; lstyle && pos < (toklen[1]); pos++)            {              if (!isASCIIDigit((tokens[1][pos])) && (tokens[1][pos]) != '/')                lstyle = 0;            }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -