001: /*
002: * SshFile.java
003: *
004: * Copyright (C) 2002 Peter Graves
005: * $Id: SshFile.java,v 1.8 2002/12/07 19:27:03 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: import gnu.regexp.RE;
025: import gnu.regexp.REException;
026: import gnu.regexp.REMatch;
027:
028: public final class SshFile extends File {
029: public static final int DEFAULT_PORT = 22;
030:
031: private SshFile() {
032: isRemote = true;
033: protocol = PROTOCOL_SSH;
034: port = DEFAULT_PORT;
035: }
036:
037: public SshFile(String hostName, String path, String userName,
038: String password, int port) {
039: isRemote = true;
040: protocol = PROTOCOL_SSH;
041: this .hostName = hostName;
042: this .canonicalPath = path;
043: this .userName = userName;
044: this .password = password;
045: this .port = port;
046: }
047:
048: public static SshFile getSshFile(String name) {
049: SshFile file = new SshFile();
050: if (file.initRemote(name, PREFIX_SSH))
051: return file;
052: return null;
053: }
054:
055: public static SshFile getSshFile(SshFile directory, String name) {
056: SshFile file = new SshFile();
057:
058: file.hostName = directory.hostName;
059: file.userName = directory.userName;
060: file.password = directory.password;
061: file.port = directory.port;
062:
063: if (Utilities.isFilenameAbsolute(name))
064: file.canonicalPath = canonicalize(name, "/");
065: else
066: file.canonicalPath = canonicalize(appendNameToPath(
067: directory.canonicalPath(), name, '/'), "/");
068:
069: return file;
070: }
071:
072: public final File getRoot() {
073: SshFile file = new SshFile();
074: file.hostName = this .hostName;
075: file.userName = this .userName;
076: file.password = this .password;
077: file.port = this .port;
078: file.canonicalPath = "/";
079: file.type = TYPE_DIRECTORY;
080: return file;
081: }
082:
083: public String netPath() {
084: FastStringBuffer sb = new FastStringBuffer(256);
085: sb.append(PREFIX_SSH);
086: if (userName != null) {
087: sb.append(userName);
088: sb.append('@');
089: }
090: sb.append(hostName);
091: if (port != DEFAULT_PORT) {
092: sb.append(':');
093: sb.append(port);
094: }
095: if (canonicalPath != null)
096: sb.append(canonicalPath);
097: return sb.toString();
098: }
099:
100: public File getParentFile() {
101: if (canonicalPath() == null || canonicalPath.equals("/"))
102: return null; // No parent.
103: int index = canonicalPath.lastIndexOf('/');
104: if (index < 0)
105: return null; // No parent.
106: if (index == 0) // "/usr"
107: return new SshFile(hostName, "/", userName, password, port);
108: return new SshFile(hostName, canonicalPath.substring(0, index),
109: userName, password, port);
110: }
111:
112: public boolean isDirectory() {
113: if (type == TYPE_LINK) {
114: if (DirectoryCache.getDirectoryCache().getListing(this ) != null)
115: return true;
116: SshSession session = SshSession.getSession(this );
117: if (session != null) {
118: Debug.assertTrue(session.isLocked());
119: boolean result = session.isDirectory(canonicalPath());
120: session.unlock();
121: return result;
122: } else
123: return false;
124: }
125: if (type == TYPE_UNKNOWN) {
126: if (DirectoryCache.getDirectoryCache().getListing(this ) != null)
127: return true;
128: SshFile parent = (SshFile) getParentFile();
129: if (parent != null) {
130: String listing = parent.getDirectoryListing();
131: if (listing != null) {
132: try {
133: String pattern = "\\n[d\\-][^\\n]+ "
134: + getName() + "\\n";
135: RE re = new RE(pattern);
136: REMatch match = re.getMatch(listing);
137: if (match != null) {
138: String s = match.toString();
139: if (s.length() > 1) {
140: char c = s.charAt(1);
141: if (c == 'd')
142: return true;
143: if (c == '-')
144: return false;
145: // Otherwise fall through...
146: }
147: }
148: } catch (REException e) {
149: Log.error(e);
150: }
151: }
152: }
153: SshSession session = SshSession.getSession(this );
154: if (session != null) {
155: Debug.assertTrue(session.isLocked());
156: if (session.isDirectory(canonicalPath()))
157: type = TYPE_DIRECTORY;
158: session.unlock();
159: }
160: }
161: return type == TYPE_DIRECTORY;
162: }
163:
164: public boolean isLink() {
165: return type == TYPE_LINK;
166: }
167:
168: public boolean exists() {
169: SshSession session = SshSession.getSession(this );
170: if (session == null)
171: return false;
172: Debug.assertTrue(session.isLocked());
173: boolean result = session.exists(canonicalPath());
174: session.unlock();
175: return result;
176: }
177:
178: public String getDirectoryListing() {
179: return getDirectoryListing(false);
180: }
181:
182: public String getDirectoryListing(boolean forceRefresh) {
183: if (!forceRefresh) {
184: String listing = DirectoryCache.getDirectoryCache()
185: .getListing(this );
186: if (listing != null)
187: return listing;
188: }
189: SshSession session = SshSession.getSession(this );
190: if (session == null)
191: return null;
192: if (!session.isLocked()) {
193: Debug.bug();
194: return null;
195: }
196: String listing = session.retrieveDirectoryListing(this );
197: session.unlock();
198: DirectoryCache.getDirectoryCache().put(this , listing);
199: return listing;
200: }
201:
202: public boolean equals(Object obj) {
203: if (!(obj instanceof SshFile))
204: return false;
205: SshFile f = (SshFile) obj;
206: // Protocol.
207: if (f.protocol != protocol)
208: return false;
209: // Port.
210: if (f.port != port)
211: return false;
212: // Host name.
213: if (f.hostName == null) {
214: if (hostName != null)
215: return false;
216: } else if (!f.hostName.equals(hostName))
217: return false;
218: // Handle pathological corner case where both canonical paths are null.
219: if (f.canonicalPath() == canonicalPath())
220: return true;
221: // At this point the canonical paths are cached for both files.
222: // If either one is null, they can't be equal.
223: if (f.canonicalPath == null || canonicalPath == null)
224: return false;
225: return f.canonicalPath.equals(canonicalPath);
226: }
227:
228: public final String getSeparator() {
229: return "/";
230: }
231:
232: public final char getSeparatorChar() {
233: return '/';
234: }
235: }
|