X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=etc%2Fafpd%2Fdesktop.c;h=af2264479d2d07af9b9d141492f5bf12eb2eb390;hb=d81ea56449b54aaeccf8bba1dc7ae88773268c33;hp=629da9d1affa776895fc5f2706fcb147109091d4;hpb=dae33a574ac2963d8bd279eaf96e08b5b48afc03;p=netatalk.git diff --git a/etc/afpd/desktop.c b/etc/afpd/desktop.c index 629da9d1..af226447 100644 --- a/etc/afpd/desktop.c +++ b/etc/afpd/desktop.c @@ -1,5 +1,5 @@ /* - * $Id: desktop.c,v 1.22 2003-01-24 07:08:42 didg Exp $ + * $Id: desktop.c,v 1.43 2009-10-25 09:47:03 didg Exp $ * * See COPYRIGHT. * @@ -13,13 +13,16 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#include +#include +#include +#include + #include -#include -#include +#include + +#include #include #include -#include #include #include #include @@ -27,32 +30,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" -#ifdef FILE_MANGLING #include "mangle.h" -#endif /* CNID_DB */ -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; @@ -70,20 +58,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 int iconopen( vol, creator, flags, mode ) -struct vol *vol; -u_char creator[ 4 ]; +static char *icon_dtfile(struct vol *vol, u_char creator[ 4 ]) +{ + return dtfile( vol, creator, ".icon" ); +} + +static int iconopen(struct vol *vol, u_char creator[ 4 ], int flags, int mode) { char *dtf, *adt, *adts; @@ -96,7 +84,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 )) { @@ -114,7 +102,7 @@ u_char creator[ 4 ]; *adts = '/'; if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) { - LOG(log_error, logtype_afpd, "iconopen: open %s: %s", dtf, strerror(errno) ); + LOG(log_error, logtype_afpd, "iconopen(%s): open: %s", dtf, strerror(errno) ); return -1; } } else { @@ -128,15 +116,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; @@ -146,7 +134,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; } @@ -179,7 +167,7 @@ int ibuflen, *rbuflen; if (lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0) { close(si.sdt_fd); si.sdt_fd = -1; - LOG(log_error, logtype_afpd, "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; } @@ -214,7 +202,7 @@ int ibuflen, *rbuflen; } if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) { - LOG(log_error, logtype_afpd, "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; } } @@ -224,7 +212,6 @@ int ibuflen, *rbuflen; */ addicon_err: if ( cc < 0 ) { - LOG(log_error, logtype_afpd, "afp_addicon: %s", strerror(errno) ); if (obj->proto == AFPPROTO_DSI) { dsi_writeinit(obj->handle, rbuf, buflen); dsi_writeflush(obj->handle); @@ -232,7 +219,6 @@ addicon_err: return cc; } - switch (obj->proto) { #ifndef NO_DDP case AFPPROTO_ASP: @@ -240,10 +226,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. */ @@ -265,7 +253,7 @@ addicon_err: } if ( writev( si.sdt_fd, iov, iovcnt ) < 0 ) { - LOG(log_error, logtype_afpd, "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; @@ -278,25 +266,20 @@ addicon_err: /* add headers at end of file */ if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) { - LOG(log_error, logtype_afpd, "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) { - LOG(log_error, logtype_afpd, "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) { - LOG(log_error, logtype_afpd, "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; } @@ -310,11 +293,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, @@ -348,11 +333,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 ]; @@ -363,7 +346,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 ); } @@ -410,7 +393,7 @@ int ibuflen, *rbuflen; memcpy( &bsize, ih + 10, sizeof( bsize )); bsize = ntohs(bsize); if ( lseek( si.sdt_fd, (off_t) bsize, SEEK_CUR ) < 0 ) { - LOG(log_error, logtype_afpd, "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 ) { @@ -423,14 +406,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; @@ -440,7 +420,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 ); } @@ -453,6 +433,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 && @@ -461,6 +442,7 @@ int ibuflen, *rbuflen; *rbuflen = bsize; return( AFP_OK ); } +#endif if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) { return( AFPERR_NOITEM ); @@ -469,7 +451,7 @@ int ibuflen, *rbuflen; if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) { close(si.sdt_fd); si.sdt_fd = -1; - LOG(log_error, logtype_afpd, "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 ); } @@ -485,14 +467,14 @@ int ibuflen, *rbuflen; memcpy( &rsize, ih + 10, sizeof( rsize )); rsize = ntohs( rsize ); if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) { - LOG(log_error, logtype_afpd, "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 ) { - LOG(log_error, logtype_afpd, "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 ); } @@ -515,37 +497,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) @@ -553,15 +532,14 @@ int ibuflen, *rbuflen; *rbuflen = buflen; } - -geticon_done: + dsi_readdone(dsi); return AFP_OK; geticon_exit: - LOG(log_info, logtype_afpd, "afp_geticon: %s", strerror(errno)); + LOG(log_info, 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 { @@ -569,12 +547,12 @@ 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]; @@ -609,238 +587,165 @@ char *dtfile(const struct vol *vol, u_char creator[], char *ext ) return( path ); } -/* +/* --------------------------- * mpath is only a filename + * did filename parent directory ID. */ -char *mtoupath(const struct vol *vol, char *mpath) + +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; - int changed = 0; + size_t inplen; + size_t outlen; + u_int16_t flags = 0; if ( *mpath == '\0' ) { return( "." ); } -#ifdef FILE_MANGLING - m = demangle(vol, mpath); + /* set conversion flags */ + if (!(vol->v_flags & AFPVOL_NOHEX)) + flags |= CONV_ESCAPEHEX; + if (!(vol->v_flags & AFPVOL_USEDOTS)) + flags |= CONV_ESCAPEDOTS; + + if ((vol->v_casefold & AFPVOL_MTOUUPPER)) + flags |= CONV_TOUPPER; + else if ((vol->v_casefold & AFPVOL_MTOULOWER)) + flags |= CONV_TOLOWER; + + if ((vol->v_flags & AFPVOL_EILSEQ)) { + flags |= CONV__EILSEQ; + } + + m = demangle(vol, mpath, did); if (m != mpath) { - changed = 1; - mpath = m; + return m; } -#endif /* FILE_MANGLING */ + 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 (vol->v_mtoupage && ((*m & 0x80) || - vol->v_flags & AFPVOL_MAPASCII)) { - *u = vol->v_mtoupage->map[(unsigned char) *m].value; - changed = 1; - if (!*u && *m) { - /* if conversion failed, encode in hex - * to prevent silly truncation - * H.P. Jansen */ -#ifdef DEBUG - LOG(log_debug, logtype_afpd, "mtoupath: hex encode: 0x%x", (unsigned char) *m); -#endif /* DEBUG */ - *u++ = ':'; - *u++ = hexdig[ ( *m & 0xf0 ) >> 4 ]; - *u = hexdig[ *m & 0x0f ]; - } - } else { -#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 ]; - changed = 1; - } else - *u = *m; - } - u++; - i++; - m++; + + 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; } - *u = '\0'; #ifdef DEBUG LOG(log_debug, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath); #endif /* DEBUG */ - - return( (changed)?upath:mpath ); + 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; - int changed = 0; + u_int16_t flags = CONV_IGNORE | CONV_UNESCAPEHEX; + 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; - changed = 1; - } 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; - changed = 1; - } 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'; m = mpath; + outlen = strlen(upath); -#ifdef FILE_MANGLING - m = mangle(vol, mpath); - if (m != mpath) { - changed = 1; + if ((vol->v_casefold & AFPVOL_UTOMUPPER)) + flags |= CONV_TOUPPER; + else if ((vol->v_casefold & AFPVOL_UTOMLOWER)) + flags |= CONV_TOLOWER; + + if ((vol->v_flags & AFPVOL_EILSEQ)) { + flags |= CONV__EILSEQ; } -#endif /* FILE_MANGLING */ + + u = upath; + + /* 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; + } + + if (!(flags & CONV_REQMANGLE)) + flags = 0; + else + flags = 1; + + if (utf8) + flags |= 2; + + m = mangle(vol, mpath, outlen, upath, id, flags); #ifdef DEBUG - LOG(log_debug, logtype_afpd, "utompath: '%s':'%s'", upath, mpath); + LOG(log_debug, logtype_afpd, "utompath: '%s':'%s':'%2.2X'", upath, m, ntohl(id)); #endif /* DEBUG */ + return(m); - return((changed)? m:upath ); +utompath_error: + u = "???"; + m = mangle(vol, u, strlen(u), upath, id, (utf8)?3:1); + return(m); } -int afp_addcomment(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +/* ------------------------- */ +static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf) { - struct adouble ad, *adp; - struct vol *vol; - struct dir *dir; struct ofork *of; - struct path *path; char *name, *upath; - int clen; - u_int32_t did; - u_int16_t vid; int isadir; - - *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 == ( path = cname( vol, dir, &ibuf )) ) { - return afp_errno; - } - - if ((u_long)ibuf & 1 ) { - ibuf++; - } + int clen; + struct adouble ad, *adp; clen = (u_char)*ibuf++; clen = min( clen, 199 ); upath = path->u_name; - if (check_access(upath, OPENACC_WR ) < 0) { + if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) { return AFPERR_ACCESS; } - + isadir = path_isadir(path); if (isadir || !(of = of_findname(path))) { - memset(&ad, 0, sizeof(ad)); + ad_init(&ad, vol->v_adouble, vol->v_ad_options); adp = &ad; } else adp = of->of_ad; - if (ad_open( upath , vol_noadouble(vol) | - (( isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF), - O_RDWR|O_CREAT, 0666, adp) < 0 ) { + if (ad_open_metadata( upath , vol_noadouble(vol) | ( (isadir) ? ADFLAGS_DIR :0),O_CREAT, adp) < 0 ) { return( AFPERR_ACCESS ); } - if ( (ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT) ) { - if ( *path->m_name == '\0' ) { - name = curdir->d_m_name; - } else { - name = path->m_name; + if (ad_getentryoff(adp, ADEID_COMMENT)) { + if ( (ad_get_MD_flags( adp ) & O_CREAT) ) { + if ( *path->m_name == '\0' ) { + name = curdir->d_m_name; + } 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; - struct path *s_path; - char *upath; - u_int32_t did; + struct path *path; + u_int32_t did; u_int16_t vid; - int isadir; - + *rbuflen = 0; ibuf += 2; @@ -856,57 +761,69 @@ int ibuflen, *rbuflen; return afp_errno; } - if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) { - return afp_errno; + if (NULL == ( path = cname( vol, dir, &ibuf )) ) { + return get_afp_errno(AFPERR_NOOBJ); + } + + if ((u_long)ibuf & 1 ) { + ibuf++; } - upath = s_path->u_name; - isadir = path_isadir(s_path); - if (isadir || !(of = of_findname(s_path))) { - memset(&ad, 0, sizeof(ad)); + 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( upath, - ( isadir) ? 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 AFPERR_NOITEM if len == 0 ? */ 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; struct path *s_path; - char *upath; u_int32_t did; u_int16_t vid; - int isadir; - + *rbuflen = 0; ibuf += 2; @@ -922,25 +839,34 @@ int ibuflen, *rbuflen; return afp_errno; } - if (NULL == ( s_path = cname( vol, dir, &ibuf ))) { - return afp_errno; + if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) { + return get_afp_errno(AFPERR_NOOBJ); } - upath = s_path->u_name; - if (check_access(upath, OPENACC_WR ) < 0) { + 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 (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) { return AFPERR_ACCESS; } - isadir = path_isadir(s_path); - if (isadir || !(of = of_findname(s_path))) { - memset(&ad, 0, sizeof(ad)); + 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( upath, - (isadir) ? 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 ); @@ -951,8 +877,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); +}