~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to etc/afpd/appl.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: appl.c,v 1.7.2.1 2003/06/09 15:09:06 srittau Exp $
 
3
 *
 
4
 * Copyright (c) 1990,1993 Regents of The University of Michigan.
 
5
 * All Rights Reserved.  See COPYRIGHT.
 
6
 */
 
7
 
 
8
#ifdef HAVE_CONFIG_H
 
9
#include "config.h"
 
10
#endif /* HAVE_CONFIG_H */
 
11
 
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <string.h>
 
15
#include <ctype.h>
 
16
#ifdef HAVE_FCNTL_H
 
17
#include <fcntl.h>
 
18
#endif /* HAVE_FCNTL_H */
 
19
#ifdef HAVE_UNISTD_H
 
20
#include <unistd.h>
 
21
#endif /* HAVE_UNISTD_H */
 
22
#include <sys/types.h>
 
23
#include <sys/stat.h>
 
24
#include <sys/param.h>
 
25
#include <atalk/logger.h>
 
26
#include <errno.h>
 
27
 
 
28
#include <netatalk/endian.h>
 
29
#include <atalk/adouble.h>
 
30
#include <atalk/afp.h>
 
31
 
 
32
#include "volume.h"
 
33
#include "globals.h"
 
34
#include "directory.h"
 
35
#include "file.h"
 
36
#include "desktop.h"
 
37
 
 
38
static struct savedt    sa = { { 0, 0, 0, 0 }, -1, 0 };
 
39
 
 
40
static __inline__ int pathcmp( p, plen, q, qlen )
 
41
char    *p;
 
42
int     plen;
 
43
char    *q;
 
44
int     qlen;
 
45
{
 
46
    return (( plen == qlen && memcmp( p, q, plen ) == 0 ) ? 0 : 1 );
 
47
}
 
48
 
 
49
static int applopen( vol, creator, flags, mode )
 
50
struct vol      *vol;
 
51
u_char  creator[ 4 ];
 
52
{
 
53
    char        *dtf, *adt, *adts;
 
54
 
 
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 ) {
 
59
            return( AFP_OK );
 
60
        }
 
61
        close( sa.sdt_fd );
 
62
        sa.sdt_fd = -1;
 
63
    }
 
64
 
 
65
    dtf = dtfile( vol, creator, ".appl" );
 
66
 
 
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 );
 
71
            }
 
72
            *adts = '\0';
 
73
            if (( adt = strrchr( dtf, '/' )) == NULL ) {
 
74
                return( AFPERR_PARAM );
 
75
            }
 
76
            *adt = '\0';
 
77
            (void) ad_mkdir( dtf, DIRBITS | 0777 );
 
78
            *adt = '/';
 
79
            (void) ad_mkdir( dtf, DIRBITS | 0777 );
 
80
            *adts = '/';
 
81
 
 
82
            if (( sa.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
 
83
                return( AFPERR_PARAM );
 
84
            }
 
85
        } else {
 
86
            return( AFPERR_PARAM );
 
87
        }
 
88
    }
 
89
    memcpy( sa.sdt_creator, creator, sizeof( CreatorType ));
 
90
    sa.sdt_vid = vol->v_vid;
 
91
    sa.sdt_index = 0;
 
92
    return( AFP_OK );
 
93
}
 
94
 
 
95
/*
 
96
 * copy appls to new file, deleting any matching (old) appl entries
 
97
 */
 
98
static int copyapplfile( sfd, dfd, mpath, mplen )
 
99
int             sfd;
 
100
int             dfd;
 
101
char    *mpath;
 
102
u_short mplen;
 
103
{
 
104
    int         cc;
 
105
    char        *p;
 
106
    u_int16_t   len;
 
107
    u_char      appltag[ 4 ];
 
108
    char        buf[ MAXPATHLEN ];
 
109
 
 
110
    while (( cc = read( sfd, buf, sizeof(appltag) + sizeof( u_short ))) > 0 ) {
 
111
        p = buf + sizeof(appltag);
 
112
        memcpy( &len, p, sizeof(len));
 
113
        len = ntohs( len );
 
114
        p += sizeof( len );
 
115
        if (( cc = read( sa.sdt_fd, p, len )) < len ) {
 
116
            break;
 
117
        }
 
118
        if ( pathcmp( mpath, mplen, p, len ) != 0 ) {
 
119
            p += len;
 
120
            if ( write( dfd, buf, p - buf ) != p - buf ) {
 
121
                cc = -1;
 
122
                break;
 
123
            }
 
124
        }
 
125
    }
 
126
    return( cc );
 
127
}
 
128
 
 
129
/*
 
130
 * build mac. path (backwards) by traversing the directory tree
 
131
 *
 
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.
 
135
 *
 
136
 * The new way: dir and path refer to an app, path is a mac format
 
137
 * pathname.  makemacpath() builds a cname.
 
138
 *
 
139
 * See afp_getappl() for the backward compatiblity code.
 
140
 */
 
141
static char *
 
142
makemacpath( mpath, mpathlen, dir, path )
 
143
char    *mpath;
 
144
int             mpathlen;
 
145
struct dir      *dir;
 
146
char    *path;
 
147
{
 
148
    char        *p;
 
149
 
 
150
    p = mpath + mpathlen;
 
151
    p -= strlen( path );
 
152
    strncpy( p, path, strlen( path ));
 
153
 
 
154
    while ( dir->d_parent != NULL ) {
 
155
        p -= strlen( dir->d_name ) + 1;
 
156
        strcpy( p, dir->d_name );
 
157
        dir = dir->d_parent;
 
158
    }
 
159
    return( p );
 
160
}
 
161
 
 
162
 
 
163
int afp_addappl(obj, ibuf, ibuflen, rbuf, rbuflen )
 
164
AFPObj      *obj;
 
165
char    *ibuf, *rbuf;
 
166
int             ibuflen, *rbuflen;
 
167
{
 
168
    struct vol          *vol;
 
169
    struct dir          *dir;
 
170
    int                 tfd, cc;
 
171
    u_int32_t           did;
 
172
    u_int16_t           vid, mplen;
 
173
    char                *path, *dtf, *p, *mp;
 
174
    u_char              creator[ 4 ];
 
175
    u_char              appltag[ 4 ];
 
176
    char                *mpath, *tempfile;
 
177
 
 
178
    *rbuflen = 0;
 
179
    ibuf += 2;
 
180
 
 
181
    memcpy( &vid, ibuf, sizeof( vid ));
 
182
    ibuf += sizeof( vid );
 
183
    if (NULL == ( vol = getvolbyvid( vid ))) {
 
184
        return( AFPERR_PARAM );
 
185
    }
 
186
 
 
187
    memcpy( &did, ibuf, sizeof( did ));
 
188
    ibuf += sizeof( did );
 
189
    if (NULL == ( dir = dirlookup( vol, did )) ) {
 
190
        return( AFPERR_NOOBJ );
 
191
    }
 
192
 
 
193
    memcpy( creator, ibuf, sizeof( creator ));
 
194
    ibuf += sizeof( creator );
 
195
 
 
196
    memcpy( appltag, ibuf, sizeof( appltag ));
 
197
    ibuf += sizeof( appltag );
 
198
 
 
199
    if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
 
200
        return( AFPERR_NOOBJ );
 
201
    }
 
202
    if ( *path == '\0' ) {
 
203
        return( AFPERR_BADTYPE );
 
204
    }
 
205
 
 
206
    if ( applopen( vol, creator, O_RDWR|O_CREAT, 0666 ) != AFP_OK ) {
 
207
        return( AFPERR_PARAM );
 
208
    }
 
209
    if ( lseek( sa.sdt_fd, 0L, SEEK_SET ) < 0 ) {
 
210
        return( AFPERR_PARAM );
 
211
    }
 
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 );
 
217
    }
 
218
    mpath = obj->newtmp;
 
219
    mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path );
 
220
    mplen =  mpath + AFPOBJ_TMPSIZ - mp;
 
221
 
 
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 ) {
 
231
        unlink( tempfile );
 
232
        return( AFPERR_PARAM );
 
233
    }
 
234
    cc = copyapplfile( sa.sdt_fd, tfd, mp, mplen );
 
235
    close( tfd );
 
236
    close( sa.sdt_fd );
 
237
    sa.sdt_fd = -1;
 
238
 
 
239
    if ( cc < 0 ) {
 
240
        unlink( tempfile );
 
241
        return( AFPERR_PARAM );
 
242
    }
 
243
    if ( rename( tempfile, dtfile( vol, creator, ".appl" )) < 0 ) {
 
244
        return( AFPERR_PARAM );
 
245
    }
 
246
    return( AFP_OK );
 
247
}
 
248
 
 
249
int afp_rmvappl(obj, ibuf, ibuflen, rbuf, rbuflen )
 
250
AFPObj      *obj;
 
251
char    *ibuf, *rbuf;
 
252
int             ibuflen, *rbuflen;
 
253
{
 
254
    struct vol          *vol;
 
255
    struct dir          *dir;
 
256
    int                 tfd, cc;
 
257
    u_int32_t           did;
 
258
    u_int16_t           vid, mplen;
 
259
    char                *path, *dtf, *mp;
 
260
    u_char              creator[ 4 ];
 
261
    char                *tempfile, *mpath;
 
262
 
 
263
    *rbuflen = 0;
 
264
    ibuf += 2;
 
265
 
 
266
    memcpy( &vid, ibuf, sizeof( vid ));
 
267
    ibuf += sizeof( vid );
 
268
    if (NULL == ( vol = getvolbyvid( vid ))) {
 
269
        return( AFPERR_PARAM );
 
270
    }
 
271
 
 
272
    memcpy( &did, ibuf, sizeof( did ));
 
273
    ibuf += sizeof( did );
 
274
    if (NULL == ( dir = dirlookup( vol, did )) ) {
 
275
        return( AFPERR_NOOBJ );
 
276
    }
 
277
 
 
278
    memcpy( creator, ibuf, sizeof( creator ));
 
279
    ibuf += sizeof( creator );
 
280
 
 
281
    if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
 
282
        return( AFPERR_NOOBJ );
 
283
    }
 
284
    if ( *path == '.' ) {
 
285
        return( AFPERR_BADTYPE );
 
286
    }
 
287
 
 
288
    if ( applopen( vol, creator, O_RDWR, 0666 ) != AFP_OK ) {
 
289
        return( AFPERR_NOOBJ );
 
290
    }
 
291
    if ( lseek( sa.sdt_fd, 0L, SEEK_SET ) < 0 ) {
 
292
        return( AFPERR_PARAM );
 
293
    }
 
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 );
 
299
    }
 
300
    mpath = obj->newtmp;
 
301
    mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path );
 
302
    mplen =  mpath + AFPOBJ_TMPSIZ - mp;
 
303
    cc = copyapplfile( sa.sdt_fd, tfd, mp, mplen );
 
304
    close( tfd );
 
305
    close( sa.sdt_fd );
 
306
    sa.sdt_fd = -1;
 
307
 
 
308
    if ( cc < 0 ) {
 
309
        unlink( tempfile );
 
310
        return( AFPERR_PARAM );
 
311
    }
 
312
    if ( rename( tempfile, dtfile( vol, creator, ".appl" )) < 0 ) {
 
313
        return( AFPERR_PARAM );
 
314
    }
 
315
    return( AFP_OK );
 
316
}
 
317
 
 
318
int afp_getappl(obj, ibuf, ibuflen, rbuf, rbuflen )
 
319
AFPObj      *obj;
 
320
char    *ibuf, *rbuf;
 
321
int             ibuflen, *rbuflen;
 
322
{
 
323
    struct stat         st;
 
324
    struct vol          *vol;
 
325
    char                *p, *q;
 
326
    int                 cc, buflen;
 
327
    u_int16_t           vid, aindex, bitmap, len;
 
328
    u_char              creator[ 4 ];
 
329
    u_char              appltag[ 4 ];
 
330
    char                *buf, *cbuf;
 
331
 
 
332
    ibuf += 2;
 
333
 
 
334
    memcpy( &vid, ibuf, sizeof( vid ));
 
335
    ibuf += sizeof( vid );
 
336
    if (NULL == ( vol = getvolbyvid( vid )) ) {
 
337
        *rbuflen = 0;
 
338
        return( AFPERR_PARAM );
 
339
    }
 
340
 
 
341
    memcpy( creator, ibuf, sizeof( creator ));
 
342
    ibuf += sizeof( creator );
 
343
 
 
344
    memcpy( &aindex, ibuf, sizeof( aindex ));
 
345
    ibuf += sizeof( aindex );
 
346
    aindex = ntohs( aindex );
 
347
    if ( aindex ) { /* index 0 == index 1 */
 
348
        --aindex;
 
349
    }
 
350
 
 
351
    memcpy( &bitmap, ibuf, sizeof( bitmap ));
 
352
    bitmap = ntohs( bitmap );
 
353
    ibuf += sizeof( bitmap );
 
354
 
 
355
    if ( applopen( vol, creator, O_RDONLY, 0666 ) != AFP_OK ) {
 
356
        *rbuflen = 0;
 
357
        return( AFPERR_NOITEM );
 
358
    }
 
359
    if ( aindex < sa.sdt_index ) {
 
360
        if ( lseek( sa.sdt_fd, 0L, SEEK_SET ) < 0 ) {
 
361
            *rbuflen = 0;
 
362
            return( AFPERR_PARAM );
 
363
        }
 
364
        sa.sdt_index = 0;
 
365
    }
 
366
 
 
367
    /* position to correct spot within appl file */
 
368
    buf = obj->oldtmp;
 
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 ));
 
373
        len = ntohs( len );
 
374
        p += sizeof( u_short );
 
375
        if (( cc = read( sa.sdt_fd, p, len )) < len ) {
 
376
            break;
 
377
        }
 
378
        if ( sa.sdt_index == aindex ) {
 
379
            break;
 
380
        }
 
381
        sa.sdt_index++;
 
382
    }
 
383
    if ( cc <= 0 || sa.sdt_index != aindex ) {
 
384
        *rbuflen = 0;
 
385
        return( AFPERR_NOITEM );
 
386
    }
 
387
    sa.sdt_index++;
 
388
 
 
389
#ifdef APPLCNAME
 
390
    /*
 
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.
 
394
     */
 
395
    {
 
396
#define hextoint( c )   ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
 
397
#define islxdigit(x)    (!isupper(x)&&isxdigit(x))
 
398
 
 
399
        char    utomname[ MAXPATHLEN + 1];
 
400
        char            *u, *m;
 
401
        int             i, h;
 
402
 
 
403
        u = p;
 
404
        m = utomname;
 
405
        i = len;
 
406
        while ( i ) {
 
407
            if ( *u == ':' && *(u+1) != '\0' && islxdigit( *(u+1)) &&
 
408
                    *(u+2) != '\0' && islxdigit( *(u+2))) {
 
409
                ++u, --i;
 
410
                h = hextoint( *u ) << 4;
 
411
                ++u, --i;
 
412
                h |= hextoint( *u );
 
413
                *m++ = h;
 
414
            } else {
 
415
                *m++ = *u;
 
416
            }
 
417
            ++u, --i;
 
418
        }
 
419
 
 
420
        len = m - utomname;
 
421
        p = utomname;
 
422
 
 
423
        if ( p[ len - 1 ] == '\0' ) {
 
424
            len--;
 
425
        }
 
426
    }
 
427
#endif /* APPLCNAME */
 
428
 
 
429
    /* fake up a cname */
 
430
    cbuf = obj->newtmp;
 
431
    q = cbuf;
 
432
    *q++ = 2;   /* long path type */
 
433
    *q++ = (unsigned char)len;
 
434
    memcpy( q, p, len );
 
435
    q = cbuf;
 
436
 
 
437
    if (( p = cname( vol, vol->v_dir, &q )) == NULL ) {
 
438
        *rbuflen = 0;
 
439
        return( AFPERR_NOITEM );
 
440
    }
 
441
 
 
442
    if ( stat( mtoupath(vol, p), &st ) < 0 ) {
 
443
        *rbuflen = 0;
 
444
        return( AFPERR_NOITEM );
 
445
    }
 
446
    buflen = *rbuflen - sizeof( bitmap ) - sizeof( appltag );
 
447
    if ( getfilparams(vol, bitmap, p, curdir, &st, rbuf + sizeof( bitmap ) +
 
448
                      sizeof( appltag ), &buflen ) != AFP_OK ) {
 
449
        *rbuflen = 0;
 
450
        return( AFPERR_BITMAP );
 
451
    }
 
452
 
 
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 );
 
459
    return( AFP_OK );
 
460
}
 
461