001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.net.ftp.parser;
018
019 import java.util.Calendar;
020
021 import junit.framework.TestSuite;
022
023 import org.apache.commons.net.ftp.FTPFile;
024 import org.apache.commons.net.ftp.FTPFileEntryParser;
025
026 /**
027 * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
028 * @version $Id: UnixFTPEntryParserTest.java 629276 2008-02-19 23:31:25Z rwinston $
029 */
030 public class UnixFTPEntryParserTest extends FTPParseTestFramework {
031
032 private static final String[] badsamples = {
033 "zrwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox",
034 "dxrwr-xr-x 2 root root 4096 Aug 24 2001 zxjdbc",
035 "drwxr-xr-x 2 root root 4096 Jam 4 00:03 zziplib",
036 "drwxr-xr-x 2 root 99 4096 Feb 23 30:01 zzplayer",
037 "drwxr-xr-x 2 root root 4096 Aug 36 2001 zztpp",
038 "-rw-r--r-- 1 14 staff 80284 Aug 22 zxJDBC-1.2.3.tar.gz",
039 "-rw-r--r-- 1 14 staff 119:26 Aug 22 2000 zxJDBC-1.2.3.zip",
040 /*"-rw-r--r-- 1 ftp no group 83853 Jan 22 2001 zxJDBC-1.2.4.tar.gz",*/
041 "-rw-r--r-- 1ftp nogroup 126552 Jan 22 2001 zxJDBC-1.2.4.zip",
042 "-rw-r--r-- 1 root root 190144 2001-04-27 zxJDBC-2.0.1b1.zip",
043 "-rw-r--r-- 1 root root 111325 Apr -7 18:79 zxJDBC-2.0.1b1.tar.gz" };
044
045 private static final String[] goodsamples =
046 {
047 "-rw-r--r-- 1 500 500 21 Aug 8 14:14 JB3-TES1.gz",
048 "-rwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox",
049 "drwxr-xr-x 2 root root 4096 Aug 24 2001 zxjdbc",
050 "drwxr-xr-x 2 root root 4096 Jan 4 00:03 zziplib",
051 "drwxr-xr-x 2 root 99 4096 Feb 23 2001 zzplayer",
052 "drwxr-xr-x 2 root root 4096 Aug 6 2001 zztpp",
053 "drwxr-xr-x 1 usernameftp 512 Jan 29 23:32 prog",
054 "lrw-r--r-- 1 14 14 80284 Aug 22 2000 zxJDBC-1.2.3.tar.gz",
055 "frw-r--r-- 1 14 staff 119926 Aug 22 2000 zxJDBC-1.2.3.zip",
056 "crw-r--r-- 1 ftp nogroup 83853 Jan 22 2001 zxJDBC-1.2.4.tar.gz",
057 "brw-r--r-- 1 ftp nogroup 126552 Jan 22 2001 zxJDBC-1.2.4.zip",
058 "-rw-r--r-- 1 root root 111325 Apr 27 2001 zxJDBC-2.0.1b1.tar.gz",
059 "-rw-r--r-- 1 root root 190144 Apr 27 2001 zxJDBC-2.0.1b1.zip",
060 "-rwxr-xr-x 2 500 500 166 Nov 2 2001 73131-testtes1.afp",
061 "-rw-r--r-- 1 500 500 166 Nov 9 2001 73131-testtes1.AFP",
062 "-rw-r--r-- 1 500 500 166 Nov 12 2001 73131-testtes2.afp",
063 "-rw-r--r-- 1 500 500 166 Nov 12 2001 73131-testtes2.AFP",
064 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:35 testRemoteUPCopyNIX",
065 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:31 testRemoteUPDCopyNIX",
066 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:31 testRemoteUPVCopyNIX",
067 "-rw-r--r-T 1 500 500 0 Mar 25 08:20 testSticky",
068 "-rwxr-xr-t 1 500 500 0 Mar 25 08:21 testStickyExec",
069 "-rwSr-Sr-- 1 500 500 0 Mar 25 08:22 testSuid",
070 "-rwsr-sr-- 1 500 500 0 Mar 25 08:23 testSuidExec",
071 "-rwsr-sr-- 1 500 500 0 Mar 25 0:23 testSuidExec2",
072 "drwxrwx---+ 23 500 500 0 Jan 10 13:09 testACL",
073 "-rw-r--r-- 1 1 3518644 May 25 12:12 std",
074 "lrwxrwxrwx 1 neeme neeme 23 Mar 2 18:06 macros -> ./../../global/macros/.",
075 "-rw-r--r-- 1 ftp group with spaces in it as allowed in cygwin see bug 38634 83853 Jan 22 2001 zxJDBC-1.2.4.tar.gz",
076 "crw-r----- 1 root kmem 0, 27 Jan 30 11:42 kmem", //FreeBSD device
077 "crw------- 1 root sys 109,767 Jul 2 2004 pci@1c,600000:devctl" //Solaris device
078
079
080 };
081
082 /**
083 * @see junit.framework.TestCase#TestCase(String)
084 */
085 public UnixFTPEntryParserTest(String name) {
086 super(name);
087 }
088
089 /**
090 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
091 */
092 @Override
093 protected String[] getBadListing() {
094 return (badsamples);
095 }
096
097 /**
098 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
099 */
100 @Override
101 protected String[] getGoodListing() {
102 return (goodsamples);
103 }
104
105 /**
106 */
107 public void testNumericDateFormat()
108 {
109 String testNumericDF =
110 "-rw-r----- 1 neeme neeme 346 2005-04-08 11:22 services.vsp";
111 String testNumericDF2 =
112 "lrwxrwxrwx 1 neeme neeme 23 2005-03-02 18:06 macros -> ./../../global/macros/.";
113
114 UnixFTPEntryParser parser =
115 new UnixFTPEntryParser(UnixFTPEntryParser.NUMERIC_DATE_CONFIG);
116
117 FTPFile f = parser.parseFTPEntry(testNumericDF);
118 assertNotNull("Failed to parse " + testNumericDF,
119 f);
120
121
122 Calendar cal = Calendar.getInstance();
123 cal.clear();
124 cal.set(Calendar.YEAR, 2005);
125 cal.set(Calendar.MONTH, Calendar.APRIL);
126
127 cal.set(Calendar.DATE, 8);
128 cal.set(Calendar.HOUR_OF_DAY, 11);
129 cal.set(Calendar.MINUTE, 22);
130 assertEquals(cal.getTime(), f.getTimestamp().getTime());
131
132 FTPFile f2 = parser.parseFTPEntry(testNumericDF2);
133 assertNotNull("Failed to parse " + testNumericDF2,
134 f2);
135 assertEquals("symbolic link", "./../../global/macros/.", f2.getLink());
136
137 }
138
139
140 /**
141 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
142 */
143 @Override
144 protected FTPFileEntryParser getParser() {
145 return (new UnixFTPEntryParser());
146 }
147
148 public void testOwnerNameWithSpaces() {
149 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 john smith group 4096 Mar 2 15:13 zxbox");
150 assertNotNull(f);
151 assertEquals("john smith", f.getUser());
152 }
153
154 public void testOwnerANdGroupNameWithSpaces() {
155 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 john smith test group 4096 Mar 2 15:13 zxbox");
156 assertNotNull(f);
157 assertEquals("john smith", f.getUser());
158 assertEquals("test group", f.getGroup());
159 }
160
161 public void testGroupNameWithSpaces() {
162 FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 .metadata");
163 assertNotNull(f);
164 assertEquals("maxm", f.getUser());
165 assertEquals("Domain Users", f.getGroup());
166 }
167
168 public void testTrailingSpaces() {
169 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 john smith group 4096 Mar 2 15:13 zxbox ");
170 assertNotNull(f);
171 assertEquals(f.getName(), "zxbox ");
172 }
173
174 public void testNameWIthPunctuation() {
175 FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 abc(test)123.pdf");
176 assertNotNull(f);
177 assertEquals(f.getName(), "abc(test)123.pdf");
178
179 }
180
181 /**
182 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
183 */
184 @Override
185 public void testParseFieldsOnDirectory() throws Exception {
186 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 user group 4096 Mar 2 15:13 zxbox");
187 assertNotNull("Could not parse entry.", f);
188 assertTrue("Should have been a directory.", f.isDirectory());
189 checkPermissions(f);
190 assertEquals(2, f.getHardLinkCount());
191 assertEquals("user", f.getUser());
192 assertEquals("group", f.getGroup());
193 assertEquals("zxbox", f.getName());
194 assertEquals(4096, f.getSize());
195
196 Calendar cal = Calendar.getInstance();
197 cal.set(Calendar.MONTH, Calendar.MARCH);
198
199 cal.set(Calendar.DATE, 1);
200 cal.set(Calendar.HOUR_OF_DAY, 0);
201 cal.set(Calendar.MINUTE, 0);
202 cal.set(Calendar.SECOND, 0);
203 if (f.getTimestamp().getTime().before(cal.getTime())) {
204 cal.add(Calendar.YEAR, -1);
205 }
206 cal.set(Calendar.DATE, 2);
207 cal.set(Calendar.HOUR_OF_DAY, 15);
208 cal.set(Calendar.MINUTE, 13);
209
210 assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp()
211 .getTime()));
212 }
213
214
215 /**
216 * Method checkPermissions.
217 * Verify that the persmissions were properly set.
218 * @param f
219 */
220 private void checkPermissions(FTPFile f) {
221 assertTrue("Should have user read permission.", f.hasPermission(
222 FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION));
223 assertTrue("Should have user write permission.", f.hasPermission(
224 FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION));
225 assertTrue("Should have user execute permission.", f.hasPermission(
226 FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION));
227 assertTrue("Should have group read permission.", f.hasPermission(
228 FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION));
229 assertTrue("Should NOT have group write permission.", !f.hasPermission(
230 FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION));
231 assertTrue("Should have group execute permission.", f.hasPermission(
232 FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION));
233 assertTrue("Should have world read permission.", f.hasPermission(
234 FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION));
235 assertTrue("Should NOT have world write permission.", !f.hasPermission(
236 FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION));
237 assertTrue("Should have world execute permission.", f.hasPermission(
238 FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION));
239 }
240
241 /**
242 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
243 */
244 @Override
245 public void testParseFieldsOnFile() throws Exception {
246 FTPFile f = getParser()
247 .parseFTPEntry(
248 "-rwxr-xr-x 2 user my group 500 5000000000 Mar 2 15:13 zxbox");
249 assertNotNull("Could not parse entry.", f);
250 assertTrue("Should have been a file.", f.isFile());
251 checkPermissions(f);
252 assertEquals(2, f.getHardLinkCount());
253 assertEquals("user", f.getUser());
254 assertEquals("my group 500", f.getGroup());
255 assertEquals("zxbox", f.getName());
256 assertEquals(5000000000L, f.getSize());
257
258 Calendar cal = Calendar.getInstance();
259 cal.set(Calendar.MONTH, Calendar.MARCH);
260
261 cal.set(Calendar.DATE, 1);
262 cal.set(Calendar.HOUR_OF_DAY, 0);
263 cal.set(Calendar.MINUTE, 0);
264 cal.set(Calendar.SECOND, 0);
265 if (f.getTimestamp().getTime().before(cal.getTime())) {
266 cal.add(Calendar.YEAR, -1);
267 }
268 cal.set(Calendar.DATE, 2);
269 cal.set(Calendar.HOUR_OF_DAY, 15);
270 cal.set(Calendar.MINUTE, 13);
271 assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp().getTime()));
272 }
273
274
275 /**
276 * Method suite.
277 * @return TestSuite
278 */
279 public static TestSuite suite() {
280 return (new TestSuite(UnixFTPEntryParserTest.class));
281 }
282
283
284 /*
285 * @param test
286 * @param f
287 */
288 @Override
289 protected void doAdditionalGoodTests(String test, FTPFile f) {
290 String link = f.getLink();
291 if (null != link) {
292 int linklen = link.length();
293 if (linklen > 0) {
294 assertEquals(link, test.substring(test.length() - linklen));
295 assertEquals(f.getType(), FTPFile.SYMBOLIC_LINK_TYPE);
296 }
297 }
298 int type = f.getType();
299 switch (test.charAt(0))
300 {
301 case 'd':
302 assertEquals("Type of "+ test, type, FTPFile.DIRECTORY_TYPE);
303 break;
304 case 'l':
305 assertEquals("Type of "+ test, type, FTPFile.SYMBOLIC_LINK_TYPE);
306 break;
307 case 'b':
308 case 'c':
309 assertEquals(0, f.getHardLinkCount());
310 case 'f':
311 case '-':
312 assertEquals("Type of "+ test, type, FTPFile.FILE_TYPE);
313 break;
314 default:
315 assertEquals("Type of "+ test, type, FTPFile.UNKNOWN_TYPE);
316 }
317
318 for (int access = FTPFile.USER_ACCESS;
319 access <= FTPFile.WORLD_ACCESS; access++)
320 {
321 for (int perm = FTPFile.READ_PERMISSION;
322 perm <= FTPFile.EXECUTE_PERMISSION; perm++)
323 {
324 int pos = 3*access + perm + 1;
325 char permchar = test.charAt(pos);
326 assertEquals("Permission " + test.substring(1,10),
327 Boolean.valueOf(f.hasPermission(access, perm)),
328 Boolean.valueOf(permchar != '-' && !Character.isUpperCase(permchar)));
329 }
330 }
331
332 }
333 }