in src/main/java/org/apache/commons/net/ftp/parser/MLSxEntryParser.java [203:298]
public FTPFile parseFTPEntry(final String entry) {
if (entry.startsWith(" ")) { // leading space means no facts are present
if (entry.length() > 1) { // is there a path name?
final FTPFile file = new FTPFile();
file.setRawListing(entry);
file.setName(entry.substring(1));
return file;
}
return null; // Invalid - no path
}
final String[] parts = entry.split(" ", 2); // Path may contain space
if (parts.length != 2 || parts[1].isEmpty()) {
return null; // no space found or no file name
}
final String factList = parts[0];
if (!factList.endsWith(";")) {
return null;
}
final FTPFile file = new FTPFile();
file.setRawListing(entry);
file.setName(parts[1]);
final String[] facts = factList.split(";");
final boolean hasUnixMode = parts[0].toLowerCase(Locale.ENGLISH).contains("unix.mode=");
for (final String fact : facts) {
final String[] factparts = fact.split("=", -1); // Don't drop empty values
// Sample missing permission
// drwx------ 2 mirror mirror 4096 Mar 13 2010 subversion
// modify=20100313224553;perm=;type=dir;unique=811U282598;UNIX.group=500;UNIX.mode=0700;UNIX.owner=500; subversion
if (factparts.length != 2) {
return null; // invalid - there was no "=" sign
}
final String factname = factparts[0].toLowerCase(Locale.ENGLISH);
final String factvalue = factparts[1];
if (factvalue.isEmpty()) {
continue; // nothing to see here
}
final String valueLowerCase = factvalue.toLowerCase(Locale.ENGLISH);
switch (factname) {
case "size":
case "sizd":
file.setSize(Long.parseLong(factvalue));
break;
case "modify": {
final Calendar parsed = parseGMTdateTime(factvalue);
if (parsed == null) {
return null;
}
file.setTimestamp(parsed);
break;
}
case "type": {
final Integer intType = TYPE_TO_INT.get(valueLowerCase);
if (intType == null) {
file.setType(FTPFile.UNKNOWN_TYPE);
} else {
file.setType(intType.intValue());
}
break;
}
default:
if (factname.startsWith("unix.")) {
final String unixfact = factname.substring("unix.".length()).toLowerCase(Locale.ENGLISH);
switch (unixfact) {
case "group":
file.setGroup(factvalue);
break;
case "owner":
file.setUser(factvalue);
break;
case "mode": {
final int off = factvalue.length() - 3; // only parse last 3 digits
for (int i = 0; i < 3; i++) {
final int ch = factvalue.charAt(off + i) - '0';
if (ch >= 0 && ch <= 7) { // Check it's valid octal
for (final int p : UNIX_PERMS[ch]) {
file.setPermission(UNIX_GROUPS[i], p, true);
}
} else {
// TODO should this cause failure, or can it be reported somehow?
}
} // digits
break;
}
default:
break;
} // mode
// unix.
} else if (!hasUnixMode && "perm".equals(factname)) { // skip if we have the UNIX.mode
doUnixPerms(file, valueLowerCase);
}
break;
} // process "perm"
} // each fact
return file;
}