source: trunk/samba-3.0.25pre1/source/ndpsmb/os2ea.c@ 5

Last change on this file since 5 was 5, checked in by Yuri Dario, 18 years ago

OS/2 client code, initial import.

  • Property svn:eol-style set to native
File size: 9.9 KB
Line 
1#define INCL_LONGLONG
2#define INCL_DOS
3#define INCL_DOSERRORS
4//_SMB_H
5#include <os2.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <errno.h>
9#include <types.h>
10#ifndef TESTING
11#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
12#include "local.h"
13#include "xfile.h"
14#include "pstring.h"
15#include "debug.h"
16#else
17#define DEBUG(a,b) (0)
18#endif
19
20#include <string.h>
21
22#ifndef ENOATTR
23#define ENOATTR 22
24#endif
25
26static void maperrno(int rc)
27{
28 switch (rc)
29 {
30 case ERROR_PATH_NOT_FOUND :
31 case ERROR_FILE_NOT_FOUND : errno = ENOENT; break;
32 case ERROR_INVALID_HANDLE : errno = EBADF; break;
33 case ERROR_ACCESS_DENIED : errno = EACCES; break;
34 case ERROR_BUFFER_OVERFLOW :
35 case ERROR_NOT_ENOUGH_MEMORY : errno = ERANGE; break;
36 case ERROR_INVALID_EA_NAME : errno = ENOATTR; break;
37 case ERROR_INVALID_LEVEL :
38 case ERROR_INVALID_PARAMETER : errno = EINVAL; break;
39 case ERROR_SHARING_VIOLATION : errno = EACCES; break;
40 default : errno = EINVAL;
41 }
42}
43
44static ssize_t unigetxattr (const char *path, int file, const char *name, void *value, size_t size)
45{
46 int rc, namelen;
47 EAOP2 eaop2 = {0};
48 PGEA2LIST pgea2list = NULL;
49 PFEA2LIST pfea2list = NULL;
50 char * p;
51
52 if ((!path && !file) || !name)
53 {
54 errno = EINVAL;
55 return -1;
56 }
57 namelen = strlen(name);
58 if (namelen > 0xFF)
59 {
60 errno = EINVAL;
61 return -1;
62 }
63 pgea2list = (PGEA2LIST)calloc(sizeof(GEA2LIST) + namelen + 1, 1);
64 pgea2list->list[0].oNextEntryOffset = 0;
65 pgea2list->list[0].cbName = namelen;
66 strcpy(pgea2list->list[0].szName, name);
67 pgea2list->cbList = sizeof(GEA2LIST) + namelen;
68
69 // max ea is 64kb
70 pfea2list = (PFEA2LIST)calloc(sizeof(FEA2LIST) + 0x10000, 1);
71 pfea2list->cbList = sizeof(FEA2LIST) + 0x10000;
72
73 eaop2.fpGEA2List = pgea2list;
74 eaop2.fpFEA2List = pfea2list;
75 eaop2.oError = 0;
76 do
77 {
78 if (path)
79 {
80 char npath[CCHMAXPATH + 1] = {0};
81 strncpy(npath, path, CCHMAXPATH);
82 for (p = npath; *p; p++)
83 {
84 if (*p == '/') *p = '\\';
85 }
86 rc = DosQueryPathInfo(npath, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
87 }
88 else
89 {
90 rc = DosQueryFileInfo( file, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
91 }
92 if (rc)
93 {
94 maperrno(rc);
95 rc = -1;
96 break;
97 }
98 if (strnicmp(pfea2list->list[0].szName, name, namelen) || pfea2list->list[0].cbValue == 0)
99 {
100 errno = ENOATTR;
101 rc = -1;
102 break;
103 }
104 rc = pfea2list->list[0].cbValue;
105 if (value)
106 {
107 if (size < rc)
108 {
109 errno = ERANGE;
110 rc = -1;
111 }
112 else
113 {
114 p = pfea2list->list[0].szName + pfea2list->list[0].cbName + 1;
115 memcpy(value, p, rc);
116 }
117 }
118 } while (0);
119 if (pgea2list)
120 {
121 free(pgea2list);
122 }
123 if (pgea2list)
124 {
125 free(pfea2list);
126 }
127 DEBUG(4,("unigetxattr : (%s:%d) %s %d\n", path ? path : "null", file, name, rc));
128 return rc;
129}
130
131ssize_t getxattr (const char *path, const char *name, void *value, size_t size)
132{
133 return unigetxattr(path, 0, name, value, size);
134}
135
136ssize_t lgetxattr (const char *path, const char *name, void *value, size_t size)
137{
138 return unigetxattr(path, 0, name, value, size);
139}
140
141ssize_t fgetxattr (int filedes, const char *name, void *value, size_t size)
142{
143 return unigetxattr(0, filedes, name, value, size);
144}
145
146static ssize_t unilistxattr (const char *path, int file, char *list, size_t size)
147{
148 ssize_t gotsize = 0;
149 unsigned long ulCount = -1;
150 int rc;
151 char * buf, *p = list;
152 PFEA2 pfea;
153 FILESTATUS4 stat = {0};
154 char npath[CCHMAXPATH + 1] = {0};
155 if (!path && !file)
156 {
157 errno = EINVAL;
158 return -1;
159 }
160 if (path)
161 {
162 char * p;
163 strncpy(npath, path, CCHMAXPATH);
164 for (p = npath; *p; p++)
165 {
166 if (*p == '/') *p = '\\';
167 }
168 rc = DosQueryPathInfo(npath, FIL_QUERYEASIZE, &stat, sizeof(stat));
169 }
170 else
171 {
172 rc = DosQueryFileInfo( file, FIL_QUERYEASIZE, &stat, sizeof(stat));
173 }
174 if (rc)
175 {
176 DEBUG(4,("unilistxattr1 : (%s:%d) %d\n", path ? path : "null", file, rc));
177 maperrno(rc);
178 return -1;
179 }
180 if (stat.cbList <= 4)
181 {
182 // NO ea
183 return 0;
184 }
185 buf = (char *)malloc(stat.cbList * 2);
186 rc = DosEnumAttribute(path ? 1 : 0, path ? (PVOID)path : (PVOID)&file, 1, (PVOID)buf, stat.cbList * 2, &ulCount, 1);
187 if (rc)
188 {
189 DEBUG(4,("unilistxattr2 : (%s:%d) %d\n", path ? path : "null", file, rc));
190 maperrno(rc);
191 free(buf);
192 return -1;
193 }
194 if (ulCount > 0)
195 for (pfea = (PFEA2)buf;;pfea = (PFEA2)((char *)pfea + pfea->oNextEntryOffset))
196 {
197 if (pfea->cbName > 0)
198 {
199 gotsize += pfea->cbName + 1;
200 if (p && size >= gotsize)
201 {
202 pfea->szName[pfea->cbName] = 0;
203 strcpy(p, pfea->szName);
204 p += strlen(p) + 1;
205 }
206 }
207 if (!pfea->oNextEntryOffset)
208 {
209 break;
210 }
211 }
212 free(buf);
213 DEBUG(4,("unilistxattr : (%s:%d) %d\n", path ? path : "null", file, gotsize));
214 if (gotsize > size)
215 {
216 errno = ERANGE;
217 return list ? -1 : gotsize;
218 }
219 return gotsize;
220}
221
222ssize_t listxattr (const char *path, char *list, size_t size)
223{
224 return unilistxattr(path, 0, list, size);
225}
226
227ssize_t llistxattr (const char *path, char *list, size_t size)
228{
229 return unilistxattr(path, 0, list, size);
230}
231
232ssize_t flistxattr (int file, char *list, size_t size)
233{
234 return unilistxattr(0, file, list, size);
235}
236
237static int uniremovexattr (const char *path, int file, const char *name)
238{
239 int rc, namelen;
240 EAOP2 eaop2 = {0};
241 PFEA2LIST pfea2list = NULL;
242 char buf[300] = {0};
243
244 if ((!path && !file) || !name)
245 {
246 errno = EINVAL;
247 return -1;
248 }
249
250 namelen = strlen(name);
251 if (namelen > 0xFF)
252 {
253 errno = EINVAL;
254 return -1;
255 }
256
257 pfea2list = (PFEA2LIST)buf;
258 pfea2list->list[0].cbName = namelen;
259 pfea2list->list[0].cbValue = 0;
260 pfea2list->list[0].fEA = 0;
261 strcpy(pfea2list->list[0].szName, name);
262 pfea2list->cbList = sizeof(FEA2LIST) + namelen;
263 eaop2.fpFEA2List = pfea2list;
264
265 if (path)
266 {
267 char npath[CCHMAXPATH + 1] = {0};
268 char * p;
269 strncpy(npath, path, CCHMAXPATH);
270 for (p = npath; *p; p++)
271 {
272 if (*p == '/') *p = '\\';
273 }
274 rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
275 }
276 else
277 {
278 rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
279 }
280 if (rc)
281 {
282 maperrno(rc);
283 return -1;
284 }
285 return 0;
286}
287
288int removexattr (const char *path, const char *name)
289{
290 return uniremovexattr (path, 0, name);
291}
292
293int lremovexattr (const char *path, const char *name)
294{
295 return uniremovexattr (path, 0, name);
296}
297
298int fremovexattr (int file, const char *name)
299{
300 return uniremovexattr (0, file, name);
301}
302
303#ifndef XATTR_CREATE
304#define XATTR_CREATE 1
305#endif
306#ifndef XATTR_REPLACE
307#define XATTR_REPLACE 2
308#endif
309
310static int unisetxattr (const char *path, int file, const char *name, const void *value, size_t size, int flags)
311{
312 int rc, namelen, totalsize;
313 EAOP2 eaop2 = {0};
314 PFEA2LIST pfea2list = NULL;
315 char * p;
316
317 if ((!path && !file) || !name || (!value && size))
318 {
319 errno = EINVAL;
320 return -1;
321 }
322 namelen = strlen(name);
323 if (namelen > 0xFF)
324 {
325 errno = EINVAL;
326 return -1;
327 }
328
329 if (flags & (XATTR_CREATE | XATTR_REPLACE))
330 {
331 ssize_t esize = unigetxattr(path, file, name, 0, 0);
332 if (flags & XATTR_CREATE && esize > 0)
333 {
334 errno = EEXIST;
335 return -1;
336 }
337 if (flags & XATTR_REPLACE && esize < 0)
338 {
339 errno = ENOATTR;
340 return -1;
341 }
342 }
343
344 totalsize = sizeof(GEALIST) + size + namelen + 1;
345
346 pfea2list = (PFEA2LIST)calloc(totalsize, 1);
347 pfea2list->cbList = totalsize;
348 pfea2list->list[0].oNextEntryOffset = 0;
349 pfea2list->list[0].cbName = namelen;
350 pfea2list->list[0].cbValue = size;
351 strcpy(pfea2list->list[0].szName, name);
352 if (value)
353 {
354 memcpy(pfea2list->list[0].szName + namelen + 1, value, size);
355 }
356 eaop2.fpFEA2List = pfea2list;
357
358 if (path)
359 {
360 char npath[CCHMAXPATH + 1] = {0};
361 char * p;
362 strncpy(npath, path, CCHMAXPATH);
363 for (p = npath; *p; p++)
364 {
365 if (*p == '/') *p = '\\';
366 }
367 rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
368 }
369 else
370 {
371 rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
372 }
373 free(pfea2list);
374 if (rc)
375 {
376 maperrno(rc);
377 return -1;
378 }
379 return 0;
380}
381
382int setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
383{
384 return unisetxattr (path, 0, name, value, size, flags);
385}
386
387int lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
388{
389 return unisetxattr (path, 0, name, value, size, flags);
390}
391
392int fsetxattr (int file, const char *name, const void *value, size_t size, int flags)
393{
394 return unisetxattr (0, file, name, value, size, flags);
395}
396
397#ifdef TESTING
398#include <fcntl.h>
399#include <sys/stat.h>
400
401 int main(int argc, char ** argv)
402{
403 int rc;
404 if (argc < 2)
405 {
406 char * p = strrchr(*argv, '\\');
407 p = p ? p + 1 : *argv;
408 printf("Usage: %s <file1> [<file2> ...]\n", p);
409 return 1;
410 }
411 for (argc--, argv++; argc > 0; argc--, argv++)
412 {
413 char * ealist, * p;
414 ssize_t ealistsize;
415 printf("Processing file <%s>\n", *argv);
416 ealistsize = listxattr(*argv, 0, 0);
417 printf("EA list size %ld\n", ealistsize);
418/*
419 if (ealistsize)
420 {
421 continue;
422 }
423*/
424 ealist = malloc(ealistsize);
425 ealistsize = listxattr(*argv, ealist, ealistsize);
426 printf("EA list size2 %ld\n", ealistsize);
427 if (ealistsize > 0)
428 {
429 int file = open(*argv, O_RDWR | O_BINARY, S_IREAD | S_IWRITE);
430 if (file < 0)
431 {
432 printf("Cant open file <%s> : %d\n", *argv, errno);
433 continue;
434 }
435 for (p = ealist; (p - ealist) < ealistsize && *p; p += strlen(p) + 1)
436 {
437 ssize_t easize;
438 unsigned char * eavalue;
439 printf("EA name <%s>\n", p);
440 easize = fgetxattr(file, p, 0, 0);
441 printf("EA size %ld\n", easize);
442 eavalue = malloc(easize);
443 easize = fgetxattr(file, p, eavalue, easize);
444 printf("EA size2 %ld\n", easize);
445/*
446 if (easize > 0)
447 {
448 unsigned char * q;
449 printf("Eavalue :");
450 for (q = eavalue; q - eavalue < easize; q++)
451 {
452 printf(" %02x", *q);
453 }
454 printf("\n");
455 }
456*/
457 free(eavalue);
458 }
459 rc = fremovexattr(file, ealist);
460 printf("remove <%s> rc %d\n", ealist, rc);
461
462 rc = fsetxattr(file, "XYZ3", "QWERTY", 6, 0);
463 printf("set rc %d\n", rc);
464/*
465 rc = fsetxattr(file, "XYZ3", "QWERTY", 6, XATTR_REPLACE);
466 printf("set rc %d\n", rc);
467*/
468 free(ealist);
469 close(file);
470 }
471 }
472 return 0;
473}
474#endif
Note: See TracBrowser for help on using the repository browser.