/*
- * $Id: ad_read.c,v 1.10 2010-02-10 14:05:37 franklahm Exp $
- *
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
*
#include "config.h"
#endif /* HAVE_CONFIG_H */
-#include <atalk/adouble.h>
#include <string.h>
#include <sys/param.h>
+#include <atalk/adouble.h>
+#include <atalk/ea.h>
+
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
#endif /* ! MIN */
cc = adf_pread(&ad->ad_data_fork, buf, buflen, off);
}
} else {
- off_t r_off;
-
- if ( ad_reso_fileno( ad ) == -1 ) {
- /* resource fork is not open ( cf etc/afp/fork.c) */
- return 0;
- }
- r_off = ad_getentryoff(ad, eid) + off;
-
- if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 ) {
- return( -1 );
- }
- /*
- * We've just read in bytes from the disk that we read earlier
- * into ad_data. If we're going to write this buffer out later,
- * we need to update ad_data.
- * FIXME : always false?
- */
- if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
- if ( ad->ad_resource_fork.adf_flags & O_RDWR ) {
- memcpy(buf, ad->ad_data + r_off,
- MIN(sizeof( ad->ad_data ) - r_off, cc));
- } else {
- memcpy(ad->ad_data + r_off, buf,
- MIN(sizeof( ad->ad_data ) - r_off, cc));
+ 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;
+ r_off = ad_getentryoff(ad, eid) + off;
+ if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 )
+ return( -1 );
+ /*
+ * We've just read in bytes from the disk that we read earlier
+ * into ad_data. If we're going to write this buffer out later,
+ * we need to update ad_data.
+ * FIXME : always false?
+ */
+ if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
+ if ( ad->ad_resource_fork.adf_flags & O_RDWR ) {
+ memcpy(buf, ad->ad_data + r_off,
+ MIN(sizeof( ad->ad_data ) - r_off, cc));
+ } else {
+ memcpy(ad->ad_data + r_off, buf,
+ MIN(sizeof( ad->ad_data ) - r_off, cc));
+ }
+ }
+ } else { /* AD_VERSION_EA */
+ if ((off + buflen) > ad->ad_rlen) {
+ errno = ERANGE;
+ return -1;
}
+ memcpy(buf, ad->ad_resforkbuf + off, buflen);
+ cc = buflen;
}
}
#include "config.h"
#endif /* HAVE_CONFIG_H */
-#include <atalk/adouble.h>
-
+#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <errno.h>
+#include <atalk/adouble.h>
+#include <atalk/ea.h>
+#include <atalk/bstrlib.h>
+#include <atalk/bstradd.h>
#ifndef MIN
#define MIN(a,b) ((a)<(b)?(a):(b))
}
/* end is always 0 */
-ssize_t ad_write(struct adouble *ad, const u_int32_t eid, off_t off, const int end, const char *buf, const size_t buflen)
+ssize_t ad_write(struct adouble *ad, uint32_t eid, off_t off, int end, const char *buf, size_t buflen)
{
struct stat st;
ssize_t cc;
}
if ( eid == ADEID_DFORK ) {
- if ( end ) {
- if ( fstat( ad_data_fileno(ad), &st ) < 0 ) {
- return( -1 );
- }
- off = st.st_size - off;
- }
- cc = adf_pwrite(&ad->ad_data_fork, buf, buflen, off);
- } else if ( eid == ADEID_RFORK ) {
- off_t r_off;
-
- if ( end ) {
- if ( fstat( ad_data_fileno(ad), &st ) < 0 ) {
- return( -1 );
- }
- off = st.st_size - off -ad_getentryoff(ad, eid);
- }
- r_off = ad_getentryoff(ad, eid) + off;
- cc = adf_pwrite(&ad->ad_resource_fork, buf, buflen, r_off);
-
- /* sync up our internal buffer FIXME always false? */
- if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
- memcpy(ad->ad_data + r_off, buf, MIN(sizeof(ad->ad_data) -r_off, cc));
+ if ( end ) {
+ if ( fstat( ad_data_fileno(ad), &st ) < 0 ) {
+ return( -1 );
+ }
+ off = st.st_size - off;
}
- if ( ad->ad_rlen < off + cc ) {
- ad->ad_rlen = off + cc;
+ cc = adf_pwrite(&ad->ad_data_fork, buf, buflen, off);
+ } else if ( eid == ADEID_RFORK ) {
+ if (ad->ad_flags != AD_VERSION_EA) {
+ off_t r_off;
+ if ( end ) {
+ if ( fstat( ad_data_fileno(ad), &st ) < 0 )
+ return( -1 );
+ off = st.st_size - off -ad_getentryoff(ad, eid);
+ }
+ r_off = ad_getentryoff(ad, eid) + off;
+ cc = adf_pwrite(&ad->ad_resource_fork, buf, buflen, r_off);
+
+ /* sync up our internal buffer FIXME always false? */
+ if (r_off < ad_getentryoff(ad, ADEID_RFORK))
+ memcpy(ad->ad_data + r_off, buf, MIN(sizeof(ad->ad_data) -r_off, cc));
+ if ( ad->ad_rlen < off + cc )
+ ad->ad_rlen = off + cc;
+ } else { /* AD_VERSION_EA */
+ if ((off + buflen) > ad->ad_resforkbufsize) {
+ free(ad->ad_resforkbuf);
+ size_t roundup = (((off + buflen) / RFORK_EA_ALLOCSIZE) + 1) * RFORK_EA_ALLOCSIZE;
+ if ((ad->ad_resforkbuf = malloc(roundup)) == NULL)
+ return -1;
+ ad->ad_resforkbufsize = roundup;
+ }
+ memcpy(ad->ad_resforkbuf + off, buf, buflen);
+ if ((off + buflen) > ad->ad_rlen)
+ ad->ad_rlen = off + buflen;
+
+ if (sys_lsetxattr(cfrombstr(ad->ad_fullpath), AD_EA_RESO, ad->ad_resforkbuf, ad->ad_rlen, 0) == -1)
+ return -1;
+ cc = buflen;
}
- }
- else {
+ } else {
return -1; /* we don't know how to write if it's not a ressource or data fork */
}
+
return( cc );
}
/* ------------------------ */
int ad_rtruncate( struct adouble *ad, const off_t size)
{
- if ( sys_ftruncate( ad_reso_fileno(ad),
- size + ad->ad_eid[ ADEID_RFORK ].ade_off ) < 0 ) {
- return -1;
- }
+ if (ad->ad_flags != AD_VERSION_EA)
+ if (sys_ftruncate(ad_reso_fileno(ad), size + ad->ad_eid[ ADEID_RFORK ].ade_off ) < 0 )
+ return -1;
+
ad->ad_rlen = size;
return 0;
int ad_dtruncate(struct adouble *ad, const off_t size)
{
- if (sys_ftruncate(ad_data_fileno(ad), size) < 0) {
- return -1;
- }
+ if (sys_ftruncate(ad_data_fileno(ad), size) < 0)
+ return -1;
+
return 0;
}