X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fdesktop.c;h=9f105e13e13c612757386f70c342626e28fe5e77;hb=6ee7ecd6892a1750128dcced1410e76b5e166874;hp=db003f58b953c999b41a4b150c62998000f2129a;hpb=860d731692831b16749021c7ccfdd5f1f5437d97;p=netatalk.git diff --git a/etc/afpd/desktop.c b/etc/afpd/desktop.c index db003f58..9f105e13 100644 --- a/etc/afpd/desktop.c +++ b/etc/afpd/desktop.c @@ -1,20 +1,27 @@ /* - * $Id: desktop.c,v 1.10 2002-01-03 17:49:38 sibaz Exp $ + * $Id: desktop.c,v 1.50.2.1 2010-02-01 10:56:08 franklahm Exp $ * * See COPYRIGHT. + * + * bug: + * afp_XXXcomment are (the only) functions able to open + * a ressource fork when there's no data fork, eg after + * it was removed with samba. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ -#include +#include +#include +#include + #include -#include -#include + +#include #include #include -#include #include #include #include @@ -22,29 +29,17 @@ #include #include #include -#include #include -#include -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ -#include -#include -#include -#ifdef HAVE_FCNTL_H -#include -#endif /* HAVE_FCNTL_H */ - +#include #include "volume.h" #include "directory.h" #include "fork.h" #include "globals.h" #include "desktop.h" +#include "mangle.h" -int afp_opendt(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; + +int afp_opendt(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { struct vol *vol; u_int16_t vid; @@ -52,7 +47,7 @@ int ibuflen, *rbuflen; ibuf += 2; memcpy( &vid, ibuf, sizeof(vid)); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { *rbuflen = 0; return( AFPERR_PARAM ); } @@ -62,20 +57,20 @@ int ibuflen, *rbuflen; return( AFP_OK ); } -int afp_closedt(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +int afp_closedt(AFPObj *obj _U_, char *ibuf _U_, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { *rbuflen = 0; return( AFP_OK ); } -struct savedt si = { { 0, 0, 0, 0 }, -1, 0 }; +static struct savedt si = { { 0, 0, 0, 0 }, -1, 0, 0 }; + +static char *icon_dtfile(struct vol *vol, u_char creator[ 4 ]) +{ + return dtfile( vol, creator, ".icon" ); +} -static int iconopen( vol, creator, flags, mode ) -struct vol *vol; -u_char creator[ 4 ]; +static int iconopen(struct vol *vol, u_char creator[ 4 ], int flags, int mode) { char *dtf, *adt, *adts; @@ -88,7 +83,7 @@ u_char creator[ 4 ]; si.sdt_fd = -1; } - dtf = dtfile( vol, creator, ".icon" ); + dtf = icon_dtfile( vol, creator); if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) { if ( errno == ENOENT && ( flags & O_CREAT )) { @@ -106,7 +101,7 @@ u_char creator[ 4 ]; *adts = '/'; if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) { - syslog( LOG_ERR, "iconopen: open %s: %s", dtf, strerror(errno) ); + LOG(log_error, logtype_afpd, "iconopen(%s): open: %s", dtf, strerror(errno) ); return -1; } } else { @@ -120,15 +115,15 @@ u_char creator[ 4 ]; return 0; } -int afp_addicon(obj, ibuf, ibuflen, rbuf, rbuflen) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +int afp_addicon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { struct vol *vol; +#ifndef NO_DDP struct iovec iov[ 2 ]; +#endif u_char fcreator[ 4 ], imh[ 12 ], irh[ 12 ], *p; - int itype, cc = AFP_OK, iovcnt = 0, buflen; + int itype, cc = AFP_OK, iovcnt = 0; + size_t buflen; u_int32_t ftype, itag; u_int16_t bsize, rsize, vid; @@ -138,7 +133,7 @@ int ibuflen, *rbuflen; memcpy( &vid, ibuf, sizeof( vid )); ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { cc = AFPERR_PARAM; goto addicon_err; } @@ -171,7 +166,7 @@ int ibuflen, *rbuflen; if (lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0) { close(si.sdt_fd); si.sdt_fd = -1; - syslog( LOG_ERR, "afp_addicon: lseek: %s", strerror(errno) ); + LOG(log_error, logtype_afpd, "afp_addicon(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) ); cc = AFPERR_PARAM; goto addicon_err; } @@ -206,7 +201,7 @@ int ibuflen, *rbuflen; } if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) { - syslog( LOG_ERR, "afp_addicon: lseek: %s", strerror(errno) ); + LOG(log_error, logtype_afpd, "afp_addicon(%s): lseek: %s", icon_dtfile(vol, fcreator),strerror(errno) ); cc = AFPERR_PARAM; } } @@ -216,7 +211,6 @@ int ibuflen, *rbuflen; */ addicon_err: if ( cc < 0 ) { - syslog( LOG_ERR, "afp_addicon: %s", strerror(errno) ); if (obj->proto == AFPPROTO_DSI) { dsi_writeinit(obj->handle, rbuf, buflen); dsi_writeflush(obj->handle); @@ -224,7 +218,6 @@ addicon_err: return cc; } - switch (obj->proto) { #ifndef NO_DDP case AFPPROTO_ASP: @@ -232,10 +225,12 @@ addicon_err: if ((asp_wrtcont(obj->handle, rbuf, &buflen) < 0) || buflen != bsize) return( AFPERR_PARAM ); +#ifdef DEBUG1 if (obj->options.flags & OPTION_DEBUG) { printf("(write) len: %d\n", buflen); bprint(rbuf, buflen); } +#endif /* * We're at the end of the file, add the headers, etc. */ @@ -257,7 +252,7 @@ addicon_err: } if ( writev( si.sdt_fd, iov, iovcnt ) < 0 ) { - syslog( LOG_ERR, "afp_addicon: writev: %s", strerror(errno) ); + LOG(log_error, logtype_afpd, "afp_addicon(%s): writev: %s", icon_dtfile(vol, fcreator), strerror(errno) ); return( AFPERR_PARAM ); } break; @@ -270,25 +265,20 @@ addicon_err: /* add headers at end of file */ if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) { - syslog(LOG_ERR, "afp_addicon: write: %s", strerror(errno)); + LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno)); dsi_writeflush(dsi); return AFPERR_PARAM; } if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) { - syslog(LOG_ERR, "afp_addicon: write: %s", strerror(errno)); + LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno)); dsi_writeflush(dsi); return AFPERR_PARAM; } while ((iovcnt = dsi_write(dsi, rbuf, buflen))) { - if ( obj->options.flags & OPTION_DEBUG ) { - printf("(write) command cont'd: %d\n", iovcnt); - bprint(rbuf, iovcnt); - } - if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) { - syslog(LOG_ERR, "afp_addicon: write: %s", strerror(errno)); + LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno)); dsi_writeflush(dsi); return AFPERR_PARAM; } @@ -302,11 +292,13 @@ addicon_err: return( AFP_OK ); } -u_char utag[] = { 0, 0, 0, 0 }; -u_char ucreator[] = { 'U', 'N', 'I', 'X' }; -u_char utype[] = { 'T', 'E', 'X', 'T' }; -short usize = 256; -u_char uicon[] = { +static const u_char utag[] = { 0, 0, 0, 0 }; +static const u_char ucreator[] = { 0, 0, 0, 0 };/* { 'U', 'N', 'I', 'X' };*/ +static const u_char utype[] = { 0, 0, 0, 0 };/* { 'T', 'E', 'X', 'T' };*/ +static const short usize = 256; + +#if 0 +static const u_char uicon[] = { 0x1F, 0xFF, 0xFC, 0x00, 0x10, 0x00, 0x06, 0x00, 0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x04, 0x80, 0x10, 0x00, 0x04, 0x40, 0x10, 0x00, 0x04, 0x20, @@ -340,11 +332,9 @@ u_char uicon[] = { 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0, }; +#endif -int afp_geticoninfo(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +int afp_geticoninfo(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { struct vol *vol; u_char fcreator[ 4 ], ih[ 12 ]; @@ -355,7 +345,7 @@ int ibuflen, *rbuflen; memcpy( &vid, ibuf, sizeof( vid )); ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { return( AFPERR_PARAM ); } @@ -402,7 +392,7 @@ int ibuflen, *rbuflen; memcpy( &bsize, ih + 10, sizeof( bsize )); bsize = ntohs(bsize); if ( lseek( si.sdt_fd, (off_t) bsize, SEEK_CUR ) < 0 ) { - syslog( LOG_ERR, "afp_iconinfo: lseek: %s", strerror(errno) ); + LOG(log_error, logtype_afpd, "afp_iconinfo(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) ); return( AFPERR_PARAM ); } if ( si.sdt_index == iindex ) { @@ -415,14 +405,11 @@ int ibuflen, *rbuflen; } -int afp_geticon(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +int afp_geticon(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { struct vol *vol; off_t offset; - int rc, buflen; + ssize_t rc, buflen; u_char fcreator[ 4 ], ftype[ 4 ], itype, ih[ 12 ]; u_int16_t vid, bsize, rsize; @@ -432,7 +419,7 @@ int ibuflen, *rbuflen; memcpy( &vid, ibuf, sizeof( vid )); ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { return( AFPERR_PARAM ); } @@ -445,6 +432,7 @@ int ibuflen, *rbuflen; memcpy( &bsize, ibuf, sizeof( bsize )); bsize = ntohs( bsize ); +#if 0 if ( memcmp( fcreator, ucreator, sizeof( ucreator )) == 0 && memcmp( ftype, utype, sizeof( utype )) == 0 && itype == 1 && @@ -453,6 +441,7 @@ int ibuflen, *rbuflen; *rbuflen = bsize; return( AFP_OK ); } +#endif if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) { return( AFPERR_NOITEM ); @@ -461,7 +450,7 @@ int ibuflen, *rbuflen; if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) { close(si.sdt_fd); si.sdt_fd = -1; - syslog(LOG_ERR, "afp_geticon: lseek: %s", strerror(errno)); + LOG(log_error, logtype_afpd, "afp_geticon(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno)); return( AFPERR_PARAM ); } @@ -477,14 +466,14 @@ int ibuflen, *rbuflen; memcpy( &rsize, ih + 10, sizeof( rsize )); rsize = ntohs( rsize ); if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) { - syslog( LOG_ERR, "afp_geticon: lseek: %s", strerror(errno) ); + LOG(log_error, logtype_afpd, "afp_geticon(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) ); return( AFPERR_PARAM ); } offset += rsize; } if ( rc < 0 ) { - syslog(LOG_ERR, "afp_geticon: read: %s", strerror(errno)); + LOG(log_error, logtype_afpd, "afp_geticon(%s): read: %s", icon_dtfile(vol, fcreator), strerror(errno)); return( AFPERR_PARAM ); } @@ -507,37 +496,34 @@ int ibuflen, *rbuflen; return AFPERR_PARAM; } - if ((*rbuflen = dsi_readinit(dsi, rbuf, buflen, rc, AFP_OK)) < 0) + if ((buflen = dsi_readinit(dsi, rbuf, buflen, rc, AFP_OK)) < 0) goto geticon_exit; + *rbuflen = buflen; /* do to the streaming nature, we have to exit if we encounter * a problem. much confusion results otherwise. */ while (*rbuflen > 0) { -#if defined(SENDFILE_FLAVOR_LINUX) || defined(SENDFILE_FLAVOR_BSD) +#ifdef WITH_SENDFILE if (!obj->options.flags & OPTION_DEBUG) { -#ifdef SENDFILE_FLAVOR_LINUX - if (sendfile(dsi->socket, si.sdt_fd, &offset, dsi->datasize) < 0) - goto geticon_exit; -#endif /* SENDFILE_FLAVOR_LINUX */ - -#ifdef SENDFILE_FLAVOR_BSD - if (sendfile(si.sdt_fd, dsi->socket, offset, rc, NULL, NULL, 0) < 0) - goto geticon_exit; -#endif /* SENDFILE_FLAVOR_BSD */ - - goto geticon_done; + if (dsi_stream_read_file(dsi, si.sdt_fd, offset, dsi->datasize) < 0) { + switch (errno) { + case ENOSYS: + case EINVAL: /* there's no guarantee that all fs support sendfile */ + break; + default: + goto geticon_exit; + } + } + else { + dsi_readdone(dsi); + return AFP_OK; + } } -#endif /* SENDFILE_FLAVOR_LINUX || SENDFILE_FLAVOR_BSD */ - +#endif buflen = read(si.sdt_fd, rbuf, *rbuflen); if (buflen < 0) goto geticon_exit; - if (obj->options.flags & OPTION_DEBUG) { - printf( "(read) reply: %d, %d\n", buflen, dsi->clientID); - bprint(rbuf, buflen); - } - /* dsi_read() also returns buffer size of next allocation */ buflen = dsi_read(dsi, rbuf, buflen); /* send it off */ if (buflen < 0) @@ -545,15 +531,14 @@ int ibuflen, *rbuflen; *rbuflen = buflen; } - -geticon_done: + dsi_readdone(dsi); return AFP_OK; geticon_exit: - syslog(LOG_INFO, "afp_geticon: %s", strerror(errno)); + LOG(log_error, logtype_afpd, "afp_geticon(%s): %s", icon_dtfile(vol, fcreator), strerror(errno)); dsi_readdone(dsi); - obj->exit(1); + obj->exit(EXITERR_SYS); return AFP_OK; } else { @@ -561,17 +546,17 @@ geticon_exit: return( AFPERR_PARAM ); } *rbuflen = rc; - return AFP_OK; } + return AFP_OK; } - -static char hexdig[] = "0123456789abcdef"; +/* ---------------------- */ +static const char hexdig[] = "0123456789abcdef"; char *dtfile(const struct vol *vol, u_char creator[], char *ext ) { static char path[ MAXPATHLEN + 1]; char *p; - int i; + unsigned int i; strcpy( path, vol->v_path ); strcat( path, "/.AppleDesktop/" ); @@ -601,182 +586,142 @@ char *dtfile(const struct vol *vol, u_char creator[], char *ext ) return( path ); } -char *mtoupath(const struct vol *vol, char *mpath) +/* --------------------------- + * mpath is only a filename + * did filename parent directory ID. +*/ + +char *mtoupath(const struct vol *vol, char *mpath, cnid_t did, int utf8) { - static char upath[ MAXPATHLEN + 1]; + static char upath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */ char *m, *u; - int i = 0; - + size_t inplen; + size_t outlen; + u_int16_t flags; + if ( *mpath == '\0' ) { - return( "." ); + strcpy(upath, "."); + return upath; + } + + /* set conversion flags */ + flags = vol->v_mtou_flags; + + m = demangle(vol, mpath, did); + if (m != mpath) { + return m; } m = mpath; u = upath; - while ( *m != '\0' ) { - /* handle case conversion first */ - if (vol->v_casefold & AFPVOL_MTOUUPPER) - *m = diatoupper( *m ); - else if (vol->v_casefold & AFPVOL_MTOULOWER) - *m = diatolower( *m ); - - /* we have a code page. we only use the ascii range - * if we have map ascii specified. */ -#if 1 - if (vol->v_mtoupage && ((*m & 0x80) || - vol->v_flags & AFPVOL_MAPASCII)) { - *u = vol->v_mtoupage->map[(unsigned char) *m].value; - } else -#endif /* 1 */ -#if AD_VERSION == AD_VERSION1 - if ((((vol->v_flags & AFPVOL_NOHEX) == 0) && - (!isascii(*m) || *m == '/')) || - (((vol->v_flags & AFPVOL_USEDOTS) == 0) && - ( i == 0 && (*m == '.' )))) { -#else /* AD_VERSION == AD_VERSION1 */ - if ((((vol->v_flags & AFPVOL_NOHEX) == 0) && - (!isprint(*m) || *m == '/')) || - (((vol->v_flags & AFPVOL_USEDOTS) == 0) && - ( i == 0 && (*m == '.' )))) { -#endif /* AD_VERSION == AD_VERSION1 */ - /* do hex conversion. */ - *u++ = ':'; - *u++ = hexdig[ ( *m & 0xf0 ) >> 4 ]; - *u = hexdig[ *m & 0x0f ]; - } else - *u = *m; - u++; - i++; - m++; - } - *u = '\0'; + inplen = strlen(m); + outlen = MAXPATHLEN; + + if ((size_t)-1 == (outlen = convert_charset ( (utf8)?CH_UTF8_MAC:vol->v_maccharset, vol->v_volcharset, vol->v_maccharset, m, inplen, u, outlen, &flags)) ) { + LOG(log_error, logtype_afpd, "conversion from %s to %s for %s failed.", (utf8)?"UTF8-MAC":vol->v_maccodepage, vol->v_volcodepage, mpath); + return NULL; + } + +#ifdef DEBUG + LOG(log_debug9, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath); +#endif /* DEBUG */ return( upath ); } -#define hextoint( c ) ( isdigit( c ) ? c - '0' : c + 10 - 'a' ) -#define islxdigit(x) (!isupper(x)&&isxdigit(x)) - -char *utompath(const struct vol *vol, char *upath) +/* --------------- + * id filename ID +*/ +char *utompath(const struct vol *vol, char *upath, cnid_t id, int utf8) { - static char mpath[ MAXPATHLEN + 1]; + static char mpath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */ char *m, *u; - int h; + u_int16_t flags; + size_t outlen; - /* do the hex conversion */ - u = upath; m = mpath; - while ( *u != '\0' ) { - /* we have a code page */ -#if 1 - if (vol->v_utompage && ((*u & 0x80) || - (vol->v_flags & AFPVOL_MAPASCII))) { - *m = vol->v_utompage->map[(unsigned char) *u].value; - } else -#endif /* 1 */ - if ( *u == ':' && *(u+1) != '\0' && islxdigit( *(u+1)) && - *(u+2) != '\0' && islxdigit( *(u+2))) { - ++u; - h = hextoint( *u ) << 4; - ++u; - h |= hextoint( *u ); - *m = h; - } else - *m = *u; - - /* handle case conversion */ - if (vol->v_casefold & AFPVOL_UTOMLOWER) - *m = diatolower( *m ); - else if (vol->v_casefold & AFPVOL_UTOMUPPER) - *m = diatoupper( *m ); - - u++; - m++; - } - *m = '\0'; - return( mpath ); -} + outlen = strlen(upath); -int afp_addcomment(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; -{ - struct adouble ad, *adp; - struct vol *vol; - struct dir *dir; - struct ofork *of; - char *path, *name; - int clen; - u_int32_t did; - u_int16_t vid; + flags = vol->v_utom_flags; - *rbuflen = 0; - ibuf += 2; + u = upath; - memcpy( &vid, ibuf, sizeof( vid )); - ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { - return( AFPERR_PARAM ); + /* convert charsets */ + if ((size_t)-1 == ( outlen = convert_charset ( vol->v_volcharset, (utf8)?CH_UTF8_MAC:vol->v_maccharset, vol->v_maccharset, u, outlen, mpath, MAXPATHLEN, &flags)) ) { + LOG(log_error, logtype_afpd, "Conversion from %s to %s for %s (%u) failed.", vol->v_volcodepage, vol->v_maccodepage, u, ntohl(id)); + goto utompath_error; } - memcpy( &did, ibuf, sizeof( did )); - ibuf += sizeof( did ); - if (( dir = dirsearch( vol, did )) == NULL ) { - return( AFPERR_NOOBJ ); - } + flags = !!(flags & CONV_REQMANGLE); - if (( path = cname( vol, dir, &ibuf )) == NULL ) { - return( AFPERR_NOOBJ ); - } + if (utf8) + flags |= 2; - if ((u_long)ibuf & 1 ) { - ibuf++; - } + m = mangle(vol, mpath, outlen, upath, id, flags); + +#ifdef DEBUG + LOG(log_debug9, logtype_afpd, "utompath: '%s':'%s':'%2.2X'", upath, m, ntohl(id)); +#endif /* DEBUG */ + return(m); + +utompath_error: + u = "???"; + m = mangle(vol, u, strlen(u), upath, id, (utf8)?3:1); + return(m); +} + +/* ------------------------- */ +static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf) +{ + struct ofork *of; + char *name, *upath; + int isadir; + int clen; + struct adouble ad, *adp; clen = (u_char)*ibuf++; clen = min( clen, 199 ); - if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) { - memset(&ad, 0, sizeof(ad)); + upath = path->u_name; + if (check_access(upath, OPENACC_WR ) < 0) { + return AFPERR_ACCESS; + } + + isadir = path_isadir(path); + if (isadir || !(of = of_findname(path))) { + ad_init(&ad, vol->v_adouble, vol->v_ad_options); adp = &ad; } else adp = of->of_ad; - if (ad_open( mtoupath( vol, path ), vol_noadouble(vol) | - (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF), - O_RDWR|O_CREAT, 0666, adp) < 0 ) { + + if (ad_open_metadata( upath , ( (isadir) ? ADFLAGS_DIR : 0), O_CREAT, adp) < 0 ) { return( AFPERR_ACCESS ); } - if ( ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT ) { - if ( *path == '\0' ) { - name = curdir->d_name; - } else { - name = path; + if (ad_getentryoff(adp, ADEID_COMMENT)) { + if ( (ad_get_MD_flags( adp ) & O_CREAT) ) { + if ( *path->m_name == '\0' ) { + name = (char *)curdir->d_m_name->data; + } else { + name = path->m_name; + } + ad_setname(adp, name); } - ad_setentrylen( adp, ADEID_NAME, strlen( name )); - memcpy( ad_entry( adp, ADEID_NAME ), name, - ad_getentrylen( adp, ADEID_NAME )); + ad_setentrylen( adp, ADEID_COMMENT, clen ); + memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen ); + ad_flush( adp ); } - - ad_setentrylen( adp, ADEID_COMMENT, clen ); - memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen ); - ad_flush( adp, ADFLAGS_HF ); - ad_close( adp, ADFLAGS_HF ); + ad_close_metadata( adp); return( AFP_OK ); } -int afp_getcomment(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +/* ----------------------------- */ +int afp_addcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) { - struct adouble ad, *adp; struct vol *vol; struct dir *dir; - struct ofork *of; - char *path; - u_int32_t did; + struct path *path; + u_int32_t did; u_int16_t vid; *rbuflen = 0; @@ -784,88 +729,122 @@ int ibuflen, *rbuflen; memcpy( &vid, ibuf, sizeof( vid )); ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { return( AFPERR_PARAM ); } memcpy( &did, ibuf, sizeof( did )); ibuf += sizeof( did ); - if (( dir = dirsearch( vol, did )) == NULL ) { - return( AFPERR_NOOBJ ); + if (NULL == ( dir = dirlookup( vol, did )) ) { + return afp_errno; } - if (( path = cname( vol, dir, &ibuf )) == NULL ) { - return( AFPERR_NOOBJ ); + if (NULL == ( path = cname( vol, dir, &ibuf )) ) { + return get_afp_errno(AFPERR_NOOBJ); } - if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) { - memset(&ad, 0, sizeof(ad)); + if ((u_long)ibuf & 1 ) { + ibuf++; + } + + return ad_addcomment(vol, path, ibuf); +} + +/* -------------------- */ +static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, size_t *rbuflen) +{ + struct adouble ad, *adp; + struct ofork *of; + char *upath; + int isadir; + int clen; + + upath = path->u_name; + isadir = path_isadir(path); + if (isadir || !(of = of_findname(path))) { + ad_init(&ad, vol->v_adouble, vol->v_ad_options); adp = &ad; } else adp = of->of_ad; - if ( ad_open( mtoupath( vol, path ), - (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF), - O_RDONLY, 0666, adp) < 0 ) { + + if ( ad_metadata( upath, ((isadir) ? ADFLAGS_DIR : 0), adp) < 0 ) { return( AFPERR_NOITEM ); } + if (!ad_getentryoff(adp, ADEID_COMMENT)) { + ad_close_metadata( adp ); + return AFPERR_NOITEM; + } /* * Make sure the AD file is not bogus. */ - if ( ad_getentrylen( adp, ADEID_COMMENT ) < 0 || + if ( ad_getentrylen( adp, ADEID_COMMENT ) <= 0 || ad_getentrylen( adp, ADEID_COMMENT ) > 199 ) { - ad_close( adp, ADFLAGS_HF ); + ad_close_metadata( adp ); return( AFPERR_NOITEM ); } - *rbuf++ = ad_getentrylen( adp, ADEID_COMMENT ); - memcpy( rbuf, ad_entry( adp, ADEID_COMMENT ), - ad_getentrylen( adp, ADEID_COMMENT )); - *rbuflen = ad_getentrylen( adp, ADEID_COMMENT ) + 1; - ad_close( adp, ADFLAGS_HF ); + clen = min( ad_getentrylen( adp, ADEID_COMMENT ), 128 ); /* OSX only use 128, greater kill Adobe CS2 */ + *rbuf++ = clen; + memcpy( rbuf, ad_entry( adp, ADEID_COMMENT ), clen); + *rbuflen = clen + 1; + ad_close_metadata( adp); + return( AFP_OK ); } -int afp_rmvcomment(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +/* -------------------- */ +int afp_getcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { - struct adouble ad, *adp; struct vol *vol; struct dir *dir; - struct ofork *of; - char *path; + struct path *s_path; u_int32_t did; u_int16_t vid; - + *rbuflen = 0; ibuf += 2; memcpy( &vid, ibuf, sizeof( vid )); ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { return( AFPERR_PARAM ); } memcpy( &did, ibuf, sizeof( did )); ibuf += sizeof( did ); - if (( dir = dirsearch( vol, did )) == NULL ) { - return( AFPERR_NOOBJ ); + if (NULL == ( dir = dirlookup( vol, did )) ) { + return afp_errno; } - if (( path = cname( vol, dir, &ibuf )) == NULL ) { - return( AFPERR_NOOBJ ); + if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) { + return get_afp_errno(AFPERR_NOOBJ); } - if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) { - memset(&ad, 0, sizeof(ad)); + return ad_getcomment(vol, s_path, rbuf, rbuflen); +} + +/* ----------------------- */ +static int ad_rmvcomment(struct vol *vol, struct path *path) +{ + struct adouble ad, *adp; + struct ofork *of; + int isadir; + char *upath; + + upath = path->u_name; + if (check_access(upath, OPENACC_WR ) < 0) { + return AFPERR_ACCESS; + } + + isadir = path_isadir(path); + if (isadir || !(of = of_findname(path))) { + ad_init(&ad, vol->v_adouble, vol->v_ad_options); adp = &ad; } else adp = of->of_ad; - if ( ad_open( mtoupath( vol, path ), - (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF), - O_RDWR, 0, adp) < 0 ) { + + if ( ad_open_metadata( upath, (isadir) ? ADFLAGS_DIR : 0, 0, adp) < 0 ) { switch ( errno ) { case ENOENT : return( AFPERR_NOITEM ); @@ -876,8 +855,41 @@ int ibuflen, *rbuflen; } } - ad_setentrylen( adp, ADEID_COMMENT, 0 ); - ad_flush( adp, ADFLAGS_HF ); - ad_close( adp, ADFLAGS_HF ); + if (ad_getentryoff(adp, ADEID_COMMENT)) { + ad_setentrylen( adp, ADEID_COMMENT, 0 ); + ad_flush( adp ); + } + ad_close_metadata( adp); return( AFP_OK ); } + +/* ----------------------- */ +int afp_rmvcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen) +{ + struct vol *vol; + struct dir *dir; + struct path *s_path; + u_int32_t did; + u_int16_t vid; + + *rbuflen = 0; + ibuf += 2; + + memcpy( &vid, ibuf, sizeof( vid )); + ibuf += sizeof( vid ); + if (NULL == ( vol = getvolbyvid( vid )) ) { + return( AFPERR_PARAM ); + } + + memcpy( &did, ibuf, sizeof( did )); + ibuf += sizeof( did ); + if (NULL == ( dir = dirlookup( vol, did )) ) { + return afp_errno; + } + + if (NULL == ( s_path = cname( vol, dir, &ibuf ))) { + return get_afp_errno(AFPERR_NOOBJ); + } + + return ad_rmvcomment(vol, s_path); +}