return( AFPERR_BITMAP );
}
- if ( ad_reso_fileno( ofork->of_ad ) == -1 ) { /* META ? */
+ if (! AD_META_OPEN(ofork->of_ad)) {
adp = NULL;
} else {
adp = ofork->of_ad;
return( AFPERR_PARAM );
}
- if (AD_META_OPEN(ofork->of_ad))) {
+ if (AD_META_OPEN(ofork->of_ad)) {
if ( ad_refresh( ofork->of_ad ) < 0 ) {
LOG(log_error, logtype_afpd, "getforkparams(%s): ad_refresh: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );
extern char *ad_dir (const char *);
extern const char *ad_path (const char *, int);
extern const char *ad_path_ea (const char *, int);
-extern int ad_mode (const char *, int);
-extern int ad_mkdir (const char *, int);
+extern int ad_mode (const char *, mode_t);
+extern int ad_mkdir (const char *, mode_t);
struct vol;
extern void ad_init (struct adouble *, const struct vol * restrict);
extern void ad_init_old (struct adouble *ad, int flags, int options);
*/
int ad_setid (struct adouble *adp, const dev_t dev, const ino_t ino , const uint32_t id, const cnid_t did, const void *stamp)
{
- if ((adp->ad_flags == AD_VERSION2) && (adp->ad_options & ADVOL_CACHE)) {
+ if ((adp->ad_vers == AD_VERSION2) && (adp->ad_options & ADVOL_CACHE)) {
/* ad_getid depends on this to detect presence of ALL entries */
ad_setentrylen( adp, ADEID_PRIVID, sizeof(id));
nent = htons( nent );
memcpy(nentp, &nent, sizeof( nent ));
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
len = ad_getentryoff(ad, ADEID_RFORK);
break;
int len;
struct ad_fd *adf;
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
adf = ad->ad_mdp;
break;
}
len = ad->ad_ops->ad_rebuild_header(ad);
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
if (adf_pwrite(ad->ad_mdp, ad->ad_data, len, 0) != len) {
if (errno == 0)
}
if ((adflags & ADFLAGS_HF)) {
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
if ((ad_meta_fileno(ad) != -1) && !(--ad->ad_mdp->adf_refcount)) {
if (close( ad_meta_fileno(ad) ) < 0)
}
if ((adflags & ADFLAGS_RF)) {
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
/* Do nothing as ADFLAGS_RF == ADFLAGS_HF */
break;
}
}
} else { /* rfork */
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
if (ad_meta_fileno(ad) == -1 || ad_reso_fileno(ad) == -1) {
/* there's no meta data. return a lock error
*/
int ad_testlock(struct adouble *ad, int eid, const off_t off)
{
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
return ad_testlock_v2(ad, eid, off);
case AD_VERSION_EA:
*/
uint16_t ad_openforks(struct adouble *ad, uint16_t attrbits)
{
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
return ad_openforks_v2(ad, attrbits);
case AD_VERSION_EA:
struct stat st;
ad->ad_magic = AD_MAGIC;
- ad->ad_version = ad->ad_flags & 0x0f0000;
+ ad->ad_version = ad->ad_vers & 0x0f0000;
if (!ad->ad_version) {
ad->ad_version = AD_VERSION;
}
memset(ad->ad_data, 0, sizeof(ad->ad_data));
- if (ad->ad_flags == AD_VERSION2)
+ if (ad->ad_vers == AD_VERSION2)
eid = entry_order2;
- else if (ad->ad_flags == AD_VERSION_EA)
+ else if (ad->ad_vers == AD_VERSION_EA)
eid = entry_order_ea;
else {
return -1;
/* Now parse entries */
parse_entries(ad, buf + AD_HEADER_LEN, nentries);
+
+ return 0;
+}
+
+static int ad_rsrc_len_ea(struct adouble *ad)
+{
+ ssize_t rlen;
+
+ if ((rlen = sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
+ switch (errno) {
+ case ENOATTR:
+ case ENOENT:
+ ad->ad_rlen = 0;
+ break;
+ default:
+ LOG(log_error, logtype_default, "ad_refresh_rsrc_len_ea: %s", strerror(errno));
+ ad->ad_rlen = 0;
+ return -1;
+ }
+ }
+ ad->ad_rlen = rlen;
return 0;
}
/* ----------------
return access right and inode of path parent directory
*/
-static int ad_mode_st(const char *path, int *mode, struct stat *stbuf)
+static int ad_mode_st(const char *path, mode_t *mode, struct stat *stbuf)
{
if (*mode == 0) {
return -1;
static int ad_error(struct adouble *ad, int adflags)
{
int err = errno;
- if ((adflags & ADFLAGS_NOHF)) { /* 1 */
+ if (adflags & ADFLAGS_NOHF) { /* 1 */
ad->ad_adflags &= ~ADFLAGS_HF;
return 0;
}
- if ((adflags & ADFLAGS_DF) { /* 2 */
+ if (adflags & ADFLAGS_DF) { /* 2 */
ad_close( ad, ADFLAGS_DF );
err = errno;
}
memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
ad->ad_rlen = 0;
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
ret = ad_open_hf_v2(path, adflags, mode, ad);
break;
return ret;
}
+
/*!
* Open ressource fork
*
{
int ret = 0;
int oflags;
+ ssize_t rlen;
- if (ad->ad_flags != AD_VERSION_EA)
+ if (ad->ad_vers != AD_VERSION_EA)
return 0;
LOG(log_debug, logtype_default, "ad_open_rf(\"%s\", %04o)", path, mode);
adf_lock_init(&ad->ad_data_fork);
}
- if ((ad->ad_rlen = sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
- switch (errno) {
- case ENOATTR:
- ad->ad_rlen = 0;
- break;
- default:
- LOG(log_warning, logtype_default, "ad_open_rf(\"%s\"): %s",
- fullpathname(path), strerror(errno));
- ret = -1;
- goto exit;
- }
- }
-
- /* Round up and allocate buffer */
- size_t roundup = ((ad->ad_rlen / RFORK_EA_ALLOCSIZE) + 1) * RFORK_EA_ALLOCSIZE;
- if ((ad->ad_resforkbuf = malloc(roundup)) == NULL) {
- ret = -1;
+ if ((ret = ad_rsrc_len_ea(ad)) != 0)
goto exit;
- }
-
- ad->ad_resforkbufsize = roundup;
-
- /* Read the EA into the buffer */
- if (ad->ad_rlen > 0) {
- if (sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen) == -1) {
- ret = -1;
- goto exit;
- }
- }
ad->ad_data_fork.adf_refcount++;
exit:
- if (ret != 0) {
- if (ad->ad_resforkbuf)
- free(ad->ad_resforkbuf);
- ad->ad_resforkbuf = NULL;
- ad->ad_rlen = 0;
- ad->ad_resforkbufsize = 0;
- }
-
return ret;
}
/* ----------------
return access right of path parent directory
*/
-int ad_mode( const char *path, int mode)
+int ad_mode( const char *path, mode_t mode)
{
struct stat stbuf;
ad_mode_st(path, &mode, &stbuf);
/*
* Use mkdir() with mode bits taken from ad_mode().
*/
-int ad_mkdir( const char *path, int mode)
+int ad_mkdir( const char *path, mode_t mode)
{
int ret;
int st_invalid;
static void ad_init_func(struct adouble *ad)
{
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
ad->ad_ops = &ad_adouble;
ad->ad_rfp = &ad->ad_resource_fork;
void ad_init_old(struct adouble *ad, int flags, int options)
{
- ad->ad_flags = flags;
+ ad->ad_vers = flags;
ad->ad_options = options;
ad_init_func(ad);
}
void ad_init(struct adouble *ad, const struct vol * restrict vol)
{
- ad->ad_flags = vol->v_adouble;
+ ad->ad_vers = vol->v_adouble;
ad->ad_options = vol->v_ad_options;
ad->ad_maxeafssize = 3500; /* FIXME: option from vol */
ad_init_func(ad);
int ad_refresh(struct adouble *ad)
{
-
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
if (ad_meta_fileno(ad) == -1)
return -1;
case AD_VERSION_EA:
if (ad_data_fileno(ad) == -1)
return -1;
+ if (ad_rsrc_len_ea(ad) != 0)
+ return -1;
return ad->ad_ops->ad_header_read(ad, NULL);
break;
default:
#include <string.h>
#include <sys/param.h>
#include <errno.h>
+#include <stdlib.h>
#include <atalk/adouble.h>
#include <atalk/ea.h>
-
-#ifndef MIN
-#define MIN(a,b) ((a)<(b)?(a):(b))
-#endif /* ! MIN */
+#include <atalk/logger.h>
+#include <atalk/util.h>
ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset)
{
ssize_t ad_read( struct adouble *ad, const uint32_t eid, off_t off, char *buf, const size_t buflen)
{
ssize_t cc;
+ ssize_t rlen;
+ off_t r_off;
/* We're either reading the data fork (and thus the data file)
* or we're reading anything else (and thus the header file). */
cc = adf_pread(&ad->ad_data_fork, buf, buflen, off);
}
} else {
- if (ad->ad_flags != AD_VERSION_EA) {
- off_t r_off;
- if ( ad_reso_fileno( ad ) == -1 )
- /* resource fork is not open ( cf etc/afp/fork.c) */
- return 0;
+ if (! AD_RSRC_OPEN(ad))
+ /* resource fork is not open ( cf etc/afp/fork.c) */
+ return 0;
+
+ switch (ad->ad_vers) {
+ case AD_VERSION2:
r_off = ad_getentryoff(ad, eid) + off;
if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 )
return( -1 );
MIN(sizeof( ad->ad_data ) - r_off, cc));
}
}
- } else { /* AD_VERSION_EA */
+ break;
+
+ case AD_VERSION_EA:
+ if ((rlen = sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, NULL, 0)) <= 0) {
+ switch (errno) {
+ case ENOATTR:
+ case ENOENT:
+ cc = ad->ad_rlen = 0;
+ break;
+ default:
+ LOG(log_error, logtype_default, "ad_read: %s", strerror(errno));
+ return -1;
+ }
+ }
+ ad->ad_rlen = rlen;
+
if (off > ad->ad_rlen) {
errno = ERANGE;
return -1;
}
- if (ad->ad_rlen == 0)
- return 0;
+
+ if (ad->ad_resforkbuf == NULL) {
+ if ((ad->ad_resforkbuf = malloc(ad->ad_rlen)) == NULL) {
+ ad->ad_rlen = 0;
+ return -1;
+ }
+ } else {
+ if ((ad->ad_resforkbuf = realloc(ad->ad_resforkbuf, ad->ad_rlen)) == NULL) {
+ ad->ad_rlen = 0;
+ return -1;
+ }
+ }
+
+ if (sys_fgetxattr(ad_data_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen) == -1) {
+ ad->ad_rlen = 0;
+ return -1;
+ }
+
if ((off + buflen) > ad->ad_rlen)
cc = ad->ad_rlen;
memcpy(buf, ad->ad_resforkbuf + off, cc);
- }
+ break;
+ } /* switch (ad->ad_vers) */
}
return( cc );
}
cc = adf_pwrite(&ad->ad_data_fork, buf, buflen, off);
} else if ( eid == ADEID_RFORK ) {
- switch (ad->ad_flags) {
+ switch (ad->ad_vers) {
case AD_VERSION2:
if ( end ) {
break;
case AD_VERSION_EA:
- if ((off + buflen) > ad->ad_resforkbufsize) {
- roundup = (((off + buflen) / RFORK_EA_ALLOCSIZE) + 1) * RFORK_EA_ALLOCSIZE;
- if ((ad->ad_resforkbuf = realloc(ad->ad_resforkbuf, roundup)) == NULL)
+ if (ad->ad_resforkbuf == NULL) {
+ ad->ad_rlen = off + buflen;
+ if ((ad->ad_resforkbuf = malloc(ad->ad_rlen)) == NULL) {
+ ad->ad_rlen = 0;
return -1;
- ad->ad_resforkbufsize = roundup;
+ }
}
- memcpy(ad->ad_resforkbuf + off, buf, buflen);
- if ((off + buflen) > ad->ad_rlen)
+ if ((off + buflen) > ad->ad_rlen) {
+ if ((ad->ad_resforkbuf = realloc(ad->ad_resforkbuf, off + buflen)) == NULL)
+ return -1;
ad->ad_rlen = off + buflen;
+ }
+ memcpy(ad->ad_resforkbuf + off, buf, buflen);
if (fsetrsrcea(ad, ad_data_fileno(ad), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen, 0) == -1)
return -1;
/* ------------------------ */
int ad_rtruncate( struct adouble *ad, const off_t size)
{
- if (ad->ad_flags != AD_VERSION_EA)
+ if (ad->ad_vers != AD_VERSION_EA)
if (sys_ftruncate(ad_reso_fileno(ad), size + ad->ad_eid[ ADEID_RFORK ].ade_off ) < 0 )
return -1;
{
int filedes = openat(fildes, path, oflag, mode);
if (filedes == -1) {
- LOG(log_error, logtype_default, "openat(\"%s\"): %s",
- path, strerror(errno));
+ if (errno != ENOENT)
+ LOG(log_error, logtype_default, "openat(\"%s\"): %s",
+ path, strerror(errno));
+ errno = ENOATTR;
}
return filedes;
}