#include <sys/socket.h>
#include <inttypes.h>
-#include <netatalk/at.h>
#include <atalk/dsi.h>
#include <atalk/afp.h>
#include <atalk/adouble.h>
#include <atalk/util.h>
#include <atalk/cnid.h>
#include <atalk/bstradd.h>
+#include <atalk/globals.h>
#include "fork.h"
#include "file.h"
-#include "globals.h"
#include "directory.h"
#include "desktop.h"
#include "volume.h"
struct ofork *writtenfork;
#endif
-static int getforkparams(struct ofork *ofork, u_int16_t bitmap, char *buf, size_t *buflen)
+static int getforkparams(struct ofork *ofork, uint16_t bitmap, char *buf, size_t *buflen)
{
struct path path;
struct stat *st;
static off_t get_off_t(char **ibuf, int is64)
{
- u_int32_t temp;
+ uint32_t temp;
off_t ret;
ret = 0;
static int set_off_t(off_t offset, char *rbuf, int is64)
{
- u_int32_t temp;
+ uint32_t temp;
int ret;
ret = 0;
return AFPERR_BADTYPE;
}
- LOG(log_debug, logtype_afpd,
- "afp_openfork(\"%s\", %s)",
- abspath(s_path->u_name),
- (fork & OPENFORK_RSCS) ? "OPENFORK_RSCS" : "OPENFORK_DATA");
+ LOG(log_debug, logtype_afpd, "afp_openfork(\"%s\", %s)",
+ fullpathname(s_path->u_name), (fork & OPENFORK_RSCS) ? "RSRC" : "DATA");
/* stat() data fork st is set because it's not a dir */
switch ( s_path->st_errno ) {
ret = AFPERR_NOOBJ;
if (access & OPENACC_WR) {
/* try opening in read-write mode */
- if (ad_open(ofork->of_ad, upath, adflags, O_RDWR, O_RDWR) < 0) {
+ if (ad_open(ofork->of_ad, upath,
+ adflags | ADFLAGS_RDWR | ADFLAGS_SETSHRMD) < 0) {
switch ( errno ) {
case EROFS:
ret = AFPERR_VLOCK;
case ENOENT:
if (fork == OPENFORK_DATA) {
/* try to open only the data fork */
- if (ad_open(ofork->of_ad, upath, ADFLAGS_DF, O_RDWR) < 0) {
+ if (ad_open(ofork->of_ad, upath,
+ ADFLAGS_DF | ADFLAGS_RDWR | ADFLAGS_SETSHRMD) < 0) {
goto openfork_err;
}
adflags = ADFLAGS_DF;
} else {
/* here's the deal. we only try to create the resource
* fork if the user wants to open it for write acess. */
- if (ad_open(ofork->of_ad, upath, adflags, O_RDWR | O_CREAT, 0666, O_RDWR | O_CREAT, 0666) < 0)
+ if (ad_open(ofork->of_ad, upath,
+ adflags | ADFLAGS_RDWR | ADFLAGS_SETSHRMD | ADFLAGS_CREATE, 0666) < 0)
goto openfork_err;
ofork->of_flags |= AFPFORK_OPEN;
}
} else {
/* try opening in read-only mode */
ret = AFPERR_NOOBJ;
- if (ad_open(ofork->of_ad, upath, adflags, O_RDONLY, O_RDONLY) < 0) {
+ /* we need w access for setting deny mode fcntl excl lock */
+ if (ad_open(ofork->of_ad, upath, adflags | ADFLAGS_RDONLY | ADFLAGS_SETSHRMD) < 0) {
switch ( errno ) {
case EROFS:
ret = AFPERR_VLOCK;
+ goto openfork_err;
case EACCES:
goto openfork_err;
- break;
case ENOENT:
/* see if client asked for a read only data fork */
if (fork == OPENFORK_DATA) {
- if (ad_open(ofork->of_ad, upath, ADFLAGS_DF, O_RDONLY) < 0) {
+ if (ad_open(ofork->of_ad, upath, ADFLAGS_DF | ADFLAGS_RDONLY | ADFLAGS_SETSHRMD) < 0) {
goto openfork_err;
}
adflags = ADFLAGS_DF;
break;
default:
LOG(log_error, logtype_afpd, "afp_openfork(\"%s\"): %s",
- abspath(s_path->m_name), strerror(errno) );
+ fullpathname(s_path->m_name), strerror(errno) );
goto openfork_err;
break;
}
goto openfork_err;
}
- *rbuflen = buflen + 2 * sizeof( u_int16_t );
+ *rbuflen = buflen + 2 * sizeof( uint16_t );
bitmap = htons( bitmap );
- memcpy(rbuf, &bitmap, sizeof( u_int16_t ));
- rbuf += sizeof( u_int16_t );
+ memcpy(rbuf, &bitmap, sizeof( uint16_t ));
+ rbuf += sizeof( uint16_t );
/* check WriteInhibit bit if we have a ressource fork
* the test is done here, after some Mac trafic capture
{
struct ofork *ofork;
off_t size;
- u_int16_t ofrefnum, bitmap;
+ uint16_t ofrefnum, bitmap;
int err;
int is64;
int eid;
struct ofork *ofork;
off_t offset, length;
int eid;
- u_int16_t ofrefnum;
- u_int8_t flags;
+ uint16_t ofrefnum;
+ uint8_t flags;
int lockop;
*rbuflen = 0;
off_t offset, saveoff, reqcount, savereqcount;
ssize_t cc, err;
int eid, xlate = 0;
- u_int16_t ofrefnum;
+ uint16_t ofrefnum;
u_char nlmask, nlchar;
ibuf += 2;
reqcount = get_off_t(&ibuf, is64);
LOG(log_debug, logtype_afpd,
- "afp_read(\"%s\", off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)",
- cfrombstr(ofork->of_ad->ad_fullpath), offset, reqcount,
- (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
+ "afp_read(off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)", offset, reqcount,
+ (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
if (is64) {
nlmask = nlchar = 0;
goto afp_read_err;
}
+ LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd)",
+ of_name(ofork), (intmax_t)offset, (intmax_t)reqcount);
+
savereqcount = reqcount;
saveoff = offset;
if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount,ofork->of_refnum) < 0) {
goto afp_read_err;
}
-#define min(a,b) ((a)<(b)?(a):(b))
- *rbuflen = min( reqcount, *rbuflen );
+ *rbuflen = MIN(reqcount, *rbuflen);
+ LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd): reading %jd bytes from file",
+ of_name(ofork), (intmax_t)offset, (intmax_t)reqcount, (intmax_t)*rbuflen);
+
err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen, xlate);
if (err < 0)
goto afp_read_done;
+ LOG(log_debug, logtype_afpd, "afp_read(name: \"%s\", offset: %jd, reqcount: %jd): got %jd bytes from file",
+ of_name(ofork), (intmax_t)offset, (intmax_t)reqcount, (intmax_t)*rbuflen);
/* dsi can stream requests. we can only do this if we're not checking
* for an end-of-line character. oh well. */
int fd;
fd = ad_readfile_init(ofork->of_ad, eid, &offset, 0);
+
if (dsi_stream_read_file(dsi, fd, offset, dsi->datasize) < 0) {
if (errno == EINVAL || errno == ENOSYS)
goto afp_read_loop;
int afp_flush(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
struct vol *vol;
- u_int16_t vid;
+ uint16_t vid;
*rbuflen = 0;
ibuf += 2;
int afp_flushfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
struct ofork *ofork;
- u_int16_t ofrefnum;
+ uint16_t ofrefnum;
*rbuflen = 0;
ibuf += 2;
return( AFPERR_PARAM );
}
- LOG(log_debug, logtype_afpd,
- "afp_flushfork(\"%s\", fork: %s)",
- cfrombstr(ofork->of_ad->ad_fullpath),
+ LOG(log_debug, logtype_afpd, "afp_flushfork(fork: %s)",
(ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
if ( flushfork( ofork ) < 0 ) {
int afp_syncfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
struct ofork *ofork;
- u_int16_t ofrefnum;
+ uint16_t ofrefnum;
*rbuflen = 0;
ibuf += 2;
return( AFPERR_PARAM );
}
- LOG(log_debug, logtype_afpd,
- "afp_syncfork(\"%s\", fork: %s)",
- cfrombstr(ofork->of_ad->ad_fullpath),
+ LOG(log_debug, logtype_afpd, "afp_syncfork(fork: %s)",
(ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
if ( flushfork( ofork ) < 0 ) {
int afp_closefork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
{
struct ofork *ofork;
- u_int16_t ofrefnum;
+ uint16_t ofrefnum;
*rbuflen = 0;
ibuf += 2;
return( AFPERR_PARAM );
}
- LOG(log_debug, logtype_afpd,
- "afp_closefork(\"%s\", fork: %s)",
- cfrombstr(ofork->of_ad->ad_fullpath),
+ LOG(log_debug, logtype_afpd, "afp_closefork(fork: %s)",
(ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
if ( of_closefork( ofork ) < 0 ) {
static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen, int is64)
{
struct ofork *ofork;
- off_t offset, saveoff, reqcount;
+ off_t offset, saveoff, reqcount, oldsize, newsize;
int endflag, eid, xlate = 0, err = AFP_OK;
- u_int16_t ofrefnum;
+ uint16_t ofrefnum;
ssize_t cc;
/* figure out parameters */
goto afp_write_err;
}
- LOG(log_debug, logtype_afpd,
- "afp_write(\"%s\", off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)",
- cfrombstr(ofork->of_ad->ad_fullpath), offset, reqcount,
- (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
+ LOG(log_debug, logtype_afpd, "afp_write(off: %" PRIu64 ", size: %" PRIu64 ", fork: %s)",
+ offset, reqcount, (ofork->of_flags & AFPFORK_DATA) ? "d" : "r");
if ((ofork->of_flags & AFPFORK_ACCWR) == 0) {
err = AFPERR_ACCESS;
goto afp_write_err;
}
+ oldsize = ad_size(ofork->of_ad, eid);
if (endflag)
- offset += ad_size(ofork->of_ad, eid);
+ offset += oldsize;
/* handle bogus parameters */
if (reqcount < 0 || offset < 0) {
goto afp_write_err;
}
+ newsize = ((offset + reqcount) > oldsize) ? (offset + reqcount) : oldsize;
+
/* offset can overflow on 64-bit capable filesystems.
* report disk full if that's going to happen. */
if (sum_neg(is64, offset, reqcount)) {
if ( ad_meta_fileno( ofork->of_ad ) != -1 ) /* META */
ofork->of_flags |= AFPFORK_DIRTY;
+ /* we have modified any fork, remember until close_fork */
+ ofork->of_flags |= AFPFORK_MODIFIED;
+
+ /* update write count */
+ ofork->of_vol->v_appended += (newsize > oldsize) ? (newsize - oldsize) : 0;
+
*rbuflen = set_off_t (offset, rbuf, is64);
return( AFP_OK );
{
struct ofork *ofork;
int ret;
- u_int16_t ofrefnum, bitmap;
+ uint16_t ofrefnum, bitmap;
size_t buflen;
ibuf += 2;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));