/*
- * Copyright (c) 1990,1993 Regents of The University of Michigan.
- * All Rights Reserved. See COPYRIGHT.
+ * $Id: desktop.c,v 1.47 2009-11-27 12:37:24 didg 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.
*/
-#include <sys/syslog.h>
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_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>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <unistd.h>
-
+#include <atalk/logger.h>
#include "volume.h"
#include "directory.h"
#include "fork.h"
#include "globals.h"
#include "desktop.h"
+#include "mangle.h"
-int afp_opendt(obj, ibuf, ibuflen, rbuf, rbuflen )
- AFPObj *obj;
- char *ibuf, *rbuf;
- int ibuflen, *rbuflen;
+
+int afp_opendt(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen)
{
struct vol *vol;
u_int16_t vid;
ibuf += 2;
memcpy( &vid, ibuf, sizeof(vid));
- if (( vol = getvolbyvid( vid )) == NULL ) {
- *rbuflen = 0;
- return( AFPERR_PARAM );
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
+ *rbuflen = 0;
+ return( AFPERR_PARAM );
}
memcpy( rbuf, &vid, sizeof(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;
if ( si.sdt_fd != -1 ) {
- if ( memcmp( si.sdt_creator, creator, sizeof( CreatorType )) == 0 &&
- si.sdt_vid == vol->v_vid ) {
- return 0;
- }
- close( si.sdt_fd );
- si.sdt_fd = -1;
+ if ( memcmp( si.sdt_creator, creator, sizeof( CreatorType )) == 0 &&
+ si.sdt_vid == vol->v_vid ) {
+ return 0;
+ }
+ close( si.sdt_fd );
+ 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 )) {
- if (( adts = strrchr( dtf, '/' )) == NULL ) {
- return -1;
- }
- *adts = '\0';
- if (( adt = strrchr( dtf, '/' )) == NULL ) {
- return -1;
- }
- *adt = '\0';
- (void) ad_mkdir( dtf, DIRBITS | 0777 );
- *adt = '/';
- (void) ad_mkdir( dtf, DIRBITS | 0777 );
- *adts = '/';
-
- if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
- syslog( LOG_ERR, "iconopen: open %s: %m", dtf );
- return -1;
- }
- } else {
- return -1;
- }
+ if ( errno == ENOENT && ( flags & O_CREAT )) {
+ if (( adts = strrchr( dtf, '/' )) == NULL ) {
+ return -1;
+ }
+ *adts = '\0';
+ if (( adt = strrchr( dtf, '/' )) == NULL ) {
+ return -1;
+ }
+ *adt = '\0';
+ (void) ad_mkdir( dtf, DIRBITS | 0777 );
+ *adt = '/';
+ (void) ad_mkdir( dtf, DIRBITS | 0777 );
+ *adts = '/';
+
+ if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
+ LOG(log_error, logtype_afpd, "iconopen(%s): open: %s", dtf, strerror(errno) );
+ return -1;
+ }
+ } else {
+ return -1;
+ }
}
memcpy( si.sdt_creator, creator, sizeof( CreatorType ));
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 ) {
- cc = AFPERR_PARAM;
- goto addicon_err;
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
+ cc = AFPERR_PARAM;
+ goto addicon_err;
}
-
+
memcpy( fcreator, ibuf, sizeof( fcreator ));
ibuf += sizeof( fcreator );
-
+
memcpy( &ftype, ibuf, sizeof( ftype ));
ibuf += sizeof( ftype );
-
+
itype = (unsigned char) *ibuf;
ibuf += 2;
-
+
memcpy( &itag, ibuf, sizeof( itag ));
ibuf += sizeof( itag );
-
+
memcpy( &bsize, ibuf, sizeof( bsize ));
bsize = ntohs( bsize );
-
+
if ( si.sdt_fd != -1 ) {
- (void)close( si.sdt_fd );
- si.sdt_fd = -1;
+ (void)close( si.sdt_fd );
+ si.sdt_fd = -1;
}
if (iconopen( vol, fcreator, O_RDWR|O_CREAT, 0666 ) < 0) {
- cc = AFPERR_NOITEM;
- goto addicon_err;
+ cc = AFPERR_NOITEM;
+ goto addicon_err;
}
if (lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0) {
close(si.sdt_fd);
- si.sdt_fd = -1;
- syslog( LOG_ERR, "afp_addicon: lseek: %m" );
- cc = AFPERR_PARAM;
- goto addicon_err;
+ si.sdt_fd = -1;
+ LOG(log_error, logtype_afpd, "afp_addicon(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) );
+ cc = AFPERR_PARAM;
+ goto addicon_err;
}
/*
memcpy( p, &bsize, sizeof( bsize ));
bsize = ntohs( bsize );
while (( cc = read( si.sdt_fd, irh, sizeof( irh ))) > 0 ) {
- memcpy( &rsize, irh + 10, sizeof( rsize ));
- rsize = ntohs( rsize );
- /*
- * Is this our set of headers?
- */
- if ( memcmp( irh, imh, sizeof( irh ) - sizeof( u_short )) == 0 ) {
- /*
- * Is the size correct?
- */
- if ( bsize != rsize )
- cc = AFPERR_ITYPE;
- break;
- }
-
- if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
- syslog( LOG_ERR, "afp_addicon: lseek: %m" );
- cc = AFPERR_PARAM;
- }
+ memcpy( &rsize, irh + 10, sizeof( rsize ));
+ rsize = ntohs( rsize );
+ /*
+ * Is this our set of headers?
+ */
+ if ( memcmp( irh, imh, sizeof( irh ) - sizeof( u_short )) == 0 ) {
+ /*
+ * Is the size correct?
+ */
+ if ( bsize != rsize )
+ cc = AFPERR_ITYPE;
+ break;
+ }
+
+ if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
+ LOG(log_error, logtype_afpd, "afp_addicon(%s): lseek: %s", icon_dtfile(vol, fcreator),strerror(errno) );
+ cc = AFPERR_PARAM;
+ }
}
-
+
/*
* Some error occurred, return.
*/
addicon_err:
if ( cc < 0 ) {
- syslog( LOG_ERR, "afp_addicon: %m" );
- if (obj->proto == AFPPROTO_DSI) {
- dsi_writeinit(obj->handle, rbuf, buflen);
- dsi_writeflush(obj->handle);
- }
- return cc;
+ 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:
- buflen = bsize;
- if ((asp_wrtcont(obj->handle, rbuf, &buflen) < 0) || buflen != bsize)
- return( AFPERR_PARAM );
-
- if (obj->options.flags & OPTION_DEBUG) {
- printf("(write) len: %d\n", buflen);
- bprint(rbuf, buflen);
- }
-
- /*
- * We're at the end of the file, add the headers, etc. */
- if ( cc == 0 ) {
- iov[ 0 ].iov_base = (caddr_t)imh;
- iov[ 0 ].iov_len = sizeof( imh );
- iov[ 1 ].iov_base = rbuf;
- iov[ 1 ].iov_len = bsize;
- iovcnt = 2;
- }
-
- /*
- * We found an icon to replace.
- */
- if ( cc > 0 ) {
- iov[ 0 ].iov_base = rbuf;
- iov[ 0 ].iov_len = bsize;
- iovcnt = 1;
- }
-
- if ( writev( si.sdt_fd, iov, iovcnt ) < 0 ) {
- syslog( LOG_ERR, "afp_addicon: writev: %m" );
- return( AFPERR_PARAM );
- }
- break;
+ buflen = bsize;
+ 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 ( cc == 0 ) {
+ iov[ 0 ].iov_base = (caddr_t)imh;
+ iov[ 0 ].iov_len = sizeof( imh );
+ iov[ 1 ].iov_base = rbuf;
+ iov[ 1 ].iov_len = bsize;
+ iovcnt = 2;
+ }
+
+ /*
+ * We found an icon to replace.
+ */
+ if ( cc > 0 ) {
+ iov[ 0 ].iov_base = rbuf;
+ iov[ 0 ].iov_len = bsize;
+ iovcnt = 1;
+ }
+
+ if ( writev( si.sdt_fd, iov, iovcnt ) < 0 ) {
+ LOG(log_error, logtype_afpd, "afp_addicon(%s): writev: %s", icon_dtfile(vol, fcreator), strerror(errno) );
+ return( AFPERR_PARAM );
+ }
+ break;
#endif /* no afp/asp */
- case AFPPROTO_DSI:
- {
- DSI *dsi = obj->handle;
-
- iovcnt = dsi_writeinit(dsi, rbuf, buflen);
-
- /* add headers at end of file */
- if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) {
- syslog(LOG_ERR, "afp_addicon: write: %m");
- dsi_writeflush(dsi);
- return AFPERR_PARAM;
- }
-
- if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
- syslog(LOG_ERR, "afp_addicon: write: %m");
- dsi_writeflush(dsi);
- return AFPERR_PARAM;
- }
-
- while ((iovcnt = dsi_write(dsi, rbuf, buflen))) {
- if ( obj->options.flags & OPTION_DEBUG ) {
- printf("(write) command cont'd: %d\n", iovcnt);
- bprint(rbuf, iovcnt);
- }
-
- if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
- syslog(LOG_ERR, "afp_addicon: write: %m");
- dsi_writeflush(dsi);
- return AFPERR_PARAM;
- }
- }
- }
- break;
+ case AFPPROTO_DSI:
+ {
+ DSI *dsi = obj->handle;
+
+ iovcnt = dsi_writeinit(dsi, rbuf, buflen);
+
+ /* add headers at end of file */
+ if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) {
+ 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(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
+ dsi_writeflush(dsi);
+ return AFPERR_PARAM;
+ }
+
+ while ((iovcnt = dsi_write(dsi, rbuf, buflen))) {
+ if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
+ LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
+ dsi_writeflush(dsi);
+ return AFPERR_PARAM;
+ }
+ }
+ }
+ break;
}
close( si.sdt_fd );
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[] = {
-0x1F, 0xFF, 0xFC, 0x00, 0x10, 0x00, 0x06, 0x00,
-0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x04, 0x80,
-0x10, 0x00, 0x04, 0x40, 0x10, 0x00, 0x04, 0x20,
-0x10, 0x00, 0x07, 0xF0, 0x10, 0x00, 0x00, 0x10,
-0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,
-0x10, 0x00, 0x00, 0x10, 0x10, 0x80, 0x02, 0x10,
-0x11, 0x80, 0x03, 0x10, 0x12, 0x80, 0x02, 0x90,
-0x12, 0x80, 0x02, 0x90, 0x14, 0x80, 0x02, 0x50,
-0x14, 0x87, 0xC2, 0x50, 0x14, 0x58, 0x34, 0x50,
-0x14, 0x20, 0x08, 0x50, 0x12, 0x16, 0xD0, 0x90,
-0x11, 0x01, 0x01, 0x10, 0x12, 0x80, 0x02, 0x90,
-0x12, 0x9C, 0x72, 0x90, 0x14, 0x22, 0x88, 0x50,
-0x14, 0x41, 0x04, 0x50, 0x14, 0x49, 0x24, 0x50,
-0x14, 0x55, 0x54, 0x50, 0x14, 0x5D, 0x74, 0x50,
-0x14, 0x5D, 0x74, 0x50, 0x12, 0x49, 0x24, 0x90,
-0x12, 0x22, 0x88, 0x90, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFE, 0x00,
-0x1F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0x80,
-0x1F, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xE0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
-0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+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,
+ 0x10, 0x00, 0x07, 0xF0, 0x10, 0x00, 0x00, 0x10,
+ 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,
+ 0x10, 0x00, 0x00, 0x10, 0x10, 0x80, 0x02, 0x10,
+ 0x11, 0x80, 0x03, 0x10, 0x12, 0x80, 0x02, 0x90,
+ 0x12, 0x80, 0x02, 0x90, 0x14, 0x80, 0x02, 0x50,
+ 0x14, 0x87, 0xC2, 0x50, 0x14, 0x58, 0x34, 0x50,
+ 0x14, 0x20, 0x08, 0x50, 0x12, 0x16, 0xD0, 0x90,
+ 0x11, 0x01, 0x01, 0x10, 0x12, 0x80, 0x02, 0x90,
+ 0x12, 0x9C, 0x72, 0x90, 0x14, 0x22, 0x88, 0x50,
+ 0x14, 0x41, 0x04, 0x50, 0x14, 0x49, 0x24, 0x50,
+ 0x14, 0x55, 0x54, 0x50, 0x14, 0x5D, 0x74, 0x50,
+ 0x14, 0x5D, 0x74, 0x50, 0x12, 0x49, 0x24, 0x90,
+ 0x12, 0x22, 0x88, 0x90, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFE, 0x00,
+ 0x1F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0x80,
+ 0x1F, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xE0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
+ 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 ) {
- return( AFPERR_PARAM );
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
+ return( AFPERR_PARAM );
}
memcpy( fcreator, ibuf, sizeof( fcreator ));
iindex = ntohs( iindex );
if ( memcmp( fcreator, ucreator, sizeof( ucreator )) == 0 ) {
- if ( iindex > 1 ) {
- return( AFPERR_NOITEM );
- }
- memcpy( ih, utag, sizeof( utag ));
- memcpy( ih + sizeof( utag ), utype, sizeof( utype ));
- *( ih + sizeof( utag ) + sizeof( utype )) = 1;
- *( ih + sizeof( utag ) + sizeof( utype ) + 1 ) = 0;
- memcpy( ih + sizeof( utag ) + sizeof( utype ) + 2, &usize,
- sizeof( usize ));
- memcpy( rbuf, ih, sizeof( ih ));
- *rbuflen = sizeof( ih );
- return( AFP_OK );
+ if ( iindex > 1 ) {
+ return( AFPERR_NOITEM );
+ }
+ memcpy( ih, utag, sizeof( utag ));
+ memcpy( ih + sizeof( utag ), utype, sizeof( utype ));
+ *( ih + sizeof( utag ) + sizeof( utype )) = 1;
+ *( ih + sizeof( utag ) + sizeof( utype ) + 1 ) = 0;
+ memcpy( ih + sizeof( utag ) + sizeof( utype ) + 2, &usize,
+ sizeof( usize ));
+ memcpy( rbuf, ih, sizeof( ih ));
+ *rbuflen = sizeof( ih );
+ return( AFP_OK );
}
if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) {
- return( AFPERR_NOITEM );
+ return( AFPERR_NOITEM );
}
if ( iindex < si.sdt_index ) {
- if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) {
- return( AFPERR_PARAM );
- }
- si.sdt_index = 1;
+ if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) {
+ return( AFPERR_PARAM );
+ }
+ si.sdt_index = 1;
}
/*
* Position to the correct spot.
*/
for (;;) {
- if ( read( si.sdt_fd, ih, sizeof( ih )) != sizeof( ih )) {
- close( si.sdt_fd );
- si.sdt_fd = -1;
- return( AFPERR_NOITEM );
- }
- memcpy( &bsize, ih + 10, sizeof( bsize ));
- bsize = ntohs(bsize);
- if ( lseek( si.sdt_fd, (off_t) bsize, SEEK_CUR ) < 0 ) {
- syslog( LOG_ERR, "afp_iconinfo: lseek: %m" );
- return( AFPERR_PARAM );
- }
- if ( si.sdt_index == iindex ) {
- memcpy( rbuf, ih, sizeof( ih ));
- *rbuflen = sizeof( ih );
- return( AFP_OK );
- }
- si.sdt_index++;
+ if ( read( si.sdt_fd, ih, sizeof( ih )) != sizeof( ih )) {
+ close( si.sdt_fd );
+ si.sdt_fd = -1;
+ return( AFPERR_NOITEM );
+ }
+ 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(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) );
+ return( AFPERR_PARAM );
+ }
+ if ( si.sdt_index == iindex ) {
+ memcpy( rbuf, ih, sizeof( ih ));
+ *rbuflen = sizeof( ih );
+ return( AFP_OK );
+ }
+ si.sdt_index++;
}
}
-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 ) {
- return( AFPERR_PARAM );
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
+ return( AFPERR_PARAM );
}
memcpy( fcreator, ibuf, sizeof( fcreator ));
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 &&
- bsize <= usize ) {
- memcpy( rbuf, uicon, bsize);
- *rbuflen = bsize;
- return( AFP_OK );
+ memcmp( ftype, utype, sizeof( utype )) == 0 &&
+ itype == 1 &&
+ bsize <= usize ) {
+ memcpy( rbuf, uicon, bsize);
+ *rbuflen = bsize;
+ return( AFP_OK );
}
+#endif
if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) {
- return( AFPERR_NOITEM );
+ return( AFPERR_NOITEM );
}
if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) {
- close(si.sdt_fd);
- si.sdt_fd = -1;
- syslog(LOG_ERR, "afp_geticon: lseek: %m");
- return( AFPERR_PARAM );
+ close(si.sdt_fd);
+ si.sdt_fd = -1;
+ LOG(log_error, logtype_afpd, "afp_geticon(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno));
+ return( AFPERR_PARAM );
}
si.sdt_index = 1;
offset = 0;
while (( rc = read( si.sdt_fd, ih, sizeof( ih ))) > 0 ) {
- si.sdt_index++;
- offset += sizeof(ih);
- if ( memcmp( ih + sizeof( int ), ftype, sizeof( ftype )) == 0 &&
- *(ih + sizeof( int ) + sizeof( ftype )) == itype ) {
- break;
- }
- memcpy( &rsize, ih + 10, sizeof( rsize ));
- rsize = ntohs( rsize );
- if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
- syslog( LOG_ERR, "afp_geticon: lseek: %m" );
- return( AFPERR_PARAM );
- }
- offset += rsize;
+ si.sdt_index++;
+ offset += sizeof(ih);
+ if ( memcmp( ih + sizeof( int ), ftype, sizeof( ftype )) == 0 &&
+ *(ih + sizeof( int ) + sizeof( ftype )) == itype ) {
+ break;
+ }
+ 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(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) );
+ return( AFPERR_PARAM );
+ }
+ offset += rsize;
}
if ( rc < 0 ) {
- syslog(LOG_ERR, "afp_geticon: read: %m");
- return( AFPERR_PARAM );
+ LOG(log_error, logtype_afpd, "afp_geticon(%s): read: %s", icon_dtfile(vol, fcreator), strerror(errno));
+ return( AFPERR_PARAM );
}
if ( rc == 0 ) {
- return( AFPERR_NOITEM );
+ return( AFPERR_NOITEM );
}
memcpy( &rsize, ih + 10, sizeof( rsize ));
rc = min( bsize, rsize );
if ((obj->proto == AFPPROTO_DSI) && (buflen < rc)) {
- DSI *dsi = obj->handle;
- struct stat st;
- off_t size;
-
- size = (fstat(si.sdt_fd, &st) < 0) ? 0 : st.st_size;
- if (size < rc + offset) {
- return AFPERR_PARAM;
- }
-
- if ((*rbuflen = dsi_readinit(dsi, rbuf, buflen, rc, AFP_OK)) < 0)
- goto geticon_exit;
-
- /* 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)
- 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
-
-#ifdef SENDFILE_FLAVOR_BSD
- if (sendfile(si.sdt_fd, dsi->socket, offset, rc, NULL, NULL, 0) < 0)
- goto geticon_exit;
-#endif
-
- goto geticon_done;
- }
+ DSI *dsi = obj->handle;
+ struct stat st;
+ off_t size;
+
+ size = (fstat(si.sdt_fd, &st) < 0) ? 0 : st.st_size;
+ if (size < rc + offset) {
+ return AFPERR_PARAM;
+ }
+
+ 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) {
+#ifdef WITH_SENDFILE
+ if (!obj->options.flags & OPTION_DEBUG) {
+ 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
+ buflen = read(si.sdt_fd, rbuf, *rbuflen);
+ if (buflen < 0)
+ goto geticon_exit;
+
+ /* dsi_read() also returns buffer size of next allocation */
+ buflen = dsi_read(dsi, rbuf, buflen); /* send it off */
+ if (buflen < 0)
+ goto geticon_exit;
+
+ *rbuflen = buflen;
+ }
+
+ dsi_readdone(dsi);
+ return AFP_OK;
- 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)
- goto geticon_exit;
-
- *rbuflen = buflen;
- }
-
-geticon_done:
- dsi_readdone(dsi);
- return AFP_OK;
-
geticon_exit:
- syslog(LOG_INFO, "afp_geticon: %m");
- dsi_readdone(dsi);
- obj->exit(1);
+ LOG(log_info, logtype_afpd, "afp_geticon(%s): %s", icon_dtfile(vol, fcreator), strerror(errno));
+ dsi_readdone(dsi);
+ obj->exit(EXITERR_SYS);
+ return AFP_OK;
} else {
- if ( read( si.sdt_fd, rbuf, rc ) < rc ) {
- return( AFPERR_PARAM );
- }
- *rbuflen = rc;
- return AFP_OK;
+ if ( read( si.sdt_fd, rbuf, rc ) < rc ) {
+ return( AFPERR_PARAM );
+ }
+ *rbuflen = rc;
}
+ 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/" );
for ( p = path; *p != '\0'; p++ )
- ;
+ ;
if ( !isprint( creator[ 0 ] ) || creator[ 0 ] == '/' ) {
- *p++ = hexdig[ ( creator[ 0 ] & 0xf0 ) >> 4 ];
- *p++ = hexdig[ creator[ 0 ] & 0x0f ];
+ *p++ = hexdig[ ( creator[ 0 ] & 0xf0 ) >> 4 ];
+ *p++ = hexdig[ creator[ 0 ] & 0x0f ];
} else {
- *p++ = creator[ 0 ];
+ *p++ = creator[ 0 ];
}
*p++ = '/';
for ( i = 0; i < sizeof( CreatorType ); i++ ) {
- if ( !isprint( creator[ i ] ) || creator[ i ] == '/' ) {
- *p++ = hexdig[ ( creator[ i ] & 0xf0 ) >> 4 ];
- *p++ = hexdig[ creator[ i ] & 0x0f ];
- } else {
- *p++ = creator[ i ];
- }
+ if ( !isprint( creator[ i ] ) || creator[ i ] == '/' ) {
+ *p++ = hexdig[ ( creator[ i ] & 0xf0 ) >> 4 ];
+ *p++ = hexdig[ creator[ i ] & 0x0f ];
+ } else {
+ *p++ = creator[ i ];
+ }
}
*p = '\0';
strcat( path, ext );
return( path );
}
-char *mtoupath(const struct vol *vol, char *mpath)
-{
- static unsigned char upath[ MAXPATHLEN + 1];
- unsigned char *m, *u;
- int i = 0;
+/* ---------------------------
+ * 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 + 2]; /* for convert_charset dest_len parameter +2 */
+ char *m, *u;
+ size_t inplen;
+ size_t outlen;
+ u_int16_t flags;
+
if ( *mpath == '\0' ) {
- return( "." );
+ return( "." );
+ }
+
+ /* 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 0
- if (vol->v_mtoupage && ((*m > 0x7F) ||
- vol->v_flags & AFPVOL_MAPASCII)) {
- *u = vol->v_mtoupage[*m];
- } else
-#endif
-#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 ];
- } else
- *u = *m;
- u++;
- i++;
- m++;
- }
- *u = '\0';
+ inplen = strlen(m);
+ outlen = MAXPATHLEN;
+
+ if ((size_t)-1 == (outlen = convert_charset ( (utf8)?CH_UTF8_MAC:vol->v_maccharset, vol->v_volcharset, vol->v_maccharset, m, inplen, u, outlen, &flags)) ) {
+ LOG(log_error, logtype_afpd, "conversion from %s to %s for %s failed.", (utf8)?"UTF8-MAC":vol->v_maccodepage, vol->v_volcodepage, mpath);
+ return NULL;
+ }
+
+#ifdef DEBUG
+ LOG(log_debug9, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath);
+#endif /* DEBUG */
return( upath );
}
-#define hextoint( c ) ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
-#define islxdigit(x) (!isupper(x)&&isxdigit(x))
-
-char *utompath(const struct vol *vol, char *upath)
+/* ---------------
+ * id filename ID
+*/
+char *utompath(const struct vol *vol, char *upath, cnid_t id, int utf8)
{
- static unsigned char mpath[ MAXPATHLEN + 1];
- unsigned char *m, *u;
- int h;
+ static char mpath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */
+ char *m, *u;
+ u_int16_t flags;
+ size_t outlen;
- /* do the hex conversion */
- u = upath;
m = mpath;
- while ( *u != '\0' ) {
- /* we have a code page */
-#if 0
- if (vol->v_utompage && ((*u > 0x7F) ||
- (vol->v_flags & AFPVOL_MAPASCII))) {
- *m = vol->v_utompage[*u];
- } else
-#endif
- if ( *u == ':' && *(u+1) != '\0' && islxdigit( *(u+1)) &&
- *(u+2) != '\0' && islxdigit( *(u+2))) {
- ++u;
- h = hextoint( *u ) << 4;
- ++u;
- h |= hextoint( *u );
- *m = h;
- } else
- *m = *u;
-
- /* handle case conversion */
- if (vol->v_casefold & AFPVOL_UTOMLOWER)
- *m = diatolower( *m );
- else if (vol->v_casefold & AFPVOL_UTOMUPPER)
- *m = diatoupper( *m );
-
- u++;
- m++;
- }
- *m = '\0';
- return( mpath );
+ outlen = strlen(upath);
+
+ 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_debug9, logtype_afpd, "utompath: '%s':'%s':'%2.2X'", upath, m, ntohl(id));
+#endif /* DEBUG */
+ return(m);
+
+utompath_error:
+ u = "???";
+ m = mangle(vol, u, strlen(u), upath, id, (utf8)?3:1);
+ return(m);
}
-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 ofork *of;
+ char *name, *upath;
+ int isadir;
+ int clen;
struct adouble ad, *adp;
+
+ clen = (u_char)*ibuf++;
+ clen = min( clen, 199 );
+
+ upath = path->u_name;
+ if (!vol_unix_priv(vol) && 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_metadata( upath , vol_noadouble(vol) | ( (isadir) ? ADFLAGS_DIR :0),O_CREAT, adp) < 0 ) {
+ return( AFPERR_ACCESS );
+ }
+
+ 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_COMMENT, clen );
+ memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen );
+ ad_flush( adp );
+ }
+ ad_close_metadata( adp);
+ return( AFP_OK );
+}
+
+/* ----------------------------- */
+int afp_addcomment(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_, size_t *rbuflen)
+{
struct vol *vol;
struct dir *dir;
- struct ofork *of;
- char *path, *name;
- int clen;
+ struct path *path;
u_int32_t did;
u_int16_t vid;
memcpy( &vid, ibuf, sizeof( vid ));
ibuf += sizeof( vid );
- if (( vol = getvolbyvid( vid )) == NULL ) {
- return( AFPERR_PARAM );
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
+ return( AFPERR_PARAM );
}
memcpy( &did, ibuf, sizeof( did ));
ibuf += sizeof( did );
- if (( dir = dirsearch( vol, did )) == NULL ) {
- return( AFPERR_NOOBJ );
+ if (NULL == ( dir = dirlookup( vol, did )) ) {
+ return afp_errno;
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
- return( AFPERR_NOOBJ );
+ if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
+ return get_afp_errno(AFPERR_NOOBJ);
}
if ((u_long)ibuf & 1 ) {
- ibuf++;
+ ibuf++;
}
- clen = (u_char)*ibuf++;
- clen = min( clen, 199 );
+ return ad_addcomment(vol, path, ibuf);
+}
- if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
- memset(&ad, 0, sizeof(ad));
- adp = &ad;
+/* -------------------- */
+static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, size_t *rbuflen)
+{
+ struct adouble ad, *adp;
+ struct ofork *of;
+ char *upath;
+ int isadir;
+ int clen;
+
+ upath = path->u_name;
+ isadir = path_isadir(path);
+ if (isadir || !(of = of_findname(path))) {
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options);
+ adp = &ad;
} else
- adp = of->of_ad;
- if (ad_open( mtoupath( vol, path ), vol_noadouble(vol) |
- (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
- O_RDWR|O_CREAT, 0666, adp) < 0 ) {
- return( AFPERR_ACCESS );
- }
-
- if ( ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT ) {
- if ( *path == '\0' ) {
- name = curdir->d_name;
- } else {
- name = path;
- }
- 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, ADFLAGS_HF );
- ad_close( adp, ADFLAGS_HF );
+ adp = of->of_ad;
+
+ if ( ad_metadata( upath,vol_noadouble(vol) | ((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 ||
+ 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);
+
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;
- char *path;
+ struct path *s_path;
u_int32_t did;
u_int16_t vid;
-
+
*rbuflen = 0;
ibuf += 2;
memcpy( &vid, ibuf, sizeof( vid ));
ibuf += sizeof( vid );
- if (( vol = getvolbyvid( vid )) == NULL ) {
- return( AFPERR_PARAM );
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
+ return( AFPERR_PARAM );
}
memcpy( &did, ibuf, sizeof( did ));
ibuf += sizeof( did );
- if (( dir = dirsearch( vol, did )) == NULL ) {
- return( AFPERR_NOOBJ );
+ if (NULL == ( dir = dirlookup( vol, did )) ) {
+ return afp_errno;
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
- return( AFPERR_NOOBJ );
+ if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
+ return get_afp_errno(AFPERR_NOOBJ);
}
- if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
- memset(&ad, 0, sizeof(ad));
- adp = &ad;
- } else
- adp = of->of_ad;
- if ( ad_open( mtoupath( vol, path ),
- (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
- O_RDONLY, 0666, adp) < 0 ) {
- return( AFPERR_NOITEM );
+ 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;
}
- /*
- * 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 );
+ 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, 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 );
+ 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;
- char *path;
+ struct path *s_path;
u_int32_t did;
u_int16_t vid;
memcpy( &vid, ibuf, sizeof( vid ));
ibuf += sizeof( vid );
- if (( vol = getvolbyvid( vid )) == NULL ) {
- return( AFPERR_PARAM );
+ if (NULL == ( vol = getvolbyvid( vid )) ) {
+ return( AFPERR_PARAM );
}
memcpy( &did, ibuf, sizeof( did ));
ibuf += sizeof( did );
- if (( dir = dirsearch( vol, did )) == NULL ) {
- return( AFPERR_NOOBJ );
+ if (NULL == ( dir = dirlookup( vol, did )) ) {
+ return afp_errno;
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
- return( AFPERR_NOOBJ );
+ if (NULL == ( s_path = cname( vol, dir, &ibuf ))) {
+ return get_afp_errno(AFPERR_NOOBJ);
}
-
- if ((*path == '\0') || !(of = of_findname(vol, curdir, path))) {
- memset(&ad, 0, sizeof(ad));
- adp = &ad;
- } else
- adp = of->of_ad;
- if ( ad_open( mtoupath( vol, path ),
- (( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
- O_RDWR, 0, adp) < 0 ) {
- 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);
}