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

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

Fix missing function os2_randget in lib/os2ea.c

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