701 lines
20 KiB
C
701 lines
20 KiB
C
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipcom_mshell.c,v $ $Revision: 1.26 $
|
|
* $Source: /home/interpeak/CVSRoot/ipcom/src/ipcom_mshell.c,v $
|
|
* $Author: jonas $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Lennart Bang <lob@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#include "ipcom_config.h"
|
|
|
|
#define IPCOM_MSHELL_PORT 2323
|
|
|
|
/* Define if you want support for a 2nd login on the telnet port+1.
|
|
* #define IPCOM_MSHELL_USE_PORT2
|
|
*/
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#if IPCOM_USE_SHELL == IPCOM_SHELL_MINI
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include "ipcom_sock.h"
|
|
#include "ipcom_clib.h"
|
|
#include "ipcom_clib2.h"
|
|
#include "ipcom_syslog.h"
|
|
#include "ipcom_err.h"
|
|
#include "ipcom_os.h"
|
|
#include "ipcom_shell.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_SYSLOG_PRIORITY IPCOM_SYSLOG_IPCOM_PRIORITY
|
|
#define IPCOM_SYSLOG_FACILITY IPCOM_LOG_IPCOM_SHELL
|
|
|
|
/* Telnet command codes */
|
|
#define IPCOM_TELNET_WILL 251
|
|
#define IPCOM_TELNET_WONT 252
|
|
#define IPCOM_TELNET_DO 253
|
|
#define IPCOM_TELNET_DONT 254
|
|
#define IPCOM_TELNET_IAC 255
|
|
|
|
/* Telnet option id's */
|
|
#define IPCOM_TELNET_ECHO 1
|
|
#define IPCOM_TELNET_SGA 3
|
|
|
|
#define IPCOM_MAX_ARGV 12
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
typedef struct Ipcom_mshell_command_struct
|
|
{
|
|
IP_CONST char *name;
|
|
int (*function)(int argc, char **argv);
|
|
}
|
|
Ipcom_mshell_command;
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_PUBLIC int ipcom_cmd_ttcp(int argc, char **argv);
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_GLOBAL Ip_err ipcom_mshell_init(void);
|
|
|
|
IPCOM_PROCESS(ipcom_mshell_proc);
|
|
#ifdef IPCOM_MSHELL_USE_PORT2
|
|
IPCOM_PROCESS(ipcom_mshell_proc2);
|
|
#endif
|
|
|
|
IP_STATIC int ipcom_mshell_cmd_msleep(int argc, char **argv);
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_STATIC Ipcom_mshell_command ipcom_mshell_commands[] =
|
|
{
|
|
{ "msleep", ipcom_mshell_cmd_msleep },
|
|
#ifndef IP_SIZE
|
|
{ "ttcp", ipcom_cmd_ttcp },
|
|
#endif
|
|
{ IP_NULL, IP_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_mshell
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipcom_mshell_cmd_msleep(int argc, char **argv)
|
|
{
|
|
if(argc != 2)
|
|
ipcom_fprintf(ip_stdout, "usage: msleep <milliseconds>\n\r");
|
|
else
|
|
{
|
|
int msec = ipcom_atoi(argv[1]);
|
|
|
|
ipcom_fprintf(ip_stdout, "Sleeping %d milliseconds, ZZzzz...\n\r", msec);
|
|
ipcom_millisleep(msec);
|
|
ipcom_fprintf(ip_stdout, "Morning!\n\r");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_mshell
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters: Server TCP port.
|
|
* Returns: Never returns.
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipcom_mshell(Ip_u16 port)
|
|
{
|
|
#ifdef IPCOM_USE_INET
|
|
Ip_fd mother4 = IP_INVALID_SOCKET;
|
|
struct Ip_sockaddr_in addr4;
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
Ip_fd mother6 = IP_INVALID_SOCKET;
|
|
struct Ip_sockaddr_in6 addr6;
|
|
#endif
|
|
Ip_ssize_t length;
|
|
Ip_u8 *buf, bufdata[64], cmd[160];
|
|
int n, cmdlen, num, max = 0;
|
|
Ip_fd_set read_set;
|
|
Ip_bool host_echo, peer_echo;
|
|
Ip_fd ipcom_mshell_fd;
|
|
Ipcom_proc *proc;
|
|
|
|
ipcom_proc_init();
|
|
|
|
proc = ipcom_proc_self();
|
|
if(proc == IP_NULL)
|
|
{
|
|
IPCOM_LOG0(ERR, "ipcom_mshell :: ipcom_proc_self() failed");
|
|
goto error;
|
|
}
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
mother4 = ipcom_socket(IP_AF_INET, IP_SOCK_STREAM, 0);
|
|
if(mother4 == IP_INVALID_SOCKET)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipcom_mshell :: ipcom_socket(IPv4, IP_SOCK_STREAM) failed, errno = %d", ipcom_errno);
|
|
goto ipv6; /* If stack not compiled with IPv4, try IPv6 if enabled. */
|
|
}
|
|
max = mother4;
|
|
|
|
ipcom_memset(&addr4, 0, sizeof(addr4));
|
|
addr4.sin_len = sizeof(struct Ip_sockaddr_in);
|
|
addr4.sin_family = IP_AF_INET;
|
|
addr4.sin_port = ip_htons(port);
|
|
if(ipcom_bind(mother4, (struct Ip_sockaddr *)&addr4, sizeof(addr4)) == IP_SOCKERR)
|
|
{
|
|
IPCOM_LOG2(ERR, "ipcom_mshell :: ipcom_bind(IPv4, %d) failed, errno = %d",
|
|
port, ipcom_errno);
|
|
goto error;
|
|
}
|
|
|
|
if(ipcom_listen(mother4, 5) == IP_SOCKERR)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipcom_mshell :: ipcom_listen(IPv4) failed, errno = %d", ipcom_errno);
|
|
goto error;
|
|
}
|
|
#endif /* IPCOM_USE_INET */
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
ipv6:
|
|
#endif
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
mother6 = ipcom_socket(IP_AF_INET6, IP_SOCK_STREAM, 0);
|
|
if(mother6 == IP_INVALID_SOCKET)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipcom_mshell :: ipcom_socket(IPv6, IP_SOCK_STREAM) failed, errno = %d", ipcom_errno);
|
|
goto main_loop;
|
|
}
|
|
max = IP_MAX(max, mother6);
|
|
|
|
ipcom_memset(&addr6, 0, sizeof(struct Ip_sockaddr_in6));
|
|
addr6.sin6_len = sizeof(struct Ip_sockaddr_in6);
|
|
addr6.sin6_family = IP_AF_INET6;
|
|
addr6.sin6_port = ip_htons(port);
|
|
if(ipcom_bind(mother6, (struct Ip_sockaddr *)&addr6, sizeof(addr6)) == IP_SOCKERR)
|
|
{
|
|
IPCOM_LOG2(ERR, "ipcom_mshell :: ipcom_bind(IPv6, %d) failed, errno = %d",
|
|
port, ipcom_errno);
|
|
goto error;
|
|
}
|
|
|
|
if(ipcom_listen(mother6, 5) == IP_SOCKERR)
|
|
{
|
|
IPCOM_LOG1(ERR, "ipcom_mshell :: ipcom_listen(IPv6) failed, errno = %d", ipcom_errno);
|
|
goto error;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef IPCOM_USE_INET6
|
|
main_loop:
|
|
#endif
|
|
|
|
for(;;)
|
|
{
|
|
IP_FD_ZERO(&read_set);
|
|
#ifdef IPCOM_USE_INET
|
|
if(mother4 != IP_INVALID_SOCKET)
|
|
IP_FD_SET(mother4, &read_set);
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
if(mother6 != IP_INVALID_SOCKET)
|
|
IP_FD_SET(mother6, &read_set);
|
|
#endif
|
|
|
|
num = ipcom_socketselect(max + 1, &read_set, IP_NULL, IP_NULL, IP_NULL);
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
if(num > 0 && mother4 != IP_INVALID_SOCKET && IP_FD_ISSET(mother4, &read_set))
|
|
{
|
|
ipcom_mshell_fd = ipcom_accept(mother4, IP_NULL, IP_NULL);
|
|
if (ipcom_mshell_fd == IP_INVALID_SOCKET)
|
|
{
|
|
IPCOM_LOG1(DEBUG, "ipcom_mshell :: ipcom_accept(IPv4) failed, errno = %d", ipcom_errno);
|
|
continue;
|
|
}
|
|
goto accept;
|
|
}
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
if(num > 0 && mother6 != IP_INVALID_SOCKET && IP_FD_ISSET(mother6, &read_set))
|
|
{
|
|
ipcom_mshell_fd = ipcom_accept(mother6, IP_NULL, IP_NULL);
|
|
if (ipcom_mshell_fd == IP_INVALID_SOCKET)
|
|
{
|
|
IPCOM_LOG1(DEBUG, "ipcom_mshell :: ipcom_accept(IPv6) failed, errno = %d", ipcom_errno);
|
|
continue;
|
|
}
|
|
goto accept;
|
|
}
|
|
#endif
|
|
|
|
continue;
|
|
|
|
|
|
accept:
|
|
proc->shell_fd = ipcom_mshell_fd;
|
|
|
|
/* Init the connection. */
|
|
bufdata[0] = IPCOM_TELNET_IAC;
|
|
bufdata[1] = IPCOM_TELNET_WILL;
|
|
bufdata[2] = IPCOM_TELNET_ECHO;
|
|
bufdata[3] = IPCOM_TELNET_IAC;
|
|
bufdata[4] = IPCOM_TELNET_WILL;
|
|
bufdata[5] = IPCOM_TELNET_SGA;
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, bufdata, 6) != 6)
|
|
goto logout;
|
|
host_echo = IP_TRUE;
|
|
peer_echo = IP_FALSE;
|
|
cmdlen = 0;
|
|
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, "Welcome to Interpeak Mini Shell.\n\r$> ", 38) != 38)
|
|
goto logout;
|
|
|
|
/* Logged in. */
|
|
for(;;)
|
|
{
|
|
buf = bufdata;
|
|
length = ipcom_socketread(ipcom_mshell_fd, bufdata, sizeof(bufdata));
|
|
if(length <= 0)
|
|
goto logout;
|
|
|
|
/* Ignore all telnet options except ECHO. */
|
|
while(length >= 2 && buf[0] == IPCOM_TELNET_IAC)
|
|
{
|
|
Ip_u8 reply;
|
|
Ip_ssize_t offset;
|
|
|
|
reply = 0;
|
|
offset = 3;
|
|
|
|
switch(buf[1])
|
|
{
|
|
case IPCOM_TELNET_DO :
|
|
if (buf[2] == IPCOM_TELNET_ECHO)
|
|
{
|
|
host_echo = IP_TRUE;
|
|
reply = IPCOM_TELNET_WILL;
|
|
}
|
|
else if (buf[2] == IPCOM_TELNET_SGA)
|
|
reply = IPCOM_TELNET_WILL;
|
|
else
|
|
reply = IPCOM_TELNET_WONT;
|
|
break;
|
|
case IPCOM_TELNET_DONT :
|
|
if (buf[2] == IPCOM_TELNET_ECHO)
|
|
host_echo = IP_FALSE;
|
|
reply = IPCOM_TELNET_WONT;
|
|
break;
|
|
case IPCOM_TELNET_WILL :
|
|
if (buf[2] == IPCOM_TELNET_ECHO)
|
|
{
|
|
peer_echo = IP_TRUE;
|
|
reply = IPCOM_TELNET_DO;
|
|
}
|
|
else
|
|
reply = IPCOM_TELNET_WONT;
|
|
break;
|
|
case IPCOM_TELNET_WONT :
|
|
if (buf[2] == IPCOM_TELNET_ECHO)
|
|
peer_echo = IP_FALSE;
|
|
reply = IPCOM_TELNET_DONT;
|
|
break;
|
|
default:
|
|
offset = 2;
|
|
break;
|
|
}
|
|
|
|
if(reply != 0)
|
|
{
|
|
Ip_u8 cbuf[3];
|
|
|
|
cbuf[0] = (Ip_u8)IPCOM_TELNET_IAC;
|
|
cbuf[1] = reply;
|
|
cbuf[2] = buf[2];
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, cbuf, 3) != 3)
|
|
goto logout;
|
|
}
|
|
|
|
buf += offset;
|
|
length -= offset;
|
|
}
|
|
|
|
if(length > 0 && peer_echo == IP_FALSE && host_echo == IP_TRUE)
|
|
{
|
|
/* Echo client data. */
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, buf, length) != length)
|
|
goto logout;
|
|
|
|
/* Add 'buf' data to 'cmd' buffer. */
|
|
length = IP_MIN(length, sizeof(cmd) - cmdlen);
|
|
ipcom_strncpy((char*)cmd + cmdlen, (char*)buf, length);
|
|
cmdlen += length;
|
|
}
|
|
|
|
/* Full command buffer, parse what we got. */
|
|
if(cmdlen == sizeof(cmd))
|
|
{
|
|
n = cmdlen - 1;
|
|
goto parse_cmd;
|
|
}
|
|
|
|
/* Check for 'Enter' */
|
|
for(n = 0; n < cmdlen; n++)
|
|
if(cmd[n] == '\n' || cmd[n] == '\r')
|
|
{
|
|
cmd[n] = '\0';
|
|
if(n > 0)
|
|
{
|
|
int i, argc;
|
|
char *argv[IPCOM_MAX_ARGV];
|
|
|
|
parse_cmd:
|
|
i = 0;
|
|
argc = 0;
|
|
|
|
/* Fill in argv and set argc. */
|
|
while(cmd[i] == ' ')
|
|
i++;
|
|
argv[argc++] = (char*)&cmd[i];
|
|
for(; i < n; i++)
|
|
if(cmd[i] == ' ')
|
|
{
|
|
cmd[i++] = '\0';
|
|
while(cmd[i] == ' ')
|
|
i++;
|
|
if(cmd[i] != '\0')
|
|
argv[argc++] = (char*)&cmd[i];
|
|
}
|
|
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, "\n\r", 2) != 2)
|
|
goto logout;
|
|
|
|
/* Run the command. */
|
|
ip_assert(argv[0] != IP_NULL);
|
|
if(ipcom_strcmp(argv[0], "exit") == 0)
|
|
goto logout;
|
|
if(ipcom_strcmp(argv[0], "help") == 0 || *argv[0] == '?')
|
|
{
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, "? help exit", 11) != 11)
|
|
goto logout;
|
|
for(i = 0; ipcom_mshell_commands[i].name; i++)
|
|
{
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, " ", 1) != 1)
|
|
goto logout;
|
|
length = ipcom_strlen(ipcom_mshell_commands[i].name);
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, ipcom_mshell_commands[i].name, length) != length)
|
|
goto logout;
|
|
}
|
|
goto prompt;
|
|
}
|
|
for(i = 0; ipcom_mshell_commands[i].name; i++)
|
|
if(ipcom_strcmp(ipcom_mshell_commands[i].name, argv[0]) == 0)
|
|
{
|
|
(void)ipcom_mshell_commands[i].function(argc, argv);
|
|
goto prompt;
|
|
}
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, "Unknown command, type '?' for help.", 35) != 35)
|
|
goto logout;
|
|
}
|
|
|
|
/* Write prompt. */
|
|
prompt:
|
|
if(ipcom_socketwrite(ipcom_mshell_fd, "\n\r$> ", 5) != 5)
|
|
goto logout;
|
|
cmdlen = 0;
|
|
}
|
|
}
|
|
|
|
logout:
|
|
(void)ipcom_socketwrite(ipcom_mshell_fd, "Bye!\n\r", 6);
|
|
ipcom_socketclose(ipcom_mshell_fd);
|
|
proc->shell_fd = IP_INVALID_SOCKET;
|
|
}
|
|
|
|
error:
|
|
#ifdef IPCOM_USE_INET
|
|
if(mother4 != IP_INVALID_SOCKET)
|
|
ipcom_socketclose(mother4);
|
|
#endif
|
|
#ifdef IPCOM_USE_INET6
|
|
if(mother6 != IP_INVALID_SOCKET)
|
|
ipcom_socketclose(mother6);
|
|
#endif
|
|
ipcom_proc_exit();
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_mshell_proc
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IPCOM_PROCESS(ipcom_mshell_proc)
|
|
{
|
|
ipcom_mshell(IPCOM_MSHELL_PORT);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_mshell_proc2
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
#ifdef IPCOM_MSHELL_USE_PORT2
|
|
IPCOM_PROCESS(ipcom_mshell_proc2)
|
|
{
|
|
ipcom_mshell(IPCOM_MSHELL_PORT + 1);
|
|
}
|
|
#endif
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_mshell_init
|
|
*===========================================================================
|
|
* Context:
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL Ip_err
|
|
ipcom_mshell_init(void)
|
|
{
|
|
Ip_err err;
|
|
|
|
err = ipcom_proc_acreate("ipcom_mshell", (Ipcom_proc_func)ipcom_mshell_proc, IP_NULL, IP_NULL);
|
|
if(err != IPCOM_SUCCESS)
|
|
return err;
|
|
|
|
#ifdef IPCOM_MSHELL_USE_PORT2
|
|
err = ipcom_proc_acreate("ipcom_mshell2", (Ipcom_proc_func)ipcom_mshell_proc2, IP_NULL, IP_NULL);
|
|
if(err != IPCOM_SUCCESS)
|
|
return err;
|
|
#endif
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_shell_fwrite
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ip_size_t
|
|
ipcom_shell_fwrite(IP_CONST void *ptr, Ip_size_t size, Ip_size_t nitems, IP_FILE *stream)
|
|
{
|
|
Ip_fd ipcom_mshell_fd;
|
|
Ipcom_proc *proc;
|
|
int retval;
|
|
|
|
(void)stream;
|
|
|
|
if (size == 0 || nitems == 0)
|
|
return 0;
|
|
|
|
proc = ipcom_proc_self();
|
|
if(proc == IP_NULL)
|
|
return 0;
|
|
ipcom_mshell_fd = proc->shell_fd;
|
|
if(ipcom_mshell_fd == IP_INVALID_SOCKET)
|
|
return 0;
|
|
|
|
retval = (int)ipcom_socketwrite(ipcom_mshell_fd, ptr, size * nitems);
|
|
if (retval < 0)
|
|
return 0;
|
|
return (Ip_size_t)(retval / size);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_shell_fread
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ip_size_t
|
|
ipcom_shell_fread(void *ptr, Ip_size_t size, Ip_size_t nitems, IP_FILE *stream)
|
|
{
|
|
Ip_fd ipcom_mshell_fd;
|
|
Ipcom_proc *proc;
|
|
int retval;
|
|
|
|
(void)stream;
|
|
|
|
proc = ipcom_proc_self();
|
|
if(proc == IP_NULL)
|
|
return 0;
|
|
ipcom_mshell_fd = proc->shell_fd;
|
|
if(ipcom_mshell_fd == IP_INVALID_SOCKET)
|
|
return 0;
|
|
|
|
retval = (int)ipcom_socketread(ipcom_mshell_fd, ptr, size * nitems);
|
|
retval = IP_MAX(0, retval);
|
|
return retval;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_shell_write
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC Ip_ssize_t
|
|
ipcom_shell_write(Ip_fd fd, IP_CONST void *buf, Ip_size_t count)
|
|
{
|
|
return ipcom_shell_fwrite(buf, count, 1, IP_NULL /* ununsed */);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipcom_shell_add_cmd
|
|
*===========================================================================
|
|
* Description: Add a command to the list of available ipcom_shell commands
|
|
* Parameters: name : command's name
|
|
* usage : usage string
|
|
* description : description of command
|
|
* hook : function to that executes the command
|
|
* priority : na
|
|
* stack_size : the stack to be used by the process that
|
|
* executes the hook.
|
|
*
|
|
* Returns: IPCOM_SUCCESS : ok
|
|
* IPCOM_ERR_DUPLICATE : command already exists
|
|
* IPCOM_ERR_NO_MEMORY : out of memory
|
|
*
|
|
*
|
|
*/
|
|
#if 0
|
|
IP_PUBLIC Ip_err
|
|
ipcom_shell_add_cmd(const char *name, const char *usage,
|
|
const char *description, Ipcom_shell_cmd_type hook,
|
|
Ip_s32 priority, Ip_s32 stack_size)
|
|
{
|
|
(void)name;
|
|
(void)usage;
|
|
(void)description;
|
|
(void)hook;
|
|
(void)priority;
|
|
(void)stack_size;
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
#endif
|
|
|
|
|
|
#else
|
|
int ipcom_mshell_empty_file;
|
|
#endif /* IPCOM_USE_SHELL == IPCOM_SHELL_MINI */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|