1   /*
2    * Copyright 2001-2005 The Apache Software Foundation
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.net.ftp.parser;
17  
18  import java.util.Calendar;
19  
20  import junit.framework.TestSuite;
21  
22  import org.apache.commons.net.ftp.FTPFile;
23  import org.apache.commons.net.ftp.FTPFileEntryParser;
24  
25  /**
26   * @author <a href="mailto:scohen@apache.org">Steve Cohen</a>
27   * @version $Id: UnixFTPEntryParserTest.java 165675 2005-05-02 20:09:55Z rwinston $
28   */
29  public class UnixFTPEntryParserTest extends FTPParseTestFramework {
30  
31  	private static final String[] badsamples = {
32  			"zrwxr-xr-x   2 root     root         4096 Mar  2 15:13 zxbox",
33  			"dxrwr-xr-x   2 root     root         4096 Aug 24  2001 zxjdbc",
34  			"drwxr-xr-x   2 root     root         4096 Jam  4 00:03 zziplib",
35  			"drwxr-xr-x   2 root     99           4096 Feb 23 30:01 zzplayer",
36  			"drwxr-xr-x   2 root     root         4096 Aug 36  2001 zztpp",
37  			"-rw-r--r--   1 14       staff       80284 Aug 22  zxJDBC-1.2.3.tar.gz",
38  			"-rw-r--r--   1 14       staff      119:26 Aug 22  2000 zxJDBC-1.2.3.zip",
39  			"-rw-r--r--   1 ftp      no group    83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz",
40  			"-rw-r--r--   1ftp       nogroup    126552 Jan 22  2001 zxJDBC-1.2.4.zip",
41  			"-rw-r--r--   1 root     root       190144 2001-04-27 zxJDBC-2.0.1b1.zip",
42  			"-rw-r--r--   1 root     root       111325 Apr -7 18:79 zxJDBC-2.0.1b1.tar.gz" };
43  
44  	private static final String[] goodsamples = 
45  	{
46  			"-rw-r--r--   1 500      500            21 Aug  8 14:14 JB3-TES1.gz",
47  			"-rwxr-xr-x   2 root     root         4096 Mar  2 15:13 zxbox",
48  			"drwxr-xr-x   2 root     root         4096 Aug 24  2001 zxjdbc",
49  			"drwxr-xr-x   2 root     root         4096 Jan  4 00:03 zziplib",
50  			"drwxr-xr-x   2 root     99           4096 Feb 23  2001 zzplayer",
51  			"drwxr-xr-x   2 root     root         4096 Aug  6  2001 zztpp",
52  			"drwxr-xr-x 1 usernameftp 512 Jan 29 23:32 prog",
53  			"lrw-r--r--   1 14       14          80284 Aug 22  2000 zxJDBC-1.2.3.tar.gz",
54  			"frw-r--r--   1 14       staff      119926 Aug 22  2000 zxJDBC-1.2.3.zip",
55  			"crw-r--r--   1 ftp      nogroup     83853 Jan 22  2001 zxJDBC-1.2.4.tar.gz",
56  			"brw-r--r--   1 ftp      nogroup    126552 Jan 22  2001 zxJDBC-1.2.4.zip",
57  			"-rw-r--r--   1 root     root       111325 Apr 27  2001 zxJDBC-2.0.1b1.tar.gz",
58  			"-rw-r--r--   1 root     root       190144 Apr 27  2001 zxJDBC-2.0.1b1.zip",
59  			"-rwxr-xr-x   2 500      500           166 Nov  2  2001 73131-testtes1.afp",
60  			"-rw-r--r--   1 500      500           166 Nov  9  2001 73131-testtes1.AFP",
61  			"-rw-r--r--   1 500      500           166 Nov 12  2001 73131-testtes2.afp",
62  			"-rw-r--r--   1 500      500           166 Nov 12  2001 73131-testtes2.AFP",
63  			"-rw-r--r--   1 500      500       2040000 Aug  5 07:35 testRemoteUPCopyNIX",
64  			"-rw-r--r--   1 500      500       2040000 Aug  5 07:31 testRemoteUPDCopyNIX",
65  			"-rw-r--r--   1 500      500       2040000 Aug  5 07:31 testRemoteUPVCopyNIX",
66  			"-rw-r--r-T   1 500      500             0 Mar 25 08:20 testSticky",
67  			"-rwxr-xr-t   1 500      500             0 Mar 25 08:21 testStickyExec",
68  			"-rwSr-Sr--   1 500      500             0 Mar 25 08:22 testSuid",
69  			"-rwsr-sr--   1 500      500             0 Mar 25 08:23 testSuidExec",
70  			"-rwsr-sr--   1 500      500             0 Mar 25 0:23 testSuidExec2",
71  			"drwxrwx---+ 23 500     500    0 Jan 10 13:09 testACL",
72  			"-rw-r--r--   1 1        3518644 May 25 12:12 std",
73              "lrwxrwxrwx   1 neeme neeme             23 Mar  2 18:06 macros -> ./../../global/macros/."
74  
75  		};
76  
77  	/**
78  	 * @see junit.framework.TestCase#TestCase(String)
79  	 */
80  	public UnixFTPEntryParserTest(String name) {
81  		super(name);
82  	}
83  
84  	/**
85  	 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getBadListing()
86  	 */
87  	protected String[] getBadListing() {
88  		return (badsamples);
89  	}
90  
91  	/**
92  	 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getGoodListing()
93  	 */
94  	protected String[] getGoodListing() {
95  		return (goodsamples);
96  	}
97  	
98      /**
99       */
100     public void testNumericDateFormat()
101     {
102         String testNumericDF = 
103 			"-rw-r-----   1 neeme neeme   346 2005-04-08 11:22 services.vsp";
104         String testNumericDF2 = 
105             "lrwxrwxrwx   1 neeme neeme    23 2005-03-02 18:06 macros -> ./../../global/macros/.";
106 
107         UnixFTPEntryParser parser = 
108             new UnixFTPEntryParser(UnixFTPEntryParser.NUMERIC_DATE_CONFIG);
109         
110         FTPFile f = parser.parseFTPEntry(testNumericDF);
111         assertNotNull("Failed to parse " + testNumericDF,
112                       f);
113         
114         
115 		Calendar cal = Calendar.getInstance();
116 		cal.clear();
117 		cal.set(Calendar.YEAR, 2005);
118 		cal.set(Calendar.MONTH, Calendar.APRIL);
119 
120 		cal.set(Calendar.DATE, 8);
121 		cal.set(Calendar.HOUR_OF_DAY, 11);
122 		cal.set(Calendar.MINUTE, 22);
123 		assertEquals(cal.getTime(), f.getTimestamp().getTime());
124 
125         FTPFile f2 = parser.parseFTPEntry(testNumericDF2);
126         assertNotNull("Failed to parse " + testNumericDF2,
127                       f2);
128         assertEquals("symbolic link", "./../../global/macros/.", f2.getLink());
129 
130     }
131 
132 
133 	/**
134 	 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#getParser()
135 	 */
136 	protected FTPFileEntryParser getParser() {
137 		return (new UnixFTPEntryParser());
138 	}
139 
140 	/**
141 	 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnDirectory()
142 	 */
143 	public void testParseFieldsOnDirectory() throws Exception {
144 		FTPFile f = getParser().parseFTPEntry("drwxr-xr-x   2 user     group         4096 Mar  2 15:13 zxbox");
145 		assertNotNull("Could not parse entry.", f);
146 		assertTrue("Should have been a directory.", f.isDirectory());
147 		checkPermissions(f);
148 		assertEquals(2, f.getHardLinkCount());
149 		assertEquals("user", f.getUser());
150 		assertEquals("group", f.getGroup());
151 		assertEquals("zxbox", f.getName());
152 		assertEquals(4096, f.getSize());
153 
154 		Calendar cal = Calendar.getInstance();
155 		cal.set(Calendar.MONTH, Calendar.MARCH);
156 
157 		cal.set(Calendar.DATE, 1);
158 		cal.set(Calendar.HOUR_OF_DAY, 0);
159 		cal.set(Calendar.MINUTE, 0);
160 		cal.set(Calendar.SECOND, 0);
161 		if (f.getTimestamp().getTime().before(cal.getTime())) {
162 			cal.add(Calendar.YEAR, -1);
163 		}
164 		cal.set(Calendar.DATE, 2);
165 		cal.set(Calendar.HOUR_OF_DAY, 15);
166 		cal.set(Calendar.MINUTE, 13);
167 
168 		assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp()
169 				.getTime()));
170 	}
171 
172 	
173 	/**
174 	 * Method checkPermissions.
175 	 * Verify that the persmissions were properly set.
176 	 * @param f
177 	 */
178 	private void checkPermissions(FTPFile f) {
179 		assertTrue("Should have user read permission.", f.hasPermission(
180 				FTPFile.USER_ACCESS, FTPFile.READ_PERMISSION));
181 		assertTrue("Should have user write permission.", f.hasPermission(
182 				FTPFile.USER_ACCESS, FTPFile.WRITE_PERMISSION));
183 		assertTrue("Should have user execute permission.", f.hasPermission(
184 				FTPFile.USER_ACCESS, FTPFile.EXECUTE_PERMISSION));
185 		assertTrue("Should have group read permission.", f.hasPermission(
186 				FTPFile.GROUP_ACCESS, FTPFile.READ_PERMISSION));
187 		assertTrue("Should NOT have group write permission.", !f.hasPermission(
188 				FTPFile.GROUP_ACCESS, FTPFile.WRITE_PERMISSION));
189 		assertTrue("Should have group execute permission.", f.hasPermission(
190 				FTPFile.GROUP_ACCESS, FTPFile.EXECUTE_PERMISSION));
191 		assertTrue("Should have world read permission.", f.hasPermission(
192 				FTPFile.WORLD_ACCESS, FTPFile.READ_PERMISSION));
193 		assertTrue("Should NOT have world write permission.", !f.hasPermission(
194 				FTPFile.WORLD_ACCESS, FTPFile.WRITE_PERMISSION));
195 		assertTrue("Should have world execute permission.", f.hasPermission(
196 				FTPFile.WORLD_ACCESS, FTPFile.EXECUTE_PERMISSION));
197 	}
198 
199 	/**
200 	 * @see org.apache.commons.net.ftp.parser.FTPParseTestFramework#testParseFieldsOnFile()
201 	 */
202 	public void testParseFieldsOnFile() throws Exception {
203 		FTPFile f = getParser()
204 				.parseFTPEntry(
205 						"-rwxr-xr-x   2 user     group         5000000000 Mar  2 15:13 zxbox");
206 		assertNotNull("Could not parse entry.", f);
207 		assertTrue("Should have been a file.", f.isFile());
208 		checkPermissions(f);
209 		assertEquals(2, f.getHardLinkCount());
210 		assertEquals("user", f.getUser());
211 		assertEquals("group", f.getGroup());
212 		assertEquals("zxbox", f.getName());
213 		assertEquals(5000000000L, f.getSize());
214 
215 		Calendar cal = Calendar.getInstance();
216 		cal.set(Calendar.MONTH, Calendar.MARCH);
217 
218 		cal.set(Calendar.DATE, 1);
219 		cal.set(Calendar.HOUR_OF_DAY, 0);
220 		cal.set(Calendar.MINUTE, 0);
221 		cal.set(Calendar.SECOND, 0);
222 		if (f.getTimestamp().getTime().before(cal.getTime())) {
223 			cal.add(Calendar.YEAR, -1);
224 		}
225 		cal.set(Calendar.DATE, 2);
226 		cal.set(Calendar.HOUR_OF_DAY, 15);
227 		cal.set(Calendar.MINUTE, 13);
228 		assertEquals(df.format(cal.getTime()), df.format(f.getTimestamp().getTime()));
229 	}
230 	
231 
232 	/**
233 	 * Method suite.
234 	 * @return TestSuite
235 	 */
236 	public static TestSuite suite() {
237 		return (new TestSuite(UnixFTPEntryParserTest.class));
238 	}
239 	
240 	
241     /* 
242      * @param test
243      * @param f
244      */
245     protected void doAdditionalGoodTests(String test, FTPFile f) {
246         String link = f.getLink();
247         if (null != link) {
248             int linklen = link.length();
249             if (linklen > 0) {
250                 assertEquals(link, test.substring(test.length() - linklen));
251                 assertEquals(f.getType(), FTPFile.SYMBOLIC_LINK_TYPE);
252             }
253         }
254         int type = f.getType();
255         switch (test.charAt(0))
256         {
257         case 'd':
258             assertEquals("Type of "+ test, type, FTPFile.DIRECTORY_TYPE);
259             break;
260         case 'l':
261              assertEquals("Type of "+ test, type, FTPFile.SYMBOLIC_LINK_TYPE);
262              break;
263         case 'b':
264         case 'c':
265             assertEquals(0, f.getHardLinkCount());
266         case 'f':
267         case '-':
268             assertEquals("Type of "+ test, type, FTPFile.FILE_TYPE);
269             break;
270         default:
271             assertEquals("Type of "+ test, type, FTPFile.UNKNOWN_TYPE);
272         }
273         
274         for (int access = FTPFile.USER_ACCESS; 
275         	access <= FTPFile.WORLD_ACCESS; access++) 
276         {
277             for (int perm = FTPFile.READ_PERMISSION; 
278             	perm <= FTPFile.EXECUTE_PERMISSION; perm++)
279             {
280                 int pos = 3*access + perm + 1;
281                 char permchar = test.charAt(pos);
282                 assertEquals("Permission " + test.substring(1,10), 
283                         f.hasPermission(access, perm), 
284                         permchar != '-' && !Character.isUpperCase(permchar)); 
285             }
286         }
287 
288     }
289 }