1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.net.ftp.parser;
18
19 import java.util.Calendar;
20
21 import org.apache.commons.net.ftp.FTPFile;
22 import org.apache.commons.net.ftp.FTPFileEntryParser;
23
24
25
26
27
28 public class UnixFTPEntryParserTest extends FTPParseTestFramework {
29
30 private static final String[] badsamples = {
31 "zrwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox",
32 "dxrwr-xr-x 2 root root 4096 Aug 24 2001 zxjdbc",
33 "drwxr-xr-x 2 root root 4096 Jam 4 00:03 zziplib",
34 "drwxr-xr-x 2 root 99 4096 Feb 23 30:01 zzplayer",
35 "drwxr-xr-x 2 root root 4096 Aug 36 2001 zztpp",
36 "-rw-r--r-- 1 14 staff 80284 Aug 22 zxJDBC-1.2.3.tar.gz",
37 "-rw-r--r-- 1 14 staff 119:26 Aug 22 2000 zxJDBC-1.2.3.zip",
38
39 "-rw-r--r-- 1ftp nogroup 126552 Jan 22 2001 zxJDBC-1.2.4.zip",
40 "-rw-r--r-- 1 root root 190144 2001-04-27 zxJDBC-2.0.1b1.zip",
41 "-rw-r--r-- 1 root root 111325 Apr -7 18:79 zxJDBC-2.0.1b1.tar.gz" };
42
43 private static final String[] goodsamples =
44 {
45 "-rw-r--r-- 1 500 500 21 Aug 8 14:14 JB3-TES1.gz",
46 "-rwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox",
47 "drwxr-xr-x 2 root root 4096 Aug 24 2001 zxjdbc",
48 "drwxr-xr-x 2 root root 4096 Jan 4 00:03 zziplib",
49 "drwxr-xr-x 2 root 99 4096 Feb 23 2001 zzplayer",
50 "drwxr-xr-x 2 root root 4096 Aug 6 2001 zztpp",
51 "drwxr-xr-x 1 usernameftp 512 Jan 29 23:32 prog",
52 "lrw-r--r-- 1 14 14 80284 Aug 22 2000 zxJDBC-1.2.3.tar.gz",
53 "frw-r--r-- 1 14 staff 119926 Aug 22 2000 zxJDBC-1.2.3.zip",
54 "crw-r--r-- 1 ftp nogroup 83853 Jan 22 2001 zxJDBC-1.2.4.tar.gz",
55 "brw-r--r-- 1 ftp nogroup 126552 Jan 22 2001 zxJDBC-1.2.4.zip",
56 "-rw-r--r-- 1 root root 111325 Apr 27 2001 zxJDBC-2.0.1b1.tar.gz",
57 "-rw-r--r-- 1 root root 190144 Apr 27 2001 zxJDBC-2.0.1b1.zip",
58 "-rwxr-xr-x 2 500 500 166 Nov 2 2001 73131-testtes1.afp",
59 "-rw-r--r-- 1 500 500 166 Nov 9 2001 73131-testtes1.AFP",
60 "-rw-r--r-- 1 500 500 166 Nov 12 2001 73131-testtes2.afp",
61 "-rw-r--r-- 1 500 500 166 Nov 12 2001 73131-testtes2.AFP",
62 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:35 testRemoteUPCopyNIX",
63 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:31 testRemoteUPDCopyNIX",
64 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:31 testRemoteUPVCopyNIX",
65 "-rw-r--r-T 1 500 500 0 Mar 25 08:20 testSticky",
66 "-rwxr-xr-t 1 500 500 0 Mar 25 08:21 testStickyExec",
67 "-rwSr-Sr-- 1 500 500 0 Mar 25 08:22 testSuid",
68 "-rwsr-sr-- 1 500 500 0 Mar 25 08:23 testSuidExec",
69 "-rwsr-sr-- 1 500 500 0 Mar 25 0:23 testSuidExec2",
70 "drwxrwx---+ 23 500 500 0 Jan 10 13:09 testACL",
71 "-rw-r--r-- 1 1 3518644 May 25 12:12 std",
72 "lrwxrwxrwx 1 neeme neeme 23 Mar 2 18:06 macros -> ./../../global/macros/.",
73 "-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",
74
75 "crw-r----- 1 root kmem 0, 27 Jan 30 11:42 kmem",
76 "crw------- 1 root sys 109,767 Jul 2 2004 pci@1c,600000:devctl",
77 "-rwxrwx--- 1 ftp ftp-admin 816026400 Oct 5 2008 bloplab 7 cd1.img",
78
79
80 };
81
82
83
84
85 public UnixFTPEntryParserTest(String name) {
86 super(name);
87 }
88
89
90
91
92 @Override
93 protected String[] getBadListing() {
94 return (badsamples);
95 }
96
97
98
99
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
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 testNET294() {
162 FTPFile f = getParser().parseFTPEntry(
163 "-rwxrwx--- 1 ftp ftp-admin 816026400 Oct 5 2008 bloplab 7 cd1.img");
164 assertNotNull(f);
165 assertEquals("ftp", f.getUser());
166 assertEquals("ftp-admin", f.getGroup());
167 assertEquals(816026400L,f.getSize());
168 assertNotNull("Timestamp should not be null",f.getTimestamp());
169 assertEquals(2008,f.getTimestamp().get(Calendar.YEAR));
170 assertEquals("bloplab 7 cd1.img",f.getName());
171 }
172
173 public void testGroupNameWithSpaces() {
174 FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 .metadata");
175 assertNotNull(f);
176 assertEquals("maxm", f.getUser());
177 assertEquals("Domain Users", f.getGroup());
178 }
179
180 public void testTrailingSpaces() {
181 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 john smith group 4096 Mar 2 15:13 zxbox ");
182 assertNotNull(f);
183 assertEquals(f.getName(), "zxbox ");
184 }
185
186 public void testNameWIthPunctuation() {
187 FTPFile f = getParser().parseFTPEntry("drwx------ 4 maxm Domain Users 512 Oct 2 10:59 abc(test)123.pdf");
188 assertNotNull(f);
189 assertEquals(f.getName(), "abc(test)123.pdf");
190 }
191
192 public void testNoSpacesBeforeFileSize() {
193 FTPFile f = getParser().parseFTPEntry("drwxr-x---+1464 chrism chrism 41472 Feb 25 13:17 20090225");
194 assertNotNull(f);
195 assertEquals(f.getSize(), 41472);
196 assertEquals(f.getType(), FTPFile.DIRECTORY_TYPE);
197 assertEquals(f.getUser(), "chrism");
198 assertEquals(f.getGroup(), "chrism");
199 assertEquals(f.getHardLinkCount(), 1464);
200 }
201
202 public void testCorrectGroupNameParsing() {
203 FTPFile f = getParser().parseFTPEntry("-rw-r--r-- 1 ftpuser ftpusers 12414535 Mar 17 11:07 test 1999 abc.pdf");
204 assertNotNull(f);
205 assertEquals(f.getHardLinkCount(), 1);
206 assertEquals(f.getUser(), "ftpuser");
207 assertEquals(f.getGroup(), "ftpusers");
208 assertEquals(f.getSize(), 12414535);
209 assertEquals(f.getName(), "test 1999 abc.pdf");
210
211 Calendar cal = Calendar.getInstance();
212 cal.set(Calendar.MONTH, Calendar.MARCH);
213 cal.set(Calendar.DAY_OF_MONTH, 17);
214 cal.set(Calendar.HOUR_OF_DAY, 11);
215 cal.set(Calendar.MINUTE, 7);
216 cal.set(Calendar.SECOND, 0);
217 cal.set(Calendar.MILLISECOND, 0);
218
219 assertEquals(f.getTimestamp().get(Calendar.MONTH), cal.get(Calendar.MONTH));
220 assertEquals(f.getTimestamp().get(Calendar.DAY_OF_MONTH), cal.get(Calendar.DAY_OF_MONTH));
221 assertEquals(f.getTimestamp().get(Calendar.HOUR_OF_DAY), cal.get(Calendar.HOUR_OF_DAY));
222 assertEquals(f.getTimestamp().get(Calendar.MINUTE), cal.get(Calendar.MINUTE));
223 assertEquals(f.getTimestamp().get(Calendar.SECOND), cal.get(Calendar.SECOND));
224 }
225
226 public void testFilenamesWithEmbeddedNumbers() {
227 FTPFile f = getParser().parseFTPEntry("-rw-rw-rw- 1 user group 5840 Mar 19 09:34 123 456 abc.csv");
228 assertEquals(f.getName(), "123 456 abc.csv");
229 assertEquals(f.getSize(), 5840);
230 assertEquals(f.getUser(), "user");
231 assertEquals(f.getGroup(), "group");
232 }
233
234
235
236
237 @Override
238 public void testParseFieldsOnDirectory() throws Exception {
239 FTPFile f = getParser().parseFTPEntry("drwxr-xr-x 2 user group 4096 Mar 2 15:13 zxbox");
240 assertNotNull("Could not parse entry.", f);
241 assertTrue("Should have been a directory.", f.isDirectory());
242 checkPermissions(f);
243 assertEquals(2, f.getHardLinkCount());
244 assertEquals("user", f.getUser());
245 assertEquals("group", f.getGroup());
246 assertEquals("zxbox", f.getName());
247 assertEquals(4096, f.getSize());
248
249 Calendar cal = Calendar.getInstance();
250 cal.set(Calendar.MONTH, Calendar.MARCH);
251
252 cal.set(Calendar.DATE, 1);
253 cal.set(Calendar.HOUR_OF_DAY, 0);
254 cal.set(Calendar.MINUTE, 0);
255 cal.set(Calendar.SECOND, 0);
256 if (f.getTimestamp().getTime().before(cal.getTime())) {
257 cal.add(Calendar.YEAR, -1);
258 }
259 cal.set(Calendar.DATE, 2);
260 cal.set(Calendar.HOUR_OF_DAY, 15);
261 cal.set(Calendar.MINUTE, 13);
262
263 assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp()
264 .getTime()));
265 }
266
267
268
269
270
271
272
273 private void checkPermissions(FTPFile f) {
274 assertTrue("Should have user read permission.", f.hasPermission(
275 FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION));
276 assertTrue("Should have user write permission.", f.hasPermission(
277 FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION));
278 assertTrue("Should have user execute permission.", f.hasPermission(
279 FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION));
280 assertTrue("Should have group read permission.", f.hasPermission(
281 FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION));
282 assertTrue("Should NOT have group write permission.", !f.hasPermission(
283 FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION));
284 assertTrue("Should have group execute permission.", f.hasPermission(
285 FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION));
286 assertTrue("Should have world read permission.", f.hasPermission(
287 FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION));
288 assertTrue("Should NOT have world write permission.", !f.hasPermission(
289 FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION));
290 assertTrue("Should have world execute permission.", f.hasPermission(
291 FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION));
292 }
293
294
295
296
297 @Override
298 public void testParseFieldsOnFile() throws Exception {
299 FTPFile f = getParser()
300 .parseFTPEntry(
301 "-rwxr-xr-x 2 user my group 500 5000000000 Mar 2 15:13 zxbox");
302 assertNotNull("Could not parse entry.", f);
303 assertTrue("Should have been a file.", f.isFile());
304 checkPermissions(f);
305 assertEquals(2, f.getHardLinkCount());
306 assertEquals("user", f.getUser());
307 assertEquals("my group 500", f.getGroup());
308 assertEquals("zxbox", f.getName());
309 assertEquals(5000000000L, f.getSize());
310
311 Calendar cal = Calendar.getInstance();
312 cal.set(Calendar.MONTH, Calendar.MARCH);
313
314 cal.set(Calendar.DATE, 1);
315 cal.set(Calendar.HOUR_OF_DAY, 0);
316 cal.set(Calendar.MINUTE, 0);
317 cal.set(Calendar.SECOND, 0);
318 if (f.getTimestamp().getTime().before(cal.getTime())) {
319 cal.add(Calendar.YEAR, -1);
320 }
321 cal.set(Calendar.DATE, 2);
322 cal.set(Calendar.HOUR_OF_DAY, 15);
323 cal.set(Calendar.MINUTE, 13);
324 assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp().getTime()));
325 }
326
327
328
329
330
331 @Override
332 protected void doAdditionalGoodTests(String test, FTPFile f) {
333 String link = f.getLink();
334 if (null != link) {
335 int linklen = link.length();
336 if (linklen > 0) {
337 assertEquals(link, test.substring(test.length() - linklen));
338 assertEquals(f.getType(), FTPFile.SYMBOLIC_LINK_TYPE);
339 }
340 }
341 int type = f.getType();
342 switch (test.charAt(0))
343 {
344 case 'd':
345 assertEquals("Type of "+ test, type, FTPFile.DIRECTORY_TYPE);
346 break;
347 case 'l':
348 assertEquals("Type of "+ test, type, FTPFile.SYMBOLIC_LINK_TYPE);
349 break;
350 case 'b':
351 case 'c':
352 assertEquals(0, f.getHardLinkCount());
353
354 case 'f':
355 case '-':
356 assertEquals("Type of "+ test, type, FTPFile.FILE_TYPE);
357 break;
358 default:
359 assertEquals("Type of "+ test, type, FTPFile.UNKNOWN_TYPE);
360 }
361
362 for (int access = FTPFile.USER_ACCESS;
363 access <= FTPFile.WORLD_ACCESS; access++)
364 {
365 for (int perm = FTPFile.READ_PERMISSION;
366 perm <= FTPFile.EXECUTE_PERMISSION; perm++)
367 {
368 int pos = 3*access + perm + 1;
369 char permchar = test.charAt(pos);
370 assertEquals("Permission " + test.substring(1,10),
371 Boolean.valueOf(f.hasPermission(access, perm)),
372 Boolean.valueOf(permchar != '-' && !Character.isUpperCase(permchar)));
373 }
374 }
375
376 assertNotNull("Expected to find a timestamp",f.getTimestamp());
377
378
379 }
380 }