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