X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=f0ccf0031d3058ddf6a51e32f258ddcc5fd5771c;hb=edf01c724768d494e522ec84380e8e49b37a2bd6;hp=2d3a5ff5283d64305715dcc2d9b98055a67ff3e0;hpb=7136ab002cac368c55566e93a0f64ba006f94bc2;p=netatalk.git diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 2d3a5ff5..f0ccf003 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "fork.h" #include "file.h" @@ -35,7 +36,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,7 +64,7 @@ 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.u_name = mtoupath(vol, of_name(ofork), dir->d_did, utf8_encoding(obj)))) { return( AFPERR_MISC ); } path.m_name = of_name(ofork); @@ -84,7 +85,7 @@ static int getforkparams(struct ofork *ofork, uint16_t bitmap, char *buf, size_t } } } - return getmetadata(vol, bitmap, &path, dir, buf, buflen, adp ); + return getmetadata(obj, vol, bitmap, &path, dir, buf, buflen, adp ); } static off_t get_off_t(char **ibuf, int is64) @@ -281,11 +282,11 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si /* FIXME should we check it first ? */ upath = s_path->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; } } @@ -304,10 +305,10 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si if ( fork == OPENFORK_DATA ) { eid = ADEID_DFORK; - adflags = ADFLAGS_DF | ADFLAGS_HF ; + adflags = ADFLAGS_DF | ADFLAGS_HF | ADFLAGS_NOHF; } else { eid = ADEID_RFORK; - adflags = ADFLAGS_RF | ADFLAGS_HF; + adflags = ADFLAGS_RF | ADFLAGS_HF | ADFLAGS_NOHF; if (!(access & OPENACC_WR)) adflags |= ADFLAGS_NORF; } @@ -320,7 +321,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si LOG(log_debug, logtype_afpd, "afp_openfork(\"%s\", %s, %s)", fullpathname(s_path->u_name), - (fork & OPENFORK_RSCS) ? "data" : "reso", + (fork == OPENFORK_DATA) ? "data" : "reso", !(access & OPENACC_WR) ? "O_RDONLY" : "O_RDWR"); ret = AFPERR_NOOBJ; @@ -417,8 +418,8 @@ 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) { - ad_close( ofork->of_ad, adflags ); + 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; } @@ -433,7 +434,7 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si if (ad_meta_fileno(ofork->of_ad) != -1) { /* META */ ad_getattr(ofork->of_ad, &bshort); if ((bshort & htons(ATTRBIT_NOWRITE)) && (access & OPENACC_WR)) { - ad_close( ofork->of_ad, adflags ); + ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD); of_dealloc( ofork ); ofrefnum = 0; memcpy(rbuf, &ofrefnum, sizeof(ofrefnum)); @@ -452,8 +453,9 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si ret = fork_setmode(ofork->of_ad, eid, access, ofrefnum); /* can we access the fork? */ if (ret < 0) { + ofork->of_flags |= AFPFORK_ERROR; ret = errno; - ad_close( ofork->of_ad, adflags ); + ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD); of_dealloc( ofork ); switch (ret) { case EAGAIN: /* return data anyway */ @@ -486,7 +488,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; @@ -534,7 +536,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 @@ -714,30 +716,10 @@ int afp_bytelock_ext(AFPObj *obj, char *ibuf, size_t ibuflen, char *rbuf, size_t #undef UNLOCKBIT -/* --------------------------- */ -static int crlf(struct ofork *of) -{ - struct extmap *em; - - if ( ad_meta_fileno( of->of_ad ) == -1 || !memcmp( ufinderi, ad_entry( of->of_ad, ADEID_FINDERI),8)) { /* META */ - /* 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 ssize_t read_file(struct ofork *ofork, int eid, off_t offset, u_char nlmask, u_char nlchar, char *rbuf, - size_t *rbuflen, const int xlate) + size_t *rbuflen) { ssize_t cc; int eof = 0; @@ -768,20 +750,6 @@ static ssize_t read_file(struct ofork *ofork, int eid, } } - /* - * If this file is of type TEXT, then swap \012 to \015. - */ - if (xlate) { - for ( p = rbuf, q = p + cc; p < q; p++ ) { - if ( *p == '\012' ) { - *p = '\015'; - } else if ( *p == '\015' ) { - *p = '\012'; - } - - } - } - *rbuflen = cc; if ( eof ) { return( AFPERR_EOF ); @@ -807,7 +775,7 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si struct ofork *ofork; off_t offset, saveoff, reqcount, savereqcount; ssize_t cc, err; - int eid, xlate = 0; + int eid; uint16_t ofrefnum; u_char nlmask, nlchar; @@ -849,7 +817,6 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si if ( ofork->of_flags & AFPFORK_DATA) { eid = ADEID_DFORK; - xlate = (ofork->of_vol->v_flags & AFPVOL_CRLF) ? crlf(ofork) : 0; } else if (ofork->of_flags & AFPFORK_RSRC) { eid = ADEID_RFORK; } else { /* fork wasn't opened. this should never really happen. */ @@ -877,7 +844,7 @@ static int read_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, si 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); + err = read_file(ofork, eid, offset, nlmask, nlchar, rbuf, rbuflen); 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", @@ -885,8 +852,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. */ @@ -910,30 +877,28 @@ 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 - if (!(xlate)) { - int fd; + int fd; - fd = ad_readfile_init(ofork->of_ad, eid, &offset, 0); + 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 (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; } - - dsi_readdone(dsi); - goto afp_read_done; } + dsi_readdone(dsi); + goto afp_read_done; + afp_read_loop: #endif /* 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); if (cc < 0) goto afp_read_exit; @@ -1120,24 +1085,11 @@ int afp_closefork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U static ssize_t write_file(struct ofork *ofork, int eid, off_t offset, char *rbuf, - size_t rbuflen, const int xlate) + size_t rbuflen) { char *p, *q; ssize_t cc; - /* - * If this file is of type TEXT, swap \015 to \012. - */ - if (xlate) { - for ( p = rbuf, q = p + rbuflen; p < q; p++ ) { - if ( *p == '\015' ) { - *p = '\012'; - } else if ( *p == '\012' ) { - *p = '\015'; - } - } - } - LOG(log_debug, logtype_afpd, "write_file(off: %ju, size: %zu)", (uintmax_t)offset, rbuflen); @@ -1167,7 +1119,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s { struct ofork *ofork; off_t offset, saveoff, reqcount, oldsize, newsize; - int endflag, eid, xlate = 0, err = AFP_OK; + int endflag, eid, err = AFP_OK; uint16_t ofrefnum; ssize_t cc; @@ -1201,7 +1153,6 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s if ( ofork->of_flags & AFPFORK_DATA) { eid = ADEID_DFORK; - xlate = (ofork->of_vol->v_flags & AFPVOL_CRLF) ? crlf(ofork) : 0; } else if (ofork->of_flags & AFPFORK_RSRC) { eid = ADEID_RFORK; } else { @@ -1241,63 +1192,56 @@ 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; + } + + offset += cc; - if (!cc || (cc = write_file(ofork, eid, offset, rbuf, cc, xlate)) < 0) { +#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); + ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, + reqcount, ofork->of_refnum); return cc; } offset += cc; - -#if 0 /*def HAVE_SENDFILE_WRITE*/ - if (!(xlate || 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; - } + 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, xlate)) < 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); @@ -1314,10 +1258,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; } @@ -1339,7 +1282,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; @@ -1365,7 +1308,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 ); }