X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fadouble%2Fad_read.c;h=852a6e963b94f964e3b47d1ea8b67df6cac0717e;hb=3a84db87064922ad10ac10cc1d6833380e575995;hp=1fcda8a11dba36c1e9b823ac04773fc040ac9990;hpb=458fcac4e6aee7eb54ba744f57169f70cce12505;p=netatalk.git diff --git a/libatalk/adouble/ad_read.c b/libatalk/adouble/ad_read.c index 1fcda8a1..852a6e96 100644 --- a/libatalk/adouble/ad_read.c +++ b/libatalk/adouble/ad_read.c @@ -12,95 +12,88 @@ * permission. This software is supplied as is without expressed or * implied warranties of any kind. * - * Research Systems Unix Group - * The University of Michigan - * c/o Mike Clark - * 535 W. William Street - * Ann Arbor, Michigan - * +1-313-763-0525 - * netatalk@itd.umich.edu + * Research Systems Unix Group + * The University of Michigan + * c/o Mike Clark + * 535 W. William Street + * Ann Arbor, Michigan + * +1-313-763-0525 + * netatalk@itd.umich.edu */ #ifdef HAVE_CONFIG_H #include "config.h" -#endif +#endif /* HAVE_CONFIG_H */ #include -#include #include +#include +#include + #include -#include +#include +#include +#include -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) +ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset) +{ + ssize_t cc; + +#ifndef HAVE_PREAD + if ( ad_fd->adf_off != offset ) { + if ( lseek( ad_fd->adf_fd, offset, SEEK_SET ) < 0 ) { + return -1; + } + ad_fd->adf_off = offset; + } + if (( cc = read( ad_fd->adf_fd, buf, count )) < 0 ) { + return -1; + } + ad_fd->adf_off += cc; +#else + cc = pread(ad_fd->adf_fd, buf, count, offset ); #endif + return cc; +} -/* XXX: this would probably benefit from pread. - * locks have to be checked before each stream of consecutive +/* XXX: locks have to be checked before each stream of consecutive * ad_reads to prevent a denial in the middle from causing * problems. */ -ssize_t ad_read( ad, eid, off, buf, buflen) - struct adouble *ad; - const u_int32_t eid; - off_t off; - char *buf; - const size_t buflen; +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 cc; + off_t r_off = 0; /* We're either reading the data fork (and thus the data file) * or we're reading anything else (and thus the header file). */ if ( eid == ADEID_DFORK ) { - if ( ad->ad_df.adf_off != off ) { - if ( lseek( ad->ad_df.adf_fd, (off_t) off, SEEK_SET ) < 0 ) { - return( -1 ); - } - ad->ad_df.adf_off = off; - } - if (( cc = read( ad->ad_df.adf_fd, buf, buflen )) < 0 ) { - return( -1 ); - } - ad->ad_df.adf_off += cc; + if (ad->ad_data_fork.adf_syml !=0 ) { + /* It's a symlink, we already have the target in adf_syml */ + cc = strlen(ad->ad_data_fork.adf_syml); + if (buflen < cc) + /* Request buffersize is too small, force AFPERR_PARAM */ + return -1; + memcpy(buf, ad->ad_data_fork.adf_syml, cc); + } else { + cc = adf_pread(&ad->ad_data_fork, buf, buflen, off); + } } else { - cc = ad->ad_eid[eid].ade_off + off; + if (! AD_RSRC_OPEN(ad)) + /* resource fork is not open ( cf etc/afp/fork.c) */ + return 0; -#ifdef USE_MMAPPED_HEADERS - if (eid != ADEID_RFORK) { - memcpy(buf, ad->ad_data + cc, buflen); - cc = buflen; - goto ad_read_done; - } -#endif - if ( ad->ad_hf.adf_off != cc ) { - if ( lseek( ad->ad_hf.adf_fd, (off_t) cc, SEEK_SET ) < 0 ) { - return( -1 ); - } - ad->ad_hf.adf_off = cc; - } - - if (( cc = read( ad->ad_hf.adf_fd, buf, buflen )) < 0 ) { - return( -1 ); - } - -#ifndef USE_MMAPPED_HEADERS - /* - * 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. - */ - if (ad->ad_hf.adf_off < ad_getentryoff(ad, ADEID_RFORK)) { - if ( ad->ad_hf.adf_flags & O_RDWR ) { - memcpy(buf, ad->ad_data + ad->ad_hf.adf_off, - MIN(sizeof( ad->ad_data ) - ad->ad_hf.adf_off, cc)); - } else { - memcpy(ad->ad_data + ad->ad_hf.adf_off, buf, - MIN(sizeof( ad->ad_data ) - ad->ad_hf.adf_off, cc)); - } - } - ad->ad_hf.adf_off += cc; + if (ad->ad_vers == AD_VERSION_EA) { +#ifdef HAVE_EAFD + r_off = off; #else -ad_read_done: + r_off = off + ADEDOFF_RFORK_OSX; #endif + } else { + r_off = ad_getentryoff(ad, eid) + off; + } + + if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 ) + return( -1 ); } return( cc );