]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/appl.c
remove gcc warnings and cleanup inline mess
[netatalk.git] / etc / afpd / appl.c
1 /*
2  * $Id: appl.c,v 1.12.2.1.2.2.2.3 2008-11-25 15:16:32 didg 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
17 #include <sys/param.h>
18 #include <atalk/logger.h>
19 #include <errno.h>
20
21 #include <atalk/adouble.h>
22 #include <atalk/afp.h>
23
24 #include "volume.h"
25 #include "globals.h"
26 #include "directory.h"
27 #include "file.h"
28 #include "desktop.h"
29
30 static struct savedt    sa = { { 0, 0, 0, 0 }, -1, 0, 0};
31
32 static int pathcmp( p, plen, q, qlen )
33 char    *p;
34 int     plen;
35 char    *q;
36 int     qlen;
37 {
38     return (( plen == qlen && memcmp( p, q, plen ) == 0 ) ? 0 : 1 );
39 }
40
41 static int applopen( vol, creator, flags, mode )
42 struct vol      *vol;
43 u_char  creator[ 4 ];
44 int flags;
45 int mode;
46 {
47     char        *dtf, *adt, *adts;
48
49     if ( sa.sdt_fd != -1 ) {
50         if ( !(flags & ( O_RDWR | O_WRONLY )) &&
51                 memcmp( sa.sdt_creator, creator, sizeof( CreatorType )) == 0 &&
52                 sa.sdt_vid == vol->v_vid ) {
53             return( AFP_OK );
54         }
55         close( sa.sdt_fd );
56         sa.sdt_fd = -1;
57     }
58
59     dtf = dtfile( vol, creator, ".appl" );
60
61     if (( sa.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
62         if ( errno == ENOENT && ( flags & O_CREAT )) {
63             if (( adts = strrchr( dtf, '/' )) == NULL ) {
64                 return( AFPERR_PARAM );
65             }
66             *adts = '\0';
67             if (( adt = strrchr( dtf, '/' )) == NULL ) {
68                 return( AFPERR_PARAM );
69             }
70             *adt = '\0';
71             (void) ad_mkdir( dtf, DIRBITS | 0777 );
72             *adt = '/';
73             (void) ad_mkdir( dtf, DIRBITS | 0777 );
74             *adts = '/';
75
76             if (( sa.sdt_fd = open( dtf, flags, ad_mode( dtf, mode ))) < 0 ) {
77                 return( AFPERR_PARAM );
78             }
79         } else {
80             return( AFPERR_PARAM );
81         }
82     }
83     memcpy( sa.sdt_creator, creator, sizeof( CreatorType ));
84     sa.sdt_vid = vol->v_vid;
85     sa.sdt_index = 0;
86     return( AFP_OK );
87 }
88
89 /*
90  * copy appls to new file, deleting any matching (old) appl entries
91  */
92 static int copyapplfile( sfd, dfd, mpath, mplen )
93 int             sfd;
94 int             dfd;
95 char    *mpath;
96 u_short mplen;
97 {
98     int         cc;
99     char        *p;
100     u_int16_t   len;
101     u_char      appltag[ 4 ];
102     char        buf[ MAXPATHLEN ];
103
104     while (( cc = read( sfd, buf, sizeof(appltag) + sizeof( u_short ))) > 0 ) {
105         p = buf + sizeof(appltag);
106         memcpy( &len, p, sizeof(len));
107         len = ntohs( len );
108         p += sizeof( len );
109         if (( cc = read( sa.sdt_fd, p, len )) < len ) {
110             break;
111         }
112         if ( pathcmp( mpath, mplen, p, len ) != 0 ) {
113             p += len;
114             if ( write( dfd, buf, p - buf ) != p - buf ) {
115                 cc = -1;
116                 break;
117             }
118         }
119     }
120     return( cc );
121 }
122
123 /*
124  * build mac. path (backwards) by traversing the directory tree
125  *
126  * The old way: dir and path refer to an app, path is a mac format
127  * pathname.  makemacpath() builds something that looks like a cname,
128  * but uses upaths instead of mac format paths.
129  *
130  * The new way: dir and path refer to an app, path is a mac format
131  * pathname.  makemacpath() builds a cname. (zero is a path separator
132  * and it's not \0 terminated).
133  *
134  * See afp_getappl() for the backward compatiblity code.
135  */
136 static char *
137 makemacpath( mpath, mpathlen, dir, path )
138 char    *mpath;
139 int             mpathlen;
140 struct dir      *dir;
141 char    *path;
142 {
143     char        *p;
144
145     p = mpath + mpathlen;
146     p -= strlen( path );
147     memcpy( p, path, strlen( path )); 
148
149     while ( dir->d_parent != NULL ) {
150         p -= strlen( dir->d_m_name ) + 1;
151         if (p < mpath) {
152             /* FIXME: pathname too long */
153             return NULL;
154         }
155         strcpy( p, dir->d_m_name );
156         dir = dir->d_parent;
157     }
158     return( p );
159 }
160
161
162 int afp_addappl(obj, ibuf, ibuflen, rbuf, rbuflen )
163 AFPObj  *obj;
164 char    *ibuf, *rbuf _U_;
165 int     ibuflen _U_, *rbuflen;
166 {
167     struct vol          *vol;
168     struct dir          *dir;
169     int                 tfd, cc;
170     u_int32_t           did;
171     u_int16_t           vid, mplen;
172     struct path         *path;
173     char                *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 afp_errno;
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 get_afp_errno(AFPERR_PARAM);
201     }
202     if ( path_isadir(path) ) {
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->m_name );
220     if (!mp) {
221         return AFPERR_PARAM;
222     }
223     mplen =  mpath + AFPOBJ_TMPSIZ - mp;
224
225     /* write the new appl entry at start of temporary file */
226     p = mp - sizeof( u_short );
227     mplen = htons( mplen );
228     memcpy( p, &mplen, sizeof( mplen ));
229     mplen = ntohs( mplen );
230     p -= sizeof( appltag );
231     memcpy(p, appltag, sizeof( appltag ));
232     cc = mpath + AFPOBJ_TMPSIZ - p;
233     if ( write( tfd, p, cc ) != cc ) {
234         unlink( tempfile );
235         return( AFPERR_PARAM );
236     }
237     cc = copyapplfile( sa.sdt_fd, tfd, mp, mplen );
238     close( tfd );
239     close( sa.sdt_fd );
240     sa.sdt_fd = -1;
241
242     if ( cc < 0 ) {
243         unlink( tempfile );
244         return( AFPERR_PARAM );
245     }
246     if ( rename( tempfile, dtfile( vol, creator, ".appl" )) < 0 ) {
247         return( AFPERR_PARAM );
248     }
249     return( AFP_OK );
250 }
251
252 int afp_rmvappl(obj, ibuf, ibuflen, rbuf, rbuflen )
253 AFPObj  *obj;
254 char    *ibuf, *rbuf _U_;
255 int     ibuflen _U_, *rbuflen;
256 {
257     struct vol          *vol;
258     struct dir          *dir;
259     int                 tfd, cc;
260     u_int32_t           did;
261     u_int16_t           vid, mplen;
262     struct path         *path;
263     char                *dtf, *mp;
264     u_char              creator[ 4 ];
265     char                *tempfile, *mpath;
266
267     *rbuflen = 0;
268     ibuf += 2;
269
270     memcpy( &vid, ibuf, sizeof( vid ));
271     ibuf += sizeof( vid );
272     if (NULL == ( vol = getvolbyvid( vid ))) {
273         return( AFPERR_PARAM );
274     }
275
276     memcpy( &did, ibuf, sizeof( did ));
277     ibuf += sizeof( did );
278     if (NULL == ( dir = dirlookup( vol, did )) ) {
279         return afp_errno;
280     }
281
282     memcpy( creator, ibuf, sizeof( creator ));
283     ibuf += sizeof( creator );
284
285     if (NULL == ( path = cname( vol, dir, &ibuf )) ) {
286         return get_afp_errno(AFPERR_PARAM);
287     }
288     if ( path_isadir(path) ) {
289         return( AFPERR_BADTYPE );
290     }
291
292     if ( applopen( vol, creator, O_RDWR, 0666 ) != AFP_OK ) {
293         return( AFPERR_NOOBJ );
294     }
295     if ( lseek( sa.sdt_fd, 0L, SEEK_SET ) < 0 ) {
296         return( AFPERR_PARAM );
297     }
298     dtf = dtfile( vol, creator, ".appl.temp" );
299     tempfile = obj->oldtmp;
300     strcpy( tempfile, dtf );
301     if (( tfd = open( tempfile, O_RDWR|O_CREAT, 0666 )) < 0 ) {
302         return( AFPERR_PARAM );
303     }
304     mpath = obj->newtmp;
305     mp = makemacpath( mpath, AFPOBJ_TMPSIZ, curdir, path->m_name );
306     if (!mp) {
307         return AFPERR_PARAM ;
308     }
309
310     mplen =  mpath + AFPOBJ_TMPSIZ - mp;
311     cc = copyapplfile( sa.sdt_fd, tfd, mp, mplen );
312     close( tfd );
313     close( sa.sdt_fd );
314     sa.sdt_fd = -1;
315
316     if ( cc < 0 ) {
317         unlink( tempfile );
318         return( AFPERR_PARAM );
319     }
320     if ( rename( tempfile, dtfile( vol, creator, ".appl" )) < 0 ) {
321         return( AFPERR_PARAM );
322     }
323     return( AFP_OK );
324 }
325
326 int afp_getappl(obj, ibuf, ibuflen, rbuf, rbuflen )
327 AFPObj  *obj;
328 char    *ibuf, *rbuf;
329 int     ibuflen _U_, *rbuflen;
330 {
331     struct vol          *vol;
332     char                *p, *q;
333     int                 cc, buflen;
334     u_int16_t           vid, aindex, bitmap, len;
335     u_char              creator[ 4 ];
336     u_char              appltag[ 4 ];
337     char                *buf, *cbuf;
338     struct path         *path;
339     
340     ibuf += 2;
341
342     memcpy( &vid, ibuf, sizeof( vid ));
343     ibuf += sizeof( vid );
344     if (NULL == ( vol = getvolbyvid( vid )) ) {
345         *rbuflen = 0;
346         return( AFPERR_PARAM );
347     }
348
349     memcpy( creator, ibuf, sizeof( creator ));
350     ibuf += sizeof( creator );
351
352     memcpy( &aindex, ibuf, sizeof( aindex ));
353     ibuf += sizeof( aindex );
354     aindex = ntohs( aindex );
355     if ( aindex ) { /* index 0 == index 1 */
356         --aindex;
357     }
358
359     memcpy( &bitmap, ibuf, sizeof( bitmap ));
360     bitmap = ntohs( bitmap );
361     ibuf += sizeof( bitmap );
362
363     if ( applopen( vol, creator, O_RDONLY, 0666 ) != AFP_OK ) {
364         *rbuflen = 0;
365         return( AFPERR_NOITEM );
366     }
367     if ( aindex < sa.sdt_index ) {
368         if ( lseek( sa.sdt_fd, 0L, SEEK_SET ) < 0 ) {
369             *rbuflen = 0;
370             return( AFPERR_PARAM );
371         }
372         sa.sdt_index = 0;
373     }
374
375     /* position to correct spot within appl file */
376     buf = obj->oldtmp;
377     while (( cc = read( sa.sdt_fd, buf, sizeof( appltag )
378                         + sizeof( u_short ))) > 0 ) {
379         p = buf + sizeof( appltag );
380         memcpy( &len, p, sizeof( len ));
381         len = ntohs( len );
382         p += sizeof( u_short );
383         if (( cc = read( sa.sdt_fd, p, len )) < len ) {
384             break;
385         }
386         if ( sa.sdt_index == aindex ) {
387             break;
388         }
389         sa.sdt_index++;
390     }
391     if ( cc <= 0 || sa.sdt_index != aindex ) {
392         *rbuflen = 0;
393         return( AFPERR_NOITEM );
394     }
395     sa.sdt_index++;
396
397 #ifdef APPLCNAME
398     /*
399      * Check to see if this APPL mapping has an mpath or a upath.  If
400      * there are any ':'s in the name, it is a upath and must be converted
401      * to an mpath.  Hopefully, this code will go away.
402      */
403     {
404 #define hextoint( c )   ( isdigit( c ) ? c - '0' : c + 10 - 'a' )
405 #define islxdigit(x)    (!isupper(x)&&isxdigit(x))
406
407         char    utomname[ MAXPATHLEN + 1];
408         char            *u, *m;
409         int             i, h;
410
411         u = p;
412         m = utomname;
413         i = len;
414         while ( i ) {
415             if ( *u == ':' && *(u+1) != '\0' && islxdigit( *(u+1)) &&
416                     *(u+2) != '\0' && islxdigit( *(u+2))) {
417                 ++u, --i;
418                 h = hextoint( *u ) << 4;
419                 ++u, --i;
420                 h |= hextoint( *u );
421                 *m++ = h;
422             } else {
423                 *m++ = *u;
424             }
425             ++u, --i;
426         }
427
428         len = m - utomname;
429         p = utomname;
430
431         if ( p[ len - 1 ] == '\0' ) {
432             len--;
433         }
434     }
435 #endif /* APPLCNAME */
436
437     /* fake up a cname */
438     cbuf = obj->newtmp;
439     q = cbuf;
440     *q++ = 2;   /* long path type */
441     *q++ = (unsigned char)len;
442     memcpy( q, p, len );
443     q = cbuf;
444
445     if (( path = cname( vol, vol->v_dir, &q )) == NULL ) {
446         *rbuflen = 0;
447         return( AFPERR_NOITEM );
448     }
449
450     if ( path_isadir(path) || path->st_errno ) {
451         *rbuflen = 0;
452         return( AFPERR_NOITEM );
453     }
454     buflen = *rbuflen - sizeof( bitmap ) - sizeof( appltag );
455     if ( getfilparams(vol, bitmap, path, curdir, rbuf + sizeof( bitmap ) +
456                       sizeof( appltag ), &buflen ) != AFP_OK ) {
457         *rbuflen = 0;
458         return( AFPERR_BITMAP );
459     }
460
461     *rbuflen = buflen + sizeof( bitmap ) + sizeof( appltag );
462     bitmap = htons( bitmap );
463     memcpy( rbuf, &bitmap, sizeof( bitmap ));
464     rbuf += sizeof( bitmap );
465     memcpy( rbuf, appltag, sizeof( appltag ));
466     rbuf += sizeof( appltag );
467     return( AFP_OK );
468 }
469