• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.5/libatalk/adouble/
1/*
2 * Copyright (c) 1990,1995 Regents of The University of Michigan.
3 * All Rights Reserved.  See COPYRIGHT.
4 */
5
6#ifdef HAVE_CONFIG_H
7#include "config.h"
8#endif /* HAVE_CONFIG_H */
9
10#include <atalk/adouble.h>
11
12#include <string.h>
13#include <sys/param.h>
14#include <errno.h>
15
16
17#ifndef MIN
18#define MIN(a,b)	((a)<(b)?(a):(b))
19#endif /* ! MIN */
20
21/* XXX: locking has to be checked before each stream of consecutive
22 *      ad_writes to prevent a lock in the middle from causing problems.
23 */
24
25ssize_t adf_pwrite(struct ad_fd *ad_fd, const void *buf, size_t count, off_t offset)
26{
27    ssize_t		cc;
28
29#ifndef  HAVE_PWRITE
30    if ( ad_fd->adf_off != offset ) {
31	if ( lseek( ad_fd->adf_fd, offset, SEEK_SET ) < 0 ) {
32	    return -1;
33	}
34	ad_fd->adf_off = offset;
35    }
36    cc = write( ad_fd->adf_fd, buf, count );
37    if ( cc < 0 ) {
38        return -1;
39    }
40    ad_fd->adf_off += cc;
41#else
42   cc = pwrite(ad_fd->adf_fd, buf, count, offset );
43#endif
44    return cc;
45}
46
47/* end is always 0 */
48ssize_t ad_write(struct adouble *ad, const u_int32_t eid, off_t off, const int end, const char *buf, const size_t buflen)
49{
50    struct stat		st;
51    ssize_t		cc;
52
53    if (ad_data_fileno(ad) == -2) {
54        /* It's a symlink */
55        errno = EACCES;
56        return -1;
57    }
58
59    if ( eid == ADEID_DFORK ) {
60	if ( end ) {
61	    if ( fstat( ad_data_fileno(ad), &st ) < 0 ) {
62		return( -1 );
63	    }
64	    off = st.st_size - off;
65	}
66	cc = adf_pwrite(&ad->ad_data_fork, buf, buflen, off);
67    } else if ( eid == ADEID_RFORK ) {
68        off_t    r_off;
69
70	if ( end ) {
71	    if ( fstat( ad_data_fileno(ad), &st ) < 0 ) {
72		return( -1 );
73	    }
74	    off = st.st_size - off -ad_getentryoff(ad, eid);
75	}
76	r_off = ad_getentryoff(ad, eid) + off;
77	cc = adf_pwrite(&ad->ad_resource_fork, buf, buflen, r_off);
78
79	/* sync up our internal buffer  FIXME always false? */
80	if (r_off < ad_getentryoff(ad, ADEID_RFORK)) {
81	    memcpy(ad->ad_data + r_off, buf, MIN(sizeof(ad->ad_data) -r_off, cc));
82        }
83        if ( ad->ad_rlen < off + cc ) {
84             ad->ad_rlen = off + cc;
85        }
86    }
87    else {
88        return -1; /* we don't know how to write if it's not a ressource or data fork */
89    }
90    return( cc );
91}
92
93/*
94 * the caller set the locks
95 * ftruncate is undefined when the file length is smaller than 'size'
96 */
97int sys_ftruncate(int fd, off_t length)
98{
99
100#ifndef  HAVE_PWRITE
101off_t           curpos;
102#endif
103int             err;
104struct stat	st;
105char            c = 0;
106
107    if (!ftruncate(fd, length)) {
108        return 0;
109    }
110    /* maybe ftruncate doesn't work if we try to extend the size */
111    err = errno;
112
113#ifndef  HAVE_PWRITE
114    /* we only care about file pointer if we don't use pwrite */
115    if ((off_t)-1 == (curpos = lseek(fd, 0, SEEK_CUR)) ) {
116        errno = err;
117        return -1;
118    }
119#endif
120
121    if ( fstat( fd, &st ) < 0 ) {
122        errno = err;
123        return -1;
124    }
125
126    if (st.st_size > length) {
127        errno = err;
128        return -1;
129    }
130
131    if (lseek(fd, length -1, SEEK_SET) != length -1) {
132        errno = err;
133        return -1;
134    }
135
136    if (1 != write( fd, &c, 1 )) {
137        /* return the write errno */
138        return -1;
139    }
140
141#ifndef  HAVE_PWRITE
142    if (curpos != lseek(fd, curpos,  SEEK_SET)) {
143        errno = err;
144        return -1;
145    }
146#endif
147
148    return 0;
149}
150
151/* ------------------------ */
152int ad_rtruncate( struct adouble *ad, const off_t size)
153{
154    if ( sys_ftruncate( ad_reso_fileno(ad),
155	    size + ad->ad_eid[ ADEID_RFORK ].ade_off ) < 0 ) {
156	return -1;
157    }
158    ad->ad_rlen = size;
159
160    return 0;
161}
162
163int ad_dtruncate(struct adouble *ad, const off_t size)
164{
165    if (sys_ftruncate(ad_data_fileno(ad), size) < 0) {
166      return -1;
167    }
168    return 0;
169}
170