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

Last change on this file since 462 was 462, checked in by Herwig Bauernfeind, 10 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.