2 * Copyright (c) 1990,1991 Regents of The University of Michigan.
5 * Permission to use, copy, modify, and distribute this software and
6 * its documentation for any purpose and without fee is hereby granted,
7 * provided that the above copyright notice appears in all copies and
8 * that both that copyright notice and this permission notice appear
9 * in supporting documentation, and that the name of The University
10 * of Michigan not be used in advertising or publicity pertaining to
11 * distribution of the software without specific, written prior
12 * permission. This software is supplied as is without expressed or
13 * implied warranties of any kind.
15 * Research Systems Unix Group
16 * The University of Michigan
18 * 535 W. William Street
21 * netatalk@itd.umich.edu
26 #endif /* HAVE_CONFIG_H */
29 #include <sys/param.h>
32 #include <atalk/adouble.h>
36 #define MIN(a,b) ((a)<(b)?(a):(b))
39 ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset)
44 if ( ad_fd->adf_off != offset ) {
45 if ( lseek( ad_fd->adf_fd, offset, SEEK_SET ) < 0 ) {
48 ad_fd->adf_off = offset;
50 if (( cc = read( ad_fd->adf_fd, buf, count )) < 0 ) {
55 cc = pread(ad_fd->adf_fd, buf, count, offset );
60 /* XXX: locks have to be checked before each stream of consecutive
61 * ad_reads to prevent a denial in the middle from causing
63 ssize_t ad_read( struct adouble *ad, const u_int32_t eid, off_t off, char *buf, const size_t buflen)
67 /* We're either reading the data fork (and thus the data file)
68 * or we're reading anything else (and thus the header file). */
69 if ( eid == ADEID_DFORK ) {
70 if (ad->ad_data_fork.adf_syml !=0 ) {
71 /* It's a symlink, we already have the target in adf_syml */
72 cc = strlen(ad->ad_data_fork.adf_syml);
74 /* Request buffersize is too small, force AFPERR_PARAM */
76 memcpy(buf, ad->ad_data_fork.adf_syml, cc);
78 cc = adf_pread(&ad->ad_data_fork, buf, buflen, off);
81 if (ad->ad_flags != AD_VERSION_EA) {
83 if ( ad_reso_fileno( ad ) == -1 )
84 /* resource fork is not open ( cf etc/afp/fork.c) */
86 r_off = ad_getentryoff(ad, eid) + off;
87 if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 )
90 * We've just read in bytes from the disk that we read earlier
91 * into ad_data. If we're going to write this buffer out later,
92 * we need to update ad_data.
93 * FIXME : always false?
95 if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
96 if ( ad->ad_resource_fork.adf_flags & O_RDWR ) {
97 memcpy(buf, ad->ad_data + r_off,
98 MIN(sizeof( ad->ad_data ) - r_off, cc));
100 memcpy(ad->ad_data + r_off, buf,
101 MIN(sizeof( ad->ad_data ) - r_off, cc));
104 } else { /* AD_VERSION_EA */
105 if ((off + buflen) > ad->ad_rlen) {
109 memcpy(buf, ad->ad_resforkbuf + off, buflen);