File indexing completed on 2024-04-14 14:20:00

0001 /*
0002    This file is part of the KDE libraries
0003    Copyright (C) 2004 Jarosław Staniek <staniek@kde.org>
0004    Copyright (C) 2009 Christian Ehrlicher <ch.ehrlicher@gmx.de>
0005 
0006    This library is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU Library General Public
0008    License version 2 as published by the Free Software Foundation.
0009 
0010    This library is distributed in the hope that it will be useful,
0011    but WITHOUT ANY WARRANTY; without even the implied warranty of
0012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0013    Library General Public License for more details.
0014 
0015    You should have received a copy of the GNU Library General Public License
0016    along with this library; see the file COPYING.LIB.  If not, write to
0017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0018    Boston, MA 02110-1301, USA.
0019 */
0020 
0021 // needed for _wstat64
0022 #define __MSVCRT_VERSION__ 0x601
0023 
0024 #include "kde_file.h"
0025 
0026 #include <QFile>
0027 #include <errno.h>
0028 
0029 #include <sys/utime.h>
0030 #include <sys/stat.h>
0031 #include <wchar.h>
0032 #define CONV(x) ((wchar_t*)x.utf16())
0033 
0034 /** @internal, from kdewin32 lib */
0035 static int kdewin_fix_mode_string(char *fixed_mode, const char *mode)
0036 {
0037     if (strlen(mode) < 1 || strlen(mode) > 3) {
0038         errno = EINVAL;
0039         return 1;
0040     }
0041 
0042     strncpy(fixed_mode, mode, 3);
0043     if (fixed_mode[0] == 'b' || fixed_mode[1] == 'b' || fixed_mode[0] == 't' || fixed_mode[1] == 't') {
0044         return 0;
0045     }
0046     /* no 't' or 'b': append 'b' */
0047     if (fixed_mode[1] == '+') {
0048         fixed_mode[1] = 'b';
0049         fixed_mode[2] = '+';
0050         fixed_mode[3] = 0;
0051     } else {
0052         fixed_mode[1] = 'b';
0053         fixed_mode[2] = 0;
0054     }
0055     return 0;
0056 }
0057 
0058 /** @internal */
0059 static int kdewin_fix_flags(int flags)
0060 {
0061     if ((flags & O_TEXT) == 0 && (flags & O_BINARY) == 0) {
0062         return flags | O_BINARY;
0063     }
0064     return flags;
0065 }
0066 
0067 namespace KDE
0068 {
0069 int access(const QString &path, int mode)
0070 {
0071     int x_mode = 0;
0072     // X_OK gives an assert on msvc2005 and up - use stat() instead
0073     if ((mode & X_OK) == X_OK) {
0074         KDE_struct_stat st;
0075         if (KDE::stat(path, &st) != 0) {
0076             return 1;
0077         }
0078         if ((st.st_mode & S_IXUSR) != S_IXUSR) {
0079             return 1;
0080         }
0081     }
0082     mode &= ~X_OK;
0083     return _waccess(CONV(path), mode);
0084 }
0085 
0086 int chmod(const QString &path, mode_t mode)
0087 {
0088     return _wchmod(CONV(path), mode);
0089 }
0090 
0091 FILE *fopen(const QString &pathname, const char *mode)
0092 {
0093     return _wfopen(CONV(pathname), CONV(QString::fromLatin1(mode)));
0094 }
0095 
0096 int lstat(const QString &path, KDE_struct_stat *buf)
0097 {
0098     return KDE::stat(path, buf);
0099 }
0100 
0101 int mkdir(const QString &pathname, mode_t)
0102 {
0103     return _wmkdir(CONV(pathname));
0104 }
0105 
0106 int open(const QString &pathname, int flags, mode_t mode)
0107 {
0108     return _wopen(CONV(pathname), kdewin_fix_flags(flags), mode);
0109 }
0110 
0111 int rename(const QString &in, const QString &out)
0112 {
0113     // better than :waccess/_wunlink/_wrename
0114 #ifndef _WIN32_WCE
0115     bool ok = (MoveFileExW(CONV(in), CONV(out),
0116                            MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED) != 0);
0117 #else
0118     bool ok = (MoveFileW(CONV(in), CONV(out)) != 0);
0119 #endif
0120     return ok ? 0 : -1;
0121 }
0122 
0123 int stat(const QString &path, KDE_struct_stat *buf)
0124 {
0125     int result;
0126 #ifdef Q_CC_MSVC
0127 #ifndef _WIN32_WCE
0128     struct _stat64 s64;
0129 #else
0130     struct stat st;
0131 #endif
0132 #else
0133     struct __stat64 s64;
0134 #endif
0135     const int len = path.length();
0136     if ((len == 2 || len == 3) && path[1] == QLatin1Char(':') && path[0].isLetter()) {
0137         /* 1) */
0138         QString newPath(path);
0139         if (len == 2) {
0140             newPath += QLatin1Char('\\');
0141         }
0142 #ifndef _WIN32_WCE
0143         result = _wstat64(CONV(newPath), &s64);
0144 #else
0145         result = wstat(CONV(newPath), &st);
0146 #endif
0147     } else if (len > 1 && (path.endsWith(QLatin1Char('\\')) || path.endsWith(QLatin1Char('/')))) {
0148         /* 2) */
0149         const QString newPath = path.left(len - 1);
0150 #ifndef _WIN32_WCE
0151         result = _wstat64(CONV(newPath), &s64);
0152 #else
0153         result = wstat(CONV(newPath), &st);
0154 #endif
0155     } else {
0156         //TODO: is stat("/") ok?
0157 #ifndef _WIN32_WCE
0158         result = _wstat64(CONV(path), &s64);
0159 #else
0160         result = wstat(CONV(path), &st);
0161 #endif
0162     }
0163     if (result != 0) {
0164         return result;
0165     }
0166     // KDE5: fixme!
0167 #ifndef _WIN32_WCE
0168     buf->st_dev   = s64.st_dev;
0169     buf->st_ino   = s64.st_ino;
0170     buf->st_mode  = s64.st_mode;
0171     buf->st_nlink = s64.st_nlink;
0172 #else
0173     buf->st_dev   = st.st_dev;
0174     buf->st_ino   = st.st_ino;
0175     buf->st_mode  = st.st_mode;
0176     buf->st_nlink = st.st_nlink;
0177 #endif
0178     buf->st_uid   = -2; // be in sync with Qt4
0179     buf->st_gid   = -2; // be in sync with Qt4
0180 #ifndef _WIN32_WCE
0181     buf->st_rdev  = s64.st_rdev;
0182     buf->st_size  = s64.st_size;
0183     buf->st_atime = s64.st_atime;
0184     buf->st_mtime = s64.st_mtime;
0185     buf->st_ctime = s64.st_ctime;
0186 #else
0187     buf->st_rdev  = st.st_rdev;
0188     buf->st_size  = st.st_size;
0189     buf->st_atime = st.st_atime;
0190     buf->st_mtime = st.st_mtime;
0191     buf->st_ctime = st.st_ctime;
0192 #endif
0193     return result;
0194 }
0195 int utime(const QString &filename, struct utimbuf *buf)
0196 {
0197 #ifndef _WIN32_WCE
0198     return _wutime(CONV(filename), (struct _utimbuf *)buf);
0199 #else
0200     return _wutime(CONV(filename), (struct utimbuf *)buf);
0201 #endif
0202 }
0203 };