2
* $Id: appl.c,v 1.7.2.1 2003/06/09 15:09:06 srittau Exp $
4
* Copyright (c) 1990,1993 Regents of The University of Michigan.
5
* All Rights Reserved. See COPYRIGHT.
10
#endif /* HAVE_CONFIG_H */
18
#endif /* HAVE_FCNTL_H */
21
#endif /* HAVE_UNISTD_H */
22
#include <sys/types.h>
24
#include <sys/param.h>
25
#include <atalk/logger.h>
28
#include <netatalk/endian.h>
29
#include <atalk/adouble.h>
30
#include <atalk/afp.h>
34
#include "directory.h"
38
static struct savedt sa = { { 0, 0, 0, 0 }, -1, 0 };
40
static __inline__ int pathcmp( p, plen, q, qlen )
46
return (( plen == qlen && memcmp( p, q, plen ) == 0 ) ? 0 : 1 );
49
static int applopen( vol, creator, flags, mode )
53
char *dtf, *adt, *adts;
55
if ( sa.sdt_fd != -1 ) {
56
if ( !(flags & ( O_RDWR | O_WRONLY )) &&
57
memcmp( sa.sdt_creator, creator, sizeof( CreatorType )) == 0 &&
58
sa.sdt_vid == vol->v_vid ) {
65
dtf = dtfile( vol, creator, ".appl" );
67
if (( sa.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
68
if ( errno == ENOENT && ( flags & O_CREAT )) {
69
if (( adts = strrchr( dtf, '/' )) == NULL ) {
70
return( AFPERR_PARAM );
73
if (( adt = strrchr( dtf, '/' )) == NULL ) {
74
return( AFPERR_PARAM );
77
(void) ad_mkdir( dtf, DIRBITS | 0777 );
79
(void) ad_mkdir( dtf, DIRBITS | 0777 );
82
if (( sa.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
83
return( AFPERR_PARAM );
86
return( AFPERR_PARAM );
89
memcpy( sa.sdt_creator, creator, sizeof( CreatorType ));
90
sa.sdt_vid = vol->v_vid;
96
* copy appls to new file, deleting any matching (old) appl entries
98
static int copyapplfile( sfd, dfd, mpath, mplen )
108
char buf[ MAXPATHLEN ];
110
while (( cc = read( sfd, buf, sizeof(appltag) + sizeof( u_short ))) > 0 ) {
111
p = buf + sizeof(appltag);
112
memcpy( &len, p, sizeof(len));
115
if (( cc = read( sa.sdt_fd, p, len )) < len ) {
118
if ( pathcmp( mpath, mplen, p, len ) != 0 ) {
120
if ( write( dfd, buf, p - buf ) != p - buf ) {
130
* build mac. path (backwards) by traversing the directory tree
132
* The old way: dir and path refer to an app, path is a mac format
133
* pathname. makemacpath() builds something that looks like a cname,
134
* but uses upaths instead of mac format paths.
136
* The new way: dir and path refer to an app, path is a mac format
137
* pathname. makemacpath() builds a cname.
139
* See afp_getappl() for the backward compatiblity code.
142
makemacpath( mpath, mpathlen, dir, path )
150
p = mpath + mpathlen;
152
strncpy( p, path, strlen( path ));
154
while ( dir->d_parent != NULL ) {
155
p -= strlen( dir->d_name ) + 1;
156
strcpy( p, dir->d_name );
163
int afp_addappl(obj, ibuf, ibuflen, rbuf, rbuflen )
166
int ibuflen, *rbuflen;
172
u_int16_t vid, mplen;
173
char *path, *dtf, *p, *mp;
176
char *mpath, *tempfile;
181
memcpy( &vid, ibuf, sizeof( vid ));
182
ibuf += sizeof( vid );
183
if (NULL == ( vol = getvolbyvid( vid ))) {
184
return( AFPERR_PARAM );
187
memcpy( &did, ibuf, sizeof( did ));
188
ibuf += sizeof( did );
189
if (NULL == ( dir = dirlookup( vol, did )) ) {
190
return( AFPERR_NOOBJ );
193
memcpy( creator, ibuf, sizeof( creator ));
194
ibuf += sizeof( creator );
196
memcpy( appltag, ibuf, sizeof( appltag ));
197
ibuf += sizeof( appltag );
199
if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
200
return( AFPERR_NOOBJ );
202
if ( *path == '\0' ) {
203
return( AFPERR_BADTYPE );
206
if ( applopen( vol, creator, O_RDWR|O_CREAT, 0666 ) != AFP_OK ) {
207
return( AFPERR_PARAM );
209
if ( lseek( sa.sdt_fd, 0L, SEEK_SET ) < 0 ) {
210
return( AFPERR_PARAM );
212
dtf = dtfile( vol, creator, ".appl.temp" );
213
tempfile = obj->oldtmp;
214
strcpy( tempfile, dtf );
215
if (( tfd = open( tempfile, O_RDWR|O_CREAT, 0666 )) < 0 ) {
216
return( AFPERR_PARAM );
219
mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path );
220
mplen = mpath + AFPOBJ_TMPSIZ - mp;
222
/* write the new appl entry at start of temporary file */
223
p = mp - sizeof( u_short );
224
mplen = htons( mplen );
225
memcpy( p, &mplen, sizeof( mplen ));
226
mplen = ntohs( mplen );
227
p -= sizeof( appltag );
228
memcpy(p, appltag, sizeof( appltag ));
229
cc = mpath + AFPOBJ_TMPSIZ - p;
230
if ( write( tfd, p, cc ) != cc ) {
232
return( AFPERR_PARAM );
234
cc = copyapplfile( sa.sdt_fd, tfd, mp, mplen );
241
return( AFPERR_PARAM );
243
if ( rename( tempfile, dtfile( vol, creator, ".appl" )) < 0 ) {
244
return( AFPERR_PARAM );
249
int afp_rmvappl(obj, ibuf, ibuflen, rbuf, rbuflen )
252
int ibuflen, *rbuflen;
258
u_int16_t vid, mplen;
259
char *path, *dtf, *mp;
261
char *tempfile, *mpath;
266
memcpy( &vid, ibuf, sizeof( vid ));
267
ibuf += sizeof( vid );
268
if (NULL == ( vol = getvolbyvid( vid ))) {
269
return( AFPERR_PARAM );
272
memcpy( &did, ibuf, sizeof( did ));
273
ibuf += sizeof( did );
274
if (NULL == ( dir = dirlookup( vol, did )) ) {
275
return( AFPERR_NOOBJ );
278
memcpy( creator, ibuf, sizeof( creator ));
279
ibuf += sizeof( creator );
281
if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
282
return( AFPERR_NOOBJ );
284
if ( *path == '.' ) {
285
return( AFPERR_BADTYPE );
288
if ( applopen( vol, creator, O_RDWR, 0666 ) != AFP_OK ) {
289
return( AFPERR_NOOBJ );
291
if ( lseek( sa.sdt_fd, 0L, SEEK_SET ) < 0 ) {
292
return( AFPERR_PARAM );
294
dtf = dtfile( vol, creator, ".appl.temp" );
295
tempfile = obj->oldtmp;
296
strcpy( tempfile, dtf );
297
if (( tfd = open( tempfile, O_RDWR|O_CREAT, 0666 )) < 0 ) {
298
return( AFPERR_PARAM );
301
mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path );
302
mplen = mpath + AFPOBJ_TMPSIZ - mp;
303
cc = copyapplfile( sa.sdt_fd, tfd, mp, mplen );
310
return( AFPERR_PARAM );
312
if ( rename( tempfile, dtfile( vol, creator, ".appl" )) < 0 ) {
313
return( AFPERR_PARAM );
318
int afp_getappl(obj, ibuf, ibuflen, rbuf, rbuflen )
321
int ibuflen, *rbuflen;
327
u_int16_t vid, aindex, bitmap, len;
334
memcpy( &vid, ibuf, sizeof( vid ));
335
ibuf += sizeof( vid );
336
if (NULL == ( vol = getvolbyvid( vid )) ) {
338
return( AFPERR_PARAM );
341
memcpy( creator, ibuf, sizeof( creator ));
342
ibuf += sizeof( creator );
344
memcpy( &aindex, ibuf, sizeof( aindex ));
345
ibuf += sizeof( aindex );
346
aindex = ntohs( aindex );
347
if ( aindex ) { /* index 0 == index 1 */
351
memcpy( &bitmap, ibuf, sizeof( bitmap ));
352
bitmap = ntohs( bitmap );
353
ibuf += sizeof( bitmap );
355
if ( applopen( vol, creator, O_RDONLY, 0666 ) != AFP_OK ) {
357
return( AFPERR_NOITEM );
359
if ( aindex < sa.sdt_index ) {
360
if ( lseek( sa.sdt_fd, 0L, SEEK_SET ) < 0 ) {
362
return( AFPERR_PARAM );
367
/* position to correct spot within appl file */
369
while (( cc = read( sa.sdt_fd, buf, sizeof( appltag )
370
+ sizeof( u_short ))) > 0 ) {
371
p = buf + sizeof( appltag );
372
memcpy( &len, p, sizeof( len ));
374
p += sizeof( u_short );
375
if (( cc = read( sa.sdt_fd, p, len )) < len ) {
378
if ( sa.sdt_index == aindex ) {
383
if ( cc <= 0 || sa.sdt_index != aindex ) {
385
return( AFPERR_NOITEM );
391
* Check to see if this APPL mapping has an mpath or a upath. If
392
* there are any ':'s in the name, it is a upath and must be converted
393
* to an mpath. Hopefully, this code will go away.
396
#define hextoint( c ) ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
397
#define islxdigit(x) (!isupper(x)&&isxdigit(x))
399
char utomname[ MAXPATHLEN + 1];
407
if ( *u == ':' && *(u+1) != '\0' && islxdigit( *(u+1)) &&
408
*(u+2) != '\0' && islxdigit( *(u+2))) {
410
h = hextoint( *u ) << 4;
423
if ( p[ len - 1 ] == '\0' ) {
427
#endif /* APPLCNAME */
429
/* fake up a cname */
432
*q++ = 2; /* long path type */
433
*q++ = (unsigned char)len;
437
if (( p = cname( vol, vol->v_dir, &q )) == NULL ) {
439
return( AFPERR_NOITEM );
442
if ( stat( mtoupath(vol, p), &st ) < 0 ) {
444
return( AFPERR_NOITEM );
446
buflen = *rbuflen - sizeof( bitmap ) - sizeof( appltag );
447
if ( getfilparams(vol, bitmap, p, curdir, &st, rbuf + sizeof( bitmap ) +
448
sizeof( appltag ), &buflen ) != AFP_OK ) {
450
return( AFPERR_BITMAP );
453
*rbuflen = buflen + sizeof( bitmap ) + sizeof( appltag );
454
bitmap = htons( bitmap );
455
memcpy( rbuf, &bitmap, sizeof( bitmap ));
456
rbuf += sizeof( bitmap );
457
memcpy( rbuf, appltag, sizeof( appltag ));
458
rbuf += sizeof( appltag );