LCOV - code coverage report
Current view: top level - src/client - xattr.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 107 148 72.3 %
Date: 2020-07-31 05:59:47 Functions: 8 8 100.0 %

          Line data    Source code
       1             : #include "../burp.h"
       2             : #include "../alloc.h"
       3             : #include "../asfd.h"
       4             : #include "../async.h"
       5             : #include "../cntr.h"
       6             : #include "../log.h"
       7             : #include "../prepend.h"
       8             : #include "extrameta.h"
       9             : #include "xattr.h"
      10             : 
      11             : #ifdef HAVE_XATTR
      12             : 
      13             : #ifdef HAVE_SYS_XATTR_H
      14             : #include <sys/xattr.h>
      15             : #endif
      16             : #ifdef HAVE_SYS_EXTATTR_H
      17             : #include <sys/extattr.h>
      18             : #endif
      19             : #ifdef HAVE_LIBUTIL_H
      20             : #include <libutil.h>
      21             : #endif
      22             : 
      23             : #ifdef HAVE_DARWIN_OS
      24             : /*
      25             :  * OSX doesn't have llistxattr, lgetxattr and lsetxattr but has
      26             :  * listxattr, getxattr and setxattr with an extra options argument
      27             :  * which mimics the l variants of the functions when we specify
      28             :  * XATTR_NOFOLLOW as the options value.
      29             :  */
      30             : #define llistxattr(path, list, size) \
      31             : listxattr((path), (list), (size), XATTR_NOFOLLOW)
      32             : #define lgetxattr(path, name, value, size) \
      33             : getxattr((path), (name), (value), (size), 0, XATTR_NOFOLLOW)
      34             : #define lsetxattr(path, name, value, size, flags) \
      35             : setxattr((path), (name), (value), (size), (flags), XATTR_NOFOLLOW)
      36             : static const char *acl_skiplist[2] = {
      37             :     "com.apple.system.Security",
      38             :     NULL
      39             : };
      40             : #elif HAVE_LINUX_OS
      41             : static const char *acl_skiplist[3] = {
      42             :     "system.posix_acl_access",
      43             :     "system.posix_acl_default",
      44             :     NULL
      45             : };
      46             : #elif HAVE_FREEBSD_OS
      47             : static const char *acl_skiplist[2] = {
      48             :     "system.posix1e.acl_access", NULL
      49             : };
      50             : #else
      51             : static const char *acl_skiplist[1] = {
      52             :         NULL
      53             : };
      54             : #endif
      55             : 
      56             : // Skip xattr entries that were already saved as ACLs.
      57             : static int in_skiplist(const char *xattr)
      58             : {
      59           3 :         for(int c=0; acl_skiplist[c]; c++)
      60           6 :                 if(!strcmp(xattr, acl_skiplist[c]))
      61             :                         return 1;
      62             :         return 0;
      63             : }
      64             : 
      65          13 : static int append_to_extrameta(const char *toappend, char metasymbol,
      66             :         char **xattrtext, size_t *xlen, uint32_t totallen)
      67             : {
      68             :         char tmp3[10];
      69          13 :         size_t newlen=0;
      70          13 :         snprintf(tmp3, sizeof(tmp3), "%c%08X", metasymbol, totallen);
      71          13 :         newlen=(*xlen)+9+totallen+1;
      72          13 :         if(!(*xattrtext=(char *)
      73          13 :                 realloc_w(*xattrtext, newlen, __func__)))
      74             :                         return -1;
      75          13 :         memcpy((*xattrtext)+(*xlen), tmp3, 9);
      76          13 :         (*xlen)+=9;
      77          13 :         memcpy((*xattrtext)+(*xlen), toappend, totallen);
      78          13 :         (*xlen)+=totallen;
      79          13 :         (*xattrtext)[*xlen]='\0';
      80          13 :         return 0;
      81             : }
      82             : 
      83             : #ifndef UTEST
      84             : static
      85             : #endif
      86         158 : char *get_next_xattr_str(struct asfd *asfd, char **data, size_t *l,
      87             :         struct cntr *cntr, uint32_t *s, const char *path)
      88             : {
      89         158 :         char *ret=NULL;
      90             : 
      91         158 :         if(*l<8)
      92             :         {
      93           0 :                 logw(asfd, cntr, "length of xattr '%s' %zd is too short for %s\n",
      94             :                         *data, *l, path);
      95           0 :                 return NULL;
      96             :         }
      97             : 
      98         158 :         if((sscanf(*data, "%08X", s))!=1)
      99             :         {
     100           0 :                 logw(asfd, cntr, "sscanf of xattr '%s' %zd failed for %s\n",
     101             :                         *data, *l, path);
     102           0 :                 return NULL;
     103             :         }
     104         158 :         *data+=8;
     105         158 :         *l-=8;
     106         158 :         if(*s>*l)
     107             :         {
     108           0 :                 logw(asfd, cntr, "requested length %d of xattr '%s' %zd is too long for %s\n",
     109             :                         *s, *data, *l, path);
     110           0 :                 return NULL;
     111             :         }
     112         158 :         if(!(ret=(char *)malloc_w((*s)+1, __func__)))
     113             :                 return NULL;
     114         158 :         memcpy(ret, *data, *s);
     115         158 :         ret[*s]='\0';
     116             : 
     117         158 :         *data+=*s;
     118         158 :         *l-=*s;
     119             : 
     120         158 :         return ret;
     121             : }
     122             : 
     123             : #ifdef HAVE_SYS_EXTATTR_H
     124             : static int namespaces[2] = {
     125             :         EXTATTR_NAMESPACE_USER,
     126             :         EXTATTR_NAMESPACE_SYSTEM
     127             : };
     128             : 
     129             : int has_xattr(const char *path)
     130             : {
     131             :         int i=0;
     132             :         for(i=0; i<(int)(sizeof(namespaces)/sizeof(int)); i++)
     133             :         {
     134             :                 if(extattr_list_link(path, namespaces[i], NULL, 0)>0)
     135             :                         return 1;
     136             :         }
     137             :         return 0;
     138             : }
     139             : 
     140             : #define BSD_BUF_SIZE    1024
     141             : int get_xattr(struct asfd *asfd, const char *path,
     142             :         char **xattrtext, size_t *xlen, struct cntr *cntr)
     143             : {
     144             :         int i=0;
     145             :         uint32_t maxlen=0xFFFFFFFF/2;
     146             : 
     147             :         for(i=0; i<(int)(sizeof(namespaces)/sizeof(int)); i++)
     148             :         {
     149             :                 int j=0;
     150             :                 ssize_t len=0;
     151             :                 int have_acl=0;
     152             :                 char *xattrlist=NULL;
     153             :                 char *cnamespace=NULL;
     154             :                 uint32_t totallen=0;
     155             :                 char *toappend=NULL;
     156             :                 static char z[BSD_BUF_SIZE*2]="";
     157             :                 char cattrname[BSD_BUF_SIZE]="";
     158             :                 if((len=extattr_list_link(path, namespaces[i], NULL, 0))<0)
     159             :                 {
     160             :                         logw(asfd, cntr, "could not extattr_list_link of '%s': %zd\n",
     161             :                                 path, len);
     162             :                         return 0; // carry on
     163             :                 }
     164             :                 if(!len) continue;
     165             :                 if(xattrtext && *xattrtext)
     166             :                 {
     167             :                         // Already have some meta text, which means that some
     168             :                         // ACLs were set.
     169             :                         have_acl++;
     170             :                 }
     171             :                 if(!(xattrlist=(char *)calloc_w(1, len+1, __func__)))
     172             :                         return -1;
     173             :                 if((len=extattr_list_link(path, namespaces[i], xattrlist, len))<=0)
     174             :                 {
     175             :                         logw(asfd, cntr, "could not extattr_list_link '%s': %zd\n",
     176             :                                 path, len);
     177             :                         free_w(&xattrlist);
     178             :                         return 0; // carry on
     179             :                 }
     180             :                 xattrlist[len]='\0';
     181             : 
     182             :                 if(extattr_namespace_to_string(namespaces[i], &cnamespace))
     183             :                 {
     184             :                         logp("Failed to convert %d into namespace on '%s'\n",
     185             :                                  namespaces[i], path);
     186             :                         free_w(&xattrlist);
     187             :                         return 0; // carry on
     188             :                 }
     189             : 
     190             : 
     191             :                 for(j=0; j<(int)len; j+=xattrlist[j]+1)
     192             :                 {
     193             :                         int cnt=0;
     194             :                         char tmp1[9];
     195             :                         char tmp2[9];
     196             :                         size_t newlen=0;
     197             :                         uint32_t zlen=0;
     198             :                         ssize_t vlen=0;
     199             :                         char *val=NULL;
     200             :                         cnt=xattrlist[j];
     201             :                         if(cnt>((int)sizeof(cattrname)-1))
     202             :                                 cnt=((int)sizeof(cattrname)-1);
     203             :                         strncpy(cattrname, xattrlist+(j+1), cnt);
     204             :                         cattrname[cnt]='\0';
     205             :                         snprintf(z, sizeof(z), "%s.%s",
     206             :                                 cnamespace, cattrname);
     207             : 
     208             :                         if(have_acl && in_skiplist(z))
     209             :                                 continue;
     210             :                         zlen=(uint32_t)strlen(z);
     211             :                         //printf("\ngot: %s (%s)\n", z, path);
     212             : 
     213             :                         if((vlen=extattr_list_link(path, namespaces[i],
     214             :                                 xattrlist, len))<0)
     215             :                         {
     216             :                                 logw(asfd, cntr, "could not extattr_list_link on %s for %s: %zd\n", path, cnamespace, vlen);
     217             :                                 continue;
     218             :                         }
     219             :                         if(vlen)
     220             :                         {
     221             :                                 if(!(val=(char *)malloc_w(vlen+1, __func__)))
     222             :                                 {
     223             :                                         free_w(&xattrlist);
     224             :                                         free_w(&toappend);
     225             :                                         return -1;
     226             :                                 }
     227             :                                 if((vlen=extattr_get_link(path, namespaces[i],
     228             :                                         cattrname, val, vlen))<0)
     229             :                                 {
     230             :                                         logw(asfd, cntr, "could not extattr_list_link %s for %s: %zd\n", path, cnamespace, vlen);
     231             :                                         free_w(&val);
     232             :                                         continue;
     233             :                                 }
     234             :                                 val[vlen]='\0';
     235             : 
     236             :                                 if(vlen>maxlen)
     237             :                                 {
     238             :                                         logw(asfd, cntr, "xattr value of '%s' too long: %zd\n",
     239             :                                                 path, vlen);
     240             :                                         free_w(&toappend);
     241             :                                         free_w(&val);
     242             :                                         break;
     243             :                                 }
     244             :                         }
     245             : 
     246             :                         snprintf(tmp1, sizeof(tmp1), "%08X", zlen);
     247             :                         snprintf(tmp2, sizeof(tmp2), "%08X", (uint32_t)vlen);
     248             :                         newlen=totallen+8+zlen+8+vlen;
     249             :                         if(!(toappend=(char *)realloc_w(toappend, newlen, __func__)))
     250             :                         {
     251             :                                 free_w(&val);
     252             :                                 free_w(&xattrlist);
     253             :                                 return -1;
     254             :                         }
     255             :                         memcpy(toappend+totallen, tmp1, 8);
     256             :                         totallen+=8;
     257             :                         memcpy(toappend+totallen, z, zlen);
     258             :                         totallen+=zlen;
     259             :                         memcpy(toappend+totallen, tmp2, 8);
     260             :                         totallen+=8;
     261             :                         memcpy(toappend+totallen, val, vlen);
     262             :                         totallen+=vlen;
     263             :                         free_w(&val);
     264             : 
     265             :                         if(totallen>maxlen)
     266             :                         {
     267             :                                 logw(asfd, cntr,
     268             :                                   "xattr length of '%s' grew too long: %d\n",
     269             :                                   path, totallen);
     270             :                                 free_w(&val);
     271             :                                 free_w(&toappend);
     272             :                                 free_w(&xattrlist);
     273             :                                 return 0; // carry on
     274             :                         }
     275             :                 }
     276             : 
     277             :                 if(toappend)
     278             :                 {
     279             :                         if(append_to_extrameta(toappend, META_XATTR_BSD,
     280             :                                 xattrtext, xlen, totallen))
     281             :                         {
     282             :                                 free_w(&toappend);
     283             :                                 free_w(&xattrlist);
     284             :                                 return -1;
     285             :                         }
     286             :                 }
     287             :                 free_w(&toappend);
     288             :                 free_w(&xattrlist);
     289             :         }
     290             : 
     291             :         return 0;
     292             : }
     293             : 
     294             : static int do_set_xattr_bsd(struct asfd *asfd,
     295             :         const char *path,
     296             :         const char *xattrtext, size_t xlen, struct cntr *cntr)
     297             : {
     298             :         int ret=-1;
     299             :         size_t l=0;
     300             :         char *data=NULL;
     301             :         char *value=NULL;
     302             :         char *nspace=NULL;
     303             : 
     304             :         data=(char *)xattrtext;
     305             :         l=xlen;
     306             :         while(l>0)
     307             :         {
     308             :                 ssize_t cnt;
     309             :                 uint32_t vlen=0;
     310             :                 int cnspace=0;
     311             :                 char *name=NULL;
     312             : 
     313             :                 if(!(nspace=get_next_xattr_str(asfd, &data, &l,
     314             :                         cntr, &vlen, path))
     315             :                   || !(value=get_next_xattr_str(asfd, &data, &l,
     316             :                         cntr, &vlen, path)))
     317             :                                 goto end;
     318             : 
     319             :                 // Need to split the name into two parts.
     320             :                 if(!(name=strchr(nspace, '.')))
     321             :                 {
     322             :                         logw(asfd, cntr,
     323             :                           "could not split %s into namespace and name on %s\n",
     324             :                                 nspace, path);
     325             :                         goto end;
     326             :                 }
     327             :                 *name='\0';
     328             :                 name++;
     329             : 
     330             :                 if(extattr_string_to_namespace(nspace, &cnspace))
     331             :                 {
     332             :                         logw(asfd, cntr,
     333             :                                 "could not convert %s into namespace on %s\n",
     334             :                                 nspace, path);
     335             :                         goto end;
     336             :                 }
     337             : 
     338             :                 //printf("set_link: %d %s %s %s\n", cnspace, nspace, name, value);
     339             :                 if((cnt=extattr_set_link(path,
     340             :                         cnspace, name, value, vlen))!=vlen)
     341             :                 {
     342             :                         logw(asfd, cntr,
     343             :                                 "extattr_set_link error on %s %zd!=%d: %s\n",
     344             :                                 path, cnt, vlen, strerror(errno));
     345             :                         goto end;
     346             :                 }
     347             : 
     348             :                 free_w(&nspace);
     349             :                 free_w(&value);
     350             :         }
     351             :         ret=0;
     352             : end:
     353             :         free_w(&nspace);
     354             :         free_w(&value);
     355             :         return ret;
     356             : }
     357             : 
     358             : int set_xattr(struct asfd *asfd, const char *path,
     359             :         const char *xattrtext,
     360             :         size_t xlen, char metacmd, struct cntr *cntr)
     361             : {
     362             :         switch(metacmd)
     363             :         {
     364             :                 case META_XATTR_BSD:
     365             :                         return do_set_xattr_bsd(asfd, path,
     366             :                                 xattrtext, xlen, cntr);
     367             :                 default:
     368             :                         logp("unknown xattr type: %c\n", metacmd);
     369             :                         logw(asfd, cntr, "unknown xattr type: %c\n", metacmd);
     370             :                         break;
     371             :         }
     372             :         return -1;
     373             : }
     374             : 
     375             : #elif HAVE_SYS_XATTR_H
     376             : 
     377          15 : int has_xattr(const char *path)
     378             : {
     379          15 :         if(llistxattr(path, NULL, 0)>0) return 1;
     380          15 :         return 0;
     381             : }
     382             : 
     383          15 : static int get_toappend(struct asfd *asfd, const char *path,
     384             :         char **toappend, const char *xattrlist,
     385             :         ssize_t len, uint32_t *totallen,
     386             :         int have_acl,
     387             :         struct cntr *cntr)
     388             : {
     389          15 :         char *val=NULL;
     390          15 :         const char *z=NULL;
     391          15 :         uint32_t maxlen=0xFFFFFFFF/2;
     392             : 
     393          38 :         for(z=xattrlist; z-xattrlist < len; z=strchr(z, '\0')+1)
     394             :         {
     395             :                 char tmp1[9];
     396             :                 char tmp2[9];
     397             :                 ssize_t vlen;
     398          23 :                 uint32_t zlen=0;
     399          23 :                 uint32_t newlen=0;
     400             : 
     401          23 :                 free_w(&val);
     402             : 
     403          23 :                 if((zlen=(uint32_t)strlen(z))>maxlen)
     404             :                 {
     405           0 :                         logw(asfd, cntr,
     406             :                                 "xattr element of '%s' too long: %d\n",
     407             :                                 path, zlen);
     408           0 :                         goto carryon;
     409             :                 }
     410             : 
     411          27 :                 if(have_acl && in_skiplist(z))
     412           6 :                         continue;
     413             : 
     414          20 :                 if((vlen=lgetxattr(path, z, NULL, 0))<0)
     415             :                 {
     416           0 :                         logw(asfd, cntr,
     417             :                                 "could not lgetxattr on %s for %s: %zd %s\n",
     418           0 :                                 path, z, vlen, strerror(errno));
     419           0 :                         continue;
     420             :                 }
     421          20 :                 if(vlen)
     422             :                 {
     423          16 :                         if(!(val=(char *)malloc_w(vlen+1, __func__)))
     424             :                                 goto error;
     425          16 :                         if((vlen=lgetxattr(path, z, val, vlen))<0)
     426             :                         {
     427           0 :                                 logw(asfd, cntr,
     428             :                                   "could not lgetxattr %s for %s: %zd %s\n",
     429           0 :                                         path, z, vlen, strerror(errno));
     430           0 :                                 continue;
     431             :                         }
     432          16 :                         val[vlen]='\0';
     433             : 
     434          16 :                         if(vlen>maxlen)
     435             :                         {
     436           0 :                                 logw(asfd, cntr,
     437             :                                         "xattr value of '%s' too long: %zd\n",
     438             :                                         path, vlen);
     439           0 :                                 goto carryon;
     440             :                         }
     441             :                 }
     442             : 
     443          20 :                 snprintf(tmp1, sizeof(tmp1), "%08X", zlen);
     444          20 :                 snprintf(tmp2, sizeof(tmp2), "%08X", (uint32_t)vlen);
     445          20 :                 newlen=(*totallen)+8+zlen+8+vlen;
     446          20 :                 if(!(*toappend=(char *)realloc_w(*toappend, newlen, __func__)))
     447             :                         goto error;
     448          20 :                 memcpy((*toappend)+(*totallen), tmp1, 8);
     449          20 :                 *totallen+=8;
     450          20 :                 memcpy((*toappend)+(*totallen), z, zlen);
     451          20 :                 *totallen+=zlen;
     452          20 :                 memcpy((*toappend)+(*totallen), tmp2, 8);
     453          20 :                 *totallen+=8;
     454          20 :                 memcpy((*toappend)+(*totallen), val, vlen);
     455          20 :                 *totallen+=vlen;
     456             : 
     457          20 :                 if(*totallen>maxlen)
     458             :                 {
     459           0 :                         logw(asfd, cntr,
     460             :                                 "xattr length of '%s' grew too long: %d\n",
     461             :                                 path, *totallen);
     462           0 :                         goto carryon;
     463             :                 }
     464             :         }
     465             : 
     466          15 :         free_w(&val);
     467          15 :         return 0;
     468             : error:
     469           0 :         free_w(&val);
     470           0 :         free_w(toappend);
     471           0 :         return -1;
     472             : carryon:
     473           0 :         free_w(&val);
     474           0 :         free_w(toappend);
     475           0 :         return 0;
     476             : }
     477             : 
     478          15 : int get_xattr(struct asfd *asfd, const char *path,
     479             :         char **xattrtext, size_t *xlen, struct cntr *cntr)
     480             : {
     481          15 :         int ret=0;
     482             :         ssize_t len;
     483          15 :         int have_acl=0;
     484          15 :         char *toappend=NULL;
     485          15 :         char *xattrlist=NULL;
     486          15 :         uint32_t totallen=0;
     487             : 
     488          15 :         if((len=llistxattr(path, NULL, 0))<0)
     489             :         {
     490           0 :                 logw(asfd, cntr, "could not llistxattr '%s': %zd %s\n",
     491           0 :                         path, len, strerror(errno));
     492           0 :                 goto end; // Carry on.
     493             :         }
     494          15 :         if(!(xattrlist=(char *)calloc_w(1, len, __func__)))
     495             :         {
     496             :                 ret=-1;
     497             :                 goto end;
     498             :         }
     499          15 :         if((len=llistxattr(path, xattrlist, len))<0)
     500             :         {
     501           0 :                 logw(asfd, cntr, "could not llistxattr '%s': %zd %s\n",
     502           0 :                         path, len, strerror(errno));
     503           0 :                 goto end; // Carry on.
     504             :         }
     505             : 
     506          15 :         if(xattrtext && *xattrtext)
     507             :         {
     508             :                 // Already have some meta text, which means that some
     509             :                 // ACLs were set.
     510           3 :                 have_acl++;
     511             :         }
     512             : 
     513          15 :         if(get_toappend(asfd, path, &toappend, xattrlist, len, &totallen,
     514             :                 have_acl, cntr))
     515             :         {
     516             :                 ret=-1;
     517             :                 goto end;
     518             :         }
     519             : 
     520          15 :         if(toappend)
     521          13 :                 ret=append_to_extrameta(toappend, META_XATTR,
     522             :                         xattrtext, xlen, totallen);
     523             : end:
     524          15 :         free_w(&toappend);
     525          15 :         free_w(&xattrlist);
     526          15 :         return ret;
     527             : }
     528             : 
     529          13 : static int do_set_xattr(struct asfd *asfd,
     530             :         const char *path,
     531             :         const char *xattrtext, size_t xlen, struct cntr *cntr)
     532             : {
     533             :         size_t l=0;
     534          13 :         int ret=-1;
     535             :         char *data=NULL;
     536          13 :         char *name=NULL;
     537          13 :         char *value=NULL;
     538             : 
     539          13 :         data=(char *)xattrtext;
     540          13 :         l=xlen;
     541          46 :         while(l>0)
     542             :         {
     543          20 :                 uint32_t s=0;
     544          20 :                 free_w(&name);
     545          20 :                 free_w(&value);
     546             : 
     547          20 :                 if(!(name=get_next_xattr_str(asfd, &data, &l,
     548             :                         cntr, &s, path))
     549          20 :                   || !(value=get_next_xattr_str(asfd, &data, &l,
     550             :                         cntr, &s, path)))
     551             :                                 goto end;
     552          20 :                 if(lsetxattr(path, name, value, s, 0))
     553             :                 {
     554           0 :                         logw(asfd, cntr, "lsetxattr error on %s: %s\n",
     555           0 :                                 path, strerror(errno));
     556           0 :                         goto end;
     557             :                 }
     558             :         }
     559             : 
     560             :         ret=0;
     561             : end:
     562          13 :         free_w(&name);
     563          13 :         free_w(&value);
     564          13 :         return ret;
     565             : }
     566             : 
     567          13 : int set_xattr(struct asfd *asfd, const char *path,
     568             :         const char *xattrtext, size_t xlen, char metacmd, struct cntr *cntr)
     569             : {
     570          13 :         switch(metacmd)
     571             :         {
     572             :                 case META_XATTR:
     573          13 :                         return do_set_xattr(asfd,
     574             :                                 path, xattrtext, xlen, cntr);
     575             :                 default:
     576           0 :                         logp("unknown xattr type: %c\n", metacmd);
     577           0 :                         logw(asfd, cntr, "unknown xattr type: %c\n", metacmd);
     578             :                         break;
     579             :         }
     580           0 :         return -1;
     581             : }
     582             : #endif
     583             : 
     584             : #ifdef UTEST
     585        1098 : int fs_supports_xattr(void)
     586             : {
     587             :         FILE *fp;
     588        1098 :         int ret=-1;
     589        1098 :         const char *fname="xattr_test_file";
     590        1098 :         if(!(fp=fopen(fname, "w")))
     591             :         {
     592           0 :                 printf("Could not open %s!\n", fname);
     593           0 :                 return 0;
     594             :         }
     595        1098 :         fclose(fp);
     596             : #ifdef HAVE_SYS_EXTATTR_H
     597             :         ret=extattr_set_link(fname, EXTATTR_NAMESPACE_USER, "comment", "a", strlen("a"));
     598             : #elif HAVE_SYS_XATTR_H
     599        1098 :         ret=lsetxattr(fname, "user.comment", "a", strlen("a"), /*flags*/0);
     600             : #else
     601             :         errno=ENOTSUP;
     602             : #endif
     603        1098 :         if(ret<0 && errno==ENOTSUP)
     604             :         {
     605           0 :                 printf("File system does not support xattrs!\n");
     606           0 :                 unlink(fname);
     607           0 :                 return 0;
     608             :         }
     609        1098 :         unlink(fname);
     610        1098 :         return 1;
     611             : }
     612             : #endif
     613             : 
     614             : #endif

Generated by: LCOV version 1.13