Stat either a symlink or its referent, depending on the settings of * copy_links, copy_unsafe_links, etc. Returns -1 on error, 0 on success. * * If path is the name of a symlink, then the linkbuf buffer (which must hold * MAXPATHLEN chars) will be set to the symlink's target string. * * The stat structure pointed to by stp will contain information about the * link or the referent as approp
| 215 | * The stat structure pointed to by stp will contain information about the |
| 216 | * link or the referent as appropriate, if they exist. */ |
| 217 | static int readlink_stat(const char *path, STRUCT_STAT *stp, char *linkbuf) |
| 218 | { |
| 219 | #ifdef SUPPORT_LINKS |
| 220 | if (link_stat(path, stp, copy_dirlinks) < 0) |
| 221 | return -1; |
| 222 | if (S_ISLNK(stp->st_mode)) { |
| 223 | int llen = do_readlink(path, linkbuf, MAXPATHLEN - 1); |
| 224 | if (llen < 0) |
| 225 | return -1; |
| 226 | linkbuf[llen] = '\0'; |
| 227 | if (copy_unsafe_links && unsafe_symlink(linkbuf, path)) { |
| 228 | if (INFO_GTE(SYMSAFE, 1)) { |
| 229 | rprintf(FINFO,"copying unsafe symlink \"%s\" -> \"%s\"\n", |
| 230 | path, linkbuf); |
| 231 | } |
| 232 | return x_stat(path, stp, NULL); |
| 233 | } |
| 234 | if (munge_symlinks && am_sender && llen > SYMLINK_PREFIX_LEN |
| 235 | && strncmp(linkbuf, SYMLINK_PREFIX, SYMLINK_PREFIX_LEN) == 0) { |
| 236 | memmove(linkbuf, linkbuf + SYMLINK_PREFIX_LEN, |
| 237 | llen - SYMLINK_PREFIX_LEN + 1); |
| 238 | } |
| 239 | } |
| 240 | return 0; |
| 241 | #else |
| 242 | return x_stat(path, stp, NULL); |
| 243 | #endif |
| 244 | } |
| 245 | |
| 246 | int link_stat(const char *path, STRUCT_STAT *stp, int follow_dirlinks) |
| 247 | { |
no test coverage detected