XRootD
Loading...
Searching...
No Matches
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
44int 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
63int 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
83int 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
153int 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
XrdOucString Path