]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/filedir.c
dropkludge fixen
[netatalk.git] / etc / afpd / filedir.c
1 /*
2  * $Id: filedir.c,v 1.9 2001-06-06 19:04:25 rufustfirefly 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 <errno.h>
13 #include <sys/syslog.h>
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <sys/param.h>
17 #include <netatalk/endian.h>
18 #include <atalk/adouble.h>
19 #include <atalk/afp.h>
20 #include <atalk/util.h>
21 #include <atalk/cnid.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <fcntl.h>
25 #include <dirent.h>
26 #include <string.h>
27 #include <unistd.h>
28
29 #include "directory.h"
30 #include "desktop.h"
31 #include "volume.h"
32 #include "fork.h"
33 #include "file.h"
34 #include "globals.h"
35 #include "filedir.h"
36
37 int matchfile2dirperms(upath, vol, did)
38                               /* Since it's kinda' big; I decided against an
39                               inline function */
40     char        *upath;
41     struct vol  *vol;
42     int         did;
43   /* The below code changes the way file ownership is determined in the name of
44   fixing dropboxes.  It has known security problem.  See the netatalk FAQ for
45   more information */
46 {
47     struct stat st, sb;
48     struct dir  *dir;
49     char        adpath[50];
50     int         uid;
51
52 #ifdef DEBUG
53     syslog (LOG_INFO, "begin matchfile2dirperms:");
54 #endif /* DEBUG */
55
56     if (stat(upath, &st ) < 0)
57       syslog(LOG_ERR, "Could not stat %s: %m", upath);
58     strcpy (adpath, "./.AppleDouble/");
59     strcat (adpath, upath);
60     if (( dir = dirsearch( vol, did )) == NULL ) {
61       syslog (LOG_ERR, "matchfile2dirperms: Unable to get directory info.");
62       return( AFPERR_NOOBJ );
63     }
64     else if (stat(".", &sb) < 0) {
65         syslog (LOG_ERR, 
66            "matchfile2dirperms: Error checking directory \"%s\": %m", 
67            dir->d_name);
68         return(AFPERR_NOOBJ );
69       }
70     else {
71         uid=geteuid();
72         if ( uid != sb.st_uid )
73         {
74           seteuid(0);
75           if (lchown(upath, sb.st_uid, sb.st_gid) < 0)
76           {
77             syslog (LOG_ERR, 
78               "matchfile2dirperms: Error changing owner/gid of %s: %m", upath);
79             return (AFPERR_ACCESS);
80           }
81           if (chmod(upath,(st.st_mode&0x0FFFF)| S_IRGRP| S_IROTH) < 0)
82           {
83             syslog (LOG_ERR, 
84               "matchfile2dirperms:  Error adding file read permissions: %m");
85             return (AFPERR_ACCESS);
86           }
87 #ifdef DEBUG
88           else 
89             syslog (LOG_INFO, 
90               "matchfile2dirperms:  Added S_IRGRP and S_IROTH: %m");
91 #endif /* DEBUG */
92           if (lchown(adpath, sb.st_uid, sb.st_gid) < 0)
93           {
94             syslog (LOG_ERR, 
95               "matchfile2dirperms: Error changing AppleDouble owner/gid %s: %m",
96               adpath);
97             return (AFPERR_ACCESS);
98           }
99           if (chmod(adpath, (st.st_mode&0x0FFFF)| S_IRGRP| S_IROTH) < 0)
100           {
101             syslog (LOG_ERR, 
102               "matchfile2dirperms:  Error adding AD file read permissions: %m");
103             return (AFPERR_ACCESS);
104           }
105 #ifdef DEBUG
106           else 
107             syslog (LOG_INFO, 
108               "matchfile2dirperms:  Added S_IRGRP and S_IROTH to AD: %m");
109 #endif /* DEBUG */
110         }
111 #ifdef DEBUG
112         else
113           syslog (LOG_INFO, 
114             "matchfile2dirperms: No ownership change necessary.");
115 #endif /* DEBUG */
116     } /* end else if stat success */
117     seteuid(uid); /* Restore process ownership to normal */
118 #ifdef DEBUG
119     syslog (LOG_INFO, "end matchfile2dirperms:");
120 #endif /* DEBUG */
121
122     return (AFP_OK);
123
124 }
125     
126
127 int afp_getfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
128     AFPObj      *obj;
129     char        *ibuf, *rbuf;
130     int         ibuflen, *rbuflen;
131 {
132     struct stat         st;
133     struct vol          *vol;
134     struct dir          *dir;
135     u_int32_t           did;
136     int                 buflen, ret;
137     char                *path;
138     u_int16_t           fbitmap, dbitmap, vid;
139
140 #ifdef DEBUG
141     syslog(LOG_INFO, "begin afp_getfildirparams:");
142 #endif /* DEBUG */
143
144     *rbuflen = 0;
145     ibuf += 2;
146
147     memcpy( &vid, ibuf, sizeof( vid ));
148     ibuf += sizeof( vid );
149     if (( vol = getvolbyvid( vid )) == NULL ) {
150         return( AFPERR_PARAM );
151     }
152
153     memcpy( &did, ibuf, sizeof( did ));
154     ibuf += sizeof( did );
155
156     if (( dir = dirsearch( vol, did )) == NULL ) {
157         return( AFPERR_NOOBJ );
158     }
159
160     memcpy( &fbitmap, ibuf, sizeof( fbitmap ));
161     fbitmap = ntohs( fbitmap );
162     ibuf += sizeof( fbitmap );
163     memcpy( &dbitmap, ibuf, sizeof( dbitmap ));
164     dbitmap = ntohs( dbitmap );
165     ibuf += sizeof( dbitmap );
166
167     if (( path = cname( vol, dir, &ibuf )) == NULL) {
168         return( AFPERR_NOOBJ );
169     }
170
171     if ( stat( mtoupath(vol, path ), &st ) < 0 ) {
172         return( AFPERR_NOOBJ );
173     }
174
175     buflen = 0;
176     if (S_ISDIR(st.st_mode)) {
177         if (dbitmap && ( ret = getdirparams(vol, dbitmap, ".", curdir,
178                 &st, rbuf + 3 * sizeof( u_int16_t ), &buflen )) != AFP_OK ) {
179             return( ret );
180         }
181         /* this is a directory */
182         *(rbuf + 2 * sizeof( u_int16_t )) = FILDIRBIT_ISDIR; 
183     } else {
184         if (fbitmap && ( ret = getfilparams(vol, fbitmap, path, curdir, &st,
185                 rbuf + 3 * sizeof( u_int16_t ), &buflen )) != AFP_OK ) {
186             return( ret );
187         }
188         /* this is a file */
189         *(rbuf + 2 * sizeof( u_int16_t )) = FILDIRBIT_ISFILE;
190     }
191     *rbuflen = buflen + 3 * sizeof( u_int16_t );
192     fbitmap = htons( fbitmap );
193     memcpy( rbuf, &fbitmap, sizeof( fbitmap ));
194     rbuf += sizeof( fbitmap );
195     dbitmap = htons( dbitmap );
196     memcpy( rbuf, &dbitmap, sizeof( dbitmap ));
197     rbuf += sizeof( dbitmap ) + sizeof( u_char );
198     *rbuf = 0;
199
200 #ifdef DEBUG
201     syslog(LOG_INFO, "end afp_getfildirparams:");
202 #endif /* DEBUG */
203
204     return( AFP_OK );
205 }
206
207 int afp_setfildirparams(obj, ibuf, ibuflen, rbuf, rbuflen )
208     AFPObj      *obj;
209     char        *ibuf, *rbuf;
210     int         ibuflen, *rbuflen;
211 {
212     struct stat st;
213     struct vol  *vol;
214     struct dir  *dir;
215     char        *path;
216     u_int16_t   vid, bitmap;
217     int         did, rc;
218
219 #ifdef DEBUG
220     syslog(LOG_INFO, "begin afp_setfildirparams:");
221 #endif /* DEBUG */
222
223     *rbuflen = 0;
224     ibuf += 2;
225     memcpy( &vid, ibuf, sizeof(vid));
226     ibuf += sizeof( vid );
227
228     if (( vol = getvolbyvid( vid )) == NULL ) {
229         return( AFPERR_PARAM );
230     }
231
232     if (vol->v_flags & AFPVOL_RO)
233         return AFPERR_VLOCK;
234
235     memcpy( &did, ibuf, sizeof( did));
236     ibuf += sizeof( did);
237
238     if (( dir = dirsearch( vol, did )) == NULL ) {
239         return( AFPERR_NOOBJ );
240     }
241
242     memcpy( &bitmap, ibuf, sizeof( bitmap ));
243     bitmap = ntohs( bitmap );
244     ibuf += sizeof( bitmap );
245
246     if (( path = cname( vol, dir, &ibuf )) == NULL ) {
247         return( AFPERR_NOOBJ );
248     }
249
250     if ( stat( mtoupath(vol, path ), &st ) < 0 ) {
251         return( AFPERR_NOOBJ );
252     }
253
254     /*
255      * If ibuf is odd, make it even.
256      */
257     if ((u_long)ibuf & 1 ) {
258         ibuf++;
259     }
260
261     if (S_ISDIR(st.st_mode)) {
262         rc = setdirparams(vol, path, bitmap, ibuf );
263     } else {
264         rc = setfilparams(vol, path, bitmap, ibuf );
265     }
266     if ( rc == AFP_OK ) {
267         setvoltime(obj, vol );
268     }
269
270 #ifdef DEBUG
271     syslog(LOG_INFO, "end afp_setfildirparams:");
272 #endif /* DEBUG */
273
274     return( rc );
275 }
276
277 int afp_rename(obj, ibuf, ibuflen, rbuf, rbuflen )
278     AFPObj      *obj;
279     char        *ibuf, *rbuf;
280     int         ibuflen, *rbuflen;
281 {
282     struct adouble      ad;
283     struct stat         st;
284     struct vol          *vol;
285     struct dir          *dir, *odir = NULL;
286     char                *path, *buf, *upath, *newpath;
287     char                *newadpath;
288     u_int32_t           did;
289     int                 plen;
290     u_int16_t           vid;
291 #if AD_VERSION > AD_VERSION1
292     cnid_t              id;
293 #endif
294
295 #ifdef DEBUG
296     syslog(LOG_INFO, "begin afp_rename:");
297 #endif /* DEBUG */
298
299     *rbuflen = 0;
300     ibuf += 2;
301
302     memcpy( &vid, ibuf, sizeof( vid ));
303     ibuf += sizeof( vid );
304     if (( vol = getvolbyvid( vid )) == NULL ) {
305         return( AFPERR_PARAM );
306     }
307
308     if (vol->v_flags & AFPVOL_RO)
309         return AFPERR_VLOCK;
310
311     memcpy( &did, ibuf, sizeof( did ));
312     ibuf += sizeof( did );
313     if (( dir = dirsearch( vol, did )) == NULL ) {
314         return( AFPERR_NOOBJ );
315     }
316
317     if (( path = cname( vol, dir, &ibuf )) == NULL ) {
318         return( AFPERR_NOOBJ );
319     }
320
321     /* another place where we know about the path type */
322     if ( *ibuf++ != 2 ) {
323         return( AFPERR_PARAM );
324     }
325     plen = (unsigned char) *ibuf++;
326     *( ibuf + plen ) = '\0';
327
328     if ( *path == '\0' ) {
329         if ( curdir->d_parent == NULL ) { /* root directory */
330             return( AFPERR_NORENAME );
331         }
332         odir = curdir;
333         path = curdir->d_name;
334         if ( movecwd( vol, curdir->d_parent ) < 0 ) {
335             return( AFPERR_NOOBJ );
336         }
337     }
338
339 #ifdef notdef
340     if ( strcasecmp( path, ibuf ) == 0 ) {
341         return( AFP_OK );
342     }
343 #endif /* notdef */
344
345     /* if a curdir/newname ofork exists, return busy */
346     if (of_findname(vol, curdir, ibuf))
347         return AFPERR_BUSY;
348
349     /* source == destination. just say okay. */
350     if (strcmp(path, ibuf) == 0)
351         return AFP_OK;
352
353     /* check for illegal characters */
354     if ((vol->v_flags & AFPVOL_MSWINDOWS) && 
355         strpbrk(ibuf, MSWINDOWS_BADCHARS))
356         return AFPERR_PARAM;
357
358     newpath = obj->oldtmp;
359     strcpy( newpath, mtoupath(vol, ibuf ));
360
361     if ((vol->v_flags & AFPVOL_NOHEX) && strchr(newpath, '/'))
362       return AFPERR_PARAM;
363
364     if (!validupath(vol, newpath))
365       return AFPERR_EXIST;
366
367     /* the strdiacasecmp deals with case-insensitive, case preserving
368        filesystems */
369     if (stat( newpath, &st ) == 0 && strdiacasecmp(path, ibuf))
370         return( AFPERR_EXIST );
371
372     upath = mtoupath(vol, path);
373
374 #if AD_VERSION > AD_VERSION1
375     id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
376 #endif
377
378     if ( rename( upath, newpath ) < 0 ) {
379         switch ( errno ) {
380         case ENOENT :
381             return( AFPERR_NOOBJ );
382         case EACCES :
383             return( AFPERR_ACCESS );
384         default :
385             return( AFPERR_PARAM );
386         }
387     }
388
389 #if AD_VERSION > AD_VERSION1
390     if (stat(newpath, &st) < 0) /* this shouldn't fail */
391       return AFPERR_MISC;
392     cnid_update(vol->v_db, id, &st, curdir->d_did, newpath, strlen(newpath));
393 #endif
394
395     if ( !odir ) {
396         newadpath = obj->newtmp;
397         strcpy( newadpath, ad_path( newpath, 0 ));
398         if ( rename( ad_path( upath, 0 ), newadpath ) < 0 ) {
399             if ( errno == ENOENT ) {    /* no adouble header file */
400                 if (( unlink( newadpath ) < 0 ) && ( errno != ENOENT )) {
401                     return( AFPERR_PARAM );
402                 }
403                 goto out;
404             }
405             return( AFPERR_PARAM );
406         }
407
408         memset(&ad, 0, sizeof(ad));
409         if ( ad_open( newpath, ADFLAGS_HF, O_RDWR|O_CREAT, 0666,
410                       &ad) < 0 ) {
411             return( AFPERR_PARAM );
412         }
413     } else {
414         int isad = 1;
415
416         memset(&ad, 0, sizeof(ad));
417         if ( ad_open( newpath, vol_noadouble(vol)|ADFLAGS_HF|ADFLAGS_DIR, 
418                       O_RDWR|O_CREAT, 0666, &ad) < 0 ) {
419             if (!((errno == ENOENT) && vol_noadouble(vol)))
420               return( AFPERR_PARAM );
421             isad = 0;
422         }
423         if ((buf = realloc( odir->d_name, plen + 1 )) == NULL ) {
424             syslog( LOG_ERR, "afp_rename: realloc: %m" );
425             if (isad) {
426               ad_flush(&ad, ADFLAGS_HF); /* in case of create */
427               ad_close(&ad, ADFLAGS_HF);
428             }
429             return AFPERR_MISC;
430         }
431         odir->d_name = buf;
432         strcpy( odir->d_name, ibuf );
433         if (!isad)
434           goto out;
435     }
436
437     ad_setentrylen( &ad, ADEID_NAME, plen );
438     memcpy( ad_entry( &ad, ADEID_NAME ), ibuf, plen );
439     ad_flush( &ad, ADFLAGS_HF );
440     ad_close( &ad, ADFLAGS_HF );
441
442 out:
443     setvoltime(obj, vol );
444
445     /* if it's still open, rename the ofork as well. */
446     if (of_rename(vol, curdir, path, curdir, ibuf) < 0)
447         return AFPERR_MISC;
448
449 #ifdef DEBUG
450     syslog(LOG_INFO, "end afp_rename:");
451 #endif /* DEBUG */
452
453     return( AFP_OK );
454 }
455
456
457 int afp_delete(obj, ibuf, ibuflen, rbuf, rbuflen )
458     AFPObj      *obj;
459     char        *ibuf, *rbuf;
460     int         ibuflen, *rbuflen;
461 {
462     struct vol          *vol;
463     struct dir          *dir;
464     char                *path, *upath;
465     int                 did, rc;
466     u_int16_t           vid;
467
468 #ifdef DEBUG
469     syslog(LOG_INFO, "begin afp_delete:");
470 #endif /* DEBUG */ 
471
472     *rbuflen = 0;
473     ibuf += 2;
474
475     memcpy( &vid, ibuf, sizeof( vid ));
476     ibuf += sizeof( vid );
477     if (( vol = getvolbyvid( vid )) == NULL ) {
478         return( AFPERR_PARAM );
479     }
480
481     if (vol->v_flags & AFPVOL_RO)
482         return AFPERR_VLOCK;
483
484     memcpy( &did, ibuf, sizeof( did ));
485     ibuf += sizeof( int );
486     if (( dir = dirsearch( vol, did )) == NULL ) {
487         return( AFPERR_NOOBJ );
488     }
489
490     if (( path = cname( vol, dir, &ibuf )) == NULL ) {
491         return( AFPERR_NOOBJ );
492     }
493
494     if ( *path == '\0' ) {
495         rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
496     } else if (of_findname(vol, curdir, path)) {
497         rc = AFPERR_BUSY;
498     } else if ((rc = deletefile( upath = mtoupath(vol, path ))) == AFP_OK) {
499 #if AD_VERSION > AD_VERSION1 /* get rid of entry */
500         cnid_t id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
501         cnid_delete(vol->v_db, id);
502 #endif
503     }
504     if ( rc == AFP_OK ) {
505         setvoltime(obj, vol );
506     }
507
508 #ifdef DEBUG
509     syslog(LOG_INFO, "end afp_delete:");
510 #endif /* DEBUG */
511
512     return( rc );
513 }
514
515 char *ctoupath( vol, dir, name )
516     const struct vol    *vol;
517     struct dir  *dir;
518     char        *name;
519 {
520     struct dir  *d;
521     static char path[ MAXPATHLEN + 1];
522     char        *p, *u;
523     int         len;
524
525     p = path + sizeof( path ) - 1;
526     *p = '\0';
527     u = mtoupath(vol, name );
528     len = strlen( u );
529     p -= len;
530     strncpy( p, u, len );
531     for ( d = dir; d->d_parent; d = d->d_parent ) {
532         *--p = '/';
533         u = mtoupath(vol, d->d_name );
534         len = strlen( u );
535         p -= len;
536         strncpy( p, u, len );
537     }
538     *--p = '/';
539     len = strlen( vol->v_path );
540     p -= len;
541     strncpy( p, vol->v_path, len );
542
543     return( p );
544 }
545
546
547 int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen )
548     AFPObj      *obj;
549     char        *ibuf, *rbuf;
550     int         ibuflen, *rbuflen;
551 {
552     struct vol  *vol;
553     struct dir  *sdir, *ddir, *odir = NULL;
554     struct stat st;
555     char        *oldname, *newname;
556     char        *path, *p, *upath; 
557     int         did, rc;
558     int         plen;
559     u_int16_t   vid;
560 #if AD_VERSION > AD_VERSION1
561     cnid_t      id;
562 #endif
563 #ifdef DROPKLUDGE
564     int         retvalue;
565 #endif /* DROPKLUDGE */
566
567 #ifdef DEBUG
568     syslog(LOG_INFO, "begin afp_moveandrename:");
569 #endif /* DEBUG */
570
571     *rbuflen = 0;
572     ibuf += 2;
573
574     memcpy( &vid, ibuf, sizeof( vid ));
575     ibuf += sizeof( vid );
576     if (( vol = getvolbyvid( vid )) == NULL ) {
577         return( AFPERR_PARAM );
578     }
579
580     if (vol->v_flags & AFPVOL_RO)
581         return AFPERR_VLOCK;
582
583     /* source did followed by dest did */
584     memcpy( &did, ibuf, sizeof( did ));
585     ibuf += sizeof( int );
586     if (( sdir = dirsearch( vol, did )) == NULL ) {
587         return( AFPERR_PARAM );
588     }
589
590     memcpy( &did, ibuf, sizeof( did ));
591     ibuf += sizeof( int );
592
593     /* source pathname */
594     if (( path = cname( vol, sdir, &ibuf )) == NULL ) {
595         return( AFPERR_NOOBJ );
596     }
597
598     sdir = curdir;
599     newname = obj->newtmp;
600     oldname = obj->oldtmp;
601     if ( *path != '\0' ) {
602         /* not a directory */
603         strcpy(newname, path);
604         strcpy(oldname, path); /* an extra copy for of_rename */
605 #if AD_VERSION > AD_VERSION1
606         p = mtoupath(vol, path);
607         id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
608 #endif
609         p = ctoupath( vol, sdir, newname );
610     } else {
611         odir = curdir;
612         strcpy( newname, odir->d_name );
613         strcpy(oldname, odir->d_name); 
614         p = ctoupath( vol, odir->d_parent, newname );
615 #if AD_VERSION > AD_VERSION1
616         id = curdir->d_did; /* we already have the CNID */
617 #endif
618     }
619     /*
620      * p now points to the full pathname of the source fs object.
621      */
622
623     /* get the destination directory */
624     if (( ddir = dirsearch( vol, did )) == NULL ) {
625         return( AFPERR_PARAM );
626     }
627     if (( path = cname( vol, ddir, &ibuf )) == NULL ) {
628         return( AFPERR_NOOBJ );
629     }
630     if ( *path != '\0' ) {
631         return( AFPERR_BADTYPE );
632     }
633
634     /* one more place where we know about path type */
635     if ( *ibuf++ != 2 ) {
636         return( AFPERR_PARAM );
637     }
638
639     if (( plen = (unsigned char)*ibuf++ ) != 0 ) {
640         strncpy( newname, ibuf, plen );
641         newname[ plen ] = '\0';
642     }
643
644     /* check for illegal characters */
645     if ((vol->v_flags & AFPVOL_MSWINDOWS) && 
646         strpbrk(newname, MSWINDOWS_BADCHARS))
647         return AFPERR_PARAM;
648
649     upath = mtoupath(vol, newname);
650
651     if ((vol->v_flags & AFPVOL_NOHEX) && strchr(upath, '/'))
652       return AFPERR_PARAM;
653
654     if (!validupath(vol, upath))
655       return AFPERR_EXIST;
656
657     /* source == destination. we just silently accept this. */
658     if (curdir == sdir) {
659       if (strcmp(oldname, newname) == 0)
660         return AFP_OK;
661       
662       /* deal with case insensitive, case-preserving filesystems. */
663       if ((stat(upath, &st) == 0) && strdiacasecmp(oldname, newname)) 
664         return AFPERR_EXIST;
665       
666     } else if (stat(upath, &st ) == 0)
667       return( AFPERR_EXIST );
668       
669     if ( !odir ) {
670       if (of_findname(vol, curdir, newname)) {
671         rc = AFPERR_BUSY;
672       } else if ((rc = renamefile( p, upath, newname, 
673                                    vol_noadouble(vol) )) == AFP_OK) {
674         /* if it's still open, rename the ofork as well. */
675         rc = of_rename(vol, sdir, oldname, curdir, newname);
676       }
677     } else {
678         rc = renamedir(p, upath, odir, curdir, newname, vol_noadouble(vol));
679     }
680
681 #ifdef DROPKLUDGE
682     if (vol->v_flags & AFPVOL_DROPBOX) {
683         if (retvalue=matchfile2dirperms (newname, vol, did) != AFP_OK) {
684             return retvalue;
685         }
686     }
687 #endif /* DROPKLUDGE */
688
689     if ( rc == AFP_OK ) {
690 #if AD_VERSION > AD_VERSION1
691         /* renaming may have moved the file/dir across a filesystem */
692         if (stat(upath, &st) < 0) 
693           return AFPERR_MISC;
694         
695         /* fix up the catalog entry */
696         cnid_update(vol->v_db, id, &st, curdir->d_did, upath, strlen(upath));
697 #endif      
698         setvoltime(obj, vol );
699     }
700
701 #ifdef DEBUG
702     syslog(LOG_INFO, "end afp_moveandrename:");
703 #endif /* DEBUG */
704
705     return( rc );
706 }
707