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