2
* $Id: desktop.c,v 1.18 2002/10/05 14:04:47 didg Exp $
9
#endif /* HAVE_CONFIG_H */
11
#include <atalk/logger.h>
13
#include <sys/types.h>
16
#include <sys/param.h>
18
#include <sys/socket.h>
19
#include <netatalk/at.h>
20
#include <netatalk/endian.h>
21
#include <atalk/dsi.h>
22
#include <atalk/atp.h>
23
#include <atalk/asp.h>
24
#include <atalk/afp.h>
25
#include <atalk/adouble.h>
26
#include <atalk/util.h>
30
#endif /* HAVE_FCNTL_H */
36
#endif /* HAVE_FCNTL_H */
39
#include "directory.h"
47
int afp_opendt(obj, ibuf, ibuflen, rbuf, rbuflen )
50
int ibuflen, *rbuflen;
57
memcpy( &vid, ibuf, sizeof(vid));
58
if (( vol = getvolbyvid( vid )) == NULL ) {
60
return( AFPERR_PARAM );
63
memcpy( rbuf, &vid, sizeof(vid));
64
*rbuflen = sizeof(vid);
68
int afp_closedt(obj, ibuf, ibuflen, rbuf, rbuflen )
71
int ibuflen, *rbuflen;
77
struct savedt si = { { 0, 0, 0, 0 }, -1, 0 };
79
static int iconopen( vol, creator, flags, mode )
83
char *dtf, *adt, *adts;
85
if ( si.sdt_fd != -1 ) {
86
if ( memcmp( si.sdt_creator, creator, sizeof( CreatorType )) == 0 &&
87
si.sdt_vid == vol->v_vid ) {
94
dtf = dtfile( vol, creator, ".icon" );
96
if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
97
if ( errno == ENOENT && ( flags & O_CREAT )) {
98
if (( adts = strrchr( dtf, '/' )) == NULL ) {
102
if (( adt = strrchr( dtf, '/' )) == NULL ) {
106
(void) ad_mkdir( dtf, DIRBITS | 0777 );
108
(void) ad_mkdir( dtf, DIRBITS | 0777 );
111
if (( si.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
112
LOG(log_error, logtype_afpd, "iconopen: open %s: %s", dtf, strerror(errno) );
120
memcpy( si.sdt_creator, creator, sizeof( CreatorType ));
121
si.sdt_vid = vol->v_vid;
126
int afp_addicon(obj, ibuf, ibuflen, rbuf, rbuflen)
129
int ibuflen, *rbuflen;
132
struct iovec iov[ 2 ];
133
u_char fcreator[ 4 ], imh[ 12 ], irh[ 12 ], *p;
134
int itype, cc = AFP_OK, iovcnt = 0, buflen;
135
u_int32_t ftype, itag;
136
u_int16_t bsize, rsize, vid;
142
memcpy( &vid, ibuf, sizeof( vid ));
143
ibuf += sizeof( vid );
144
if (( vol = getvolbyvid( vid )) == NULL ) {
149
memcpy( fcreator, ibuf, sizeof( fcreator ));
150
ibuf += sizeof( fcreator );
152
memcpy( &ftype, ibuf, sizeof( ftype ));
153
ibuf += sizeof( ftype );
155
itype = (unsigned char) *ibuf;
158
memcpy( &itag, ibuf, sizeof( itag ));
159
ibuf += sizeof( itag );
161
memcpy( &bsize, ibuf, sizeof( bsize ));
162
bsize = ntohs( bsize );
164
if ( si.sdt_fd != -1 ) {
165
(void)close( si.sdt_fd );
169
if (iconopen( vol, fcreator, O_RDWR|O_CREAT, 0666 ) < 0) {
174
if (lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0) {
177
LOG(log_error, logtype_afpd, "afp_addicon: lseek: %s", strerror(errno) );
183
* Read icon elements until we find a match to replace, or
184
* we get to the end to insert.
187
memcpy( p, &itag, sizeof( itag ));
189
memcpy( p, &ftype, sizeof( ftype ));
190
p += sizeof( ftype );
193
bsize = htons( bsize );
194
memcpy( p, &bsize, sizeof( bsize ));
195
bsize = ntohs( bsize );
196
while (( cc = read( si.sdt_fd, irh, sizeof( irh ))) > 0 ) {
197
memcpy( &rsize, irh + 10, sizeof( rsize ));
198
rsize = ntohs( rsize );
200
* Is this our set of headers?
202
if ( memcmp( irh, imh, sizeof( irh ) - sizeof( u_short )) == 0 ) {
204
* Is the size correct?
206
if ( bsize != rsize )
211
if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
212
LOG(log_error, logtype_afpd, "afp_addicon: lseek: %s", strerror(errno) );
218
* Some error occurred, return.
222
LOG(log_error, logtype_afpd, "afp_addicon: %s", strerror(errno) );
223
if (obj->proto == AFPPROTO_DSI) {
224
dsi_writeinit(obj->handle, rbuf, buflen);
225
dsi_writeflush(obj->handle);
231
switch (obj->proto) {
235
if ((asp_wrtcont(obj->handle, rbuf, &buflen) < 0) || buflen != bsize)
236
return( AFPERR_PARAM );
238
if (obj->options.flags & OPTION_DEBUG) {
239
printf("(write) len: %d\n", buflen);
240
bprint(rbuf, buflen);
244
* We're at the end of the file, add the headers, etc. */
246
iov[ 0 ].iov_base = (caddr_t)imh;
247
iov[ 0 ].iov_len = sizeof( imh );
248
iov[ 1 ].iov_base = rbuf;
249
iov[ 1 ].iov_len = bsize;
254
* We found an icon to replace.
257
iov[ 0 ].iov_base = rbuf;
258
iov[ 0 ].iov_len = bsize;
262
if ( writev( si.sdt_fd, iov, iovcnt ) < 0 ) {
263
LOG(log_error, logtype_afpd, "afp_addicon: writev: %s", strerror(errno) );
264
return( AFPERR_PARAM );
267
#endif /* no afp/asp */
270
DSI *dsi = obj->handle;
272
iovcnt = dsi_writeinit(dsi, rbuf, buflen);
274
/* add headers at end of file */
275
if ((cc == 0) && (write(si.sdt_fd, imh, sizeof(imh)) < 0)) {
276
LOG(log_error, logtype_afpd, "afp_addicon: write: %s", strerror(errno));
281
if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
282
LOG(log_error, logtype_afpd, "afp_addicon: write: %s", strerror(errno));
287
while ((iovcnt = dsi_write(dsi, rbuf, buflen))) {
288
if ( obj->options.flags & OPTION_DEBUG ) {
289
printf("(write) command cont'd: %d\n", iovcnt);
290
bprint(rbuf, iovcnt);
293
if ((cc = write(si.sdt_fd, rbuf, iovcnt)) < 0) {
294
LOG(log_error, logtype_afpd, "afp_addicon: write: %s", strerror(errno));
308
u_char utag[] = { 0, 0, 0, 0 };
309
u_char ucreator[] = { 'U', 'N', 'I', 'X' };
310
u_char utype[] = { 'T', 'E', 'X', 'T' };
313
0x1F, 0xFF, 0xFC, 0x00, 0x10, 0x00, 0x06, 0x00,
314
0x10, 0x00, 0x05, 0x00, 0x10, 0x00, 0x04, 0x80,
315
0x10, 0x00, 0x04, 0x40, 0x10, 0x00, 0x04, 0x20,
316
0x10, 0x00, 0x07, 0xF0, 0x10, 0x00, 0x00, 0x10,
317
0x10, 0x00, 0x00, 0x10, 0x10, 0x00, 0x00, 0x10,
318
0x10, 0x00, 0x00, 0x10, 0x10, 0x80, 0x02, 0x10,
319
0x11, 0x80, 0x03, 0x10, 0x12, 0x80, 0x02, 0x90,
320
0x12, 0x80, 0x02, 0x90, 0x14, 0x80, 0x02, 0x50,
321
0x14, 0x87, 0xC2, 0x50, 0x14, 0x58, 0x34, 0x50,
322
0x14, 0x20, 0x08, 0x50, 0x12, 0x16, 0xD0, 0x90,
323
0x11, 0x01, 0x01, 0x10, 0x12, 0x80, 0x02, 0x90,
324
0x12, 0x9C, 0x72, 0x90, 0x14, 0x22, 0x88, 0x50,
325
0x14, 0x41, 0x04, 0x50, 0x14, 0x49, 0x24, 0x50,
326
0x14, 0x55, 0x54, 0x50, 0x14, 0x5D, 0x74, 0x50,
327
0x14, 0x5D, 0x74, 0x50, 0x12, 0x49, 0x24, 0x90,
328
0x12, 0x22, 0x88, 0x90, 0x1F, 0xFF, 0xFF, 0xF0,
329
0x1F, 0xFF, 0xFC, 0x00, 0x1F, 0xFF, 0xFE, 0x00,
330
0x1F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0x80,
331
0x1F, 0xFF, 0xFF, 0xC0, 0x1F, 0xFF, 0xFF, 0xE0,
332
0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
333
0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
334
0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
335
0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
336
0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
337
0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
338
0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
339
0x1F, 0xFF, 0xFF, 0xF0, 0x1F, 0xFF, 0xFF, 0xF0,
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,
347
int afp_geticoninfo(obj, ibuf, ibuflen, rbuf, rbuflen )
350
int ibuflen, *rbuflen;
353
u_char fcreator[ 4 ], ih[ 12 ];
354
u_int16_t vid, iindex, bsize;
359
memcpy( &vid, ibuf, sizeof( vid ));
360
ibuf += sizeof( vid );
361
if (( vol = getvolbyvid( vid )) == NULL ) {
362
return( AFPERR_PARAM );
365
memcpy( fcreator, ibuf, sizeof( fcreator ));
366
ibuf += sizeof( fcreator );
367
memcpy( &iindex, ibuf, sizeof( iindex ));
368
iindex = ntohs( iindex );
370
if ( memcmp( fcreator, ucreator, sizeof( ucreator )) == 0 ) {
372
return( AFPERR_NOITEM );
374
memcpy( ih, utag, sizeof( utag ));
375
memcpy( ih + sizeof( utag ), utype, sizeof( utype ));
376
*( ih + sizeof( utag ) + sizeof( utype )) = 1;
377
*( ih + sizeof( utag ) + sizeof( utype ) + 1 ) = 0;
378
memcpy( ih + sizeof( utag ) + sizeof( utype ) + 2, &usize,
380
memcpy( rbuf, ih, sizeof( ih ));
381
*rbuflen = sizeof( ih );
385
if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) {
386
return( AFPERR_NOITEM );
389
if ( iindex < si.sdt_index ) {
390
if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) {
391
return( AFPERR_PARAM );
397
* Position to the correct spot.
400
if ( read( si.sdt_fd, ih, sizeof( ih )) != sizeof( ih )) {
403
return( AFPERR_NOITEM );
405
memcpy( &bsize, ih + 10, sizeof( bsize ));
406
bsize = ntohs(bsize);
407
if ( lseek( si.sdt_fd, (off_t) bsize, SEEK_CUR ) < 0 ) {
408
LOG(log_error, logtype_afpd, "afp_iconinfo: lseek: %s", strerror(errno) );
409
return( AFPERR_PARAM );
411
if ( si.sdt_index == iindex ) {
412
memcpy( rbuf, ih, sizeof( ih ));
413
*rbuflen = sizeof( ih );
421
int afp_geticon(obj, ibuf, ibuflen, rbuf, rbuflen )
424
int ibuflen, *rbuflen;
429
u_char fcreator[ 4 ], ftype[ 4 ], itype, ih[ 12 ];
430
u_int16_t vid, bsize, rsize;
436
memcpy( &vid, ibuf, sizeof( vid ));
437
ibuf += sizeof( vid );
438
if (( vol = getvolbyvid( vid )) == NULL ) {
439
return( AFPERR_PARAM );
442
memcpy( fcreator, ibuf, sizeof( fcreator ));
443
ibuf += sizeof( fcreator );
444
memcpy( ftype, ibuf, sizeof( ftype ));
445
ibuf += sizeof( ftype );
446
itype = (unsigned char) *ibuf++;
448
memcpy( &bsize, ibuf, sizeof( bsize ));
449
bsize = ntohs( bsize );
451
if ( memcmp( fcreator, ucreator, sizeof( ucreator )) == 0 &&
452
memcmp( ftype, utype, sizeof( utype )) == 0 &&
455
memcpy( rbuf, uicon, bsize);
460
if ( iconopen( vol, fcreator, O_RDONLY, 0 ) < 0) {
461
return( AFPERR_NOITEM );
464
if ( lseek( si.sdt_fd, (off_t) 0L, SEEK_SET ) < 0 ) {
467
LOG(log_error, logtype_afpd, "afp_geticon: lseek: %s", strerror(errno));
468
return( AFPERR_PARAM );
473
while (( rc = read( si.sdt_fd, ih, sizeof( ih ))) > 0 ) {
475
offset += sizeof(ih);
476
if ( memcmp( ih + sizeof( int ), ftype, sizeof( ftype )) == 0 &&
477
*(ih + sizeof( int ) + sizeof( ftype )) == itype ) {
480
memcpy( &rsize, ih + 10, sizeof( rsize ));
481
rsize = ntohs( rsize );
482
if ( lseek( si.sdt_fd, (off_t) rsize, SEEK_CUR ) < 0 ) {
483
LOG(log_error, logtype_afpd, "afp_geticon: lseek: %s", strerror(errno) );
484
return( AFPERR_PARAM );
490
LOG(log_error, logtype_afpd, "afp_geticon: read: %s", strerror(errno));
491
return( AFPERR_PARAM );
495
return( AFPERR_NOITEM );
498
memcpy( &rsize, ih + 10, sizeof( rsize ));
499
rsize = ntohs( rsize );
500
#define min(a,b) ((a)<(b)?(a):(b))
501
rc = min( bsize, rsize );
503
if ((obj->proto == AFPPROTO_DSI) && (buflen < rc)) {
504
DSI *dsi = obj->handle;
508
size = (fstat(si.sdt_fd, &st) < 0) ? 0 : st.st_size;
509
if (size < rc + offset) {
513
if ((*rbuflen = dsi_readinit(dsi, rbuf, buflen, rc, AFP_OK)) < 0)
516
/* do to the streaming nature, we have to exit if we encounter
517
* a problem. much confusion results otherwise. */
518
while (*rbuflen > 0) {
519
#if defined(SENDFILE_FLAVOR_LINUX) || defined(SENDFILE_FLAVOR_BSD)
520
if (!obj->options.flags & OPTION_DEBUG) {
521
#ifdef SENDFILE_FLAVOR_LINUX
522
if (sendfile(dsi->socket, si.sdt_fd, &offset, dsi->datasize) < 0)
524
#endif /* SENDFILE_FLAVOR_LINUX */
526
#ifdef SENDFILE_FLAVOR_BSD
527
if (sendfile(si.sdt_fd, dsi->socket, offset, rc, NULL, NULL, 0) < 0)
529
#endif /* SENDFILE_FLAVOR_BSD */
533
#endif /* SENDFILE_FLAVOR_LINUX || SENDFILE_FLAVOR_BSD */
535
buflen = read(si.sdt_fd, rbuf, *rbuflen);
539
if (obj->options.flags & OPTION_DEBUG) {
540
printf( "(read) reply: %d, %d\n", buflen, dsi->clientID);
541
bprint(rbuf, buflen);
544
/* dsi_read() also returns buffer size of next allocation */
545
buflen = dsi_read(dsi, rbuf, buflen); /* send it off */
557
LOG(log_info, logtype_afpd, "afp_geticon: %s", strerror(errno));
563
if ( read( si.sdt_fd, rbuf, rc ) < rc ) {
564
return( AFPERR_PARAM );
572
static char hexdig[] = "0123456789abcdef";
573
char *dtfile(const struct vol *vol, u_char creator[], char *ext )
575
static char path[ MAXPATHLEN + 1];
579
strcpy( path, vol->v_path );
580
strcat( path, "/.AppleDesktop/" );
581
for ( p = path; *p != '\0'; p++ )
584
if ( !isprint( creator[ 0 ] ) || creator[ 0 ] == '/' ) {
585
*p++ = hexdig[ ( creator[ 0 ] & 0xf0 ) >> 4 ];
586
*p++ = hexdig[ creator[ 0 ] & 0x0f ];
593
for ( i = 0; i < sizeof( CreatorType ); i++ ) {
594
if ( !isprint( creator[ i ] ) || creator[ i ] == '/' ) {
595
*p++ = hexdig[ ( creator[ i ] & 0xf0 ) >> 4 ];
596
*p++ = hexdig[ creator[ i ] & 0x0f ];
607
char *mtoupath(const struct vol *vol, char *mpath)
609
static char upath[ MAXPATHLEN + 1];
613
if ( *mpath == '\0' ) {
618
mpath = demangle(vol, mpath);
619
#endif /* FILE_MANGLING */
623
while ( *m != '\0' ) {
624
/* handle case conversion first */
625
if (vol->v_casefold & AFPVOL_MTOUUPPER)
626
*m = diatoupper( *m );
627
else if (vol->v_casefold & AFPVOL_MTOULOWER)
628
*m = diatolower( *m );
630
/* we have a code page. we only use the ascii range
631
* if we have map ascii specified. */
633
if (vol->v_mtoupage && ((*m & 0x80) ||
634
vol->v_flags & AFPVOL_MAPASCII)) {
635
*u = vol->v_mtoupage->map[(unsigned char) *m].value;
637
/* if conversion failed, encode in hex
638
* to prevent silly truncation
639
* H.P. Jansen <hpj@urpla.net> */
641
LOG(log_debug, logtype_afpd, "mtoupath: hex encode: 0x%x", (unsigned char) *m);
644
*u++ = hexdig[ ( *m & 0xf0 ) >> 4 ];
645
*u = hexdig[ *m & 0x0f ];
649
#if AD_VERSION == AD_VERSION1
650
if ((((vol->v_flags & AFPVOL_NOHEX) == 0) &&
651
(!isascii(*m) || *m == '/')) ||
652
(((vol->v_flags & AFPVOL_USEDOTS) == 0) &&
653
( i == 0 && (*m == '.' )))) {
654
#else /* AD_VERSION == AD_VERSION1 */
655
if ((((vol->v_flags & AFPVOL_NOHEX) == 0) &&
656
(!isprint(*m) || *m == '/')) ||
657
(((vol->v_flags & AFPVOL_USEDOTS) == 0) &&
658
( i == 0 && (*m == '.' )))) {
659
#endif /* AD_VERSION == AD_VERSION1 */
660
/* do hex conversion. */
662
*u++ = hexdig[ ( *m & 0xf0 ) >> 4 ];
663
*u = hexdig[ *m & 0x0f ];
673
LOG(log_debug, logtype_afpd, "mtoupath: '%s':'%s'", mpath, upath);
679
#define hextoint( c ) ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
680
#define islxdigit(x) (!isupper(x)&&isxdigit(x))
682
char *utompath(const struct vol *vol, char *upath)
684
static char mpath[ MAXPATHLEN + 1];
688
/* do the hex conversion */
691
while ( *u != '\0' ) {
692
/* we have a code page */
694
if (vol->v_utompage && ((*u & 0x80) ||
695
(vol->v_flags & AFPVOL_MAPASCII))) {
696
*m = vol->v_utompage->map[(unsigned char) *u].value;
699
if ( *u == ':' && *(u+1) != '\0' && islxdigit( *(u+1)) &&
700
*(u+2) != '\0' && islxdigit( *(u+2))) {
702
h = hextoint( *u ) << 4;
709
/* handle case conversion */
710
if (vol->v_casefold & AFPVOL_UTOMLOWER)
711
*m = diatolower( *m );
712
else if (vol->v_casefold & AFPVOL_UTOMUPPER)
713
*m = diatoupper( *m );
721
strcpy(mpath,mangle(vol, mpath));
722
#endif /* FILE_MANGLING */
725
LOG(log_debug, logtype_afpd, "utompath: '%s':'%s'", upath, mpath);
731
int afp_addcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
734
int ibuflen, *rbuflen;
736
struct adouble ad, *adp;
740
char *path, *name, *upath;
748
memcpy( &vid, ibuf, sizeof( vid ));
749
ibuf += sizeof( vid );
750
if (( vol = getvolbyvid( vid )) == NULL ) {
751
return( AFPERR_PARAM );
754
memcpy( &did, ibuf, sizeof( did ));
755
ibuf += sizeof( did );
756
if (( dir = dirlookup( vol, did )) == NULL ) {
757
return( AFPERR_NOOBJ );
760
if (( path = cname( vol, dir, &ibuf )) == NULL ) {
761
return( AFPERR_NOOBJ );
764
if ((u_long)ibuf & 1 ) {
768
clen = (u_char)*ibuf++;
769
clen = min( clen, 199 );
770
upath = mtoupath( vol, path );
771
if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
772
memset(&ad, 0, sizeof(ad));
776
if (ad_open( upath , vol_noadouble(vol) |
777
(( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
778
O_RDWR|O_CREAT, 0666, adp) < 0 ) {
779
return( AFPERR_ACCESS );
782
if ( ad_getoflags( adp, ADFLAGS_HF ) & O_CREAT ) {
783
if ( *path == '\0' ) {
784
name = curdir->d_name;
788
ad_setentrylen( adp, ADEID_NAME, strlen( name ));
789
memcpy( ad_entry( adp, ADEID_NAME ), name,
790
ad_getentrylen( adp, ADEID_NAME ));
793
ad_setentrylen( adp, ADEID_COMMENT, clen );
794
memcpy( ad_entry( adp, ADEID_COMMENT ), ibuf, clen );
795
ad_flush( adp, ADFLAGS_HF );
796
ad_close( adp, ADFLAGS_HF );
800
int afp_getcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
803
int ibuflen, *rbuflen;
805
struct adouble ad, *adp;
816
memcpy( &vid, ibuf, sizeof( vid ));
817
ibuf += sizeof( vid );
818
if (( vol = getvolbyvid( vid )) == NULL ) {
819
return( AFPERR_PARAM );
822
memcpy( &did, ibuf, sizeof( did ));
823
ibuf += sizeof( did );
824
if (( dir = dirlookup( vol, did )) == NULL ) {
825
return( AFPERR_NOOBJ );
828
if (( path = cname( vol, dir, &ibuf )) == NULL ) {
829
return( AFPERR_NOOBJ );
833
upath = mtoupath( vol, path );
834
if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
835
memset(&ad, 0, sizeof(ad));
840
(( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
841
O_RDONLY, 0666, adp) < 0 ) {
842
return( AFPERR_NOITEM );
846
* Make sure the AD file is not bogus.
848
if ( ad_getentrylen( adp, ADEID_COMMENT ) < 0 ||
849
ad_getentrylen( adp, ADEID_COMMENT ) > 199 ) {
850
ad_close( adp, ADFLAGS_HF );
851
return( AFPERR_NOITEM );
854
*rbuf++ = ad_getentrylen( adp, ADEID_COMMENT );
855
memcpy( rbuf, ad_entry( adp, ADEID_COMMENT ),
856
ad_getentrylen( adp, ADEID_COMMENT ));
857
*rbuflen = ad_getentrylen( adp, ADEID_COMMENT ) + 1;
858
ad_close( adp, ADFLAGS_HF );
862
int afp_rmvcomment(obj, ibuf, ibuflen, rbuf, rbuflen )
865
int ibuflen, *rbuflen;
867
struct adouble ad, *adp;
878
memcpy( &vid, ibuf, sizeof( vid ));
879
ibuf += sizeof( vid );
880
if (( vol = getvolbyvid( vid )) == NULL ) {
881
return( AFPERR_PARAM );
884
memcpy( &did, ibuf, sizeof( did ));
885
ibuf += sizeof( did );
886
if (( dir = dirlookup( vol, did )) == NULL ) {
887
return( AFPERR_NOOBJ );
890
if (( path = cname( vol, dir, &ibuf )) == NULL ) {
891
return( AFPERR_NOOBJ );
894
upath = mtoupath( vol, path );
895
if ((*path == '\0') || !(of = of_findname(upath, NULL))) {
896
memset(&ad, 0, sizeof(ad));
902
(( *path == '\0' ) ? ADFLAGS_HF|ADFLAGS_DIR : ADFLAGS_HF),
903
O_RDWR, 0, adp) < 0 ) {
906
return( AFPERR_NOITEM );
908
return( AFPERR_ACCESS );
910
return( AFPERR_PARAM );
914
ad_setentrylen( adp, ADEID_COMMENT, 0 );
915
ad_flush( adp, ADFLAGS_HF );
916
ad_close( adp, ADFLAGS_HF );