X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffork.c;h=8e0ba7325bfd450c3b7f9003198c013494fec151;hb=df7560dfdb12b06090dc4b2c6e88d0858930b591;hp=40ae7cdad88b56e6aa63ad821bf419f4207ab79f;hpb=5737d08e3c85485df6ad56d7be7423d6309e9b94;p=netatalk.git diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index 40ae7cda..8e0ba732 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -266,9 +266,6 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si return AFPERR_BADTYPE; } - 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 ) { case 0: @@ -307,10 +304,12 @@ 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; } path = s_path->m_name; @@ -319,6 +318,11 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si return( AFPERR_NFILE ); } + LOG(log_debug, logtype_afpd, "afp_openfork(\"%s\", %s, %s)", + fullpathname(s_path->u_name), + (fork == OPENFORK_DATA) ? "data" : "reso", + !(access & OPENACC_WR) ? "O_RDONLY" : "O_RDWR"); + ret = AFPERR_NOOBJ; if (access & OPENACC_WR) { /* try opening in read-write mode */ @@ -366,7 +370,6 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si } else { /* try opening in read-only mode */ ret = AFPERR_NOOBJ; - /* 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: @@ -415,7 +418,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) { - ad_close( ofork->of_ad, adflags ); + ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD); goto openfork_err; } @@ -430,7 +433,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)); @@ -444,14 +447,14 @@ int afp_openfork(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si /* don't try to lock non-existent rforks. */ if ((eid == ADEID_DFORK) - || (ad_meta_fileno(ofork->of_ad) != -1) - || (vol->v_adouble & AD_VERSION_EA)) { /* META */ - + || (ad_reso_fileno(ofork->of_ad) != -1) + || (ofork->of_ad->ad_vers == AD_VERSION_EA)) { 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 */ @@ -561,7 +564,7 @@ int afp_setforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen, char *rbuf _U if (err < 0) goto afp_setfork_err; } else if (bitmap == (1<of_ad ); + ad_refresh(NULL, ofork->of_ad ); st_size = ad_size(ofork->of_ad, eid); err = -2; @@ -640,7 +643,7 @@ static int byte_lock(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf ibuf += sizeof(ofrefnum); if (NULL == ( ofork = of_find( ofrefnum )) ) { - LOG(log_error, logtype_afpd, "afp_bytelock: of_find(%d) could not locate fork", ofrefnum ); + LOG(log_error, logtype_afpd, "byte_lock: of_find(%d) could not locate fork", ofrefnum ); return( AFPERR_PARAM ); } @@ -654,7 +657,6 @@ static int byte_lock(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf offset = get_off_t(&ibuf, is64); length = get_off_t(&ibuf, is64); - /* FIXME AD_FILELOCK test is surely wrong */ if (length == -1) length = BYTELOCK_MAX; else if (!length || is_neg(is64, length)) { @@ -713,30 +715,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; @@ -767,20 +749,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 ); @@ -806,7 +774,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; @@ -848,7 +816,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. */ @@ -876,7 +843,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,7 +852,7 @@ 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; + DSI *dsi = obj->dsi; off_t size; /* reqcount isn't always truthful. we need to deal with that. */ @@ -909,30 +876,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; @@ -1067,7 +1032,7 @@ int flushfork(struct ofork *ofork) (ofork->of_flags & AFPFORK_RSRC)) { /* read in the rfork length */ - ad_refresh(ofork->of_ad); + ad_refresh(NULL, ofork->of_ad); /* set the date if we're dirty */ if ((ofork->of_flags & AFPFORK_DIRTY) && !gettimeofday(&tv, NULL)) { @@ -1119,23 +1084,13 @@ 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); if (( cc = ad_write(ofork->of_ad, eid, offset, 0, rbuf, rbuflen)) < 0 ) { @@ -1163,7 +1118,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; @@ -1197,7 +1152,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,20 +1195,21 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s switch (obj->proto) { case AFPPROTO_DSI: { - DSI *dsi = obj->handle; - + 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, xlate)) < 0) { + + 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 0 /*def HAVE_SENDFILE_WRITE*/ - if (!(xlate || obj->options.flags & OPTION_DEBUG)) { + if (!(obj->options.flags & OPTION_DEBUG)) { if ((cc = ad_writefile(ofork->of_ad, eid, dsi->socket, offset, dsi->datasize)) < 0) { switch (errno) { @@ -1282,7 +1237,7 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s /* 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) { + if ((cc = write_file(ofork, eid, offset, rbuf, cc)) < 0) { dsi_writeflush(dsi); *rbuflen = 0; ad_tmplock(ofork->of_ad, eid, ADLOCK_CLR, saveoff, @@ -1310,8 +1265,8 @@ static int write_fork(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, s 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; @@ -1354,7 +1309,7 @@ int afp_getforkparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbu } if (AD_META_OPEN(ofork->of_ad)) { - if ( ad_refresh( ofork->of_ad ) < 0 ) { + if ( ad_refresh(NULL, ofork->of_ad ) < 0 ) { LOG(log_error, logtype_afpd, "getforkparams(%s): ad_refresh: %s", of_name(ofork), strerror(errno) ); return( AFPERR_PARAM ); }