if (ad->ad_data_fork.adf_fd == -1) {
switch (errno) {
+ case EACCES:
case EPERM:
case EROFS:
if ((adflags & ADFLAGS_SETSHRMD) && (adflags & ADFLAGS_RDONLY)) {
if (ad_meta_fileno(ad) != -1) {
/* the file is already open, but we want write access: */
- if (!(adflags & ADFLAGS_RDONLY) &&
+ if ((adflags & ADFLAGS_RDWR) &&
/* and it was already denied: */
- !(ad->ad_mdp->adf_flags & O_RDWR)) {
+ (ad->ad_mdp->adf_flags & O_RDONLY)) {
errno = EACCES;
return -1;
}
ad->ad_mdp->adf_fd = open(ad_p, nocreatflags);
- if (ad->ad_mdp->adf_fd < 0) {
+ if (ad->ad_mdp->adf_fd != -1) {
+ ad->ad_mdp->adf_flags = nocreatflags;
+ } else {
switch (errno) {
+ case EACCES:
case EPERM:
case EROFS:
if ((adflags & ADFLAGS_RDONLY) && (adflags & ADFLAGS_SETSHRMD)) {
nocreatflags |= O_RDONLY;
if ((ad->ad_mdp->adf_fd = open(ad_p, nocreatflags)) == -1)
return -1;
+ ad->ad_mdp->adf_flags = nocreatflags;
break;
}
return -1;
if (!st_invalid)
ad_chown(ad_p, &st_dir);
break;
+ default:
+ return -1;
}
- } else {
- ad->ad_mdp->adf_flags = nocreatflags;
- if (fstat(ad->ad_mdp->adf_fd, &st_meta) == 0 && st_meta.st_size == 0) {
- /* for 0 length files, treat them as new. */
- ad->ad_mdp->adf_flags |= O_TRUNC;
- } else {
- /* we have valid data in st_meta stat structure, reused it in ad_header_read */
- pst = &st_meta;
+ }
+
+ if (!(ad->ad_mdp->adf_flags & O_CREAT)) {
+ /* check for 0 length files, treat them as new. */
+ if (fstat(ad->ad_mdp->adf_fd, &st_meta) == 0) {
+ if (st_meta.st_size == 0)
+ ad->ad_mdp->adf_flags |= O_TRUNC;
+ else
+ /* we have valid data in st_meta stat structure, reused it in ad_header_read */
+ pst = &st_meta;
}
}
ssize_t rforklen;
int oflags = O_NOFOLLOW;
- oflags = ad2openflags(adflags) & ~(O_CREAT | O_TRUNC);
+ LOG(log_error, logtype_default, "ad_open_hf_ea(\"%s\", %04o)", path, mode);
+
+ oflags |= ad2openflags(adflags) & ~(O_CREAT | O_TRUNC);
- if (ad_meta_fileno(ad) == -1) {
- if ((ad_meta_fileno(ad) = open(path, oflags)) == -1)
+ if (ad_data_fileno(ad) != -1) {
+ /* the file is already open, but we want write access: */
+ if ((adflags & ADFLAGS_RDWR) &&
+ /* and it was already denied: */
+ (ad->ad_data_fork.adf_flags & O_RDONLY)) {
+ LOG(log_error, logtype_default, "ad_open_hf_ea(%s): rw request for ro file: %s",
+ fullpathname(path), strerror(errno));
+ errno = EACCES;
+ return -1;
+ }
+
+ /* it's not new anymore */
+ ad->ad_mdp->adf_flags &= ~( O_TRUNC | O_CREAT );
+ } else {
+ if ((ad_data_fileno(ad) = open(path, oflags)) == -1)
goto error;
- ad->ad_mdp->adf_flags = oflags;
- ad->ad_mdp->adf_refcount = 1;
- adf_lock_init(ad->ad_mdp);
+ ad->ad_data_fork.adf_flags = oflags;
+ adf_lock_init(&ad->ad_data_fork);
}
/* Read the adouble header in and parse it.*/
if (ad->ad_ops->ad_header_read(ad, NULL) != 0) {
+ LOG(log_error, logtype_default, "ad_open_hf_ea(\"%s\", %04o): ad_header_read: %s", path, mode, strerror(errno));
+
if (!(adflags & ADFLAGS_CREATE))
goto error;
+ LOG(log_error, logtype_default, "ad_open_hf_ea(\"%s\", %04o): create metadata EA", path, mode);
/* It doesnt exist, EPERM or another error */
if (!(errno == ENOATTR || errno == ENOENT)) {
LOG(log_debug, logtype_default, "ad_open_hf_ea(\"%s\"): created metadata EA", path);
}
- ad->ad_mdp->adf_refcount++;
+ ad->ad_data_fork.adf_refcount++;
- if ((rforklen = sys_fgetxattr(ad_meta_fileno(ad), AD_EA_RESO, NULL, 0)) > 0)
+ if ((rforklen = sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, NULL, 0)) > 0)
ad->ad_rlen = rforklen;
return 0;
error:
- if (ad_meta_fileno(ad) != -1) {
- close(ad_meta_fileno(ad));
- ad_meta_fileno(ad) = -1;
+ if (ad_data_fileno(ad) != -1) {
+ close(ad_data_fileno(ad));
+ ad_data_fileno(ad) = -1;
}
return ad_error(ad, adflags);
}
LOG(log_debug, logtype_default, "ad_open_rf(\"%s\", %04o)",
path, mode);
- if ((ad->ad_rlen = sys_fgetxattr(ad_meta_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
+ if ((ad->ad_rlen = sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
switch (errno) {
case ENOATTR:
ad->ad_rlen = 0;
/* Read the EA into the buffer */
if (ad->ad_rlen > 0) {
- if (sys_fgetxattr(ad_meta_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen) == -1) {
+ if (sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen) == -1) {
ret = -1;
goto exit;
}
break;
case AD_VERSION_EA:
ad->ad_ops = &ad_adouble_ea;
- ad->ad_rfp = &ad->ad_data_fork;
- ad->ad_mdp = &ad->ad_data_fork;
+ ad->ad_rfp = &ad->ad_resource_fork;
+ ad->ad_mdp = &ad->ad_resource_fork;
break;
default:
LOG(log_error, logtype_default, "ad_init: unknown AD version");
int ad_refresh(struct adouble *ad)
{
- if (ad_meta_fileno(ad) == -1)
+ switch (ad->ad_flags) {
+ case AD_VERSION2:
+ if (ad_meta_fileno(ad) == -1)
+ return -1;
+ return ad->ad_ops->ad_header_read(ad, NULL);
+ break;
+ case AD_VERSION_EA:
+ if (ad_data_fileno(ad) == -1)
+ return -1;
+ return ad->ad_ops->ad_header_read(ad, NULL);
+ break;
+ default:
return -1;
+ break;
+ }
- return ad->ad_ops->ad_header_read(ad, NULL);
}
int ad_openat(struct adouble *ad,