X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fvfs%2Fea.c;h=44188c0a8858dca4e88159e4234a696cd3ec8d35;hb=dbf558207127d21596b307d388a90df42d7a218e;hp=6cfa6132d4e00531fec6b9ab432a843dc05c58a2;hpb=d0f90628ecad684ef1b417471ea3f76292964b11;p=netatalk.git diff --git a/libatalk/vfs/ea.c b/libatalk/vfs/ea.c index 6cfa6132..44188c0a 100644 --- a/libatalk/vfs/ea.c +++ b/libatalk/vfs/ea.c @@ -1,5 +1,5 @@ /* - $Id: ea.c,v 1.3 2009-10-14 15:04:01 franklahm Exp $ + $Id: ea.c,v 1.4 2009-10-15 12:06:07 franklahm Exp $ Copyright (c) 2009 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -39,6 +39,7 @@ #include #include #include +#include /* * Store Extended Attributes inside .AppleDouble folders as follows: @@ -1661,3 +1662,84 @@ exit: ea_close(&dstea); return ret; } + +int ea_copyfile(VFS_FUNC_ARGS_COPYFILE) +{ + int count = 0; + int ret = AFP_OK; + size_t easize; + char srceapath[ MAXPATHLEN + 1]; + char *eapath; + char *eaname; + struct ea srcea; + struct ea dstea; + struct adouble ad; + + LOG(log_debug, logtype_afpd, "ea_copyfile('%s'/'%s')", src, dst); + + /* Open EA stuff */ + if ((ea_open(vol, src, EA_RDWR, &srcea)) != 0) { + if (errno == ENOENT) + /* no EA files, nothing to do */ + return AFP_OK; + else { + LOG(log_error, logtype_afpd, "ea_copyfile('%s'/'%s'): ea_open error: '%s'", src, dst, src); + return AFPERR_MISC; + } + } + + if ((ea_open(vol, dst, EA_RDWR | EA_CREATE, &dstea)) != 0) { + if (errno == ENOENT) { + /* Possibly the .AppleDouble folder didn't exist, we create it and try again */ + ad_init(&ad, vol->v_adouble, vol->v_ad_options); + if ((ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad)) != 0) { + LOG(log_error, logtype_afpd, "ea_copyfile('%s/%s'): ad_open error: '%s'", src, dst, dst); + ret = AFPERR_MISC; + goto exit; + } + ad_close(&ad, ADFLAGS_HF); + if ((ea_open(vol, dst, EA_RDWR | EA_CREATE, &dstea)) != 0) { + ret = AFPERR_MISC; + goto exit; + } + } + } + + /* Loop through all EAs: */ + while (count < srcea.ea_count) { + /* Copy EA */ + eaname = (*srcea.ea_entries)[count].ea_name; + easize = (*srcea.ea_entries)[count].ea_size; + + /* Build src and dst paths for copy_file() */ + eapath = ea_path(&srcea, eaname); + strcpy(srceapath, eapath); + eapath = ea_path(&dstea, eaname); + + LOG(log_maxdebug, logtype_afpd, "ea_copyfile('%s/%s'): copying EA '%s' to '%s'", + src, dst, srceapath, eapath); + + /* Add EA to dstea */ + if ((ea_addentry(&dstea, eaname, easize, 0)) == -1) { + LOG(log_error, logtype_afpd, "ea_copyfile('%s/%s'): ea_addentry('%s') error", + src, dst, eaname); + ret = AFPERR_MISC; + goto exit; + } + + /* Now copy the EA */ + if ((copy_file( srceapath, eapath, (0666 & ~vol->v_umask))) < 0) { + LOG(log_error, logtype_afpd, "ea_copyfile('%s/%s'): copying EA '%s' to '%s'", + src, dst, srceapath, eapath); + ret = AFPERR_MISC; + goto exit; + } + + count++; + } + +exit: + ea_close(&srcea); + ea_close(&dstea); + return ret; +}