xref: /aoo41x/main/ucb/source/ucp/ftp/ftpdirp.cxx (revision 2f86921c)
1*2f86921cSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*2f86921cSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*2f86921cSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*2f86921cSAndrew Rist  * distributed with this work for additional information
6*2f86921cSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*2f86921cSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*2f86921cSAndrew Rist  * "License"); you may not use this file except in compliance
9*2f86921cSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*2f86921cSAndrew Rist  *
11*2f86921cSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*2f86921cSAndrew Rist  *
13*2f86921cSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*2f86921cSAndrew Rist  * software distributed under the License is distributed on an
15*2f86921cSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*2f86921cSAndrew Rist  * KIND, either express or implied.  See the License for the
17*2f86921cSAndrew Rist  * specific language governing permissions and limitations
18*2f86921cSAndrew Rist  * under the License.
19*2f86921cSAndrew Rist  *
20*2f86921cSAndrew Rist  *************************************************************/
21*2f86921cSAndrew Rist 
22*2f86921cSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_ucb.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir /**************************************************************************
28cdf0e10cSrcweir                                 TODO
29cdf0e10cSrcweir  **************************************************************************
30cdf0e10cSrcweir 
31cdf0e10cSrcweir  *************************************************************************/
32cdf0e10cSrcweir #include "ftpdirp.hxx"
33cdf0e10cSrcweir #include <osl/time.h>
34cdf0e10cSrcweir 
35cdf0e10cSrcweir 
36cdf0e10cSrcweir using namespace rtl;
37cdf0e10cSrcweir using namespace ftp;
38cdf0e10cSrcweir 
39cdf0e10cSrcweir 
40cdf0e10cSrcweir typedef sal_uInt32 ULONG;
41cdf0e10cSrcweir 
42cdf0e10cSrcweir 
ascii_isLetter(sal_Unicode ch)43cdf0e10cSrcweir inline sal_Bool ascii_isLetter( sal_Unicode ch )
44cdf0e10cSrcweir {
45cdf0e10cSrcweir     return (( (ch >= 0x0041) && (ch <= 0x005A)) ||
46cdf0e10cSrcweir             (( ch >= 0x0061) && (ch <= 0x007A)));
47cdf0e10cSrcweir }
48cdf0e10cSrcweir 
ascii_isWhitespace(sal_Unicode ch)49cdf0e10cSrcweir inline sal_Bool ascii_isWhitespace( sal_Unicode ch )
50cdf0e10cSrcweir {
51cdf0e10cSrcweir     return ((ch <= 0x20) && ch);
52cdf0e10cSrcweir }
53cdf0e10cSrcweir 
54cdf0e10cSrcweir 
55cdf0e10cSrcweir 
56cdf0e10cSrcweir /*========================================================================
57cdf0e10cSrcweir  *
58cdf0e10cSrcweir  * FTPDirectoryParser implementation.
59cdf0e10cSrcweir  *
60cdf0e10cSrcweir  *======================================================================*/
61cdf0e10cSrcweir /*
62cdf0e10cSrcweir  * parseDOS.
63cdf0e10cSrcweir  * Accepts one of two styles:
64cdf0e10cSrcweir  *
65cdf0e10cSrcweir  * 1  *WSP 1*2DIGIT ("." / "-") 1*2DIGIT ("." / "-") 1*4DIGIT 1*WSP
66cdf0e10cSrcweir  *    1*2DIGIT ":" 1*2DIGIT [*WSP ("A" / "P") "M"] 1*WSP
67cdf0e10cSrcweir  *    ((DIGIT *(DIGIT / "." / ",")) / "<DIR>") 1*WSP 1*OCTET
68cdf0e10cSrcweir  *
69cdf0e10cSrcweir  *    interpreted as: mm.dd.yy hh:mm (size / <DIR>) name
70cdf0e10cSrcweir  *
71cdf0e10cSrcweir  * 2  *WSP 1*DIGIT 1*WSP *(1*CHAR *WSP) *1("DIR" 1*WSP) 1*2DIGIT "-" 1*2DIGIT
72cdf0e10cSrcweir  *    "-" 1*4DIGIT 1*WSP 1*2DIGIT ":" 1*2DIGIT 1*WSP 1*OCTET
73cdf0e10cSrcweir  *
74cdf0e10cSrcweir  *    interpreted as: size attribs DIR mm-dd-yy hh:mm name
75cdf0e10cSrcweir  */
76cdf0e10cSrcweir 
parseDOS(FTPDirentry & rEntry,const sal_Char * pBuffer)77cdf0e10cSrcweir sal_Bool FTPDirectoryParser::parseDOS (
78cdf0e10cSrcweir     FTPDirentry &rEntry,
79cdf0e10cSrcweir     const sal_Char  *pBuffer)
80cdf0e10cSrcweir {
81cdf0e10cSrcweir     sal_Bool   bDirectory = false;
82cdf0e10cSrcweir     sal_uInt32 nSize = 0;
83cdf0e10cSrcweir     sal_uInt16 nYear = 0;
84cdf0e10cSrcweir     sal_uInt16 nMonth = 0;
85cdf0e10cSrcweir     sal_uInt16 nDay = 0;
86cdf0e10cSrcweir     sal_uInt16 nHour = 0;
87cdf0e10cSrcweir     sal_uInt16 nMinute = 0;
88cdf0e10cSrcweir 
89cdf0e10cSrcweir     enum StateType
90cdf0e10cSrcweir     {
91cdf0e10cSrcweir         STATE_INIT_LWS,
92cdf0e10cSrcweir         STATE_MONTH_OR_SIZE,
93cdf0e10cSrcweir         STATE_1_DAY, STATE_1_YEAR, STATE_1_YEAR_LWS, STATE_1_HOUR,
94cdf0e10cSrcweir         STATE_1_MINUTE, STATE_1_MINUTE_LWS, STATE_1_AP,
95cdf0e10cSrcweir         STATE_1_APM, STATE_1_LESS, STATE_1_D, STATE_1_DI,
96cdf0e10cSrcweir         STATE_1_DIR, STATE_1_SIZE,
97cdf0e10cSrcweir         STATE_2_SIZE, STATE_2_SIZE_LWS, STATE_2_ATTRIB,
98cdf0e10cSrcweir         STATE_2_D, STATE_2_DI, STATE_2_DIR_LWS,
99cdf0e10cSrcweir         STATE_2_MONTH, STATE_2_DAY, STATE_2_YEAR, STATE_2_YEAR_LWS,
100cdf0e10cSrcweir         STATE_2_HOUR, STATE_2_MINUTE,
101cdf0e10cSrcweir         STATE_LWS_NAME,
102cdf0e10cSrcweir         STATE_ERROR
103cdf0e10cSrcweir     };
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     int nDigits = 0;
106cdf0e10cSrcweir     enum StateType eState = STATE_INIT_LWS;
107cdf0e10cSrcweir     for (const sal_Char *p = pBuffer;
108cdf0e10cSrcweir          eState != STATE_ERROR && *p;
109cdf0e10cSrcweir          ++p)
110cdf0e10cSrcweir     {
111cdf0e10cSrcweir         switch (eState)
112cdf0e10cSrcweir         {
113cdf0e10cSrcweir             case STATE_INIT_LWS:
114cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
115cdf0e10cSrcweir                 {
116cdf0e10cSrcweir                     nMonth = *p - '0';
117cdf0e10cSrcweir                     nDigits = 1;
118cdf0e10cSrcweir                     eState = STATE_MONTH_OR_SIZE;
119cdf0e10cSrcweir                 }
120cdf0e10cSrcweir                 else if (!ascii_isWhitespace(*p))
121cdf0e10cSrcweir                     eState = STATE_ERROR;
122cdf0e10cSrcweir                 break;
123cdf0e10cSrcweir 
124cdf0e10cSrcweir             case STATE_MONTH_OR_SIZE:
125cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
126cdf0e10cSrcweir                 {
127cdf0e10cSrcweir                     nMonth = 10 * nMonth + (*p - '0');
128cdf0e10cSrcweir                     if (nDigits < 2)
129cdf0e10cSrcweir                         ++nDigits;
130cdf0e10cSrcweir                     else
131cdf0e10cSrcweir                     {
132cdf0e10cSrcweir                         nSize = nMonth;
133cdf0e10cSrcweir                         nMonth = 0;
134cdf0e10cSrcweir                         eState = STATE_2_SIZE;
135cdf0e10cSrcweir                     }
136cdf0e10cSrcweir                 }
137cdf0e10cSrcweir                 else if (ascii_isWhitespace(*p))
138cdf0e10cSrcweir                 {
139cdf0e10cSrcweir                     nSize = nMonth;
140cdf0e10cSrcweir                     nMonth = 0;
141cdf0e10cSrcweir                     eState = STATE_2_SIZE_LWS;
142cdf0e10cSrcweir                 }
143cdf0e10cSrcweir                 else if ((*p == '.' || *p == '-') && nMonth && nMonth <= 12)
144cdf0e10cSrcweir                 {
145cdf0e10cSrcweir                     nDigits = 0;
146cdf0e10cSrcweir                     eState = STATE_1_DAY;
147cdf0e10cSrcweir                 }
148cdf0e10cSrcweir                 else
149cdf0e10cSrcweir                     eState = STATE_ERROR;
150cdf0e10cSrcweir                 break;
151cdf0e10cSrcweir 
152cdf0e10cSrcweir             case STATE_1_DAY:
153cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
154cdf0e10cSrcweir                     if (nDigits < 2)
155cdf0e10cSrcweir                     {
156cdf0e10cSrcweir                         nDay = 10 * nDay + (*p - '0');
157cdf0e10cSrcweir                         ++nDigits;
158cdf0e10cSrcweir                     }
159cdf0e10cSrcweir                     else
160cdf0e10cSrcweir                         eState = STATE_ERROR;
161cdf0e10cSrcweir                 else if ((*p == '.' || *p == '-') && nDay && nDay <= 31)
162cdf0e10cSrcweir                 {
163cdf0e10cSrcweir                     nDigits = 0;
164cdf0e10cSrcweir                     eState = STATE_1_YEAR;
165cdf0e10cSrcweir                 }
166cdf0e10cSrcweir                 else
167cdf0e10cSrcweir                     eState = STATE_ERROR;
168cdf0e10cSrcweir                 break;
169cdf0e10cSrcweir 
170cdf0e10cSrcweir             case STATE_1_YEAR:
171cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
172cdf0e10cSrcweir                 {
173cdf0e10cSrcweir                     if (nDigits < 4)
174cdf0e10cSrcweir                     {
175cdf0e10cSrcweir                         nYear = 10 * nYear + (*p - '0');
176cdf0e10cSrcweir                         ++nDigits;
177cdf0e10cSrcweir                     }
178cdf0e10cSrcweir                     else
179cdf0e10cSrcweir                         eState = STATE_ERROR;
180cdf0e10cSrcweir                 }
181cdf0e10cSrcweir                 else
182cdf0e10cSrcweir                 {
183cdf0e10cSrcweir                     if (ascii_isWhitespace(*p))
184cdf0e10cSrcweir                         eState = STATE_1_YEAR_LWS;
185cdf0e10cSrcweir                     else
186cdf0e10cSrcweir                         eState = STATE_ERROR;
187cdf0e10cSrcweir                 }
188cdf0e10cSrcweir                 break;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir             case STATE_1_YEAR_LWS:
191cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
192cdf0e10cSrcweir                 {
193cdf0e10cSrcweir                     nHour = *p - '0';
194cdf0e10cSrcweir                     nDigits = 1;
195cdf0e10cSrcweir                     eState = STATE_1_HOUR;
196cdf0e10cSrcweir                 }
197cdf0e10cSrcweir                 else if (!ascii_isWhitespace(*p))
198cdf0e10cSrcweir                     eState = STATE_ERROR;
199cdf0e10cSrcweir                 break;
200cdf0e10cSrcweir 
201cdf0e10cSrcweir             case STATE_1_HOUR:
202cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
203cdf0e10cSrcweir                     if (nDigits < 2)
204cdf0e10cSrcweir                     {
205cdf0e10cSrcweir                         nHour = 10 * nHour + (*p - '0');
206cdf0e10cSrcweir                         ++nDigits;
207cdf0e10cSrcweir                     }
208cdf0e10cSrcweir                     else
209cdf0e10cSrcweir                         eState = STATE_ERROR;
210cdf0e10cSrcweir                 else if (*p == ':' && nHour < 24)
211cdf0e10cSrcweir                 {
212cdf0e10cSrcweir                     nDigits = 0;
213cdf0e10cSrcweir                     eState = STATE_1_MINUTE;
214cdf0e10cSrcweir                 }
215cdf0e10cSrcweir                 else
216cdf0e10cSrcweir                     eState = STATE_ERROR;
217cdf0e10cSrcweir                 break;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir             case STATE_1_MINUTE:
220cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
221cdf0e10cSrcweir                     if (nDigits < 2)
222cdf0e10cSrcweir                     {
223cdf0e10cSrcweir                         nMinute = 10 * nMinute + (*p - '0');
224cdf0e10cSrcweir                         ++nDigits;
225cdf0e10cSrcweir                     }
226cdf0e10cSrcweir                     else
227cdf0e10cSrcweir                         eState = STATE_ERROR;
228cdf0e10cSrcweir                 else if ((*p == 'a' || *p == 'A') && nMinute < 60)
229cdf0e10cSrcweir                     if (nHour >= 1 && nHour <= 11)
230cdf0e10cSrcweir                         eState = STATE_1_AP;
231cdf0e10cSrcweir                     else if (nHour == 12)
232cdf0e10cSrcweir                     {
233cdf0e10cSrcweir                         nHour = 0;
234cdf0e10cSrcweir                         eState = STATE_1_AP;
235cdf0e10cSrcweir                     }
236cdf0e10cSrcweir                     else
237cdf0e10cSrcweir                         eState = STATE_ERROR;
238cdf0e10cSrcweir                 else if ((*p == 'p' || *p == 'P') && nMinute < 60)
239cdf0e10cSrcweir                     if (nHour >= 1 && nHour <= 11)
240cdf0e10cSrcweir                     {
241cdf0e10cSrcweir                         nHour += 12;
242cdf0e10cSrcweir                         eState = STATE_1_AP;
243cdf0e10cSrcweir                     }
244cdf0e10cSrcweir                     else if (nHour == 12)
245cdf0e10cSrcweir                         eState = STATE_1_AP;
246cdf0e10cSrcweir                     else
247cdf0e10cSrcweir                         eState = STATE_ERROR;
248cdf0e10cSrcweir                 else if (ascii_isWhitespace(*p) && (nMinute < 60))
249cdf0e10cSrcweir                     eState = STATE_1_MINUTE_LWS;
250cdf0e10cSrcweir                 else
251cdf0e10cSrcweir                     eState = STATE_ERROR;
252cdf0e10cSrcweir                 break;
253cdf0e10cSrcweir 
254cdf0e10cSrcweir             case STATE_1_MINUTE_LWS:
255cdf0e10cSrcweir                 if (*p == 'a' || *p == 'A')
256cdf0e10cSrcweir                     if (nHour >= 1 && nHour <= 11)
257cdf0e10cSrcweir                         eState = STATE_1_AP;
258cdf0e10cSrcweir                     else if (nHour == 12)
259cdf0e10cSrcweir                     {
260cdf0e10cSrcweir                         nHour = 0;
261cdf0e10cSrcweir                         eState = STATE_1_AP;
262cdf0e10cSrcweir                     }
263cdf0e10cSrcweir                     else
264cdf0e10cSrcweir                         eState = STATE_ERROR;
265cdf0e10cSrcweir                 else if (*p == 'p' || *p == 'P')
266cdf0e10cSrcweir                     if (nHour >= 1 && nHour <= 11)
267cdf0e10cSrcweir                     {
268cdf0e10cSrcweir                         nHour += 12;
269cdf0e10cSrcweir                         eState = STATE_1_AP;
270cdf0e10cSrcweir                     }
271cdf0e10cSrcweir                     else if (nHour == 12)
272cdf0e10cSrcweir                         eState = STATE_1_AP;
273cdf0e10cSrcweir                     else
274cdf0e10cSrcweir                         eState = STATE_ERROR;
275cdf0e10cSrcweir                 else if (*p == '<')
276cdf0e10cSrcweir                     eState = STATE_1_LESS;
277cdf0e10cSrcweir                 else if (*p >= '0' && *p <= '9')
278cdf0e10cSrcweir                 {
279cdf0e10cSrcweir                     nSize = *p - '0';
280cdf0e10cSrcweir                     eState = STATE_1_SIZE;
281cdf0e10cSrcweir                 }
282cdf0e10cSrcweir                 else if (!ascii_isWhitespace(*p))
283cdf0e10cSrcweir                     eState = STATE_ERROR;
284cdf0e10cSrcweir                 break;
285cdf0e10cSrcweir 
286cdf0e10cSrcweir             case STATE_1_AP:
287cdf0e10cSrcweir                 eState = *p == 'm' || *p == 'M' ? STATE_1_APM : STATE_ERROR;
288cdf0e10cSrcweir                 break;
289cdf0e10cSrcweir 
290cdf0e10cSrcweir             case STATE_1_APM:
291cdf0e10cSrcweir                 if (*p == '<')
292cdf0e10cSrcweir                     eState = STATE_1_LESS;
293cdf0e10cSrcweir                 else if (*p >= '0' && *p <= '9')
294cdf0e10cSrcweir                 {
295cdf0e10cSrcweir                     nSize = *p - '0';
296cdf0e10cSrcweir                     eState = STATE_1_SIZE;
297cdf0e10cSrcweir                 }
298cdf0e10cSrcweir                 else if (!ascii_isWhitespace(*p))
299cdf0e10cSrcweir                     eState = STATE_ERROR;
300cdf0e10cSrcweir                 break;
301cdf0e10cSrcweir 
302cdf0e10cSrcweir             case STATE_1_LESS:
303cdf0e10cSrcweir                 eState = *p == 'd' || *p == 'D' ? STATE_1_D : STATE_ERROR;
304cdf0e10cSrcweir                 break;
305cdf0e10cSrcweir 
306cdf0e10cSrcweir             case STATE_1_D:
307cdf0e10cSrcweir                 eState = *p == 'i' || *p == 'I' ? STATE_1_DI : STATE_ERROR;
308cdf0e10cSrcweir                 break;
309cdf0e10cSrcweir 
310cdf0e10cSrcweir             case STATE_1_DI:
311cdf0e10cSrcweir                 eState = *p == 'r' || *p == 'R' ? STATE_1_DIR : STATE_ERROR;
312cdf0e10cSrcweir                 break;
313cdf0e10cSrcweir 
314cdf0e10cSrcweir             case STATE_1_DIR:
315cdf0e10cSrcweir                 if (*p == '>')
316cdf0e10cSrcweir                 {
317cdf0e10cSrcweir                     bDirectory = true;
318cdf0e10cSrcweir                     eState = STATE_LWS_NAME;
319cdf0e10cSrcweir                 }
320cdf0e10cSrcweir                 else
321cdf0e10cSrcweir                     eState = STATE_ERROR;
322cdf0e10cSrcweir                 break;
323cdf0e10cSrcweir 
324cdf0e10cSrcweir             case STATE_1_SIZE:
325cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
326cdf0e10cSrcweir                     nSize = 10 * nSize + (*p - '0');
327cdf0e10cSrcweir                 else if (ascii_isWhitespace(*p))
328cdf0e10cSrcweir                     eState = STATE_LWS_NAME;
329cdf0e10cSrcweir                 else
330cdf0e10cSrcweir                     eState = STATE_ERROR;
331cdf0e10cSrcweir                 break;
332cdf0e10cSrcweir 
333cdf0e10cSrcweir             case STATE_2_SIZE:
334cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
335cdf0e10cSrcweir                     nSize = 10 * nSize + (*p - '0');
336cdf0e10cSrcweir                 else if (ascii_isWhitespace(*p))
337cdf0e10cSrcweir                     eState = STATE_2_SIZE_LWS;
338cdf0e10cSrcweir                 else
339cdf0e10cSrcweir                     eState = STATE_ERROR;
340cdf0e10cSrcweir                 break;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir             case STATE_2_SIZE_LWS:
343cdf0e10cSrcweir                 if (*p == 'd' || *p == 'D')
344cdf0e10cSrcweir                     eState = STATE_2_D;
345cdf0e10cSrcweir                 else if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z'))
346cdf0e10cSrcweir                     eState = STATE_2_ATTRIB;
347cdf0e10cSrcweir                 else if (*p >= '0' && *p <= '9')
348cdf0e10cSrcweir                 {
349cdf0e10cSrcweir                     nMonth = *p - '0';
350cdf0e10cSrcweir                     nDigits = 1;
351cdf0e10cSrcweir                     eState = STATE_2_MONTH;
352cdf0e10cSrcweir                 }
353cdf0e10cSrcweir                 else if (!ascii_isWhitespace(*p))
354cdf0e10cSrcweir                     eState = STATE_ERROR;
355cdf0e10cSrcweir                 break;
356cdf0e10cSrcweir 
357cdf0e10cSrcweir             case STATE_2_ATTRIB:
358cdf0e10cSrcweir                 if (ascii_isWhitespace(*p))
359cdf0e10cSrcweir                     eState = STATE_2_SIZE_LWS;
360cdf0e10cSrcweir                 else if ((*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z'))
361cdf0e10cSrcweir                     eState = STATE_ERROR;
362cdf0e10cSrcweir                 break;
363cdf0e10cSrcweir 
364cdf0e10cSrcweir             case STATE_2_D:
365cdf0e10cSrcweir                 if (*p == 'i' || *p == 'I')
366cdf0e10cSrcweir                     eState = STATE_2_DI;
367cdf0e10cSrcweir                 else if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z'))
368cdf0e10cSrcweir                     eState = STATE_2_ATTRIB;
369cdf0e10cSrcweir                 else if (ascii_isWhitespace(*p))
370cdf0e10cSrcweir                     eState = STATE_2_SIZE_LWS;
371cdf0e10cSrcweir                 else
372cdf0e10cSrcweir                     eState = STATE_ERROR;
373cdf0e10cSrcweir                 break;
374cdf0e10cSrcweir 
375cdf0e10cSrcweir             case STATE_2_DI:
376cdf0e10cSrcweir                 if (*p == 'r' || *p == 'R')
377cdf0e10cSrcweir                 {
378cdf0e10cSrcweir                     bDirectory = true;
379cdf0e10cSrcweir                     eState = STATE_2_DIR_LWS;
380cdf0e10cSrcweir                 }
381cdf0e10cSrcweir                 else
382cdf0e10cSrcweir                 {
383cdf0e10cSrcweir                     if ((*p >= 'a' && *p <= 'z') || (*p >= 'A' && *p <= 'Z'))
384cdf0e10cSrcweir                         eState = STATE_2_ATTRIB;
385cdf0e10cSrcweir                     else if (ascii_isWhitespace(*p))
386cdf0e10cSrcweir                         eState = STATE_2_SIZE_LWS;
387cdf0e10cSrcweir                     else
388cdf0e10cSrcweir                         eState = STATE_ERROR;
389cdf0e10cSrcweir                 }
390cdf0e10cSrcweir                 break;
391cdf0e10cSrcweir 
392cdf0e10cSrcweir             case STATE_2_DIR_LWS:
393cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
394cdf0e10cSrcweir                 {
395cdf0e10cSrcweir                     nMonth = *p - '0';
396cdf0e10cSrcweir                     nDigits = 1;
397cdf0e10cSrcweir                     eState = STATE_2_MONTH;
398cdf0e10cSrcweir                 }
399cdf0e10cSrcweir                 else if (!ascii_isWhitespace(*p))
400cdf0e10cSrcweir                     eState = STATE_ERROR;
401cdf0e10cSrcweir                 break;
402cdf0e10cSrcweir 
403cdf0e10cSrcweir             case STATE_2_MONTH:
404cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
405cdf0e10cSrcweir                     if (nDigits < 2)
406cdf0e10cSrcweir                     {
407cdf0e10cSrcweir                         nMonth = 10 * nMonth + (*p - '0');
408cdf0e10cSrcweir                         ++nDigits;
409cdf0e10cSrcweir                     }
410cdf0e10cSrcweir                     else
411cdf0e10cSrcweir                         eState = STATE_ERROR;
412cdf0e10cSrcweir                 else if (*p == '-' && nMonth && nMonth <= 12)
413cdf0e10cSrcweir                 {
414cdf0e10cSrcweir                     nDigits = 0;
415cdf0e10cSrcweir                     eState = STATE_2_DAY;
416cdf0e10cSrcweir                 }
417cdf0e10cSrcweir                 else
418cdf0e10cSrcweir                     eState = STATE_ERROR;
419cdf0e10cSrcweir                 break;
420cdf0e10cSrcweir 
421cdf0e10cSrcweir             case STATE_2_DAY:
422cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
423cdf0e10cSrcweir                     if (nDigits < 2)
424cdf0e10cSrcweir                     {
425cdf0e10cSrcweir                         nDay = 10 * nDay + (*p - '0');
426cdf0e10cSrcweir                         ++nDigits;
427cdf0e10cSrcweir                     }
428cdf0e10cSrcweir                     else
429cdf0e10cSrcweir                         eState = STATE_ERROR;
430cdf0e10cSrcweir                 else if (*p == '-' && nDay && nDay <= 31)
431cdf0e10cSrcweir                 {
432cdf0e10cSrcweir                     nDigits = 0;
433cdf0e10cSrcweir                     eState = STATE_2_YEAR;
434cdf0e10cSrcweir                 }
435cdf0e10cSrcweir                 else
436cdf0e10cSrcweir                     eState = STATE_ERROR;
437cdf0e10cSrcweir                 break;
438cdf0e10cSrcweir 
439cdf0e10cSrcweir             case STATE_2_YEAR:
440cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
441cdf0e10cSrcweir                 {
442cdf0e10cSrcweir                     if (nDigits < 4)
443cdf0e10cSrcweir                     {
444cdf0e10cSrcweir                         nYear = 10 * nYear + (*p - '0');
445cdf0e10cSrcweir                         ++nDigits;
446cdf0e10cSrcweir                     }
447cdf0e10cSrcweir                     else
448cdf0e10cSrcweir                         eState = STATE_ERROR;
449cdf0e10cSrcweir                 }
450cdf0e10cSrcweir                 else
451cdf0e10cSrcweir                 {
452cdf0e10cSrcweir                     if (ascii_isWhitespace(*p))
453cdf0e10cSrcweir                         eState = STATE_2_YEAR_LWS;
454cdf0e10cSrcweir                     else
455cdf0e10cSrcweir                         eState = STATE_ERROR;
456cdf0e10cSrcweir                 }
457cdf0e10cSrcweir                 break;
458cdf0e10cSrcweir 
459cdf0e10cSrcweir             case STATE_2_YEAR_LWS:
460cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
461cdf0e10cSrcweir                 {
462cdf0e10cSrcweir                     nHour = *p - '0';
463cdf0e10cSrcweir                     nDigits = 1;
464cdf0e10cSrcweir                     eState = STATE_2_HOUR;
465cdf0e10cSrcweir                 }
466cdf0e10cSrcweir                 else if (!ascii_isWhitespace(*p))
467cdf0e10cSrcweir                     eState = STATE_ERROR;
468cdf0e10cSrcweir                 break;
469cdf0e10cSrcweir 
470cdf0e10cSrcweir             case STATE_2_HOUR:
471cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
472cdf0e10cSrcweir                     if (nDigits < 2)
473cdf0e10cSrcweir                     {
474cdf0e10cSrcweir                         nHour = 10 * nHour + (*p - '0');
475cdf0e10cSrcweir                         ++nDigits;
476cdf0e10cSrcweir                     }
477cdf0e10cSrcweir                     else
478cdf0e10cSrcweir                         eState = STATE_ERROR;
479cdf0e10cSrcweir                 else if (*p == ':' && nHour < 24)
480cdf0e10cSrcweir                 {
481cdf0e10cSrcweir                     nDigits = 0;
482cdf0e10cSrcweir                     eState = STATE_2_MINUTE;
483cdf0e10cSrcweir                 }
484cdf0e10cSrcweir                 else
485cdf0e10cSrcweir                     eState = STATE_ERROR;
486cdf0e10cSrcweir                 break;
487cdf0e10cSrcweir 
488cdf0e10cSrcweir             case STATE_2_MINUTE:
489cdf0e10cSrcweir                 if (*p >= '0' && *p <= '9')
490cdf0e10cSrcweir                 {
491cdf0e10cSrcweir                     if (nDigits < 2)
492cdf0e10cSrcweir                     {
493cdf0e10cSrcweir                         nMinute = 10 * nMinute + (*p - '0');
494cdf0e10cSrcweir                         ++nDigits;
495cdf0e10cSrcweir                     }
496cdf0e10cSrcweir                     else
497cdf0e10cSrcweir                         eState = STATE_ERROR;
498cdf0e10cSrcweir                 }
499cdf0e10cSrcweir                 else
500cdf0e10cSrcweir                 {
501cdf0e10cSrcweir                     if (ascii_isWhitespace(*p) && (nMinute < 60))
502cdf0e10cSrcweir                         eState = STATE_LWS_NAME;
503cdf0e10cSrcweir                     else
504cdf0e10cSrcweir                         eState = STATE_ERROR;
505cdf0e10cSrcweir                 }
506cdf0e10cSrcweir                 break;
507cdf0e10cSrcweir 
508cdf0e10cSrcweir             case STATE_LWS_NAME:
509cdf0e10cSrcweir                 if (!ascii_isWhitespace(*p))
510cdf0e10cSrcweir                 {
511cdf0e10cSrcweir                     setPath (rEntry.m_aName, p);
512cdf0e10cSrcweir                     if (bDirectory)
513cdf0e10cSrcweir                         rEntry.m_nMode |= INETCOREFTP_FILEMODE_ISDIR;
514cdf0e10cSrcweir                     rEntry.m_nSize = nSize;
515cdf0e10cSrcweir 
516cdf0e10cSrcweir                     setYear (rEntry.m_aDate, nYear);
517cdf0e10cSrcweir 
518cdf0e10cSrcweir                     rEntry.m_aDate.SetMonth(nMonth);
519cdf0e10cSrcweir                     rEntry.m_aDate.SetDay(nDay);
520cdf0e10cSrcweir                     rEntry.m_aDate.SetHour(nHour);
521cdf0e10cSrcweir                     rEntry.m_aDate.SetMin(nMinute);
522cdf0e10cSrcweir 
523cdf0e10cSrcweir                     return sal_True;
524cdf0e10cSrcweir                 }
525cdf0e10cSrcweir                 break;
526cdf0e10cSrcweir             case STATE_ERROR:
527cdf0e10cSrcweir                 break;
528cdf0e10cSrcweir         }
529cdf0e10cSrcweir     }
530cdf0e10cSrcweir 
531cdf0e10cSrcweir     return sal_False;
532cdf0e10cSrcweir }
533cdf0e10cSrcweir 
534cdf0e10cSrcweir /*
535cdf0e10cSrcweir  * parseVMS.
536cdf0e10cSrcweir  * Directory entries may span one or two lines:
537cdf0e10cSrcweir  *
538cdf0e10cSrcweir  *   entry: *lws name *1(*lws <NEWLINE>) 1*lws size 1*lws datetime rest
539cdf0e10cSrcweir  *
540cdf0e10cSrcweir  *   name: filename "." filetype ";" version
541cdf0e10cSrcweir  *   filename: 1*39fchar
542cdf0e10cSrcweir  *   filetype: 1*39fchar
543cdf0e10cSrcweir  *   version: non0digit *digit
544cdf0e10cSrcweir  *
545cdf0e10cSrcweir  *   size: "0" / non0digit *digit
546cdf0e10cSrcweir  *
547cdf0e10cSrcweir  *   datetime: date 1*lwsp time
548cdf0e10cSrcweir  *   date: day "-" month "-" year
549cdf0e10cSrcweir  *   day: (*1"0" non0digit) / ("1"-"2" digit) / ("3" "0"-"1")
550cdf0e10cSrcweir  *   month: "JAN" / "FEB" / "MAR" / "APR" / "MAY" / "JUN" / "JUL" / "AUG"
551cdf0e10cSrcweir  *        / "SEP" / "OCT" / "NOV" / "DEC" ; all case insensitive
552cdf0e10cSrcweir  *   year: 2digit / 4digit
553cdf0e10cSrcweir  *   time: hour ":" minute
554cdf0e10cSrcweir  *   hour: ((*1"0" / "1") digit) / ("2" "0"-"3")
555cdf0e10cSrcweir  *   minute: "0"-"5" digit
556cdf0e10cSrcweir  *
557cdf0e10cSrcweir  *   rest: *1(lws *<ANY>)
558cdf0e10cSrcweir  *
559cdf0e10cSrcweir  *   lws: <TAB> / <SPACE>
560cdf0e10cSrcweir  *   non0digit: "1"-"9"
561cdf0e10cSrcweir  *   digit: "0" / non0digit
562cdf0e10cSrcweir  *   fchar: "A"-"Z" / "a"-"z" / digit / "-" / "_" / "$"
563cdf0e10cSrcweir  *
564cdf0e10cSrcweir  * For directories, the returned name is the <filename> part; for non-
565cdf0e10cSrcweir  * directory files, the returned name is the <filename "." filetype> part.
566cdf0e10cSrcweir  * An entry is a directory iff its filetype is "DIR" (ignoring case).
567cdf0e10cSrcweir  *
568cdf0e10cSrcweir  * The READ, WRITE, and ISLINK mode bits are not supported.
569cdf0e10cSrcweir  *
570cdf0e10cSrcweir  * The returned size is the <size> part, multiplied by 512, and with the high
571cdf0e10cSrcweir  * order bits truncated to fit into a ULONG.
572cdf0e10cSrcweir  *
573cdf0e10cSrcweir  */
parseVMS(FTPDirentry & rEntry,const sal_Char * pBuffer)574cdf0e10cSrcweir sal_Bool FTPDirectoryParser::parseVMS (
575cdf0e10cSrcweir     FTPDirentry &rEntry,
576cdf0e10cSrcweir     const sal_Char  *pBuffer)
577cdf0e10cSrcweir {
578cdf0e10cSrcweir     static OUString aFirstLineName;
579cdf0e10cSrcweir     static sal_Bool bFirstLineDir = sal_False;
580cdf0e10cSrcweir 
581cdf0e10cSrcweir     for (sal_Bool bFirstLine = sal_True;; bFirstLine = sal_False)
582cdf0e10cSrcweir     {
583cdf0e10cSrcweir         const sal_Char *p = pBuffer;
584cdf0e10cSrcweir         if (bFirstLine)
585cdf0e10cSrcweir         {
586cdf0e10cSrcweir             // Skip <*lws> part:
587cdf0e10cSrcweir             while (*p == '\t' || *p == ' ')
588cdf0e10cSrcweir                 ++p;
589cdf0e10cSrcweir 
590cdf0e10cSrcweir             // Parse <filename "."> part:
591cdf0e10cSrcweir             const sal_Char *pFileName = p;
592cdf0e10cSrcweir             while ((*p >= 'A' && *p <= 'Z') ||
593cdf0e10cSrcweir                    (*p >= 'a' && *p <= 'z') ||
594cdf0e10cSrcweir                    (*p >= '0' && *p <= '9') ||
595cdf0e10cSrcweir                    *p == '-' || *p == '_' || *p == '$')
596cdf0e10cSrcweir                 ++p;
597cdf0e10cSrcweir 
598cdf0e10cSrcweir             if (*p != '.' || p == pFileName || p - pFileName > 39)
599cdf0e10cSrcweir             {
600cdf0e10cSrcweir                 if (aFirstLineName.getLength())
601cdf0e10cSrcweir                     continue;
602cdf0e10cSrcweir                 else
603cdf0e10cSrcweir                     return sal_False;
604cdf0e10cSrcweir             }
605cdf0e10cSrcweir 
606cdf0e10cSrcweir             // Parse <filetype ";"> part:
607cdf0e10cSrcweir             const sal_Char *pFileType = ++p;
608cdf0e10cSrcweir             while ((*p >= 'A' && *p <= 'Z') ||
609cdf0e10cSrcweir                    (*p >= 'a' && *p <= 'z') ||
610cdf0e10cSrcweir                    (*p >= '0' && *p <= '9') ||
611cdf0e10cSrcweir                    *p == '-' || *p == '_' || *p == '$')
612cdf0e10cSrcweir                 ++p;
613cdf0e10cSrcweir 
614cdf0e10cSrcweir             if (*p != ';' || p == pFileName || p - pFileName > 39)
615cdf0e10cSrcweir             {
616cdf0e10cSrcweir                 if (aFirstLineName.getLength())
617cdf0e10cSrcweir                     continue;
618cdf0e10cSrcweir                 else
619cdf0e10cSrcweir                     return sal_False;
620cdf0e10cSrcweir             }
621cdf0e10cSrcweir             ++p;
622cdf0e10cSrcweir 
623cdf0e10cSrcweir             // Set entry's name and mode (ISDIR flag):
624cdf0e10cSrcweir             if ((p - pFileType == 4) &&
625cdf0e10cSrcweir                 (pFileType[0] == 'D' || pFileType[0] == 'd') &&
626cdf0e10cSrcweir                 (pFileType[1] == 'I' || pFileType[1] == 'i') &&
627cdf0e10cSrcweir                 (pFileType[2] == 'R' || pFileType[2] == 'r')    )
628cdf0e10cSrcweir             {
629cdf0e10cSrcweir                 setPath (rEntry.m_aName, pFileName, (pFileType - pFileName));
630cdf0e10cSrcweir                 rEntry.m_nMode = INETCOREFTP_FILEMODE_ISDIR;
631cdf0e10cSrcweir             }
632cdf0e10cSrcweir             else
633cdf0e10cSrcweir             {
634cdf0e10cSrcweir                 setPath (rEntry.m_aName, pFileName, (p - pFileName));
635cdf0e10cSrcweir                 rEntry.m_nMode = 0;
636cdf0e10cSrcweir             }
637cdf0e10cSrcweir 
638cdf0e10cSrcweir             // Skip <version> part:
639cdf0e10cSrcweir             if (*p < '1' || *p > '9')
640cdf0e10cSrcweir             {
641cdf0e10cSrcweir                 if (aFirstLineName.getLength())
642cdf0e10cSrcweir                     continue;
643cdf0e10cSrcweir                 else
644cdf0e10cSrcweir                     return sal_False;
645cdf0e10cSrcweir             }
646cdf0e10cSrcweir             ++p;
647cdf0e10cSrcweir             while (*p >= '0' && *p <= '9')
648cdf0e10cSrcweir                 ++p;
649cdf0e10cSrcweir 
650cdf0e10cSrcweir             // Parse <1*lws> or <*lws <NEWLINE>> part:
651cdf0e10cSrcweir             sal_Bool bLWS = false;
652cdf0e10cSrcweir             while (*p == '\t' || *p == ' ')
653cdf0e10cSrcweir             {
654cdf0e10cSrcweir                 bLWS = true;
655cdf0e10cSrcweir                 ++p;
656cdf0e10cSrcweir             }
657cdf0e10cSrcweir             if (*p)
658cdf0e10cSrcweir             {
659cdf0e10cSrcweir                 if (!bLWS)
660cdf0e10cSrcweir                 {
661cdf0e10cSrcweir                     if (aFirstLineName.getLength())
662cdf0e10cSrcweir                         continue;
663cdf0e10cSrcweir                     else
664cdf0e10cSrcweir                         return sal_False;
665cdf0e10cSrcweir                 }
666cdf0e10cSrcweir             }
667cdf0e10cSrcweir             else
668cdf0e10cSrcweir             {
669cdf0e10cSrcweir                 /*
670cdf0e10cSrcweir                  * First line of entry spanning two lines,
671cdf0e10cSrcweir                  * wait for second line.
672cdf0e10cSrcweir                  */
673cdf0e10cSrcweir                 aFirstLineName = rEntry.m_aName;
674cdf0e10cSrcweir                 bFirstLineDir =
675cdf0e10cSrcweir                     ((rEntry.m_nMode & INETCOREFTP_FILEMODE_ISDIR) != 0);
676cdf0e10cSrcweir                 return sal_False;
677cdf0e10cSrcweir             }
678cdf0e10cSrcweir         }
679cdf0e10cSrcweir         else
680cdf0e10cSrcweir         {
681cdf0e10cSrcweir             /*
682cdf0e10cSrcweir              * Second line of entry spanning two lines,
683cdf0e10cSrcweir              * restore entry's name and mode (ISDIR flag).
684cdf0e10cSrcweir              */
685cdf0e10cSrcweir             rEntry.m_aName = aFirstLineName;
686cdf0e10cSrcweir             rEntry.m_nMode = (bFirstLineDir ? INETCOREFTP_FILEMODE_ISDIR : 0);
687cdf0e10cSrcweir 
688cdf0e10cSrcweir             // Skip <1*lws> part:
689cdf0e10cSrcweir             if (*p != '\t' && *p != ' ')
690cdf0e10cSrcweir                 return sal_False;
691cdf0e10cSrcweir             ++p;
692cdf0e10cSrcweir             while (*p == '\t' || *p == ' ')
693cdf0e10cSrcweir                 ++p;
694cdf0e10cSrcweir         }
695cdf0e10cSrcweir 
696cdf0e10cSrcweir         // Parse <size> part and set entry's size:
697cdf0e10cSrcweir         if (*p < '0' || *p > '9')
698cdf0e10cSrcweir             return sal_False;
699cdf0e10cSrcweir         ULONG nSize = *p - '0';
700cdf0e10cSrcweir         if (*p++ != '0')
701cdf0e10cSrcweir             while (*p >= '0' && *p <= '9')
702cdf0e10cSrcweir                 nSize = 10 * rEntry.m_nSize + (*p++ - '0');
703cdf0e10cSrcweir         rEntry.m_nSize = 512 * nSize;
704cdf0e10cSrcweir 
705cdf0e10cSrcweir         // Skip <1*lws> part:
706cdf0e10cSrcweir         if (*p != '\t' && *p != ' ')
707cdf0e10cSrcweir             return sal_False;
708cdf0e10cSrcweir         ++p;
709cdf0e10cSrcweir         while (*p == '\t' || *p == ' ')
710cdf0e10cSrcweir             ++p;
711cdf0e10cSrcweir 
712cdf0e10cSrcweir         // Parse <day "-"> part and set entry date's day:
713cdf0e10cSrcweir         sal_uInt16 nDay;
714cdf0e10cSrcweir         if (*p == '0')
715cdf0e10cSrcweir         {
716cdf0e10cSrcweir             ++p;
717cdf0e10cSrcweir             if (*p < '1' || *p > '9')
718cdf0e10cSrcweir                 return sal_False;
719cdf0e10cSrcweir             nDay = *p++ - '0';
720cdf0e10cSrcweir         }
721cdf0e10cSrcweir         else if (*p == '1' || *p == '2')
722cdf0e10cSrcweir         {
723cdf0e10cSrcweir             nDay = *p++ - '0';
724cdf0e10cSrcweir             if (*p >= '0' && *p <= '9')
725cdf0e10cSrcweir                 nDay = 10 * nDay + (*p++ - '0');
726cdf0e10cSrcweir         }
727cdf0e10cSrcweir         else if (*p == '3')
728cdf0e10cSrcweir         {
729cdf0e10cSrcweir             ++p;
730cdf0e10cSrcweir             nDay = (*p == '0' || *p == '1') ? 30 + (*p++ - '0') : 3;
731cdf0e10cSrcweir         }
732cdf0e10cSrcweir         else if (*p >= '4' && *p <= '9')
733cdf0e10cSrcweir             nDay = *p++ - '0';
734cdf0e10cSrcweir         else
735cdf0e10cSrcweir             return sal_False;
736cdf0e10cSrcweir 
737cdf0e10cSrcweir         rEntry.m_aDate.SetDay(nDay);
738cdf0e10cSrcweir         if (*p++ != '-')
739cdf0e10cSrcweir             return sal_False;
740cdf0e10cSrcweir 
741cdf0e10cSrcweir         // Parse <month "-"> part and set entry date's month:
742cdf0e10cSrcweir         sal_Char const * pMonth = p;
743cdf0e10cSrcweir         sal_Int32 const monthLen = 3;
744cdf0e10cSrcweir         for (int i = 0; i < monthLen; ++i)
745cdf0e10cSrcweir         {
746cdf0e10cSrcweir             if (!((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z')))
747cdf0e10cSrcweir                 return sal_False;
748cdf0e10cSrcweir             ++p;
749cdf0e10cSrcweir         }
750cdf0e10cSrcweir         if (rtl_str_compareIgnoreAsciiCase_WithLength(
751cdf0e10cSrcweir                 pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("JAN")) == 0)
752cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(1);
753cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
754cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("FEB")) == 0)
755cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(2);
756cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
757cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("MAR")) == 0)
758cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(3);
759cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
760cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("APR")) == 0)
761cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(4);
762cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
763cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("MAY")) == 0)
764cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(5);
765cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
766cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("JUN")) == 0)
767cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(6);
768cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
769cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("JUL")) == 0)
770cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(7);
771cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
772cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("AUG")) == 0)
773cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(8);
774cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
775cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("SEP")) == 0)
776cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(9);
777cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
778cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("OCT")) == 0)
779cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(10);
780cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
781cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("NOV")) == 0)
782cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(11);
783cdf0e10cSrcweir         else if (rtl_str_compareIgnoreAsciiCase_WithLength(
784cdf0e10cSrcweir                      pMonth, monthLen, RTL_CONSTASCII_STRINGPARAM("DEC")) == 0)
785cdf0e10cSrcweir             rEntry.m_aDate.SetMonth(12);
786cdf0e10cSrcweir         else
787cdf0e10cSrcweir             return sal_False;
788cdf0e10cSrcweir         if (*p++ != '-')
789cdf0e10cSrcweir             return sal_False;
790cdf0e10cSrcweir 
791cdf0e10cSrcweir         // Parse <year> part and set entry date's year:
792cdf0e10cSrcweir         sal_uInt16 nYear = 0;
793cdf0e10cSrcweir         {for (int i = 0; i < 2; ++i)
794cdf0e10cSrcweir         {
795cdf0e10cSrcweir             if (*p < '0' || *p > '9')
796cdf0e10cSrcweir                 return sal_False;
797cdf0e10cSrcweir             nYear = 10 * nYear + (*p++ - '0');
798cdf0e10cSrcweir         }}
799cdf0e10cSrcweir         if (*p >= '0' && *p <= '9')
800cdf0e10cSrcweir         {
801cdf0e10cSrcweir             nYear = 10 * nYear + (*p++ - '0');
802cdf0e10cSrcweir             if (*p < '0' || *p > '9')
803cdf0e10cSrcweir                 return sal_False;
804cdf0e10cSrcweir             nYear = 10 * nYear + (*p++ - '0');
805cdf0e10cSrcweir         }
806cdf0e10cSrcweir         setYear (rEntry.m_aDate, nYear);
807cdf0e10cSrcweir 
808cdf0e10cSrcweir         // Skip <1*lws> part:
809cdf0e10cSrcweir         if (*p != '\t' && *p != ' ')
810cdf0e10cSrcweir             return sal_False;
811cdf0e10cSrcweir         ++p;
812cdf0e10cSrcweir         while (*p == '\t' || *p == ' ')
813cdf0e10cSrcweir             ++p;
814cdf0e10cSrcweir 
815cdf0e10cSrcweir         // Parse <hour ":"> part and set entry time's hour:
816cdf0e10cSrcweir         sal_uInt16 nHour;
817cdf0e10cSrcweir         if (*p == '0' || *p == '1')
818cdf0e10cSrcweir         {
819cdf0e10cSrcweir             nHour = *p++ - '0';
820cdf0e10cSrcweir             if (*p >= '0' && *p <= '9')
821cdf0e10cSrcweir                 nHour = 10 * nHour + (*p++ - '0');
822cdf0e10cSrcweir         }
823cdf0e10cSrcweir         else if (*p == '2')
824cdf0e10cSrcweir         {
825cdf0e10cSrcweir             ++p;
826cdf0e10cSrcweir             nHour = (*p >= '0' && *p <= '3') ? 20 + (*p++ - '0') : 2;
827cdf0e10cSrcweir         }
828cdf0e10cSrcweir         else if (*p >= '3' && *p <= '9')
829cdf0e10cSrcweir             nHour = *p++ - '0';
830cdf0e10cSrcweir         else
831cdf0e10cSrcweir             return sal_False;
832cdf0e10cSrcweir 
833cdf0e10cSrcweir         rEntry.m_aDate.SetHour(nHour);
834cdf0e10cSrcweir         if (*p++ != ':')
835cdf0e10cSrcweir             return sal_False;
836cdf0e10cSrcweir 
837cdf0e10cSrcweir         /*
838cdf0e10cSrcweir          * Parse <minute> part and set entry time's minutes,
839cdf0e10cSrcweir          * seconds (0), and 1/100 seconds (0).
840cdf0e10cSrcweir          */
841cdf0e10cSrcweir         if (*p < '0' || *p > '5')
842cdf0e10cSrcweir             return sal_False;
843cdf0e10cSrcweir 
844cdf0e10cSrcweir         sal_uInt16 nMinute = *p++ - '0';
845cdf0e10cSrcweir         if (*p < '0' || *p > '9')
846cdf0e10cSrcweir             return sal_False;
847cdf0e10cSrcweir 
848cdf0e10cSrcweir         nMinute = 10 * nMinute + (*p++ - '0');
849cdf0e10cSrcweir         rEntry.m_aDate.SetMin(nMinute);
850cdf0e10cSrcweir         rEntry.m_aDate.SetSec(0);
851cdf0e10cSrcweir         rEntry.m_aDate.Set100Sec(0);
852cdf0e10cSrcweir 
853cdf0e10cSrcweir         // Skip <rest> part:
854cdf0e10cSrcweir         if (*p && (*p != '\t' && *p != ' '))
855cdf0e10cSrcweir             return sal_False;
856cdf0e10cSrcweir 
857cdf0e10cSrcweir         return sal_True;
858cdf0e10cSrcweir     }
859cdf0e10cSrcweir }
860cdf0e10cSrcweir 
861cdf0e10cSrcweir /*
862cdf0e10cSrcweir  * parseUNIX
863cdf0e10cSrcweir  */
parseUNIX(FTPDirentry & rEntry,const sal_Char * pBuffer)864cdf0e10cSrcweir sal_Bool FTPDirectoryParser::parseUNIX (
865cdf0e10cSrcweir     FTPDirentry &rEntry,
866cdf0e10cSrcweir     const sal_Char  *pBuffer)
867cdf0e10cSrcweir {
868cdf0e10cSrcweir     const sal_Char *p1, *p2;
869cdf0e10cSrcweir     p1 = p2 = pBuffer;
870cdf0e10cSrcweir 
871cdf0e10cSrcweir     if (!((*p1 == '-') || (*p1 == 'd') || (*p1 == 'l')))
872cdf0e10cSrcweir         return sal_False;
873cdf0e10cSrcweir 
874cdf0e10cSrcweir     // 1st column: FileMode.
875cdf0e10cSrcweir     if (*p1 == 'd')
876cdf0e10cSrcweir         rEntry.m_nMode |= INETCOREFTP_FILEMODE_ISDIR;
877cdf0e10cSrcweir 
878cdf0e10cSrcweir     if (*p1 == 'l')
879cdf0e10cSrcweir         rEntry.m_nMode |= INETCOREFTP_FILEMODE_ISLINK;
880cdf0e10cSrcweir 
881cdf0e10cSrcweir     // Skip to end of column and set rights by the way
882cdf0e10cSrcweir     while (*p1 && !ascii_isWhitespace(*p1)) {
883cdf0e10cSrcweir         if(*p1 == 'r')
884cdf0e10cSrcweir             rEntry.m_nMode |= INETCOREFTP_FILEMODE_READ;
885cdf0e10cSrcweir         else if(*p1 == 'w')
886cdf0e10cSrcweir             rEntry.m_nMode |= INETCOREFTP_FILEMODE_WRITE;
887cdf0e10cSrcweir         p1++;
888cdf0e10cSrcweir     }
889cdf0e10cSrcweir 
890cdf0e10cSrcweir     /*
891cdf0e10cSrcweir      * Scan for the sequence of size and date fields:
892cdf0e10cSrcweir      *   *LWS 1*DIGIT 1*LWS 3CHAR 1*LWS 1*2DIGIT 1*LWS
893cdf0e10cSrcweir      *   (4DIGIT / (1*2DIGIT ":" 2DIGIT)) 1*LWS
894cdf0e10cSrcweir      */
895cdf0e10cSrcweir     enum Mode
896cdf0e10cSrcweir     {
897cdf0e10cSrcweir         FOUND_NONE, FOUND_SIZE, FOUND_MONTH, FOUND_DAY, FOUND_YEAR_TIME
898cdf0e10cSrcweir     };
899cdf0e10cSrcweir 
900cdf0e10cSrcweir     const sal_Char *pDayStart = 0;
901cdf0e10cSrcweir     const sal_Char *pDayEnd = 0;
902cdf0e10cSrcweir     Mode eMode;
903cdf0e10cSrcweir     for (eMode = FOUND_NONE; *p1 && eMode != FOUND_YEAR_TIME; p1 = p2 + 1)
904cdf0e10cSrcweir     {
905cdf0e10cSrcweir         while (*p1 && ascii_isWhitespace(*p1))
906cdf0e10cSrcweir             ++p1;
907cdf0e10cSrcweir         p2 = p1;
908cdf0e10cSrcweir         while (*p2 && !ascii_isWhitespace(*p2))
909cdf0e10cSrcweir             ++p2;
910cdf0e10cSrcweir 
911cdf0e10cSrcweir         switch (eMode)
912cdf0e10cSrcweir         {
913cdf0e10cSrcweir             case FOUND_NONE:
914cdf0e10cSrcweir                 if (parseUNIX_isSizeField (p1, p2, rEntry.m_nSize))
915cdf0e10cSrcweir                     eMode = FOUND_SIZE;
916cdf0e10cSrcweir                 break;
917cdf0e10cSrcweir 
918cdf0e10cSrcweir             case FOUND_SIZE:
919cdf0e10cSrcweir                 if (parseUNIX_isMonthField (p1, p2, rEntry.m_aDate))
920cdf0e10cSrcweir                     eMode = FOUND_MONTH;
921cdf0e10cSrcweir                 else if (!parseUNIX_isSizeField (p1, p2, rEntry.m_nSize))
922cdf0e10cSrcweir                     eMode = FOUND_NONE;
923cdf0e10cSrcweir                 break;
924cdf0e10cSrcweir 
925cdf0e10cSrcweir             case FOUND_MONTH:
926cdf0e10cSrcweir                 if (parseUNIX_isDayField (p1, p2, rEntry.m_aDate))
927cdf0e10cSrcweir                 {
928cdf0e10cSrcweir                     pDayStart = p1;
929cdf0e10cSrcweir                     pDayEnd = p2;
930cdf0e10cSrcweir                     eMode = FOUND_DAY;
931cdf0e10cSrcweir                 }
932cdf0e10cSrcweir                 else if (parseUNIX_isSizeField (p1, p2, rEntry.m_nSize))
933cdf0e10cSrcweir                     eMode = FOUND_SIZE;
934cdf0e10cSrcweir                 else
935cdf0e10cSrcweir                     eMode = FOUND_NONE;
936cdf0e10cSrcweir                 break;
937cdf0e10cSrcweir 
938cdf0e10cSrcweir             case FOUND_DAY:
939cdf0e10cSrcweir                 if (parseUNIX_isYearTimeField (p1, p2, rEntry.m_aDate))
940cdf0e10cSrcweir                     eMode = FOUND_YEAR_TIME;
941cdf0e10cSrcweir                 else if (
942cdf0e10cSrcweir                     parseUNIX_isSizeField (
943cdf0e10cSrcweir                         pDayStart, pDayEnd, rEntry.m_nSize) &&
944cdf0e10cSrcweir                     parseUNIX_isMonthField (
945cdf0e10cSrcweir                         p1, p2, rEntry.m_aDate))
946cdf0e10cSrcweir                     eMode = FOUND_MONTH;
947cdf0e10cSrcweir                 else if (parseUNIX_isSizeField (p1, p2, rEntry.m_nSize))
948cdf0e10cSrcweir                     eMode = FOUND_SIZE;
949cdf0e10cSrcweir                 else
950cdf0e10cSrcweir                     eMode = FOUND_NONE;
951cdf0e10cSrcweir                 break;
952cdf0e10cSrcweir             case FOUND_YEAR_TIME:
953cdf0e10cSrcweir                 break;
954cdf0e10cSrcweir         }
955cdf0e10cSrcweir     }
956cdf0e10cSrcweir 
957cdf0e10cSrcweir     if (eMode == FOUND_YEAR_TIME)
958cdf0e10cSrcweir     {
959cdf0e10cSrcweir         // 9th column: FileName (rest of line).
960cdf0e10cSrcweir         while (*p1 && ascii_isWhitespace(*p1)) p1++;
961cdf0e10cSrcweir         setPath (rEntry.m_aName, p1);
962cdf0e10cSrcweir 
963cdf0e10cSrcweir         // Done.
964cdf0e10cSrcweir         return sal_True;
965cdf0e10cSrcweir     }
966cdf0e10cSrcweir     return sal_False;
967cdf0e10cSrcweir }
968cdf0e10cSrcweir 
969cdf0e10cSrcweir /*
970cdf0e10cSrcweir  * parseUNIX_isSizeField.
971cdf0e10cSrcweir  */
parseUNIX_isSizeField(const sal_Char * pStart,const sal_Char * pEnd,sal_uInt32 & rSize)972cdf0e10cSrcweir sal_Bool FTPDirectoryParser::parseUNIX_isSizeField (
973cdf0e10cSrcweir     const sal_Char *pStart,
974cdf0e10cSrcweir     const sal_Char *pEnd,
975cdf0e10cSrcweir     sal_uInt32     &rSize)
976cdf0e10cSrcweir {
977cdf0e10cSrcweir     if (!*pStart || !*pEnd || pStart == pEnd)
978cdf0e10cSrcweir         return sal_False;
979cdf0e10cSrcweir 
980cdf0e10cSrcweir     rSize = 0;
981cdf0e10cSrcweir     if (*pStart >= '0' && *pStart <= '9')
982cdf0e10cSrcweir     {
983cdf0e10cSrcweir         for (; pStart < pEnd; ++pStart)
984cdf0e10cSrcweir             if ((*pStart >= '0') && (*pStart <= '9'))
985cdf0e10cSrcweir                 rSize = 10 * rSize + (*pStart - '0');
986cdf0e10cSrcweir             else
987cdf0e10cSrcweir                 return sal_False;
988cdf0e10cSrcweir         return sal_True;
989cdf0e10cSrcweir     }
990cdf0e10cSrcweir     else
991cdf0e10cSrcweir     {
992cdf0e10cSrcweir         /*
993cdf0e10cSrcweir          * For a combination of long group name and large file size,
994cdf0e10cSrcweir          * some FTPDs omit LWS between those two columns.
995cdf0e10cSrcweir          */
996cdf0e10cSrcweir         int nNonDigits = 0;
997cdf0e10cSrcweir         int nDigits = 0;
998cdf0e10cSrcweir 
999cdf0e10cSrcweir         for (; pStart < pEnd; ++pStart)
1000cdf0e10cSrcweir             if ((*pStart >= '1') && (*pStart <= '9'))
1001cdf0e10cSrcweir             {
1002cdf0e10cSrcweir                 ++nDigits;
1003cdf0e10cSrcweir                 rSize = 10 * rSize + (*pStart - '0');
1004cdf0e10cSrcweir             }
1005cdf0e10cSrcweir             else if ((*pStart == '0') && nDigits)
1006cdf0e10cSrcweir             {
1007cdf0e10cSrcweir                 ++nDigits;
1008cdf0e10cSrcweir                 rSize *= 10;
1009cdf0e10cSrcweir             }
1010cdf0e10cSrcweir             else if ((*pStart > ' ') && (sal::static_int_cast<sal_uInt8>(*pStart) <= '\x7F'))
1011cdf0e10cSrcweir             {
1012cdf0e10cSrcweir                 nNonDigits += nDigits + 1;
1013cdf0e10cSrcweir                 nDigits = 0;
1014cdf0e10cSrcweir                 rSize = 0;
1015cdf0e10cSrcweir             }
1016cdf0e10cSrcweir             else
1017cdf0e10cSrcweir                 return sal_False;
1018cdf0e10cSrcweir         return ((nNonDigits >= 9) && (nDigits >= 7));
1019cdf0e10cSrcweir     }
1020cdf0e10cSrcweir }
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir /*
1023cdf0e10cSrcweir  * parseUNIX_isMonthField.
1024cdf0e10cSrcweir  */
parseUNIX_isMonthField(const sal_Char * pStart,const sal_Char * pEnd,DateTime & rDateTime)1025cdf0e10cSrcweir sal_Bool FTPDirectoryParser::parseUNIX_isMonthField (
1026cdf0e10cSrcweir     const sal_Char *pStart,
1027cdf0e10cSrcweir     const sal_Char *pEnd,
1028cdf0e10cSrcweir     DateTime       &rDateTime)
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir     if (!*pStart || !*pEnd || pStart + 3 != pEnd)
1031cdf0e10cSrcweir         return sal_False;
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir     if ((pStart[0] == 'j' || pStart[0] == 'J') &&
1034cdf0e10cSrcweir         (pStart[1] == 'a' || pStart[1] == 'A') &&
1035cdf0e10cSrcweir         (pStart[2] == 'n' || pStart[2] == 'N')    )
1036cdf0e10cSrcweir     {
1037cdf0e10cSrcweir         rDateTime.SetMonth(1);
1038cdf0e10cSrcweir         return sal_True;
1039cdf0e10cSrcweir     }
1040cdf0e10cSrcweir     if ((pStart[0] == 'f' || pStart[0] == 'F') &&
1041cdf0e10cSrcweir         (pStart[1] == 'e' || pStart[1] == 'E') &&
1042cdf0e10cSrcweir         (pStart[2] == 'b' || pStart[2] == 'B')    )
1043cdf0e10cSrcweir     {
1044cdf0e10cSrcweir         rDateTime.SetMonth(2);
1045cdf0e10cSrcweir         return sal_True;
1046cdf0e10cSrcweir     }
1047cdf0e10cSrcweir     if ((pStart[0] == 'm' || pStart[0] == 'M') &&
1048cdf0e10cSrcweir         (pStart[1] == 'a' || pStart[1] == 'A') &&
1049cdf0e10cSrcweir         (pStart[2] == 'r' || pStart[2] == 'R')    )
1050cdf0e10cSrcweir     {
1051cdf0e10cSrcweir         rDateTime.SetMonth(3);
1052cdf0e10cSrcweir         return sal_True;
1053cdf0e10cSrcweir     }
1054cdf0e10cSrcweir     if ((pStart[0] == 'a' || pStart[0] == 'A') &&
1055cdf0e10cSrcweir         (pStart[1] == 'p' || pStart[1] == 'P') &&
1056cdf0e10cSrcweir         (pStart[2] == 'r' || pStart[2] == 'R')    )
1057cdf0e10cSrcweir     {
1058cdf0e10cSrcweir         rDateTime.SetMonth(4);
1059cdf0e10cSrcweir         return sal_True;
1060cdf0e10cSrcweir     }
1061cdf0e10cSrcweir     if ((pStart[0] == 'm' || pStart[0] == 'M') &&
1062cdf0e10cSrcweir         (pStart[1] == 'a' || pStart[1] == 'A') &&
1063cdf0e10cSrcweir         (pStart[2] == 'y' || pStart[2] == 'Y')    )
1064cdf0e10cSrcweir     {
1065cdf0e10cSrcweir         rDateTime.SetMonth(5);
1066cdf0e10cSrcweir         return sal_True;
1067cdf0e10cSrcweir     }
1068cdf0e10cSrcweir     if ((pStart[0] == 'j' || pStart[0] == 'J') &&
1069cdf0e10cSrcweir         (pStart[1] == 'u' || pStart[1] == 'U') &&
1070cdf0e10cSrcweir         (pStart[2] == 'n' || pStart[2] == 'N')    )
1071cdf0e10cSrcweir     {
1072cdf0e10cSrcweir         rDateTime.SetMonth(6);
1073cdf0e10cSrcweir         return sal_True;
1074cdf0e10cSrcweir     }
1075cdf0e10cSrcweir     if ((pStart[0] == 'j' || pStart[0] == 'J') &&
1076cdf0e10cSrcweir         (pStart[1] == 'u' || pStart[1] == 'U') &&
1077cdf0e10cSrcweir         (pStart[2] == 'l' || pStart[2] == 'L')    )
1078cdf0e10cSrcweir     {
1079cdf0e10cSrcweir         rDateTime.SetMonth(7);
1080cdf0e10cSrcweir         return sal_True;
1081cdf0e10cSrcweir     }
1082cdf0e10cSrcweir     if ((pStart[0] == 'a' || pStart[0] == 'A') &&
1083cdf0e10cSrcweir         (pStart[1] == 'u' || pStart[1] == 'U') &&
1084cdf0e10cSrcweir         (pStart[2] == 'g' || pStart[2] == 'G')    )
1085cdf0e10cSrcweir     {
1086cdf0e10cSrcweir         rDateTime.SetMonth(8);
1087cdf0e10cSrcweir         return sal_True;
1088cdf0e10cSrcweir     }
1089cdf0e10cSrcweir     if ((pStart[0] == 's' || pStart[0] == 'S') &&
1090cdf0e10cSrcweir         (pStart[1] == 'e' || pStart[1] == 'E') &&
1091cdf0e10cSrcweir         (pStart[2] == 'p' || pStart[2] == 'P')    )
1092cdf0e10cSrcweir     {
1093cdf0e10cSrcweir         rDateTime.SetMonth(9);
1094cdf0e10cSrcweir         return sal_True;
1095cdf0e10cSrcweir     }
1096cdf0e10cSrcweir     if ((pStart[0] == 'o' || pStart[0] == 'O') &&
1097cdf0e10cSrcweir         (pStart[1] == 'c' || pStart[1] == 'C') &&
1098cdf0e10cSrcweir         (pStart[2] == 't' || pStart[2] == 'T')    )
1099cdf0e10cSrcweir     {
1100cdf0e10cSrcweir         rDateTime.SetMonth(10);
1101cdf0e10cSrcweir         return sal_True;
1102cdf0e10cSrcweir     }
1103cdf0e10cSrcweir     if ((pStart[0] == 'n' || pStart[0] == 'N') &&
1104cdf0e10cSrcweir         (pStart[1] == 'o' || pStart[1] == 'O') &&
1105cdf0e10cSrcweir         (pStart[2] == 'v' || pStart[2] == 'V')    )
1106cdf0e10cSrcweir     {
1107cdf0e10cSrcweir         rDateTime.SetMonth(11);
1108cdf0e10cSrcweir         return sal_True;
1109cdf0e10cSrcweir     }
1110cdf0e10cSrcweir     if ((pStart[0] == 'd' || pStart[0] == 'D') &&
1111cdf0e10cSrcweir         (pStart[1] == 'e' || pStart[1] == 'E') &&
1112cdf0e10cSrcweir         (pStart[2] == 'c' || pStart[2] == 'C')    )
1113cdf0e10cSrcweir     {
1114cdf0e10cSrcweir         rDateTime.SetMonth(12);
1115cdf0e10cSrcweir         return sal_True;
1116cdf0e10cSrcweir     }
1117cdf0e10cSrcweir     return sal_False;
1118cdf0e10cSrcweir }
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir /*
1121cdf0e10cSrcweir  * parseUNIX_isDayField.
1122cdf0e10cSrcweir  */
parseUNIX_isDayField(const sal_Char * pStart,const sal_Char * pEnd,DateTime & rDateTime)1123cdf0e10cSrcweir sal_Bool FTPDirectoryParser::parseUNIX_isDayField (
1124cdf0e10cSrcweir     const sal_Char *pStart,
1125cdf0e10cSrcweir     const sal_Char *pEnd,
1126cdf0e10cSrcweir     DateTime       &rDateTime)
1127cdf0e10cSrcweir {
1128cdf0e10cSrcweir     if (!*pStart || !*pEnd || pStart == pEnd)
1129cdf0e10cSrcweir         return sal_False;
1130cdf0e10cSrcweir     if (*pStart < '0' || *pStart > '9')
1131cdf0e10cSrcweir         return sal_False;
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir     sal_uInt16 nDay = *pStart - '0';
1134cdf0e10cSrcweir     if (pStart + 1 < pEnd)
1135cdf0e10cSrcweir     {
1136cdf0e10cSrcweir         if (pStart + 2 != pEnd || pStart[1] < '0' || pStart[1] > '9')
1137cdf0e10cSrcweir             return sal_False;
1138cdf0e10cSrcweir         nDay = 10 * nDay + (pStart[1] - '0');
1139cdf0e10cSrcweir     }
1140cdf0e10cSrcweir     if (!nDay || nDay > 31)
1141cdf0e10cSrcweir         return sal_False;
1142cdf0e10cSrcweir 
1143cdf0e10cSrcweir     rDateTime.SetDay(nDay);
1144cdf0e10cSrcweir     return sal_True;
1145cdf0e10cSrcweir }
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir /*
1148cdf0e10cSrcweir  * parseUNIX_isYearTimeField.
1149cdf0e10cSrcweir  */
parseUNIX_isYearTimeField(const sal_Char * pStart,const sal_Char * pEnd,DateTime & rDateTime)1150cdf0e10cSrcweir sal_Bool FTPDirectoryParser::parseUNIX_isYearTimeField (
1151cdf0e10cSrcweir     const sal_Char *pStart,
1152cdf0e10cSrcweir     const sal_Char *pEnd,
1153cdf0e10cSrcweir     DateTime       &rDateTime)
1154cdf0e10cSrcweir {
1155cdf0e10cSrcweir     if (!*pStart || !*pEnd || pStart == pEnd ||
1156cdf0e10cSrcweir         *pStart < '0' || *pStart > '9')
1157cdf0e10cSrcweir         return sal_False;
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir     sal_uInt16 nNumber = *pStart - '0';
1160cdf0e10cSrcweir     ++pStart;
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir     if (pStart == pEnd)
1163cdf0e10cSrcweir         return sal_False;
1164cdf0e10cSrcweir     if (*pStart == ':')
1165cdf0e10cSrcweir         return parseUNIX_isTime (pStart, pEnd, nNumber, rDateTime);
1166cdf0e10cSrcweir     if (*pStart < '0' || *pStart > '9')
1167cdf0e10cSrcweir         return sal_False;
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir     nNumber = 10 * nNumber + (*pStart - '0');
1170cdf0e10cSrcweir     ++pStart;
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir     if (pStart == pEnd)
1173cdf0e10cSrcweir         return sal_False;
1174cdf0e10cSrcweir     if (*pStart == ':')
1175cdf0e10cSrcweir         return parseUNIX_isTime (pStart, pEnd, nNumber, rDateTime);
1176cdf0e10cSrcweir     if (*pStart < '0' || *pStart > '9')
1177cdf0e10cSrcweir         return sal_False;
1178cdf0e10cSrcweir 
1179cdf0e10cSrcweir     nNumber = 10 * nNumber + (*pStart - '0');
1180cdf0e10cSrcweir     ++pStart;
1181cdf0e10cSrcweir 
1182cdf0e10cSrcweir     if (pStart == pEnd || *pStart < '0' || *pStart > '9')
1183cdf0e10cSrcweir         return sal_False;
1184cdf0e10cSrcweir 
1185cdf0e10cSrcweir     nNumber = 10 * nNumber + (*pStart - '0');
1186cdf0e10cSrcweir     if (pStart + 1 != pEnd || nNumber < 1970)
1187cdf0e10cSrcweir         return sal_False;
1188cdf0e10cSrcweir 
1189cdf0e10cSrcweir     rDateTime.SetYear(nNumber);
1190cdf0e10cSrcweir     rDateTime.SetTime(0);
1191cdf0e10cSrcweir     return sal_True;
1192cdf0e10cSrcweir }
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir /*
1195cdf0e10cSrcweir  * parseUNIX_isTime.
1196cdf0e10cSrcweir  */
parseUNIX_isTime(const sal_Char * pStart,const sal_Char * pEnd,sal_uInt16 nHour,DateTime & rDateTime)1197cdf0e10cSrcweir sal_Bool FTPDirectoryParser::parseUNIX_isTime (
1198cdf0e10cSrcweir     const sal_Char *pStart,
1199cdf0e10cSrcweir     const sal_Char *pEnd,
1200cdf0e10cSrcweir     sal_uInt16      nHour,
1201cdf0e10cSrcweir     DateTime       &rDateTime)
1202cdf0e10cSrcweir {
1203cdf0e10cSrcweir     if ((nHour     > 23 ) || (pStart + 3 != pEnd) ||
1204cdf0e10cSrcweir         (pStart[1] < '0') || (pStart[1] > '5')    ||
1205cdf0e10cSrcweir         (pStart[2] < '0') || (pStart[2] > '9')       )
1206cdf0e10cSrcweir         return sal_False;
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir     sal_uInt16 nMin = 10 * (pStart[1] - '0') + (pStart[2] - '0');
1209cdf0e10cSrcweir 
1210cdf0e10cSrcweir     rDateTime.SetHour (nHour);
1211cdf0e10cSrcweir     rDateTime.SetMin (nMin);
1212cdf0e10cSrcweir     rDateTime.SetSec (0);
1213cdf0e10cSrcweir     rDateTime.Set100Sec (0);
1214cdf0e10cSrcweir 
1215cdf0e10cSrcweir //      Date aCurDate;
1216cdf0e10cSrcweir //      if (rDateTime.GetMonth() > aCurDate.GetMonth())
1217cdf0e10cSrcweir //          rDateTime.SetYear(aCurDate.GetYear() - 1);
1218cdf0e10cSrcweir //      else
1219cdf0e10cSrcweir //          rDateTime.SetYear(aCurDate.GetYear());
1220cdf0e10cSrcweir //      return sal_True;
1221cdf0e10cSrcweir 
1222cdf0e10cSrcweir     TimeValue aTimeVal;
1223cdf0e10cSrcweir     osl_getSystemTime(&aTimeVal);
1224cdf0e10cSrcweir     oslDateTime aCurrDateTime;
1225cdf0e10cSrcweir     osl_getDateTimeFromTimeValue(&aTimeVal,&aCurrDateTime);
1226cdf0e10cSrcweir 
1227cdf0e10cSrcweir     if (rDateTime.GetMonth() > aCurrDateTime.Month)
1228cdf0e10cSrcweir         rDateTime.SetYear(aCurrDateTime.Year - 1);
1229cdf0e10cSrcweir     else
1230cdf0e10cSrcweir         rDateTime.SetYear(aCurrDateTime.Year);
1231cdf0e10cSrcweir     return sal_True;
1232cdf0e10cSrcweir }
1233cdf0e10cSrcweir 
1234cdf0e10cSrcweir /*
1235cdf0e10cSrcweir  * setYear.
1236cdf0e10cSrcweir  *
1237cdf0e10cSrcweir  * Two-digit years are taken as within 50 years back and 49 years forward
1238cdf0e10cSrcweir  * (both ends inclusive) from the current year. The returned date is not
1239cdf0e10cSrcweir  * checked for validity of the given day in the given month and year.
1240cdf0e10cSrcweir  *
1241cdf0e10cSrcweir  */
setYear(DateTime & rDateTime,sal_uInt16 nYear)1242cdf0e10cSrcweir sal_Bool FTPDirectoryParser::setYear (
1243cdf0e10cSrcweir     DateTime &rDateTime, sal_uInt16 nYear)
1244cdf0e10cSrcweir {
1245cdf0e10cSrcweir     if (nYear < 100)
1246cdf0e10cSrcweir     {
1247cdf0e10cSrcweir         TimeValue aTimeVal;
1248cdf0e10cSrcweir         osl_getSystemTime(&aTimeVal);
1249cdf0e10cSrcweir         oslDateTime aCurrDateTime;
1250cdf0e10cSrcweir         osl_getDateTimeFromTimeValue(&aTimeVal,&aCurrDateTime);
1251cdf0e10cSrcweir         sal_uInt16 nCurrentYear = aCurrDateTime.Year;
1252cdf0e10cSrcweir //        sal_uInt16 nCurrentYear = Date().GetYear();
1253cdf0e10cSrcweir         sal_uInt16 nCurrentCentury = nCurrentYear / 100;
1254cdf0e10cSrcweir         nCurrentYear %= 100;
1255cdf0e10cSrcweir         if (nCurrentYear < 50)
1256cdf0e10cSrcweir             if (nYear <= nCurrentYear)
1257cdf0e10cSrcweir                 nYear += nCurrentCentury * 100;
1258cdf0e10cSrcweir             else if (nYear < nCurrentYear + 50)
1259cdf0e10cSrcweir                 nYear += nCurrentCentury * 100;
1260cdf0e10cSrcweir             else
1261cdf0e10cSrcweir                 nYear += (nCurrentCentury - 1) * 100;
1262cdf0e10cSrcweir         else
1263cdf0e10cSrcweir             if (nYear >= nCurrentYear)
1264cdf0e10cSrcweir                 nYear += nCurrentCentury * 100;
1265cdf0e10cSrcweir             else if (nYear >= nCurrentYear - 50)
1266cdf0e10cSrcweir                 nYear += nCurrentCentury * 100;
1267cdf0e10cSrcweir             else
1268cdf0e10cSrcweir                 nYear += (nCurrentCentury + 1) * 100;
1269cdf0e10cSrcweir     }
1270cdf0e10cSrcweir 
1271cdf0e10cSrcweir     rDateTime.SetYear(nYear);
1272cdf0e10cSrcweir     return sal_True;
1273cdf0e10cSrcweir }
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir /*
1276cdf0e10cSrcweir  * setPath.
1277cdf0e10cSrcweir  */
setPath(OUString & rPath,const sal_Char * value,sal_Int32 length)1278cdf0e10cSrcweir sal_Bool FTPDirectoryParser::setPath (
1279cdf0e10cSrcweir     OUString &rPath, const sal_Char *value, sal_Int32 length)
1280cdf0e10cSrcweir {
1281cdf0e10cSrcweir     if (value)
1282cdf0e10cSrcweir     {
1283cdf0e10cSrcweir         if (length < 0)
1284cdf0e10cSrcweir             length = rtl_str_getLength (value);
1285cdf0e10cSrcweir         rPath = OUString (value, length, RTL_TEXTENCODING_UTF8);
1286cdf0e10cSrcweir     }
1287cdf0e10cSrcweir     return (!!value);
1288cdf0e10cSrcweir }
1289