source: trunk/samba-3.0.25pre1/source/lib/os2ea.c@ 1

Last change on this file since 1 was 1, checked in by Paul Smedley, 18 years ago

Initial code import

File size: 7.5 KB
Line 
1/* This file contains helper functions for OS/2 - don't try and compile on other platforms */
2
3#ifdef __OS2__
4
5#define INCL_LONGLONG
6#define INCL_DOS
7#define INCL_DOSERRORS
8//_SMB_H
9#include <os2.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <errno.h>
13#include <types.h>
14#ifndef TESTING
15#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
16#include "local.h"
17#include "xfile.h"
18#include "pstring.h"
19#include "debug.h"
20#else
21#define DEBUG(a,b) (0)
22#endif
23
24#include <string.h>
25
26#ifndef ENOATTR
27#define ENOATTR 22
28#endif
29
30int os2_ftruncate(int fd, off_t size)
31{
32 // We call there __libc_Back_ioFileSizeSet directly instead of
33 // ftruncate to force it not to zero expanding files to optimize
34 // samba performance when copying files
35 int rc = __libc_Back_ioFileSizeSet(fd, size, 0);
36 if (rc < 0)
37 {
38 errno = -rc;
39 return -1;
40 }
41 return 0;
42}
43
44void maperrno(int rc)
45{
46 switch (rc)
47 {
48 case ERROR_PATH_NOT_FOUND :
49 case ERROR_FILE_NOT_FOUND : errno = ENOENT; break;
50 case ERROR_INVALID_HANDLE : errno = EBADF; break;
51 case ERROR_ACCESS_DENIED : errno = EACCES; break;
52 case ERROR_BUFFER_OVERFLOW :
53 case ERROR_NOT_ENOUGH_MEMORY : errno = ERANGE; break;
54 case ERROR_INVALID_EA_NAME : errno = ENOATTR; break;
55 case ERROR_INVALID_LEVEL :
56 case ERROR_INVALID_PARAMETER : errno = EINVAL; break;
57 case ERROR_SHARING_VIOLATION : errno = EACCES; break;
58 default : errno = EINVAL;
59 }
60}
61
62ssize_t unigetxattr (const char *path, int file, const char *name, void *value, size_t size)
63{
64 int rc, namelen;
65 EAOP2 eaop2 = {0};
66 PGEA2LIST pgea2list = NULL;
67 PFEA2LIST pfea2list = NULL;
68 char * p;
69
70 if ((!path && !file) || !name)
71 {
72 errno = EINVAL;
73 return -1;
74 }
75 namelen = strlen(name);
76 if (namelen > 0xFF)
77 {
78 errno = EINVAL;
79 return -1;
80 }
81 pgea2list = (PGEA2LIST)calloc(sizeof(GEA2LIST) + namelen + 1, 1);
82 pgea2list->list[0].oNextEntryOffset = 0;
83 pgea2list->list[0].cbName = namelen;
84 strcpy(pgea2list->list[0].szName, name);
85 pgea2list->cbList = sizeof(GEA2LIST) + namelen;
86
87 // max ea is 64kb
88 pfea2list = (PFEA2LIST)calloc(sizeof(FEA2LIST) + 0x10000, 1);
89 pfea2list->cbList = sizeof(FEA2LIST) + 0x10000;
90
91 eaop2.fpGEA2List = pgea2list;
92 eaop2.fpFEA2List = pfea2list;
93 eaop2.oError = 0;
94 do
95 {
96 if (path)
97 {
98 char npath[CCHMAXPATH + 1] = {0};
99 strncpy(npath, path, CCHMAXPATH);
100 for (p = npath; *p; p++)
101 {
102 if (*p == '/') *p = '\\';
103 }
104 rc = DosQueryPathInfo(npath, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
105 }
106 else
107 {
108 rc = DosQueryFileInfo( file, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
109 }
110 if (rc)
111 {
112 maperrno(rc);
113 rc = -1;
114 break;
115 }
116 if (strnicmp(pfea2list->list[0].szName, name, namelen) || pfea2list->list[0].cbValue == 0)
117 {
118 errno = ENOATTR;
119 rc = -1;
120 break;
121 }
122 rc = pfea2list->list[0].cbValue;
123 if (value)
124 {
125 if (size < rc)
126 {
127 errno = ERANGE;
128 rc = -1;
129 }
130 else
131 {
132 p = pfea2list->list[0].szName + pfea2list->list[0].cbName + 1;
133 memcpy(value, p, rc);
134 }
135 }
136 } while (0);
137 if (pgea2list)
138 {
139 free(pgea2list);
140 }
141 if (pgea2list)
142 {
143 free(pfea2list);
144 }
145 DEBUG(4,("unigetxattr : (%s:%d) %s %d\n", path ? path : "null", file, name, rc));
146 return rc;
147}
148
149ssize_t unilistxattr (const char *path, int file, char *list, size_t size)
150{
151 ssize_t gotsize = 0;
152 unsigned long ulCount = -1;
153 int rc;
154 char * buf, *p = list;
155 PFEA2 pfea;
156 FILESTATUS4 stat = {0};
157 char npath[CCHMAXPATH + 1] = {0};
158 if (!path && !file)
159 {
160 errno = EINVAL;
161 return -1;
162 }
163 if (path)
164 {
165 char * p;
166 strncpy(npath, path, CCHMAXPATH);
167 for (p = npath; *p; p++)
168 {
169 if (*p == '/') *p = '\\';
170 }
171 rc = DosQueryPathInfo(npath, FIL_QUERYEASIZE, &stat, sizeof(stat));
172 }
173 else
174 {
175 rc = DosQueryFileInfo( file, FIL_QUERYEASIZE, &stat, sizeof(stat));
176 }
177 if (rc)
178 {
179 DEBUG(4,("unilistxattr1 : (%s:%d) %d\n", path ? path : "null", file, rc));
180 maperrno(rc);
181 return -1;
182 }
183 if (stat.cbList <= 4)
184 {
185 // NO ea
186 return 0;
187 }
188 buf = (char *)malloc(stat.cbList * 2);
189 rc = DosEnumAttribute(path ? 1 : 0, path ? (PVOID)path : (PVOID)&file, 1, (PVOID)buf, stat.cbList * 2, &ulCount, 1);
190 if (rc)
191 {
192 DEBUG(4,("unilistxattr2 : (%s:%d) %d\n", path ? path : "null", file, rc));
193 maperrno(rc);
194 free(buf);
195 return -1;
196 }
197 if (ulCount > 0)
198 for (pfea = (PFEA2)buf;;pfea = (PFEA2)((char *)pfea + pfea->oNextEntryOffset))
199 {
200 if (pfea->cbName > 0)
201 {
202 gotsize += pfea->cbName + 1;
203 if (p && size >= gotsize)
204 {
205 pfea->szName[pfea->cbName] = 0;
206 strcpy(p, pfea->szName);
207 p += strlen(p) + 1;
208 }
209 }
210 if (!pfea->oNextEntryOffset)
211 {
212 break;
213 }
214 }
215 free(buf);
216 DEBUG(4,("unilistxattr : (%s:%d) %d\n", path ? path : "null", file, gotsize));
217 if (gotsize > size)
218 {
219 errno = ERANGE;
220 return list ? -1 : gotsize;
221 }
222 return gotsize;
223}
224
225int uniremovexattr (const char *path, int file, const char *name)
226{
227 int rc, namelen;
228 EAOP2 eaop2 = {0};
229 PFEA2LIST pfea2list = NULL;
230 char buf[300] = {0};
231
232 if ((!path && !file) || !name)
233 {
234 errno = EINVAL;
235 return -1;
236 }
237
238 namelen = strlen(name);
239 if (namelen > 0xFF)
240 {
241 errno = EINVAL;
242 return -1;
243 }
244
245 pfea2list = (PFEA2LIST)buf;
246 pfea2list->list[0].cbName = namelen;
247 pfea2list->list[0].cbValue = 0;
248 pfea2list->list[0].fEA = 0;
249 strcpy(pfea2list->list[0].szName, name);
250 pfea2list->cbList = sizeof(FEA2LIST) + namelen;
251 eaop2.fpFEA2List = pfea2list;
252
253 if (path)
254 {
255 char npath[CCHMAXPATH + 1] = {0};
256 char * p;
257 strncpy(npath, path, CCHMAXPATH);
258 for (p = npath; *p; p++)
259 {
260 if (*p == '/') *p = '\\';
261 }
262 rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
263 }
264 else
265 {
266 rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
267 }
268 if (rc)
269 {
270 maperrno(rc);
271 return -1;
272 }
273 return 0;
274}
275
276#ifndef XATTR_CREATE
277#define XATTR_CREATE 1
278#endif
279#ifndef XATTR_REPLACE
280#define XATTR_REPLACE 2
281#endif
282
283int unisetxattr (const char *path, int file, const char *name, const void *value, size_t size, int flags)
284{
285 int rc, namelen, totalsize;
286 EAOP2 eaop2 = {0};
287 PFEA2LIST pfea2list = NULL;
288 char * p;
289
290 if ((!path && !file) || !name || (!value && size))
291 {
292 errno = EINVAL;
293 return -1;
294 }
295 namelen = strlen(name);
296 if (namelen > 0xFF)
297 {
298 errno = EINVAL;
299 return -1;
300 }
301
302 if (flags & (XATTR_CREATE | XATTR_REPLACE))
303 {
304 ssize_t esize = unigetxattr(path, file, name, 0, 0);
305 if (flags & XATTR_CREATE && esize > 0)
306 {
307 errno = EEXIST;
308 return -1;
309 }
310 if (flags & XATTR_REPLACE && esize < 0)
311 {
312 errno = ENOATTR;
313 return -1;
314 }
315 }
316
317 totalsize = sizeof(GEALIST) + size + namelen + 1;
318
319 pfea2list = (PFEA2LIST)calloc(totalsize, 1);
320 pfea2list->cbList = totalsize;
321 pfea2list->list[0].oNextEntryOffset = 0;
322 pfea2list->list[0].cbName = namelen;
323 pfea2list->list[0].cbValue = size;
324 strcpy(pfea2list->list[0].szName, name);
325 if (value)
326 {
327 memcpy(pfea2list->list[0].szName + namelen + 1, value, size);
328 }
329 eaop2.fpFEA2List = pfea2list;
330
331 if (path)
332 {
333 char npath[CCHMAXPATH + 1] = {0};
334 char * p;
335 strncpy(npath, path, CCHMAXPATH);
336 for (p = npath; *p; p++)
337 {
338 if (*p == '/') *p = '\\';
339 }
340 rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
341 }
342 else
343 {
344 rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
345 }
346 free(pfea2list);
347 if (rc)
348 {
349 maperrno(rc);
350 return -1;
351 }
352 return 0;
353}
354
355#endif
Note: See TracBrowser for help on using the repository browser.