XRootD
XrdSysFAttrBsd.icc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S y s F A t t r B s d . i c c */
4 /* */
5 /* (c) 2010 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cerrno>
32 #include <cstdio>
33 #include <cstring>
34 #include <unistd.h>
35 #include <sys/types.h>
36 #include <sys/extattr.h>
37 
38 #include "XrdSys/XrdSysFAttr.hh"
39 
40 /******************************************************************************/
41 /* X r d S y s F A t t r : : D e l */
42 /******************************************************************************/
43 
44 int XrdSysFAttr::Del(const char *Aname, const char *Path, int fd)
45 {
46  int ec;
47 
48 // Remove the attrbiute but ignore errors if it doesn't exist
49 //
50  ec = (fd < 0 ? extattr_delete_file(Path, EXTATTR_NAMESPACE_USER, Aname)
51  : extattr_delete_fd( fd, EXTATTR_NAMESPACE_USER, Aname));
52 
53 // Diagnose errors but ignore errors if it doesn't exist
54 //
55  if (ec) ec = Diagnose("remove", Aname, Path, errno);
56  return ec;
57 }
58 
59 /******************************************************************************/
60 /* X r d S y s F A t t r : : G e t */
61 /******************************************************************************/
62 
63 int XrdSysFAttr::Get(const char *Aname, void *Aval, int Avsz,
64  const char *Path, int fd)
65 {
66  int ec;
67 
68 // Obtain the attribute.
69 //
70  ec = (fd < 0 ? extattr_get_file(Path,EXTATTR_NAMESPACE_USER,Aname,Aval,Avsz)
71  : extattr_get_fd( fd, EXTATTR_NAMESPACE_USER,Aname,Aval,Avsz));
72 
73 // Diagnose errors.
74 //
75  if (ec < 0) ec = Diagnose("get", Aname, Path, errno);
76  return ec;
77 }
78 
79 /******************************************************************************/
80 /* X r d S y s F A t t r : : L i s t */
81 /******************************************************************************/
82 
83 int XrdSysFAttr::List(AList **aPL, const char *Path, int fd, int getSz)
84 {
85  AList *aNew;
86  char *Buff, *bP, *bEnd;
87  int ec, Tlen, maxSz = 0, *msP = (getSz ? &maxSz : 0);
88 
89 // First obtain the amount of storage we will need for the whole list
90 //
91  *aPL = 0;
92  Tlen = (fd < 0 ? extattr_list_file(Path,EXTATTR_NAMESPACE_USER, 0, 0)
93  : extattr_list_fd( fd,EXTATTR_NAMESPACE_USER, 0, 0));
94  if (Tlen < 0)
95  {if ((ec = Diagnose("list", "*", Path, errno)) == -ENOATTR) ec = 0;
96  return ec;
97  }
98 
99 // If we don't have any then just return 0. Otherwise, add 4K to the buffer
100 // size just in case some one is adding attributes while we get the list.
101 //
102  if (!Tlen) return 0;
103  Tlen += 4096;
104 
105 // Allocate storage to get the whole list
106 //
107  if (!(Buff = (char *)malloc(Tlen))) return -ENOMEM;
108 
109 // Now get the actual list. We will not recover if someone added an attribute
110 // since the time we actual determined the size of the buffer we need.
111 //
112  Tlen = (fd < 0 ? extattr_list_file(Path,EXTATTR_NAMESPACE_USER, Buff, Tlen)
113  : extattr_list_fd( fd,EXTATTR_NAMESPACE_USER, Buff, Tlen));
114  if (Tlen < 0)
115  {if ((ec = Diagnose("list", "*", Path, errno)) == -ENOATTR) ec = 0;
116  free(Buff);
117  return ec;
118  }
119  if (!Tlen) return 0;
120 
121 // Run through the memory and allocate an AList entry for each.
122 //
123 #ifdef __ubuntu__
124 // Ubuntu BSD returns attribute names preceeded by the length.
125 //
126  int n, i = 0;
127  char Vname[256];
128  while(i < Tlen)
129  {n = (unsigned char)Buff[i];
130  strncpy(Vname, &Buff[i+1], n);
131  Vname[n] = '\0';
132  if (n && (aNew = getEnt(Path, fd, Vname, *aPL, msP))) *aPL = aNew;
133  i += (n + 1);
134  }
135 #else
136  bP = Buff; bEnd = Buff+Tlen;
137  while(bP < bEnd)
138  {if ((aNew = getEnt(Path, fd, bP, *aPL, msP))) *aPL = aNew;
139  bP = bP + strlen(bP) + 1;
140  }
141 #endif
142 
143 // All done
144 //
145  free(Buff);
146  return maxSz;
147 }
148 
149 /******************************************************************************/
150 /* X r d S y s F A t t r : : S e t */
151 /******************************************************************************/
152 
153 int XrdSysFAttr::Set(const char *Aname, const void *Aval, int Avsz,
154  const char *Path, int fd, int isNew)
155 {
156  int ec;
157 
158 // Check if we should see if the attribute already exists as BSD always replaces
159 // or creates attributes, as needed. This is not MT safe, sigh.
160 //
161  if (isNew)
162  {ec = (fd < 0 ? extattr_get_file(Path,EXTATTR_NAMESPACE_USER,Aname,0,0)
163  : extattr_get_fd( fd, EXTATTR_NAMESPACE_USER,Aname,0,0));
164  if (ec >= 0) return -EEXIST;
165  }
166 
167 // Set the attribute
168 //
169  ec = (fd < 0 ? extattr_set_file(Path,EXTATTR_NAMESPACE_USER,Aname,Aval,Avsz)
170  : extattr_set_fd( fd, EXTATTR_NAMESPACE_USER,Aname,Aval,Avsz));
171  if (ec < 0 || ec != Avsz)
172  ec = Diagnose("set", Aname, Path, (ec < 0 ? errno : ENOSPC));
173 
174 // Return appropriately
175 //
176  return ec;
177 }
#define ENOATTR
Definition: XProtocol.hh:1342
XrdOucString Path