wolfssh/wolfssh/port.h

364 lines
11 KiB
C

/* port.h
*
* Copyright (C) 2014-2016 wolfSSL Inc.
*
* This file is part of wolfSSH.
*
* wolfSSH is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* wolfSSH is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with wolfSSH. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* The port module wraps standard C library functions with macros to
* cover portablility issues when building in environments that rename
* those functions. This module also provides local versions of some
* standard C library functions that are missing on some platforms.
*/
#pragma once
#include <wolfssh/settings.h>
#ifdef __cplusplus
extern "C" {
#endif
/* setup memory handling */
#ifndef WMALLOC_USER
#include <wolfssh/memory.h>
#define WMALLOC(s, h, t) ((void)h, (void)t, wolfSSH_Malloc((s)))
#define WFREE(p, h, t) {void* xp = (p); if ((xp)) wolfSSH_Free((xp));}
#define WREALLOC(p, n, h, t) wolfSSH_Realloc((p), (n))
#endif /* WMALLOC_USER */
#ifndef WFGETS
#define WFGETS fgets
#endif
#ifndef WFPUTS
#define WFPUTS fputs
#endif
#ifndef NO_FILESYSTEM
#ifdef WOLFSSL_NUCLEUS
#define WFILE int
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
#define WFOPEN(f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(f) NU_Close(*(f))
#define WFWRITE(b,x,s,f) NU_Write(*(f),(const CHAR*)(b),(s))
#define WFREAD(b,x,s,f) NU_Read(*(f),(CHAR*)(b),(s))
#else
#define WFILE FILE
WOLFSSH_API int wfopen(WFILE**, const char*, const char*);
#define WFOPEN(f,fn,m) wfopen((f),(fn),(m))
#define WFCLOSE(f) fclose(f)
#define WFREAD(b,s,a,f) fread((b),(s),(a),(f))
#define WFWRITE(b,s,a,f) fwrite((b),(s),(a),(f))
#define WFSEEK(s,o,w) fseek((s),(o),(w))
#define WFTELL(s) ftell((s))
#define WREWIND(s) rewind((s))
#define WSEEK_END SEEK_END
#if (defined(WOLFSSH_SCP) || defined(WOLFSSH_SFTP)) && \
!defined(WOLFSSH_SCP_USER_CALLBACKS) && \
!defined(NO_FILESYSTEM)
/* for chdir() */
#include <unistd.h>
/* for mkdir() */
#include <sys/stat.h>
#define WCHDIR(p) chdir((p))
#define WMKDIR(p,m) mkdir((p),(m))
#endif
#endif
#endif
/* setup string handling */
#ifndef WSTRING_USER
#include <string.h>
WOLFSSH_API char* wstrnstr(const char*, const char*, unsigned int);
#define WMEMCPY(d,s,l) memcpy((d),(s),(l))
#define WMEMSET(b,c,l) memset((b),(c),(l))
#define WMEMCMP(s1,s2,n) memcmp((s1),(s2),(n))
#define WMEMMOVE(d,s,l) memmove((d),(s),(l))
#define WSTRLEN(s1) strlen((s1))
#define WSTRSTR(s1,s2) strstr((s1),(s2))
#define WSTRNSTR(s1,s2,n) wstrnstr((s1),(s2),(n))
#define WSTRNCMP(s1,s2,n) strncmp((s1),(s2),(n))
#define WSTRNCAT(s1,s2,n) strncat((s1),(s2),(n))
#define WSTRSPN(s1,s2) strspn((s1),(s2))
#define WSTRCSPN(s1,s2) strcspn((s1),(s2))
#ifdef USE_WINDOWS_API
#define WSTRNCPY(s1,s2,n) strncpy_s((s1),(n),(s2),(n))
#define WSTRNCASECMP(s1,s2,n) _strnicmp((s1),(s2),(n))
#define WSNPRINTF(s,n,f,...) _snprintf_s((s),(n),(n),(f),##__VA_ARGS__)
#define WVSNPRINTF(s,n,f,...) vsnprintf_s((s),(n),(n),(f),##__VA_ARGS__)
#elif defined(MICROCHIP_MPLAB_HARMONY) || defined(MICROCHIP_PIC32)
#include <stdio.h>
#define WSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n))
#define WSTRNCASECMP(s1, s2, n) strncmp((s1), (s2), (n))
#define WSNPRINTF(s,n,f,...) snprintf((s),(n),(f),##__VA_ARGS__)
#define WVSNPRINTF(s,n,f,...) vsnprintf((s),(n),(f),##__VA_ARGS__)
#else
#include <stdio.h>
#define WSTRNCPY(s1,s2,n) strncpy((s1),(s2),(n))
#define WSTRNCASECMP(s1,s2,n) strncasecmp((s1),(s2),(n))
#define WSNPRINTF(s,n,f,...) snprintf((s),(n),(f),##__VA_ARGS__)
#define WVSNPRINTF(s,n,f,...) vsnprintf((s),(n),(f),##__VA_ARGS__)
#endif
#endif /* WSTRING_USER */
/* get local time for debug print out */
#ifdef USE_WINDOWS_API
#define WTIME time
#define WLOCALTIME(c,r) (localtime_s((r),(c))==0)
#elif defined(MICROCHIP_MPLAB_HARMONY)
#define WTIME XTIME
#define WLOCALTIME(c,r) (localtime((c)) != NULL && \
WMEMCPY((r), localtime((c)), sizeof(struct tm)))
#else
#define WTIME time
#define WLOCALTIME(c,r) (localtime_r((c),(r))!=NULL)
#endif
#if defined(WOLFSSH_SFTP) && !defined(NO_WOLFSSH_SERVER)
#ifdef WOLFSSL_NUCLEUS
#include "storage/nu_storage.h"
#define WRMDIR(d) (NU_Remove_Dir((d)) == NU_SUCCESS)?0:1
#define WMKDIR(d,m) (NU_Make_Dir((d)) == NU_SUCCESS)?0:1
#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))
#define WS_DELIM '\\'
#ifndef WGETCWD
static inline char* wGetCwd(char* buf, unsigned int bufSz)
{
int ret;
MNT_LIST_S* list = NU_NULL;
if (buf == NULL || bufSz < 3) {
return NULL;
}
ret = NU_List_Mount(&list);
if (ret != NU_SUCCESS) {
return NULL;
}
buf[0] = list->mnt_name[0];
buf[1] = ':';
buf[2] = '\0';
return buf;
}
#define WGETCWD(r,rSz) wGetCwd((r),(rSz))
#endif
#define WOLFSSH_O_RDWR PO_RDWR
#define WOLFSSH_O_RDONLY PO_RDONLY
#define WOLFSSH_O_WRONLY PO_WRONLY
#define WOLFSSH_O_APPEND PO_APPEND
#define WOLFSSH_O_CREAT PO_CREAT
#define WOLFSSH_O_TRUNC PO_TRUNC
#define WOLFSSH_O_EXCL PO_EXCL
#define WFD int
#ifndef WOPEN
static inline int wOpen(char* f, short flag, short mode)
{
/* @TODO could use PS_IWRITE only or PS_IREAD only? */
return NU_Open(f, PO_TEXT | flag, (PS_IWRITE | PS_IREAD));
}
#define WOPEN(f,m,p) wOpen((f),(m),(p))
#endif
#define WCLOSE(fd) NU_Close((fd))
#ifndef WPWRITE
static inline int wPwrite(WFD fd, unsigned char* buf, unsigned int sz, long ofst)
{
if (ofst > 0) {
NU_Seek(fd, ofst, 0);
}
return NU_Write(fd, (const CHAR*)buf, sz);
}
#define WPWRITE(fd,b,s,o) wPwrite((fd),(b),(s),(o))
#endif
#ifndef WPREAD
static inline int wPread(WFD fd, unsigned char* buf, unsigned int sz, long ofst)
{
if (ofst > 0) {
NU_Seek(fd, ofst, 0);
}
return NU_Read(fd, (CHAR*)buf, sz);
}
#define WPREAD(fd,b,s,o) wPread((fd),(b),(s),(o))
#endif
#ifndef NO_WOLFSSL_DIR
#define WDIR DSTAT
#ifndef WOPENDIR
static inline int wOpenDir(WDIR* d, char* dir)
{
int ret;
int idx = WSTRLEN(dir);
char tmp[256]; /* default max file name size */
if (idx < 3) {
return -1;
}
memcpy(tmp, dir, idx);
if (tmp[idx - 1] == '.') {
tmp[idx - 1] = '*';
}
else {
/* if opening a directory then make sure pattern '/' '*' is used */
unsigned char atrib = 0;
if (NU_Get_Attributes(&atrib, dir) == NU_SUCCESS) {
if (atrib & ADIRENT) {
if (tmp[idx-1] != WS_DELIM) {
if (idx + 2 > sizeof(tmp)) {
/* not enough space */
return -1;
}
tmp[idx++] = WS_DELIM;
tmp[idx++] = '*';
}
}
}
}
if (tmp[idx - 1] == WS_DELIM) {
if (idx + 1 > sizeof(tmp)) {
/* not enough space */
return -1;
}
tmp[idx++] = '*';
}
tmp[idx] = '\0';
ret = NU_Get_First(d, tmp);
/* if back to root directory i.e. A:/ then handle case
* where file system has nothing in it. */
if (dir[idx - 3] == ':' && ret == NUF_NOFILE) {
memset(d, 0, sizeof(WDIR));
ret = NU_SUCCESS;
}
if (ret == NU_SUCCESS) {
return 0;
}
return -1;
}
#define WOPENDIR(c,d) wOpenDir((c),(d))
#endif
#define WCLOSEDIR(d) NU_Done((d))
#define WREADDIR(d) (NU_Get_Next((d)) == NU_SUCCESS)?(d):NULL
#endif /* NO_WOLFSSL_DIR */
#else
#include <unistd.h> /* used for rmdir */
#include <sys/stat.h> /* used for mkdir, stat, and lstat */
#include <stdio.h> /* used for remove and rename */
#include <dirent.h> /* used for opening directory and reading */
#define WRMDIR(d) rmdir((d))
#define WSTAT(p,b) stat((p),(b))
#define WLSTAT(p,b) lstat((p),(b))
#define WREMOVE(d) remove((d))
#define WRENAME(o,n) rename((o),(n))
#define WGETCWD(r,rSz) getcwd((r),(rSz))
#define WS_DELIM '/'
#include <fcntl.h> /* used for open, close, pwrite, and pread */
#define WFD int
#define WOLFSSH_O_RDWR O_RDWR
#define WOLFSSH_O_RDONLY O_RDONLY
#define WOLFSSH_O_WRONLY O_WRONLY
#define WOLFSSH_O_APPEND O_APPEND
#define WOLFSSH_O_CREAT O_CREAT
#define WOLFSSH_O_TRUNC O_TRUNC
#define WOLFSSH_O_EXCL O_EXCL
#define WOPEN(f,m,p) open((f),(m),(p))
#define WCLOSE(fd) close((fd))
#define WPWRITE(fd,b,s,o) pwrite((fd),(b),(s),(o))
#define WPREAD(fd,b,s,o) pread((fd),(b),(s),(o))
#ifndef NO_WOLFSSL_DIR
#include <dirent.h> /* used for opendir, readdir, and closedir */
#define WDIR DIR*
/* returns 0 on success */
#define WOPENDIR(c,d) ((*(c) = opendir((d))) == NULL)
#define WCLOSEDIR(d) closedir((d))
#define WREADDIR(d) readdir((d))
#endif /* NO_WOLFSSL_DIR */
#endif
#endif /* WOLFSSH_SFTP */
/* setup compiler inlining */
#ifndef INLINE
#ifndef NO_INLINE
#ifdef _MSC_VER
#define INLINE __inline
#elif defined(__GNUC__)
#define INLINE inline
#elif defined(__IAR_SYSTEMS_ICC__)
#define INLINE inline
#elif defined(THREADX)
#define INLINE _Inline
#else
#define INLINE
#endif
#else
#define INLINE
#endif
#endif /* INLINE */
/* GCC 7 has new switch() fall-through detection */
#if defined(__GNUC__)
#if ((__GNUC__ > 7) || ((__GNUC__ == 7) && (__GNUC_MINOR__ >= 1)))
#define FALL_THROUGH __attribute__ ((fallthrough));
#endif
#endif
#ifndef FALL_THROUGH
#define FALL_THROUGH
#endif
#ifdef __cplusplus
}
#endif