/*
- * $Id: desktop.c,v 1.18 2002-10-05 14:04:47 didg 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 <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 */
-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;
ibuf += 2;
memcpy( &vid, ibuf, sizeof(vid));
- if (( vol = getvolbyvid( vid )) == NULL ) {
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
*rbuflen = 0;
return( AFPERR_PARAM );
}
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;
memcpy( &vid, ibuf, sizeof( vid ));
ibuf += sizeof( vid );
- if (( vol = getvolbyvid( vid )) == NULL ) {
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
cc = AFPERR_PARAM;
goto addicon_err;
}
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( &vid, ibuf, sizeof( vid ));
ibuf += sizeof( vid );
- if (( vol = getvolbyvid( vid )) == NULL ) {
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
return( AFPERR_PARAM );
}
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( &vid, ibuf, sizeof( vid ));
ibuf += sizeof( vid );
- if (( vol = getvolbyvid( vid )) == NULL ) {
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
return( AFPERR_PARAM );
}
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];
char *p;
- int i;
+ unsigned int i;
strcpy( path, vol->v_path );
strcat( path, "/.AppleDesktop/" );
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;
}
-#ifdef FILE_MANGLING
- mpath = demangle(vol, mpath);
-#endif /* FILE_MANGLING */
+ /* 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;
- 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 /* DEBUG */
- *u++ = ':';
- *u++ = hexdig[ ( *m & 0xf0 ) >> 4 ];
- *u = hexdig[ *m & 0x0f ];
- }
- } 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_debug, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath);
+ 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';
-
-#ifdef FILE_MANGLING
- strcpy(mpath,mangle(vol, mpath));
-#endif /* FILE_MANGLING */
+ outlen = strlen(upath);
+
+ flags = vol->v_utom_flags;
+
+ 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;
+ }
+
+ flags = !!(flags & CONV_REQMANGLE);
+
+ 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_debug9, logtype_afpd, "utompath: '%s':'%s':'%2.2X'", upath, m, ntohl(id));
#endif /* DEBUG */
+ return(m);
- return( mpath );
+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;
- char *path, *name, *upath;
+ char *name, *upath;
+ int isadir;
int clen;
- 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 ) {
- return( AFPERR_PARAM );
- }
-
- memcpy( &did, ibuf, sizeof( did ));
- ibuf += sizeof( did );
- if (( dir = dirlookup( vol, did )) == NULL ) {
- return( AFPERR_NOOBJ );
- }
-
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
- return( AFPERR_NOOBJ );
- }
-
- if ((u_long)ibuf & 1 ) {
- ibuf++;
- }
+ struct adouble ad, *adp;
clen = (u_char)*ibuf++;
clen = min( clen, 199 );
- upath = mtoupath( vol, path );
- if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
- 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( upath , 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, *upath;
- u_int32_t did;
+ struct path *path;
+ u_int32_t did;
u_int16_t vid;
*rbuflen = 0;
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 = dirlookup( 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 ((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 = mtoupath( vol, path );
- if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
- memset(&ad, 0, sizeof(ad));
+ 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,
- (( *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, *upath;
+ 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 = dirlookup( 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);
}
- upath = mtoupath( vol, path );
- if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
- 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,
- (( *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 );
}
}
- 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);
+}