📄 ftpdirectoryparser.cpp
字号:
if (result.modifiedTime.tm_mon != 0) { result.modifiedTime.tm_mon--; result.modifiedTime.tm_mday = atoi(tokens[0]+3); result.modifiedTime.tm_year = atoi(tokens[0]+6); if (result.modifiedTime.tm_year < 80) result.modifiedTime.tm_year += 100; } result.modifiedTime.tm_hour = atoi(tokens[1]+0); result.modifiedTime.tm_min = atoi(tokens[1]+3); if ((tokens[1][5]) == 'P' && result.modifiedTime.tm_hour < 12) result.modifiedTime.tm_hour += 12; /* 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 == 'W' && (!state.listStyle || state.listStyle == lstyle)) */ } /* if (!lstyle && (!state.listStyle || state.listStyle == 'W')) */#endif /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */#if defined(SUPPORT_OS2) if (!lstyle && (!state.listStyle || state.listStyle == 'O')) /* OS/2 test */ { /* 220 server IBM TCP/IP for OS/2 - FTP Server ver 23:04:36 on Jan 15 1997 ready. * fixed position, space padded columns. I have only a vague idea * of what the contents between col 18 and 34 might be: All I can infer * is that there may be attribute flags in there and there may be * a " DIR" in there. * * 1 2 3 4 5 6 *0123456789012345678901234567890123456789012345678901234567890123456789 *----- size -------|??????????????? MM-DD-YY| HH:MM| nnnnnnnnn.... * 0 DIR 04-11-95 16:26 . * 0 DIR 04-11-95 16:26 .. * 0 DIR 04-11-95 16:26 ADDRESS * 612 RHSA 07-28-95 16:45 air_tra1.bag * 195 A 08-09-95 10:23 Alfa1.bag * 0 RHS DIR 04-11-95 16:26 ATTACH * 372 A 08-09-95 10:26 Aussie_1.bag * 310992 06-28-94 09:56 INSTALL.EXE * 1 2 3 4 * 01234567890123456789012345678901234567890123456789 * dirlist from the mirror.pl project, col positions from Mozilla. */ p = &(line[toklen[0]]); /* \s(\d\d-\d\d-\d\d)\s+(\d\d:\d\d)\s */ if (numtoks >= 4 && toklen[0] <= 18 && isASCIIDigit(*tokens[0]) && (linelen - toklen[0]) >= (53-18) && p[18-18] == ' ' && p[34-18] == ' ' && p[37-18] == '-' && p[40-18] == '-' && p[43-18] == ' ' && p[45-18] == ' ' && p[48-18] == ':' && p[51-18] == ' ' && isASCIIDigit(p[35-18]) && isASCIIDigit(p[36-18]) && isASCIIDigit(p[38-18]) && isASCIIDigit(p[39-18]) && isASCIIDigit(p[41-18]) && isASCIIDigit(p[42-18]) && isASCIIDigit(p[46-18]) && isASCIIDigit(p[47-18]) && isASCIIDigit(p[49-18]) && isASCIIDigit(p[50-18]) ) { lstyle = 'O'; /* OS/2 */ if (!state.listStyle) { for (pos = 1; lstyle && pos < toklen[0]; pos++) { if (!isASCIIDigit(tokens[0][pos])) lstyle = 0; } } } if (lstyle == 'O') { state.parsedOne = true; state.listStyle = lstyle; p = &(line[toklen[0]]); result.caseSensitive = true; result.filename = &p[53-18]; result.filenameLength = (&(line[linelen_sans_wsp])) - (result.filename); result.type = FTPFileEntry; /* I don't have a real listing to determine exact pos, so scan. */ for (pos = (18-18); pos < ((35-18)-4); pos++) { if (p[pos+0] == ' ' && p[pos+1] == 'D' && p[pos+2] == 'I' && p[pos+3] == 'R') { result.type = FTPDirectoryEntry; break; } } if (result.type != FTPDirectoryEntry) { pos = toklen[0]; result.fileSize = String(tokens[0], pos); } result.modifiedTime.tm_mon = atoi(&p[35-18]) - 1; result.modifiedTime.tm_mday = atoi(&p[38-18]); result.modifiedTime.tm_year = atoi(&p[41-18]); if (result.modifiedTime.tm_year < 80) result.modifiedTime.tm_year += 100; result.modifiedTime.tm_hour = atoi(&p[46-18]); result.modifiedTime.tm_min = atoi(&p[49-18]); /* 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 == 'O') */ } /* if (!lstyle && (!state.listStyle || state.listStyle == 'O')) */#endif /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ #if defined(SUPPORT_LSL) if (!lstyle && (!state.listStyle || state.listStyle == 'U')) /* /bin/ls & co. */ { /* UNIX-style listing, without inum and without blocks * "-rw-r--r-- 1 root other 531 Jan 29 03:26 README" * "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc" * "dr-xr-xr-x 2 root 512 Apr 8 1994 etc" * "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin" * Also produced by Microsoft's FTP servers for Windows: * "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z" * "d--------- 1 owner group 0 May 9 19:45 Softlib" * Also WFTPD for MSDOS: * "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp" * Hellsoft for NetWare: * "d[RWCEMFA] supervisor 512 Jan 16 18:53 login" * "-[RWCEMFA] rhesus 214059 Oct 20 15:27 cx.exe" * Newer Hellsoft for NetWare: (netlab2.usu.edu) * - [RWCEAFMS] NFAUUser 192 Apr 27 15:21 HEADER.html * d [RWCEAFMS] jrd 512 Jul 11 03:01 allupdates * Also NetPresenz for the Mac: * "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit" * "drwxrwxr-x folder 2 May 10 1996 network" * Protected directory: * "drwx-wx-wt 2 root wheel 512 Jul 1 02:15 incoming" * uid/gid instead of username/groupname: * "drwxr-xr-x 2 0 0 512 May 28 22:17 etc" */ if (numtoks >= 6) { /* there are two perm formats (Hellsoft/NetWare and *IX strmode(3)). * Scan for size column only if the perm format is one or the other. */ if (toklen[0] == 1 || (tokens[0][1]) == '[') { if (*tokens[0] == 'd' || *tokens[0] == '-') { pos = toklen[0]-1; p = tokens[0] + 1; if (pos == 0) { p = tokens[1]; pos = toklen[1]; } if ((pos == 9 || pos == 10) && (*p == '[' && p[pos-1] == ']') && (p[1] == 'R' || p[1] == '-') && (p[2] == 'W' || p[2] == '-') && (p[3] == 'C' || p[3] == '-') && (p[4] == 'E' || p[4] == '-')) { /* rest is FMA[S] or AFM[S] */ lstyle = 'U'; /* very likely one of the NetWare servers */ } } } else if ((toklen[0] == 10 || toklen[0] == 11) && strchr("-bcdlpsw?DFam", *tokens[0])) { p = &(tokens[0][1]); if ((p[0] == 'r' || p[0] == '-') && (p[1] == 'w' || p[1] == '-') && (p[3] == 'r' || p[3] == '-') && (p[4] == 'w' || p[4] == '-') && (p[6] == 'r' || p[6] == '-') && (p[7] == 'w' || p[7] == '-')) /* 'x'/p[9] can be S|s|x|-|T|t or implementation specific */ { lstyle = 'U'; /* very likely /bin/ls */ } } } if (lstyle == 'U') /* first token checks out */ { lstyle = 0; for (pos = (numtoks-5); !lstyle && pos > 1; pos--) { /* scan for: (\d+)\s+([A-Z][a-z][a-z])\s+ * (\d\d\d\d|\d\:\d\d|\d\d\:\d\d|\d\:\d\d\:\d\d|\d\d\:\d\d\:\d\d) * \s+(.+)$ */ if (isASCIIDigit(*tokens[pos]) /* size */ /* (\w\w\w) */ && toklen[pos+1] == 3 && isASCIIAlpha(*tokens[pos+1]) && isASCIIAlpha(tokens[pos+1][1]) && isASCIIAlpha(tokens[pos+1][2]) /* (\d|\d\d) */ && isASCIIDigit(*tokens[pos+2]) && (toklen[pos+2] == 1 || (toklen[pos+2] == 2 && isASCIIDigit(tokens[pos+2][1]))) && toklen[pos+3] >= 4 && isASCIIDigit(*tokens[pos+3]) /* (\d\:\d\d\:\d\d|\d\d\:\d\d\:\d\d) */ && (toklen[pos+3] <= 5 || ( (toklen[pos+3] == 7 || toklen[pos+3] == 8) && (tokens[pos+3][toklen[pos+3]-3]) == ':')) && isASCIIDigit(tokens[pos+3][toklen[pos+3]-2]) && isASCIIDigit(tokens[pos+3][toklen[pos+3]-1]) && ( /* (\d\d\d\d) */ ((toklen[pos+3] == 4 || toklen[pos+3] == 5) && isASCIIDigit(tokens[pos+3][1]) && isASCIIDigit(tokens[pos+3][2]) ) /* (\d\:\d\d|\d\:\d\d\:\d\d) */ || ((toklen[pos+3] == 4 || toklen[pos+3] == 7) && (tokens[pos+3][1]) == ':' && isASCIIDigit(tokens[pos+3][2]) && isASCIIDigit(tokens[pos+3][3])) /* (\d\d\:\d\d|\d\d\:\d\d\:\d\d) */ || ((toklen[pos+3] == 5 || toklen[pos+3] == 8) && isASCIIDigit(tokens[pos+3][1]) && (tokens[pos+3][2]) == ':' && isASCIIDigit(tokens[pos+3][3]) && isASCIIDigit(tokens[pos+3][4])) ) ) { lstyle = 'U'; /* assume /bin/ls or variant format */ tokmarker = pos; /* check that size is numeric */ p = tokens[tokmarker]; for (pos = 0; lstyle && pos < toklen[tokmarker]; pos++) { if (!isASCIIDigit(*p++)) lstyle = 0; } if (lstyle) { month_num = 0; p = tokens[tokmarker+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) lstyle = 0; } } /* relative position test */ } /* while (pos+5) < numtoks */ } /* if (numtoks >= 4) */ if (lstyle == 'U') { state.parsedOne = true; state.listStyle = lstyle; result.caseSensitive = false; result.type = FTPJunkEntry; if (*tokens[0] == 'd' || *tokens[0] == 'D') result.type = FTPDirectoryEntry; else if (*tokens[0] == 'l') result.type = FTPLinkEntry; else if (*tokens[0] == '-' || *tokens[0] == 'F') result.type = FTPFileEntry; /* (hopefully a regular file) */ if (result.type != FTPDirectoryEntry) { pos = toklen[tokmarker]; result.fileSize = String(tokens[tokmarker], pos); } result.modifiedTime.tm_mon = month_num; result.modifiedTime.tm_mday = atoi(tokens[tokmarker+2]); if (result.modifiedTime.tm_mday == 0) result.modifiedTime.tm_mday++; p = tokens[tokmarker+3]; pos = (unsigned int)atoi(p); if (p[1] == ':') /* one digit hour */ p--; if (p[2] != ':') /* year */ { result.modifiedTime.tm_year = pos; } else { result.modifiedTime.tm_hour = pos; result.modifiedTime.tm_min = atoi(p+3); if (p[5] == ':') result.modifiedTime.tm_sec = atoi(p+6); 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 << 5) + state.nowFTPTime.tm_mday) < ((result.modifiedTime.tm_mon << 5) + result.modifiedTime.tm_mday) ) result.modifiedTime.tm_year--; } /* time/year */ result.filename = tokens[tokmarker+4]; result.filenameLength = (&(line[linelen_sans_wsp])) - (result.filename); if (result.type == FTPLinkEntry && result.filenameLength > 4) { p = result.filename + 1; for (pos = 1; pos < (result.filenameLength - 4); pos++) { if (*p == ' ' && p[1] == '-' && p[2] == '>' && p[3] == ' ') { result.linkname = p + 4; result.linknameLength = (&(line[linelen_sans_wsp])) - (result.linkname); result.filenameLength = pos; break; } p++; } }#if defined(SUPPORT_LSLF) /* some (very rare) servers return ls -lF */ if (result.filenameLength > 1) { p = result.filename[result.filenameLength-1]; pos = result.type; if (pos == 'd') { if (*p == '/') result.filenameLength--; /* directory */ } else if (pos == 'l') { if (*p == '@') result.filenameLength--; /* symlink */ } else if (pos == 'f') { if (*p == '*') result.filenameLength--; /* executable */ } else if (*p == '=' || *p == '%' || *p == '|') { result.filenameLength--; /* socket, whiteout, fifo */ } }#endif /* 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 == 'U') */ } /* if (!lstyle && (!state.listStyle || state.listStyle == 'U')) */#endif /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */#if defined(SUPPORT_W16) /* 16bit Windows */ if (!lstyle && (!state.listStyle || state.listStyle == 'w')) { /* old SuperTCP suite FTP server for Win3.1 */ /* old NetManage Chameleon TCP/IP suite FTP server for Win3.1 */ /* * SuperTCP dirlist from the mirror.pl project * mon/day/year separator may be '/' or '-'. * . <DIR> 11-16-94 17:16 * .. <DIR> 11-16-94 17:16 * INSTALL <DIR> 11-16-94 17:17 * CMT <DIR> 11-21-94 10:17 * DESIGN1.DOC 11264 05-11-95 14:20 * README.TXT 1045 05-10-95 11:01 * WPKIT1.EXE 960338 06-21-95 17:01 * CMT.CSV 0 07-06-95 14:56 * * Chameleon dirlist guessed from lynx * . <DIR> Nov 16 1994 17:16 * .. <DIR> Nov 16 1994 17:16 * INSTALL <DIR> Nov 16 1994 17:17 * CMT <DIR> Nov 21 1994 10:17 * DESIGN1.DOC 11264 May 11 1995 14:20 A * README.TXT 1045 May 10 1995 11:01 * WPKIT1.EXE 960338 Jun 21 1995 17:01 R * CMT.CSV 0 Jul 06 1995 14:56 RHA
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -