2 * $Id: desktop.c,v 1.26.2.4.2.18.2.8 2009-01-13 01:05:53 didg Exp $
7 * afp_XXXcomment are (the only) functions able to open
8 * a ressource fork when there's no data fork, eg after
9 * it was removed with samba.
14 #endif /* HAVE_CONFIG_H */
23 #include <atalk/adouble.h>
25 #include <sys/param.h>
26 #include <sys/socket.h>
27 #include <netatalk/at.h>
28 #include <netatalk/endian.h>
29 #include <atalk/dsi.h>
30 #include <atalk/atp.h>
31 #include <atalk/asp.h>
32 #include <atalk/afp.h>
33 #include <atalk/util.h>
34 #include <atalk/logger.h>
36 #include "directory.h"
43 int afp_opendt(obj, ibuf, ibuflen, rbuf, rbuflen )
46 int ibuflen _U_, *rbuflen;
53 memcpy( &vid, ibuf, sizeof(vid));
54 if (NULL == ( vol = getvolbyvid( vid )) ) {
56 return( AFPERR_PARAM );
59 memcpy( rbuf, &vid, sizeof(vid));
60 *rbuflen = sizeof(vid);
64 int afp_closedt(obj, ibuf, ibuflen, rbuf, rbuflen )
66 char *ibuf _U_, *rbuf _U_;
67 int ibuflen _U_, *rbuflen;
73 struct savedt si = { { 0, 0, 0, 0 }, -1, 0, 0 };
75 static char *icon_dtfile(struct vol *vol, u_char creator[ 4 ])
77 return dtfile( vol, creator, ".icon" );
80 static int iconopen( vol, creator, flags, mode )
86 char *dtf, *adt, *adts;
88 if ( si.sdt_fd != -1 ) {
89 if ( memcmp( si.sdt_creator, creator, sizeof( CreatorType )) == 0 &&
90 si.sdt_vid == vol->v_vid ) {
97 dtf = icon_dtfile( vol, creator);
99 if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
100 if ( errno == ENOENT && ( flags & O_CREAT )) {
101 if (( adts = strrchr( dtf, '/' )) == NULL ) {
105 if (( adt = strrchr( dtf, '/' )) == NULL ) {
109 (void) ad_mkdir( dtf, DIRBITS | 0777 );
111 (void) ad_mkdir( dtf, DIRBITS | 0777 );
114 if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
115 LOG(log_error, logtype_afpd, "iconopen(%s): open: %s", dtf, strerror(errno) );
123 memcpy( si.sdt_creator, creator, sizeof( CreatorType ));
124 si.sdt_vid = vol->v_vid;
129 int afp_addicon(obj, ibuf, ibuflen, rbuf, rbuflen)
132 int ibuflen _U_, *rbuflen;
136 struct iovec iov[ 2 ];
138 u_char fcreator[ 4 ], imh[ 12 ], irh[ 12 ], *p;
139 int itype, cc = AFP_OK, iovcnt = 0, buflen;
140 u_int32_t ftype, itag;
141 u_int16_t bsize, rsize, vid;
147 memcpy( &vid, ibuf, sizeof( vid ));
148 ibuf += sizeof( vid );
149 if (NULL == ( vol = getvolbyvid( vid )) ) {
154 memcpy( fcreator, ibuf, sizeof( fcreator ));
155 ibuf += sizeof( fcreator );
157 memcpy( &ftype, ibuf, sizeof( ftype ));
158 ibuf += sizeof( ftype );
160 itype = (unsigned char) *ibuf;
163 memcpy( &itag, ibuf, sizeof( itag ));
164 ibuf += sizeof( itag );
166 memcpy( &bsize, ibuf, sizeof( bsize ));
167 bsize = ntohs( bsize );
169 if ( si.sdt_fd != -1 ) {
170 (void)close( si.sdt_fd );
174 if (iconopen( vol, fcreator, O_RDWR|O_CREAT, 0666 ) < 0) {
179 if (lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0) {
182 LOG(log_error, logtype_afpd, "afp_addicon(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) );
188 * Read icon elements until we find a match to replace, or
189 * we get to the end to insert.
192 memcpy( p, &itag, sizeof( itag ));
194 memcpy( p, &ftype, sizeof( ftype ));
195 p += sizeof( ftype );
198 bsize = htons( bsize );
199 memcpy( p, &bsize, sizeof( bsize ));
200 bsize = ntohs( bsize );
201 while (( cc = read( si.sdt_fd, irh, sizeof( irh ))) > 0 ) {
202 memcpy( &rsize, irh + 10, sizeof( rsize ));
203 rsize = ntohs( rsize );
205 * Is this our set of headers?
207 if ( memcmp( irh, imh, sizeof( irh ) - sizeof( u_short )) == 0 ) {
209 * Is the size correct?
211 if ( bsize != rsize )
216 if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
217 LOG(log_error, logtype_afpd, "afp_addicon(%s): lseek: %s", icon_dtfile(vol, fcreator),strerror(errno) );
223 * Some error occurred, return.
227 if (obj->proto == AFPPROTO_DSI) {
228 dsi_writeinit(obj->handle, rbuf, buflen);
229 dsi_writeflush(obj->handle);
234 switch (obj->proto) {
238 if ((asp_wrtcont(obj->handle, rbuf, &buflen) < 0) || buflen != bsize)
239 return( AFPERR_PARAM );
242 if (obj->options.flags & OPTION_DEBUG) {
243 printf("(write) len: %d\n", buflen);
244 bprint(rbuf, buflen);
249 * We're at the end of the file, add the headers, etc. */
251 iov[ 0 ].iov_base = (caddr_t)imh;
252 iov[ 0 ].iov_len = sizeof( imh );
253 iov[ 1 ].iov_base = rbuf;
254 iov[ 1 ].iov_len = bsize;
259 * We found an icon to replace.
262 iov[ 0 ].iov_base = rbuf;
263 iov[ 0 ].iov_len = bsize;
267 if ( writev( si.sdt_fd, iov, iovcnt ) < 0 ) {
268 LOG(log_error, logtype_afpd, "afp_addicon(%s): writev: %s", icon_dtfile(vol, fcreator), strerror(errno) );
269 return( AFPERR_PARAM );
272 #endif /* no afp/asp */
275 DSI *dsi = obj->handle;
277 iovcnt = dsi_writeinit(dsi, rbuf, buflen);
279 /* add headers at end of file */
280 if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) {
281 LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
286 if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
287 LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
292 while ((iovcnt = dsi_write(dsi, rbuf, buflen))) {
294 if ( obj->options.flags & OPTION_DEBUG ) {
295 printf("(write) command cont'd: %d\n", iovcnt);
296 bprint(rbuf, iovcnt);
299 if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
300 LOG(log_error, logtype_afpd, "afp_addicon(%s): write: %s", icon_dtfile(vol, fcreator), strerror(errno));
314 static const u_char utag[] = { 0, 0, 0, 0 };
315 static const u_char ucreator[] = { 0, 0, 0, 0 };/* { 'U', 'N', 'I', 'X' };*/
316 static const u_char utype[] = { 0, 0, 0, 0 };/* { 'T', 'E', 'X', 'T' };*/
317 static const short usize = 256;
320 static const u_char uicon[] = {
321 0x1F, 0xFF, 0xFC, 0x00, 0x10, 0x00, 0x06, 0x00,
322 0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x04, 0x80,
323 0x10, 0x00, 0x04, 0x40, 0x10, 0x00, 0x04, 0x20,
324 0x10, 0x00, 0x07, 0xF0, 0x10, 0x00, 0x00, 0x10,
325 0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,
326 0x10, 0x00, 0x00, 0x10, 0x10, 0x80, 0x02, 0x10,
327 0x11, 0x80, 0x03, 0x10, 0x12, 0x80, 0x02, 0x90,
328 0x12, 0x80, 0x02, 0x90, 0x14, 0x80, 0x02, 0x50,
329 0x14, 0x87, 0xC2, 0x50, 0x14, 0x58, 0x34, 0x50,
330 0x14, 0x20, 0x08, 0x50, 0x12, 0x16, 0xD0, 0x90,
331 0x11, 0x01, 0x01, 0x10, 0x12, 0x80, 0x02, 0x90,
332 0x12, 0x9C, 0x72, 0x90, 0x14, 0x22, 0x88, 0x50,
333 0x14, 0x41, 0x04, 0x50, 0x14, 0x49, 0x24, 0x50,
334 0x14, 0x55, 0x54, 0x50, 0x14, 0x5D, 0x74, 0x50,
335 0x14, 0x5D, 0x74, 0x50, 0x12, 0x49, 0x24, 0x90,
336 0x12, 0x22, 0x88, 0x90, 0x1F, 0xFF, 0xFF, 0xF0,
337 0x1F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFE, 0x00,
338 0x1F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0x80,
339 0x1F, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xE0,
340 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
341 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
342 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
343 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
344 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
345 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
346 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
347 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
348 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
349 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
350 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
351 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
352 0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
356 int afp_geticoninfo(obj, ibuf, ibuflen, rbuf, rbuflen )
359 int ibuflen _U_, *rbuflen;
362 u_char fcreator[ 4 ], ih[ 12 ];
363 u_int16_t vid, iindex, bsize;
368 memcpy( &vid, ibuf, sizeof( vid ));
369 ibuf += sizeof( vid );
370 if (NULL == ( vol = getvolbyvid( vid )) ) {
371 return( AFPERR_PARAM );
374 memcpy( fcreator, ibuf, sizeof( fcreator ));
375 ibuf += sizeof( fcreator );
376 memcpy( &iindex, ibuf, sizeof( iindex ));
377 iindex = ntohs( iindex );
379 if ( memcmp( fcreator, ucreator, sizeof( ucreator )) == 0 ) {
381 return( AFPERR_NOITEM );
383 memcpy( ih, utag, sizeof( utag ));
384 memcpy( ih + sizeof( utag ), utype, sizeof( utype ));
385 *( ih + sizeof( utag ) + sizeof( utype )) = 1;
386 *( ih + sizeof( utag ) + sizeof( utype ) + 1 ) = 0;
387 memcpy( ih + sizeof( utag ) + sizeof( utype ) + 2, &usize,
389 memcpy( rbuf, ih, sizeof( ih ));
390 *rbuflen = sizeof( ih );
394 if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) {
395 return( AFPERR_NOITEM );
398 if ( iindex < si.sdt_index ) {
399 if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) {
400 return( AFPERR_PARAM );
406 * Position to the correct spot.
409 if ( read( si.sdt_fd, ih, sizeof( ih )) != sizeof( ih )) {
412 return( AFPERR_NOITEM );
414 memcpy( &bsize, ih + 10, sizeof( bsize ));
415 bsize = ntohs(bsize);
416 if ( lseek( si.sdt_fd, (off_t) bsize, SEEK_CUR ) < 0 ) {
417 LOG(log_error, logtype_afpd, "afp_iconinfo(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) );
418 return( AFPERR_PARAM );
420 if ( si.sdt_index == iindex ) {
421 memcpy( rbuf, ih, sizeof( ih ));
422 *rbuflen = sizeof( ih );
430 int afp_geticon(obj, ibuf, ibuflen, rbuf, rbuflen )
433 int ibuflen _U_, *rbuflen;
438 u_char fcreator[ 4 ], ftype[ 4 ], itype, ih[ 12 ];
439 u_int16_t vid, bsize, rsize;
445 memcpy( &vid, ibuf, sizeof( vid ));
446 ibuf += sizeof( vid );
447 if (NULL == ( vol = getvolbyvid( vid )) ) {
448 return( AFPERR_PARAM );
451 memcpy( fcreator, ibuf, sizeof( fcreator ));
452 ibuf += sizeof( fcreator );
453 memcpy( ftype, ibuf, sizeof( ftype ));
454 ibuf += sizeof( ftype );
455 itype = (unsigned char) *ibuf++;
457 memcpy( &bsize, ibuf, sizeof( bsize ));
458 bsize = ntohs( bsize );
461 if ( memcmp( fcreator, ucreator, sizeof( ucreator )) == 0 &&
462 memcmp( ftype, utype, sizeof( utype )) == 0 &&
465 memcpy( rbuf, uicon, bsize);
471 if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) {
472 return( AFPERR_NOITEM );
475 if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) {
478 LOG(log_error, logtype_afpd, "afp_geticon(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno));
479 return( AFPERR_PARAM );
484 while (( rc = read( si.sdt_fd, ih, sizeof( ih ))) > 0 ) {
486 offset += sizeof(ih);
487 if ( memcmp( ih + sizeof( int ), ftype, sizeof( ftype )) == 0 &&
488 *(ih + sizeof( int ) + sizeof( ftype )) == itype ) {
491 memcpy( &rsize, ih + 10, sizeof( rsize ));
492 rsize = ntohs( rsize );
493 if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
494 LOG(log_error, logtype_afpd, "afp_geticon(%s): lseek: %s", icon_dtfile(vol, fcreator), strerror(errno) );
495 return( AFPERR_PARAM );
501 LOG(log_error, logtype_afpd, "afp_geticon(%s): read: %s", icon_dtfile(vol, fcreator), strerror(errno));
502 return( AFPERR_PARAM );
506 return( AFPERR_NOITEM );
509 memcpy( &rsize, ih + 10, sizeof( rsize ));
510 rsize = ntohs( rsize );
511 #define min(a,b) ((a)<(b)?(a):(b))
512 rc = min( bsize, rsize );
514 if ((obj->proto == AFPPROTO_DSI) && (buflen < rc)) {
515 DSI *dsi = obj->handle;
519 size = (fstat(si.sdt_fd, &st) < 0) ? 0 : st.st_size;
520 if (size < rc + offset) {
524 if ((*rbuflen = dsi_readinit(dsi, rbuf, buflen, rc, AFP_OK)) < 0)
527 /* do to the streaming nature, we have to exit if we encounter
528 * a problem. much confusion results otherwise. */
529 while (*rbuflen > 0) {
531 if (!obj->options.flags & OPTION_DEBUG) {
532 if (sys_sendfile(dsi->socket, si.sdt_fd, &offset, dsi->datasize) < 0) {
535 case EINVAL: /* there's no guarantee that all fs support sendfile */
544 buflen = read(si.sdt_fd, rbuf, *rbuflen);
549 if (obj->options.flags & OPTION_DEBUG) {
550 printf( "(read) reply: %d, %d\n", buflen, dsi->clientID);
551 bprint(rbuf, buflen);
554 /* dsi_read() also returns buffer size of next allocation */
555 buflen = dsi_read(dsi, rbuf, buflen); /* send it off */
567 LOG(log_info, logtype_afpd, "afp_geticon(%s): %s", icon_dtfile(vol, fcreator), strerror(errno));
569 obj->exit(EXITERR_SYS);
573 if ( read( si.sdt_fd, rbuf, rc ) < rc ) {
574 return( AFPERR_PARAM );
581 /* ---------------------- */
582 static const char hexdig[] = "0123456789abcdef";
583 char *dtfile(const struct vol *vol, u_char creator[], char *ext )
585 static char path[ MAXPATHLEN + 1];
589 strcpy( path, vol->v_path );
590 strcat( path, "/.AppleDesktop/" );
591 for ( p = path; *p != '\0'; p++ )
594 if ( !isprint( creator[ 0 ] ) || creator[ 0 ] == '/' ) {
595 *p++ = hexdig[ ( creator[ 0 ] & 0xf0 ) >> 4 ];
596 *p++ = hexdig[ creator[ 0 ] & 0x0f ];
603 for ( i = 0; i < sizeof( CreatorType ); i++ ) {
604 if ( !isprint( creator[ i ] ) || creator[ i ] == '/' ) {
605 *p++ = hexdig[ ( creator[ i ] & 0xf0 ) >> 4 ];
606 *p++ = hexdig[ creator[ i ] & 0x0f ];
617 /* ---------------------------
618 * mpath is only a filename
619 * did filename parent directory ID.
621 static char upath[ MAXPATHLEN + 2]; /* for convert_charset dest_len parameter +2 */
622 static char mpath[ MAXPATHLEN + 2];/* for convert_charset dest_len parameter +2 */
624 char *mtoupath(const struct vol *vol, char *mpath, cnid_t did, int utf8)
631 if ( *mpath == '\0' ) {
635 /* set conversion flags */
636 if (!(vol->v_flags & AFPVOL_NOHEX))
637 flags |= CONV_ESCAPEHEX;
638 if (!(vol->v_flags & AFPVOL_USEDOTS))
639 flags |= CONV_ESCAPEDOTS;
641 if (vol->v_casefold & AFPVOL_MTOUUPPER)
642 flags |= CONV_TOUPPER;
643 else if (vol->v_casefold & AFPVOL_MTOULOWER)
644 flags |= CONV_TOLOWER;
646 if (vol->v_flags & AFPVOL_EILSEQ) {
647 flags |= CONV__EILSEQ;
650 m = demangle(vol, mpath, did);
661 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)) ) {
662 LOG(log_error, logtype_afpd, "conversion from %s to %s for %s failed.", (utf8)?"UTF8-MAC":vol->v_maccodepage, vol->v_volcodepage, mpath);
667 LOG(log_debug, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath);
675 char *utompath(const struct vol *vol, char *upath, cnid_t id, int utf8)
678 u_int16_t flags = CONV_IGNORE | CONV_UNESCAPEHEX;
682 outlen = strlen(upath);
684 if ((vol->v_casefold & AFPVOL_UTOMUPPER))
685 flags |= CONV_TOUPPER;
686 else if ((vol->v_casefold & AFPVOL_UTOMLOWER))
687 flags |= CONV_TOLOWER;
689 if (vol->v_flags & AFPVOL_EILSEQ) {
690 flags |= CONV__EILSEQ;
695 /* convert charsets */
696 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)) ) {
697 LOG(log_error, logtype_afpd, "Conversion from %s to %s for %s (%u) failed.", vol->v_volcodepage, vol->v_maccodepage, u, ntohl(id));
701 if (!(flags & CONV_REQMANGLE))
709 m = mangle(vol, mpath, outlen, upath, id, flags);
712 LOG(log_debug, logtype_afpd, "utompath: '%s':'%s':'%2.2X'", upath, m, ntohl(id));
718 m = mangle(vol, u, strlen(u), upath, id, (utf8)?3:1);
722 /* ------------------------- */
723 static int ad_addcomment(struct vol *vol, struct path *path, char *ibuf)
729 struct adouble ad, *adp;
731 clen = (u_char)*ibuf++;
732 clen = min( clen, 199 );
734 upath = path->u_name;
735 if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
736 return AFPERR_ACCESS;
739 isadir = path_isadir(path);
740 if (isadir || !(of = of_findname(path))) {
741 ad_init(&ad, vol->v_adouble, vol->v_ad_options);
746 if (ad_open( upath , vol_noadouble(vol) |
747 (( isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
748 O_RDWR|O_CREAT, 0666, adp) < 0 ) {
749 return( AFPERR_ACCESS );
752 if (ad_getentryoff(adp, ADEID_COMMENT)) {
753 if ( (ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT) ) {
754 if ( *path->m_name == '\0' ) {
755 name = curdir->d_m_name;
759 ad_setname(adp, name);
761 ad_setentrylen( adp, ADEID_COMMENT, clen );
762 memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen );
763 ad_flush( adp, ADFLAGS_HF );
765 ad_close( adp, ADFLAGS_HF );
769 /* ----------------------------- */
770 int afp_addcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
772 char *ibuf, *rbuf _U_;
773 int ibuflen _U_, *rbuflen;
784 memcpy( &vid, ibuf, sizeof( vid ));
785 ibuf += sizeof( vid );
786 if (NULL == ( vol = getvolbyvid( vid )) ) {
787 return( AFPERR_PARAM );
790 memcpy( &did, ibuf, sizeof( did ));
791 ibuf += sizeof( did );
792 if (NULL == ( dir = dirlookup( vol, did )) ) {
796 if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
797 return get_afp_errno(AFPERR_NOOBJ);
800 if ((u_long)ibuf & 1 ) {
804 return ad_addcomment(vol, path, ibuf);
807 /* -------------------- */
808 static int ad_getcomment(struct vol *vol, struct path *path, char *rbuf, int *rbuflen)
810 struct adouble ad, *adp;
816 upath = path->u_name;
817 isadir = path_isadir(path);
818 if (isadir || !(of = of_findname(path))) {
819 ad_init(&ad, vol->v_adouble, vol->v_ad_options);
824 if ( ad_metadata( upath,( isadir) ? ADFLAGS_DIR : 0, adp) < 0 ) {
825 return( AFPERR_NOITEM );
828 if (!ad_getentryoff(adp, ADEID_COMMENT)) {
829 ad_close( adp, ADFLAGS_HF );
830 return AFPERR_NOITEM;
833 * Make sure the AD file is not bogus.
835 if ( ad_getentrylen( adp, ADEID_COMMENT ) <= 0 ||
836 ad_getentrylen( adp, ADEID_COMMENT ) > 199 ) {
837 ad_close( adp, ADFLAGS_HF );
838 return( AFPERR_NOITEM );
841 clen = min( ad_getentrylen( adp, ADEID_COMMENT ), 128 ); /* OSX only use 128, greater kill Adobe CS2 */
843 memcpy( rbuf, ad_entry( adp, ADEID_COMMENT ), clen);
845 ad_close( adp, ADFLAGS_HF );
850 /* -------------------- */
851 int afp_getcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
854 int ibuflen _U_, *rbuflen;
865 memcpy( &vid, ibuf, sizeof( vid ));
866 ibuf += sizeof( vid );
867 if (NULL == ( vol = getvolbyvid( vid )) ) {
868 return( AFPERR_PARAM );
871 memcpy( &did, ibuf, sizeof( did ));
872 ibuf += sizeof( did );
873 if (NULL == ( dir = dirlookup( vol, did )) ) {
877 if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) {
878 return get_afp_errno(AFPERR_NOOBJ);
881 return ad_getcomment(vol, s_path, rbuf, rbuflen);
884 /* ----------------------- */
885 static int ad_rmvcomment(struct vol *vol, struct path *path)
887 struct adouble ad, *adp;
892 upath = path->u_name;
893 if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
894 return AFPERR_ACCESS;
897 isadir = path_isadir(path);
898 if (isadir || !(of = of_findname(path))) {
899 ad_init(&ad, vol->v_adouble, vol->v_ad_options);
905 (isadir) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF,
906 O_RDWR, 0, adp) < 0 ) {
909 return( AFPERR_NOITEM );
911 return( AFPERR_ACCESS );
913 return( AFPERR_PARAM );
917 if (ad_getentryoff(adp, ADEID_COMMENT)) {
918 ad_setentrylen( adp, ADEID_COMMENT, 0 );
919 ad_flush( adp, ADFLAGS_HF );
921 ad_close( adp, ADFLAGS_HF );
925 /* ----------------------- */
926 int afp_rmvcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
928 char *ibuf, *rbuf _U_;
929 int ibuflen _U_, *rbuflen;
940 memcpy( &vid, ibuf, sizeof( vid ));
941 ibuf += sizeof( vid );
942 if (NULL == ( vol = getvolbyvid( vid )) ) {
943 return( AFPERR_PARAM );
946 memcpy( &did, ibuf, sizeof( did ));
947 ibuf += sizeof( did );
948 if (NULL == ( dir = dirlookup( vol, did )) ) {
952 if (NULL == ( s_path = cname( vol, dir, &ibuf ))) {
953 return get_afp_errno(AFPERR_NOOBJ);
956 return ad_rmvcomment(vol, s_path);