001: /*
002: * This program is free software; you can redistribute it and/or
003: * modify it under the terms of the GNU General Public License
004: * as published by the Free Software Foundation; either version 2
005: * of the License, or (at your option) any later version.
006: *
007: * This program is distributed in the hope that it will be useful,
008: * but WITHOUT ANY WARRANTY; without even the implied warranty of
009: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: * GNU General Public License for more details.
011: *
012: * You should have received a copy of the GNU General Public License
013: * along with this program; if not, write to the Free Software
014: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
015: */
016: package net.sf.jftp.net;
017:
018: import java.io.BufferedInputStream;
019: import java.io.BufferedOutputStream;
020: import java.io.File;
021: import java.io.FileInputStream;
022: import java.io.FileOutputStream;
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.io.StreamTokenizer;
026: import java.util.Date;
027: import java.util.Vector;
028:
029: import net.sf.jftp.config.Settings;
030: import net.sf.jftp.system.StringUtils;
031: import net.sf.jftp.system.logging.Log;
032:
033: import com.sun.xfile.XFile;
034: import com.sun.xfile.XFileInputStream;
035: import com.sun.xfile.XFileOutputStream;
036:
037: public class NfsConnection implements BasicConnection {
038: public static int buffer = 128000;
039: private String url = "";
040: private String host = "";
041: private String path = "";
042: private String pwd = "";
043: private Vector listeners = new Vector();
044: private String[] files;
045: private String[] size = new String[0];
046: private int[] perms = null;
047:
048: //private NfsHandler handler = new NfsHandler();
049: private String baseFile;
050: private int fileCount;
051: private boolean isDirUpload = false;
052: private boolean shortProgress = false;
053: private boolean dummy = false;
054:
055: public NfsConnection(String url) {
056: this .url = url;
057:
058: host = url.substring(6);
059:
060: int x = host.indexOf("/");
061:
062: if (x >= 0) {
063: host = host.substring(0, x);
064: }
065:
066: Log.out("nfs host is: " + host);
067: }
068:
069: public boolean login(String user, String pass) {
070: Log.out("nfs login called: " + url);
071:
072: try {
073: XFile xf = new XFile(url);
074:
075: if (xf.exists()) {
076: Log.out("nfs url ok");
077: } else {
078: Log
079: .out("WARNING: nfs url not found, cennection will fail!");
080: }
081:
082: com.sun.nfs.XFileExtensionAccessor nfsx = (com.sun.nfs.XFileExtensionAccessor) xf
083: .getExtensionAccessor();
084:
085: //Log.out("nfs extension accessor: " + nfsx);
086: if (!nfsx.loginPCNFSD(host, user, pass)) {
087: Log.out("login failed!");
088:
089: return false;
090: } else {
091: Log.debug("Login successful...");
092: }
093: } catch (Exception e) {
094: e.printStackTrace();
095: }
096:
097: return true;
098: }
099:
100: public String[] getExports() throws Exception {
101: XFile xf = new XFile(url);
102: com.sun.nfs.XFileExtensionAccessor nfsx = (com.sun.nfs.XFileExtensionAccessor) xf
103: .getExtensionAccessor();
104:
105: String[] tmp = nfsx.getExports();
106:
107: if (tmp == null) {
108: return new String[0];
109: }
110:
111: for (int i = 0; i < tmp.length; i++) {
112: Log.out("nfs export found: " + tmp[i]);
113: }
114:
115: return tmp;
116: }
117:
118: public int removeFileOrDir(String file) {
119: try {
120: String tmp = toNFS(file);
121:
122: XFile f = new XFile(tmp);
123:
124: if (!f.getAbsolutePath().equals(f.getCanonicalPath())) {
125: Log.debug("WARNING: Skipping symlink, remove failed.");
126: Log
127: .debug("This is necessary to prevent possible data loss when removing those symlinks.");
128:
129: return -1;
130: }
131:
132: if (f.exists() && f.isDirectory()) {
133: cleanLocalDir(tmp);
134: }
135:
136: //System.out.println(tmp);
137: if (!f.delete()) {
138: return -1;
139: } else {
140: return 1;
141: }
142: } catch (IOException ex) {
143: Log.debug("Error: " + ex.toString());
144: ex.printStackTrace();
145: }
146:
147: return -1;
148: }
149:
150: private void cleanLocalDir(String dir) {
151: dir = toNFS(dir);
152:
153: if (dir.endsWith("\\")) {
154: Log.out("need to fix \\-problem!!!");
155: }
156:
157: if (!dir.endsWith("/")) {
158: dir = dir + "/";
159: }
160:
161: //String remoteDir = StringUtils.removeStart(dir,path);
162: //System.out.println(">>> " + dir);
163: XFile f2 = new XFile(dir);
164: String[] tmp = f2.list();
165:
166: if (tmp == null) {
167: return;
168: }
169:
170: for (int i = 0; i < tmp.length; i++) {
171: XFile f3 = new XFile(dir + tmp[i]);
172:
173: if (f3.isDirectory()) {
174: //System.out.println(dir);
175: cleanLocalDir(dir + tmp[i]);
176: f3.delete();
177: } else {
178: //System.out.println(dir+tmp[i]);
179: f3.delete();
180: }
181: }
182: }
183:
184: public void sendRawCommand(String cmd) {
185: }
186:
187: public void disconnect() {
188: }
189:
190: public boolean isConnected() {
191: return true;
192: }
193:
194: public String getPWD() {
195: String tmp = toNFS(pwd);
196:
197: if (!tmp.endsWith("/")) {
198: tmp = tmp + "/";
199: }
200:
201: return tmp;
202: }
203:
204: public boolean cdup() {
205: String tmp = pwd;
206:
207: if (pwd.endsWith("/") && !pwd.equals("nfs://")) {
208: tmp = pwd.substring(0, pwd.lastIndexOf("/"));
209: }
210:
211: return chdir(tmp.substring(0, tmp.lastIndexOf("/") + 1));
212: }
213:
214: public boolean mkdir(String dirName) {
215: if (!dirName.endsWith("/")) {
216: dirName = dirName + "/";
217: }
218:
219: dirName = toNFS(dirName);
220:
221: File f = new File(dirName);
222:
223: boolean x = f.mkdir();
224: fireDirectoryUpdate();
225:
226: return x;
227: }
228:
229: public void list() throws IOException {
230: }
231:
232: public boolean chdir(String p) {
233: return chdir(p, true);
234: }
235:
236: public boolean chdir(String p, boolean refresh) {
237: if (p.endsWith("..")) {
238: return cdup();
239: }
240:
241: String tmp = toNFS(p);
242:
243: if (!tmp.endsWith("/")) {
244: tmp = tmp + "/";
245: }
246:
247: if (check(tmp) < 3) {
248: return false;
249: }
250:
251: pwd = tmp;
252:
253: if (refresh) {
254: fireDirectoryUpdate();
255: }
256:
257: return true;
258: }
259:
260: private int check(String url) {
261: int x = 0;
262:
263: for (int j = 0; j < url.length(); j++) {
264: if (url.charAt(j) == '/') {
265: x++;
266: }
267: }
268:
269: return x;
270: }
271:
272: public boolean chdirNoRefresh(String p) {
273: /*
274: String p2 = toNFS(p);
275: if(p2 == null) return false;
276:
277: pwd = p2;
278:
279: return true;
280: */
281: return chdir(p, false);
282: }
283:
284: public String getLocalPath() {
285: //System.out.println("local: " + path);
286: return path;
287: }
288:
289: private String toNFS(String f) {
290: String file;
291:
292: if (f.lastIndexOf("nfs://") > 0) {
293: f = f.substring(f.lastIndexOf("nfs://"));
294: }
295:
296: if (f.startsWith("nfs://")) {
297: file = f;
298: } else {
299: file = getPWD() + f;
300: }
301:
302: file = file.replace('\\', '/');
303:
304: Log.out("nfs url: " + file);
305:
306: return file;
307: }
308:
309: public boolean setLocalPath(String p) {
310: if (!p.startsWith("/") && !p.startsWith(":", 1)) {
311: p = path + p;
312: }
313:
314: File f = new File(p);
315:
316: if (f.exists()) {
317: try {
318: path = f.getCanonicalPath();
319: path = path.replace('\\', '/');
320:
321: if (!path.endsWith("/")) {
322: path = path + "/";
323: }
324:
325: //System.out.println("2:"+path+":"+getPWD());
326: } catch (IOException ex) {
327: Log.debug("Error: can not get pathname (local)!");
328:
329: return false;
330: }
331: } else {
332: Log.debug("(local) No such path: \"" + p + "\"");
333:
334: return false;
335: }
336:
337: return true;
338: }
339:
340: public String[] sortLs() {
341: String dir = getPWD();
342:
343: if (check(toNFS(dir)) == 3) {
344: try {
345: files = getExports();
346: } catch (Exception ex) {
347: Log.debug("Can not list exports:" + ex.toString());
348: ex.printStackTrace();
349: }
350: } else {
351: XFile f = new XFile(dir);
352: files = f.list();
353: }
354:
355: if (files == null) {
356: return new String[0];
357: }
358:
359: size = new String[files.length];
360: perms = new int[files.length];
361:
362: int accessible = 0;
363:
364: for (int i = 0; i < files.length; i++) {
365: XFile f2 = new XFile(dir + files[i]);
366:
367: if (f2.isDirectory() && !files[i].endsWith("/")) {
368: files[i] = files[i] + "/";
369: }
370:
371: size[i] = "" + f2.length();
372:
373: if (f2.canWrite()) {
374: accessible = FtpConnection.W;
375: } else if (f2.canRead()) {
376: accessible = FtpConnection.R;
377: } else {
378: accessible = FtpConnection.DENIED;
379: }
380:
381: perms[i] = accessible;
382:
383: //System.out.println(pwd+files[i] +" : " +accessible + " : " + size[i]);
384: }
385:
386: return files;
387: }
388:
389: public String[] sortSize() {
390: return size;
391: }
392:
393: public int[] getPermissions() {
394: return perms;
395: }
396:
397: public int handleUpload(String f) {
398: upload(f);
399:
400: return 0;
401: }
402:
403: public int handleDownload(String f) {
404: download(f);
405:
406: return 0;
407: }
408:
409: public int upload(String f) {
410: String file = toNFS(f);
411:
412: if (file.endsWith("/")) {
413: String out = StringUtils.getDir(file);
414: uploadDir(file, getLocalPath() + out);
415: fireActionFinished(this );
416: } else {
417: String outfile = StringUtils.getFile(file);
418:
419: //System.out.println("transfer: " + file + ", " + getLocalPath() + outfile);
420: work(getLocalPath() + outfile, file);
421: fireActionFinished(this );
422: }
423:
424: return 0;
425: }
426:
427: public int download(String f) {
428: String file = toNFS(f);
429:
430: if (file.endsWith("/")) {
431: String out = StringUtils.getDir(file);
432: downloadDir(file, getLocalPath() + out);
433: fireActionFinished(this );
434: } else {
435: String outfile = StringUtils.getFile(file);
436:
437: //System.out.println("transfer: " + file + ", " + getLocalPath() + outfile);
438: work(file, getLocalPath() + outfile);
439: fireActionFinished(this );
440: }
441:
442: return 0;
443: }
444:
445: private void downloadDir(String dir, String out) {
446: try {
447: //System.out.println("downloadDir: " + dir + "," + out);
448: fileCount = 0;
449: shortProgress = true;
450: baseFile = StringUtils.getDir(dir);
451:
452: XFile f2 = new XFile(dir);
453: String[] tmp = f2.list();
454:
455: if (tmp == null) {
456: return;
457: }
458:
459: File fx = new File(out);
460: fx.mkdir();
461:
462: for (int i = 0; i < tmp.length; i++) {
463: tmp[i] = tmp[i].replace('\\', '/');
464:
465: //System.out.println("1: " + dir+tmp[i] + ", " + out +tmp[i]);
466: XFile f3 = new XFile(dir + tmp[i]);
467:
468: if (f3.isDirectory()) {
469: if (!tmp[i].endsWith("/")) {
470: tmp[i] = tmp[i] + "/";
471: }
472:
473: downloadDir(dir + tmp[i], out + tmp[i]);
474: } else {
475: fileCount++;
476: fireProgressUpdate(baseFile, DataConnection.GETDIR
477: + ":" + fileCount, -1);
478: work(dir + tmp[i], out + tmp[i]);
479: }
480: }
481:
482: fireProgressUpdate(baseFile, DataConnection.DFINISHED + ":"
483: + fileCount, -1);
484: } catch (Exception ex) {
485: ex.printStackTrace();
486:
487: //System.out.println(dir + ", " + out);
488: Log.debug("Transfer error: " + ex);
489: fireProgressUpdate(baseFile, DataConnection.FAILED + ":"
490: + fileCount, -1);
491: }
492:
493: shortProgress = false;
494: }
495:
496: private void uploadDir(String dir, String out) {
497: try {
498: //System.out.println("uploadDir: " + dir + "," + out);
499: isDirUpload = true;
500: fileCount = 0;
501: shortProgress = true;
502: baseFile = StringUtils.getDir(dir);
503:
504: File f2 = new File(out);
505: String[] tmp = f2.list();
506:
507: if (tmp == null) {
508: return;
509: }
510:
511: XFile fx = new XFile(dir);
512: fx.mkdir();
513:
514: for (int i = 0; i < tmp.length; i++) {
515: tmp[i] = tmp[i].replace('\\', '/');
516:
517: //System.out.println("1: " + dir+tmp[i] + ", " + out +tmp[i]);
518: File f3 = new File(out + tmp[i]);
519:
520: if (f3.isDirectory()) {
521: if (!tmp[i].endsWith("/")) {
522: tmp[i] = tmp[i] + "/";
523: }
524:
525: uploadDir(dir + tmp[i], out + tmp[i]);
526: } else {
527: fileCount++;
528: fireProgressUpdate(baseFile, DataConnection.PUTDIR
529: + ":" + fileCount, -1);
530: work(out + tmp[i], dir + tmp[i]);
531: }
532: }
533:
534: fireProgressUpdate(baseFile, DataConnection.DFINISHED + ":"
535: + fileCount, -1);
536: } catch (Exception ex) {
537: ex.printStackTrace();
538:
539: //System.out.println(dir + ", " + out);
540: Log.debug("Transfer error: " + ex);
541: fireProgressUpdate(baseFile, DataConnection.FAILED + ":"
542: + fileCount, -1);
543: }
544:
545: isDirUpload = false;
546: shortProgress = true;
547: }
548:
549: private void work(String file, String outfile) {
550: BufferedOutputStream out = null;
551: BufferedInputStream in = null;
552:
553: try {
554: boolean outflag = false;
555:
556: if (outfile.startsWith("nfs://")) {
557: outflag = true;
558: out = new BufferedOutputStream(new XFileOutputStream(
559: outfile));
560: } else {
561: out = new BufferedOutputStream(new FileOutputStream(
562: outfile));
563: }
564:
565: //System.out.println("out: " + outfile + ", in: " + file);
566: if (file.startsWith("nfs://")) {
567: in = new BufferedInputStream(new XFileInputStream(file));
568: } else {
569: in = new BufferedInputStream(new FileInputStream(file));
570: }
571:
572: byte[] buf = new byte[buffer];
573: int len = 0;
574: int reallen = 0;
575:
576: //System.out.println(file+":"+getLocalPath()+outfile);
577: while (true) {
578: len = in.read(buf);
579:
580: //System.out.print(".");
581: if (len == StreamTokenizer.TT_EOF) {
582: break;
583: }
584:
585: out.write(buf, 0, len);
586: reallen += len;
587:
588: //System.out.println(file + ":" + StringUtils.getFile(file));
589: if (outflag) {
590: fireProgressUpdate(StringUtils.getFile(outfile),
591: DataConnection.PUT, reallen);
592: } else {
593: fireProgressUpdate(StringUtils.getFile(file),
594: DataConnection.GET, reallen);
595: }
596: }
597:
598: fireProgressUpdate(file, DataConnection.FINISHED, -1);
599: } catch (IOException ex) {
600: Log.debug("Error with file IO (" + ex + ")!");
601: fireProgressUpdate(file, DataConnection.FAILED, -1);
602: } finally {
603: try {
604: out.flush();
605: out.close();
606: in.close();
607: } catch (Exception ex) {
608: ex.printStackTrace();
609: }
610: }
611: }
612:
613: private void update(String file, String type, int bytes) {
614: if (listeners == null) {
615: return;
616: } else {
617: for (int i = 0; i < listeners.size(); i++) {
618: ConnectionListener listener = (ConnectionListener) listeners
619: .elementAt(i);
620: listener.updateProgress(file, type, bytes);
621: }
622: }
623: }
624:
625: public void addConnectionListener(ConnectionListener l) {
626: listeners.add(l);
627: }
628:
629: public void setConnectionListeners(Vector l) {
630: listeners = l;
631: }
632:
633: /** remote directory has changed */
634: public void fireDirectoryUpdate() {
635: if (listeners == null) {
636: return;
637: } else {
638: for (int i = 0; i < listeners.size(); i++) {
639: ((ConnectionListener) listeners.elementAt(i))
640: .updateRemoteDirectory(this );
641: }
642: }
643: }
644:
645: /** progress update */
646: public void fireProgressUpdate(String file, String type, int bytes) {
647: //System.out.println(listener);
648: if (listeners == null) {
649: return;
650: } else {
651: for (int i = 0; i < listeners.size(); i++) {
652: ConnectionListener listener = (ConnectionListener) listeners
653: .elementAt(i);
654:
655: if (shortProgress && Settings.shortProgress) {
656: if (type.startsWith(DataConnection.DFINISHED)) {
657: listener.updateProgress(baseFile,
658: DataConnection.DFINISHED + ":"
659: + fileCount, bytes);
660: } else if (isDirUpload) {
661: listener
662: .updateProgress(baseFile,
663: DataConnection.PUTDIR + ":"
664: + fileCount, bytes);
665: } else {
666: listener
667: .updateProgress(baseFile,
668: DataConnection.GETDIR + ":"
669: + fileCount, bytes);
670: }
671: } else {
672: listener.updateProgress(file, type, bytes);
673: }
674: }
675: }
676: }
677:
678: public void fireActionFinished(NfsConnection con) {
679: if (listeners == null) {
680: return;
681: } else {
682: for (int i = 0; i < listeners.size(); i++) {
683: ((ConnectionListener) listeners.elementAt(i))
684: .actionFinished(con);
685: }
686: }
687: }
688:
689: public int upload(String file, InputStream i) {
690: BufferedInputStream in = null;
691: BufferedOutputStream out = null;
692:
693: try {
694: file = toNFS(file);
695:
696: out = new BufferedOutputStream(new XFileOutputStream(file));
697: in = new BufferedInputStream(i);
698:
699: byte[] buf = new byte[buffer];
700: int len = 0;
701: int reallen = 0;
702:
703: while (true) {
704: len = in.read(buf);
705:
706: if (len == StreamTokenizer.TT_EOF) {
707: break;
708: }
709:
710: out.write(buf, 0, len);
711: reallen += len;
712:
713: fireProgressUpdate(StringUtils.getFile(file),
714: DataConnection.PUT, reallen);
715: }
716:
717: fireProgressUpdate(file, DataConnection.FINISHED, -1);
718: } catch (IOException ex) {
719: Log.debug("Error with file IO (" + ex + ")!");
720: fireProgressUpdate(file, DataConnection.FAILED, -1);
721:
722: return -1;
723: } finally {
724: try {
725: out.flush();
726: out.close();
727: in.close();
728: } catch (Exception ex) {
729: ex.printStackTrace();
730: }
731: }
732:
733: return 0;
734: }
735:
736: public InputStream getDownloadInputStream(String file) {
737: file = toNFS(file);
738: Log.debug(file);
739:
740: try {
741: return new BufferedInputStream(new XFileInputStream(file));
742: } catch (Exception ex) {
743: ex.printStackTrace();
744: Log.debug(ex.toString()
745: + " @NfsConnection::getDownloadInputStream");
746:
747: return null;
748: }
749: }
750:
751: public Date[] sortDates() {
752: return null;
753: }
754:
755: public boolean rename(String from, String to) {
756: Log.debug("Not implemented!");
757:
758: return false;
759: }
760: }
|