2 * $Id: ad_read.c,v 1.3 2001-06-29 14:14:46 rufustfirefly Exp $
4 * Copyright (c) 1990,1991 Regents of The University of Michigan.
7 * Permission to use, copy, modify, and distribute this software and
8 * its documentation for any purpose and without fee is hereby granted,
9 * provided that the above copyright notice appears in all copies and
10 * that both that copyright notice and this permission notice appear
11 * in supporting documentation, and that the name of The University
12 * of Michigan not be used in advertising or publicity pertaining to
13 * distribution of the software without specific, written prior
14 * permission. This software is supplied as is without expressed or
15 * implied warranties of any kind.
17 * Research Systems Unix Group
18 * The University of Michigan
20 * 535 W. William Street
23 * netatalk@itd.umich.edu
28 #endif /* HAVE_CONFIG_H */
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <atalk/adouble.h>
36 #endif /* HAVE_UNISTD_H */
39 #define MIN(a,b) ((a)<(b)?(a):(b))
42 /* XXX: this would probably benefit from pread.
43 * locks have to be checked before each stream of consecutive
44 * ad_reads to prevent a denial in the middle from causing
46 ssize_t ad_read( ad, eid, off, buf, buflen)
55 /* We're either reading the data fork (and thus the data file)
56 * or we're reading anything else (and thus the header file). */
57 if ( eid == ADEID_DFORK ) {
58 if ( ad->ad_df.adf_off != off ) {
59 if ( lseek( ad->ad_df.adf_fd, (off_t) off, SEEK_SET ) < 0 ) {
62 ad->ad_df.adf_off = off;
64 if (( cc = read( ad->ad_df.adf_fd, buf, buflen )) < 0 ) {
67 ad->ad_df.adf_off += cc;
69 cc = ad->ad_eid[eid].ade_off + off;
71 #ifdef USE_MMAPPED_HEADERS
72 if (eid != ADEID_RFORK) {
73 memcpy(buf, ad->ad_data + cc, buflen);
77 #endif /* USE_MMAPPED_HEADERS */
78 if ( ad->ad_hf.adf_off != cc ) {
79 if ( lseek( ad->ad_hf.adf_fd, (off_t) cc, SEEK_SET ) < 0 ) {
82 ad->ad_hf.adf_off = cc;
85 if (( cc = read( ad->ad_hf.adf_fd, buf, buflen )) < 0 ) {
89 #ifndef USE_MMAPPED_HEADERS
91 * We've just read in bytes from the disk that we read earlier
92 * into ad_data. If we're going to write this buffer out later,
93 * we need to update ad_data.
95 if (ad->ad_hf.adf_off < ad_getentryoff(ad, ADEID_RFORK)) {
96 if ( ad->ad_hf.adf_flags & O_RDWR ) {
97 memcpy(buf, ad->ad_data + ad->ad_hf.adf_off,
98 MIN(sizeof( ad->ad_data ) - ad->ad_hf.adf_off, cc));
100 memcpy(ad->ad_data + ad->ad_hf.adf_off, buf,
101 MIN(sizeof( ad->ad_data ) - ad->ad_hf.adf_off, cc));
104 ad->ad_hf.adf_off += cc;
105 #else /* ! USE_MMAPPED_HEADERS */
107 #endif /* ! USE_MMAPPED_HEADERS */