View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
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   * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
26   * @version $Id: UnixFTPEntryParserTest.java 1489533 2013-06-04 17:49:00Z sebb $
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              /*"-rw-r--r--   1 ftp      no group    83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz",*/
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                                                                                     // Bug 38634 => NET-16
75              "crw-r----- 1 root kmem 0, 27 Jan 30 11:42 kmem",  //FreeBSD device
76              "crw-------   1 root     sys      109,767 Jul  2  2004 pci@1c,600000:devctl", //Solaris device
77              "-rwxrwx---   1 ftp      ftp-admin 816026400 Oct  5  2008 bloplab 7 cd1.img", // NET-294
78  
79  
80          };
81  
82      /**
83       * @see junit.framework.TestCase#TestCase(String)
84       */
85      public UnixFTPEntryParserTest(String name) {
86          super(name);
87      }
88  
89      /**
90       * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
91       */
92      @Override
93      protected String[] getBadListing() {
94          return (badsamples);
95      }
96  
97      /**
98       * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
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      * @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 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      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
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      * Method checkPermissions.
270      * Verify that the persmissions were properly set.
271      * @param f
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      * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
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      * @param test
329      * @param f
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             //$FALL-THROUGH$ TODO this needs to be fixed if a device type is introduced
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 // Perhaps check date range (need to ensure all good examples qualify)
378 //        assertTrue(test,f.getTimestamp().get(Calendar.YEAR)>=2000);
379     }
380 }