| 33 | } |
| 34 | |
| 35 | bool resolvepath(TString& folder, const TString& home) { |
| 36 | Y_ASSERT(home && home.at(0) == '/'); |
| 37 | if (!folder) { |
| 38 | return false; |
| 39 | } |
| 40 | // may be from windows |
| 41 | char* ptr = folder.begin(); |
| 42 | while ((ptr = strchr(ptr, '\\')) != nullptr) { |
| 43 | *ptr = '/'; |
| 44 | } |
| 45 | |
| 46 | if (folder.at(0) == '~') { |
| 47 | if (folder.length() == 1 || folder.at(1) == '/') { |
| 48 | folder = GetHomeDir() + (folder.data() + 1); |
| 49 | } else { |
| 50 | char* buf = (char*)alloca(folder.length() + 1); |
| 51 | strcpy(buf, folder.data() + 1); |
| 52 | char* p = strchr(buf, '/'); |
| 53 | if (p) { |
| 54 | *p++ = 0; |
| 55 | } |
| 56 | passwd* pw = getpwnam(buf); |
| 57 | if (pw) { |
| 58 | folder = pw->pw_dir; |
| 59 | folder += "/"; |
| 60 | if (p) { |
| 61 | folder += p; |
| 62 | } |
| 63 | } else { |
| 64 | return false; // unknown user |
| 65 | } |
| 66 | } |
| 67 | } |
| 68 | int len = folder.length() + home.length() + 1; |
| 69 | char* path = (char*)alloca(len); |
| 70 | if (folder.at(0) != '/') { |
| 71 | strcpy(path, home.data()); |
| 72 | strcpy(strrchr(path, '/') + 1, folder.data()); // the last char must be '/' if it's a dir |
| 73 | } else { |
| 74 | strcpy(path, folder.data()); |
| 75 | } |
| 76 | len = strlen(path) + 1; |
| 77 | // grabbed from url.cpp |
| 78 | char* newpath = (char*)alloca(len + 2); |
| 79 | const char** pp = (const char**)alloca(len * sizeof(char*)); |
| 80 | int i = 0; |
| 81 | for (char* s = path; s;) { |
| 82 | pp[i++] = s; |
| 83 | s = strchr(s, '/'); |
| 84 | if (s) { |
| 85 | *s++ = 0; |
| 86 | } |
| 87 | } |
| 88 | |
| 89 | for (int j = 1; j < i;) { |
| 90 | const char*& p = pp[j]; |
| 91 | if (strcmp(p, ".") == 0 || strcmp(p, "") == 0) { |
| 92 | if (j == i - 1) { |
no test coverage detected