source: branches/samba-3.3.x/source/lib/os2ea.c@ 221

Last change on this file since 221 was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 10.8 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_DOSPROCESS
8#define INCL_DOSPROFILE
9#define INCL_DOSMISC
10#define INCL_DOSMODULEMGR
11#define INCL_DOSERRORS
12//_SMB_H
13#include <os2.h>
14#include <stdio.h>
15#include <stdlib.h>
16#include <errno.h>
17#include <types.h>
18
19//YD for tmalloc
20#include <malloc.h>
21
22/* these define the attribute byte as seen by DOS */
23#define aRONLY (1L<<0) /* 0x01 */
24#define aHIDDEN (1L<<1) /* 0x02 */
25#define aSYSTEM (1L<<2) /* 0x04 */
26#define aVOLID (1L<<3) /* 0x08 */
27#define aDIR (1L<<4) /* 0x10 */
28#define aARCH (1L<<5) /* 0x20 */
29
30#ifndef TESTING
31#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2)))
32#define CMD_KI_RDCNT (0x63)
33
34typedef struct _CPUUTIL {
35 ULONG ulTimeLow; /* Low 32 bits of time stamp */
36 ULONG ulTimeHigh; /* High 32 bits of time stamp */
37 ULONG ulIdleLow; /* Low 32 bits of idle time */
38 ULONG ulIdleHigh; /* High 32 bits of idle time */
39 ULONG ulBusyLow; /* Low 32 bits of busy time */
40 ULONG ulBusyHigh; /* High 32 bits of busy time */
41 ULONG ulIntrLow; /* Low 32 bits of interrupt time */
42 ULONG ulIntrHigh; /* High 32 bits of interrupt time */
43 } CPUUTIL;
44
45#include "local.h"
46#include "xfile.h"
47#define DEBUG(a,b) (0)
48
49#else
50
51#define DEBUG(a,b) (0)
52#endif
53
54#include <string.h>
55
56#ifndef ENOATTR
57#define ENOATTR 22
58#endif
59
60int os2_ftruncate(int fd, off_t size)
61{
62 // We call there __libc_Back_ioFileSizeSet directly instead of
63 // ftruncate to force it not to zero expanding files to optimize
64 // samba performance when copying files
65 int rc = __libc_Back_ioFileSizeSet(fd, size, 0);
66 if (rc < 0)
67 {
68 errno = -rc;
69 return -1;
70 }
71 return 0;
72}
73
74int os2_isattribute(char *path, unsigned short attr)
75{
76 HDIR hdirFindHandle = HDIR_CREATE;
77 FILEFINDBUF3 FindBuffer = {0}; /* Returned from FindFirst/Next */
78 USHORT dosattr; /* attribute to search for */
79 ULONG ulResultBufLen = sizeof(FILEFINDBUF3);
80 ULONG ulFindCount = 1; /* Look for 1 file at a time */
81 APIRET rc = NO_ERROR; /* Return code */
82 if (attr==aARCH)
83 dosattr=MUST_HAVE_ARCHIVED;
84 else if (attr==aRONLY)
85 dosattr=MUST_HAVE_READONLY;
86 else if (attr==aSYSTEM)
87 dosattr=MUST_HAVE_SYSTEM;
88 else if (attr==aHIDDEN)
89 dosattr=MUST_HAVE_HIDDEN;
90
91 rc = DosFindFirst( path, /* File pattern - all files */
92 &hdirFindHandle, /* Directory search handle */
93 dosattr,
94 &FindBuffer, /* Result buffer */
95 ulResultBufLen, /* Result buffer length */
96 &ulFindCount, /* Number of entries to find */
97 FIL_STANDARD); /* Return Level 1 file info */
98
99 if (rc != NO_ERROR) {
100 rc = DosFindClose(hdirFindHandle); /* Close our directory handle */
101 return 1;
102
103 } else {
104 rc = DosFindClose(hdirFindHandle); /* Close our directory handle */
105 return 0;
106
107 } /* endif */
108
109}
110
111// very simple random data gatherer derived from openssl
112void os2_randget(char * buffer, int length)
113{
114 QWORD qwTime;
115 ULONG SysVars[QSV_FOREGROUND_PROCESS];
116 int done = 0;
117
118 if (!buffer || length <= 0)
119 {
120 return;
121 }
122
123 DosTmrQueryTime(&qwTime);
124 memcpy(buffer, &qwTime, sizeof(qwTime) > length ? length : sizeof(qwTime));
125 done += sizeof(qwTime);
126 if (done >= length)
127 {
128 return;
129 }
130
131 if (DosPerfSysCall)
132 {
133 CPUUTIL util;
134 if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0)
135 {
136 memcpy(buffer + done, &util, sizeof(util) > length - done ? length - done : sizeof(util));
137 done += sizeof(util);
138 if (done >= length)
139 {
140 return;
141 }
142 }
143 }
144
145 DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars));
146 memcpy(buffer + done, SysVars, sizeof(SysVars) > length - done ? length - done : sizeof(SysVars));
147}
148
149
150void maperrno(int rc)
151{
152 switch (rc)
153 {
154 case ERROR_PATH_NOT_FOUND :
155 case ERROR_FILE_NOT_FOUND : errno = ENOENT; break;
156 case ERROR_INVALID_HANDLE : errno = EBADF; break;
157 case ERROR_ACCESS_DENIED : errno = EACCES; break;
158 case ERROR_BUFFER_OVERFLOW :
159 case ERROR_NOT_ENOUGH_MEMORY : errno = ERANGE; break;
160 case ERROR_INVALID_EA_NAME : errno = ENOATTR; break;
161 case ERROR_INVALID_LEVEL :
162 case ERROR_INVALID_PARAMETER : errno = EINVAL; break;
163 case ERROR_SHARING_VIOLATION : errno = EACCES; break;
164 default : errno = EINVAL;
165 }
166}
167
168ssize_t unigetxattr (const char *path, int file, const char *name, void *value, size_t size)
169{
170 int rc, namelen;
171 EAOP2 eaop2 = {0};
172 PGEA2LIST pgea2list = NULL;
173 PFEA2LIST pfea2list = NULL;
174 char * p;
175
176 if ((!path && !file) || !name)
177 {
178 errno = EINVAL;
179 return -1;
180 }
181 namelen = strlen(name);
182 if (namelen > 0xFF)
183 {
184 errno = EINVAL;
185 return -1;
186 }
187 pgea2list = (PGEA2LIST)calloc(sizeof(GEA2LIST) + namelen + 1, 1);
188 pgea2list->list[0].oNextEntryOffset = 0;
189 pgea2list->list[0].cbName = namelen;
190 strcpy(pgea2list->list[0].szName, name);
191 pgea2list->cbList = sizeof(GEA2LIST) + namelen;
192
193 // max ea is 64kb
194 pfea2list = (PFEA2LIST)calloc(sizeof(FEA2LIST) + 0x10000, 1);
195 pfea2list->cbList = sizeof(FEA2LIST) + 0x10000;
196
197 eaop2.fpGEA2List = pgea2list;
198 eaop2.fpFEA2List = pfea2list;
199 eaop2.oError = 0;
200 do
201 {
202 if (path)
203 {
204 char npath[CCHMAXPATH + 1] = {0};
205 strncpy(npath, path, CCHMAXPATH);
206 for (p = npath; *p; p++)
207 {
208 if (*p == '/') *p = '\\';
209 }
210 rc = DosQueryPathInfo(npath, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
211 }
212 else
213 {
214 rc = DosQueryFileInfo( file, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2));
215 }
216 if (rc)
217 {
218 maperrno(rc);
219 rc = -1;
220 break;
221 }
222 if (strnicmp(pfea2list->list[0].szName, name, namelen) || pfea2list->list[0].cbValue == 0)
223 {
224 errno = ENOATTR;
225 rc = -1;
226 break;
227 }
228 rc = pfea2list->list[0].cbValue;
229 if (value)
230 {
231 if (size < rc)
232 {
233 errno = ERANGE;
234 rc = -1;
235 }
236 else
237 {
238 p = pfea2list->list[0].szName + pfea2list->list[0].cbName + 1;
239 memcpy(value, p, rc);
240 }
241 }
242 } while (0);
243 if (pgea2list)
244 {
245 free(pgea2list);
246 }
247 if (pgea2list)
248 {
249 free(pfea2list);
250 }
251 DEBUG(4,("unigetxattr : (%s:%d) %s %d\n", path ? path : "null", file, name, rc));
252 return rc;
253}
254
255ssize_t unilistxattr (const char *path, int file, char *list, size_t size)
256{
257 ssize_t gotsize = 0;
258 unsigned long ulCount = -1;
259 int rc;
260 char * buf, *p = list;
261 PFEA2 pfea;
262 FILESTATUS4 stat = {0};
263 char npath[CCHMAXPATH + 1] = {0};
264 if (!path && !file)
265 {
266 errno = EINVAL;
267 return -1;
268 }
269 if (path)
270 {
271 char * p;
272 strncpy(npath, path, CCHMAXPATH);
273 for (p = npath; *p; p++)
274 {
275 if (*p == '/') *p = '\\';
276 }
277 rc = DosQueryPathInfo(npath, FIL_QUERYEASIZE, &stat, sizeof(stat));
278 }
279 else
280 {
281 rc = DosQueryFileInfo( file, FIL_QUERYEASIZE, &stat, sizeof(stat));
282 }
283 if (rc)
284 {
285 DEBUG(4,("unilistxattr1 : (%s:%d) %d\n", path ? path : "null", file, rc));
286 maperrno(rc);
287 return -1;
288 }
289 if (stat.cbList <= 4)
290 {
291 // NO ea
292 return 0;
293 }
294 //YD DosEnumAttribute doesn't like high-mem buffers, get a low one.
295 buf = (char *)_tmalloc(stat.cbList * 2);
296 rc = DosEnumAttribute(path ? 1 : 0, path ? (PVOID)path : (PVOID)&file, 1, (PVOID)buf, stat.cbList * 2, &ulCount, 1);
297 if (rc)
298 {
299 DEBUG(4,("unilistxattr2 : (%s:%d) %d\n", path ? path : "null", file, rc));
300 maperrno(rc);
301 _tfree(buf);
302 return -1;
303 }
304 if (ulCount > 0)
305 for (pfea = (PFEA2)buf;;pfea = (PFEA2)((char *)pfea + pfea->oNextEntryOffset))
306 {
307 if (pfea->cbName > 0)
308 {
309 gotsize += pfea->cbName + 1;
310 if (p && size >= gotsize)
311 {
312 pfea->szName[pfea->cbName] = 0;
313 strcpy(p, pfea->szName);
314 p += strlen(p) + 1;
315 }
316 }
317 if (!pfea->oNextEntryOffset)
318 {
319 break;
320 }
321 }
322 _tfree(buf);
323 DEBUG(4,("unilistxattr : (%s:%d) %d\n", path ? path : "null", file, gotsize));
324 if (gotsize > size)
325 {
326 errno = ERANGE;
327 return list ? -1 : gotsize;
328 }
329 return gotsize;
330}
331
332int uniremovexattr (const char *path, int file, const char *name)
333{
334 int rc, namelen;
335 EAOP2 eaop2 = {0};
336 PFEA2LIST pfea2list = NULL;
337 char buf[300] = {0};
338
339 if ((!path && !file) || !name)
340 {
341 errno = EINVAL;
342 return -1;
343 }
344
345 namelen = strlen(name);
346 if (namelen > 0xFF)
347 {
348 errno = EINVAL;
349 return -1;
350 }
351
352 pfea2list = (PFEA2LIST)buf;
353 pfea2list->list[0].cbName = namelen;
354 pfea2list->list[0].cbValue = 0;
355 pfea2list->list[0].fEA = 0;
356 strcpy(pfea2list->list[0].szName, name);
357 pfea2list->cbList = sizeof(FEA2LIST) + namelen;
358 eaop2.fpFEA2List = pfea2list;
359
360 if (path)
361 {
362 char npath[CCHMAXPATH + 1] = {0};
363 char * p;
364 strncpy(npath, path, CCHMAXPATH);
365 for (p = npath; *p; p++)
366 {
367 if (*p == '/') *p = '\\';
368 }
369 rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
370 }
371 else
372 {
373 rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
374 }
375 if (rc)
376 {
377 maperrno(rc);
378 return -1;
379 }
380 return 0;
381}
382
383#ifndef XATTR_CREATE
384#define XATTR_CREATE 1
385#endif
386#ifndef XATTR_REPLACE
387#define XATTR_REPLACE 2
388#endif
389
390int unisetxattr (const char *path, int file, const char *name, const void *value, size_t size, int flags)
391{
392 int rc, namelen, totalsize;
393 EAOP2 eaop2 = {0};
394 PFEA2LIST pfea2list = NULL;
395 char * p;
396
397 if ((!path && !file) || !name || (!value && size))
398 {
399 errno = EINVAL;
400 return -1;
401 }
402 namelen = strlen(name);
403 if (namelen > 0xFF)
404 {
405 errno = EINVAL;
406 return -1;
407 }
408
409 if (flags & (XATTR_CREATE | XATTR_REPLACE))
410 {
411 ssize_t esize = unigetxattr(path, file, name, 0, 0);
412 if (flags & XATTR_CREATE && esize > 0)
413 {
414 errno = EEXIST;
415 return -1;
416 }
417 if (flags & XATTR_REPLACE && esize < 0)
418 {
419 errno = ENOATTR;
420 return -1;
421 }
422 }
423
424 totalsize = sizeof(FEA2LIST) + size + namelen + 1;
425
426 pfea2list = (PFEA2LIST)calloc(totalsize, 1);
427 pfea2list->cbList = totalsize;
428 pfea2list->list[0].oNextEntryOffset = 0;
429 pfea2list->list[0].cbName = namelen;
430 pfea2list->list[0].cbValue = size;
431 strcpy(pfea2list->list[0].szName, name);
432 if (value)
433 {
434 memcpy(pfea2list->list[0].szName + namelen + 1, value, size);
435 }
436 eaop2.fpFEA2List = pfea2list;
437
438 if (path)
439 {
440 char npath[CCHMAXPATH + 1] = {0};
441 char * p;
442 strncpy(npath, path, CCHMAXPATH);
443 for (p = npath; *p; p++)
444 {
445 if (*p == '/') *p = '\\';
446 }
447 rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU);
448 }
449 else
450 {
451 rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2));
452 }
453 free(pfea2list);
454 if (rc)
455 {
456 maperrno(rc);
457 return -1;
458 }
459 return 0;
460}
461
462#endif
Note: See TracBrowser for help on using the repository browser.