📄 ftpdirectoryparser.cpp
字号:
*/ if (numtoks >= 4 && toklen[0] < 13 && ((toklen[1] == 5 && *tokens[1] == '<') || isASCIIDigit(*tokens[1])) ) { if (numtoks == 4 && (toklen[2] == 8 || toklen[2] == 9) && (((tokens[2][2]) == '/' && (tokens[2][5]) == '/') || ((tokens[2][2]) == '-' && (tokens[2][5]) == '-')) && (toklen[3] == 4 || toklen[3] == 5) && (tokens[3][toklen[3]-3]) == ':' && isASCIIDigit(tokens[2][0]) && isASCIIDigit(tokens[2][1]) && isASCIIDigit(tokens[2][3]) && isASCIIDigit(tokens[2][4]) && isASCIIDigit(tokens[2][6]) && isASCIIDigit(tokens[2][7]) && (toklen[2] < 9 || isASCIIDigit(tokens[2][8])) && isASCIIDigit(tokens[3][toklen[3]-1]) && isASCIIDigit(tokens[3][toklen[3]-2]) && isASCIIDigit(tokens[3][toklen[3]-4]) && isASCIIDigit(*tokens[3]) ) { lstyle = 'w'; } else if ((numtoks == 6 || numtoks == 7) && toklen[2] == 3 && toklen[3] == 2 && toklen[4] == 4 && toklen[5] == 5 && (tokens[5][2]) == ':' && isASCIIAlpha(tokens[2][0]) && isASCIIAlpha(tokens[2][1]) && isASCIIAlpha(tokens[2][2]) && isASCIIDigit(tokens[3][0]) && isASCIIDigit(tokens[3][1]) && isASCIIDigit(tokens[4][0]) && isASCIIDigit(tokens[4][1]) && isASCIIDigit(tokens[4][2]) && isASCIIDigit(tokens[4][3]) && isASCIIDigit(tokens[5][0]) && isASCIIDigit(tokens[5][1]) && isASCIIDigit(tokens[5][3]) && isASCIIDigit(tokens[5][4]) /* could also check that (&(tokens[5][5]) - tokens[2]) == 17 */ ) { lstyle = 'w'; } if (lstyle && state.listStyle != lstyle) /* first time */ { p = tokens[1]; if (toklen[1] != 5 || p[0] != '<' || p[1] != 'D' || p[2] != 'I' || p[3] != 'R' || p[4] != '>') { for (pos = 0; lstyle && pos < toklen[1]; pos++) { if (!isASCIIDigit(*p++)) lstyle = 0; } } /* not <DIR> */ } /* if (first time) */ } /* if (numtoks == ...) */ if (lstyle == 'w') { state.parsedOne = true; state.listStyle = lstyle; result.caseSensitive = true; result.filename = tokens[0]; result.filenameLength = toklen[0]; result.type = FTPDirectoryEntry; p = tokens[1]; if (isASCIIDigit(*p)) { result.type = FTPFileEntry; pos = toklen[1]; result.fileSize = String(p, pos); } p = tokens[2]; if (toklen[2] == 3) /* Chameleon */ { tbuf[0] = toASCIIUpper(p[0]); tbuf[1] = toASCIILower(p[1]); tbuf[2] = toASCIILower(p[2]); for (pos = 0; pos < (12*3); pos+=3) { if (tbuf[0] == month_names[pos+0] && tbuf[1] == month_names[pos+1] && tbuf[2] == month_names[pos+2]) { result.modifiedTime.tm_mon = pos/3; result.modifiedTime.tm_mday = atoi(tokens[3]); result.modifiedTime.tm_year = atoi(tokens[4]) - 1900; break; } } pos = 5; /* Chameleon toknum of date field */ } else { result.modifiedTime.tm_mon = atoi(p+0)-1; result.modifiedTime.tm_mday = atoi(p+3); result.modifiedTime.tm_year = atoi(p+6); if (result.modifiedTime.tm_year < 80) /* SuperTCP */ result.modifiedTime.tm_year += 100; pos = 3; /* SuperTCP toknum of date field */ } result.modifiedTime.tm_hour = atoi(tokens[pos]); result.modifiedTime.tm_min = atoi(&(tokens[pos][toklen[pos]-2])); /* the caller should do this (if dropping "." and ".." is desired) if (result.type == FTPDirectoryEntry && result.filename[0] == '.' && (result.filenameLength == 1 || (result.filenameLength == 2 && result.filename[1] == '.'))) return FTPJunkEntry; */ return result.type; } /* (lstyle == 'w') */ } /* if (!lstyle && (!state.listStyle || state.listStyle == 'w')) */#endif /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */#if defined(SUPPORT_DLS) /* dls -dtR */ if (!lstyle && (state.listStyle == 'D' || (!state.listStyle && state.numLines == 1))) /* /bin/dls lines have to be immediately recognizable (first line) */ { /* I haven't seen an FTP server that delivers a /bin/dls listing, * but can infer the format from the lynx and mirror.pl projects. * Both formats are supported. * * Lynx says: * README 763 Information about this server\0 * bin/ - \0 * etc/ = \0 * ls-lR 0 \0 * ls-lR.Z 3 \0 * pub/ = Public area\0 * usr/ - \0 * morgan 14 -> ../real/morgan\0 * TIMIT.mostlikely.Z\0 * 79215 \0 * * mirror.pl says: * filename: ^(\S*)\s+ * size: (\-|\=|\d+)\s+ * month/day: ((\w\w\w\s+\d+|\d+\s+\w\w\w)\s+ * time/year: (\d+:\d+|\d\d\d\d))\s+ * rest: (.+) * * README 763 Jul 11 21:05 Information about this server * bin/ - Apr 28 1994 * etc/ = 11 Jul 21:04 * ls-lR 0 6 Aug 17:14 * ls-lR.Z 3 05 Sep 1994 * pub/ = Jul 11 21:04 Public area * usr/ - Sep 7 09:39 * morgan 14 Apr 18 09:39 -> ../real/morgan * TIMIT.mostlikely.Z * 79215 Jul 11 21:04 */ if (!state.listStyle && line[linelen-1] == ':' && linelen >= 2 && toklen[numtoks-1] != 1) { /* code in mirror.pl suggests that a listing may be preceded * by a PWD line in the form "/some/dir/names/here:" * but does not necessarily begin with '/'. *sigh* */ pos = 0; p = line; while (pos < (linelen-1)) { /* illegal (or extremely unusual) chars in a dirspec */ if (*p == '<' || *p == '|' || *p == '>' || *p == '?' || *p == '*' || *p == '\\') break; if (*p == '/' && pos < (linelen-2) && p[1] == '/') break; pos++; p++; } if (pos == (linelen-1)) { state.listStyle = 'D'; return FTPJunkEntry; } } if (!lstyle && numtoks >= 2) { pos = 22; /* pos of (\d+|-|=) if this is not part of a multiline */ if (state.listStyle && carry_buf_len) /* first is from previous line */ pos = toklen[1]-1; /* and is 'as-is' (may contain whitespace) */ if (linelen > pos) { p = &line[pos]; if ((*p == '-' || *p == '=' || isASCIIDigit(*p)) && ((linelen == (pos+1)) || (linelen >= (pos+3) && p[1] == ' ' && p[2] == ' ')) ) { tokmarker = 1; if (!carry_buf_len) { pos = 1; while (pos < numtoks && (tokens[pos]+toklen[pos]) < (&line[23])) pos++; tokmarker = 0; if ((tokens[pos]+toklen[pos]) == (&line[23])) tokmarker = pos; } if (tokmarker) { lstyle = 'D'; if (*tokens[tokmarker] == '-' || *tokens[tokmarker] == '=') { if (toklen[tokmarker] != 1 || (tokens[tokmarker-1][toklen[tokmarker-1]-1]) != '/') lstyle = 0; } else { for (pos = 0; lstyle && pos < toklen[tokmarker]; pos++) { if (!isASCIIDigit(tokens[tokmarker][pos])) lstyle = 0; } } if (lstyle && !state.listStyle) /* first time */ { /* scan for illegal (or incredibly unusual) chars in fname */ for (p = tokens[0]; lstyle && p < &(tokens[tokmarker-1][toklen[tokmarker-1]]); p++) { if (*p == '<' || *p == '|' || *p == '>' || *p == '?' || *p == '*' || *p == '/' || *p == '\\') lstyle = 0; } } } /* size token found */ } /* expected chars behind expected size token */ } /* if (linelen > pos) */ } /* if (!lstyle && numtoks >= 2) */ if (!lstyle && state.listStyle == 'D' && !carry_buf_len) { /* the filename of a multi-line entry can be identified * correctly only if dls format had been previously established. * This should always be true because there should be entries * for '.' and/or '..' and/or CWD that precede the rest of the * listing. */ pos = linelen; if (pos > (sizeof(state.carryBuffer)-1)) pos = sizeof(state.carryBuffer)-1; memcpy( state.carryBuffer, line, pos ); state.carryBufferLength = pos; return FTPJunkEntry; } if (lstyle == 'D') { state.parsedOne = true; state.listStyle = lstyle; p = &(tokens[tokmarker-1][toklen[tokmarker-1]]); result.filename = tokens[0]; result.filenameLength = p - tokens[0]; result.type = FTPFileEntry; if (result.filename[result.filenameLength-1] == '/') { if (result.linknameLength == 1) result.type = FTPJunkEntry; else { result.filenameLength--; result.type = FTPDirectoryEntry; } } else if (isASCIIDigit(*tokens[tokmarker])) { pos = toklen[tokmarker]; result.fileSize = String(tokens[tokmarker], pos); } if ((tokmarker+3) < numtoks && (&(tokens[numtoks-1][toklen[numtoks-1]]) - tokens[tokmarker+1]) >= (1+1+3+1+4) ) { pos = (tokmarker+3); p = tokens[pos]; pos = toklen[pos]; if ((pos == 4 || pos == 5) && isASCIIDigit(*p) && isASCIIDigit(p[pos-1]) && isASCIIDigit(p[pos-2]) && ((pos == 5 && p[2] == ':') || (pos == 4 && (isASCIIDigit(p[1]) || p[1] == ':'))) ) { month_num = tokmarker+1; /* assumed position of month field */ pos = tokmarker+2; /* assumed position of mday field */ if (isASCIIDigit(*tokens[month_num])) /* positions are reversed */ { month_num++; pos--; } p = tokens[month_num]; if (isASCIIDigit(*tokens[pos]) && (toklen[pos] == 1 || (toklen[pos] == 2 && isASCIIDigit(tokens[pos][1]))) && toklen[month_num] == 3 && isASCIIAlpha(*p) && isASCIIAlpha(p[1]) && isASCIIAlpha(p[2]) ) { pos = atoi(tokens[pos]); if (pos > 0 && pos <= 31) { result.modifiedTime.tm_mday = pos; month_num = 1; for (pos = 0; pos < (12*3); pos+=3) { if (p[0] == month_names[pos+0] && p[1] == month_names[pos+1] && p[2] == month_names[pos+2]) break; month_num++; } if (month_num > 12) result.modifiedTime.tm_mday = 0; else result.modifiedTime.tm_mon = month_num - 1; } } if (result.modifiedTime.tm_mday) { tokmarker += 3; /* skip mday/mon/yrtime (to find " -> ") */ p = tokens[tokmarker]; pos = atoi(p); if (pos > 24) result.modifiedTime.tm_year = pos-1900; else { if (p[1] == ':') p--; result.modifiedTime.tm_hour = pos; result.modifiedTime.tm_min = atoi(p+3); if (!state.now) { time_t now = time(NULL); state.now = now * 1000000.0; // FIXME: This code has the year 2038 bug gmtime_r(&now, &state.nowFTPTime); state.nowFTPTime.tm_year += 1900; } result.modifiedTime.tm_year = state.nowFTPTime.tm_year; if ( (( state.nowFTPTime.tm_mon << 4) + state.nowFTPTime.tm_mday) < ((result.modifiedTime.tm_mon << 4) + result.modifiedTime.tm_mday) ) result.modifiedTime.tm_year--; } /* got year or time */ } /* got month/mday */ } /* may have year or time */ } /* enough remaining to possibly have date/time */ if (numtoks > (tokmarker+2)) { pos = tokmarker+1; p = tokens[pos]; if (toklen[pos] == 2 && *p == '-' && p[1] == '>') { p = &(tokens[numtoks-1][toklen[numtoks-1]]); result.type = FTPLinkEntry; result.linkname = tokens[pos+1]; result.linknameLength = p - result.linkname; if (result.linknameLength > 1 && result.linkname[result.linknameLength-1] == '/') result.linknameLength--; } } /* if (numtoks > (tokmarker+2)) */ /* the caller should do this (if dropping "." and ".." is desired) if (result.type == FTPDirectoryEntry && result.filename[0] == '.' && (result.filenameLength == 1 || (result.filenameLength == 2 && result.filename[1] == '.'))) return FTPJunkEntry; */ return result.type; } /* if (lstyle == 'D') */ } /* if (!lstyle && (!state.listStyle || state.listStyle == 'D')) */#endif /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ } /* if (linelen > 0) */ if (state.parsedOne || state.listStyle) /* junk if we fail to parse */ return FTPJunkEntry; /* this time but had previously parsed sucessfully */ return FTPMiscEntry; /* its part of a comment or error message */}} // namespace WebCore#endif // ENABLE(FTPDIR)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -