IND$FILE Browse!
This commit is contained in:
@@ -9,10 +9,11 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public class FTConfig {
|
||||
|
||||
private static final Pattern RECFM_PATTERN = Pattern.compile("(?i)RECFM[\\s\\(]+([FVU]|FIXED|VARIABLE|UNDEFINED)\\)?");
|
||||
private static final Pattern RECFM_PATTERN = Pattern.compile("(?i)RECFM[\\s\\(]+([FVU]|FB|VB|VBS|FBS|FIXED|VARIABLE|UNDEFINED)\\)?");
|
||||
private static final Pattern LRECL_PATTERN = Pattern.compile("(?i)LRECL[\\s\\(]+(\\d+)\\)?");
|
||||
private static final Pattern BLK_PATTERN = Pattern.compile("(?i)(?:BLKSIZE|BLOCK)[\\s\\(]+(\\d+)\\)?");
|
||||
private static final Pattern SPACE_PATTERN = Pattern.compile("(?i)SPACE[\\s\\(]+(\\d+)(?:[\\s,]+(\\d+))?\\)?");
|
||||
private static final Pattern SPACE_PATTERN = Pattern.compile("(?i)SPACE[\\s\\(]+(\\d+)(?:[\\s,]+(\\d+))?(?:[\\s,]+(\\d+))?\\)?");
|
||||
private static final Pattern DIR_PATTERN = Pattern.compile("(?i)(?:DIR|DIRECTORY)[\\s\\(]+(\\d+)\\)?");
|
||||
private static final Pattern AVB_PATTERN = Pattern.compile("(?i)AVBLOCK[\\s\\(]+(\\d+)\\)?");
|
||||
private static final Pattern CP_PATTERN = Pattern.compile("(?i)CODEPAGE[\\s\\(]+([A-Za-z0-9_-]+)\\)?");
|
||||
private static final Pattern MTU_PATTERN = Pattern.compile("(?i)(?:BUFFERSIZE|MTU|BUFSIZE)[\\s\\(]+(\\d+)\\)?");
|
||||
@@ -68,6 +69,7 @@ public class FTConfig {
|
||||
private int blksize = 0;
|
||||
private int primarySpace = 0;
|
||||
private int secondarySpace = 0;
|
||||
private int directoryBlocks = 0;
|
||||
private int avblock = 0;
|
||||
private int dftBufferSize = FTConstants.DFT_BUF;
|
||||
private String otherOptions = null;
|
||||
@@ -172,6 +174,20 @@ public class FTConfig {
|
||||
public int getSecondarySpace() { return secondarySpace; }
|
||||
public void setSecondarySpace(int secondarySpace) { this.secondarySpace = secondarySpace; }
|
||||
|
||||
public int getDirectoryBlocks() { return directoryBlocks; }
|
||||
public void setDirectoryBlocks(int directoryBlocks) { this.directoryBlocks = Math.max(0, directoryBlocks); }
|
||||
public void setDirectoryBlocks(String dir) {
|
||||
if (dir == null || dir.trim().isEmpty()) {
|
||||
this.directoryBlocks = 0;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.directoryBlocks = Math.max(0, Integer.parseInt(dir.trim()));
|
||||
} catch (NumberFormatException e) {
|
||||
this.directoryBlocks = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int getAvblock() { return avblock; }
|
||||
public void setAvblock(int avblock) { this.avblock = avblock; }
|
||||
|
||||
@@ -217,9 +233,9 @@ public class FTConfig {
|
||||
this.recfm = RecordFormat.DEFAULT;
|
||||
} else {
|
||||
String u = r.trim().toUpperCase();
|
||||
if (u.equals("F") || u.startsWith("FIXED")) this.recfm = RecordFormat.FIXED;
|
||||
else if (u.equals("V") || u.startsWith("VAR")) this.recfm = RecordFormat.VARIABLE;
|
||||
else if (u.equals("U") || u.startsWith("UNDEF")) this.recfm = RecordFormat.UNDEFINED;
|
||||
if (u.startsWith("F") || u.startsWith("FIXED")) this.recfm = RecordFormat.FIXED;
|
||||
else if (u.startsWith("V") || u.startsWith("VAR")) this.recfm = RecordFormat.VARIABLE;
|
||||
else if (u.startsWith("U") || u.startsWith("UNDEF")) this.recfm = RecordFormat.UNDEFINED;
|
||||
else this.recfm = RecordFormat.DEFAULT;
|
||||
}
|
||||
}
|
||||
@@ -233,14 +249,23 @@ public class FTConfig {
|
||||
}
|
||||
|
||||
public void setSpace(String s) {
|
||||
// Space string like "10,5" for primary/secondary
|
||||
// Space string like "10,5" or "10,5,10" for primary/secondary/directory
|
||||
if (s == null || s.trim().isEmpty()) return;
|
||||
String[] parts = s.split(",");
|
||||
try {
|
||||
if (parts.length > 0) this.primarySpace = Integer.parseInt(parts[0].trim());
|
||||
if (parts.length > 1) this.secondarySpace = Integer.parseInt(parts[1].trim());
|
||||
} catch (NumberFormatException e) {
|
||||
// ignore
|
||||
if (parts.length > 0 && !parts[0].trim().isEmpty()) {
|
||||
this.primarySpace = Integer.parseInt(parts[0].trim());
|
||||
if (this.units == AllocationUnit.DEFAULT) {
|
||||
this.units = AllocationUnit.TRACKS;
|
||||
}
|
||||
}
|
||||
if (parts.length > 1 && !parts[1].trim().isEmpty()) {
|
||||
this.secondarySpace = Integer.parseInt(parts[1].trim());
|
||||
}
|
||||
if (parts.length > 2 && !parts[2].trim().isEmpty()) {
|
||||
this.directoryBlocks = Math.max(0, Integer.parseInt(parts[2].trim()));
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,6 +304,22 @@ public class FTConfig {
|
||||
if (spaceMatcher.group(2) != null) {
|
||||
this.secondarySpace = Integer.parseInt(spaceMatcher.group(2));
|
||||
}
|
||||
if (spaceMatcher.group(3) != null) {
|
||||
this.directoryBlocks = Math.max(0, Integer.parseInt(spaceMatcher.group(3)));
|
||||
}
|
||||
if (this.units == AllocationUnit.DEFAULT) {
|
||||
this.units = AllocationUnit.TRACKS;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
Matcher dirMatcher = DIR_PATTERN.matcher(trimmed);
|
||||
if (dirMatcher.find()) {
|
||||
try {
|
||||
this.directoryBlocks = Math.max(0, Integer.parseInt(dirMatcher.group(1)));
|
||||
if (this.units == AllocationUnit.DEFAULT) {
|
||||
this.units = AllocationUnit.TRACKS;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
|
||||
@@ -568,14 +609,18 @@ public class FTConfig {
|
||||
opts.append(" BLKSIZE(").append(blksize).append(")");
|
||||
}
|
||||
}
|
||||
if (units != AllocationUnit.DEFAULT) {
|
||||
if (units != AllocationUnit.DEFAULT || primarySpace > 0 || directoryBlocks > 0) {
|
||||
AllocationUnit effectiveUnits = (units != AllocationUnit.DEFAULT) ? units : AllocationUnit.TRACKS;
|
||||
if (opts.length() > 0) opts.append(" ");
|
||||
opts.append("SPACE(").append(primarySpace);
|
||||
if (secondarySpace > 0) {
|
||||
if (secondarySpace > 0 || directoryBlocks > 0) {
|
||||
opts.append(",").append(secondarySpace);
|
||||
}
|
||||
if (directoryBlocks > 0) {
|
||||
opts.append(",").append(directoryBlocks);
|
||||
}
|
||||
opts.append(")");
|
||||
switch (units) {
|
||||
switch (effectiveUnits) {
|
||||
case TRACKS: opts.append(" TRACKS"); break;
|
||||
case CYLINDERS: opts.append(" CYLINDERS"); break;
|
||||
case AVBLOCK: opts.append(" AVBLOCK(").append(avblock).append(")"); break;
|
||||
|
||||
@@ -17,7 +17,7 @@ public class CMSDirectoryParser {
|
||||
return entries;
|
||||
}
|
||||
|
||||
String[] lines = text.split("\r?\n");
|
||||
String[] lines = splitIntoLines(text);
|
||||
|
||||
for (String line : lines) {
|
||||
String trimmed = line.trim();
|
||||
@@ -26,6 +26,7 @@ public class CMSDirectoryParser {
|
||||
|
||||
String upper = trimmed.toUpperCase();
|
||||
if (upper.startsWith("FILENAME") || upper.startsWith("DIRECTORY") || upper.startsWith("FILELIST")) continue;
|
||||
if (upper.startsWith("READY;") || upper.equals("READY") || upper.startsWith("MORE...") || upper.startsWith("HOLDING")) continue;
|
||||
|
||||
CMSDirectoryEntry entry = parseCmsLine(trimmed);
|
||||
if (entry != null) {
|
||||
@@ -36,6 +37,24 @@ public class CMSDirectoryParser {
|
||||
return entries;
|
||||
}
|
||||
|
||||
private static String[] splitIntoLines(String text) {
|
||||
if (text.contains("\n") || text.contains("\r")) {
|
||||
return text.split("\r?\n");
|
||||
}
|
||||
if (text.length() >= 80) {
|
||||
int lineLen = (text.length() % 132 == 0 && text.length() % 80 != 0) ? 132 : 80;
|
||||
int numLines = (text.length() + lineLen - 1) / lineLen;
|
||||
String[] lines = new String[numLines];
|
||||
for (int i = 0; i < numLines; i++) {
|
||||
int start = i * lineLen;
|
||||
int end = Math.min(start + lineLen, text.length());
|
||||
lines[i] = text.substring(start, end);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
return new String[]{text};
|
||||
}
|
||||
|
||||
private static CMSDirectoryEntry parseCmsLine(String line) {
|
||||
String[] tokens = line.split("\\s+");
|
||||
if (tokens.length < 2) return null;
|
||||
|
||||
@@ -27,7 +27,7 @@ public class TSODirectoryParser {
|
||||
return entries;
|
||||
}
|
||||
|
||||
String[] lines = text.split("\r?\n");
|
||||
String[] lines = splitIntoLines(text);
|
||||
|
||||
// Check if text is LISTCAT format
|
||||
if (text.toUpperCase().contains("NONVSAM") || text.toUpperCase().contains("IN-CAT")) {
|
||||
@@ -39,7 +39,8 @@ public class TSODirectoryParser {
|
||||
for (String line : lines) {
|
||||
String trimmed = line.trim();
|
||||
if (trimmed.isEmpty()) continue;
|
||||
if (trimmed.startsWith("--") || trimmed.startsWith("==") || trimmed.startsWith("**")) continue;
|
||||
if (trimmed.startsWith("--") || trimmed.startsWith("==") || trimmed.startsWith("**") || trimmed.startsWith("***")) continue;
|
||||
if (trimmed.equalsIgnoreCase("READY") || trimmed.toUpperCase().startsWith("READY;")) continue;
|
||||
if (trimmed.toUpperCase().startsWith("COMMAND") || trimmed.toUpperCase().startsWith("DSLIST") || trimmed.toUpperCase().startsWith("DATA SETS")) continue;
|
||||
|
||||
TSODirectoryEntry entry = parseTabularLine(trimmed);
|
||||
@@ -51,6 +52,24 @@ public class TSODirectoryParser {
|
||||
return entries;
|
||||
}
|
||||
|
||||
private static String[] splitIntoLines(String text) {
|
||||
if (text.contains("\n") || text.contains("\r")) {
|
||||
return text.split("\r?\n");
|
||||
}
|
||||
if (text.length() >= 80) {
|
||||
int lineLen = (text.length() % 132 == 0 && text.length() % 80 != 0) ? 132 : 80;
|
||||
int numLines = (text.length() + lineLen - 1) / lineLen;
|
||||
String[] lines = new String[numLines];
|
||||
for (int i = 0; i < numLines; i++) {
|
||||
int start = i * lineLen;
|
||||
int end = Math.min(start + lineLen, text.length());
|
||||
lines[i] = text.substring(start, end);
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
return new String[]{text};
|
||||
}
|
||||
|
||||
private static void parseListcat(String[] lines, List<TSODirectoryEntry> entries) {
|
||||
TSODirectoryEntry current = null;
|
||||
for (String line : lines) {
|
||||
|
||||
@@ -37,6 +37,7 @@ public class FileTransferFileObject implements Serializable {
|
||||
private int blksize = 0;
|
||||
private int primarySpace = 0;
|
||||
private int secondarySpace = 0;
|
||||
private int directoryBlocks = 0;
|
||||
private int avblock = 0;
|
||||
private String options = "";
|
||||
|
||||
@@ -201,6 +202,14 @@ public class FileTransferFileObject implements Serializable {
|
||||
this.secondarySpace = secondarySpace;
|
||||
}
|
||||
|
||||
public int getDirectoryBlocks() {
|
||||
return directoryBlocks;
|
||||
}
|
||||
|
||||
public void setDirectoryBlocks(int directoryBlocks) {
|
||||
this.directoryBlocks = Math.max(0, directoryBlocks);
|
||||
}
|
||||
|
||||
public int getAvblock() {
|
||||
return avblock;
|
||||
}
|
||||
@@ -241,6 +250,7 @@ public class FileTransferFileObject implements Serializable {
|
||||
config.setBlksize(blksize);
|
||||
config.setPrimarySpace(primarySpace);
|
||||
config.setSecondarySpace(secondarySpace);
|
||||
config.setDirectoryBlocks(directoryBlocks);
|
||||
config.setAvblock(avblock);
|
||||
if (options != null && !options.isEmpty()) {
|
||||
config.parseOptions(options);
|
||||
@@ -263,6 +273,7 @@ public class FileTransferFileObject implements Serializable {
|
||||
this.blksize = config.getBlksize();
|
||||
this.primarySpace = config.getPrimarySpace();
|
||||
this.secondarySpace = config.getSecondarySpace();
|
||||
this.directoryBlocks = config.getDirectoryBlocks();
|
||||
this.avblock = config.getAvblock();
|
||||
}
|
||||
|
||||
|
||||
@@ -603,10 +603,73 @@ public class Xfer3270 implements FileTransferInterface {
|
||||
if (callback != null) callback.setStatus(FileTransferHostDirectoryInterface.STATUS_PROCESSING);
|
||||
Vector result = new Vector();
|
||||
|
||||
String dataToParse = hostQuery;
|
||||
if (hostQuery == null || (!hostQuery.contains("\n") && !hostQuery.contains("\r")
|
||||
&& !hostQuery.toUpperCase().contains("NONVSAM") && !hostQuery.toUpperCase().contains("IN-CAT")
|
||||
&& !hostQuery.toUpperCase().contains("FORMAT"))) {
|
||||
if (session != null && session.getPS() != null) {
|
||||
try {
|
||||
ECLPS ps = session.getPS();
|
||||
ps.SendKeys("[clear]");
|
||||
if (session.getOIA() != null) {
|
||||
session.getOIA().waitForInput(3000);
|
||||
}
|
||||
if (hostType == VM_CMS) {
|
||||
String filter = (hostQuery != null && !hostQuery.trim().isEmpty()) ? hostQuery.trim() : "* * *";
|
||||
ps.SendKeys("LISTFILE " + filter + " ( nohead alloc date[enter]");
|
||||
} else {
|
||||
String filter = (hostQuery != null && !hostQuery.trim().isEmpty()) ? hostQuery.trim() : "";
|
||||
if (filter.isEmpty()) {
|
||||
ps.SendKeys("LISTCAT[enter]");
|
||||
} else {
|
||||
if (!filter.startsWith("'")) filter = "'" + filter + "'";
|
||||
ps.SendKeys("LISTCAT LEVEL(" + filter + ")[enter]");
|
||||
}
|
||||
}
|
||||
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
|
||||
if (session.getOIA() != null) {
|
||||
session.getOIA().waitForInput(5000);
|
||||
}
|
||||
StringBuilder sbAll = new StringBuilder();
|
||||
for (int page = 0; page < 20; page++) {
|
||||
int rows = ps.getRows();
|
||||
int cols = ps.getCols();
|
||||
String screen = ps.copyString(0, 0, rows - 1, cols - 1);
|
||||
sbAll.append(screen).append("\n");
|
||||
|
||||
boolean hasMore = false;
|
||||
if (hostType == VM_CMS) {
|
||||
if (screen.contains("MORE...") || screen.contains("HOLDING")) {
|
||||
hasMore = true;
|
||||
ps.SendKeys("[enter]");
|
||||
}
|
||||
} else {
|
||||
if (screen.contains("***")) {
|
||||
hasMore = true;
|
||||
ps.SendKeys("[enter]");
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMore) {
|
||||
try { Thread.sleep(100); } catch (InterruptedException ignored) {}
|
||||
if (session.getOIA() != null) {
|
||||
session.getOIA().waitForInput(3000);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
dataToParse = sbAll.toString();
|
||||
} catch (Exception ignored) {
|
||||
// Fall back to hostQuery
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (hostType == VM_CMS) {
|
||||
if (callback != null) callback.setStatus(FileTransferHostDirectoryInterface.STATUS_RECEIVING);
|
||||
List<CMSDirectoryEntry> cmsEntries = CMSDirectoryParser.parse(hostQuery);
|
||||
List<CMSDirectoryEntry> cmsEntries = CMSDirectoryParser.parse(dataToParse);
|
||||
for (CMSDirectoryEntry entry : cmsEntries) {
|
||||
String hName = entry.getFilename() + " " + entry.getFiletype();
|
||||
String lName = entry.getFilename() + "." + entry.getFiletype();
|
||||
@@ -622,7 +685,7 @@ public class Xfer3270 implements FileTransferInterface {
|
||||
}
|
||||
} else {
|
||||
if (callback != null) callback.setStatus(FileTransferHostDirectoryInterface.STATUS_RECEIVING);
|
||||
List<TSODirectoryEntry> tsoEntries = TSODirectoryParser.parse(hostQuery);
|
||||
List<TSODirectoryEntry> tsoEntries = TSODirectoryParser.parse(dataToParse);
|
||||
for (TSODirectoryEntry entry : tsoEntries) {
|
||||
String name = entry.getName();
|
||||
if (hostFiles != null) hostFiles.addElement(name);
|
||||
|
||||
Reference in New Issue
Block a user