mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-09-26 11:29:04 +02:00
SFTP bug fixes (#53)
https://github.com/PowerShell/Win32-OpenSSH/issues/479 https://github.com/PowerShell/Win32-OpenSSH/issues/476 https://github.com/PowerShell/Win32-OpenSSH/issues/474 https://github.com/PowerShell/Win32-OpenSSH/issues/467 bug #479 - "ls c:" is not working sanitized_path() is modified to handle the edge case "\x:" 2.bug #476 - "cd c:" is not working If "c:" is passed to _fullpath() then it is returning existing path but not "c:", so if we append "\" to "c:" then it is working fine. 3.bug #474 - code cleanup MAX_PATH Using PATH_MAX variable instead of MAX_PATH In dirent.h, used PATH_MAX instead of hardcoding 256 characters In readdir(), changed the pdirentry to be a static variable. Before this, we are leaking the memory. 4.bug #467 - SFTP rename failed if the newpath already exists. The _wrename throws error if the newpath exists. To make it consistent with the linux behavrior, a) if the newpath is a file and if it exists then delete it so that _wrename will succeed. b) if the newpath is a directory and if it is empty then delete it so that _wrename will succeed.
This commit is contained in:
parent
e95aef2cf3
commit
039f2eca7a
@ -37,6 +37,7 @@
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include "inc\utf.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
/* internal read buffer size */
|
||||
#define READ_BUFFER_SIZE 100*1024
|
||||
@ -76,7 +77,7 @@ int
|
||||
fileio_pipe(struct w32_io* pio[2]) {
|
||||
HANDLE read_handle = INVALID_HANDLE_VALUE, write_handle = INVALID_HANDLE_VALUE;
|
||||
struct w32_io *pio_read = NULL, *pio_write = NULL;
|
||||
char pipe_name[MAX_PATH];
|
||||
char pipe_name[PATH_MAX];
|
||||
SECURITY_ATTRIBUTES sec_attributes;
|
||||
|
||||
if (pio == NULL) {
|
||||
@ -86,7 +87,7 @@ fileio_pipe(struct w32_io* pio[2]) {
|
||||
}
|
||||
|
||||
/* create name for named pipe */
|
||||
if (-1 == sprintf_s(pipe_name, MAX_PATH, "\\\\.\\Pipe\\W32PosixPipe.%08x.%08x",
|
||||
if (-1 == sprintf_s(pipe_name, PATH_MAX, "\\\\.\\Pipe\\W32PosixPipe.%08x.%08x",
|
||||
GetCurrentProcessId(), pipe_counter++)) {
|
||||
errno = EOTHER;
|
||||
debug("pipe - ERROR sprintf_s %d", errno);
|
||||
@ -564,15 +565,15 @@ fileio_fstat(struct w32_io* pio, struct _stat64 *buf) {
|
||||
|
||||
int
|
||||
fileio_stat(const char *path, struct _stat64 *buf) {
|
||||
wchar_t wpath[MAX_PATH];
|
||||
wchar_t* wtmp = NULL;
|
||||
wchar_t wpath[PATH_MAX];
|
||||
wchar_t* wtmp = NULL;
|
||||
|
||||
if ((wtmp = utf8_to_utf16(path)) == NULL)
|
||||
fatal("failed to covert input arguments");
|
||||
wcscpy(&wpath[0], wtmp);
|
||||
free(wtmp);
|
||||
if ((wtmp = utf8_to_utf16(path)) == NULL)
|
||||
fatal("failed to covert input arguments");
|
||||
wcscpy(&wpath[0], wtmp);
|
||||
free(wtmp);
|
||||
|
||||
return _wstat64(wpath, buf);
|
||||
return _wstat64(wpath, buf);
|
||||
}
|
||||
|
||||
long
|
||||
|
@ -10,10 +10,11 @@
|
||||
#include <direct.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include "..\misc_internal.h"
|
||||
|
||||
struct dirent {
|
||||
int d_ino; /* Inode number */
|
||||
char d_name[256]; /* Null-terminated filename */
|
||||
char d_name[PATH_MAX]; /* Null-terminated filename */
|
||||
};
|
||||
|
||||
typedef struct DIR_ DIR;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <NTSecPkg.h>
|
||||
#include <ntstatus.h>
|
||||
#include <stdio.h>
|
||||
#include "..\misc_internal.h"
|
||||
|
||||
#define Unsigned unsigned
|
||||
#define Char char
|
||||
@ -264,7 +265,7 @@ LsaApLogonUser(PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logonType,
|
||||
UNICODE_STRING *flatName = NULL;
|
||||
UCHAR *userAuth = NULL;
|
||||
ULONG userAuthSize;
|
||||
wchar_t homeDir[MAX_PATH];
|
||||
wchar_t homeDir[PATH_MAX];
|
||||
TOKEN_SOURCE tokenSource;
|
||||
|
||||
HANDLE token = NULL;
|
||||
@ -292,9 +293,9 @@ LsaApLogonUser(PLSA_CLIENT_REQUEST request, SECURITY_LOGON_TYPE logonType,
|
||||
*authority, &token, logonId,
|
||||
*accountName, subStat));
|
||||
|
||||
NTFAIL(LsaApi.AllocateClientBuffer(request, MAX_PATH * sizeof(wchar_t), profile));
|
||||
*profileSize = MAX_PATH;
|
||||
NTFAIL(LsaApi.CopyToClientBuffer(request, MAX_PATH * sizeof(wchar_t),
|
||||
NTFAIL(LsaApi.AllocateClientBuffer(request, PATH_MAX * sizeof(wchar_t), profile));
|
||||
*profileSize = PATH_MAX;
|
||||
NTFAIL(LsaApi.CopyToClientBuffer(request, PATH_MAX * sizeof(wchar_t),
|
||||
*profile, homeDir));
|
||||
|
||||
PLSA_TOKEN_INFORMATION_V1 outTokenInfo;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <Shlwapi.h>
|
||||
#include "misc_internal.h"
|
||||
#include "inc\dlfcn.h"
|
||||
#include "inc\dirent.h"
|
||||
|
||||
int usleep(unsigned int useconds)
|
||||
{
|
||||
@ -134,7 +135,7 @@ FARPROC dlsym(HMODULE handle, const char *symbol) {
|
||||
*/
|
||||
FILE*
|
||||
w32_fopen_utf8(const char *path, const char *mode) {
|
||||
wchar_t wpath[MAX_PATH], wmode[5];
|
||||
wchar_t wpath[PATH_MAX], wmode[5];
|
||||
FILE* f;
|
||||
char utf8_bom[] = { 0xEF,0xBB,0xBF };
|
||||
char first3_bytes[3];
|
||||
@ -144,7 +145,7 @@ w32_fopen_utf8(const char *path, const char *mode) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, MAX_PATH) == 0 ||
|
||||
if (MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, PATH_MAX) == 0 ||
|
||||
MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, 5) == 0) {
|
||||
errno = EFAULT;
|
||||
debug("WideCharToMultiByte failed for %c - ERROR:%d", path, GetLastError());
|
||||
@ -478,8 +479,7 @@ settimes(wchar_t * path, FILETIME *cretime, FILETIME *acttime, FILETIME *modtime
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (SetFileTime(handle, cretime, acttime, modtime) == 0)
|
||||
{
|
||||
if (SetFileTime(handle, cretime, acttime, modtime) == 0) {
|
||||
errno = GetLastError();
|
||||
debug("w32_settimes - SetFileTime ERROR:%d", errno);
|
||||
CloseHandle(handle);
|
||||
@ -533,6 +533,28 @@ w32_rename(const char *old_name, const char *new_name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* To be consistent with linux rename(),
|
||||
* 1) if the new_name is file, then delete it so that _wrename will succeed.
|
||||
* 2) if the new_name is directory and it is empty then delete it so that _wrename will succeed.
|
||||
*/
|
||||
struct _stat64 st;
|
||||
if (fileio_stat(sanitized_path(new_name), &st) != -1) {
|
||||
if(((st.st_mode & _S_IFMT) == _S_IFREG)) {
|
||||
w32_unlink(new_name);
|
||||
} else {
|
||||
DIR *dirp = opendir(new_name);
|
||||
if (NULL != dirp) {
|
||||
struct dirent *dp = readdir(dirp);
|
||||
closedir(dirp);
|
||||
|
||||
if (dp == NULL) {
|
||||
w32_rmdir(new_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int returnStatus = _wrename(resolvedOldPathName_utf16, resolvedNewPathName_utf16);
|
||||
free(resolvedOldPathName_utf16);
|
||||
free(resolvedNewPathName_utf16);
|
||||
@ -585,10 +607,10 @@ w32_chdir(const char *dirname_utf8) {
|
||||
|
||||
char *
|
||||
w32_getcwd(char *buffer, int maxlen) {
|
||||
wchar_t wdirname[MAX_PATH];
|
||||
wchar_t wdirname[PATH_MAX];
|
||||
char* putf8 = NULL;
|
||||
|
||||
_wgetcwd(&wdirname[0], MAX_PATH);
|
||||
_wgetcwd(&wdirname[0], PATH_MAX);
|
||||
|
||||
if ((putf8 = utf16_to_utf8(&wdirname[0])) == NULL)
|
||||
fatal("failed to convert input arguments");
|
||||
@ -655,19 +677,25 @@ convertToForwardslash(char *str) {
|
||||
}
|
||||
|
||||
/*
|
||||
* This method will resolves references to /./, /../ and extra '/' characters in the null-terminated string named by
|
||||
* path to produce a canonicalized absolute pathname.
|
||||
*/
|
||||
* This method will resolves references to /./, /../ and extra '/' characters in the null-terminated string named by
|
||||
* path to produce a canonicalized absolute pathname.
|
||||
*/
|
||||
char *
|
||||
realpath(const char *path, char resolved[MAX_PATH]) {
|
||||
char tempPath[MAX_PATH];
|
||||
realpath(const char *path, char resolved[PATH_MAX]) {
|
||||
char tempPath[PATH_MAX];
|
||||
|
||||
if ( (strlen(path) >= 2) && (path[0] == '/') && (path[2] == ':') )
|
||||
if ((path[0] == '/') && path[1] && (path[2] == ':')) {
|
||||
strncpy(resolved, path + 1, strlen(path)); // skip the first '/'
|
||||
else
|
||||
} else {
|
||||
strncpy(resolved, path, strlen(path) + 1);
|
||||
}
|
||||
|
||||
if (_fullpath(tempPath, resolved, MAX_PATH) == NULL)
|
||||
if ((resolved[0]) && (resolved[1] == ':') && (resolved[2] == '\0')) { // make "x:" as "x:\\"
|
||||
resolved[2] = '\\';
|
||||
resolved[3] = '\0';
|
||||
}
|
||||
|
||||
if (_fullpath(tempPath, resolved, PATH_MAX) == NULL)
|
||||
return NULL;
|
||||
|
||||
convertToForwardslash(tempPath);
|
||||
@ -677,6 +705,27 @@ realpath(const char *path, char resolved[MAX_PATH]) {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
char*
|
||||
sanitized_path(const char *path) {
|
||||
static char newPath[PATH_MAX] = { '\0', };
|
||||
|
||||
if (path[0] == '/' && path[1]) {
|
||||
if (path[2] == ':') {
|
||||
if (path[3] == '\0') { // make "/x:" as "x:\\"
|
||||
strncpy(newPath, path + 1, strlen(path) - 1);
|
||||
newPath[2] = '\\';
|
||||
newPath[3] = '\0';
|
||||
|
||||
return newPath;
|
||||
} else {
|
||||
return (char *)(path + 1); // skip the first "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (char *)path;
|
||||
}
|
||||
|
||||
// Maximum reparse buffer info size. The max user defined reparse
|
||||
// data is 16KB, plus there's a header.
|
||||
#define MAX_REPARSE_SIZE 17000
|
||||
@ -813,7 +862,7 @@ int statvfs(const char *path, struct statvfs *buf) {
|
||||
buf->f_favail = -1;
|
||||
buf->f_fsid = 0;
|
||||
buf->f_flag = 0;
|
||||
buf->f_namemax = MAX_PATH - 1;
|
||||
buf->f_namemax = PATH_MAX - 1;
|
||||
|
||||
free(path_utf16);
|
||||
return 0;
|
||||
|
@ -1,3 +1,4 @@
|
||||
#define PATH_MAX MAX_PATH
|
||||
|
||||
/* removes first '/' for Windows paths that are unix styled. Ex: /c:/ab.cd */
|
||||
#define sanitized_path(p) (((p)[0] == '/' && (p)[1] != '\0' && (p)[2] == ':')? (p)+1 : (p))
|
||||
char * sanitized_path(const char *);
|
@ -39,6 +39,7 @@
|
||||
#include "inc\pwd.h"
|
||||
#include "inc\grp.h"
|
||||
#include "inc\utf.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
static struct passwd pw;
|
||||
static char* pw_shellpath = NULL;
|
||||
@ -87,9 +88,9 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
|
||||
char *uname_utf8 = NULL, *pw_home_utf8 = NULL;
|
||||
LPBYTE user_info = NULL;
|
||||
LPWSTR user_sid_local = NULL;
|
||||
wchar_t reg_path[MAX_PATH], profile_home[MAX_PATH];
|
||||
wchar_t reg_path[PATH_MAX], profile_home[PATH_MAX];
|
||||
HKEY reg_key = 0;
|
||||
int tmp_len = MAX_PATH;
|
||||
int tmp_len = PATH_MAX;
|
||||
PDOMAIN_CONTROLLER_INFOW pdc = NULL;
|
||||
|
||||
errno = 0;
|
||||
@ -141,10 +142,10 @@ get_passwd(const char *user_utf8, LPWSTR user_sid) {
|
||||
user_sid = user_sid_local;
|
||||
}
|
||||
|
||||
if (swprintf(reg_path, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == MAX_PATH ||
|
||||
if (swprintf(reg_path, PATH_MAX, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\%ls", user_sid) == PATH_MAX ||
|
||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, reg_path, 0, STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_WOW64_64KEY, ®_key) != 0 ||
|
||||
RegQueryValueExW(reg_key, L"ProfileImagePath", 0, NULL, (LPBYTE)profile_home, &tmp_len) != 0)
|
||||
GetWindowsDirectoryW(profile_home, MAX_PATH);
|
||||
GetWindowsDirectoryW(profile_home, PATH_MAX);
|
||||
|
||||
if ((uname_utf8 = _strdup(user_utf8)) == NULL ||
|
||||
(pw_home_utf8 = utf16_to_utf8(profile_home)) == NULL) {
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <Strsafe.h>
|
||||
#include <stdio.h>
|
||||
#include <io.h>
|
||||
#include "misc_internal.h"
|
||||
|
||||
#define MAX_CONSOLE_COLUMNS 9999
|
||||
#define MAX_CONSOLE_ROWS 9999
|
||||
@ -1068,15 +1069,15 @@ int start_with_pty(int ac, wchar_t **av) {
|
||||
/*TODO - pick this up from system32*/
|
||||
cmd[0] = L'\0';
|
||||
if (ac)
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L"cmd.exe"));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L"cmd.exe"));
|
||||
|
||||
ac--;
|
||||
av++;
|
||||
if (ac)
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" /c"));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" /c"));
|
||||
while (ac) {
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, *av));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, *av));
|
||||
ac--;
|
||||
av++;
|
||||
}
|
||||
@ -1182,14 +1183,14 @@ int start_withno_pty(int ac, wchar_t **av) {
|
||||
|
||||
/*TODO - pick this up from system32*/
|
||||
cmd[0] = L'\0';
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L"cmd.exe"));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L"cmd.exe"));
|
||||
ac -= 2;
|
||||
av += 2;
|
||||
if (ac)
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" /c"));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" /c"));
|
||||
while (ac) {
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, MAX_PATH, *av));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, L" "));
|
||||
GOTO_CLEANUP_ON_ERR(wcscat_s(cmd, PATH_MAX, *av));
|
||||
ac--;
|
||||
av++;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "agent.h"
|
||||
#include <sddl.h>
|
||||
#include <UserEnv.h>
|
||||
#include "..\misc_internal.h"
|
||||
#define BUFSIZE 5 * 1024
|
||||
|
||||
static HANDLE ioc_port = NULL;
|
||||
@ -179,15 +180,15 @@ agent_listen_loop() {
|
||||
}
|
||||
else {
|
||||
/* spawn a child to take care of this*/
|
||||
wchar_t path[MAX_PATH], module_path[MAX_PATH];
|
||||
wchar_t path[PATH_MAX], module_path[PATH_MAX];
|
||||
PROCESS_INFORMATION pi;
|
||||
STARTUPINFOW si;
|
||||
|
||||
si.cb = sizeof(STARTUPINFOW);
|
||||
memset(&si, 0, sizeof(STARTUPINFOW));
|
||||
GetModuleFileNameW(NULL, module_path, MAX_PATH);
|
||||
GetModuleFileNameW(NULL, module_path, PATH_MAX);
|
||||
SetHandleInformation(con, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
|
||||
if ((swprintf_s(path, MAX_PATH, L"%s %d", module_path, (int)(intptr_t)con) == -1 ) ||
|
||||
if ((swprintf_s(path, PATH_MAX, L"%s %d", module_path, (int)(intptr_t)con) == -1 ) ||
|
||||
(CreateProcessW(NULL, path, NULL, NULL, TRUE,
|
||||
DETACHED_PROCESS, NULL, NULL,
|
||||
&si, &pi) == FALSE)) {
|
||||
|
@ -87,15 +87,15 @@ int GetCurrentModulePath(wchar_t *path, int pathSize)
|
||||
}
|
||||
|
||||
int load_config() {
|
||||
wchar_t basePath[MAX_PATH] = { 0 };
|
||||
wchar_t path[MAX_PATH] = { 0 };
|
||||
wchar_t basePath[PATH_MAX] = { 0 };
|
||||
wchar_t path[PATH_MAX] = { 0 };
|
||||
|
||||
/* TODO - account for UNICODE paths*/
|
||||
if (GetCurrentModulePath(basePath, MAX_PATH) == -1)
|
||||
if (GetCurrentModulePath(basePath, PATH_MAX) == -1)
|
||||
return -1;
|
||||
|
||||
wcsncpy(path, basePath, MAX_PATH);
|
||||
wcsncat(path, L"/sshd_config", MAX_PATH);
|
||||
wcsncpy(path, basePath, PATH_MAX);
|
||||
wcsncat(path, L"/sshd_config", PATH_MAX);
|
||||
|
||||
if ((config_file_name = utf16_to_utf8(path)) == NULL)
|
||||
return -1;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include "inc\syslog.h"
|
||||
#include "misc_internal.h"
|
||||
|
||||
#define MSGBUFSIZ 1024
|
||||
static int logfd = -1;
|
||||
@ -42,10 +43,11 @@ openlog(char *ident, unsigned int option, int facility) {
|
||||
if (logfd != -1 || ident == NULL)
|
||||
return;
|
||||
|
||||
wchar_t path[MAX_PATH], log_file[MAX_PATH + 12];
|
||||
if (GetModuleFileNameW(NULL, path, MAX_PATH) == 0)
|
||||
wchar_t path[PATH_MAX], log_file[PATH_MAX + 12];
|
||||
if (GetModuleFileNameW(NULL, path, PATH_MAX) == 0)
|
||||
|
||||
return;
|
||||
path[MAX_PATH - 1] = '\0';
|
||||
path[PATH_MAX - 1] = '\0';
|
||||
|
||||
/* split path root and module */
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ DIR * opendir(const char *name)
|
||||
struct _wfinddata_t c_file;
|
||||
intptr_t hFile;
|
||||
DIR *pdir;
|
||||
wchar_t searchstr[MAX_PATH];
|
||||
wchar_t searchstr[PATH_MAX];
|
||||
wchar_t* wname = NULL;
|
||||
int needed;
|
||||
|
||||
@ -37,7 +37,7 @@ DIR * opendir(const char *name)
|
||||
}
|
||||
|
||||
// add *.* for Windows _findfirst() search pattern
|
||||
swprintf_s(searchstr, MAX_PATH, L"%s\\*.*", wname);
|
||||
swprintf_s(searchstr, PATH_MAX, L"%s\\*.*", wname);
|
||||
free(wname);
|
||||
|
||||
if ((hFile = _wfindfirst(searchstr, &c_file)) == -1L)
|
||||
@ -77,7 +77,7 @@ int closedir(DIR *dirp)
|
||||
by a later readdir call on the same DIR stream. */
|
||||
struct dirent *readdir(void *avp)
|
||||
{
|
||||
struct dirent *pdirentry;
|
||||
static struct dirent pdirentry;
|
||||
struct _wfinddata_t c_file;
|
||||
DIR *dirp = (DIR *)avp;
|
||||
char *tmp = NULL;
|
||||
@ -93,18 +93,17 @@ struct dirent *readdir(void *avp)
|
||||
if (wcscmp(c_file.name, L".") == 0 || wcscmp(c_file.name, L"..") == 0 )
|
||||
continue;
|
||||
|
||||
if ((pdirentry = malloc(sizeof(struct dirent))) == NULL ||
|
||||
(tmp = utf16_to_utf8(c_file.name)) == NULL) {
|
||||
if ((tmp = utf16_to_utf8(c_file.name)) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
strncpy(pdirentry->d_name, tmp, strlen(tmp) + 1);
|
||||
strncpy(pdirentry.d_name, tmp, strlen(tmp) + 1);
|
||||
free(tmp);
|
||||
|
||||
pdirentry->d_ino = 1; // a fictious one like UNIX to say it is nonzero
|
||||
return pdirentry ;
|
||||
}
|
||||
pdirentry.d_ino = 1; // a fictious one like UNIX to say it is nonzero
|
||||
return &pdirentry ;
|
||||
}
|
||||
}
|
||||
|
||||
// return last part of a path. The last path being a filename.
|
||||
@ -123,4 +122,3 @@ char *basename(char *path)
|
||||
|
||||
return path; // path does not have a slash
|
||||
}
|
||||
// end of dirent functions in Windows
|
||||
|
Loading…
x
Reference in New Issue
Block a user