00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 package wttools.remotecons;
00024
00025 import java.net.Socket;
00026 import java.net.SocketException;
00027 import java.io.PrintWriter;
00028 import java.io.BufferedReader;
00029 import java.io.IOException;
00030 import java.io.InputStreamReader;
00031 import java.io.File;
00032 import java.io.FileReader;
00033 import java.io.ByteArrayOutputStream;
00034 import java.util.List;
00035 import java.util.ArrayList;
00036 import java.util.Collections;
00037 import java.util.StringTokenizer;
00038 import java.util.Date;
00039 import java.text.DateFormat;
00040 import wttools.remotecons.ifc.CommandHandlerIfc;
00041 import wttools.remotecons.ifc.LogIfc;
00042
00066 public class ConnectionServer extends Thread {
00067
00075 protected static List active_connections =
00076 Collections.synchronizedList(new ArrayList());
00084 protected Socket my_socket = null;
00090 protected BufferedReader inst = null;
00096 protected PrintWriter out = null;
00106 protected List comm_handl = null;
00113 protected LogIfc log_impl = null;
00124 protected boolean prompt = true;
00142 protected boolean echo = true;
00143
00153 public ConnectionServer(Socket socket, List command_handlers)
00154 throws IOException
00155 {
00156 comm_handl = command_handlers;
00157 if (comm_handl == null) {
00158 comm_handl = new ArrayList();
00159 }
00160 comm_handl.add(0, new CommandHandlerImpl());
00161 comm_handl.add(0, new InternalCommands());
00162
00163 my_socket = socket;
00164 inst =
00165 new BufferedReader(new InputStreamReader(my_socket.getInputStream()));
00166 out = new PrintWriter(my_socket.getOutputStream(), true);
00167 setDaemon(true);
00168 start();
00169 active_connections.add(this);
00170 }
00171
00177 public void run() {
00178 log("Connection server started for client: "+my_socket.getInetAddress().getHostAddress());
00179 while (inst != null) {
00180 try {
00181 if (prompt) {
00182 out.print(my_socket.getLocalAddress().getHostAddress()+" << "); out.flush();
00183 }
00184 String line = "";
00185 if (echo) {
00186 char chr = (char)inst.read();
00187 while (chr != '\n') {
00188 if (chr != '\r') {
00189 line += chr;
00190 }
00191 out.print(chr); out.flush();
00192 chr = (char)inst.read();
00193 }
00194 out.print(chr); out.flush();
00195 }
00196 else {
00197 line = inst.readLine();
00198 }
00199
00200 log("Received command: "+line);
00201 if (!processCommand(line) && out != null && !line.equals("")) {
00202 out.println(getClass().getName()+" >> Command '"+line+"' not understood.");
00203 }
00204 }
00205 catch (SocketException e) {
00206
00207 out = null;
00208 inst = null;
00209 my_socket = null;
00210 }
00211 catch (IOException e) {
00212 e.printStackTrace();
00213 out = null;
00214 inst = null;
00215 my_socket = null;
00216 }
00217 }
00218 active_connections.remove(this);
00219 }
00220
00235 protected void asyncMessage(String msg) {
00236 out.print(msg); out.flush();
00237 }
00238
00247 protected boolean processCommand(String line) {
00248 boolean comm_found = false;
00249 for (int i = 0; i < comm_handl.size(); i++) {
00250 String res = ((CommandHandlerIfc)comm_handl.get(i)).handleCommand(line);
00251 if (res != null && !res.equals("")) {
00252 if (out != null) {
00253 out.print(res); out.flush();
00254 }
00255 prompt = res.endsWith("\r\n");
00256 comm_found = true;
00257 }
00258 }
00259 return comm_found;
00260 }
00261
00267 protected void log(String msg) {
00268 if (log_impl != null) {
00269 log_impl.log(msg);
00270 }
00271 }
00272
00280 class InternalCommands implements CommandHandlerIfc {
00281
00282 protected String last_command = null;
00283
00284 public String handleCommand(String comm) {
00285 String ret_res = null;
00286 if (comm.trim().startsWith("echo")) {
00287 echo = !echo;
00288 ret_res = "Echo your command is now in '"+echo+"' mode\r\n";
00289 }
00290 if (comm.equals("quit")) {
00291 ret_res = "OK";
00292 log("'quit' received, closing connection...");
00293 out.println("Bye");
00294 out.close();
00295 out = null;
00296 try {
00297 inst.close();
00298 inst = null;
00299 my_socket.close();
00300 my_socket = null;
00301 } catch (Exception e) {
00302 e.printStackTrace();
00303 out = null;
00304 inst = null;
00305 my_socket = null;
00306 }
00307 }
00308 if (comm.startsWith("help")) {
00309 ret_res = "";
00310 if (comm.trim().equals("help")) {
00311 for (int i = 0; i < comm_handl.size(); i++) {
00312 String res = ((CommandHandlerIfc)comm_handl.get(i)).help();
00313 ret_res += comm_handl.get(i).getClass().getName()+" >> "+res;
00314 }
00315 }
00316 else {
00317 for (int i = 0; i < comm_handl.size(); i++) {
00318 String res = ((CommandHandlerIfc)comm_handl.get(i)).help(comm.substring(5));
00319 ret_res += comm_handl.get(i).getClass().getName()+" >> "+res;
00320 }
00321 }
00322 }
00323 if (comm.trim().equals("who")) {
00324 ret_res = "\r\n";
00325 for (int i = 0; i < active_connections.size(); i++) {
00326 ConnectionServer cs = (ConnectionServer)active_connections.get(i);
00327 if (cs.my_socket == my_socket) {
00328 ret_res += "this: ";
00329 }
00330 else {
00331 ret_res += "other: ";
00332 }
00333 ret_res += ""+i+". "+cs.my_socket+"\r\n";
00334 }
00335 }
00336 if (comm.trim().startsWith("ls")) {
00337 StringTokenizer stt = null;
00338 if (comm.trim().length() > 2) {
00339 stt = new StringTokenizer(comm.substring(2));
00340 }
00341 else {
00342 stt = new StringTokenizer(".");
00343 }
00344 while (stt.hasMoreTokens()) {
00345 File dir = new File(stt.nextToken());
00346 File[] files = dir.listFiles();
00347 if (files != null && files.length > 0) {
00348 for (int i = 0; i < files.length; i++) {
00349 out.println(buildFileString(files[i]));
00350 }
00351 out.println("\r\ntotal "+files.length);
00352 }
00353 else {
00354 out.println(dir.toString()+" is not a directory or");
00355 out.println("this directory does not contains any antries.");
00356 }
00357 }
00358 ret_res = "\r\n";
00359 }
00360 if (comm.trim().startsWith("show")) {
00361 if (comm.trim().length() < 5) {
00362 ret_res = "Wrong number of arguments. I need file name here.\r\n";
00363 }
00364 else {
00365 StringTokenizer stt = new StringTokenizer(comm.substring(5));
00366 while (stt.hasMoreTokens()) {
00367 File ff = new File(stt.nextToken());
00368 if (ff.exists()) {
00369 try {
00370 BufferedReader brin = new BufferedReader(new FileReader(ff));
00371 String line = brin.readLine();
00372 while (line != null) {
00373 out.println(line);
00374 line = brin.readLine();
00375 }
00376 brin.close();
00377 ret_res = " ----- End of file "+ff.toString()+" -----\r\n";
00378 } catch (Exception e) {
00379 ByteArrayOutputStream baos = new ByteArrayOutputStream();
00380 PrintWriter pw = new PrintWriter(baos, false);
00381 e.printStackTrace(pw);
00382 pw.flush();
00383 ret_res = baos.toString();
00384 pw.close();
00385 }
00386 }
00387 else {
00388 ret_res = "File "+ff.toString()+" does not exists!\r\n";
00389 }
00390 }
00391 }
00392 }
00393 if (comm.trim().startsWith("close")) {
00394 int no = -1;
00395 try {
00396 no = Integer.parseInt(comm.substring(6).trim());
00397 if (no >= 0 && no < active_connections.size()) {
00398 ConnectionServer cs = (ConnectionServer)active_connections.get(no);
00399 out.print("closing "+cs.my_socket+" ... "); out.flush();
00400 cs.processCommand("quit");
00401 active_connections.remove(cs);
00402 ret_res = "OK\r\n";
00403 }
00404 else {
00405 ret_res = "Argument out of range. Check valid ranges with 'who' command.";
00406 }
00407 }
00408 catch (StringIndexOutOfBoundsException e) {
00409 ret_res = "Wrong number of arguments. I need integer number here.";
00410 }
00411 catch (NumberFormatException e) {
00412 ret_res = "Bad argument to 'close' command. I need integer number here.";
00413 }
00414 }
00415 return ret_res;
00416 }
00417
00418 protected String buildFileString(File ff) {
00419 StringBuffer res = new StringBuffer(80);
00420 res.append(setForTrueOrFalse(ff.isDirectory(), "d", "-"));
00421 res.append(setForTrueOrFalse(ff.canRead(), "r", "-"));
00422 res.append(setForTrueOrFalse(ff.canWrite(), "w", "-"));
00423 res.append(setForTrueOrFalse(ff.isHidden(), "h", "-"));
00424 res.append(" "+ff.length());
00425 while (res.length() < 17) {
00426 res.append(' ');
00427 }
00428 DateFormat dt = DateFormat.getDateInstance();
00429 res.append(" "+dt.format(new Date(ff.lastModified())));
00430 res.append(" "+ff.getName());
00431 res.append(setForTrueOrFalse(ff.isDirectory(), "/", ""));
00432 return res.toString();
00433 }
00434
00435 protected String setForTrueOrFalse(boolean cond, String for_true, String for_false) {
00436 if (cond) {
00437 return for_true;
00438 }
00439 else {
00440 return for_false;
00441 }
00442 }
00443
00444 public String help() {
00445 String help_text =
00446 "\r\n"+
00447 " echo - switch 'echo' mode (for windows telnet is really needed)\r\n"+
00448 " quit - close connection to server\r\n"+
00449 " who - list all active connections\r\n"+
00450 " close n - close active connection number 'n'\r\n"+
00451 " help [command] - display this message info\r\n"+
00452 " ls [dir]* - list content of given directory\r\n"+
00453 " show filename - display content of given file\r\n";
00454 return help_text;
00455 }
00456
00457 public String help(String command) {
00458 return "";
00459 }
00460
00461 public CommandHandlerIfc getInstance() {
00462 return new InternalCommands();
00463 }
00464
00465 }
00466
00467
00468 }
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517