• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/netatalk-3.0.5/libatalk/adouble/
1/*
2 * Copyright (c) 1990,1991 Regents of The University of Michigan.
3 * All Rights Reserved.
4 *
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.
14 *
15 *  Research Systems Unix Group
16 *  The University of Michigan
17 *  c/o Mike Clark
18 *  535 W. William Street
19 *  Ann Arbor, Michigan
20 *  +1-313-763-0525
21 *  netatalk@itd.umich.edu
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif /* HAVE_CONFIG_H */
27
28#include <string.h>
29#include <sys/param.h>
30#include <errno.h>
31#include <stdlib.h>
32
33#include <atalk/adouble.h>
34#include <atalk/ea.h>
35#include <atalk/logger.h>
36#include <atalk/util.h>
37
38ssize_t adf_pread(struct ad_fd *ad_fd, void *buf, size_t count, off_t offset)
39{
40    ssize_t     cc;
41
42#ifndef  HAVE_PREAD
43    if ( ad_fd->adf_off != offset ) {
44        if ( lseek( ad_fd->adf_fd, offset, SEEK_SET ) < 0 ) {
45            return -1;
46        }
47        ad_fd->adf_off = offset;
48    }
49    if (( cc = read( ad_fd->adf_fd, buf, count )) < 0 ) {
50        return -1;
51    }
52    ad_fd->adf_off += cc;
53#else
54    cc = pread(ad_fd->adf_fd, buf, count, offset );
55#endif
56    return cc;
57}
58
59/* XXX: locks have to be checked before each stream of consecutive
60 *      ad_reads to prevent a denial in the middle from causing
61 *      problems. */
62ssize_t ad_read( struct adouble *ad, const uint32_t eid, off_t off, char *buf, const size_t buflen)
63{
64    ssize_t     cc;
65    off_t r_off = 0;
66
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);
73            if (buflen < cc)
74                /* Request buffersize is too small, force AFPERR_PARAM */
75                return -1;
76            memcpy(buf, ad->ad_data_fork.adf_syml, cc);
77        } else {
78            cc = adf_pread(&ad->ad_data_fork, buf, buflen, off);
79        }
80    } else {
81        if (! AD_RSRC_OPEN(ad))
82            /* resource fork is not open ( cf etc/afp/fork.c) */
83            return 0;
84
85        if (ad->ad_vers == AD_VERSION_EA) {
86#ifdef HAVE_EAFD
87            r_off = off;
88#else
89            r_off = off + ADEDOFF_RFORK_OSX;
90#endif
91        } else {
92            r_off = ad_getentryoff(ad, eid) + off;
93        }
94
95        if (( cc = adf_pread( &ad->ad_resource_fork, buf, buflen, r_off )) < 0 )
96            return( -1 );
97    }
98
99    return( cc );
100}
101