2419 res->path = util_concat_path(path, "/"); |
2419 res->path = util_concat_path(path, "/"); |
2420 res->isdirectory = 1; |
2420 res->isdirectory = 1; |
2421 } |
2421 } |
2422 |
2422 |
2423 if(S_ISLNK(s.st_mode)) { |
2423 if(S_ISLNK(s.st_mode)) { |
2424 size_t lnksize = s.st_size > 256 ? s.st_size : 256; |
2424 off_t l_sz = s.st_size + 16; |
|
2425 size_t lnksize = l_sz > 256 ? l_sz : 256; |
2425 char *lnkbuf = malloc(lnksize); |
2426 char *lnkbuf = malloc(lnksize); |
2426 |
2427 |
2427 ssize_t len = 0; |
2428 ssize_t len = 0; |
2428 for(int i=0;i<4;i++) { |
2429 for(int i=0;i<4;i++) { |
2429 // we try to read the link at most 4 times |
2430 // we try to read the link at most 4 times |
2435 lnksize *= 2; |
2436 lnksize *= 2; |
2436 lnkbuf = realloc(lnkbuf, lnksize); |
2437 lnkbuf = realloc(lnkbuf, lnksize); |
2437 } |
2438 } |
2438 |
2439 |
2439 if(len > 0) { |
2440 if(len > 0) { |
2440 res->link_target = lnkbuf; |
2441 // readlink successful |
2441 res->link_target[len] = 0; |
2442 lnkbuf[len] = 0; |
2442 } else { |
2443 |
2443 free(lnkbuf); |
2444 char *normalized = NULL; |
|
2445 if(lnkbuf[0] != '/') { |
|
2446 char *link_parent = util_parent_path(res->path); |
|
2447 char *abs_link_parent = util_concat_path(dir->path, link_parent); |
|
2448 char *link = util_concat_path(abs_link_parent, lnkbuf); |
|
2449 normalized = util_path_normalize(link); |
|
2450 free(abs_link_parent); |
|
2451 free(link_parent); |
|
2452 free(link); |
|
2453 } else { |
|
2454 normalized = util_path_normalize(lnkbuf); |
|
2455 } |
|
2456 |
|
2457 if(util_path_isrelated(dir->path, normalized)) { |
|
2458 // the link points to a file inside the syncdir |
|
2459 char *rel = util_create_relative_path(normalized, file_path); |
|
2460 res->link_target = rel; |
|
2461 } |
|
2462 free(normalized); |
2444 } |
2463 } |
2445 |
2464 |
2446 free(lnkbuf); |
2465 free(lnkbuf); |
2447 } |
2466 } |
2448 |
2467 |