/* This file contains helper functions for OS/2 - don't try and compile on other platforms */ #ifdef __OS2__ #define INCL_LONGLONG #define INCL_DOS #define INCL_DOSPROCESS #define INCL_DOSPROFILE #define INCL_DOSMISC #define INCL_DOSMODULEMGR #define INCL_DOSERRORS //_SMB_H #include #include #include #include #include //YD for tmalloc #include /* these define the attribute byte as seen by DOS */ #define aRONLY (1L<<0) /* 0x01 */ #define aHIDDEN (1L<<1) /* 0x02 */ #define aSYSTEM (1L<<2) /* 0x04 */ #define aVOLID (1L<<3) /* 0x08 */ #define aDIR (1L<<4) /* 0x10 */ #define aARCH (1L<<5) /* 0x20 */ #ifndef TESTING #define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) #define CMD_KI_RDCNT (0x63) #include "local.h" #include "xfile.h" #include "pstring.h" #include "debug.h" #else #define DEBUG(a,b) (0) #endif #include #ifndef ENOATTR #define ENOATTR 22 #endif int os2_ftruncate(int fd, off_t size) { // We call there __libc_Back_ioFileSizeSet directly instead of // ftruncate to force it not to zero expanding files to optimize // samba performance when copying files int rc = __libc_Back_ioFileSizeSet(fd, size, 0); if (rc < 0) { errno = -rc; return -1; } return 0; } int os2_isattribute(char *path, unsigned short attr) { HDIR hdirFindHandle = HDIR_CREATE; FILEFINDBUF3 FindBuffer = {0}; /* Returned from FindFirst/Next */ USHORT dosattr; /* attribute to search for */ ULONG ulResultBufLen = sizeof(FILEFINDBUF3); ULONG ulFindCount = 1; /* Look for 1 file at a time */ APIRET rc = NO_ERROR; /* Return code */ if (attr==aARCH) dosattr=MUST_HAVE_ARCHIVED; else if (attr==aRONLY) dosattr=MUST_HAVE_READONLY; else if (attr==aSYSTEM) dosattr=MUST_HAVE_SYSTEM; else if (attr==aHIDDEN) dosattr=MUST_HAVE_HIDDEN; rc = DosFindFirst( path, /* File pattern - all files */ &hdirFindHandle, /* Directory search handle */ dosattr, &FindBuffer, /* Result buffer */ ulResultBufLen, /* Result buffer length */ &ulFindCount, /* Number of entries to find */ FIL_STANDARD); /* Return Level 1 file info */ if (rc != NO_ERROR) { rc = DosFindClose(hdirFindHandle); /* Close our directory handle */ return 1; } else { rc = DosFindClose(hdirFindHandle); /* Close our directory handle */ return 0; } /* endif */ } /* Functions below are based on APR random code */ /* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ void os2_randget(char * buffer, int length) { UCHAR randbyte(); unsigned int idx; for (idx=0; idx 0xFF) { errno = EINVAL; return -1; } pgea2list = (PGEA2LIST)calloc(sizeof(GEA2LIST) + namelen + 1, 1); pgea2list->list[0].oNextEntryOffset = 0; pgea2list->list[0].cbName = namelen; strcpy(pgea2list->list[0].szName, name); pgea2list->cbList = sizeof(GEA2LIST) + namelen; // max ea is 64kb pfea2list = (PFEA2LIST)calloc(sizeof(FEA2LIST) + 0x10000, 1); pfea2list->cbList = sizeof(FEA2LIST) + 0x10000; eaop2.fpGEA2List = pgea2list; eaop2.fpFEA2List = pfea2list; eaop2.oError = 0; do { if (path) { char npath[CCHMAXPATH + 1] = {0}; strncpy(npath, path, CCHMAXPATH); for (p = npath; *p; p++) { if (*p == '/') *p = '\\'; } rc = DosQueryPathInfo(npath, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2)); } else { rc = DosQueryFileInfo( file, FIL_QUERYEASFROMLIST, &eaop2, sizeof(eaop2)); } if (rc) { maperrno(rc); rc = -1; break; } if (strnicmp(pfea2list->list[0].szName, name, namelen) || pfea2list->list[0].cbValue == 0) { errno = ENOATTR; rc = -1; break; } rc = pfea2list->list[0].cbValue; if (value) { if (size < rc) { errno = ERANGE; rc = -1; } else { p = pfea2list->list[0].szName + pfea2list->list[0].cbName + 1; memcpy(value, p, rc); } } } while (0); if (pgea2list) { free(pgea2list); } if (pfea2list) { free(pfea2list); } DEBUG(4,("unigetxattr : (%s:%d) %s %d\n", path ? path : "null", file, name, rc)); return rc; } ssize_t unilistxattr (const char *path, int file, char *list, size_t size) { ssize_t gotsize = 0; unsigned long ulCount = -1; int rc; char * buf, *p = list; PFEA2 pfea; FILESTATUS4 stat = {0}; char npath[CCHMAXPATH + 1] = {0}; if (!path && !file) { errno = EINVAL; return -1; } if (path) { char * p; strncpy(npath, path, CCHMAXPATH); for (p = npath; *p; p++) { if (*p == '/') *p = '\\'; } rc = DosQueryPathInfo(npath, FIL_QUERYEASIZE, &stat, sizeof(stat)); } else { rc = DosQueryFileInfo( file, FIL_QUERYEASIZE, &stat, sizeof(stat)); } if (rc) { DEBUG(4,("unilistxattr1 : (%s:%d) %d\n", path ? path : "null", file, rc)); maperrno(rc); return -1; } if (stat.cbList <= 4) { // NO ea return 0; } //YD DosEnumAttribute doesn't like high-mem buffers, get a low one. buf = (char *)_tmalloc(stat.cbList * 2); rc = DosEnumAttribute(path ? 1 : 0, path ? (PVOID)path : (PVOID)&file, 1, (PVOID)buf, stat.cbList * 2, &ulCount, 1); if (rc) { DEBUG(4,("unilistxattr2 : (%s:%d) %d\n", path ? path : "null", file, rc)); maperrno(rc); _tfree(buf); return -1; } if (ulCount > 0) for (pfea = (PFEA2)buf;;pfea = (PFEA2)((char *)pfea + pfea->oNextEntryOffset)) { if (pfea->cbName > 0) { gotsize += pfea->cbName + 1; if (p && size >= gotsize) { pfea->szName[pfea->cbName] = 0; strcpy(p, pfea->szName); p += strlen(p) + 1; } } // had to be added to avoid crash in case of broken extended attributes if (pfea->oNextEntryOffset > 0x10000) { DEBUG(0, ("Broken Extended Attributes detected for: %s:%d\n", path ? path : "null", file)); // DEBUG(0, ("Broken Extended Attributes detected for: %s:%d, Last EA:%s\n", path ? path : "null", file, pfea->szName)); break; } if (!pfea->oNextEntryOffset) { break; } } _tfree(buf); DEBUG(4,("unilistxattr : (%s:%d) %d\n", path ? path : "null", file, gotsize)); if (gotsize > size) { errno = ERANGE; return list ? -1 : gotsize; } return gotsize; } int uniremovexattr (const char *path, int file, const char *name) { int rc, namelen; EAOP2 eaop2 = {0}; PFEA2LIST pfea2list = NULL; char buf[300] = {0}; if ((!path && !file) || !name) { errno = EINVAL; return -1; } namelen = strlen(name); if (namelen > 0xFF) { errno = EINVAL; return -1; } pfea2list = (PFEA2LIST)buf; pfea2list->list[0].cbName = namelen; pfea2list->list[0].cbValue = 0; pfea2list->list[0].fEA = 0; strcpy(pfea2list->list[0].szName, name); pfea2list->cbList = sizeof(FEA2LIST) + namelen; eaop2.fpFEA2List = pfea2list; if (path) { char npath[CCHMAXPATH + 1] = {0}; char * p; strncpy(npath, path, CCHMAXPATH); for (p = npath; *p; p++) { if (*p == '/') *p = '\\'; } rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU); } else { rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2)); } if (rc) { maperrno(rc); return -1; } return 0; } #ifndef XATTR_CREATE #define XATTR_CREATE 1 #endif #ifndef XATTR_REPLACE #define XATTR_REPLACE 2 #endif int unisetxattr (const char *path, int file, const char *name, const void *value, size_t size, int flags) { int rc, namelen, totalsize; EAOP2 eaop2 = {0}; PFEA2LIST pfea2list = NULL; char * p; if ((!path && !file) || !name || (!value && size)) { errno = EINVAL; return -1; } namelen = strlen(name); if (namelen > 0xFF) { errno = EINVAL; return -1; } if (flags & (XATTR_CREATE | XATTR_REPLACE)) { ssize_t esize = unigetxattr(path, file, name, 0, 0); if (flags & XATTR_CREATE && esize > 0) { errno = EEXIST; return -1; } if (flags & XATTR_REPLACE && esize < 0) { errno = ENOATTR; return -1; } } totalsize = sizeof(FEA2LIST) + size + namelen + 1; pfea2list = (PFEA2LIST)calloc(totalsize, 1); pfea2list->cbList = totalsize; pfea2list->list[0].oNextEntryOffset = 0; pfea2list->list[0].cbName = namelen; pfea2list->list[0].cbValue = size; strcpy(pfea2list->list[0].szName, name); if (value) { memcpy(pfea2list->list[0].szName + namelen + 1, value, size); } eaop2.fpFEA2List = pfea2list; if (path) { char npath[CCHMAXPATH + 1] = {0}; char * p; strncpy(npath, path, CCHMAXPATH); for (p = npath; *p; p++) { if (*p == '/') *p = '\\'; } rc = DosSetPathInfo(npath, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2), DSPI_WRTTHRU); } else { rc = DosSetFileInfo( file, FIL_QUERYEASIZE, &eaop2, sizeof(eaop2)); } free(pfea2list); if (rc) { maperrno(rc); return -1; } return 0; } #endif