X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fdesktop.c;h=9f105e13e13c612757386f70c342626e28fe5e77;hb=6ee7ecd6892a1750128dcced1410e76b5e166874;hp=c6a3e9173b078adf126ecdfb53d82426fdd5a63e;hpb=ccaca461c5374341894f85fc56b17f3a3572948f;p=netatalk.git diff --git a/etc/afpd/desktop.c b/etc/afpd/desktop.c index c6a3e917..9f105e13 100644 --- a/etc/afpd/desktop.c +++ b/etc/afpd/desktop.c @@ -1,5 +1,5 @@ /* - * $Id: desktop.c,v 1.29 2003-06-05 09:17:10 didg Exp $ + * $Id: desktop.c,v 1.50.2.1 2010-02-01 10:56:08 franklahm Exp $ * * See COPYRIGHT. * @@ -13,13 +13,15 @@ #include "config.h" #endif /* HAVE_CONFIG_H */ -#include +#include +#include +#include + #include -#include -#include + +#include #include #include -#include #include #include #include @@ -27,37 +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" - -#ifdef FILE_MANGLING #include "mangle.h" -#endif /* CNID_DB */ -#ifdef AFP3x -#include -#endif -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; @@ -75,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 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; @@ -101,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 )) { @@ -119,7 +101,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 { @@ -133,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; @@ -184,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; - 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; } @@ -219,7 +201,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; } } @@ -229,7 +211,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); @@ -237,7 +218,6 @@ addicon_err: return cc; } - switch (obj->proto) { #ifndef NO_DDP case AFPPROTO_ASP: @@ -245,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. */ @@ -270,7 +252,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; @@ -283,25 +265,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; } @@ -315,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, @@ -353,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 ]; @@ -415,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 ) { - 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 ) { @@ -428,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; @@ -458,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 && @@ -466,6 +441,7 @@ int ibuflen, *rbuflen; *rbuflen = bsize; return( AFP_OK ); } +#endif if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) { return( AFPERR_NOITEM ); @@ -474,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; - 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 ); } @@ -490,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 ) { - 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 ); } @@ -520,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) @@ -558,15 +531,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_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 { @@ -574,12 +546,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]; @@ -616,404 +588,141 @@ char *dtfile(const struct vol *vol, u_char creator[], char *ext ) /* --------------------------- * mpath is only a filename + * did filename parent directory ID. */ -static char upath[ MAXPATHLEN + 1]; -static char mpath[ MAXPATHLEN + 1]; -static char ucs2[ MAXPATHLEN + 1]; -static char *old_mtoupath(const struct vol *vol, char *mpath) +char *mtoupath(const struct vol *vol, char *mpath, cnid_t did, int utf8) { + 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; + if ( *mpath == '\0' ) { + 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; - if ((vol->v_casefold & (AFPVOL_MTOUUPPER| AFPVOL_MTOULOWER))) { - changed = 1; - } - 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 - *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 - if ((((vol->v_flags & AFPVOL_NOHEX) == 0) && - (!isprint(*m) || *m == '/')) || - (((vol->v_flags & AFPVOL_USEDOTS) == 0) && - ( i == 0 && (*m == '.' )))) { -#endif - /* 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); + LOG(log_debug9, 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)) - -static char *old_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 + 2]; /* for convert_charset dest_len parameter +2 */ char *m, *u; - int h; - int changed = 0; + u_int16_t flags; + size_t outlen; - /* do the hex conversion */ - u = upath; - m = mpath; - if ((vol->v_casefold & (AFPVOL_MTOUUPPER| AFPVOL_MTOULOWER))) { - changed = 1; - } - while ( *u != '\0' ) { - /* we have a code page */ - if (vol->v_utompage && ((*u & 0x80) || - (vol->v_flags & AFPVOL_MAPASCII))) { - *m = vol->v_utompage->map[(unsigned char) *u].value; - changed = 1; - } else - 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, upath, 0); - if (m != mpath) { - changed = 1; - } -#endif /* FILE_MANGLING */ + flags = vol->v_utom_flags; -#ifdef DEBUG - LOG(log_debug, logtype_afpd, "utompath: '%s':'%s'", upath, mpath); -#endif /* DEBUG */ - - return((changed)? m:upath ); -} - -/* --------------- */ -extern unsigned int do_precomposition(unsigned int base, unsigned int comb); - -static char comp[MAXPATHLEN +1]; + u = upath; -static char *precompose(u_int16_t *name, size_t inplen, size_t *outlen) -{ -size_t i; -u_int16_t base, comb; -u_int16_t *in, *out; -u_int16_t result; - - if (!inplen || (inplen & 1) || inplen > sizeof(comp)/sizeof(u_int16_t)) - return NULL; - i = 0; - in = name; - out = (u_int16_t *)comp; - *outlen = 0; - - base = *in; - while (1) { - i += 2; - in++; - if (i == inplen) { - *out = base; - *outlen += 2; - return comp; - } - comb = *in; - if (comb >= 0x300 && (result = do_precomposition(base, comb))) { - *out = result; - out++; - *outlen += 2; - i += 2; - in++; - if (i == inplen) - return comp; - base = *in; - } - else { - *out = base; - out++; - *outlen += 2; - base = comb; - } + /* 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; } -} - -/* --------------- */ -extern unsigned int do_decomposition(unsigned int base); - -static char *decompose(u_int16_t *name, size_t inplen, size_t *outlen) -{ -size_t i; -u_int16_t base; -u_int16_t *in, *out; -unsigned int result; - - if (!inplen || (inplen & 1)) - return NULL; - i = 0; - in = name; - out = (u_int16_t *)comp; - *outlen = 0; - - while (i < inplen) { - if (*outlen >= sizeof(comp)/sizeof(u_int16_t) +2) { - return NULL; - } - base = *in; - if ((result = do_decomposition(base))) { - *out = result >> 16; - out++; - *outlen += 2; - *out = result & 0xffff; - out++; - *outlen += 2; - } - else { - *out = base; - out++; - *outlen += 2; - } - i += 2; - in++; - } - return comp; -} -/* --------------------------- */ -char *mtoupath(const struct vol *vol, char *mpath, int utf8) -{ - char *m, *u, *r; - int i = 0; - size_t inplen; - size_t outlen; - - if ( *mpath == '\0' ) { - return( "." ); - } + flags = !!(flags & CONV_REQMANGLE); -#ifdef FILE_MANGLING - m = demangle(vol, mpath); - if (m != mpath) { - return m; - } -#endif /* FILE_MANGLING */ + if (utf8) + flags |= 2; - if (!vol_utf8(vol)) - return old_mtoupath(vol, mpath); + m = mangle(vol, mpath, outlen, upath, id, flags); - m = mpath; - u = upath; - while ( *m != '\0' ) { - if ( (!(vol->v_flags & AFPVOL_NOHEX) && *m == '/') || - (!(vol->v_flags & AFPVOL_USEDOTS) && i == 0 && *m == '.') || - (!utf8 && (unsigned char)*m == 0xf0) /* Apple logo */ - ) { - /* do hex conversion. */ - *u++ = ':'; - *u++ = hexdig[ ( *m & 0xf0 ) >> 4 ]; - *u = hexdig[ *m & 0x0f ]; - } else - *u = *m; - u++; - i++; - m++; - } - *u = '\0'; - u = upath; -#ifdef AFP3x - inplen = strlen(u); - outlen = MAXPATHLEN; - r = ucs2; - if (!utf8) { - if ((size_t)(-1) == iconv(vol->v_mactoutf8, 0,0,0,0) ) - return NULL; - /* assume precompose */ - if ((size_t)(-1) == iconv(vol->v_mactoutf8, &u, &inplen, &r, &outlen)) - return NULL; - u = ucs2; - } - else { - if ((size_t)(-1) == iconv(vol->v_utf8toucs2, 0,0,0,0) ) - return NULL; - - if ((size_t)(-1) == iconv(vol->v_utf8toucs2, &u, &inplen, &r, &outlen)) - return NULL; - - u = precompose((u_int16_t *)ucs2, MAXPATHLEN -outlen, &inplen); - - if ((size_t)(-1) == iconv(vol->v_ucs2toutf8, 0,0,0,0)) - return NULL; - - outlen = MAXPATHLEN; - r = upath; - if ((size_t)(-1) == iconv(vol->v_ucs2toutf8, &u, &inplen, &r, &outlen)) - return NULL; - u = upath; - } - u[MAXPATHLEN -outlen] = 0; -#endif #ifdef DEBUG - LOG(log_debug, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath); + LOG(log_debug9, logtype_afpd, "utompath: '%s':'%s':'%2.2X'", upath, m, ntohl(id)); #endif /* DEBUG */ - return( u ); + return(m); + +utompath_error: + u = "???"; + m = mangle(vol, u, strlen(u), upath, id, (utf8)?3:1); + return(m); } -/* --------------- */ -char *utompath(const struct vol *vol, char *upath, int utf8) +/* ------------------------- */ +static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf) { - char *m, *u, *r; - int h; - int mangleflag = 0; - size_t inplen; - size_t outlen; + struct ofork *of; + char *name, *upath; + int isadir; + int clen; + struct adouble ad, *adp; - if (!vol_utf8(vol)) - return old_utompath(vol, upath); - /* do the hex conversion */ - u = upath; - m = mpath; - while ( *u != '\0' ) { - if ( *u == ':' && islxdigit( *(u+1)) && islxdigit( *(u+2))) { - ++u; - h = hextoint( *u ) << 4; - ++u; - h |= hextoint( *u ); - *m = h; - } else - *m = *u; - u++; - m++; + clen = (u_char)*ibuf++; + clen = min( clen, 199 ); + + upath = path->u_name; + if (check_access(upath, OPENACC_WR ) < 0) { + return AFPERR_ACCESS; } - *m = '\0'; - m = mpath; -#ifdef AFP3x - if ((size_t)(-1) == iconv(vol->v_utf8toucs2, 0,0,0,0) ) - return NULL; - inplen = strlen(mpath); - outlen = MAXPATHLEN; - r = ucs2; - if ((size_t)(-1) == iconv(vol->v_utf8toucs2, &m, &inplen, &r, &outlen)) - return NULL; - - if (utf8) { - if ( NULL == (m = decompose((u_int16_t *)ucs2, MAXPATHLEN -outlen, &inplen))) - return NULL; - - if ((size_t)(-1) == iconv(vol->v_ucs2toutf8, 0,0,0,0)) - return NULL; - - outlen = MAXPATHLEN; - r = mpath; - if ((size_t)(-1) == iconv(vol->v_ucs2toutf8, &m, &inplen, &r, &outlen)) - return NULL; + + 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_metadata( upath , ( (isadir) ? ADFLAGS_DIR : 0), O_CREAT, adp) < 0 ) { + return( AFPERR_ACCESS ); } - else { - m = precompose((u_int16_t *)ucs2, MAXPATHLEN -outlen, &inplen); - - if ((size_t)(-1) == iconv(vol->v_ucs2tomac, 0,0,0,0)) - return NULL; - - outlen = MAXPATHLEN; - r = mpath; - if ((size_t)(-1) == iconv(vol->v_ucs2tomac, &m, &inplen, &r, &outlen)) { - switch (errno) { - case EILSEQ: - if (outlen != MAXPATHLEN) { - mangleflag = 1; - } - default: - return NULL; + + 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_COMMENT, clen ); + memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen ); + ad_flush( adp ); } - mpath[MAXPATHLEN -outlen] = 0; -#endif -#ifdef FILE_MANGLING - m = mangle(vol, mpath, upath, mangleflag); -#else - if (mangleflag) - return NULL; - m = mpath; -#endif /* FILE_MANGLING */ - - return(m); + ad_close_metadata( adp); + return( AFP_OK ); } /* ----------------------------- */ -int afp_addcomment(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 *path; - char *name, *upath; - int clen; u_int32_t did; u_int16_t vid; - int isadir; *rbuflen = 0; ibuf += 2; @@ -1038,59 +747,60 @@ int ibuflen, *rbuflen; ibuf++; } - clen = (u_char)*ibuf++; - clen = min( clen, 199 ); + return ad_addcomment(vol, path, ibuf); +} - upath = path->u_name; - if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) { - return AFPERR_ACCESS; - } +/* -------------------- */ +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))) { - 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 ) { - return( AFPERR_ACCESS ); + + if ( ad_metadata( upath, ((isadir) ? ADFLAGS_DIR : 0), adp) < 0 ) { + return( AFPERR_NOITEM ); } - if ( (ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT) ) { - if ( *path->m_name == '\0' ) { - name = curdir->d_m_name; - } else { - name = path->m_name; - } - ad_setentrylen( adp, ADEID_NAME, strlen( name )); - memcpy( ad_entry( adp, ADEID_NAME ), name, - ad_getentrylen( adp, ADEID_NAME )); + 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 || + ad_getentrylen( adp, ADEID_COMMENT ) > 199 ) { + ad_close_metadata( adp ); + return( AFPERR_NOITEM ); } - ad_setentrylen( adp, ADEID_COMMENT, clen ); - memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen ); - ad_flush( adp, ADFLAGS_HF ); - 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_getcomment(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; @@ -1111,52 +821,56 @@ int ibuflen, *rbuflen; return get_afp_errno(AFPERR_NOOBJ); } - upath = s_path->u_name; - isadir = path_isadir(s_path); - if (isadir || !(of = of_findname(s_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( upath, - ( isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF, - O_RDONLY, 0666, adp) < 0 ) { - return( AFPERR_NOITEM ); - } - /* - * Make sure the AD file is not bogus. - */ - if ( ad_getentrylen( adp, ADEID_COMMENT ) < 0 || - ad_getentrylen( adp, ADEID_COMMENT ) > 199 ) { - ad_close( adp, ADFLAGS_HF ); - return( AFPERR_NOITEM ); + if ( ad_open_metadata( upath, (isadir) ? ADFLAGS_DIR : 0, 0, adp) < 0 ) { + switch ( errno ) { + case ENOENT : + return( AFPERR_NOITEM ); + case EACCES : + return( AFPERR_ACCESS ); + default : + return( AFPERR_PARAM ); + } } - *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 ); - - /* return AFPERR_NOITEM if len == 0 ? */ + 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(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +/* ----------------------- */ +int afp_rmvcomment(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; u_int16_t vid; - int isadir; *rbuflen = 0; ibuf += 2; @@ -1176,34 +890,6 @@ int ibuflen, *rbuflen; if (NULL == ( s_path = cname( vol, dir, &ibuf ))) { return get_afp_errno(AFPERR_NOOBJ); } - - upath = s_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)); - adp = &ad; - } else - adp = of->of_ad; - - if ( ad_open( upath, - (isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF, - O_RDWR, 0, adp) < 0 ) { - switch ( errno ) { - case ENOENT : - return( AFPERR_NOITEM ); - case EACCES : - return( AFPERR_ACCESS ); - default : - return( AFPERR_PARAM ); - } - } - - ad_setentrylen( adp, ADEID_COMMENT, 0 ); - ad_flush( adp, ADFLAGS_HF ); - ad_close( adp, ADFLAGS_HF ); - return( AFP_OK ); + + return ad_rmvcomment(vol, s_path); }