/*
- * $Id: fork.c,v 1.51.2.2.2.1 2003-09-09 16:42:20 didg Exp $
+ * $Id: fork.c,v 1.51.2.2.2.10.2.6 2008-11-25 15:16:33 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif /* HAVE_UNISTD_H */
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif /* HAVE_FCNTL_H */
+
#include <dirent.h>
#include <string.h>
#include <errno.h>
+
+#include <atalk/adouble.h>
#include <atalk/logger.h>
#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/time.h>
#include <sys/socket.h>
-#include <netatalk/endian.h>
#include <netatalk/at.h>
#include <atalk/dsi.h>
#include <atalk/atp.h>
#include <atalk/asp.h>
#include <atalk/afp.h>
-#include <atalk/adouble.h>
+
#include <atalk/util.h>
#include <atalk/cnid.h>
#include "desktop.h"
#include "volume.h"
+#ifdef DEBUG1
+#define Debug(a) ((a)->options.flags & OPTION_DEBUG)
+#else
+#define Debug(a) (0)
+#endif
+
struct ofork *writtenfork;
extern int getmetadata(struct vol *vol,
u_int16_t bitmap,
vol = ofork->of_vol;
dir = ofork->of_dir;
- if (NULL == (path.u_name = mtoupath(vol, ofork->of_name, utf8_encoding()))) {
+ if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding()))) {
return( AFPERR_MISC );
}
- path.m_name = ofork->of_name;
+ path.m_name = of_name(ofork);
st = &path.st;
if ( bitmap & ( (1<<FILPBIT_DFLEN) | (1<<FILPBIT_EXTDFLEN) |
(1<<FILPBIT_FNUM) | (1 << FILPBIT_CDATE) |
return 0;
}
-static __inline__ int sum_neg(int is64, off_t offset, off_t reqcount)
+static int sum_neg(int is64, off_t offset, off_t reqcount)
{
if (is_neg(is64, offset +reqcount) )
return 1;
/* -------------------------
*/
-static int getforkmode(struct adouble *adp, int eid, int what)
+int getforkmode(struct adouble *adp, int eid, int what)
{
return ad_testlock(adp, eid, what);
}
+/* -------------------------
+*/
static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum)
{
int ret;
return ret;
}
}
-
if ( access == (OPENACC_WR | OPENACC_RD | OPENACC_DWR | OPENACC_DRD)) {
return ad_excl_lock(adp, eid);
}
-
return 0;
}
/* ----------------------- */
int afp_openfork(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
+AFPObj *obj _U_;
char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int ibuflen _U_, *rbuflen;
{
struct vol *vol;
struct dir *dir;
case EACCES:
return (access & OPENACC_WR) ? AFPERR_LOCK : AFPERR_ACCESS;
default:
- LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_open: %s", s_path->m_name, strerror(errno) );
return AFPERR_PARAM;
}
/* FIXME should we check it first ? */
goto openfork_err;
break;
default:
- LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_open: %s", s_path->m_name, strerror(errno) );
ret = AFPERR_PARAM;
goto openfork_err;
break;
goto openfork_err;
break;
default:
- LOG(log_error, logtype_afpd, "afp_openfork: ad_open: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_open: %s", s_path->m_name, strerror(errno) );
goto openfork_err;
break;
}
}
if ((adflags & ADFLAGS_HF) && (ad_get_HF_flags( ofork->of_ad) & O_CREAT)) {
- ad_setentrylen( ofork->of_ad, ADEID_NAME, strlen( path ));
- memcpy(ad_entry( ofork->of_ad, ADEID_NAME ), path,
- ad_getentrylen( ofork->of_ad, ADEID_NAME ));
- ad_flush( ofork->of_ad, adflags );
+ if (ad_setname(ofork->of_ad, path)) {
+ ad_flush( ofork->of_ad, adflags );
+ }
}
if (( ret = getforkparams(ofork, bitmap, rbuf + 2 * sizeof( u_int16_t ),
break;
default:
*rbuflen = 0;
- LOG(log_error, logtype_afpd, "afp_openfork: ad_lock: %s", strerror(ret) );
+ LOG(log_error, logtype_afpd, "afp_openfork(%s): ad_lock: %s", s_path->m_name, strerror(ret) );
return( AFPERR_PARAM );
}
}
}
int afp_setforkparams(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj _U_;
+char *ibuf, *rbuf _U_;
+int ibuflen, *rbuflen;
{
struct ofork *ofork;
off_t size;
*rbuflen = 0;
if (NULL == ( ofork = of_find( ofrefnum )) ) {
- LOG(log_error, logtype_afpd, "afp_setforkparams: of_find could not locate open fork refnum: %u", ofrefnum );
+ LOG(log_error, logtype_afpd, "afp_setforkparams: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
goto afp_setfork_err;
if (ad_flush( ofork->of_ad, ADFLAGS_HF ) < 0) {
- LOG(log_error, logtype_afpd, "afp_setforkparams: ad_flush: %s",strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_setforkparams(%s): ad_flush: %s", of_name(ofork), strerror(errno) );
return AFPERR_PARAM;
}
} else
#ifdef AFS
if ( flushfork( ofork ) < 0 ) {
- LOG(log_error, logtype_afpd, "afp_setforkparams: flushfork: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_setforkparams(%s): flushfork: %s", of_name(ofork), strerror(errno) );
}
#endif /* AFS */
/* ---------------------- */
static int byte_lock(obj, ibuf, ibuflen, rbuf, rbuflen, is64 )
-AFPObj *obj;
+AFPObj *obj _U_;
char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int ibuflen _U_, *rbuflen;
int is64;
{
struct ofork *ofork;
ibuf += sizeof(ofrefnum);
if (NULL == ( ofork = of_find( ofrefnum )) ) {
- LOG(log_error, logtype_afpd, "afp_bytelock: of_find");
+ LOG(log_error, logtype_afpd, "afp_bytelock: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
#undef UNLOCKBIT
/* --------------------------- */
-static __inline__ int crlf( of )
+static int crlf( of )
struct ofork *of;
{
struct extmap *em;
- if ( ad_hfileno( of->of_ad ) == -1 ||
- memcmp( ufinderi, ad_entry( of->of_ad, ADEID_FINDERI ),
- 8) == 0 ) {
- if (NULL == ( em = getextmap( of->of_name )) ||
- memcmp( "TEXT", em->em_type, sizeof( em->em_type )) == 0 ) {
- return( 1 );
- } else {
- return( 0 );
- }
- } else {
- if ( memcmp( ufinderi,
- ad_entry( of->of_ad, ADEID_FINDERI ), 4 ) == 0 ) {
- return( 1 );
- } else {
- return( 0 );
- }
+ if ( ad_hfileno( of->of_ad ) == -1 || !memcmp( ufinderi, ad_entry( of->of_ad, ADEID_FINDERI),8)) {
+ /* no resource fork or no finderinfo, use our files extension mapping */
+ if (!( em = getextmap( of_name(of) )) || memcmp( "TEXT", em->em_type, sizeof( em->em_type ))) {
+ return 0;
+ }
+ /* file type is TEXT */
+ return 1;
+
+ } else if ( !memcmp( "TEXT", ad_entry( of->of_ad, ADEID_FINDERI ), 4 )) {
+ return 1;
}
+ return 0;
}
-static __inline__ ssize_t read_file(struct ofork *ofork, int eid,
+static ssize_t read_file(struct ofork *ofork, int eid,
off_t offset, u_char nlmask,
u_char nlchar, char *rbuf,
int *rbuflen, const int xlate)
cc = ad_read(ofork->of_ad, eid, offset, rbuf, *rbuflen);
if ( cc < 0 ) {
- LOG(log_error, logtype_afpd, "afp_read: ad_read: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_read(%s): ad_read: %s", of_name(ofork), strerror(errno) );
*rbuflen = 0;
return( AFPERR_PARAM );
}
* with dsi, should we check that reqcount < server quantum?
*/
static int read_fork(obj, ibuf, ibuflen, rbuf, rbuflen, is64)
-AFPObj *obj;
+AFPObj *obj;
char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
-int is64;
+int ibuflen _U_, *rbuflen;
+int is64;
{
struct ofork *ofork;
- off_t size;
off_t offset, saveoff, reqcount, savereqcount;
int cc, err, eid, xlate = 0;
u_int16_t ofrefnum;
ibuf += sizeof( u_short );
if (NULL == ( ofork = of_find( ofrefnum )) ) {
- LOG(log_error, logtype_afpd, "afp_read: of_find");
+ LOG(log_error, logtype_afpd, "afp_read: of_find(%d) could not locate fork", ofrefnum );
err = AFPERR_PARAM;
goto afp_read_err;
}
goto afp_read_err;
}
- /* reqcount isn't always truthful. we need to deal with that. */
- size = ad_size(ofork->of_ad, eid);
-
- if (offset >= size) {
- err = AFPERR_EOF;
- goto afp_read_err;
- }
-
savereqcount = reqcount;
saveoff = offset;
if (ad_tmplock(ofork->of_ad, eid, ADLOCK_RD, saveoff, savereqcount,ofork->of_refnum) < 0) {
#define min(a,b) ((a)<(b)?(a):(b))
*rbuflen = min( reqcount, *rbuflen );
- err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen,
- xlate);
+ err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen, xlate);
if (err < 0)
goto afp_read_done;
/* dsi can stream requests. we can only do this if we're not checking
* for an end-of-line character. oh well. */
if ((obj->proto == AFPPROTO_DSI) && (*rbuflen < reqcount) && !nlmask) {
- DSI *dsi = obj->handle;
+ DSI *dsi = obj->handle;
+ off_t size;
+ int non_blocking = 0;
+#ifdef DEBUG1
if (obj->options.flags & OPTION_DEBUG) {
- printf( "(read) reply: %d/%d, %d\n", *rbuflen,
- (int) reqcount, dsi->clientID);
+ printf( "(read) reply: %d/%d, %d\n", *rbuflen,(int) reqcount, dsi->clientID);
bprint(rbuf, *rbuflen);
}
+#endif
+ /* reqcount isn't always truthful. we need to deal with that. */
+ size = ad_size(ofork->of_ad, eid);
+
/* subtract off the offset */
size -= offset;
if (reqcount > size) {
/* due to the nature of afp packets, we have to exit if we get
an error. we can't do this with translation on. */
-#ifdef HAVE_SENDFILE_READ
- if (!(xlate || (obj->options.flags & OPTION_DEBUG))) {
- if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset,
- dsi->datasize) < 0) {
- if (errno == EINVAL)
+#if 0 /* ifdef WITH_SENDFILE */
+ /* FIXME with OS X deadlock partial workaround we can't use sendfile */
+ if (!(xlate || Debug(obj) )) {
+ if (ad_readfile(ofork->of_ad, eid, dsi->socket, offset, dsi->datasize) < 0) {
+ if (errno == EINVAL || errno == ENOSYS)
goto afp_read_loop;
else {
- LOG(log_error, logtype_afpd, "afp_read: ad_readfile: %s", strerror(errno));
+ LOG(log_error, logtype_afpd, "afp_read(%s): ad_readfile: %s", of_name(ofork), strerror(errno));
goto afp_read_exit;
}
}
}
afp_read_loop:
-#endif /* HAVE_SENDFILE_READ */
+#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);
+ cc = read_file(ofork, eid, offset, nlmask, nlchar, rbuf,rbuflen, xlate);
if (cc < 0)
goto afp_read_exit;
offset += *rbuflen;
+#ifdef DEBUG1
if (obj->options.flags & OPTION_DEBUG) {
printf( "(read) reply: %d, %d\n", *rbuflen, dsi->clientID);
bprint(rbuf, *rbuflen);
}
-
+#endif
/* dsi_read() also returns buffer size of next allocation */
cc = dsi_read(dsi, rbuf, *rbuflen); /* send it off */
if (cc < 0)
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;
afp_read_exit:
- LOG(log_error, logtype_afpd, "afp_read: %s", strerror(errno));
+ LOG(log_error, logtype_afpd, "afp_read(%s): %s", of_name(ofork), strerror(errno));
dsi_readdone(dsi);
ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, savereqcount,ofork->of_refnum);
- obj->exit(1);
+ obj->exit(EXITERR_CLNT);
}
afp_read_done:
/* ---------------------- */
int afp_flush(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj _U_;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
{
struct vol *vol;
u_int16_t vid;
}
int afp_flushfork(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj _U_;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
{
struct ofork *ofork;
u_int16_t ofrefnum;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
if (NULL == ( ofork = of_find( ofrefnum )) ) {
- LOG(log_error, logtype_afpd, "afp_flushfork: of_find");
+ LOG(log_error, logtype_afpd, "afp_flushfork: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
if ( flushfork( ofork ) < 0 ) {
- LOG(log_error, logtype_afpd, "afp_flushfork: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_flushfork(%s): %s", of_name(ofork), strerror(errno) );
}
return( AFP_OK );
if ( ad_dfileno( ofork->of_ad ) != -1 &&
fsync( ad_dfileno( ofork->of_ad )) < 0 ) {
- LOG(log_error, logtype_afpd, "flushfork: dfile(%d) %s",
- ad_dfileno(ofork->of_ad), strerror(errno) );
+ LOG(log_error, logtype_afpd, "flushfork(%s): dfile(%d) %s",
+ of_name(ofork), ad_dfileno(ofork->of_ad), strerror(errno) );
err = -1;
}
err = -1;
if (err < 0)
- LOG(log_error, logtype_afpd, "flushfork: hfile(%d) %s",
- ad_hfileno(ofork->of_ad), strerror(errno) );
+ LOG(log_error, logtype_afpd, "flushfork(%s): hfile(%d) %s",
+ of_name(ofork), ad_hfileno(ofork->of_ad), strerror(errno) );
}
return( err );
}
int afp_closefork(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj _U_;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
{
struct ofork *ofork;
struct timeval tv;
int adflags, doflush = 0;
u_int16_t ofrefnum;
+ int ret;
+
*rbuflen = 0;
ibuf += 2;
memcpy(&ofrefnum, ibuf, sizeof( ofrefnum ));
if (NULL == ( ofork = of_find( ofrefnum )) ) {
- LOG(log_error, logtype_afpd, "afp_closefork: of_find");
+ LOG(log_error, logtype_afpd, "afp_closefork: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
}
}
}
-
+ ret = AFP_OK;
if ( ad_close( ofork->of_ad, adflags ) < 0 ) {
- LOG(log_error, logtype_afpd, "afp_closefork: ad_close: %s", strerror(errno) );
- return( AFPERR_PARAM );
+ LOG(log_error, logtype_afpd, "afp_closefork(%s): ad_close: %s", of_name(ofork), strerror(errno) );
+ ret = AFPERR_PARAM;
}
of_dealloc( ofork );
- return( AFP_OK );
+ return ret;
}
-static __inline__ ssize_t write_file(struct ofork *ofork, int eid,
+static ssize_t write_file(struct ofork *ofork, int eid,
off_t offset, char *rbuf,
size_t rbuflen, const int xlate)
{
case ENOSPC :
return( AFPERR_DFULL );
default :
- LOG(log_error, logtype_afpd, "afp_write: ad_write: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "afp_write(%s): ad_write: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );
}
}
static int write_fork(obj, ibuf, ibuflen, rbuf, rbuflen, is64)
AFPObj *obj;
char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int ibuflen _U_, *rbuflen;
int is64;
{
struct ofork *ofork;
reqcount = get_off_t(&ibuf, is64);
if (NULL == ( ofork = of_find( ofrefnum )) ) {
- LOG(log_error, logtype_afpd, "afp_write: of_find");
+ LOG(log_error, logtype_afpd, "afp_write: of_find(%d) could not locate fork", ofrefnum );
err = AFPERR_PARAM;
goto afp_write_err;
}
return( AFPERR_PARAM );
}
+#ifdef DEBUG1
if (obj->options.flags & OPTION_DEBUG) {
printf("(write) len: %d\n", *rbuflen);
bprint(rbuf, *rbuflen);
}
-
+#endif
if ((cc = write_file(ofork, eid, offset, rbuf, *rbuflen,
xlate)) < 0) {
*rbuflen = 0;
/* find out what we have already and write it out. */
cc = dsi_writeinit(dsi, rbuf, *rbuflen);
- if (!cc ||
- (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
+ if (!cc || (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
dsi_writeflush(dsi);
*rbuflen = 0;
ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum);
/* loop until everything gets written. currently
* dsi_write handles the end case by itself. */
while ((cc = dsi_write(dsi, rbuf, *rbuflen))) {
+#ifdef DEBUG1
if ( obj->options.flags & OPTION_DEBUG ) {
printf("(write) command cont'd: %d\n", cc);
bprint(rbuf, cc);
}
-
+#endif
if ((cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) {
dsi_writeflush(dsi);
*rbuflen = 0;
/* ---------------------------- */
int afp_getforkparams(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
+AFPObj *obj _U_;
char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int ibuflen _U_, *rbuflen;
{
struct ofork *ofork;
int buflen, ret;
*rbuflen = 0;
if (NULL == ( ofork = of_find( ofrefnum )) ) {
- LOG(log_error, logtype_afpd, "afp_getforkparams: of_find");
+ LOG(log_error, logtype_afpd, "afp_getforkparams: of_find(%d) could not locate fork", ofrefnum );
return( AFPERR_PARAM );
}
attrbits = ((ofork->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
if ( ad_hfileno( ofork->of_ad ) != -1 ) {
if ( ad_refresh( ofork->of_ad ) < 0 ) {
- LOG(log_error, logtype_afpd, "getforkparams: ad_refresh: %s", strerror(errno) );
+ LOG(log_error, logtype_afpd, "getforkparams(%s): ad_refresh: %s", of_name(ofork), strerror(errno) );
return( AFPERR_PARAM );
}
}