Java FTP LIST command - java

Hello I am in the process of making a FTP client for a uni project and before starting I am experimenting with the basic commands of the FTP protocol. So far I have been able to login successfully to a FTP server. Now, what I want to do is to list the root directory in order to get it's contents.
I have implemented this method to do what I describe but I can't seem to make it work. As far as I can tell it does go into passive mode, but when I issue the list command nothing happens. I cannot understand why this is happening. Can anyone help?
Here is the code in question:
public synchronized boolean list() throws IOException{
sendLine("PASV");
String response = readLine();
if(!response.startsWith("227 "))
throw new IOException("Could not request PASSIVE mode: " + response);
String ip = null;
int port = -1;
int opening = response.indexOf('(');
int closing = response.indexOf(')', opening + 1);
if(closing > 0){
String dataLink = response.substring(opening + 1, closing);
StringTokenizer tokenizer = new StringTokenizer(dataLink, ",");
try{
ip = tokenizer.nextToken() + "." + tokenizer.nextToken() + "." + tokenizer.nextToken() + "." + tokenizer.nextToken();
port = Integer.parseInt(tokenizer.nextToken()) * 256 + Integer.parseInt(tokenizer.nextToken());
}catch(Exception e){
throw new IOException("Received bad data information: " + response);
}
}
sendLine("LIST");
response = readLine();
return (response.startsWith("200 "));
}

Related

Win32Exception: The parameter is incorrect

I am making an application that displays ur saved browser password(s) (right now I'm using Google Chrome) in an easy way. Everytime I run this code I get an error at byte[] newbyte = Crypt32Util.cryptUnprotectData(mybyte);. The code used is written below. This code provides some context. I never had this problem and after some research I can't find a clear solution. I hope someone can help me with it.
Code:
Connection connection = null;
connection = DriverManager.getConnection("jdbc:sqlite:" + path_to_copied_db);
PreparedStatement statement = connection.prepareStatement("SELECT `origin_url`,`username_value`,`password_value` FROM `logins`");
ResultSet re = statement.executeQuery();
StringBuilder builder = new StringBuilder();
while (re.next()) {
String pass = "";
try {
byte[] mybyte = (byte[])re.getBytes("password_value");
byte[] newbyte = Crypt32Util.cryptUnprotectData(mybyte); //Error on this line:71
pass = new String(newbyte);
}catch(Win32Exception e){
e.printStackTrace();
}
builder.append(user + ": " + re.getString("origin_url") + " " + re.getString("username_value") + " " + re.getBinaryStream("password_value") + "\n");
}
Error:
com.sun.jna.platform.win32.Win32Exception: The parameter is incorrect.
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:128)
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:103)
at com.sun.jna.platform.win32.Crypt32Util.cryptUnprotectData(Crypt32Util.java:90)
at Client.Client.main(Client.java:71)

What is a good way to handle command read from user and server's response in a remote command-line interpreter?

I'm implementing a client side software that lets user input commands, sends them to a server, the server interprets them and sends the result to the client. Here's where I'm stuck, I have a while loop that gets responses from server until the connection ends.
try(Socket socket = new Socket(hostname, port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))){
System.out.println("Connected to " + hostname + ":" + port + " !");
Scanner scanner = new Scanner(System.in);
String command = scanner.nextLine();
String fromServer = null;
int status;
HashMap<String, String> response;
long start = 0;
System.out.println("C:" + command);
if (command.toLowerCase().equals("exit")) return;
out.println(command);
if (command.toLowerCase().equals("shutdown")) return;
out.println();
while ((fromServer = in.readLine()) != null) {
// Here's my problem
response = parseResponse(fromServer);
if (response.containsKey("response")) response.put("response", response.get("response").replaceAll("\\\\n", "\n"));
try {
status = Integer.parseInt(response.get("status"));
} catch (NumberFormatException e){
status = Status.RESPONSE_CORRUPTED;
}
System.out.println("S:" + status + (response.get("response") != null ? "\n" + response.get("response") : ""));
command = scanner.nextLine();
System.out.println("C:" + command);
out.println(command);
}
} catch (IOException e){
System.out.println("Server isn't connected, try again later.");
}
The real problem is that I need to put
if (command.toLowerCase().equals("exit")) return;
out.println(command);
if (command.toLowerCase().equals("shutdown")) return;
out.println();
before the while, so there's three out.println() in the code while one would be more "logic" and I need to put
if (command.toLowerCase().startsWith("shutdown") && fromServer.equalsIgnoreCase("0") || status == Status.RESPONSE_CORRUPTED) break;
in that while so the client stops directly when the command shutdown is sent (to shutdown the server) to prevent the user from entering another command.
I'm searching for a more efficient way to manage commands and to add a ping command (but I need to add an if before the one to shutdown), maybe using more OOP but I don't see how to do it.
I think you should give a try to Spring Shell first before attempting to make your own from scratch. It is quite modular and you can create the backend handlers that send the commands to the remote server.
Use an infinite loop and break it based on the user input or on the server response
Here is an example which does not send the exit/shutdown commands to the server, but rather they only stop the client. If you need to send all the commands to the server and stop only based on the server response then just delete the if statement from the while loop
Scanner scanner = new Scanner(System.in);
String command = null;
while (true) {
command = scanner.nextLine();
if (command.toLowerCase().equals("exit") || command.toLowerCase().equals("shutdown")) {
break;
}
out.print(command);
out.flush();
String response = in.readLine();
// do something with the response (ex. stop the client by calling break or just print the response
}

OutputStream.write only writing part of a String in Java

I'm working on a Java-based IRC client as a way to learn both Java and more about writing networked applications.
The client I've designed mostly works, except when I post a message. The message goes through alright, but only up to the first space. I've tried everything: I've dumped my text into a StringArray, into a byte array, in a loop. But each time, only the first word of the intended message gets posted.
Here's the part of the code that I believe is relevant, although I'm happy to post the entire code if necessary (it's only a few hundred lines, and I can cut out the unimportant parts):
public void send(String msg) throws UnsupportedEncodingException {
if ( ! msg.startsWith("/")) {
msg = ("PRIVMSG " + chan + " " + msg);
// DEBUG confirm that msg == command+chan+userText
System.out.println(msg);
} else if ( msg.toUpperCase().startsWith("/JOIN ")) {
// System.out.println("\nJoin mode");
chan = msg.substring(6);
msg = (msg.toUpperCase().substring(1) + "\r\n");
} else { // some other command
msg = (msg.toUpperCase().substring(1) + "\r\n");
}
System.out.println(msg);
ostream.print(msg + " \r\n"); // doesn't work
ostream.flush();
}
}
I have also tried this sort of thing:
CRS = msg.split("\\s+");
CharSequence chars = msg;
ostream.printf( "%s,\r\n", msg); // doesn't work
ostream.print( String.join(" ", CRS) + "\r\n" ); // nope
And this:
ostream.append(chars);
ostream.append("\r\n"); // nope
I've also tried all of the above with byte arrays.
This sort of thing, however, does work:
// this, however, works as expected
void pong(String ping) {
String msg = "PONG " + ping;
byte[] bs = null;
bs = (msg.substring(1) + "\r\n").getBytes();
try {
ostream.write(bs);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I've also tried changing my OutputStream object (the connection to the IRC server) to a PrintStream. Same results.
What about OutputStream am I not comprehending?
The IRC protocol requires you to escape messages that contain spaces with a preceding colon (":"). I think your code actually works, you've just not implemented the IRC protocol correctly.
Try making your PRIVMSG command:
msg = ("PRIVMSG " + chan + " :" + msg);
Only the first word is appearing because the IRC server ignores the trailing content after the first space. A valid message should look like:
PRIVMSG #target :Hello, world

whois in java for Android

I'm making a whois in java for android to train about streams and tcp connections.
But I have a problem. I have a php script, I wrote some time ago and I´m trying to make the same in java.
this is my java code :
public String consultawhois(String domain,String tld)
{
String domquest = domain + "." + tld;
String resultado = "";
Socket theSocket;
String hostname = "whois.internic.net";
int port = 43;
try {
theSocket = new Socket(hostname, port, true);
Writer out = new OutputStreamWriter(theSocket.getOutputStream());
out.write(domquest + "\r\n");
out.flush();
DataInputStream theWhoisStream;
theWhoisStream = new DataInputStream(theSocket.getInputStream());
String s;
while ((s = theWhoisStream.readLine()) != null) {
resultado = resultado + s + "\n";
}
}
catch (IOException e) {
}
return resultado;
}
The answer of the server is not correct and I think the problem is that I'm sending a bad query. The query I send is "dominio.com\r\n" and in my php whois code, it works perfectly.
It seems that the DNS query matches multiple records. At least, that is how I interpret the response. In the returned reponse you should see the following line:
To single out one record, look it up with "xxx", where xxx is one of the
of the records displayed above. If the records are the same, look them up
with "=xxx" to receive a full display for each record.
So if you prepend the query with "=" it returns the data of that record only. The following worked for me.
public String consultawhois(String domain,String tld)
{
String domquest = domain + "." + tld;
String resultado = "";
Socket theSocket;
String hostname = "whois.internic.net";
int port = 43;
try {
theSocket = new Socket(hostname, port, true);
Writer out = new OutputStreamWriter(theSocket.getOutputStream());
out.write("="+domquest + "\r\n");
out.flush();
DataInputStream theWhoisStream;
theWhoisStream = new DataInputStream(theSocket.getInputStream());
String s;
while ((s = theWhoisStream.readLine()) != null) {
resultado = resultado + s + "\n";
}
}
catch (IOException e) {
}
return resultado;
}
One thing to consider: Use English for method names, variables, etc. instead of Spanish. It will make your code easier to read internationally. The programming language itself also uses English words. Try to avoid a strange mix of English and your native language.
The lookup for dominio.com results in three matches:
DOMINIO.COM.BR
DOMINIO.COM.ASCPROBIENESTARIDSS.COM
DOMINIO.COM
You should specify wich one you are interested in with the query.
=dominio.com<newline>
This will allways work, even cases where there are no multiple matches.

Problem with FTPClient class in java

I'm using org.apache.commons.net.ftp.FTPClient and seeing behavior that is, well... perplexing.
The method beneath intends to go through an FTPFile list, read them in and then do something with the contents. That's all working. What is not (really) working is that the FTPClient object does the following...
1) Properly retrieves and stores the FIRST file in the list
2) List item evaluates to NULL for x number of successive iterations of the loop (x varies on successive attempts
3) manages to retrieve exactly 1 more file in the list
4) reports that it is null for exactly 1 more file in the list
5) hangs indefinitely, reporting no further activity.
public static String mergeXMLFiles(List<FTPFile> files, String rootElementNodeName, FTPClient ftp){
String ret = null;
String fileAsString = null;
//InputStream inStream;
int c;
if(files == null || rootElementNodeName == null)
return null;
try {
System.out.println("GETTING " + files.size() + " files");
for (FTPFile file : files) {
fileAsString = "";
InputStream inStream = ftp.retrieveFileStream(file.getName());
if(inStream == null){
System.out.println("FtpUtil.mergeXMLFiles() couldn't initialize inStream for file:" + file.getName());
continue;//THIS IS THE PART THAT I SEE FOR files [1 - arbitrary number (usually around 20)] and then 1 more time for [x + 2] after [x + 1] passes successfully.
}
while((c = inStream.read()) != -1){
fileAsString += Character.valueOf((char)c);
}
inStream.close();
System.out.println("FILE:" + file.getName() + "\n" + fileAsString);
}
} catch (Exception e) {
System.out.println("FtpUtil.mergeXMLFiles() failed:" + e);
}
return ret;
}
has anyone seen anything like this? I'm new to FTPClient, am I doing something wrong with it?
According to the API for FTPClient.retrieveFileStream(), the method returns null when it cannot open the data connection, in which case you should check the reply code (e.g. getReplyCode(), getReplyString(), getReplyStrings()) to see why it failed. Also, you are suppose to finalize file transfers by calling completePendingCommand() and verifying that the transfer was indeed successful.
It works ok when I add after the "retrieve" command :
int response = client.getReply();
if (response != FTPReply.CLOSING_DATA_CONNECTION){
//TODO
}

Categories

Resources