X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=2424a5e4e22823aaaa30bf3f1062de18901d82b8;hb=835046ffee549c23b8500f06b7eb63b62ad13f94;hp=9bef65b036f5dd0b5a453f40cffd4631ddc74819;hpb=4675177f7d5271edf4a2d982ebf6d5bd185d401c;p=netatalk.git diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 9bef65b0..2424a5e4 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include "fork.h" #include "file.h" @@ -35,7 +37,7 @@ struct ofork *writtenfork; #endif -static int getforkparams(struct ofork *ofork, uint16_t bitmap, char *buf, size_t *buflen) +static int getforkparams(const AFPObj *obj, struct ofork *ofork, uint16_t bitmap, char *buf, size_t *buflen) { struct path path; struct stat *st; @@ -63,10 +65,10 @@ static int getforkparams(struct ofork *ofork, uint16_t bitmap, char *buf, size_t vol = ofork->of_vol; dir = dirlookup(vol, ofork->of_did); - if (NULL == (path.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding()))) { + if (NULL == (path.m_name = utompath(vol, of_name(ofork), dir->d_did, utf8_encoding(obj)))) { return( AFPERR_MISC ); } - path.m_name = of_name(ofork); + path.u_name = of_name(ofork); path.id = 0; st = &path.st; if ( bitmap & ( (1<u_name; if (!vol_unix_priv(vol)) { - if (check_access(upath, access ) < 0) { + if (check_access(obj, vol, upath, access ) < 0) { return AFPERR_ACCESS; } } else { - if (file_access(s_path, access ) < 0) { + if (file_access(obj, vol, s_path, access ) < 0) { return AFPERR_ACCESS; } } @@ -417,7 +438,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si } } - if ((ret = getforkparams(ofork, bitmap, rbuf + 2 * sizeof(int16_t), &buflen)) != AFP_OK) { + if ((ret = getforkparams(obj, ofork, bitmap, rbuf + 2 * sizeof(int16_t), &buflen)) != AFP_OK) { ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD); goto openfork_err; } @@ -487,7 +508,7 @@ openfork_err: return ret; } -int afp_setforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen, char *rbuf _U_, size_t *rbuflen) +int afp_setforkparams(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf _U_, size_t *rbuflen) { struct ofork *ofork; off_t size; @@ -535,7 +556,7 @@ int afp_setforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen, char *rbuf _U is64 = 0; if ((bitmap & ( (1<= 30) { + if (obj->afp_version >= 30) { is64 = 4; } else @@ -572,6 +593,7 @@ int afp_setforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen, char *rbuf _U ad_tmplock(ofork->of_ad, eid, ADLOCK_WR, size, st_size -size, ofork->of_refnum) < 0) { goto afp_setfork_err; } + err = ad_rtruncate(ofork->of_ad, size); if (st_size > size) ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, size, st_size -size, ofork->of_refnum); @@ -851,8 +873,8 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si /* 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; + if ((*rbuflen < reqcount) && !nlmask) { + DSI *dsi = obj->dsi; off_t size; /* reqcount isn't always truthful. we need to deal with that. */ @@ -876,22 +898,22 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si /* 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 WITH_SENDFILE - 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 { - LOG(log_error, logtype_afpd, "afp_read(%s): ad_readfile: %s", of_name(ofork), strerror(errno)); - goto afp_read_exit; + if (!(obj->options.flags & OPTION_NOSENDFILE)) { + int fd = ad_readfile_init(ofork->of_ad, eid, &offset, 0); + if (dsi_stream_read_file(dsi, fd, offset, dsi->datasize) < 0) { + switch (errno) { + case EINVAL: + case ENOSYS: + goto afp_read_loop; + default: + LOG(log_error, logtype_afpd, "afp_read(%s): ad_readfile: %s", of_name(ofork), strerror(errno)); + goto afp_read_exit; + } } - } - - dsi_readdone(dsi); - goto afp_read_done; + dsi_readdone(dsi); + goto afp_read_done; + } afp_read_loop: #endif @@ -1073,6 +1095,15 @@ int afp_closefork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U LOG(log_debug, logtype_afpd, "afp_closefork(fork: %s)", (ofork->of_flags & AFPFORK_DATA) ? "d" : "r"); +#ifdef HAVE_FSHARE_T + fshare_t shmd; + shmd.f_id = ofork->of_refnum; + if (AD_DATA_OPEN(ofork->of_ad)) + fcntl(ad_data_fileno(ofork->of_ad), F_UNSHARE, &shmd); + if (AD_RSRC_OPEN(ofork->of_ad)) + fcntl(ad_reso_fileno(ofork->of_ad), F_UNSHARE, &shmd); +#endif + if ( of_closefork( ofork ) < 0 ) { LOG(log_error, logtype_afpd, "afp_closefork(%s): of_closefork: %s", of_name(ofork), strerror(errno) ); return( AFPERR_PARAM ); @@ -1191,63 +1222,54 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s goto afp_write_err; } - /* this is yucky, but dsi can stream i/o and asp can't */ - switch (obj->proto) { - case AFPPROTO_DSI: - { - DSI *dsi = obj->handle; - /* find out what we have already and write it out. */ - cc = dsi_writeinit(dsi, rbuf, *rbuflen); + DSI *dsi = obj->dsi; + /* 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)) < 0) { - dsi_writeflush(dsi); - *rbuflen = 0; - ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); - return cc; - } + if (!cc || (cc = write_file(ofork, eid, offset, rbuf, cc)) < 0) { + dsi_writeflush(dsi); + *rbuflen = 0; + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); + return cc; + } - offset += cc; + offset += cc; #if 0 /*def HAVE_SENDFILE_WRITE*/ - if (!(obj->options.flags & OPTION_DEBUG)) { - if ((cc = ad_writefile(ofork->of_ad, eid, dsi->socket, - offset, dsi->datasize)) < 0) { - switch (errno) { - case EDQUOT : - case EFBIG : - case ENOSPC : - cc = AFPERR_DFULL; - break; - default : - LOG(log_error, logtype_afpd, "afp_write: ad_writefile: %s", strerror(errno) ); - goto afp_write_loop; - } - dsi_writeflush(dsi); - *rbuflen = 0; - ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, - reqcount, ofork->of_refnum); - return cc; - } - - offset += cc; - goto afp_write_done; + if ((cc = ad_writefile(ofork->of_ad, eid, dsi->socket, + offset, dsi->datasize)) < 0) { + switch (errno) { + case EDQUOT: + case EFBIG: + case ENOSPC: + cc = AFPERR_DFULL; + break; + default: + LOG(log_error, logtype_afpd, "afp_write: ad_writefile: %s", strerror(errno) ); + goto afp_write_loop; } + dsi_writeflush(dsi); + *rbuflen = 0; + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, + reqcount, ofork->of_refnum); + return cc; + } + + offset += cc; + goto afp_write_done; #endif /* 0, was HAVE_SENDFILE_WRITE */ - /* loop until everything gets written. currently - * dsi_write handles the end case by itself. */ - while ((cc = dsi_write(dsi, rbuf, *rbuflen))) { - if ((cc = write_file(ofork, eid, offset, rbuf, cc)) < 0) { - dsi_writeflush(dsi); - *rbuflen = 0; - ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, - reqcount, ofork->of_refnum); - return cc; - } - offset += cc; + /* loop until everything gets written. currently + * dsi_write handles the end case by itself. */ + while ((cc = dsi_write(dsi, rbuf, *rbuflen))) { + if ((cc = write_file(ofork, eid, offset, rbuf, cc)) < 0) { + dsi_writeflush(dsi); + *rbuflen = 0; + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, + reqcount, ofork->of_refnum); + return cc; } - } - break; + offset += cc; } ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, reqcount, ofork->of_refnum); @@ -1264,10 +1286,9 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s return( AFP_OK ); afp_write_err: - if (obj->proto == AFPPROTO_DSI) { - dsi_writeinit(obj->handle, rbuf, *rbuflen); - dsi_writeflush(obj->handle); - } + dsi_writeinit(obj->dsi, rbuf, *rbuflen); + dsi_writeflush(obj->dsi); + if (err != AFP_OK) { *rbuflen = 0; } @@ -1289,7 +1310,7 @@ int afp_write_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t *r } /* ---------------------------- */ -int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) +int afp_getforkparams(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { struct ofork *ofork; int ret; @@ -1315,7 +1336,7 @@ int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbu } } - if (AFP_OK != (ret = getforkparams(ofork, bitmap, rbuf + sizeof( u_short ), &buflen ))) { + if (AFP_OK != (ret = getforkparams(obj, ofork, bitmap, rbuf + sizeof( u_short ), &buflen ))) { return( ret ); }