/* Copyright (c) 2000-2010, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dksf.c System functions. */ #include "dk.h" #include "dktypes.h" #include "dksfc.h" #include "dkmem.h" #include "dkstr.h" #include "dkerror.h" #include #line 53 "dksf.ctr" #if DK_HAVE_DOS_H #include #endif #if DK_HAVE_IO_H #include #endif #if DK_HAVE_STDLIB_H #include #endif #if DK_HAVE_STDDEF_H #include #endif #if DK_HAVE_STRING_H #include #endif #if DK_HAVE_SYS_TYPES_H #include #endif #if DK_HAVE_SYS_UIO_H #include #endif #if DK_HAVE_SYS_STAT_H #include #endif #if DK_HAVE_SYS_SYSTEMINFO_H #include #endif #if DK_HAVE_SYS_PARAM_H #include #endif #if DK_HAVE_SYS_RESOURCE_H #include #endif #if DK_HAVE_FCNTL_H #include #endif #if DK_HAVE_TERMIOS_H #include #endif #if DK_HAVE_SYS_TERMIOS_H #include #endif #if DK_HAVE_SYS_TTOLD_H #include #endif #if DK_HAVE_WINCON_H #include #endif #if DK_HAVE_UNISTD_H #include #endif #if DK_HAVE_DIRECT_H #include #endif #if DK_HAVE_DIRENT_H #include #endif #if DK_HAVE_DIR_H #include #endif #if DK_HAVE_PWD_H #include #endif #if DK_HAVE_PROCESS_H #include #endif #include "dkwin.h" #if DK_HAVE_ERRNO_H #include #endif #include "dkmem.h" /** Inside the dksf module. */ #define DK_SYSFCT_C 1 #include "dksf.h" /** Abbreviation for tm. */ typedef struct tm STRUCTTM; #ifdef MY_MAXPATHLEN #undef MY_MAXPATHLEN #endif #ifdef MAXPATHLEN /** Maximum path length. */ #define MY_MAXPATHLEN MAXPATHLEN #else #ifdef _MAX_PATH /** Maximum path length. */ #define MY_MAXPATHLEN _MAX_PATH #else /** Maximum path length. */ #define MY_MAXPATHLEN 1024L #endif #endif /** Separator between path components. */ static char path_component_separator[] = { #if DK_HAVE_FEATURE_BACKSLASH "\\" #else "/" #endif }; /** Other delimiter, not a separator between path components. */ static char no_component_separator[] = { #if DK_HAVE_FEATURE_BACKSLASH "/" #else "\\" #endif }; /** The /var/run directory. */ static char var_run[] = { DK_LOCALSTATEDIR "/run" }; /** Suffix to use for PID files. */ static char suffix_pid[] = { ".pid" }; #ifdef USE_FNE #undef USE_FNE #endif #if defined(WIN32) || defined(_WIN32) /* + Win32 */ #if DK_HAVE__FINDFIRST64 /* Win32, _findfirst64 */ /** Flag: Use file name expander. */ #define USE_FNE 1 #else #if DK_HAVE__FINDFIRST32 /* Win32, _findfirst32 */ /** Flag: Use file name expander. */ #define USE_FNE 1 #else #if DK_HAVE__FINDFIRST /* Win32, _findfirst */ /** Flag: Use file name expander. */ #define USE_FNE 1 #endif #endif #endif /* - Win32 */ #else #if DK_HAVE_FINDFIRST /* DOS, findfirst */ /** Flag: Use file name expander. */ #define USE_FNE 1 #else #if DK_HAVE_DIRENT_H /* UNIX/Linux, dirent */ /** Flag: Do not use file name expander. */ #define USE_FNE 0 #else /* any unknown directory listing mechanism */ /** Flag: Do not use file name expander. */ #define USE_FNE 0 #endif #endif #endif #if USE_FNE /** Pattern to match all files in the current directory. */ static char all_files[] = { #if DK_HAVE_ALLDOTALL "*.*" #else "*" #endif }; #endif #if DK_HAVE_FEATURE_DOS_EXEC /** Default PATH extensions on DOS and followers. */ static char default_path_ext[] = { ".COM;.EXE;.BAT" }; #endif #if DK_HAVE_FEATURE_BACKSLASH /** Default temporary directory on DOS and followers. */ static char temp_string[] = { "\\TEMP" }; #endif /** Time format to show file times. */ static char time_format[] = { "%04d/%02d/%02d %02d:%02d:%02d" }; /** File name of current working directory. */ static char curdir[] = { "." }; #if DK_HAVE_DOS_DRIVE_LETTER /** Colon, used to construct path names. */ static char str_colon = ':'; #endif #ifndef S_IFMT /** File mask. */ #ifdef _S_IFMT #define S_IFMT (_S_IFMT) #else #define S_IFMT 0170000 #endif #endif #ifndef S_IFREG /** File type: Regular file. */ #ifdef _S_IFREG #define S_IFREG (_S_IFREG) #else #define S_IFREG 0100000 #endif #endif #ifndef S_IFSOCK /** File type: Socket. */ #ifdef _S_IFSOCK #define S_IFSOCK (_S_IFSOCK) #else #define S_IFSOCK 0140000 #endif #endif #ifndef S_IFLNK /** File type: Symbolic link. */ #ifdef _S_IFLNK #define S_IFLNK (_S_IFLNK) #else #define S_IFLNK 0120000 #endif #endif #ifndef S_IFBLK /** File type: Block device. */ #ifdef _S_IFBLK #define S_IFBLK (_S_IFBLK) #else #define S_IFBLK 0060000 #endif #endif #ifndef S_IFDIR /** File type: Directory. */ #ifdef _S_IFDIR #define S_IFDIR (_S_IFDIR) #else #define S_IFDIR 0040000 #endif #endif #ifndef S_IFCHR /** File type: Character device. */ #ifdef _S_IFCHR #define S_IFCHR (_S_IFCHR) #else #define S_IFCHR 0020000 #endif #endif #ifndef S_IFIFO /** File type: FIFO. */ #ifdef _S_IFIFO #define S_IFIFO (_S_IFIFO) #else #define S_IFIFO 0010000 #endif #endif /** Convert native file type to DK_FT_xxx file type. @param m Native file type. @return DK_FT_xxx file type. */ static int dksf_filetype DK_P1(mode_t, m) { int back, found; back = found = 0; switch(m & S_IFMT) { case S_IFSOCK : back = DK_FT_SOCKET ; break; case S_IFLNK : back = DK_FT_SYMLINK ; break; case S_IFREG : back = DK_FT_REG; break; case S_IFBLK : back = DK_FT_BLK; break; case S_IFDIR : back = DK_FT_DIR; break; case S_IFCHR : back = DK_FT_CHR; break; default: back = DK_FT_OTHER; break; } return back; } /** Convert DK_PERM_xxx permissions to native permissions. @param m DK_PERM_xxx permissions. @return Native permissions. */ mode_t dksf_perm_dk2h DK_P1(int, m) { mode_t back = 0L; if(m & DK_PERM_SUID) { #ifdef S_ISUID back |= S_ISUID; #else #ifdef _S_ISUID back |= _S_ISUID; #else back |= DK_PERM_SUID; #endif #endif } if(m & DK_PERM_SGID) { #ifdef S_ISGID back |= S_ISGID; #else #ifdef _S_ISGID back |= _S_ISGID; #else back |= DK_PERM_SGID; #endif #endif } if(m & DK_PERM_VTX) { #ifdef S_ISVTX back |= S_ISVTX; #else #ifdef _S_ISVTX back |= _S_ISVTX; #else back |= DK_PERM_VTX; #endif #endif } if(m & DK_PERM_U_READ) { #ifdef S_IRUSR back |= S_IRUSR; #else #ifdef _S_IRUSR back |= _S_IRUSR; #else back |= DK_PERM_U_READ; #endif #endif } if(m & DK_PERM_U_WRITE) { #ifdef S_IWUSR back |= S_IWUSR; #else #ifdef _S_IWUSR back |= _S_IWUSR; #else back |= DK_PERM_U_WRITE; #endif #endif } if(m & DK_PERM_U_EXECUTE) { #ifdef S_IXUSR back |= S_IXUSR; #else #ifdef _S_IXUSR back |= _S_IXUSR; #else back |= DK_PERM_U_EXECUTE; #endif #endif } if(m & DK_PERM_G_READ) { #ifdef S_IRGRP back |= S_IRGRP; #else #ifdef _S_IRGRP back |= _S_IRGRP; #else back |= DK_PERM_G_READ; #endif #endif } if(m & DK_PERM_G_WRITE) { #ifdef S_IWGRP back |= S_IWGRP; #else #ifdef _S_IWGRP back |= _S_IWGRP; #else back |= DK_PERM_G_WRITE; #endif #endif } if(m & DK_PERM_G_EXECUTE) { #ifdef S_IXGRP back |= S_IXGRP; #else #ifdef _S_IXGRP back |= _S_IXGRP; #else back |= DK_PERM_G_EXECUTE; #endif #endif } if(m & DK_PERM_O_READ) { #ifdef S_IROTH back |= S_IROTH; #else #ifdef _S_IROTH back |= _S_IROTH; #else back |= DK_PERM_O_READ; #endif #endif } if(m & DK_PERM_O_WRITE) { #ifdef S_IWOTH back |= S_IWOTH; #else #ifdef _S_IWOTH back |= _S_IWOTH; #else back |= DK_PERM_O_WRITE; #endif #endif } if(m & DK_PERM_O_EXECUTE) { #ifdef S_IXOTH back |= S_IXOTH; #else #ifdef _S_IXOTH back |= _S_IXOTH; #else back |= DK_PERM_O_EXECUTE; #endif #endif } return back; } /** Convert native permissions to DK_PERM_xxx permissions. @param m Native permissions. @return DK_PERM_xxx permissions. */ int dksf_perm_h2dk DK_P1(mode_t, m) { int back = 0; #ifdef S_ISUID if(m & S_ISUID) back |= DK_PERM_SUID; #else #ifdef _S_ISUID if(m & _S_ISUID) back |= DK_PERM_SUID; #else if(m & DK_PERM_SUID) back |= DK_PERM_SUID; #endif #endif #ifdef S_ISGID if(m & S_ISGID) back |= DK_PERM_SGID; #else #ifdef _S_ISGID if(m & _S_ISGID) back |= DK_PERM_SGID; #else if(m & DK_PERM_SGID) back |= DK_PERM_SGID; #endif #endif #ifdef S_ISVTX if(m & S_ISVTX) back |= DK_PERM_VTX; #else #ifdef _S_ISVTX if(m & _S_ISVTX) back |= DK_PERM_VTX; #else if(m & DK_PERM_VTX) back |= DK_PERM_VTX; #endif #endif #ifdef S_IRUSR if(m & S_IRUSR) back |= DK_PERM_U_READ; #else #ifdef _S_IRUSR if(m & _S_IRUSR) back |= DK_PERM_U_READ; #else if(m & DK_PERM_U_READ) back |= DK_PERM_U_READ; #endif #endif #ifdef S_IWUSR if(m & S_IWUSR) back |= DK_PERM_U_WRITE; #else #ifdef _S_IWUSR if(m & _S_IWUSR) back |= DK_PERM_U_WRITE; #else if(m & DK_PERM_U_WRITE) back |= DK_PERM_U_WRITE; #endif #endif #ifdef S_IXUSR if(m & S_IXUSR) back |= DK_PERM_U_EXECUTE; #else #ifdef _S_IXUSR if(m & _S_IXUSR) back |= DK_PERM_U_EXECUTE; #else if(m & DK_PERM_U_EXECUTE) back |= DK_PERM_U_EXECUTE; #endif #endif #ifdef S_IRGRP if(m & S_IRGRP) back |= DK_PERM_G_READ; #else #ifdef _S_IRGRP if(m & _S_IRGRP) back |= DK_PERM_G_READ; #else if(m & DK_PERM_G_READ) back |= DK_PERM_G_READ; #endif #endif #ifdef S_IWGRP if(m & S_IWGRP) back |= DK_PERM_G_WRITE; #else #ifdef _S_IWGRP if(m & _S_IWGRP) back |= DK_PERM_G_WRITE; #else if(m & DK_PERM_G_WRITE) back |= DK_PERM_G_WRITE; #endif #endif #ifdef S_IXGRP if(m & S_IXGRP) back |= DK_PERM_G_EXECUTE; #else #ifdef _S_IXGRP if(m & _S_IXGRP) back |= DK_PERM_G_EXECUTE; #else if(m & DK_PERM_G_EXECUTE) back |= DK_PERM_G_EXECUTE; #endif #endif #ifdef S_IROTH if(m & S_IROTH) back |= DK_PERM_O_READ; #else #ifdef _S_IROTH if(m & _S_IROTH) back |= DK_PERM_O_READ; #else if(m & DK_PERM_O_READ) back |= DK_PERM_O_READ; #endif #endif #ifdef S_IWOTH if(m & S_IWOTH) back |= DK_PERM_O_WRITE; #else #ifdef _S_IWOTH if(m & _S_IWOTH) back |= DK_PERM_O_WRITE; #else if(m & DK_PERM_O_WRITE) back |= DK_PERM_O_WRITE; #endif #endif #ifdef S_IXOTH if(m & S_IXOTH) back |= DK_PERM_O_EXECUTE; #else #ifdef _S_IXOTH if(m & _S_IXOTH) back |= DK_PERM_O_EXECUTE; #else if(m & DK_PERM_O_EXECUTE) back |= DK_PERM_O_EXECUTE; #endif #endif return back; } /** Convert timestamp to text. @param s String buffer for result. @param t Timestamp structure. */ static void internal_time_convert DK_P2(char *, s, struct tm *, t) { struct tm *tm; tm = t; s[0] = '\0'; sprintf(s, time_format, (tm->tm_year + 1900), (tm->tm_mon + 1), tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec ); } void dksf_time_convert DK_P2(char *, s, time_t, t) { struct tm *tm; tm = localtime(&t); s[0] = '\0'; if(tm) { internal_time_convert(s, tm); } } /** Initialize a struct tm. @param tm Struct to initialize. */ static void init_struct_tm DK_P1(struct tm *,tm) { tm->tm_sec = 0; tm->tm_min = 0; tm->tm_hour = 0; tm->tm_mday = 1; tm->tm_mon = 0; tm->tm_year = 0; tm->tm_wday = 0; tm->tm_yday = 0; tm->tm_isdst = 0; } /** Initialize a dk_stat_t structure. @param ptr Structure to inspect. */ static void dkstat_init DK_P1(dk_stat_t, *ptr) { ptr->permissions = 0; ptr->filetype = 0; #if DK_HAVE_LONG_LONG_INT ptr->size = 0ULL; #else ptr->size = 0UL; #endif ptr->size_math_error = 0; ptr->inode_number = 0UL; ptr->device_number = 0UL; ptr->rdevice_number = 0UL; ptr->number_of_links = 0UL; ptr->uid = 0L; ptr->gid = 0L; ptr->ctime[0] = ptr->atime[0] = ptr->mtime[0] = '\0'; ptr->is_far_link = 0; /* ptr->ori_ctime = ptr->ori_atime = ptr->ori_mtime = (time_t)0L; */ init_struct_tm(&(ptr->ori_ctime)); init_struct_tm(&(ptr->ori_atime)); init_struct_tm(&(ptr->ori_mtime)); ptr->ud = 0x00; ptr->gd = 0x00; } int dkstat_get DK_P2(dk_stat_t *, ptr, char *, filename) { int back = 0; struct tm *tm; if((ptr) && (filename)) { #if defined(WIN32) || defined(_WIN32) #if DK_HAVE__STAT64 /* + _stat64 */ struct __stat64 st; #if DK_HAVE__LSTAT64 struct __stat64 lst; #endif if(_stat64(filename, &st) == 0) { back = 1; ptr->filetype = dksf_filetype(st.st_mode); ptr->permissions = dksf_perm_h2dk(st.st_mode); ptr->inode_number = (unsigned long)(st.st_ino); ptr->device_number = (unsigned long)(st.st_dev); ptr->rdevice_number = (unsigned long)(st.st_rdev); ptr->size = (dk_long_long_unsigned_t)(st.st_size); if(sizeof(off_t)>sizeof(dk_long_long_unsigned_t)) { ptr->size_math_error = (((off_t)(ptr->size) != st.st_size) ? 1 : 0); } else { ptr->size_math_error = 0; } ptr->number_of_links = (unsigned long)(st.st_nlink); ptr->uid = (long)(st.st_uid); ptr->gid = (long)(st.st_gid); ptr->ctime[0] = '\0'; ptr->atime[0] = '\0'; ptr->mtime[0] = '\0'; /* ptr->ori_ctime = st.st_ctime; ptr->ori_atime = st.st_atime; ptr->ori_mtime = st.st_mtime; */ tm = _localtime64(&(st.st_ctime)); if(tm) { DK_MEMCPY(&(ptr->ori_ctime), tm, sizeof(STRUCTTM)); } tm = _localtime64(&(st.st_atime)); if(tm) { DK_MEMCPY(&(ptr->ori_atime), tm, sizeof(STRUCTTM)); } tm = _localtime64(&(st.st_mtime)); if(tm) { DK_MEMCPY(&(ptr->ori_mtime), tm, sizeof(STRUCTTM)); } #if DK_HAVE__LSTAT64 if(_lstat64(filename, &lst) == 0) { if(dksf_filetype(lst.st_mode) == DK_FT_SYMLINK) { ptr->filetype |= DK_FT_SYMLINK; if(lst.st_dev != st.st_dev) { ptr->is_far_link = 1; } } if(st.st_uid != lst.st_uid) { ptr->ud = 0x01; } if(st.st_gid != lst.st_gid) { ptr->gd = 0x01; } } else { back = 0; } #endif } /* - _stat64 */ #else /* if DK_HAVE__STAT64 */ #if DK_HAVE__STAT32 /* + _stat32 */ struct __stat32 st; #if DK_HAVE__LSTAT32 struct __stat32 lst; #endif if(_stat32(filename, &st) == 0) { back = 1; ptr->filetype = dksf_filetype(st.st_mode); ptr->permissions = dksf_perm_h2dk(st.st_mode); ptr->inode_number = (unsigned long)(st.st_ino); ptr->device_number = (unsigned long)(st.st_dev); ptr->rdevice_number = (unsigned long)(st.st_rdev); ptr->size = (dk_long_long_unsigned_t)(st.st_size); if(sizeof(off_t)>sizeof(dk_long_long_unsigned_t)) { ptr->size_math_error = (((st.st_size) > ((off_t)DK_MAX_LONG_LONG_UNSIGNED)) ? 1 : 0); } else { ptr->size_math_error = 0; } ptr->number_of_links = (unsigned long)(st.st_nlink); ptr->uid = (long)(st.st_uid); ptr->gid = (long)(st.st_gid); ptr->ctime[0] = '\0'; ptr->atime[0] = '\0'; ptr->mtime[0] = '\0'; /* ptr->ori_ctime = st.st_ctime; ptr->ori_atime = st.st_atime; ptr->ori_mtime = st.st_mtime; */ tm = localtime(&(st.st_ctime)); if(tm) { DK_MEMCPY(&(ptr->ori_ctime), tm, sizeof(STRUCTTM)); } tm = localtime(&(st.st_atime)); if(tm) { DK_MEMCPY(&(ptr->ori_atime), tm, sizeof(STRUCTTM)); } tm = localtime(&(st.st_mtime)); if(tm) { DK_MEMCPY(&(ptr->ori_mtime), tm, sizeof(STRUCTTM)); } #if DK_HAVE__LSTAT32 if(_lstat32(filename, &lst) == 0) { if(dksf_filetype(lst.st_mode) == DK_FT_SYMLINK) { ptr->filetype |= DK_FT_SYMLINK; if(lst.st_dev != st.st_dev) { ptr->is_far_link = 1; } } if(st.st_uid != lst.st_uid) { ptr->ud = 0x01; } if(st.st_gid != lst.st_gid) { ptr->gd = 0x01; } } else { back = 0; } #endif } /* - _stat32 */ #else /* if DK_HAVE__STAT32 */ #if DK_HAVE__STAT /* + _stat */ struct _stat st; #if DK_HAVE__LSTAT struct _stat lst; #endif if(_stat(filename, &st) == 0) { back = 1; ptr->filetype = dksf_filetype(st.st_mode); ptr->permissions = dksf_perm_h2dk(st.st_mode); ptr->inode_number = (unsigned long)(st.st_ino); ptr->device_number = (unsigned long)(st.st_dev); ptr->rdevice_number = (unsigned long)(st.st_rdev); ptr->size = (dk_long_long_unsigned_t)(st.st_size); if(sizeof(off_t)>sizeof(dk_long_long_unsigned_t)) { ptr->size_math_error = (((st.st_size) > ((off_t)DK_MAX_LONG_LONG_UNSIGNED)) ? 1 : 0); } else { ptr->size_math_error = 0; } ptr->number_of_links = (unsigned long)(st.st_nlink); ptr->uid = (long)(st.st_uid); ptr->gid = (long)(st.st_gid); ptr->ctime[0] = '\0'; ptr->atime[0] = '\0'; ptr->mtime[0] = '\0'; /* ptr->ori_ctime = st.st_ctime; ptr->ori_atime = st.st_atime; ptr->ori_mtime = st.st_mtime; */ tm = localtime(&(st.st_ctime)); if(tm) { DK_MEMCPY(&(ptr->ori_ctime), tm, sizeof(STRUCTTM)); } tm = localtime(&(st.st_atime)); if(tm) { DK_MEMCPY(&(ptr->ori_atime), tm, sizeof(STRUCTTM)); } tm = localtime(&(st.st_mtime)); if(tm) { DK_MEMCPY(&(ptr->ori_mtime), tm, sizeof(STRUCTTM)); } #if DK_HAVE__LSTAT if(_lstat(filename, &lst) == 0) { if(dksf_filetype(lst.st_mode) == DK_FT_SYMLINK) { ptr->filetype |= DK_FT_SYMLINK; if(lst.st_dev != st.st_dev) { ptr->is_far_link = 1; } } if(st.st_uid != lst.st_uid) { ptr->ud = 0x01; } if(st.st_gid != lst.st_gid) { ptr->gd = 0x01; } } else { back = 0; } #endif } /* - _stat */ #else /* if DK_HAVE__STAT*/ /* Problem */ #endif /* if DK_HAVE__STAT*/ #endif /* if DK_HAVE__STAT32 */ #endif /* if DK_HAVE__STAT64 */ #else /* if defined(WIN32) || defined(_WIN32) */ #if DK_HAVE_STAT64 && DK_HAVE_LARGEFILE64_SOURCE /* + stat64 */ struct stat64 st; #if DK_HAVE_LSTAT64 struct stat64 lst; #endif if(stat64(filename, &st) == 0) { back = 1; ptr->filetype = dksf_filetype(st.st_mode); ptr->permissions = dksf_perm_h2dk(st.st_mode); ptr->inode_number = (unsigned long)(st.st_ino); ptr->device_number = (unsigned long)(st.st_dev); ptr->rdevice_number = (unsigned long)(st.st_rdev); ptr->size = (dk_long_long_unsigned_t)(st.st_size); if(sizeof(off_t)>sizeof(dk_long_long_unsigned_t)) { ptr->size_math_error = (((st.st_size) > ((off_t)DK_MAX_LONG_LONG_UNSIGNED)) ? 1 : 0); } else { ptr->size_math_error = 0; } ptr->number_of_links = (unsigned long)(st.st_nlink); ptr->uid = (long)(st.st_uid); ptr->gid = (long)(st.st_gid); ptr->ctime[0] = '\0'; ptr->atime[0] = '\0'; ptr->mtime[0] = '\0'; tm = localtime(&(st.st_ctime)); if(tm) { DK_MEMCPY(&(ptr->ori_ctime), tm, sizeof(STRUCTTM)); } tm = localtime(&(st.st_atime)); if(tm) { DK_MEMCPY(&(ptr->ori_atime), tm, sizeof(STRUCTTM)); } tm = localtime(&(st.st_mtime)); if(tm) { DK_MEMCPY(&(ptr->ori_mtime), tm, sizeof(STRUCTTM)); } #if DK_HAVE_LSTAT64 if(lstat64(filename, &lst) == 0) { if(dksf_filetype(lst.st_mode) == DK_FT_SYMLINK) { ptr->filetype |= DK_FT_SYMLINK; if(lst.st_dev != st.st_dev) { ptr->is_far_link = 1; } } if(st.st_uid != lst.st_uid) { ptr->ud = 0x01; } if(st.st_gid != lst.st_gid) { ptr->gd = 0x01; } } else { back = 0; } #endif } /* - stat64 */ #else /* if DK_HAVE_STAT64 */ #if DK_HAVE_STAT /* + stat */ struct stat st; #if DK_HAVE_LSTAT struct stat lst; #endif if(stat(filename, &st) == 0) { back = 1; ptr->filetype = dksf_filetype(st.st_mode); ptr->permissions = dksf_perm_h2dk(st.st_mode); ptr->inode_number = (unsigned long)(st.st_ino); ptr->device_number = (unsigned long)(st.st_dev); ptr->rdevice_number = (unsigned long)(st.st_rdev); ptr->size = (dk_long_long_unsigned_t)(st.st_size); if(sizeof(off_t)>sizeof(dk_long_long_unsigned_t)) { ptr->size_math_error = (((st.st_size) > ((off_t)DK_MAX_LONG_LONG_UNSIGNED)) ? 1 : 0); } else { ptr->size_math_error = 0; } ptr->number_of_links = (unsigned long)(st.st_nlink); ptr->uid = (long)(st.st_uid); ptr->gid = (long)(st.st_gid); ptr->ctime[0] = '\0'; ptr->atime[0] = '\0'; ptr->mtime[0] = '\0'; /* ptr->ori_ctime = st.st_ctime; ptr->ori_atime = st.st_atime; ptr->ori_mtime = st.st_mtime; */ tm = localtime(&(st.st_ctime)); if(tm) { DK_MEMCPY(&(ptr->ori_ctime), tm, sizeof(STRUCTTM)); } tm = localtime(&(st.st_atime)); if(tm) { DK_MEMCPY(&(ptr->ori_atime), tm, sizeof(STRUCTTM)); } tm = localtime(&(st.st_mtime)); if(tm) { DK_MEMCPY(&(ptr->ori_mtime), tm, sizeof(STRUCTTM)); } #if DK_HAVE_LSTAT if(lstat(filename, &lst) == 0) { if(dksf_filetype(lst.st_mode) == DK_FT_SYMLINK) { ptr->filetype |= DK_FT_SYMLINK; if(lst.st_dev != st.st_dev) { ptr->is_far_link = 1; } } if(st.st_uid != lst.st_uid) { ptr->ud = 0x01; } if(st.st_gid != lst.st_gid) { ptr->gd = 0x01; } } else { back = 0; } #endif } /* - stat */ #else /* if DK_HAVE_STAT */ /* Problem */ #endif /* if DK_HAVE_STAT */ #endif /* if DK_HAVE_STAT64 */ #endif /* if defined(WIN32) || defined(_WIN32) */ } return back; } int dksf_must_rebuild DK_P2(char *,d, char *,s) { int back = 0; if((d) && (s)) { #if defined(WIN32) || defined(_WIN32) #if DK_HAVE__STAT64 struct __stat64 sst, dst; if(_stat64(s, &sst) == 0) { back = 1; if(_stat64(d, &dst) == 0) { if(dst.st_mtime > sst.st_mtime) { back = 0; } } } #else #if DK_HAVE__STAT32 struct __stat32 sst, dst; if(_stat32(s, &sst) == 0) { back = 1; if(_stat32(d, &dst) == 0) { if(dst.st_mtime > sst.st_mtime) { back = 0; } } } #else struct _stat sst, dst; if(_stat(s, &sst) == 0) { back = 1; if(_stat(d, &dst) == 0) { if(dst.st_mtime > sst.st_mtime) { back = 0; } } } #endif #endif #else #if DK_HAVE_STAT64 && DK_HAVE_LARGEFILE64_SOURCE struct stat64 sst, dst; if(stat64(s, &sst) == 0) { back = 1; if(stat64(d, &dst) == 0) { if(dst.st_mtime > sst.st_mtime) { back = 0; } } } #else #if DK_HAVE_STAT struct stat sst, dst; if(stat(s, &sst) == 0) { back = 1; /* have source */ if(stat(d, &dst) == 0) { if(dst.st_mtime > sst.st_mtime) { back = 0; /* up to date */ } } } #endif #endif #endif } return back; } int dkstat_far_link DK_P1(dk_stat_t *, ptr) { int back = 0; if(ptr) { back = ptr->is_far_link; } return back; } dk_stat_t * dkstat_open DK_P1(char *, filename) { dk_stat_t *back = NULL; if(filename) { back = dk_new(dk_stat_t,1); if(back) { dkstat_init(back); if(!dkstat_get(back,filename)) { dk_delete(back); back = NULL; } } } return back; } void dkstat_close DK_P1(dk_stat_t *, ptr) { if(ptr) { dk_delete(ptr); } } int dkstat_filetype DK_P1(dk_stat_t *, ptr) { int back = 0; if(ptr) back = ptr->filetype; return back; } int dkstat_permissions DK_P1(dk_stat_t *, ptr) { int back = 0; if(ptr) back = ptr->permissions; return back; } unsigned long dkstat_inode DK_P1(dk_stat_t *, ptr) { unsigned long back = 0UL; if(ptr) back = ptr->inode_number; return back; } unsigned long dkstat_device DK_P1(dk_stat_t *, ptr) { unsigned long back = 0UL; if(ptr) back = ptr->device_number; return back; } unsigned long dkstat_rdevice DK_P1(dk_stat_t *, ptr) { unsigned long back = 0UL; if(ptr) back = ptr->rdevice_number; return back; } unsigned long dkstat_nlinks DK_P1(dk_stat_t *, ptr) { unsigned long back = 0UL; if(ptr) back = ptr->number_of_links; return back; } dk_long_long_unsigned_t dkstat_size DK_P1(dk_stat_t *, ptr) { #if DK_HAVE_LONG_LONG_INT dk_long_long_unsigned_t back = 0ULL; #else dk_long_long_unsigned_t back = 0UL; #endif if(ptr) back = ptr->size; #if DK_HAVE_LONG_LONG_INT #else #endif return back; } dk_long_long_unsigned_t dkstat_size_ok DK_P2(dk_stat_t *, ptr, int *,ok) { #if DK_HAVE_LONG_LONG_INT dk_long_long_unsigned_t back = 0ULL; #else dk_long_long_unsigned_t back = 0UL; #endif if(ptr) { back = ptr->size; if(ptr->size_math_error) { if(ok) { *ok = DK_ERR_MATH_OOR; } } } #if DK_HAVE_LONG_LONG_INT #else #endif return back; } long dkstat_uid DK_P1(dk_stat_t *, ptr) { long back = -1; if(ptr) back = ptr->uid; return back; } long dkstat_gid DK_P1(dk_stat_t *, ptr) { long back = -1; if(ptr) back = ptr->gid; return back; } char * dkstat_ctime DK_P1(dk_stat_t *, ptr) { char *back = NULL; if(ptr) { back = &(ptr->ctime[0]); if(!(*back)) { internal_time_convert(back, &(ptr->ori_ctime)); } } return back; } char * dkstat_atime DK_P1(dk_stat_t *, ptr) { char *back = NULL; if(ptr) { back = &(ptr->atime[0]); if(!(*back)) { internal_time_convert(back, &(ptr->ori_atime)); } } return back; } char * dkstat_mtime DK_P1(dk_stat_t *, ptr) { char *back = NULL; if(ptr) { back = &(ptr->mtime[0]); if(!(*back)) { internal_time_convert(back, &(ptr->ori_mtime)); } } return back; } int dksf_mkdir DK_P2(char *, path, int, mode) { int back = 0; mode_t mode_translated; if(path) { mode_translated = dksf_perm_dk2h(mode); #if DK_HAVE_MKDIR2 if(mkdir(path, mode_translated) == 0) { back = 1; } #else #if DK_HAVE_MKDIR || DK_HAVE__MKDIR #if DK_HAVE_MKDIR if(mkdir(path) == 0) { #else if(_mkdir(path) == 0) { #endif back = 1; } #endif #endif } return back; } int dksf_chmod DK_P2(char *, path, int, mode) { int back = 0; if(path) { #if DK_HAVE_CHMOD mode_t mode_translated; mode_translated = dksf_perm_dk2h(mode); if(chmod(path, mode_translated) == 0) { back = 1; } #endif } return back; } int dksf_fchmod DK_P2(int,fd, int,mode) { int back = 0; #if DK_HAVE_FCHMOD mode_t mode_translated; mode_translated = dksf_perm_dk2h(mode); if(fchmod(fd, mode_translated) == 0) { back = 1; } #endif return back; } dk_stat_t * dkstat_new DK_P0() { dk_stat_t *back = NULL; back = dk_new(dk_stat_t,1); if(back) { dkstat_init(back); } return back; } void dkstat_delete DK_P1(dk_stat_t *, ptr) { if(ptr) { dk_delete(ptr); } } long dksf_getpid DK_P0() { long back = -1L; #if DK_HAVE_GETCURRENTPROCESSID back = GetCurrentProcessId(); #else #if DK_HAVE_GETPID back = (long)getpid(); #endif #endif return back; } int dksf_have_getpid DK_P0() { int back = 0; #if DK_HAVE_GETPID back = 1; #endif return back; } long dksf_getppid DK_P0() { long back = -1L; #if DK_HAVE_GETPPID back = (long)getppid(); #else back = dksf_getpid(); #endif return back; } int dksf_have_getppid DK_P0() { int back = 0; #if DK_HAVE_GETPPID back = 1; #endif return back; } long dksf_getuid DK_P0() { long back = -1L; #if DK_HAVE_GETUID back = (long)getuid(); #endif return back; } int dksf_have_getuid DK_P0() { int back = 0; #if DK_HAVE_GETUID back = 1; #endif return back; } long dksf_getgid DK_P0() { long back = -1L; #if DK_HAVE_GETGID back = (long)getgid(); #endif return back; } int dksf_have_getgid DK_P0() { int back = 0; #if DK_HAVE_GETGID back = 1; #endif return back; } long dksf_geteuid DK_P0() { long back = -1L; #if DK_HAVE_GETEUID back = (long)geteuid(); #endif return back; } int dksf_have_geteuid DK_P0() { int back = 0; #if DK_HAVE_GETEUID back = 1; #endif return back; } long dksf_getegid DK_P0() { long back = -1L; #if DK_HAVE_GETEGID back = (long)getegid(); #endif return back; } int dksf_have_getegid DK_P0() { int back = 0; #if DK_HAVE_GETEGID back = 1; #endif return back; } long dksf_getpgrp DK_P0() { long back = -1L; #if DK_HAVE_GETPGRP back = (long)getpgrp(); #endif return back; } int dksf_have_getpgrp DK_P0() { int back = 0; #if DK_HAVE_GETPGRP back = 1; #endif return back; } long dksf_getpgid DK_P1(long, x) { long back = -1L; #if DK_HAVE_GETPGID back = (long)getpgid((pid_t)x); #endif return back; } int dksf_have_getpgid DK_P0() { int back = 0; #if DK_HAVE_GETPGID back = 1; #endif return back; } #if DK_HAVE_WINREG_H /** List of registry key and entry names to inspect. */ static char *subkeys_to_inspect[] = { "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", "System\\CurrentControlSet\\Services\\Tcpip\\Parameters", "System\\CurrentControlSet\\Control\\ComputerName\\ComputerName", "System\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName", "DefaultUserName", "Hostname", "Domain", "ComputerName", "System\\CurrentControlSet\\control", "Current User", "Network\\Logon", "username", "System\\CurrentControlSet\\Services\\VxD\\MSTCP", "System\\CurrentControlSet\\Services\\VxD\\VNETSUP", "HostName", NULL }; /** Read a string from the registry. @param dest Result buffer. @param dsz Size of \a dest. @param what Indicator for registry hive and key and entry name. */ static int read_registry_string DK_P3(char *, dest, size_t, dsz, int, what) { int back = 0; char *subkey, *entry_key; subkey = entry_key = NULL; switch(what) { case 0: { subkey = subkeys_to_inspect[0]; entry_key = subkeys_to_inspect[4]; } break; case 1: { subkey = subkeys_to_inspect[1]; entry_key = subkeys_to_inspect[5]; } break; case 2: { subkey = subkeys_to_inspect[1]; entry_key = subkeys_to_inspect[6]; } break; case 3: { subkey = subkeys_to_inspect[3]; entry_key = subkeys_to_inspect[7]; } break; case 4: { subkey = subkeys_to_inspect[2]; entry_key = subkeys_to_inspect[7]; } break; case 5: { /* HKLM/System/CurrentControlSet/control:Current User */ subkey = subkeys_to_inspect[8]; entry_key = subkeys_to_inspect[9]; } break; case 6: { /* HKLM/Network/Logon:username */ subkey = subkeys_to_inspect[10]; entry_key = subkeys_to_inspect[11]; } break; case 7: { /* HKLM/System/CurrentControlSet/Services/VxD/MSTCP:HostName */ subkey = subkeys_to_inspect[12]; entry_key = subkeys_to_inspect[14]; } break; case 8: { /* HKLM/System/CurrentControlSet/Services/VxD/VNETSUP:ComputerName */ subkey = subkeys_to_inspect[13]; entry_key = subkeys_to_inspect[7]; } break; case 9: { subkey = subkeys_to_inspect[12]; entry_key = subkeys_to_inspect[6]; } break; } if(subkey && entry_key) { HKEY hklmsl; PHKEY phkSubkey; DWORD disp, dwType, sz; LONG retval; phkSubkey = &hklmsl; retval = RegCreateKeyExA( HKEY_LOCAL_MACHINE, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE, NULL, phkSubkey, &disp ); if(retval == ERROR_SUCCESS) { sz = dsz; retval = RegQueryValueExA( hklmsl, entry_key, NULL, &dwType, dest, &sz ); if(retval == ERROR_SUCCESS) { if(sz < dsz) { dest[sz] = '\0'; back = 1; } } else { } } else { } } return back; } #endif #if DK_HAVE_GETPWUID || DK_HAVE_GETPWENT /** Save information to buffer. @param buffer Result buffer. @param sz Size of \a buffer. @param who 0=UID, 1=effective UID. @param how 0=LOGNAME, 1=HOME. @return 1 on success, 0 on error. */ static int fill_buffer DK_P4(char *, buffer, size_t, sz, int, who, int, how) { int back = 0; #if DK_HAVE_GETUID uid_t uid; struct passwd *pw; #if !DK_HAVE_SETPWENT struct passwd *xpw; #endif #if DK_HAVE_GETEUID uid = (who ? getuid() : geteuid()); #else uid = getuid(); #endif #if DK_HAVE_GETPWUID pw = getpwuid(uid); #else pw = NULL; #if DK_HAVE_SETPWENT setpwent(); #endif xpw = getpwent(); while((!pw) & (xpw)) { if(xpw->pw->uid == uid) { pw = xpw; } if(!pw) { xpw = getpwent(); } } #endif switch(how) { case 1: { /* HOME */ if(pw->pw_dir) { if(strlen(pw->pw_dir) < sz) { back = 1; strcpy(buffer, pw->pw_dir); } } } break; case 0: { /* LOGNAME */ if(pw->pw_name) { if(strlen(pw->pw_name) < sz) { back = 1; strcpy(buffer, pw->pw_name); } } } break; } #if (!DK_HAVE_GETPWUID) && DK_HAVE_GETENDPWENT endpwent(); #endif #else /* So what */ #endif return back; } #endif int dksf_get_uname DK_P2(char *, buffer, size_t, sz) { int back = 0; if(buffer) { if(sz) { #if DK_HAVE_GETPWUID || DK_HAVE_GETPWENT back = fill_buffer(buffer, sz, 1, 0); #else char *x; #if DK_HAVE_GETUSERNAME DWORD xs; xs = sz; if(GetUserNameA(buffer,&xs)) { back = 1; if(xs >= sz) { xs--; } buffer[(size_t)xs] = '\0'; } #endif #if DK_HAVE_WINREG_H /* Windows NT 4.0 Workstation */ if(!back) { back = read_registry_string(buffer,sz,0); } if(!back) { back = read_registry_string(buffer,sz,6); } if(!back) { back = read_registry_string(buffer,sz,5); } #endif if(!back) { x = getenv("LOGNAME"); if(x) { if(strlen(x) < sz) { back = 1; strcpy(buffer, x); } } } if(!back) { x = getenv("USERNAME"); if(x) { if(strlen(x) < sz) { back = 1; strcpy(buffer, x); } } } #endif } } return back; } int dksf_get_euname DK_P2(char *, buffer, size_t, sz) { int back = 0; if(buffer) { if(sz) { #if DK_HAVE_GETPWUID || DK_HAVE_GETPWENT back = fill_buffer(buffer, sz, 0, 0); #else char *x; #if DK_HAVE_GETUSERNAME DWORD xs; xs = sz; if(GetUserNameA(buffer,&xs)) { back = 1; if(xs >= sz) { xs--; } buffer[(size_t)xs] = '\0'; } #endif #if DK_HAVE_WINREG_H back = read_registry_string(buffer,sz,0); #endif if(!back) { x = getenv("LOGNAME"); if(x) { if(strlen(x) < sz) { back = 1; strcpy(buffer, x); } } } if(!back) { x = getenv("USERNAME"); if(x) { if(strlen(x) < sz) { back = 1; strcpy(buffer, x); } } } #endif } } return back; } #if !(DK_HAVE_GETPWUID || DK_HAVE_GETPWENT) /** Attempt to construct home directory name from environment variables. @param buffer Result buffer. @param sz Size of \a buffer. @return 1 on success, 0 on error. */ static int try_home_from_env DK_P2(char *, buffer, size_t, sz) { int back = 0; char *x; #if DK_HAVE_FEATURE_BACKSLASH char *y; #endif x = getenv("HOME"); if(x) { if(strlen(x) < sz) { back = 1; strcpy(buffer,x); } } if(!back) { #if DK_HAVE_FEATURE_BACKSLASH x = getenv("USERPROFILE"); if(x) { if(strlen(x) < sz) { back = 1; strcpy(buffer,x); } } #endif } if(!back) { #if DK_HAVE_FEATURE_BACKSLASH x = getenv("HOMEDRIVE"); y = getenv("HOMEPATH"); if(x && y) { if((strlen(x) + strlen(y) + strlen(path_component_separator)) < sz) { back = 1; strcpy(buffer,x); if(y[0] != path_component_separator[0]) { strcat(buffer, path_component_separator); } strcat(buffer,y); } } #endif } return back; } #endif /** Get home directory. @param buffer Result buffer. @param sz Size of \a buffer. @return 1 on success, 0 on error. */ static int internal_get_home DK_P2(char *, buffer, size_t, sz) { int back = 0; if(buffer) { if(sz) { #if DK_HAVE_GETPWUID || DK_HAVE_GETPWENT back = fill_buffer(buffer, sz, 1, 1); #else back = try_home_from_env(buffer,sz); #endif } } return back; } /** Check permissions to temporary directory. @param buffer Result buffer. @param sz Size of \a buffer. @param x Candidate for temprary directory. @return 1 on success, 0 on error. */ static int check_temp_dir DK_P3(char *, buffer, size_t, sz, char *, x) { int back = 0; dk_stat_t st; if(dkstat_get(&st,x)) { int ft; ft = dkstat_filetype(&st); ft &= (~DK_FT_SYMLINK); if(ft == DK_FT_DIR) { if(strlen(x) < sz) { back = 1; /* strcpy(buffer,x); */ } } } if(!back) { (void)dksf_mkdir(x, DK_PERM_CREATE_DIR); } if(dkstat_get(&st,x)) { int ft; ft = dkstat_filetype(&st); ft &= (~DK_FT_SYMLINK); if(ft == DK_FT_DIR) { if(strlen(x) < sz) { back = 1; /* strcpy(buffer,x); */ } } } return back; } /** Environment variables to inspect for temporary files directory. */ static char *variables_to_check[] = { "TMPDIR", "TEMP", "TMP", NULL }; /** Find temporary directory. @param buffer Buffer for result. @param sz Size of \a buffer. @return 1 on success, 0 on error. */ static int internal_get_tempdir DK_P2(char *, buffer, size_t, sz) { int back = 0; if(buffer) { if(sz) { char c, *p1, *p2, *p3, *vptr, **kptr; kptr = variables_to_check; while((*kptr) && (!back)) { vptr = getenv(*kptr); if(vptr) { if(strlen(vptr) < sz) { strcpy(buffer, vptr); if(dkstr_chr(buffer, ';')) { p1 = buffer; while((p1) && (!back)) { p2 = dkstr_chr(p1, ';'); if(p2) { *(p2++) = '\0'; } back = check_temp_dir(buffer, sz, p1); if(back) { p3 = buffer; while(*p1) { c = *(p1++); *(p3++) = c; } *p3 = '\0'; } p1 = p2; } } else { back = check_temp_dir(buffer, sz, vptr); if(back) { strcpy(buffer, vptr); } } } } kptr++; } #if DK_HAVE_FEATURE_BACKSLASH if(!back) { char *x; x = getenv("SystemDrive"); if(x) { if((strlen(x) + strlen(temp_string)) < sz) { strcpy(buffer,x); strcat(buffer,temp_string); back = check_temp_dir(buffer,sz,buffer); } } if(!back) { x = getenv("SystemRoot"); if(x) { if((strlen(x) + strlen(temp_string)) < sz) { strcpy(buffer,x); strcat(buffer,temp_string); back = check_temp_dir(buffer,sz,buffer); } } } if(!back) { x = getenv("windir"); if(x) { if((strlen(x) + strlen(temp_string)) < sz) { strcpy(buffer,x); strcat(buffer,temp_string); back = check_temp_dir(buffer,sz,buffer); } } } } #endif } } return back; } int dksf_get_ehome DK_P2(char *, buffer, size_t, sz) { int back = 0; if(buffer) { if(sz) { #if DK_HAVE_GETPWUID || DK_HAVE_GETPWENT back = fill_buffer(buffer, sz, 0, 1); #else back = try_home_from_env(buffer,sz); #endif if(!back) { back = internal_get_tempdir(buffer,sz); } } } return back; } int dksf_get_hostname DK_P2(char *, buffer, size_t, sz) { int back = 0; #if DK_HAVE_GETCOMPUTERNAME size_t xs; #endif if(buffer) { if(sz) { #if DK_HAVE_SYS_SYSTEMINFO #if DK_HAVE_SYSINFO #ifdef SI_HOSTNAME long l; l = sysinfo(SI_HOSTNAME, buffer, sz); if((l > 0L) && (l <= sz)) { back = 1; } #endif #endif #endif #if DK_HAVE_GETCOMPUTERNAME xs = sz; if(!back) { if(GetComputerNameA(buffer,&xs)) { if(xs >= sz) { xs--; } buffer[(size_t)xs] = '\0'; back = 1; } } #endif #if DK_HAVE_GETHOSTNAME if(!back) { if(gethostname(buffer, (int)sz) == 0) { back = 1; buffer[(sz-1UL)] = '\0'; } } #endif if(!back) { #if DK_HAVE_WINREG_H /* Windows NT 4.0 Workstation */ back = read_registry_string(buffer,sz,1); if(!back) { back = read_registry_string(buffer,sz,3); } if(!back) { back = read_registry_string(buffer,sz,4); } /* Windows 95 */ if(!back) { back = read_registry_string(buffer,sz,7); } if(!back) { back = read_registry_string(buffer,sz,8); } #endif } if(!back) { char *x; x = getenv("COMPUTERNAME"); if(x) { if(strlen(x) < sz) { back = 1; strcpy(buffer,x); } } } } } return back; } int dksf_get_home DK_P2(char *, buffer, size_t, sz) { int back; back = internal_get_home(buffer,sz); if(!back) { back = internal_get_tempdir(buffer,sz); } return back; } int dksf_get_tempdir DK_P2(char *, buffer, size_t, sz) { int back; back = internal_get_tempdir(buffer,sz); if(!back) { back = internal_get_home(buffer,sz); } return back; } int dksf_get_domainname DK_P2(char *, buffer, size_t, sz) { int back = 0; if(buffer) { if(sz) { #if DK_HAVE_SYS_SYSTEMINFO_H long l; #if DK_HAVE_SYSINFO #ifdef SI_SYSNAME l = sysinfo(SI_SRPC_DOMAIN, buffer, sz); if((l > 0L) && (l <= sz)) { back = 1; } #else #endif #else #endif #else #endif if(!back) { #if DK_HAVE_WINREG_H /* Windows NT 4.0 Workstation */ back = read_registry_string(buffer,sz,2); /* Windows 95 */ if(!back) { back = read_registry_string(buffer,sz,9); } #endif } } } return back; } long dksf_get_maxpathlen DK_P0() { long back = MY_MAXPATHLEN; return back; } long dksf_get_maxfiles DK_P0() { long back = 1024L; #if DK_HAVE_SYS_RESOURCE_H #if DK_HAVE_GETRLIMIT struct rlimit rl; if(getrlimit(RLIMIT_NOFILE, &rl) >= 0) { if(rl.rlim_max != RLIM_INFINITY) { back = (long)(rl.rlim_max); } } #endif #endif return back; } /** Directory state: Not yet initialized. */ #define DIR_STATE_UNUSED 0 /** Directory state: Initialized. */ #define DIR_STATE_INITIALIZED 1 /** Directory state: Opened. */ #define DIR_STATE_OPENED 2 /** Directory state: End of directory reached. */ #define DIR_STATE_WRAPPED 3 /** Directory state: Closed. */ #define DIR_STATE_CLOSED 4 /** Get file properties. @param ptr Directory. @param shortname File name. @return 1 on success, 0 on error. */ static int get_file_properties DK_P2(dk_dir_t *, ptr, char *, shortname) { int back = 0; size_t lgt, lgtx; if((long)strlen(shortname) < ptr->maxpathlen) { strcpy(ptr->shortname, shortname); strcpy(ptr->fullname, ptr->dirname); lgt = lgtx = strlen(ptr->dirname); lgt += strlen(path_component_separator); lgt += strlen(shortname); if((long)lgt < ptr->maxpathlen) { if(((ptr->dirname)[lgtx - 1]) != path_component_separator[0]) { strcat(ptr->fullname, path_component_separator); } strcat(ptr->fullname, shortname); if(dkstat_get(&(ptr->stbuf), ptr->fullname)) { back = 1; } } else { } } else { } return back; } int dkdir_start_search DK_P2(dk_dir_t *, ptr, char *, name) { int back = 0; if((ptr) && (name)) { switch(ptr->state) { case DIR_STATE_UNUSED: case DIR_STATE_CLOSED: { if((long)strlen(name) < ptr->maxpathlen) { strcpy(ptr->dirname, name); ptr->state = DIR_STATE_INITIALIZED; back = 1; } else { } } break; default: { } break; } } else { } return back; } #if defined(WIN32) || defined(_WIN32) /* + Win32 */ #if DK_HAVE__FINDFIRST64 /* Win32, _findfirst64 */ void dkdir_end_search DK_P1(dk_dir_t *,ptr) { if(ptr) { switch(ptr->state) { case DIR_STATE_OPENED: case DIR_STATE_WRAPPED: { _findclose(ptr->hFile64); ptr->hFile64 = -1L; } break; default: { } break; } } } int dkdir_next DK_P1(dk_dir_t *, ptr) { int back = 0; size_t lgt; size_t lgtx; size_t lgty; int i; if(ptr) { switch(ptr->state) { case DIR_STATE_INITIALIZED: { lgt = strlen(ptr->dirname); lgtx = lgty = lgt; if(lgt > 0) { lgt += strlen(path_component_separator); lgt += strlen(all_files); if((long)lgt < ptr->maxpathlen) { if(((ptr->dirname)[lgtx - 1]) != path_component_separator[0]) { strcat(ptr->dirname, path_component_separator); } strcat(ptr->dirname, all_files); ptr->hFile64 = _findfirst64(ptr->dirname, &(ptr->fdt64)); (ptr->dirname)[lgtx] = '\0'; if(ptr->hFile64 != -1L) { /* back = get_file_properties(ptr, (ptr->fdt64).name); */ back = 1; if(!get_file_properties(ptr, (ptr->fdt64).name)) { back = -1; } ptr->state = DIR_STATE_OPENED; } else { } } else { } } else { } } break; case DIR_STATE_OPENED: { i = _findnext64(ptr->hFile64, &(ptr->fdt64)); if(i == 0) { /* back = get_file_properties(ptr, (ptr->fdt64).name); */ back = 1; if(!get_file_properties(ptr, (ptr->fdt64).name)) { back = -1; } } else { _findclose(ptr->hFile64); ptr->hFile64 = -1L; ptr->state = DIR_STATE_CLOSED; } } break; default: { } break; } } return back; } /** Initialize new directory. @param ptr Directory to initialize. */ static void init_new_directory DK_P1(dk_dir_t *,ptr) { ptr->hFile64 = -1L; } #else #if DK_HAVE__FINDFIRST32 /* Win32, _findfirst32 */ void dkdir_end_search DK_P1(dk_dir_t *,ptr) { if(ptr) { switch(ptr->state) { case DIR_STATE_OPENED: case DIR_STATE_WRAPPED: { _findclose(ptr->hFile32); ptr->hFile = -1L; } break; default: { } break; } } } int dkdir_next DK_P1(dk_dir_t *, ptr) { int back = 0; size_t lgt; size_t lgtx; size_t lgty; if(ptr) { switch(ptr->state) { case DIR_STATE_INITIALIZED: { lgt = strlen(ptr->dirname); lgtx = lgty = lgt; if(lgt > 0) { lgt += strlen(path_component_separator); lgt += strlen(all_files); if((long)lgt < ptr->maxpathlen) { if(((ptr->dirname)[lgtx - 1]) != path_component_separator[0]) { strcat(ptr->dirname, path_component_separator); } strcat(ptr->dirname, all_files); ptr->hFile32 = _findfirst32(ptr->dirname, &(ptr->fdt32)); (ptr->dirname)[lgtx] = '\0'; if(ptr->hFile32 != -1L) { /* back = get_file_properties(ptr, (ptr->fdt32).name); */ back = 1; if(!get_file_properties(ptr, (ptr->fdt32).name)) { back = -1; } ptr->state = DIR_STATE_OPENED; } else { } } else { } } else { } } break; case DIR_STATE_OPENED: { i = _findnext32(ptr->hFile32, &(ptr->fdt32)); if(i == 0) { /* back = get_file_properties(ptr, (ptr->fdt32).name); */ back = 1; if(!get_file_properties(ptr, (ptr->fdt32).name)) { back = -1; } } else { _findclose(ptr->hFile32); ptr->hFile32 = -1L; ptr->state = DIR_STATE_CLOSED; } } break; default: { } break; } } return back; } /** Initialize new directory. @param ptr Directory to initialize. */ static void init_new_directory DK_P1(dk_dir_t *,ptr) { ptr->hFile32 = -1L; } #else #if DK_HAVE__FINDFIRST /* Win32, _findfirst */ void dkdir_end_search DK_P1(dk_dir_t *,ptr) { if(ptr) { switch(ptr->state) { case DIR_STATE_OPENED: case DIR_STATE_WRAPPED: { _findclose(ptr->hFile); ptr->hFile = -1L; } break; default: { } break; } } } int dkdir_next DK_P1(dk_dir_t *, ptr) { int back = 0; size_t lgt; size_t lgtx; size_t lgty; int i; if(ptr) { switch(ptr->state) { case DIR_STATE_INITIALIZED: { lgt = strlen(ptr->dirname); lgtx = lgty = lgt; if(lgt > 0) { lgt += strlen(path_component_separator); lgt += strlen(all_files); if((long)lgt < ptr->maxpathlen) { if(((ptr->dirname)[lgtx - 1]) != path_component_separator[0]) { strcat(ptr->dirname, path_component_separator); } strcat(ptr->dirname, all_files); ptr->hFile = _findfirst(ptr->dirname, &(ptr->fdt)); (ptr->dirname)[lgtx] = '\0'; if(ptr->hFile != -1L) { /* back = get_file_properties(ptr, (ptr->fdt).name); */ back = 1; if(!get_file_properties(ptr, (ptr->fdt).name)) { back = -1; } ptr->state = DIR_STATE_OPENED; } else { } } else { } } else { } } break; case DIR_STATE_OPENED: { i = _findnext(ptr->hFile, &(ptr->fdt)); if(i == 0) { /* back = get_file_properties(ptr, (ptr->fdt).name); */ back = 1; if(!get_file_properties(ptr, (ptr->fdt).name)) { back = -1; } } else { _findclose(ptr->hFile); ptr->hFile = -1L; ptr->state = DIR_STATE_CLOSED; } } break; default: { } break; } } return back; } /** Initialize new directory. @param ptr Directory to initialize. */ static void init_new_directory DK_P1(dk_dir_t *,ptr) { ptr->hFile = -1L; } #endif #endif #endif /* - Win32 */ #else #if DK_HAVE_FINDFIRST /* DOS, findfirst */ void dkdir_end_search DK_P1(dk_dir_t *,ptr) { int i; if(ptr) { switch(ptr->state) { case DIR_STATE_OPENED: case DIR_STATE_WRAPPED: { i = 0; while(!i) { i = findnext(&(ptr->dir)); } } break; default: { } break; } } } int dkdir_next DK_P1(dk_dir_t *, ptr) { int back = 0; size_t lgt; size_t lgtx; size_t lgty; int i; if(ptr) { switch(ptr->state) { case DIR_STATE_INITIALIZED: { lgt = strlen(ptr->dirname); if(lgt > 0) { lgtx = lgty = lgt; lgt += strlen(all_files); lgt += strlen(path_component_separator); if(lgt < ptr->maxpathlen) { if((ptr->dirname)[lgtx - 1] != path_component_separator[0]) { strcat(ptr->dirname, path_component_separator); } strcat(ptr->dirname, all_files); i = findfirst(ptr->dirname, &(ptr->dir), FA_DIREC); (ptr->dirname)[lgty] = '\0'; if(i == 0) { /* back = get_file_properties(ptr, (ptr->dir).ff_name); */ back = 1; if(!get_file_properties(ptr, (ptr->dir).ff_name)) { back = -1; } ptr->state = DIR_STATE_OPENED; } else { } } else { } } else { } } break; case DIR_STATE_OPENED: { i = findnext(&(ptr->dir)); if(i == 0) { /* back = get_file_properties(ptr, (ptr->dir).ff_name); */ back = 1; if(!get_file_properties(ptr, (ptr->dir).ff_name)) { back = -1; } } else { ptr->state = DIR_STATE_CLOSED; } } break; default: { } break; } } return back; } /** Initialize new directory. @param ptr Directory to initialize. */ static void init_new_directory DK_P1(dk_dir_t *,ptr) { } #else #if DK_HAVE_DIRENT_H /* UNIX/Linux, dirent */ void dkdir_end_search DK_P1(dk_dir_t *,ptr) { if(ptr) { switch(ptr->state) { case DIR_STATE_OPENED: case DIR_STATE_WRAPPED: { closedir(ptr->dir); ptr->dir = NULL; ptr->state = DIR_STATE_CLOSED; } break; default: { } break; } } } int dkdir_next DK_P1(dk_dir_t *, ptr) { int back = 0; struct dirent *de; if(ptr) { switch(ptr->state) { case DIR_STATE_INITIALIZED: { if(strlen(ptr->dirname)) { ptr->dir = opendir(ptr->dirname); if(ptr->dir) { de = readdir(ptr->dir); if(de) { ptr->state = DIR_STATE_OPENED; back = 1; /* back = get_file_properties(ptr, de->d_name); */ if(!get_file_properties(ptr, de->d_name)) { back = -1; } } else { closedir(ptr->dir); ptr->dir = NULL; ptr->state = DIR_STATE_CLOSED; } } else { } } else { } } break; case DIR_STATE_OPENED: { de = readdir(ptr->dir); if(de) { /* back = get_file_properties(ptr, de->d_name); */ back = 1; if(!get_file_properties(ptr, de->d_name)) { back = -1; } } else { closedir(ptr->dir); ptr->dir = NULL; ptr->state = DIR_STATE_CLOSED; } } break; default: { } break; } } return back; } /** Initialize a new directory. @param ptr Directory to initialize. */ static void init_new_directory DK_P1(dk_dir_t *,ptr) { ptr->dir = NULL; } #else /* any unknown directory listing mechanism */ #endif #endif #endif void dkdir_delete DK_P1(dk_dir_t *, ptr) { if(ptr) { char *p; p = ptr->dirname; if(p) { dk_delete(p); } p = ptr->fullname; if(p) { dk_delete(p); } p = ptr->shortname; if(p) { dk_delete(p); } ptr->dirname = ptr->fullname = ptr->shortname = NULL; dk_delete(ptr); } } dk_dir_t * dkdir_new DK_P0() { dk_dir_t *back = NULL; long ml; back = dk_new(dk_dir_t,1); if(back) { char *ptr; back->error_code = DK_ERR_NONE; back->dirname = back->fullname = back->shortname = NULL; ml = back->maxpathlen = dksf_get_maxpathlen(); back->state = DIR_STATE_UNUSED; ptr = dk_new(char,ml); if(ptr) { back->dirname = ptr; } ptr = dk_new(char,ml); if(ptr) { back->fullname = ptr; } ptr = dk_new(char,ml); if(ptr) { back->shortname = ptr; } if(!((back->dirname) && (back->fullname) && (back->shortname))) { dkdir_delete(back); back = NULL; } else { *(back->dirname) = '\0'; *(back->fullname) = '\0'; *(back->shortname) = '\0'; init_new_directory(back); } } return back; } void dkdir_close DK_P1(dk_dir_t *, ptr) { if(ptr) { dkdir_end_search(ptr); dkdir_delete(ptr); } } dk_dir_t * dkdir_open DK_P1(char *, name) { dk_dir_t *back = NULL; if(name) { back = dkdir_new(); if(back) { if(!dkdir_start_search(back,name)) { dkdir_close(back); back = NULL; } } else { } } else { } return back; } char * dkdir_get_fullname(dk_dir_t *ptr) { char *back = NULL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = ptr->fullname; } } return back; } char * dkdir_get_shortname(dk_dir_t *ptr) { char *back = NULL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = ptr->shortname; } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } long dkdir_uid DK_P1(dk_dir_t *, ptr) { long back = 0L; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_uid(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } long dkdir_gid DK_P1(dk_dir_t *, ptr) { long back = 0L; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_gid(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } char * dkdir_ctime DK_P1(dk_dir_t *, ptr) { char *back = NULL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_ctime(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } char * dkdir_atime DK_P1(dk_dir_t *, ptr) { char *back = NULL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_atime(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } char * dkdir_mtime DK_P1(dk_dir_t *, ptr) { char *back = NULL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_mtime(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } int dkdir_filetype DK_P1(dk_dir_t *, ptr) { int back = 0; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_filetype(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } int dkdir_permissions DK_P1(dk_dir_t *, ptr) { int back = 0; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_permissions(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } unsigned long dkdir_inode DK_P1(dk_dir_t *, ptr) { unsigned long back = 0UL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_inode(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } unsigned long dkdir_device DK_P1(dk_dir_t *, ptr) { unsigned long back = 0UL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_device(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } unsigned long dkdir_rdevice DK_P1(dk_dir_t *, ptr) { unsigned long back = 0UL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_rdevice(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } unsigned long dkdir_nlinks DK_P1(dk_dir_t *, ptr) { unsigned long back = 0UL; if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_nlinks(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } dk_long_long_unsigned_t dkdir_size DK_P1(dk_dir_t *, ptr) { #if DK_HAVE_LONG_LONG_INT dk_long_long_unsigned_t back = 0ULL; #else dk_long_long_unsigned_t back = 0UL; #endif if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_size(&(ptr->stbuf)); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } dk_long_long_unsigned_t dkdir_size_ok DK_P2(dk_dir_t *, ptr, int *, ok) { #if DK_HAVE_LONG_LONG_INT dk_long_long_unsigned_t back = 0ULL; #else dk_long_long_unsigned_t back = 0UL; #endif if(ptr) { if(ptr->state == DIR_STATE_OPENED) { back = dkstat_size_ok(&(ptr->stbuf), ok); } else { ptr->error_code = DK_ERR_NOT_NOW; } } return back; } /** File name expander state: Not yet initialized. */ #define FNE_STATE_UNUSED 0 /** File name expander state: Initialized. */ #define FNE_STATE_INITIALIZED 1 /** File name expander state: Opened. */ #define FNE_STATE_OPENED 2 /** File name expander state: Closed. */ #define FNE_STATE_CLOSED 3 /** File name expander state: Search for directories. */ #define FNE_DIRS 8 /** File name expander state: Search for files. */ #define FNE_FILES 16 /** File name expander state: Must run. */ #define FNE_MUST_RUN 32 /** File name expander state: Not yet initialized. */ #define FNE_NOT_STATE (FNE_DIRS | FNE_FILES | FNE_MUST_RUN) /** Correct a directory name. @param name Buffer containing the file name. */ static void correct_dir_name DK_P1(char *, name) { char *ptr; ptr = name; while(*ptr) { #if DK_HAVE_FEATURE_BACKSLASH if(*ptr == '/') { *ptr = '\\'; } #else if(*ptr == '\\') { *ptr = '/'; } #endif ptr++; } } dk_fne_t * dkfne_open DK_P3(char *, name, int, files, int, dirs) { dk_fne_t *back = NULL; if(name && (files || dirs)) { if(strlen(name) > 0) { back = dkdir_new(); if(back) { if((long)strlen(name) < back->maxpathlen) { strcpy(back->dirname, name); correct_dir_name(back->dirname); back->state = FNE_STATE_INITIALIZED; if(files) { back->state |= FNE_FILES; } if(dirs) { back->state |= FNE_DIRS; } #if USE_FNE if(dkstr_chr(name, '*')) { back->state |= FNE_MUST_RUN; } else { if(dkstr_chr(name, '?')) { back->state |= FNE_MUST_RUN; } } #endif } else { dkdir_delete(back); back = NULL; } } else { } } else { } } else { } return back; } /** Find one file name matching a pattern. @param f File name expander. @return 1 on success, 0 on error. */ static int dkfne_find_one DK_P1(dk_fne_t *, f) { int back = 0; char *ptr; if(f) { (f->fullname)[0] = '\0'; (f->shortname)[0] = '\0'; if(f->state & FNE_MUST_RUN) { #if USE_FNE switch(f->state & (~(FNE_NOT_STATE))) { case FNE_STATE_INITIALIZED: { #if defined(WIN32) || defined(_WIN32) /* + Win32 */ #if DK_HAVE__FINDFIRST64 /* Win32, _findfirst64 */ f->hFile64 = _findfirst64(f->dirname, &(f->fdt64)); if(f->hFile64 != -1L) { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_OPENED); if((long)strlen((f->fdt64).name) < f->maxpathlen) { strcpy(f->shortname, (f->fdt64).name); back = 1; } else { f->error_code = DK_ERR_STRING_TOO_LONG; } } else { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); f->error_code = DK_ERR_NO_SUCH_FILE; } #else #if DK_HAVE__FINDFIRST32 /* Win32, _findfirst32 */ f->hFile32 = _findfirst32(f->dirname, &(f->fdt32)); if(f->hFile32 != -1L) { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_OPENED); if((long)strlen((f->fdt32).name) < f->maxpathlen) { strcpy(f->shortname, (f->fdt).name); back = 1; } else { f->error_code = DK_ERR_STRING_TOO_LONG; } } else { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); f->error_code = DK_ERR_NO_SUCH_FILE; } #else #if DK_HAVE__FINDFIRST /* Win32, _findfirst */ f->hFile = _findfirst(f->dirname, &(f->fdt)); if(f->hFile != -1L) { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_OPENED); if((long)strlen((f->fdt).name) < f->maxpathlen) { strcpy(f->shortname, (f->fdt).name); back = 1; } else { f->error_code = DK_ERR_STRING_TOO_LONG; } } else { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); f->error_code = DK_ERR_NO_SUCH_FILE; } #endif #endif #endif /* - Win32 */ #else #if DK_HAVE_FINDFIRST /* DOS, findfirst */ int i; i = findfirst(f->dirname, &(f->dir), ((f->state & FNE_FILES) ? FA_DIREC : 0)); if(i == 0) { if(strlen((f->dir).ff_name) < f->maxpathlen) { strcpy(f->shortname, (f->dir).ff_name); back = 1; f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_OPENED); } else { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); f->error_code = DK_ERR_STRING_TOO_LONG; } } else { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); f->error_code = DK_ERR_NO_SUCH_FILE; } #else #if DK_HAVE_DIRENT_H /* UNIX/Linux, dirent */ #else /* any unknown directory listing mechanism */ #endif #endif #endif } break; case FNE_STATE_OPENED: { int i; #if defined(WIN32) || defined(_WIN32) /* + Win32 */ #if DK_HAVE__FINDFIRST64 /* Win32, _findfirst64 */ i = _findnext64(f->hFile64, &(f->fdt64)); if(i == 0) { if((long)strlen((f->fdt64).name) < f->maxpathlen) { strcpy(f->shortname, (f->fdt64).name); back = 1; } else { f->error_code = DK_ERR_STRING_TOO_LONG; } } else { _findclose(f->hFile64); f->hFile64 = -1L; f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); f->error_code = DK_ERR_FINISHED; } #else #if DK_HAVE__FINDFIRST32 /* Win32, _findfirst32 */ i = _findnext32(f->hFile32, &(f->fdt32)); if(i == 0) { if((long)strlen((f->fdt32).name) < f->maxpathlen) { strcpy(f->shortname, (f->fdt32).name); back = 1; } else { f->error_code = DK_ERR_STRING_TOO_LONG; } } else { _findclose(f->hFile32); f->hFile32 = -1L; f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); f->error_code = DK_ERR_FINISHED; } #else #if DK_HAVE__FINDFIRST /* Win32, _findfirst */ i = _findnext(f->hFile, &(f->fdt)); if(i == 0) { if((long)strlen((f->fdt).name) < f->maxpathlen) { strcpy(f->shortname, (f->fdt).name); back = 1; } else { f->error_code = DK_ERR_STRING_TOO_LONG; } } else { _findclose(f->hFile); f->hFile = -1L; f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); f->error_code = DK_ERR_FINISHED; } #endif #endif #endif /* - Win32 */ #else #if DK_HAVE_FINDFIRST /* DOS, findfirst */ i = findnext(&(f->dir)); if(i == 0) { if(strlen((f->dir).ff_name) < f->maxpathlen) { strcpy(f->shortname, (f->dir).ff_name); back = 1; } else { f->error_code = DK_ERR_STRING_TOO_LONG; } } else { f->state = ((f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED); } #else #if DK_HAVE_DIRENT_H /* UNIX/Linux, dirent */ #else /* any unknown directory listing mechanism */ #endif #endif #endif } break; default: { f->error_code = DK_ERR_NOT_NOW; } break; } #endif } else { switch(f->state & (~(FNE_NOT_STATE))) { case FNE_STATE_INITIALIZED: { strcpy(f->fullname, f->dirname); ptr = dkstr_rchr(f->fullname, path_component_separator[0]); if(ptr) { ptr++; } else { ptr = f->fullname; } strcpy(f->shortname, ptr); f->state = (FNE_STATE_CLOSED | ((f->state) & FNE_NOT_STATE)); back = 1; } break; default: { f->error_code = DK_ERR_NOT_NOW; } break; } } } if(back) { #if USE_FNE if((f->state) & FNE_MUST_RUN) { strcpy(f->fullname, f->dirname); ptr = dkstr_rchr(f->fullname, path_component_separator[0]); if(ptr) { ptr++; } else { ptr = f->fullname; } strcpy(ptr, f->shortname); } #endif } return back; } int dkfne_next DK_P1(dk_fne_t *, f) { int back = 0; int can_continue, must_continue, ft; char *fullname; dk_stat_t stb; if(f) { can_continue = must_continue = 1; while(can_continue && must_continue) { can_continue = dkfne_find_one(f); if(can_continue) { fullname = dkfne_get_fullname(f); if(fullname) { if(dkstat_get(&stb, fullname)) { ft = dkstat_filetype(&stb); ft = ft & (~(DK_FT_SYMLINK)); switch(ft) { case DK_FT_REG : { if((f->state) & FNE_FILES) { back = 1; must_continue = 0; } } break; case DK_FT_DIR : { if((f->state) & FNE_DIRS) { back = 1; must_continue = 0; } } break; } } } } } } return back; } char *dkfne_get_one DK_P1(dk_fne_t *, f) { char *back = NULL; char *ptr; if(f) { if(dkfne_next(f)) { ptr = dkfne_get_fullname(f); if(ptr) { back = dkstr_dup(ptr); if(back) { if(dkfne_next(f)) { dk_delete(back); back = NULL; f->error_code = DK_ERR_NOT_UNIQUE; } } else { f->error_code = DK_ERR_NOMEM; } } else { f->error_code = DK_ERR_NO_SUCH_FILE; } } else { f->error_code = DK_ERR_NO_SUCH_FILE; } } return back; } char * dkfne_get_fullname DK_P1(dk_fne_t *, f) { char *back = NULL; if(f) { back = f->fullname; } return back; } char * dkfne_get_shortname DK_P1(dk_fne_t *, f) { char *back = NULL; if(f) { back = f->shortname; } return back; } void dkfne_close DK_P1(dk_fne_t *, f) { if(f) { #if USE_FNE switch(f->state & (~(FNE_NOT_STATE))) { case FNE_STATE_OPENED: { #if defined(WIN32) || defined(_WIN32) /* + Win32 */ #if DK_HAVE__FINDFIRST64 /* Win32, _findfirst64 */ _findclose(f->hFile64); f->hFile64 = -1L; f->state = (f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED; #else #if DK_HAVE__FINDFIRST32 /* Win32, _findfirst32 */ _findclose(f->hFile32); f->hFile32 = -1L; f->state = (f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED; #else #if DK_HAVE__FINDFIRST /* Win32, _findfirst */ _findclose(f->hFile); f->hFile = -1L; f->state = (f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED; #endif #endif #endif /* - Win32 */ #else #if DK_HAVE_FINDFIRST /* DOS, findfirst */ int i; i = 0; while(!i) { i = findnext(&(f->dir)); } f->state = (f->state & FNE_NOT_STATE) | FNE_STATE_CLOSED; #else #if DK_HAVE_DIRENT_H /* UNIX/Linux, dirent */ #else /* any unknown directory listing mechanism */ #endif #endif #endif } break; default: { } break; } #endif } } char * dksf_get_last_filename DK_P1(char *, name) { char *back = NULL; if(name) { back = dkstr_rchr(name, path_component_separator[0]); if(back) { back++; } else { back = name; } } return back; } char * dksf_get_file_type_dot DK_P1(char *, name) { char *back = NULL; char *x; if(name) { x = dkstr_rchr(name, path_component_separator[0]); x = (x ? x : name); back = dkstr_rchr(x, '.'); } return back; } int dksf_is_abs_path DK_P1(char *, name) { int back = 0; if(name) { if(*name == path_component_separator[0]) { back = 1; } else { #if DK_HAVE_FEATURE_DRIVECHAR if(((*name >= 'a') && (*name <= 'z')) || ((*name >= 'A') && (*name <= 'Z'))) { if(name[1] == ':') { if(name[2] == path_component_separator[0]) { if(name[3]) { back = 1; } } } } #endif } } return back; } /** Find place where tu cut a file name. @param dirname Directory name. @return Pointer to cut position. */ static char * find_place_to_cut DK_P1(char *, dirname) { char *back = NULL; char *ptr; int seps_found; int last_was_sep; last_was_sep = 0; seps_found = 0; ptr = dirname; while(*ptr) { if(*ptr == path_component_separator[0]) { seps_found++; last_was_sep = 1; if(seps_found > 1) { back = ptr; } } else { if(last_was_sep) { if(seps_found == 1) { back = ptr; } } last_was_sep = 0; } ptr++; } return back; } int dksf_path_combine DK_P4(char *, buf, size_t, len, char *, cd, char *, pr) { int back = 0; size_t used; char *xptr, *yptr, *zptr; if(buf) { if(len > 3) { if(cd) { if(pr) { used = strlen(cd); if(used < len) { back = 1; strcpy(buf, cd); xptr = pr; if(dksf_is_abs_path(pr)) { xptr++; *buf = pr[0]; if(*buf != path_component_separator[0]) { buf[1] = pr[1]; buf[2] = pr[2]; buf[3] = '\0'; xptr++; xptr++; } else { buf[1] = '\0'; } used = strlen(buf); } while(xptr && back) { used = strlen(buf); yptr = dkstr_chr(xptr, path_component_separator[0]); if(yptr) { *yptr = '\0'; } if(strcmp(xptr, ".")) { if(strcmp(xptr, "..")) { if((used + strlen(xptr) + 1) < len) { if(buf[(used > 0) ? (used - 1) : used] != path_component_separator[0]) { strcat(buf, path_component_separator); } strcat(buf, xptr); } else { back = 0; } } else { /* zptr = dkstr_rchr(buf, path_component_separator[0]); */ zptr = find_place_to_cut(buf); if(zptr) { *zptr = '\0'; } else { back = 0; } } } if(yptr) { *yptr = path_component_separator[0]; } xptr = yptr; if(xptr) xptr++; } } } } } } return back; } #if DK_HAVE_FEATURE_DOS_EXEC /** Check whether a file name exists with one of the specified suffixes. @param buf Buffer containing the base file name. @param len Length of \a buf. @param pe List of suffixes for executable files, semicolon separated. @return 1 on success, 0 on error. */ static int check_executable_file(char *buf, size_t len, char *pe) { int back = 0; size_t lgt; dk_stat_t st; char *xptr, *yptr; if(dksf_get_file_type_dot(buf)) { if(dkstat_get(&st, buf)) { if((dkstat_filetype(&st) & (~(DK_FT_SYMLINK))) == DK_FT_REG) { back = 1; } } } else { lgt = strlen(buf); xptr = pe; while(xptr && (!back)) { yptr = dkstr_chr(xptr, ';'); if(yptr) { *(yptr++) = '\0'; } if((lgt + strlen(xptr)) < len) { strcat(buf, xptr); if(dkstat_get(&st, buf)) { if((dkstat_filetype(&st) & (~(DK_FT_SYMLINK))) == DK_FT_REG) { back = 1; } } } if(!back) { buf[lgt] = '\0'; } xptr = yptr; } } return back; } #endif int dksf_get_executable DK_P5(char *, buf, size_t, len, char *, cd, char *, pr, int, cu) { int back = 0; char psep; int action; char *pathori; char *pathcp; #if DK_HAVE_FEATURE_DOS_EXEC char *pe; char *pc; #endif char *xptr; char *yptr; size_t used; if(buf) { if(len) { if(cd) { if(pr) { psep = path_component_separator[0]; if(dkstr_chr(pr,psep)) { action = 2; } else { action = 0; } if(dksf_get_file_type_dot(pr)) { action += 1; } #if DK_HAVE_FEATURE_DOS_EXEC #if DK_HAVE_GETMODULEFILENAME && DK_HAVE_GETMODULEHANDLE if(cu) { if(GetModuleFileNameA(GetModuleHandle(NULL),buf,len)) { back = 1; } } #endif /* DOS exec search, current directory first */ if(!back) { pe = getenv("PATHEXT"); if(!pe) pe = default_path_ext; pc = dkstr_dup(pe); if(pc) { if(action & 2) { if(len > strlen(pr)) { strcpy(buf, pr); back = check_executable_file(buf, len, pc); } } else { if(len > (strlen(cd) + strlen(pr) + 1)) { strcpy(buf, cd); used = strlen(cd); if(used > 0) used--; if(buf[used] != path_component_separator[0]) { strcat(buf, path_component_separator); } strcat(buf, pr); back = check_executable_file(buf, len, pc); } if(!back) { pathori = getenv("PATH"); if(pathori) { pathcp = dkstr_dup(pathori); if(pathcp) { xptr = pathcp; while(xptr && (!back)) { strcpy(pc, pe); yptr = dkstr_chr(xptr, ';'); if(yptr) { *(yptr++) = '\0'; } if(len > (strlen(xptr) + 1 + strlen(pr))) { strcpy(buf, xptr); used = strlen(buf); if(used > 0) used--; if(buf[used] != path_component_separator[0]) { strcat(buf, path_component_separator); } strcat(buf, pr); back = check_executable_file(buf, len, pc); } xptr = yptr; } dkmem_free(pathcp); } } } } dkmem_free(pc); } } #else /* UNIX exec search, consult PATH/path */ if(action & 2) { if(dksf_is_abs_path(pr)) { if(strlen(pr) < len) { strcpy(buf,pr); back = 1; } } else { back = dksf_path_combine(buf, len, cd, pr); } } else { pathori = getenv("PATH"); if(pathori) { dk_stat_t st; pathcp = dkstr_dup(pathori); if(pathcp) { xptr = pathcp; while(xptr && (!back)) { yptr = dkstr_chr(xptr, ':'); if(yptr) { *(yptr++) = '\0'; } if(strlen(xptr) == 0) { if(len > (strlen(cd) + strlen(pr) + 1)) { strcpy(buf, cd); used = strlen(cd); if(used > 0) used--; if(buf[used] != path_component_separator[0]) { strcat(buf, path_component_separator); } strcat(buf, pr); if(dkstat_get(&st, buf)) { if((dkstat_filetype(&st) & (~DK_FT_SYMLINK)) == DK_FT_REG) { if(dkstat_permissions(&st) & DK_PERM_U_EXECUTE) { back = 1; } } } } } else { if(len > (strlen(xptr) + strlen(pr) + 1)) { strcpy(buf, xptr); used = strlen(xptr); if(used > 0) used--; if(buf[used] != path_component_separator[0]) { strcat(buf, path_component_separator); } strcat(buf, pr); if(dkstat_get(&st, buf)) { if((dkstat_filetype(&st) & (~DK_FT_SYMLINK)) == DK_FT_REG) { if(dkstat_permissions(&st) & DK_PERM_U_EXECUTE) { back = 1; } } } } } xptr = yptr; } dkmem_free(pathcp); } } } #endif } } } } return back; } int dksf_getcwd DK_P2(char *, buffer, size_t, lgt) { int back = 0; if(buffer && lgt) { #if DK_HAVE_GETCURRENTDIRECTORY if(GetCurrentDirectoryA(lgt,buffer)) { back = 1; } #else #if DK_HAVE_GETCWD if(getcwd(buffer, lgt)) { back = 1; } #else #if DK_HAVE_GETWD char *buf; buf = dk_new(char,DK_MAX_PATH); if(buf) { if(getwd(buf)) { if(strlen(buf) < lgt) { strcpy(buffer, buf); back = 1; } } dk_delete(buf); buf = NULL; } #else #if DK_HAVE__GETCWD if(_getcwd(buffer, lgt)) { back = 1; } #else #if DK_HAVE__GETWD char *buf; buf = dk_new(char,DK_MAX_PATH); if(buf) { if(_getwd(buf)) { if(strlen(buf) < lgt) { strcpy(buffer, buf); back = 1; } } dk_delete(buf); buf = NULL; } #else #error "No getcwd/getwd/_getcwd/_getwd function" #endif #endif #endif #endif #endif } return back; } void dksf_correct_fnsep DK_P1(char *,str) { char *ptr; if(str) { ptr = str; while(*ptr) { if(*ptr == no_component_separator[0]) { *ptr = path_component_separator[0]; } ptr++; } } } int dksf_remove_file DK_P1(char *, filename) { int back = 0; if(filename) { #if DK_HAVE_UNLINK || DK_HAVE__UNLINK #if DK_HAVE_UNLINK if(unlink(filename) == 0) { #else if(_unlink(filename) == 0) { #endif back = 1; } #else #if DK_HAVE_REMOVE if(remove(filename) == 0) { back = 1; } #endif #endif } return back; } /** Attempt to remove a directory with all contents. @param filename File name of directory. @param bck Set to 0 on error. */ static void remove_dir_rec DK_P2(char *, filename, int *, bck) { dk_stat_t st; dk_dir_t *dir; char *sn, *fn; int dnt; if(dkstat_get(&st, filename)) { if((st.filetype) & DK_FT_SYMLINK) { if(!dksf_remove_file(filename)) { *bck = 0; } } else { switch(st.filetype) { case DK_FT_DIR : { dir = dkdir_open(filename); if(dir) { while((dnt = dkdir_next(dir))) { if(dnt == 1) { sn = dir->shortname; fn = dir->fullname; if(sn && fn) { if(strcmp(sn, ".")) { if(strcmp(sn, "..")) { remove_dir_rec(fn, bck); } } } else { *bck = 0; } } } dkdir_close(dir); dir = NULL; #if DK_HAVE_RMDIR || DK_HAVE__RMDIR #if DK_HAVE_RMDIR if(rmdir(filename) != 0) #else if(_rmdir(filename) != 0) #endif { *bck = 0; } #else #if DK_HAVE_UNLINK || DK_HAVE__UNLINK #if DK_HAVE_UNLINK if(unlink(filename) != 0) #else if(_unlink(filename) != 0) #endif { *bck = 0; } #else #if DK_HAVE_REMOVE if(remove(filename) != 0) { *bck = 0; } #else #endif #endif #endif } else { *bck = 0; } } break; default : { if(!dksf_remove_file(filename)) { *bck = 0; } } break; } } } else { *bck = 0; } } int dksf_remove_directory DK_P1(char *, filename) { int back = 0; if(filename) { back = 1; remove_dir_rec(filename, &back); } return back; } dk_stat_t * dkdir_stat DK_P1(dk_dir_t *,d) { dk_stat_t *back = NULL; if(d) { back = &(d->stbuf); } return back; } int dksf_fdesk_binary DK_P2(int,fn, int,fl) { int back = 0; #if DK_HAVE_DOSWIN_SETMODE int res = 0; #endif #if DK_HAVE_DOSWIN_SETMODE if(fl) { #if DK_HAVE_DOSWIN_SETMODE #if DK_HAVE_SETMODE #ifdef O_BINARY res = setmode(fn, O_BINARY); if(res == O_BINARY) back = 1; #else #ifdef _O_BINARY res = setmode(fn, _O_BINARY); if(res == _O_BINARY) back = 1; #endif #endif #else #if DK_HAVE__SETMODE #ifdef O_BINARY res = _setmode(fn, O_BINARY); if(res == O_BINARY) back = 1; #else #ifdef _O_BINARY res = _setmode(fn, _O_BINARY); if(res == _O_BINARY) back = 1; #endif #endif #endif #endif #endif } else { #if DK_HAVE_DOSWIN_SETMODE #if DK_HAVE_SETMODE #ifdef O_TEXT res = setmode(fn, O_TEXT); if(res == O_BINARY) back = 1; #else #ifdef _O_TEXT res = setmode(fn, _O_TEXT); if(res == _O_BINARY) back = 1; #endif #endif #else #if DK_HAVE__SETMODE #ifdef O_TEXT res = _setmode(fn, O_TEXT); if(res == O_BINARY) back = 1; #else #ifdef _O_TEXT res = _setmode(fn, _O_TEXT); if(res == _O_BINARY) back = 1; #endif #endif #endif #endif #endif } #endif return back; } /** Check whether a file name is a symbolic link. @param name File name. @return 1 for symbolic link, 0 for other file types. */ static int is_symbolic_link DK_P1(char *,name) { int back = 0; dk_stat_t st; if(name) { dkstat_init(&st); if(dkstat_get(&st, name)) { if((st.filetype) & DK_FT_SYMLINK) { back = 1; } } } return back; } /** Check whether a file name is a directory. @param name File name to check. @return 1 for directory, 0 for not a directory. */ static int is_directory DK_P1(char *,name) { int back = 0; dk_stat_t st; if(name) { dkstat_init(&st); if(dkstat_get(&st, name)) { if(((st.filetype) & (~(DK_FT_SYMLINK))) == DK_FT_DIR) { back = 1; } } } return back; } /** When opening a file to write check that it is not a directory. @param name File name to open. @param ign Security checks to ignore. @param reason Pointer to buffer for reason. @return 1 on success (we can write the file), 0 on error. */ static int directory_write_check DK_P3(char *,name,int,ign,int *,reason) { int back = 1; dk_stat_t st; if(name) { if(dkstat_get(&st, name)) { if((st.permissions) & DK_PERM_O_WRITE) { if(!(ign & DK_SF_SEC_WO)) { back = 0; if(reason) *reason = DK_SF_SEC_WO; } } if((st.permissions) & DK_PERM_G_WRITE) { if(!(ign & DK_SF_SEC_WG)) { back = 0; if(reason) *reason = DK_SF_SEC_WG; } } } } return back; } /** Check whether the link target is owned by the same user as the link itself. @param name File name. @return 1 for check ok, 0 for check failed. */ static int check_ownership_for_symlink DK_P1(char *,name) { int back = 0; dk_stat_t st; if(name) { if(dkstat_get(&st, name)) { if(st.ud) { back = 1; } } } return back; } int dksf_allowed_to_write DK_P3(char *,name,int,ign,int *,reason) { int back = 0; char *dirname; char *cptr; size_t lgt; if(name) { if(is_symbolic_link(name)) { dirname = dkstr_dup(name); if(dirname) { cptr = dkstr_rchr(dirname, path_component_separator[0]); if(cptr) { *cptr = (char)0; if((lgt = strlen(dirname)) > 0) { #if DK_HAVE_DOS_DRIVE_LETTER if(lgt == 2) { if(dirname[1] == str_colon) { dirname[2] = path_component_separator[0]; dirname[3] = (char)0; } } #endif /* DK_HAVE_DOS_DRIVE_LETTER */ back = directory_write_check(dirname,ign,reason); } else { dirname[0] = path_component_separator[0]; dirname[1] = (char)0; back = directory_write_check(dirname,ign,reason); } } else { back = directory_write_check(curdir,ign,reason); } dk_delete(dirname); } if(back) { if(!(ign & DK_SF_SEC_OWNER)) { if(!check_ownership_for_symlink(name)) { back = 0; if(reason) { *reason = DK_SF_SEC_OWNER; } } } } } else { back = 1; } } return back; } FILE * dksf_msfo DK_P4(char *,name,char *,mode,int,ign,int *,reason) { FILE *back = NULL; int want_to_write; char *cptr; if(name && mode) { want_to_write = 0; cptr = mode; while(*cptr) { switch(*(cptr++)) { case 'w': case 'a': case '+': { want_to_write = 1; } break; } } if(want_to_write) { if(dksf_allowed_to_write(name,ign,reason)) { if(is_directory(name)) { if(reason) { *reason = DK_SF_SEC_DIR; } } else { #if DK_HAVE_LARGEFILE64_SOURCE && DK_HAVE_FOPEN64 back = fopen64(name,mode); #else back = fopen(name,mode); #endif } } } else { if(is_directory(name)) { if(reason) { *reason = DK_SF_SEC_DIR; } } else { #if DK_HAVE_LARGEFILE64_SOURCE && DK_HAVE_FOPEN64 back = fopen64(name, mode); #else back = fopen(name,mode); #endif } } } return back; } FILE * dksf_fopen DK_P2(char *,p,char *,m) { FILE *back = NULL; int dummy = 0; back = dksf_msfo(p,m,0,&dummy); return back; } int dksf_must_expand_filename DK_P1(char *,name) { int back = 0; #if DK_HAVE_FEATURE_BACKSLASH && USE_FNE char *ptr; ptr = name; while((!back) && (*ptr)) { if((*ptr == '?') || (*ptr == '*')) { back = 1; } ptr++; } #endif return back; } int dkfne_get_error_code DK_P2(dk_fne_t *,f, int, res) { int back = DK_ERR_NONE; if(f) { back = f->error_code; if(res) { f->error_code = DK_ERR_NONE; } } return back; } int dksf_get_filetype DK_P1(char *,pathname) { int back = 0; dk_stat_t st; if(pathname) { dkstat_init(&st); if(dkstat_get(&st, pathname)) { back = st.filetype; } } return back; } int dksf_is_directory DK_P1(char *,pathname) { int back = 0; int ft = 0; if(pathname) { ft = dksf_get_filetype(pathname); ft &= (~DK_FT_SYMLINK); if(ft == DK_FT_DIR) { back = 1; } } return back; } int dksf_no_core DK_P0() { int back = 0; #if DK_HAVE_SYS_RESOURCE_H #if DK_HAVE_GETRLIMIT #ifdef RLIMIT_CORE struct rlimit rl; rl.rlim_cur = rl.rlim_max = 0; if(setrlimit(RLIMIT_CORE, &rl) == 0) { back = 1; } #endif #endif #endif return back; } /* Usage: dk_echo_t echodata; if(dksf_echo_save(&echodata)) { dksf_echo_off(&echodata); ... dksf_echo_restore(&echodata); } */ int dksf_echo_save DK_P1(dk_echo_t *,ep) { int back = 0; if(ep) { ep->is_tty = 0; #if DK_HAVE_TCGETATTR if(tcgetattr(0, &(ep->ori)) == 0) { back = 1; } #if DK_HAVE_ISATTY ep->is_tty = isatty(0); #endif #else #ifdef TCGETS if(ioctl(0, TCGETS, &(ep->ori)) == 0) { back = 1; } #if DK_HAVE_ISATTY ep->is_tty = isatty(0); #endif #else #if DK_HAVE_GETSTDHANDLE ep->consoleHandle = GetStdHandle(STD_INPUT_HANDLE); if(ep->consoleHandle != INVALID_HANDLE_VALUE) { ep->is_tty = 1; if(GetConsoleMode(ep->consoleHandle, &(ep->ori))) { back = 1; } } #else #if DK_HAVE_ISATTY ep->is_tty = isatty(0); #endif #endif #endif #endif } return back; } int dksf_echo_restore DK_P1(dk_echo_t *,ep) { int back = 0; if(ep) { #if DK_HAVE_TCGETATTR if(tcsetattr(0, TCSANOW, &(ep->ori)) == 0) { back = 1; } #else #ifdef TCGETS if(ioctl(0, TCSETS, &(ep->ori)) == 0) { back = 1; } #else #if DK_HAVE_GETSTDHANDLE if(ep->consoleHandle != INVALID_HANDLE_VALUE) { if(SetConsoleMode(ep->consoleHandle, ep->ori)) { back = 1; } } #endif #endif #endif } return back; } /** Abbreviation for use with sizeof operator. */ typedef struct termios TIO; int dksf_echo_off DK_P1(dk_echo_t *,ep) { int back = 0; if(ep) { #if DK_HAVE_TCGETATTR struct termios nti; DK_MEMCPY(&nti, &(ep->ori), sizeof(TIO)); #ifdef ECHO nti.c_lflag &= (~(ECHO)); #endif #ifdef ECHONL nti.c_lflag |= (ECHONL); #endif if(tcsetattr(0, TCSANOW, &nti) == 0) { back = 1; } tcflush(0, TCIFLUSH); #else #ifdef TCGETS struct termios nti; DK_MEMCPY(&nti, &(ep->ori), sizeof(TIO)); #ifdef ECHO nti.c_lflag &= (~(ECHO)); #endif #ifdef ECHONL nti.c_lflag |= (ECHONL); #endif if(ioctl(0, TCSETS, &nti) == 0) { back = 1; } (void)ioctl(0, TCFLSH, 0); #else #if DK_HAVE_GETSTDHANDLE DWORD nti; nti = ep->ori; if(ep->consoleHandle != INVALID_HANDLE_VALUE) { nti &= (~(ENABLE_ECHO_INPUT)); if(SetConsoleMode(ep->consoleHandle, nti)) { back = 1; } } #endif #endif #endif } return back; } int dksf_echo_is_tty DK_P1(dk_echo_t *,ep) { int back = 0; if(ep) { back = ep->is_tty; } return back; } int dksf_echo_test_tty DK_P0() { int back = 0; #if DK_HAVE_TCGETATTR #if DK_HAVE_ISATTY back = isatty(0); #endif #else #ifdef TCGETS #if DK_HAVE_ISATTY back = isatty(0); #endif #else #if DK_HAVE_GETSTDHANDLE if(GetStdHandle(STD_INPUT_HANDLE) != INVALID_HANDLE_VALUE) { back = 1; } #else #if DK_HAVE_ISATTY back = isatty(0); #endif #endif #endif #endif return back; } unsigned long dksf_filesize_bytes DK_P0() { unsigned long back = 0UL; #if defined(WIN32) || defined(_WIN32) #if DK_HAVE__STAT64 back = 8UL; #else #if DK_HAVE__STAT32 back = 4UL; #else back = (unsigned long)sizeof(off_t); #endif #endif #else #if DK_HAVE_STAT64 && DK_HAVE_LARGEFILE64_SOURCE back = 8UL; #else back = (unsigned long)sizeof(off_t); #endif #endif return back; } unsigned long dksf_long_long_bytes DK_P0() { return (unsigned long)sizeof(dk_long_long_unsigned_t); } /** Write PID file. @param appname Application name. @param cr 1=create, 0=delete @return 1 on success, 0 on error. */ int dksf_write_pid_file DK_P2(char *,appname, int,cr) { int back = 0; size_t sz = 0; FILE *fipo = NULL; char buffer[MY_MAXPATHLEN]; if(appname) { sz = strlen(var_run); sz += strlen(path_component_separator); sz += strlen(appname); sz += strlen(suffix_pid); if(sz < sizeof(buffer)) { strcpy(buffer, var_run); strcat(buffer, path_component_separator); strcat(buffer, appname); strcat(buffer, suffix_pid); switch(cr) { case 1: { fipo = dksf_fopen(buffer, "w"); if(fipo) { fprintf(fipo, "%ld\n", dksf_getpid()); fclose(fipo); fipo = NULL; } } break; default: { back = dksf_remove_file(buffer); } break; } } } return back; }