/*
- * $Id: desktop.c,v 1.30 2003-06-09 14:42:38 srittau Exp $
+ * $Id: desktop.c,v 1.50.2.1 2010-02-01 10:56:08 franklahm Exp $
*
* See COPYRIGHT.
*
#include "config.h"
#endif /* HAVE_CONFIG_H */
-#include <atalk/logger.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
#include <errno.h>
-#include <sys/types.h>
-#include <sys/time.h>
+
+#include <atalk/adouble.h>
#include <sys/uio.h>
#include <sys/param.h>
-#include <sys/stat.h>
#include <sys/socket.h>
#include <netatalk/at.h>
#include <netatalk/endian.h>
#include <atalk/atp.h>
#include <atalk/asp.h>
#include <atalk/afp.h>
-#include <atalk/adouble.h>
#include <atalk/util.h>
-#include <dirent.h>
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif /* HAVE_FCNTL_H */
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef HAVE_FCNTL_H
-#include <unistd.h>
-#endif /* HAVE_FCNTL_H */
-
+#include <atalk/logger.h>
#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 <iconv.h>
-#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;
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;
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 )) {
*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 {
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;
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;
}
}
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;
}
}
*/
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);
return cc;
}
-
switch (obj->proto) {
#ifndef NO_DDP
case AFPPROTO_ASP:
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. */
}
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;
/* 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;
}
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,
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 ];
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 ) {
}
-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;
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 &&
*rbuflen = bsize;
return( AFP_OK );
}
+#endif
if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) {
return( AFPERR_NOITEM );
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 );
}
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 );
}
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)
*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 {
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];
/* ---------------------------
* mpath is only a filename
+ * did filename parent directory ID.
*/
-static char upath[ MAXPATHLEN + 1];
-static char mpath[ MAXPATHLEN + 1];
-#ifdef AFP3x
-static char ucs2[ MAXPATHLEN + 1];
-#endif
-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 <hpj@urpla.net> */
-#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 */
-
-#ifdef DEBUG
- LOG(log_debug, logtype_afpd, "utompath: '%s':'%s'", upath, mpath);
-#endif /* DEBUG */
-
- return((changed)? m:upath );
-}
-
-/* --------------- */
-#ifdef AFP3x
-extern unsigned int do_precomposition(unsigned int base, unsigned int comb);
+ flags = vol->v_utom_flags;
-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);
+ flags = !!(flags & CONV_REQMANGLE);
-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;
-}
-#endif
+ if (utf8)
+ flags |= 2;
-/* --------------------------- */
-char *mtoupath(const struct vol *vol, char *mpath, int utf8)
-{
- int i = 0;
- char *m, *u;
-#ifdef AFP3x
- char *r;
- size_t inplen;
- size_t outlen;
-#endif
-
- if ( *mpath == '\0' ) {
- return( "." );
- }
+ m = mangle(vol, mpath, outlen, upath, id, flags);
-#ifdef FILE_MANGLING
- m = demangle(vol, mpath);
- if (m != mpath) {
- return m;
- }
-#endif /* FILE_MANGLING */
-
- if (!vol_utf8(vol))
- return old_mtoupath(vol, mpath);
-
- 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)
{
- int h;
- int mangleflag = 0;
- char *m, *u;
-#ifdef AFP3x
- char *r;
- size_t inplen;
- size_t outlen;
-#endif
+ 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;
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 );
+ }
+
+ 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);
- ad_setentrylen( adp, ADEID_COMMENT, clen );
- memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen );
- ad_flush( adp, ADFLAGS_HF );
- ad_close( adp, ADFLAGS_HF );
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;
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;
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);
}