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:
quamrulmina 2015-12-29 22:05:37 -06:00
parent 4857c272b9
commit 46327a98b1
3 changed files with 151 additions and 3 deletions

View File

@ -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

View File

@ -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);

View File

@ -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 ;
}