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

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

Samba Server 3.3: some small adjustments for cups and unneeded function removed

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