Given the filename, return the absolute path as an SDS string, or NULL * if it fails for some reason. Note that "filename" may be an absolute path * already, this will be detected and handled correctly. * * The function does not try to normalize everything, but only the obvious * case of one or more "../" appearing at the start of "filename" * relative path. */
| 728 | * case of one or more "../" appearing at the start of "filename" |
| 729 | * relative path. */ |
| 730 | sds getAbsolutePath(char *filename) { |
| 731 | char cwd[1024]; |
| 732 | sds abspath; |
| 733 | sds relpath = sdsnew(filename); |
| 734 | |
| 735 | relpath = sdstrim(relpath," \r\n\t"); |
| 736 | if (relpath[0] == '/') return relpath; /* Path is already absolute. */ |
| 737 | |
| 738 | /* If path is relative, join cwd and relative path. */ |
| 739 | if (getcwd(cwd,sizeof(cwd)) == NULL) { |
| 740 | sdsfree(relpath); |
| 741 | return NULL; |
| 742 | } |
| 743 | abspath = sdsnew(cwd); |
| 744 | if (sdslen(abspath) && abspath[sdslen(abspath)-1] != '/') |
| 745 | abspath = sdscat(abspath,"/"); |
| 746 | |
| 747 | /* At this point we have the current path always ending with "/", and |
| 748 | * the trimmed relative path. Try to normalize the obvious case of |
| 749 | * trailing ../ elements at the start of the path. |
| 750 | * |
| 751 | * For every "../" we find in the filename, we remove it and also remove |
| 752 | * the last element of the cwd, unless the current cwd is "/". */ |
| 753 | while (sdslen(relpath) >= 3 && |
| 754 | relpath[0] == '.' && relpath[1] == '.' && relpath[2] == '/') |
| 755 | { |
| 756 | sdsrange(relpath,3,-1); |
| 757 | if (sdslen(abspath) > 1) { |
| 758 | char *p = abspath + sdslen(abspath)-2; |
| 759 | int trimlen = 1; |
| 760 | |
| 761 | while(*p != '/') { |
| 762 | p--; |
| 763 | trimlen++; |
| 764 | } |
| 765 | sdsrange(abspath,0,-(trimlen+1)); |
| 766 | } |
| 767 | } |
| 768 | |
| 769 | /* Finally glue the two parts together. */ |
| 770 | abspath = sdscatsds(abspath,relpath); |
| 771 | sdsfree(relpath); |
| 772 | return abspath; |
| 773 | } |
| 774 | |
| 775 | /* |
| 776 | * Gets the proper timezone in a more portable fashion |