60 #include <sys/types.h> 62 #include <sys/param.h> 64 #include "file_help.h" 88 while(p1 > pBuf->
ppLineBuf[i1] && (*(p1 - 1) ==
'\n' || *(p1 - 1) ==
'\r'))
111 iFile = open(szFileName, O_RDONLY);
128 lFileSize = (long)lseek(iFile, 0, SEEK_END);
129 lseek(iFile, 0, SEEK_SET);
140 bzero(pRval,
sizeof(*pRval));
142 pRval->
lBufferSize =
sizeof(*pRval) + ((lFileSize + 256 + 128) & 0xffffff00L);
148 if(read(iFile, pRval->
cData, lFileSize) != lFileSize)
171 bzero(pRval,
sizeof(*pRval));
173 pRval->
lBufferSize =
sizeof(*pRval) + ((cbBuf + 256 + 128) & 0xffffff00L);
179 memcpy(pRval->
cData, pBuf, cbBuf);
212 const char *p1, *pEnd;
229 while(p1 < pEnd && *p1 !=
'\n')
262 while(p1 < pEnd && *p1 !=
'\n')
275 FBDumpParsedFileBuf(pBuf);
290 iFile = open(szFileName, O_CREAT | O_TRUNC | O_RDWR, 0666);
310 lseek(iFile, 0, SEEK_SET);
327 static int SanityCheckFileBuf(
file_help_buf_t *pBuf,
const char *szFunction)
344 static int InternalGrowFileBuf(
file_help_buf_t **ppBuf,
long cbOffset,
long cbData)
346 long lNewSize, lActualBufSize;
355 if(SanityCheckFileBuf(*ppBuf, __FUNCTION__) < 0)
360 lActualBufSize = (*ppBuf)->lBufferSize -
sizeof(**ppBuf);
362 if(cbOffset > (*ppBuf)->lBufferCount)
364 lNewSize = cbOffset + cbData;
368 lNewSize = (*ppBuf)->lBufferCount + cbData;
371 if(lActualBufSize >= lNewSize)
376 lNewSize = (lNewSize +
sizeof(*ppBuf) + 256 + 128) & 0xffffff00L;
378 WB_DEBUG_PRINT(DebugLevel_Excessive,
"TEMPORARY: reallocating - %d %d %d\n",
379 (
int)(*ppBuf)->lBufferSize, (
int)lActualBufSize, (
int)lNewSize);
381 pNew = (
char *)
WBReAlloc(*ppBuf, lNewSize);
392 lActualBufSize = lNewSize -
sizeof(**ppBuf) +
sizeof((*ppBuf)->cData);
394 if((*ppBuf)->lBufferCount < lActualBufSize)
396 memset((
char *)((*ppBuf)->cData) + (*ppBuf)->lBufferCount, 0, lActualBufSize - (*ppBuf)->lBufferCount);
411 if(InternalGrowFileBuf(ppBuf, cbOffset, cbData) < 0)
416 if((*ppBuf)->lBufferCount < cbOffset)
418 memset((
char *)((*ppBuf)->cData) + (*ppBuf)->lBufferCount,
'\n', cbOffset - (*ppBuf)->lBufferCount);
419 (*ppBuf)->lBufferCount = cbOffset;
421 else if((*ppBuf)->lBufferCount > cbOffset)
423 memmove((
char *)((*ppBuf)->cData) + cbOffset + cbData, (
char *)((*ppBuf)->cData) + cbOffset, (*ppBuf)->lBufferCount - cbOffset);
426 memcpy((
char *)((*ppBuf)->cData) + cbOffset, pData, cbData);
427 (*ppBuf)->lBufferCount += cbData;
429 SanityCheckFileBuf(*ppBuf, __FUNCTION__);
431 (*ppBuf)->iFlags |= file_help_buf_dirty;
447 else if(cbOffset + cbDelFrom < pBuf->lBufferCount)
449 memcpy(pBuf->
cData + cbOffset, pBuf->
cData + cbOffset + cbDelFrom,
456 SanityCheckFileBuf(pBuf, __FUNCTION__);
458 pBuf->
iFlags |= file_help_buf_dirty;
470 while(i2 && (szLine[i2 - 1] ==
'\n' || szLine[i2 - 1] ==
'\r'))
475 if(!(*ppBuf)->ppLineBuf)
478 if(!(*ppBuf)->ppLineBuf)
485 i1 = lLineNum - (*ppBuf)->lLineCount;
490 pDest = (*ppBuf)->ppLineBuf[lLineNum];
493 pDest = (*ppBuf)->cData + (*ppBuf)->lBufferCount;
498 pDest = (*ppBuf)->cData + (*ppBuf)->lBufferCount + i1;
501 lOffset = (
char *)pDest - (
char *)((*ppBuf)->cData);
510 WB_DEBUG_PRINT(DebugLevel_Chatty,
"%s inserting %d blank lines\n", __FUNCTION__, i1);
511 pDest = (*ppBuf)->cData + lOffset;
515 *(pDest - i1) =
'\n';
528 long lOffset, lEndOffset;
548 lEndOffset = (
char *)pBuf->
ppLineBuf[lLineNum + 1] - (
char *)(pBuf->
cData);
551 lOffset = (
char *)pBuf->
ppLineBuf[lLineNum] - (
char *)(pBuf->
cData);
553 if(lOffset < lEndOffset)
586 iFile = open(szFileName, O_RDONLY);
595 cbLen = (
unsigned long)lseek(iFile, 0, SEEK_END);
597 if(cbLen == (off_t)-1)
603 lseek(iFile, 0, SEEK_SET);
605 *ppBuf = pBuf =
WBAlloc(cbLen + 1);
624 cb1 = read(iFile, pBuf, iChunk);
637 else if(cb1 != iChunk)
650 return (
size_t) cbLen;
655 int iFile, iRval, iChunk;
663 iFile = open(szFileName, O_CREAT | O_TRUNC | O_RDWR, 0666);
680 iRval = write(iFile, pBuf, iChunk);
696 else if(iRval != iChunk)
698 WBDebugPrint(
"TEMPORARY: writing file, only wrote %d of %d bytes\n", iRval, iChunk);
718 iRval = stat(szProto, &sb);
723 iRval = chmod(szTarget, sb.st_mode & 0777);
726 if(geteuid() == 0 || getuid() == sb.st_uid)
728 iRval = chown(szTarget, sb.st_uid, sb.st_gid);
729 if(iRval < 0 && geteuid() != 0)
731 iRval = chown(szTarget, -1, sb.st_gid);
748 char *pRval =
WBAlloc(MAXPATHLEN + 2);
753 if(!getcwd(pRval, MAXPATHLEN))
766 if(i1 > 0 && pRval[i1 - 1] !=
'/')
784 hFF = FindFirstFile(szFileName, &fd);
788 bRval = (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
795 if(!stat(szFileName, &sF))
796 bRval = S_ISDIR(sF.st_mode);
805 char *pTemp, *p1, *p2, *p3, *p4, *pRval = NULL;
820 if(*p1 ==
'/' && p1[1] ==
'/')
822 memmove(p1, p1 + 1, strlen(p1 + 1) + 1);
824 else if(*p1 ==
'/' && p1[1] ==
'.' && p1[2] ==
'/')
826 memmove(p1, p1 + 2, strlen(p1 + 2) + 1);
836 if(*pTemp ==
'~' && (pTemp[1] ==
'/' || !pTemp[1]))
852 if(p3[strlen(p3) - 1] !=
'/')
876 p2 = strchr(p1,
'/');
881 if((p1[1] ==
'.' && !p1[2]) || !p1[1])
886 p1 = (p1 - p2) + pTemp;
927 if(p2 - p1 == 1 && p1[0] ==
'.')
932 else if(p2 - p1 == 2 && p1[0] ==
'.' && p1[1] ==
'.')
936 p3 = pRval + strlen(pRval) - 1;
950 WB_ERROR_PRINT(
"%s:%d - did not find preceding '/' - %s\n", __FUNCTION__, __LINE__, pRval);
966 WB_ERROR_PRINT(
"%s:%d - WBCatStringN returned NULL pointer\n", __FUNCTION__, __LINE__);
973 p3 = pRval + strlen(pRval) - 1;
977 if(lstat(pRval, &sF))
982 else if(S_ISDIR(sF.st_mode))
987 else if(S_ISLNK(sF.st_mode))
992 p4 = (
char *)
WBAlloc(MAXPATHLEN + 2);
996 WB_ERROR_PRINT(
"%s:%d - not enough memory for buffer\n", __FUNCTION__, __LINE__);
1004 int iLen = readlink(pRval, p4, MAXPATHLEN);
1008 WB_ERROR_PRINT(
"%s:%d - readlink returned %d for %s\n", __FUNCTION__, __LINE__, iLen, pRval);
1025 while(p3 > pRval && *(p3 - 1) !=
'/')
1037 WB_ERROR_PRINT(
"%s:%d - %s not a directory\n", __FUNCTION__, __LINE__, pRval);
1073 p1 = pRval + strlen(pRval) - 1;
1075 if(p1 > pRval && *p1 !=
'/')
1077 while(p1 > pRval && *(p1 - 1) !=
'/')
1082 if(!lstat(pRval, &sF))
1084 if(S_ISDIR(sF.st_mode))
1088 else if(S_ISLNK(sF.st_mode))
1093 p4 = (
char *)
WBAlloc(MAXPATHLEN + 2);
1097 WB_ERROR_PRINT(
"%s:%d - not enough memory\n", __FUNCTION__, __LINE__);
1103 int iLen = readlink(pRval, p4, MAXPATHLEN);
1107 WB_ERROR_PRINT(
"%s:%d - readlink returned %d for %s\n", __FUNCTION__, __LINE__, iLen, pRval);
1123 p3 = pRval + strlen(pRval);
1124 while(p3 > pRval && *(p3 - 1) !=
'/')
1161 WB_ERROR_PRINT(
"%s:%d - returning NULL\n", __FUNCTION__, __LINE__);
1169 typedef struct __DIRLIST__
1171 const char *szPath, *szNameSpec;
1172 #ifdef WIN32 // also true for WIN64 1180 char cde[
sizeof(
struct dirent) + NAME_MAX + 2];
1183 #endif // WIN32 or !WIN32 - that is the question 1194 if(!szDirSpec || !*szDirSpec)
1196 WB_WARN_PRINT(
"WARNING - %s - invalid directory (NULL or empty)\n", __FUNCTION__);
1200 iLen = strlen(szDirSpec);
1201 nMaxLen = iLen + 32;
1206 WB_ERROR_PRINT(
"ERROR - %s - Unable to allocate memory for buffer size %d\n", __FUNCTION__, nMaxLen);
1210 if(szDirSpec[0] ==
'/')
1212 memcpy(pBuf, szDirSpec, iLen + 1);
1219 memcpy(pBuf + 2, szDirSpec, iLen + 1);
1224 p1 = ((
char *)pBuf) + iLen;
1225 while(p1 > pBuf && *(p1 - 1) !=
'/')
1237 if(p1 == (pBuf + 1) && *pBuf ==
'/')
1255 else if(strchr(p1,
'*') || strchr(p1,
'?'))
1257 if(p1 == (pBuf + 1) && *pBuf ==
'/')
1259 memmove(p1 + 1, p1, strlen(p1) + 1);
1284 WB_WARN_PRINT(
"TEMPORARY: I am confused, %s %s\n", pBuf, p1);
1292 WB_WARN_PRINT(
"TEMPORARY: should not happen, %s %s\n", pBuf, p1);
1294 if(strchr(pBuf,
'*') || strchr(pBuf,
'?'))
1296 p1 = (
char *)pBuf + 1;
1297 memmove(pBuf, p1, iLen + 1);
1302 p1 = (
char *)pBuf + iLen;
1314 pRval =
WBAlloc(
sizeof(DIRLIST) + iLen + strlen(p1) + 2);
1318 pRval->szPath = pBuf;
1319 pRval->szNameSpec = p1;
1321 p2 = (
char *)(pRval + 1);
1326 p1 = (
char *)(pRval + 1);
1329 pRval->hFF = FindFirstFile(p2, &(pRval->fd))
1338 pRval->hD = opendir(pBuf);
1342 if(pRval->hD == NULL)
1344 WB_WARN_PRINT(
"WARNING - %s - Unable to open dir \"%s\", errno=%d\n", __FUNCTION__, pBuf, errno);
1351 #endif // WIN32,!WIN32 1355 WB_ERROR_PRINT(
"ERROR - %s - Unable to allocate memory for DIRLIST\n", __FUNCTION__);
1366 DIRLIST *pD = (DIRLIST *)pDirectoryList;
1378 #endif // WIN32,!WIN32 1381 WBFree((
void *)(pD->szPath));
1391 int cbNameReturn,
unsigned long *pdwModeAttrReturn)
1401 DIRLIST *pDL = (DIRLIST *)pDirectoryList;
1410 pBuf =
WBAlloc(strlen(pDL->szPath) + 8 + NAME_MAX);
1417 strcpy(pBuf, pDL->szPath);
1418 p1 = pBuf + strlen(pBuf);
1419 if(p1 > pBuf && *(p1 - 1) !=
'/')
1434 while((pD = readdir(pDL->hD))
1438 if(pD->d_name[0] ==
'.' &&
1440 (pD->d_name[1] ==
'.' && !pD->d_name[2])))
1446 strcpy(p1, pD->d_name);
1448 if(!lstat(pBuf, &sF))
1450 if(!fnmatch(pDL->szNameSpec, p1, 0))
1454 if(pdwModeAttrReturn)
1456 *pdwModeAttrReturn = sF.st_mode;
1459 if(szNameReturn && cbNameReturn > 0)
1461 strncpy(szNameReturn, p1, cbNameReturn);
1475 WB_WARN_PRINT(
"%s: can't 'stat' %s, errno=%d (%08xH)\n", __FUNCTION__, pBuf, errno, errno);
1480 #endif // WIN32,!WIN32 1493 char *pRval, *pBuf, *p1;
1494 DIRLIST *pDL = (DIRLIST *)pDirectoryList;
1498 if(!szFileName || !*szFileName)
1506 if(szFileName && *szFileName ==
'/')
1512 pBuf = (
char *)
WBAlloc(strlen(pDL->szPath) + 8 + (szFileName ? strlen(szFileName) : 0) + NAME_MAX);
1519 strcpy(pBuf, pDL->szPath);
1520 p1 = pBuf + strlen(pBuf);
1521 if(p1 > pBuf && *(p1 - 1) !=
'/')
1529 strcpy(p1, szFileName);
1540 char *pRval =
WBAlloc(MAXPATHLEN + 2);
1544 int iLen = readlink(szFileName, pRval, MAXPATHLEN);
1559 char *pTemp, *pRval;
1574 int WBStat(
const char *szLinkName,
unsigned long *pdwModeAttrReturn)
1580 iRval = stat(szLinkName, &sF);
1581 if(!iRval && pdwModeAttrReturn)
1583 *pdwModeAttrReturn = sF.st_mode;
1590 unsigned long *pdwModeAttrReturn)
1602 iRval =
WBStat(pTemp, pdwModeAttrReturn);
1608 #if defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1610 #else // defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1612 #endif // defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1618 iRval = stat(szFileName, &sF);
1622 #if defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1623 return (
unsigned long long)((
long long)-1);
1624 #else // defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1625 return (
unsigned long)((long)-1);
1626 #endif // defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1634 #if defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1636 #else // defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1638 #endif // defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1640 #if defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1641 unsigned long long tNewVal;
1642 #else // defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1643 unsigned long tNewVal;
1644 #endif // defined(HAVE_LONGLONG) || defined(__DOXYGEN__) 1650 #
if defined(HAVE_LONGLONG) || defined(__DOXYGEN__)
1651 tNewVal == (
unsigned long long)((
unsigned long)-1)
1653 tNewVal == (
unsigned long)((
long)-1)
1659 else if(tNewVal < tVal)
char ** ppLineBuf
array of pointers to beginning of each line (WBAlloc'd TODO: make it part of 'cData'?...
'window helper' main header file for the X11workbench Toolkit API
int FBWriteFileBufHandle(int iFile, const file_help_buf_t *pBuf)
Write the file_help_buf_t object's text data to a file using an open file handle.
long lBufferCount
number of bytes of valid data
#define WB_DEBUG_PRINT(L,...)
Preferred method of implementing conditional debug output.
file_help_buf_t * FBGetFileBuf(const char *szFileName)
Construct a file_help_buf_t from a file.
Utilities for copying and drawing text, determining text extents, and so on.
void WBCatStringN(char **ppDest, const char *pSrc, unsigned int nMaxChars)
A simple utility that concatenates a string onto the end of a 0-byte terminated WBAlloc() string up t...
void FBInsertLineIntoFileBuf(file_help_buf_t **ppBuf, long lLineNum, const char *szLine)
Insert a line of text into a file_help_buf_t object at a specific line index.
void * WBAllocDirectoryList(const char *szDirSpec)
Allocate a 'Directory List' object for a specified directory spec.
unsigned long long WBGetFileModDateTime(const char *szFileName)
Obtain the 'time_t' value for a file's modification date/time (unix time, seconds since the epoch)
int WBWriteFileFromBuffer(const char *szFileName, const char *pBuf, size_t cbBuf)
read a file's contents into a buffer, returning the length of the buffer
void FBDestroyFileBuf(file_help_buf_t *pBuf)
Destroy a file_help_buf_t object.
char cData[sizeof(char *)]
the data itself (aligned to size of a pointer)
struct tag_file_help_buf * pNext
pointer to 'next' item in linked list (NULL for last object)
void FBDeleteLineFromFileBuf(file_help_buf_t *pBuf, long lLineNum)
Delete a line of text from a file_help_buf_t object at a specific line index.
void * WBReAlloc(void *pBuf, int nNewSize)
High performance memory sub-allocator 're-allocate'.
int WBCheckFileModDateTime(const char *szFileName, unsigned long long tVal)
Compare a 64-bit unsigned integer value against a file's modification date/time (unix time,...
int WBStat(const char *szLinkName, unsigned long *pdwModeAttrReturn)
Obtain the 'stat' flags for a file name, resolving links as needed.
int WBGetDirectoryListFileStat(const void *pDirectoryList, const char *szFileName, unsigned long *pdwModeAttrReturn)
Obtain the 'stat' flags for a file name, resolving links as needed, with respect to a 'Directory List...
long lLineCount
number of lines in 'cData' when ppLineBuf not NULL
long lLineBufSize
size of memory block pointed to by 'ppLineBuf'
size_t WBReadFileIntoBuffer(const char *szFileName, char **ppBuf)
read a file's contents into a buffer, returning the length of the buffer
void * WBAlloc(int nSize)
High performance memory sub-allocator 'allocate'.
#define WB_ERROR_PRINT(...)
Preferred method of implementing an 'error level' debug message for all subsystems.
int WBIsDirectory(const char *szFileName)
Return whether a file is a directory or a symlink to a directory.
void WBFree(void *pBuf)
High performance memory sub-allocator 'free'.
int FBParseFileBuf(file_help_buf_t *pBuf)
Parse or Re-Parse the data for a file_help_buf_t object.
void FBInsertIntoFileBuf(file_help_buf_t **ppBuf, long cbOffset, const void *pData, long cbData)
Insert text into a file_help_buf_t object at a specific byte offset.
int WBNextDirectoryEntry(void *pDirectoryList, char *szNameReturn, int cbNameReturn, unsigned long *pdwModeAttrReturn)
Obtain information about the next entry in a 'Directory List'.
char * WBGetDirectoryListFileFullPath(const void *pDirectoryList, const char *szFileName)
Construct a fully qualified canonical path from a 'Directory List' object and a file name.
int FBWriteFileBuf(const char *szFileName, const file_help_buf_t *pBuf)
Write the file_help_buf_t object's text data to a file using a filename.
char * WBGetDirectoryListSymLinkTarget(const void *pDirectoryList, const char *szFileName)
Obtain the target of a symbolic link file name with respect to a 'Directory List' object.
int WBReplicateFilePermissions(const char *szProto, const char *szTarget)
replicate permissions on a target file based on another file's permissions
void FBReplaceLineInFileBuf(file_help_buf_t **ppBuf, long lLineNum, const char *szLine)
Insert a line of text into a file_help_buf_t object at a specific line index.
basic 'buffered I/O' object structure for 'FileBuf' APIs
char * WBGetCanonicalPath(const char *szFileName)
Return the canonical path for a file name (similar to POSIX 'realpath()' funtion)
char * WBGetCurrentDirectory(void)
Return allocated string containing the current working directory.
file_help_buf_t * FBGetFileBufFromBuffer(const char *pBuf, long cbBuf)
Construct a file_help_buf_t from a buffer.
char * WBGetSymLinkTarget(const char *szFileName)
Obtain the target of a symbolic link.
void WBDestroyDirectoryList(void *pDirectoryList)
Destroy a 'Directory List' object allocated by WBAllocDirectoryList()
void WBDebugPrint(const char *pFmt,...) __attribute__((format(printf
conditional debug message output
long lBufferSize
size of entire buffer
char * WBCopyString(const char *pSrc)
A simple utility that returns a WBAlloc() copy of a 0-byte terminated string.
file_help_buf_t * FBGetFileBufViaHandle(int iFile)
Construct a file_help_buf_t from a file handle.
void FBDeleteFromFileBuf(file_help_buf_t *pBuf, long cbOffset, long cbDelFrom)
Delete text from a file_help_buf_t object at a specific byte offset.
#define WB_WARN_PRINT(...)
Preferred method of implementing a 'warning level' debug message for all subsystems.
int iFlags
various bit flags
static __inline__ WB_UINT64 WBGetDebugLevel(void)
Returns the current debug level assigned by WBSetDebugLevel.
void WBCatString(char **ppDest, const char *pSrc)
A simple utility that concatenates a string onto the end of a 0-byte terminated WBAlloc() string.