rename from different drives and list drives

pull/83/head
Jacob Barthelmeh 2018-07-31 14:39:46 -06:00
parent 8a010c168e
commit 5cbfa5e43f
3 changed files with 127 additions and 10 deletions

View File

@ -7093,6 +7093,7 @@ void clean_path(char* path)
#ifdef WOLFSSL_NUCLEUS
sz = WSTRLEN(path);
if (path[sz - 1] == ':') {
path[sz] = WS_DELIM;
path[sz + 1] = '\0';
@ -7115,6 +7116,14 @@ void clean_path(char* path)
}
}
}
/* remove leading '/' for nucleus. Preserve case of single "/" */
sz = WSTRLEN(path);
while (sz > 2 && path[0] == WS_DELIM) {
sz--;
WMEMMOVE(path, path + 1, sz);
path[sz] = '\0';
}
#endif
/* remove trailing delimiter */
if (sz > 3 && path[sz - 1] == WS_DELIM) {

View File

@ -945,11 +945,39 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
char* dirName)
{
int sz;
byte special = 0;
int ret = WS_SUCCESS;
if (dir == NULL || ssh == NULL || out == NULL) {
return WS_BAD_ARGUMENT;
}
/* special case of getting drives at "/" */
if (WSTRLEN(dirName) < 3 && dirName[0] == WS_DELIM) {
unsigned int idx = dir->fsize; /* index of current drive */
MNT_LIST_S* list = NU_NULL;
if (NU_List_Mount(&list) != NU_SUCCESS) {
return WS_FATAL_ERROR;
}
for (; idx > 0 && list != NU_NULL; idx--) list = list->next;
if (list == NULL) {
return WS_FATAL_ERROR;
}
if (list->next == NULL) {
ret = WS_NEXT_ERROR;
}
dir->lfname[0] = list->mnt_name[0];
dir->lfname[1] = ':';
dir->lfname[2] = '/';
dir->lfname[3] = '\0';
dir->fsize++;
special = 1;
}
/* use long name on Nucleus because sfname has only the file name and in all
* caps */
sz = (int)WSTRLEN(dir->lfname);
@ -981,13 +1009,16 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
return WS_MEMORY_E;
}
buf[0] = '\0';
WSTRNCAT(buf, dirName, bufSz);
tmpSz = WSTRLEN(buf);
if (!special) { /* do not add dir name in special case */
WSTRNCAT(buf, dirName, bufSz);
tmpSz = WSTRLEN(buf);
/* add delimiter between path and file/dir name */
if (tmpSz + 1 < bufSz) {
buf[tmpSz] = WS_DELIM;
buf[tmpSz+1] = '\0';
}
/* add delimiter between path and file/dir name */
if (tmpSz + 1 < bufSz) {
buf[tmpSz] = WS_DELIM;
buf[tmpSz+1] = '\0';
}
WSTRNCAT(buf, out->fName, bufSz);
@ -998,11 +1029,11 @@ static int wolfSSH_SFTPNAME_readdir(WOLFSSH* ssh, WDIR* dir, WS_SFTPNAME* out,
WFREE(buf, out->heap, DYNTYPE_SFTP);
}
if ((WREADDIR(dir)) == NULL) {
return WS_NEXT_ERROR;
if (!special && (WREADDIR(dir)) == NULL) {
ret = WS_NEXT_ERROR;
}
return WS_SUCCESS;
return ret;
}
#else
/* helper function that gets file information from reading directory
@ -1836,6 +1867,13 @@ int SFTP_GetAttributes(const char* fileName, WS_SFTP_FILEATRB* atr, byte link)
return WS_SUCCESS;
}
/* handle case of "/" */
if (sz < 3 && fileName[0] == WS_DELIM && ret == NUF_NOFILE) {
atr->flags |= WOLFSSH_FILEATRB_PERM;
atr->per |= 0x4000;
return WS_SUCCESS;
}
if (ret != NU_SUCCESS) {
return WS_BAD_FILE_E;
}

View File

@ -206,7 +206,71 @@ extern "C" {
#define WSTAT(p,b) NU_Get_First((b),(p))
#define WLSTAT(p,b) NU_Get_First((b),(p))
#define WREMOVE(d) NU_Delete((d))
#define WRENAME(o,n) NU_Rename((o),(n))
#ifndef WS_MAX_RENAME_BUF
#define WS_MAX_RENAME_BUF 256
#endif
static inline int wRename(char* o, char* n)
{
int ret;
if (o == NULL || n == NULL) {
return NUF_BADPARM;
}
ret = NU_Rename(o, n);
/* try to handle case of from one drive to another */
if (ret == NUF_BADPARM && o[0] != n[0]) {
WFILE* fOld;
WFILE* fNew;
unsigned char buf[WS_MAX_RENAME_BUF];
if ((ret = WFOPEN(&fOld, o, "rb")) != 0) {
return ret;
}
if ((ret = WFOPEN(&fNew, n, "rwb")) != 0) {
WFCLOSE(fOld);
return ret;
}
/* read from the file in chunks and write chunks to new file */
do {
ret = WFREAD(buf, 1, WS_MAX_RENAME_BUF, fOld);
if (ret > 0) {
if ((WFWRITE(buf, 1, ret, fNew)) != ret) {
WFCLOSE(fOld);
WFCLOSE(fNew);
WREMOVE(n);
return NUF_BADPARM;
}
}
} while (ret > 0);
if (WFTELL(fOld) == WFSEEK(fOld, 0, WSEEK_END)) {
/* wrote everything from file */
WFCLOSE(fOld);
WREMOVE(o);
WFCLOSE(fNew);
}
else {
/* unable to write everything to file */
WFCLOSE(fNew);
WREMOVE(n);
WFCLOSE(fOld);
return NUF_BADPARM;
}
return 0;
}
/* not special case so just return value from NU_Rename */
return ret;
}
#define WRENAME(o,n) wRename((o),(n))
#define WFD int
#ifndef WGETCWD
@ -287,6 +351,12 @@ extern "C" {
int idx = WSTRLEN(dir);
char tmp[256]; /* default max file name size */
/* handle special case at "/" to list all drives */
if (idx < 3 && dir[0] == WS_DELIM) {
d->fsize = 0; /* used to count number of drives */
return NU_SUCCESS;
}
if (idx < 3) {
return -1;
}