source: branches/samba-3.3.x/source/lib/os2helper.c@ 467

Last change on this file since 467 was 462, checked in by Herwig Bauernfeind, 15 years ago

os2helper.c cosmetic changes

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