mirror of
https://github.com/PowerShell/Win32-OpenSSH.git
synced 2025-07-23 22:15:37 +02:00
fix sftp-server not showing first entry in listing; code ls -l to show file attributes correctly
changing driver letter in sftp-server tested using usb drives; missing first entry on a top root directory is now shown correctly. ls -l output cleaned up and now correctly show file and directory attributes. strmode() function implemented for Windows like it is available in Unix/Linux OS.
This commit is contained in:
parent
4857c272b9
commit
46327a98b1
123
sftp-common.c
123
sftp-common.c
@ -33,6 +33,9 @@
|
||||
#ifdef WIN32_FIXME
|
||||
#undef GSSAPI
|
||||
#undef KRB5
|
||||
|
||||
void strmode(mode_t mode, char *p);
|
||||
void strmode_from_attrib(unsigned attrib, char *p);
|
||||
#endif
|
||||
|
||||
#include <sys/param.h> /* MAX */
|
||||
@ -231,6 +234,9 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
|
||||
|
||||
#ifndef WIN32_FIXME
|
||||
strmode(st->st_mode, mode);
|
||||
#else
|
||||
strmode(st->st_mode, mode);
|
||||
strmode_from_attrib(remote, mode);
|
||||
#endif
|
||||
if (!remote) {
|
||||
user = user_from_uid(st->st_uid, 0);
|
||||
@ -281,3 +287,120 @@ ls_file(const char *name, const struct stat *st, int remote, int si_units)
|
||||
}
|
||||
return xstrdup(buf);
|
||||
}
|
||||
|
||||
#ifdef WIN32_FIXME
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <windows.h>
|
||||
|
||||
void
|
||||
strmode_from_attrib(unsigned attrib, char *p)
|
||||
{
|
||||
if (attrib & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
*p = 'l';
|
||||
else if (attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||
*p = 'd';
|
||||
else
|
||||
*p = '-';
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
strmode(mode_t mode, char *p)
|
||||
{
|
||||
/* print type */
|
||||
switch (mode & S_IFMT) {
|
||||
case S_IFDIR: /* directory */
|
||||
*p++ = 'd';
|
||||
break;
|
||||
case S_IFCHR: /* character special */
|
||||
*p++ = 'c';
|
||||
break;
|
||||
//case S_IFBLK: /* block special */
|
||||
// *p++ = 'b';
|
||||
// break;
|
||||
case S_IFREG: /* regular */
|
||||
*p++ = '-';
|
||||
break;
|
||||
//case S_IFLNK: /* symbolic link */
|
||||
// *p++ = 'l';
|
||||
// break;
|
||||
#ifdef S_IFSOCK
|
||||
case S_IFSOCK: /* socket */
|
||||
*p++ = 's';
|
||||
break;
|
||||
#endif
|
||||
case _S_IFIFO: /* fifo */
|
||||
*p++ = 'p';
|
||||
break;
|
||||
default: /* unknown */
|
||||
*p++ = '?';
|
||||
break;
|
||||
}
|
||||
/* usr */
|
||||
if (mode & S_IRUSR)
|
||||
*p++ = 'r';
|
||||
else
|
||||
*p++ = '-';
|
||||
if (mode & S_IWUSR)
|
||||
*p++ = 'w';
|
||||
else
|
||||
*p++ = '-';
|
||||
switch (mode & (S_IXUSR)) {
|
||||
case 0:
|
||||
*p++ = '-';
|
||||
break;
|
||||
case S_IXUSR:
|
||||
*p++ = 'x';
|
||||
break;
|
||||
//case S_ISUID:
|
||||
// *p++ = 'S';
|
||||
// break;
|
||||
//case S_IXUSR | S_ISUID:
|
||||
// *p++ = 's';
|
||||
// break;
|
||||
}
|
||||
/* group */
|
||||
if (mode & S_IRGRP)
|
||||
*p++ = 'r';
|
||||
else
|
||||
*p++ = '-';
|
||||
if (mode & S_IWGRP)
|
||||
*p++ = 'w';
|
||||
else
|
||||
*p++ = '-';
|
||||
switch (mode & (S_IXGRP)) {
|
||||
case 0:
|
||||
*p++ = '-';
|
||||
break;
|
||||
case S_IXGRP:
|
||||
*p++ = 'x';
|
||||
break;
|
||||
//case S_ISGID:
|
||||
// *p++ = 'S';
|
||||
// break;
|
||||
//case S_IXGRP | S_ISGID:
|
||||
// *p++ = 's';
|
||||
// break;
|
||||
}
|
||||
/* other */
|
||||
if (mode & S_IROTH)
|
||||
*p++ = 'r';
|
||||
else
|
||||
*p++ = '-';
|
||||
if (mode & S_IWOTH)
|
||||
*p++ = 'w';
|
||||
else
|
||||
*p++ = '-';
|
||||
switch (mode & (S_IXOTH)) {
|
||||
case 0:
|
||||
*p++ = '-';
|
||||
break;
|
||||
case S_IXOTH:
|
||||
*p++ = 'x';
|
||||
break;
|
||||
}
|
||||
*p++ = ' '; /* will be a '+' if ACL's implemented */
|
||||
*p = '\0';
|
||||
}
|
||||
#endif
|
||||
|
@ -1193,6 +1193,29 @@ process_readdir(u_int32_t id)
|
||||
int nstats = 10, count = 0, i;
|
||||
|
||||
stats = xcalloc(nstats, sizeof(Stat));
|
||||
#ifdef WIN32_FIXME
|
||||
// process the first entry that opendir() has found already
|
||||
if (_stricmp(dirp->c_file.name, ".") && !_stricmp(dirp->c_file.name, dirp->initName)) // a firstfile that's not ".", this can happen for shared root drives
|
||||
{ // put first dirp in list
|
||||
if (!strcmp(path, "/")) {
|
||||
snprintf(pathname, sizeof pathname,
|
||||
"/%s", dirp->c_file.name);
|
||||
}
|
||||
else {
|
||||
snprintf(pathname, sizeof pathname,
|
||||
"%s/%s", path, dirp->c_file.name);
|
||||
}
|
||||
if (pathname) {
|
||||
if (lstat(pathname, &st) >= 0) {
|
||||
stat_to_attrib(&st, &(stats[count].attrib));
|
||||
stats[count].name = xstrdup(dirp->c_file.name);
|
||||
stats[count].long_name = ls_file(dirp->c_file.name, &st,0, 0);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if (count >= nstats) {
|
||||
nstats *= 2;
|
||||
@ -1214,7 +1237,7 @@ process_readdir(u_int32_t id)
|
||||
#else
|
||||
stats[count].name = ConvertLocal8ToUtf8(dp -> d_name, -1, NULL);
|
||||
#endif
|
||||
stats[count].long_name = ls_file(dp -> d_name, &st, 0, 0);
|
||||
stats[count].long_name = ls_file(dp -> d_name, &st, dirp->c_file.attrib, 0);
|
||||
|
||||
/*
|
||||
debug3("putting name [%s]...\n", stats[count].name);
|
||||
|
@ -19,9 +19,10 @@ DIR * opendir(char *name)
|
||||
DIR *pdir;
|
||||
char searchstr[256];
|
||||
|
||||
sprintf_s(searchstr, sizeof(searchstr), "%s\\*.*",name); // add *.* to it for NT
|
||||
// add *.* for Windows _findfirst() search pattern
|
||||
sprintf_s(searchstr, sizeof(searchstr), "%s\\*.*",name);
|
||||
|
||||
if( (hFile = _findfirst( searchstr, &c_file )) == -1L ) {
|
||||
if ((hFile = _findfirst(searchstr, &c_file)) == -1L) {
|
||||
if (1) // verbose
|
||||
printf( "No files found for %s search.\n", name );
|
||||
return (DIR *) NULL;
|
||||
@ -30,6 +31,7 @@ DIR * opendir(char *name)
|
||||
pdir = (DIR *) malloc( sizeof(DIR) );
|
||||
pdir->hFile = hFile ;
|
||||
pdir->c_file = c_file ;
|
||||
strcpy_s(pdir->initName,sizeof(pdir->initName), c_file.name);
|
||||
|
||||
return pdir ;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user