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 junit.framework.TestSuite;
22
23 import org.apache.commons.net.ftp.FTPFile;
24 import org.apache.commons.net.ftp.FTPFileEntryParser;
25
26
27
28
29
30 public class UnixFTPEntryParserTest extends FTPParseTestFramework {
31
32 private static final String[] badsamples = {
33 "zrwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox",
34 "dxrwr-xr-x 2 root root 4096 Aug 24 2001 zxjdbc",
35 "drwxr-xr-x 2 root root 4096 Jam 4 00:03 zziplib",
36 "drwxr-xr-x 2 root 99 4096 Feb 23 30:01 zzplayer",
37 "drwxr-xr-x 2 root root 4096 Aug 36 2001 zztpp",
38 "-rw-r--r-- 1 14 staff 80284 Aug 22 zxJDBC-1.2.3.tar.gz",
39 "-rw-r--r-- 1 14 staff 119:26 Aug 22 2000 zxJDBC-1.2.3.zip",
40
41 "-rw-r--r-- 1ftp nogroup 126552 Jan 22 2001 zxJDBC-1.2.4.zip",
42 "-rw-r--r-- 1 root root 190144 2001-04-27 zxJDBC-2.0.1b1.zip",
43 "-rw-r--r-- 1 root root 111325 Apr -7 18:79 zxJDBC-2.0.1b1.tar.gz" };
44
45 private static final String[] goodsamples =
46 {
47 "-rw-r--r-- 1 500 500 21 Aug 8 14:14 JB3-TES1.gz",
48 "-rwxr-xr-x 2 root root 4096 Mar 2 15:13 zxbox",
49 "drwxr-xr-x 2 root root 4096 Aug 24 2001 zxjdbc",
50 "drwxr-xr-x 2 root root 4096 Jan 4 00:03 zziplib",
51 "drwxr-xr-x 2 root 99 4096 Feb 23 2001 zzplayer",
52 "drwxr-xr-x 2 root root 4096 Aug 6 2001 zztpp",
53 "drwxr-xr-x 1 usernameftp 512 Jan 29 23:32 prog",
54 "lrw-r--r-- 1 14 14 80284 Aug 22 2000 zxJDBC-1.2.3.tar.gz",
55 "frw-r--r-- 1 14 staff 119926 Aug 22 2000 zxJDBC-1.2.3.zip",
56 "crw-r--r-- 1 ftp nogroup 83853 Jan 22 2001 zxJDBC-1.2.4.tar.gz",
57 "brw-r--r-- 1 ftp nogroup 126552 Jan 22 2001 zxJDBC-1.2.4.zip",
58 "-rw-r--r-- 1 root root 111325 Apr 27 2001 zxJDBC-2.0.1b1.tar.gz",
59 "-rw-r--r-- 1 root root 190144 Apr 27 2001 zxJDBC-2.0.1b1.zip",
60 "-rwxr-xr-x 2 500 500 166 Nov 2 2001 73131-testtes1.afp",
61 "-rw-r--r-- 1 500 500 166 Nov 9 2001 73131-testtes1.AFP",
62 "-rw-r--r-- 1 500 500 166 Nov 12 2001 73131-testtes2.afp",
63 "-rw-r--r-- 1 500 500 166 Nov 12 2001 73131-testtes2.AFP",
64 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:35 testRemoteUPCopyNIX",
65 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:31 testRemoteUPDCopyNIX",
66 "-rw-r--r-- 1 500 500 2040000 Aug 5 07:31 testRemoteUPVCopyNIX",
67 "-rw-r--r-T 1 500 500 0 Mar 25 08:20 testSticky",
68 "-rwxr-xr-t 1 500 500 0 Mar 25 08:21 testStickyExec",
69 "-rwSr-Sr-- 1 500 500 0 Mar 25 08:22 testSuid",
70 "-rwsr-sr-- 1 500 500 0 Mar 25 08:23 testSuidExec",
71 "-rwsr-sr-- 1 500 500 0 Mar 25 0:23 testSuidExec2",
72 "drwxrwx---+ 23 500 500 0 Jan 10 13:09 testACL",
73 "-rw-r--r-- 1 1 3518644 May 25 12:12 std",
74 "lrwxrwxrwx 1 neeme neeme 23 Mar 2 18:06 macros -> ./../../global/macros/.",
75 "-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",
76 "crw-r----- 1 root kmem 0, 27 Jan 30 11:42 kmem",
77 "crw------- 1 root sys 109,767 Jul 2 2004 pci@1c,600000:devctl"
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 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
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
217
218
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
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
277
278
279 public static TestSuite suite() {
280 return (new TestSuite(UnixFTPEntryParserTest.class));
281 }
282
283
284
285
286
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 }