source: trunk/server/source3/lib/os2helper.c@ 646

Last change on this file since 646 was 646, checked in by Silvan Scherrer, 14 years ago

Samba Server 3.5: some small adjustments and unneeded function removed

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