/********************************************************************************************************* ** 函数名称: __tshellTtyInputHistoryGet ** 功能描述: shell 获取一条输入历史. ** 输 入 : bNext 向前还是向后 ** ppvCookie 上次获取的位置 ** psicContext 当前输入相上下文 ** 输 出 : 是否获取成功 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static BOOL __tshellHistoryGet (BOOL bNext, PVOID *ppvCookie, __PSHELL_INPUT_CTX psicContext) { PLW_CLASS_TCB ptcbCur; __PSHELL_HISTORY_CTX psihc; __PSHELL_HISTORY psihHistory = (__PSHELL_HISTORY)*ppvCookie; PLW_LIST_RING pringGet; LW_TCB_GET_CUR_SAFE(ptcbCur); psihc = __TTINY_SHELL_GET_HIS(ptcbCur); if (psihc->SIHC_pringHeader == LW_NULL) { /* 没有历史记录 */ return (LW_FALSE); } if (psihHistory == LW_NULL) { pringGet = psihc->SIHC_pringHeader; } else { if (bNext) { pringGet = _list_ring_get_next(&psihHistory->SIH_ringManage); } else { pringGet = _list_ring_get_prev(&psihHistory->SIH_ringManage); } } psihHistory = _LIST_ENTRY(pringGet, __SHELL_HISTORY, SIH_ringManage); lib_strlcpy(CTX_BUFFER, psihHistory->SIH_cInputSave, LW_CFG_SHELL_MAX_COMMANDLEN); *ppvCookie = (PVOID)psihHistory; return (LW_TRUE); }
/********************************************************************************************************* ** 函数名称: __rtAddCallback ** 功能描述: 添加一个 sylixos 路由条目(加入链表, 在 TCPIP 上下文中执行) ** 输 入 : ipaddrDest 目的地址 ** uiFlag flag ** pcNetifName 路由设备接口名 ** 输 出 : ERROR_NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __rtAddCallback (ip_addr_t *pipaddrDest, UINT uiFlag, CPCHAR pcNetifName) { INT iHash = LW_RT_HASHINDEX(pipaddrDest); PLW_RT_ENTRY prte; prte = (PLW_RT_ENTRY)__SHEAP_ALLOC(sizeof(LW_RT_ENTRY)); if (prte == LW_NULL) { _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); return (PX_ERROR); } prte->RTE_ipaddrDest = *pipaddrDest; prte->RTE_pnetif = netif_find((PCHAR)pcNetifName); prte->RTE_uiFlag = uiFlag; lib_strlcpy(prte->RTE_cNetifName, pcNetifName, IF_NAMESIZE); if (prte->RTE_pnetif) { prte->RTE_uiFlag |= LW_RT_FLAG_U; /* 路由有效 */ _G_uiActiveNum++; } _G_uiTotalNum++; _List_Line_Add_Ahead(&prte->RTE_lineManage, &_G_plineRtHashHeader[iHash]); return (ERROR_NONE); }
LW_API ULONG API_INetNetBiosNameGet (PCHAR pcLocalNameBuffer, INT iMaxLen) { if (pcLocalNameBuffer && (iMaxLen > 0)) { lib_strlcpy(pcLocalNameBuffer, _G_cNetBiosLocalName, iMaxLen); return (ERROR_NONE); } else { _ErrorHandle(ERROR_KERNEL_BUFFER_NULL); return (ERROR_KERNEL_BUFFER_NULL); } }
/********************************************************************************************************* ** 函数名称: __netIfSpeed ** 功能描述: 显示指定的网络接口信息 (ip v4) ** 输 入 : pcIfName 网络接口名 ** netifShow 网络接口结构 ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ static VOID __netIfSpeed (struct netif *netif, PCHAR pcSpeedStr, size_t stSize) { if (netif->link_speed == 0) { lib_strlcpy(pcSpeedStr, "AUTO", stSize); } else if (netif->link_speed < 1000) { snprintf(pcSpeedStr, stSize, "%d(bps)", netif->link_speed); } else if (netif->link_speed < 5000000) { snprintf(pcSpeedStr, stSize, "%d(Kbps)", netif->link_speed / 1000); } else { snprintf(pcSpeedStr, stSize, "%d(Mbps)", netif->link_speed / 1000000); } }
/********************************************************************************************************* ** 函数名称: ifconfig ** 功能描述: 设置指定网卡 IP. ** 输 入 : name 网卡名 ** ip ip 地址 ** netmask 子网掩码 ** 输 出 : ERROR or OK ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API int ifconfig (char *name, char *ip, char *netmask) { int sock; struct ifreq req; struct in_addr ipaddr; struct in_addr mskaddr; if (!name || !ip || !netmask) { errno = EINVAL; return (PX_ERROR); } if (!inet_aton(ip, &ipaddr)) { errno = EINVAL; return (PX_ERROR); } if (!inet_aton(netmask, &mskaddr)) { errno = EINVAL; return (PX_ERROR); } lib_strlcpy(req.ifr_name, name, IFNAMSIZ); req.ifr_addr.sa_family = AF_INET; sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { return (PX_ERROR); } ((struct sockaddr_in *)&req.ifr_addr)->sin_addr = ipaddr; if (ioctl(sock, SIOCSIFADDR, &req)) { close(sock); return (PX_ERROR); } ((struct sockaddr_in *)&req.ifr_netmask)->sin_addr = mskaddr; if (ioctl(sock, SIOCSIFNETMASK, &req)) { close(sock); return (PX_ERROR); } close(sock); return (ERROR_NONE); }
/********************************************************************************************************* ** 函数名称: _posixSyslogInit ** 功能描述: 初始化 syslog 库 ** 输 入 : NONE ** 输 出 : NONE ** 全局变量: ** 调用模块: *********************************************************************************************************/ VOID _posixSyslogInit (VOID) { INT iFd; _G_ulSyslogLock = API_SemaphoreMCreate("syslog_lock", LW_PRIO_DEF_CEILING, LW_OPTION_INHERIT_PRIORITY | LW_OPTION_DELETE_SAFE | LW_OPTION_OBJECT_GLOBAL, LW_NULL); if (_G_ulSyslogLock == 0) { _DebugHandle(__ERRORMESSAGE_LEVEL, "can not initialize mutex.\r\n"); } lib_strlcpy(_G_sockaddrunLog.sun_path, LOG_DEFAULT_FILE, sizeof(_G_sockaddrunLog.sun_path)); _G_sockaddrunLog.sun_family = AF_UNIX; _G_sockaddrunLog.sun_len = (uint8_t)(SUN_LEN(&_G_sockaddrunLog) + 1); /* 包含最后一个 '\0' */ _G_sockelenLog = _G_sockaddrunLog.sun_len; iFd = open(LOG_DEFAULT_FILE, O_CREAT | O_RDWR, __PX_SYSLOG_DEF_FLAG | S_IFSOCK); if (iFd >= 0) { close(iFd); } }
/********************************************************************************************************* ** 函数名称: __rtChangeCallback ** 功能描述: 修改一个 sylixos 路由条目(在 TCPIP 上下文中执行) ** 输 入 : ipaddrDest 目的地址 ** uiFlag flag ** pcNetifName 路由设备接口名 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __rtChangeCallback (ip_addr_t *pipaddrDest, UINT uiFlag, CPCHAR pcNetifName) { PLW_RT_ENTRY prte; prte = __rtFind(pipaddrDest, 0); if (prte) { INT iHash = LW_RT_HASHINDEX(&prte->RTE_ipaddrDest); if (prte->RTE_uiFlag & LW_RT_FLAG_U) { _G_uiActiveNum--; } _G_uiTotalNum--; LW_RT_CACHE_INVAL(prte); _List_Line_Del(&prte->RTE_lineManage, &_G_plineRtHashHeader[iHash]); prte->RTE_ipaddrDest = *pipaddrDest; prte->RTE_pnetif = netif_find((PCHAR)pcNetifName); prte->RTE_uiFlag = uiFlag; lib_strlcpy(prte->RTE_cNetifName, pcNetifName, IF_NAMESIZE); if (prte->RTE_pnetif) { prte->RTE_uiFlag |= LW_RT_FLAG_U; /* 路由有效 */ _G_uiActiveNum++; } _G_uiTotalNum++; iHash = LW_RT_HASHINDEX(&prte->RTE_ipaddrDest); _List_Line_Add_Ahead(&prte->RTE_lineManage, &_G_plineRtHashHeader[iHash]); return (ERROR_NONE); } _ErrorHandle(EINVAL); return (PX_ERROR); }
/********************************************************************************************************* ** 函数名称: __tshellReadline ** 功能描述: shell 从终端读取一条命令. ** 输 入 : iFd 文件描述符 ** pvBuffer 接收缓冲区 ** stMaxBytes 接收缓冲区大小 ** 输 出 : 读取个数 ** 全局变量: ** 调用模块: *********************************************************************************************************/ ssize_t __tshellReadline (INT iFd, PVOID pcBuffer, size_t stSize) { #define __CHK_READ_OUT(res) if (sstReadNum <= 0) { \ goto __out; \ } LONG lOldOption = OPT_TERMINAL; LONG lNewOption; ssize_t sstReadNum; __SHELL_INPUT_CTX sicContext; CHAR cRead; PVOID pvCookie = LW_NULL; if (__tshellReadlineInit() < ERROR_NONE) { /* 初始化当前线程 Readline相关 */ return (0); } sicContext.SIC_uiCursor = 0; sicContext.SIC_uiTotalLen = 0; sicContext.SIC_cInputBuffer[0] = PX_EOS; ioctl(iFd, FIOGETOPTIONS, &lOldOption); lNewOption = lOldOption & ~(OPT_ECHO | OPT_LINE); /* no echo no line mode */ ioctl(iFd, FIOSETOPTIONS, lNewOption); while (sicContext.SIC_uiTotalLen < LW_CFG_SHELL_MAX_COMMANDLEN) { sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); __re_check_key: if (__KEY_IS_ESC(cRead)) { /* 功能键起始 */ sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); if (cRead == 91) { /* 方向键中间键 */ sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); switch (cRead) { case __FUNC_KEY_LEFT: /* ← */ __tshellCharLeft(iFd, &sicContext); break; case __FUNC_KEY_UP: /* ↑ */ __tshellCharUp(iFd, &pvCookie, &sicContext); break; case __FUNC_KEY_RIGHT: /* → */ __tshellCharRight(iFd, &sicContext); break; case __FUNC_KEY_DOWN: /* ↓ */ __tshellCharDown(iFd, &pvCookie, &sicContext); break; case __FUNC_KEY_HOME: /* home key */ __tshellCharHome(iFd, &sicContext); sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); if (cRead != 126) { goto __re_check_key; } break; case __FUNC_KEY_DELETE: /* delete key */ __tshellCharDelete(iFd, &sicContext); sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); if (cRead != 126) { goto __re_check_key; } break; case __FUNC_KEY_END: /* end key */ __tshellCharEnd(iFd, &sicContext); sstReadNum = read(iFd, &cRead, 1); __CHK_READ_OUT(sstReadNum); if (cRead != 126) { goto __re_check_key; } break; } } else { goto __re_check_key; } } else if (__KEY_IS_TAB(cRead)) { /* tab */ __tshellCharTab(iFd, &sicContext); } else if (__KEY_IS_BS(cRead)) { /* backspace */ __tshellCharBackspace(iFd, cRead, &sicContext); } else if (__KEY_IS_LF(cRead)) { /* 结束 */ write(iFd, &cRead, 1); /* echo */ break; } else if (__KEY_IS_EOT(cRead)) { /* CTL+D 强制退出 */ lib_strcpy(sicContext.SIC_cInputBuffer, __TTINY_SHELL_FORCE_ABORT); sicContext.SIC_uiTotalLen = (UINT)lib_strlen(__TTINY_SHELL_FORCE_ABORT); break; } else { __tshellCharInster(iFd, cRead, &sicContext); } } sicContext.SIC_cInputBuffer[sicContext.SIC_uiTotalLen] = PX_EOS; /* 命令结束 */ if (lib_strlen(sicContext.SIC_cInputBuffer)) { __tshellHistorySave(&sicContext); /* 记录历史命令 */ } __out: ioctl(iFd, FIOSETOPTIONS, lOldOption); /* 恢复以前终端状态 */ lib_strlcpy((PCHAR)pcBuffer, sicContext.SIC_cInputBuffer, stSize); return ((ssize_t)sicContext.SIC_uiTotalLen); }
/********************************************************************************************************* ** 函数名称: readlink ** 功能描述: 读取符号链接文件的. ** 输 入 : pcSymPath 链接文件 ** pcLinkDst 连接内容缓冲 ** stMaxSize 缓冲大小 ** 输 出 : 读取的内容长度 ** 全局变量: ** 调用模块: API 函数 *********************************************************************************************************/ LW_API ssize_t readlink (CPCHAR pcSymPath, PCHAR pcLinkDst, size_t stMaxSize) { REGISTER LONG lValue; PLW_FD_ENTRY pfdentry; PLW_DEV_HDR pdevhdrHdr; CHAR cFullFileName[MAX_FILENAME_LENGTH]; PCHAR pcLastTimeName; INT iLinkCount = 0; ssize_t sstRet; PCHAR pcName = (PCHAR)pcSymPath; if (pcName == LW_NULL) { /* 检查文件名 */ _DebugHandle(__ERRORMESSAGE_LEVEL, "name invalidate.\r\n"); _ErrorHandle(EFAULT); /* Bad address */ return (PX_ERROR); } if (pcName[0] == PX_EOS) { _ErrorHandle(ENOENT); return (PX_ERROR); } if (lib_strcmp(pcName, ".") == 0) { /* 滤掉当前目录 */ pcName++; } if (ioFullFileNameGet(pcName, &pdevhdrHdr, cFullFileName) != ERROR_NONE) { _ErrorHandle(ENOENT); return (PX_ERROR); } pcLastTimeName = (PCHAR)__SHEAP_ALLOC(MAX_FILENAME_LENGTH); if (pcLastTimeName == LW_NULL) { _DebugHandle(__ERRORMESSAGE_LEVEL, "system low memory.\r\n"); _ErrorHandle(ERROR_SYSTEM_LOW_MEMORY); return (PX_ERROR); } lib_strlcpy(pcLastTimeName, cFullFileName, MAX_FILENAME_LENGTH); pfdentry = _IosFileNew(pdevhdrHdr, cFullFileName); /* 创建一个临时的 fd_entry */ if (pfdentry == LW_NULL) { __SHEAP_FREE(pcLastTimeName); return (PX_ERROR); } for (;;) { lValue = iosOpen(pdevhdrHdr, cFullFileName, O_RDONLY, 0); if (lValue != FOLLOW_LINK_TAIL) { /* FOLLOW_LINK_FILE 直接退出 */ break; } else { if (iLinkCount++ > _S_iIoMaxLinkLevels) { /* 链接文件层数太多 */ _IosFileDelete(pfdentry); __SHEAP_FREE(pcLastTimeName); _ErrorHandle(ELOOP); return (PX_ERROR); } } /* * 驱动程序如果返回 FOLLOW_LINK_????, cFullFileName内部一定是目标的绝对地址, 即以/起始的文件名. */ if (ioFullFileNameGet(cFullFileName, &pdevhdrHdr, cFullFileName) != ERROR_NONE) { _IosFileDelete(pfdentry); __SHEAP_FREE(pcLastTimeName); _ErrorHandle(EXDEV); return (PX_ERROR); } lib_strlcpy(pcLastTimeName, cFullFileName, MAX_FILENAME_LENGTH); } if ((lValue != PX_ERROR) && (lValue != FOLLOW_LINK_FILE)) { _IosFileSet(pfdentry, pdevhdrHdr, lValue, O_RDONLY); _IosFileClose(pfdentry); /* 关闭 */ } _IosFileDelete(pfdentry); /* 删除临时的 fd_entry */ sstRet = iosReadlink(pdevhdrHdr, pcLastTimeName, pcLinkDst, stMaxSize); __SHEAP_FREE(pcLastTimeName); return (sstRet); }
/********************************************************************************************************* ** 函数名称: __ram_open ** 功能描述: ramfs 打开一个文件 ** 输 入 : pramfs 文件系统 ** pcName 文件名 ** ppramnFather 当无法找到节点时保存最接近的一个, 但寻找到节点时保存父系节点. LW_NULL 表示根 pbRoot 是否为根节点 ** pbLast 当匹配失败时, 是否是最后一级文件匹配失败 ** ppcTail 如果存在连接文件, 指向连接文件后的路径 ** 输 出 : 打开结果 ** 全局变量: ** 调用模块: *********************************************************************************************************/ PRAM_NODE __ram_open (PRAM_VOLUME pramfs, CPCHAR pcName, PRAM_NODE *ppramnFather, BOOL *pbRoot, BOOL *pbLast, PCHAR *ppcTail) { CHAR pcTempName[MAX_FILENAME_LENGTH]; PCHAR pcNext; PCHAR pcNode; PRAM_NODE pramn; PRAM_NODE pramnTemp; PLW_LIST_LINE plineTemp; PLW_LIST_LINE plineHeader; /* 当前目录头 */ if (ppramnFather == LW_NULL) { ppramnFather = &pramnTemp; /* 临时变量 */ } *ppramnFather = LW_NULL; if (*pcName == PX_ROOT) { /* 忽略根符号 */ lib_strlcpy(pcTempName, (pcName + 1), PATH_MAX); } else { lib_strlcpy(pcTempName, pcName, PATH_MAX); } if (pcTempName[0] == PX_EOS) { if (pbRoot) { *pbRoot = LW_TRUE; /* pcName 为根 */ } if (pbLast) { *pbLast = LW_FALSE; } return (LW_NULL); } else { if (pbRoot) { *pbRoot = LW_FALSE; /* pcName 不为根 */ } } pcNext = pcTempName; plineHeader = pramfs->RAMFS_plineSon; /* 从根目录开始搜索 */ do { pcNode = pcNext; pcNext = lib_index(pcNode, PX_DIVIDER); /* 移动到下级目录 */ if (pcNext) { /* 是否可以进入下一层 */ *pcNext = PX_EOS; pcNext++; /* 下一层的指针 */ } for (plineTemp = plineHeader; plineTemp != LW_NULL; plineTemp = _list_line_get_next(plineTemp)) { pramn = _LIST_ENTRY(plineTemp, RAM_NODE, RAMN_lineBrother); if (S_ISLNK(pramn->RAMN_mode)) { /* 链接文件 */ if (lib_strcmp(pramn->RAMN_pcName, pcNode) == 0) { goto __find_ok; /* 找到链接 */ } } else if (S_ISDIR(pramn->RAMN_mode)) { if (lib_strcmp(pramn->RAMN_pcName, pcNode) == 0) { /* 已经找到一级目录 */ break; } } else { if (lib_strcmp(pramn->RAMN_pcName, pcNode) == 0) { if (pcNext) { /* 还存在下级, 这里必须为目录 */ goto __find_error; /* 不是目录直接错误 */ } break; } } } if (plineTemp == LW_NULL) { /* 无法继续搜索 */ goto __find_error; } *ppramnFather = pramn; /* 从当前节点开始搜索 */ plineHeader = pramn->RAMN_plineSon; /* 从第一个儿子开始 */ } while (pcNext); /* 不存在下级目录 */ __find_ok: *ppramnFather = pramn->RAMN_pramnFather; /* 父系节点 */ /* * 计算 tail 的位置. */ if (ppcTail) { if (pcNext) { INT iTail = pcNext - pcTempName; *ppcTail = (PCHAR)pcName + iTail; /* 指向没有被处理的 / 字符 */ } else { *ppcTail = (PCHAR)pcName + lib_strlen(pcName); /* 指向最末尾 */ } } return (pramn); __find_error: if (pbLast) { if (pcNext == LW_NULL) { /* 最后一级查找失败 */ *pbLast = LW_TRUE; } else { *pbLast = LW_FALSE; } } return (LW_NULL); /* 无法找到节点 */ }
/********************************************************************************************************* ** 函数名称: __tshellRoute ** 功能描述: 系统命令 "route" ** 输 入 : iArgC 参数个数 ** ppcArgV 参数表 ** 输 出 : ERROR ** 全局变量: ** 调用模块: *********************************************************************************************************/ INT __tshellRoute (INT iArgC, PCHAR *ppcArgV) { #define LW_RT_PRINT_SIZE 74 INT iError; FUNCPTR pfuncAddOrChange; PCHAR pcOpAddorChange; UINT uiFlag = 0; ip_addr_t ipaddr; CHAR cNetifName[IF_NAMESIZE]; if (iArgC == 1) { PCHAR pcBuffer; size_t stSize; size_t stOffset; UINT uiNumEntries; uiNumEntries = (UINT)__rtSafeRun((FUNCPTR)__rtEntryMaxNum, 0, 0, 0, 0, 0, 0); if (uiNumEntries == 0) { printf("no route entry.\n"); return (ERROR_NONE); } /* * 在 net safe 状态下不允许调用 printf 等使用 IO 的语句. 所以只能打印到缓冲区中, * 然后统一使用 IO 打印. */ stSize = LW_RT_PRINT_SIZE * uiNumEntries; pcBuffer = (PCHAR)__SHEAP_ALLOC(stSize); if (pcBuffer == LW_NULL) { fprintf(stderr, "system low memory.\n"); return (PX_ERROR); } /* * 打印 kernel route entry */ stOffset = 0; printf("kernel routing tables\n"); printf("Destination Gateway Mask Flag Interface\n"); __rtSafeRun((FUNCPTR)__rtTraversal, (void *)__rtEntryPrint, pcBuffer, (PVOID)stSize, &stOffset, 0, 0); if (stOffset > 0) { fwrite(pcBuffer, stOffset, 1, stdout); fflush(stdout); /* 这里必须确保输出完成 */ } /* * 打印 lwip build-in route entry */ stOffset = 0; printf("\nbuild-in routing tables\n"); printf("Destination Gateway Mask Flag Interface\n"); __rtSafeRun((FUNCPTR)__buildinRtPrint, pcBuffer, (PVOID)stSize, &stOffset, 0, 0, 0); if (stOffset > 0) { fwrite(pcBuffer, stOffset, 1, stdout); fflush(stdout); /* 这里必须确保输出完成 */ } __SHEAP_FREE(pcBuffer); return (ERROR_NONE); } else { /* 操作路由表 */ if (lib_strcmp(ppcArgV[1], "add") == 0) { pfuncAddOrChange = __rtAdd; pcOpAddorChange = "add"; } else if (lib_strcmp(ppcArgV[1], "change") == 0) { pfuncAddOrChange = __rtChange; pcOpAddorChange = "change"; } else { pfuncAddOrChange = LW_NULL; } if (pfuncAddOrChange && (iArgC == 6)) { /* 添加或者修改路由表 */ if (!ipaddr_aton(ppcArgV[3], &ipaddr)) { fprintf(stderr, "inet address format error.\n"); goto __error_handle; } if (lib_strcmp(ppcArgV[4], "if") == 0) { /* 使用 ifindex 查询网卡 */ INT iIndex = lib_atoi(ppcArgV[5]); if (if_indextoname(iIndex, cNetifName) == LW_NULL) { fprintf(stderr, "can not find net interface with ifindex %d.\n", iIndex); goto __error_handle; } } else if (lib_strcmp(ppcArgV[4], "dev") == 0) { lib_strlcpy(cNetifName, ppcArgV[5], IF_NAMESIZE); } else { fprintf(stderr, "net interface argument error.\n"); goto __error_handle; } if (lib_strcmp(ppcArgV[2], "-host") == 0) { /* 主机路由 */ uiFlag |= LW_RT_FLAG_H; } else if (lib_strcmp(ppcArgV[2], "-gw") == 0) { /* 设置网卡网关 */ uiFlag |= LW_RT_GW_FLAG_SET; pfuncAddOrChange = __rtSetGw; } else if (lib_strcmp(ppcArgV[2], "-net") != 0) { /* 非网络路由 */ fprintf(stderr, "route add must determine -host or -net.\n"); goto __error_handle; } iError = pfuncAddOrChange(&ipaddr, uiFlag, cNetifName); /* 操作路由表 */ if (iError >= 0) { printf("route %s %s successful.\n", ppcArgV[3], pcOpAddorChange); return (ERROR_NONE); } } else if (pfuncAddOrChange && (iArgC == 5)) { /* 设置默认网关 */ if (lib_strcmp(ppcArgV[2], "default") != 0) { goto __error_handle; } if (lib_strcmp(ppcArgV[3], "if") == 0) { /* 使用 ifindex 查询网卡 */ INT iIndex = lib_atoi(ppcArgV[4]); if (if_indextoname(iIndex, cNetifName) == LW_NULL) { fprintf(stderr, "can not find net interface with ifindex %d.\n", iIndex); goto __error_handle; } } else if (lib_strcmp(ppcArgV[3], "dev") == 0) { lib_strlcpy(cNetifName, ppcArgV[4], IF_NAMESIZE); } else { fprintf(stderr, "net interface argument error.\n"); goto __error_handle; } uiFlag |= LW_RT_GW_FLAG_DEFAULT; pfuncAddOrChange = __rtSetGw; iError = pfuncAddOrChange(&ipaddr, uiFlag, cNetifName); /* 设置默认路由出口 */ if (iError >= 0) { printf("default device set successful.\n"); return (ERROR_NONE); } } else if ((lib_strcmp(ppcArgV[1], "del") == 0) && iArgC == 3) {/* 删除一个路由表项 */ if (!ipaddr_aton(ppcArgV[2], &ipaddr)) { fprintf(stderr, "inet address format error.\n"); goto __error_handle; } iError = __rtDel(&ipaddr); if (iError >= 0) { printf("route %s delete successful.\n", ppcArgV[2]); return (ERROR_NONE); } } } __error_handle: fprintf(stderr, "argments error!\n"); return (-ERROR_TSHELL_EPARAM); }
/********************************************************************************************************* ** 函数名称: __untarFile ** 功能描述: unpackage a .tar file. ** 输 入 : pcTarFile tar file ** pcDestPath destination directory ** 输 出 : 0 or -1 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __untarFile (CPCHAR pcTarFile, CPCHAR pcDestPath) { INT iFdTar; char *pcBuf; ssize_t sstN; char cFname[100]; char cLinkname[100]; int iSum; int iHdrChksum; int iRetVal; unsigned long ulI; unsigned long ulNblocks; unsigned long ulSize; unsigned char ucLinkflag; ULONG ulTotalFile = 0ul; ULONG ulTotalDir = 0ul; iFdTar = open(pcTarFile, O_RDONLY); if (iFdTar < 0) { fprintf(stderr, "can not open : %s : %s\n", pcTarFile, lib_strerror(errno)); return (PX_ERROR); } pcBuf = (char *)__SHEAP_ALLOC(512); if (pcBuf == LW_NULL) { close(iFdTar); fprintf(stderr, "system low memory.\n"); return (PX_ERROR); } iRetVal = ERROR_NONE; while (1) { char cOutFile[PATH_MAX + 1]; mode_t mode; if ((sstN = read(iFdTar, pcBuf, 512)) != 512) { break; } if (lib_strncmp(&pcBuf[257], TMAGIC, 5)) { break; } lib_strlcpy(cFname, pcBuf, 100); ucLinkflag = pcBuf[156]; ulSize = __untarOctal2Long(&pcBuf[124], 12); iHdrChksum = (int)__untarOctal2Long(&pcBuf[148], 8); iSum = __untarHeaderChksum(pcBuf); if (iSum != iHdrChksum) { fprintf(stderr, "tar file : %s chksum error.\n", pcTarFile); iRetVal = PX_ERROR; break; } mode = (int)__untarOctal2Long(&pcBuf[100], 8); if (pcDestPath) { if (lib_strcmp(pcDestPath, PX_STR_ROOT) == 0) { if (cFname[0] == PX_ROOT) { lib_strlcpy(cOutFile, cFname, PATH_MAX + 1); } else { snprintf(cOutFile, PATH_MAX + 1, "%s%s", pcDestPath, cFname); } } else { snprintf(cOutFile, PATH_MAX + 1, "%s/%s", pcDestPath, cFname); } } else { lib_strlcpy(cOutFile, cFname, PATH_MAX + 1); } if (ucLinkflag == SYMTYPE) { printf("unpackage %s <LNK> ...\n", cOutFile); lib_strlcpy(cLinkname, &pcBuf[157], 100); symlink(cLinkname, cOutFile); ulTotalFile++; } else if (ucLinkflag == REGTYPE) { INT iFdOut; printf("unpackage %s size : %ld ...\n", cOutFile, ulSize); ulNblocks = (((ulSize) + 511) & ~511) / 512; if ((iFdOut = creat(cOutFile, mode)) < 0) { fprintf(stderr, "can not create : %s\n", cOutFile); lseek(iFdTar, (off_t)(ulNblocks * 512), SEEK_CUR); } else { for (ulI = 0; ulI < ulNblocks; ulI++) { sstN = read(iFdTar, pcBuf, 512); sstN = min(sstN, ulSize - (ulI * 512)); write(iFdOut, pcBuf, (size_t)sstN); } close(iFdOut); ulTotalFile++; } } else if (ucLinkflag == DIRTYPE) { printf("unpackage %s <DIR> ...\n", cOutFile); mkdir(cOutFile, mode); ulTotalDir++; } } __SHEAP_FREE(pcBuf); close(iFdTar); printf("unpackage total %lu files %lu directory.\n", ulTotalFile, ulTotalDir); return (iRetVal); }
/********************************************************************************************************* ** 函数名称: __tshellNetstat ** 功能描述: 系统命令 "netstat" ** 输 入 : iArgC 参数个数 ** ppcArgV 参数表 ** 输 出 : 0 ** 全局变量: ** 调用模块: *********************************************************************************************************/ static INT __tshellNetstat (INT iArgC, PCHAR *ppcArgV) { int iC; const char cShortOpt[] = "hrigswtpuxlaA:"; struct option optionNetstat[] = { {"help", 0, LW_NULL, 'h'}, {"route", 0, LW_NULL, 'r'}, {"interface", 0, LW_NULL, 'i'}, {"groups", 0, LW_NULL, 'g'}, {"statistics", 0, LW_NULL, 's'}, {"raw", 0, LW_NULL, 'r'}, {"tcp", 0, LW_NULL, 't'}, {"udp", 0, LW_NULL, 'u'}, {"packet", 0, LW_NULL, 'p'}, {"unix", 0, LW_NULL, 'x'}, {"listening", 0, LW_NULL, 'l'}, {"all", 0, LW_NULL, 'a'}, {"unix", 0, LW_NULL, 1}, {"inet", 0, LW_NULL, 2}, {"inet6", 0, LW_NULL, 3}, {LW_NULL, 0, LW_NULL, 0}, }; BOOL bPacket = LW_FALSE; BOOL bRaw = LW_FALSE; BOOL bUdp = LW_FALSE; BOOL bTcp = LW_FALSE; BOOL bUnix = LW_FALSE; BOOL bListen = LW_FALSE; INT iNetType = 0; /* 0:all 1:unix 2:inet 3:inet6 */ CHAR cNettype[10]; while ((iC = getopt_long(iArgC, ppcArgV, cShortOpt, optionNetstat, LW_NULL)) != -1) { switch (iC) { case 'h': /* 显示帮助 */ printf(_G_cNetstatHelp); return (ERROR_NONE); case 'r': /* 显示路由表 */ ppcArgV[1] = LW_NULL; __tshellRoute(1, ppcArgV); return (ERROR_NONE); case 'i': /* 显示网络接口信息 */ __tshellNetstatIf(); return (ERROR_NONE); case 'g': /* 显示组播表情况 */ #if LW_CFG_LWIP_IGMP > 0 __tshellNetstatGroup(iNetType); #endif return (ERROR_NONE); case 's': /* 显示统计信息 */ __tshellNetstatStat(); return (ERROR_NONE); case 'p': /* 显示 packet socket */ bPacket = LW_TRUE; break; case 'w': /* 显示 raw socket */ bRaw = LW_TRUE; break; case 't': /* 显示 tcp socket */ bTcp = LW_TRUE; break; case 'u': /* 显示 udp socket */ bUdp = LW_TRUE; break; case 'x': /* 显示 unix socket */ bUnix = LW_TRUE; break; case 'l': /* 显示 listen socket */ bListen = LW_TRUE; break; case 'a': /* 显示列表 */ goto __show; case 'A': /* 网络类型 */ lib_strlcpy(cNettype, optarg, 10); if (lib_strcmp(cNettype, "unix") == 0) { iNetType = 1; } else if (lib_strcmp(cNettype, "inet") == 0) { iNetType = 2; } else if (lib_strcmp(cNettype, "inet6") == 0) { iNetType = 3; } break; case 1: iNetType = 1; break; case 2: iNetType = 2; break; case 3: iNetType = 3; break; } } getopt_free(); __show: if ((bRaw == LW_FALSE) && (bUdp == LW_FALSE) && (bTcp == LW_FALSE) && (bUnix == LW_FALSE) && (bListen == LW_FALSE) && (bPacket == LW_FALSE)) { bRaw = LW_TRUE; bUdp = LW_TRUE; bTcp = LW_TRUE; bUnix = LW_TRUE; bPacket = LW_TRUE; } if (bUnix) { __tshellNetstatUnix(iNetType); } if (bPacket) { __tshellNetstatPacket(iNetType); } if (bTcp || bListen) { __tshellNetstatTcpListen(iNetType); if (bTcp) { __tshellNetstatTcp(iNetType); } } if (bUdp) { __tshellNetstatUdp(iNetType); } if (bRaw) { __tshellNetstatRaw(iNetType); } return (ERROR_NONE); }