Lines 446-751
oslFileError osl_getSystemPathFromFileURL_Ex(
Link Here
|
446 |
return osl_error; |
446 |
return osl_error; |
447 |
} |
447 |
} |
448 |
|
448 |
|
449 |
namespace /* private */ |
449 |
/****************************************************** |
|
|
450 |
* Resolve the paths if they exist. The resulting |
451 |
* path must not exceed PATH_MAX else |
452 |
* osl_File_E_NAMETOOLONG is the result |
453 |
******************************************************/ |
454 |
|
455 |
static oslFileError osl_getAbsoluteFileURL_impl_(const rtl::OUString& unresolved, rtl::OUString& resolved) |
450 |
{ |
456 |
{ |
|
|
457 |
char unresolved_path[PATH_MAX]; |
458 |
char resolved_path[PATH_MAX]; |
451 |
|
459 |
|
452 |
/****************************************************** |
460 |
if (!UnicodeToText(unresolved_path, sizeof(unresolved_path), unresolved.getStr(), unresolved.getLength())) |
453 |
* Helper function, return a pinter to the final '\0' |
461 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
454 |
* of a string |
|
|
455 |
******************************************************/ |
456 |
|
457 |
sal_Unicode* ustrtoend(sal_Unicode* pStr) |
458 |
{ |
459 |
return (pStr + rtl_ustr_getLength(pStr)); |
460 |
} |
461 |
|
462 |
/********************************************* |
463 |
|
462 |
|
464 |
********************************************/ |
463 |
if (realpath(unresolved_path, resolved_path)) |
465 |
sal_Unicode* ustrcpy(const sal_Unicode* s, sal_Unicode* d) |
|
|
466 |
{ |
464 |
{ |
467 |
const sal_Unicode* sc = s; |
465 |
sal_Unicode path[PATH_MAX]; |
468 |
sal_Unicode* dc = d; |
466 |
if (!TextToUnicode(resolved_path, strlen(resolved_path), path, PATH_MAX)) |
469 |
|
467 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
470 |
while ((*dc++ = *sc++)) |
|
|
471 |
/**/; |
472 |
|
473 |
return d; |
474 |
} |
475 |
|
476 |
/********************************************* |
477 |
|
468 |
|
478 |
********************************************/ |
469 |
resolved = rtl::OUString(path, rtl_ustr_getLength(path)); |
479 |
|
470 |
return osl_File_E_None; |
480 |
sal_Unicode* ustrncpy(const sal_Unicode* s, sal_Unicode* d, unsigned int n) |
|
|
481 |
{ |
482 |
const sal_Unicode* sc = s; |
483 |
sal_Unicode* dc = d; |
484 |
unsigned int i = n; |
485 |
|
486 |
while (i--) |
487 |
*dc++ = *sc++; |
488 |
|
489 |
if (n) |
490 |
*dc = 0; |
491 |
|
492 |
return d; |
493 |
} |
471 |
} |
494 |
|
472 |
else |
495 |
/********************************************* |
|
|
496 |
|
497 |
********************************************/ |
498 |
|
499 |
sal_Unicode* ustrchrcat(const sal_Unicode chr, sal_Unicode* d) |
500 |
{ |
473 |
{ |
501 |
sal_Unicode* p = ustrtoend(d); |
474 |
if (EACCES != errno && ENOTDIR != errno && ENOENT != errno) |
502 |
*p++ = chr; |
475 |
return oslTranslateFileError(OSL_FET_ERROR, errno); |
503 |
*p = 0; |
|
|
504 |
return d; |
505 |
} |
476 |
} |
506 |
|
477 |
|
507 |
/********************************************* |
478 |
// the 'unresolved' does not exist, let's just copy it to 'resolved' |
508 |
|
479 |
resolved = unresolved; |
509 |
********************************************/ |
480 |
return osl_File_E_None; |
510 |
|
481 |
} |
511 |
sal_Unicode* ustrcat(const sal_Unicode* s, sal_Unicode* d) |
|
|
512 |
{ |
513 |
sal_Unicode* dc = ustrtoend(d); |
514 |
ustrcpy(s, dc); |
515 |
return d; |
516 |
} |
517 |
|
518 |
/****************************************************** |
519 |
* |
520 |
******************************************************/ |
521 |
|
522 |
bool _islastchr(sal_Unicode* pStr, sal_Unicode Chr) |
523 |
{ |
524 |
sal_Unicode* p = ustrtoend(pStr); |
525 |
if (p > pStr) |
526 |
p--; |
527 |
return (*p == Chr); |
528 |
} |
529 |
|
530 |
/****************************************************** |
531 |
* Ensure that the given string has the specified last |
532 |
* character if necessary append it |
533 |
******************************************************/ |
534 |
|
535 |
sal_Unicode* _strensurelast(sal_Unicode* pStr, sal_Unicode Chr) |
536 |
{ |
537 |
if (!_islastchr(pStr, Chr)) |
538 |
ustrchrcat(Chr, pStr); |
539 |
return pStr; |
540 |
} |
541 |
|
542 |
/****************************************************** |
543 |
* Remove the last part of a path, a path that has |
544 |
* only a '/' or no '/' at all will be returned |
545 |
* unmodified |
546 |
******************************************************/ |
547 |
|
548 |
sal_Unicode* _rmlastpathtoken(sal_Unicode* aPath) |
549 |
{ |
550 |
/* we always may skip -2 because we |
551 |
may at least stand on a '/' but |
552 |
either there is no other character |
553 |
before this '/' or it's another |
554 |
character than the '/' |
555 |
*/ |
556 |
sal_Unicode* p = ustrtoend(aPath) - 2; |
557 |
|
558 |
// move back to the next path separator |
559 |
// or to the start of the string |
560 |
while ((p > aPath) && (*p != UNICHAR_SLASH)) |
561 |
p--; |
562 |
|
563 |
if (p >= aPath) |
564 |
{ |
565 |
if (UNICHAR_SLASH == *p) |
566 |
{ |
567 |
p++; |
568 |
*p = '\0'; |
569 |
} |
570 |
else |
571 |
{ |
572 |
*p = '\0'; |
573 |
} |
574 |
} |
575 |
|
576 |
return aPath; |
577 |
} |
578 |
|
579 |
/****************************************************** |
580 |
* |
581 |
******************************************************/ |
582 |
|
583 |
oslFileError _osl_resolvepath( |
584 |
/*inout*/ sal_Unicode* path, |
585 |
/*inout*/ sal_Unicode* current_pos, |
586 |
/*inout*/ bool* failed) |
587 |
{ |
588 |
oslFileError ferr = osl_File_E_None; |
589 |
|
590 |
if (!*failed) |
591 |
{ |
592 |
char unresolved_path[PATH_MAX]; |
593 |
if (!UnicodeToText(unresolved_path, sizeof(unresolved_path), path, rtl_ustr_getLength(path))) |
594 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
595 |
|
596 |
char resolved_path[PATH_MAX]; |
597 |
if (realpath(unresolved_path, resolved_path)) |
598 |
{ |
599 |
if (!TextToUnicode(resolved_path, strlen(resolved_path), path, PATH_MAX)) |
600 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
601 |
|
602 |
current_pos = ustrtoend(path) - 1; |
603 |
} |
604 |
else |
605 |
{ |
606 |
if (EACCES == errno || ENOTDIR == errno || ENOENT == errno) |
607 |
*failed = true; |
608 |
else |
609 |
ferr = oslTranslateFileError(OSL_FET_ERROR, errno); |
610 |
} |
611 |
} |
612 |
|
613 |
return ferr; |
614 |
} |
615 |
|
616 |
/****************************************************** |
617 |
* Works even with non existing paths. The resulting |
618 |
* path must not exceed PATH_MAX else |
619 |
* osl_File_E_NAMETOOLONG is the result |
620 |
******************************************************/ |
621 |
|
622 |
oslFileError osl_getAbsoluteFileURL_impl_(const rtl::OUString& unresolved_path, rtl::OUString& resolved_path) |
623 |
{ |
624 |
// the given unresolved path must not exceed PATH_MAX |
625 |
if (unresolved_path.getLength() >= (PATH_MAX - 2)) |
626 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
627 |
|
628 |
sal_Unicode path_resolved_so_far[PATH_MAX]; |
629 |
const sal_Unicode* punresolved = unresolved_path.getStr(); |
630 |
sal_Unicode* presolvedsf = path_resolved_so_far; |
631 |
|
632 |
// reserve space for leading '/' and trailing '\0' |
633 |
// do not exceed this limit |
634 |
sal_Unicode* sentinel = path_resolved_so_far + PATH_MAX - 2; |
635 |
|
636 |
// if realpath fails with error ENOTDIR, EACCES or ENOENT |
637 |
// we will not call it again, because _osl_realpath should also |
638 |
// work with non existing directories etc. |
639 |
bool realpath_failed = false; |
640 |
oslFileError ferr; |
641 |
|
642 |
path_resolved_so_far[0] = '\0'; |
643 |
|
644 |
while (*punresolved != '\0') |
645 |
{ |
646 |
// ignore '/.' , skip one part back when '/..' |
647 |
|
648 |
if ((UNICHAR_DOT == *punresolved) && (UNICHAR_SLASH == *presolvedsf)) |
649 |
{ |
650 |
if ('\0' == *(punresolved + 1)) |
651 |
{ |
652 |
punresolved++; |
653 |
continue; |
654 |
} |
655 |
else if (UNICHAR_SLASH == *(punresolved + 1)) |
656 |
{ |
657 |
punresolved += 2; |
658 |
continue; |
659 |
} |
660 |
else if ((UNICHAR_DOT == *(punresolved + 1)) && ('\0' == *(punresolved + 2) || (UNICHAR_SLASH == *(punresolved + 2)))) |
661 |
{ |
662 |
_rmlastpathtoken(path_resolved_so_far); |
663 |
|
664 |
presolvedsf = ustrtoend(path_resolved_so_far) - 1; |
665 |
|
666 |
if (UNICHAR_SLASH == *(punresolved + 2)) |
667 |
punresolved += 3; |
668 |
else |
669 |
punresolved += 2; |
670 |
|
671 |
continue; |
672 |
} |
673 |
else // a file or directory name may start with '.' |
674 |
{ |
675 |
if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel) |
676 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
677 |
|
678 |
ustrchrcat(*punresolved++, path_resolved_so_far); |
679 |
|
680 |
if ('\0' == *punresolved && !realpath_failed) |
681 |
{ |
682 |
ferr = _osl_resolvepath( |
683 |
path_resolved_so_far, |
684 |
presolvedsf, |
685 |
&realpath_failed); |
686 |
|
687 |
if (osl_File_E_None != ferr) |
688 |
return ferr; |
689 |
} |
690 |
} |
691 |
} |
692 |
else if (UNICHAR_SLASH == *punresolved) |
693 |
{ |
694 |
if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel) |
695 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
696 |
|
697 |
ustrchrcat(*punresolved++, path_resolved_so_far); |
698 |
|
699 |
if (!realpath_failed) |
700 |
{ |
701 |
ferr = _osl_resolvepath( |
702 |
path_resolved_so_far, |
703 |
presolvedsf, |
704 |
&realpath_failed); |
705 |
|
706 |
if (osl_File_E_None != ferr) |
707 |
return ferr; |
708 |
|
709 |
if (!_islastchr(path_resolved_so_far, UNICHAR_SLASH)) |
710 |
{ |
711 |
if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel) |
712 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
713 |
|
714 |
ustrchrcat(UNICHAR_SLASH, path_resolved_so_far); |
715 |
} |
716 |
} |
717 |
} |
718 |
else // any other character |
719 |
{ |
720 |
if ((presolvedsf = ustrtoend(path_resolved_so_far)) > sentinel) |
721 |
return oslTranslateFileError(OSL_FET_ERROR, ENAMETOOLONG); |
722 |
|
723 |
ustrchrcat(*punresolved++, path_resolved_so_far); |
724 |
|
725 |
if ('\0' == *punresolved && !realpath_failed) |
726 |
{ |
727 |
ferr = _osl_resolvepath( |
728 |
path_resolved_so_far, |
729 |
presolvedsf, |
730 |
&realpath_failed); |
731 |
|
732 |
if (osl_File_E_None != ferr) |
733 |
return ferr; |
734 |
} |
735 |
} |
736 |
} |
737 |
|
738 |
sal_Int32 len = rtl_ustr_getLength(path_resolved_so_far); |
739 |
|
740 |
OSL_ASSERT(len < PATH_MAX); |
741 |
|
742 |
resolved_path = rtl::OUString(path_resolved_so_far, len); |
743 |
|
744 |
return osl_File_E_None; |
745 |
} |
746 |
|
747 |
} // end namespace private |
748 |
|
749 |
|
482 |
|
750 |
/****************************************************** |
483 |
/****************************************************** |
751 |
* osl_getAbsoluteFileURL |
484 |
* osl_getAbsoluteFileURL |