/*
- * $Id: fork.c,v 1.67 2009-10-22 12:35:38 franklahm Exp $
+ * $Id: fork.c,v 1.73 2010-03-30 12:55:26 franklahm Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#include <stdio.h>
-#include <dirent.h>
#include <string.h>
#include <errno.h>
}
vol = ofork->of_vol;
- dir = ofork->of_dir;
+ dir = dirlookup(vol, ofork->of_did);
if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding()))) {
return( AFPERR_MISC );
}
path.m_name = of_name(ofork);
+ path.id = 0;
st = &path.st;
if ( bitmap & ( (1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) |
(1<<FILPBIT_FNUM) | (1 << FILPBIT_CDATE) |
(1 << FILPBIT_MDATE) | (1 << FILPBIT_BDATE))) {
- if ( ad_data_fileno( ofork->of_ad ) == -1 ) {
+ if ( ad_data_fileno( ofork->of_ad ) <= 0 ) {
+ /* 0 is for symlink */
if (movecwd(vol, dir) < 0)
return( AFPERR_NOOBJ );
- if ( stat( path.u_name, st ) < 0 )
+ if ( lstat( path.u_name, st ) < 0 )
return( AFPERR_NOOBJ );
} else {
if ( fstat( ad_data_fileno( ofork->of_ad ), st ) < 0 ) {
goto openfork_err;
break;
default:
- LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_open: %s", s_path->m_name, strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_openfork('%s/%s'): ad_open: errno: %i (%s)",
+ getcwdpath, s_path->m_name, errno, strerror(errno) );
goto openfork_err;
break;
}
if ((obj->proto == AFPPROTO_DSI) && (*rbuflen < reqcount) && !nlmask) {
DSI *dsi = obj->handle;
off_t size;
- int non_blocking = 0;
/* reqcount isn't always truthful. we need to deal with that. */
size = ad_size(ofork->of_ad, eid);
*rbuflen = cc;
/* due to the nature of afp packets, we have to exit if we get
an error. we can't do this with translation on. */
-#if 0 /* ifdef WITH_SENDFILE */
- /* FIXME with OS X deadlock partial workaround we can't use sendfile */
+#ifdef WITH_SENDFILE
if (!(xlate || Debug(obj) )) {
- if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset, dsi->datasize) < 0) {
+ 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;
else {
afp_read_loop:
#endif
- /* fill up our buffer. */
- if (*rbuflen) {
- /* set to non blocking mode */
- non_blocking = 1;
- dsi_block(dsi, 1);
- }
/* fill up our buffer. */
while (*rbuflen > 0) {
cc = read_file(ofork, eid, offset, nlmask, nlchar, rbuf,rbuflen, xlate);
goto afp_read_exit;
*rbuflen = cc;
}
- if (non_blocking) {
- /* set back to blocking mode */
- dsi_block(dsi, 0);
- }
dsi_readdone(dsi);
goto afp_read_done;
case EFBIG :
case ENOSPC :
return( AFPERR_DFULL );
+ case EACCES:
+ return AFPERR_ACCESS;
default :
LOG(log_error, logtype_afpd, "afp_write(%s): ad_write: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );
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;
+
*rbuflen = set_off_t (offset, rbuf, is64);
return( AFP_OK );