| 1133 | #endif |
| 1134 | |
| 1135 | int get_stat_xattr(const char *fname, int fd, STRUCT_STAT *fst, STRUCT_STAT *xst) |
| 1136 | { |
| 1137 | unsigned int mode; |
| 1138 | int rdev_major, rdev_minor, uid, gid, len; |
| 1139 | char buf[256]; |
| 1140 | |
| 1141 | if (am_root >= 0 || IS_DEVICE(fst->st_mode) || IS_SPECIAL(fst->st_mode)) |
| 1142 | return -1; |
| 1143 | |
| 1144 | if (xst) |
| 1145 | *xst = *fst; |
| 1146 | else |
| 1147 | xst = fst; |
| 1148 | if (fname) { |
| 1149 | fd = -1; |
| 1150 | len = sys_lgetxattr(fname, XSTAT_ATTR, buf, sizeof buf - 1); |
| 1151 | } else { |
| 1152 | fname = "fd"; |
| 1153 | len = sys_fgetxattr(fd, XSTAT_ATTR, buf, sizeof buf - 1); |
| 1154 | } |
| 1155 | if (len >= (int)sizeof buf) { |
| 1156 | len = -1; |
| 1157 | errno = ERANGE; |
| 1158 | } |
| 1159 | if (len < 0) { |
| 1160 | if (errno == ENOTSUP || errno == ENOATTR) |
| 1161 | return -1; |
| 1162 | if (errno == EPERM && S_ISLNK(fst->st_mode)) { |
| 1163 | xst->st_uid = 0; |
| 1164 | xst->st_gid = 0; |
| 1165 | return 0; |
| 1166 | } |
| 1167 | rsyserr(FERROR_XFER, errno, "failed to read xattr %s for %s", |
| 1168 | XSTAT_ATTR, full_fname(fname)); |
| 1169 | return -1; |
| 1170 | } |
| 1171 | buf[len] = '\0'; |
| 1172 | |
| 1173 | if (sscanf(buf, "%o %d,%d %d:%d", |
| 1174 | &mode, &rdev_major, &rdev_minor, &uid, &gid) != 5) { |
| 1175 | rprintf(FERROR, "Corrupt %s xattr attached to %s: \"%s\"\n", |
| 1176 | XSTAT_ATTR, full_fname(fname), buf); |
| 1177 | exit_cleanup(RERR_FILEIO); |
| 1178 | } |
| 1179 | |
| 1180 | xst->st_mode = from_wire_mode(mode); |
| 1181 | xst->st_rdev = MAKEDEV(rdev_major, rdev_minor); |
| 1182 | xst->st_uid = uid; |
| 1183 | xst->st_gid = gid; |
| 1184 | |
| 1185 | return 0; |
| 1186 | } |
| 1187 | |
| 1188 | int set_stat_xattr(const char *fname, struct file_struct *file, mode_t new_mode) |
| 1189 | { |
no test coverage detected