Skip to content

Commit

Permalink
Merge pull request #3 from waitspring/dev
Browse files Browse the repository at this point in the history
tcping
  • Loading branch information
waitspring authored Jan 3, 2023
2 parents 76c9370 + 3202fb1 commit b3476c4
Show file tree
Hide file tree
Showing 7 changed files with 159 additions and 40 deletions.
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<h1 align="center">Morning Tavern</h1>
<h4 align="center">放置一些终端小工具与代码包</h4>

[![Version](https://img.shields.io/badge/Version-1.0.0-207F4C)](https://github.com/waitspring/morning-tavern)
[![Version](https://img.shields.io/badge/Version-1.0.1-207F4C)](https://github.com/waitspring/morning-tavern)
[![License](https://img.shields.io/badge/License-Apache%202.0-373834)](https://github.com/waitspring/morning-tavern/blob/master/license)

</div>
4 changes: 4 additions & 0 deletions static/morning-tavern/tcping/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
AUTOMAKE_OPTIONS = foreign
bin_PROGRAMS = tcping
tcping_SOURCES = src/tcping.c

16 changes: 16 additions & 0 deletions static/morning-tavern/tcping/configure.ac
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
AC_PREREQ([2.69])
AC_INIT([morning-tavern], [1.0.1], [[email protected]])
AM_INIT_AUTOMAKE
AC_CONFIG_SRCDIR([src/tcping.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([Makefile])

AC_PROG_CC

AC_CHECK_HEADERS([arpa/inet.h netdb.h stdlib.h string.h sys/socket.h sys/time.h unistd.h])

AC_FUNC_ERROR_AT_LINE
AC_CHECK_FUNCS([gettimeofday memset socket strrchr])

AC_OUTPUT

31 changes: 21 additions & 10 deletions static/spec/morning-tavern.spec
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
Name: morning-tavern
Version: 1.0.0
Release: 1%{?dist}
Summary: A good repository for bash tools
Name: morning-tavern
Version: 1.0.1
Release: 1%{?dist}
Summary: A good repository for bash tools

Group: Development/Tools
License: Apache 2.0
URL: https://github.com/waitspring/morning-tavern
Source0: %{name}-%{version}.tar.gz
Group: Development/Tools
License: Apache 2.0
URL: https://github.com/waitspring/morning-tavern
Source0: %{name}-%{version}.tar.gz

Requires: bash
BuildArch: noarch
BuildRequires: gcc, make
Requires: bash
BuildArch: x86_64

%description
A good repository for bash tools
Expand All @@ -19,16 +20,26 @@ A good repository for bash tools

%build

cd %{_builddir}/%{name}-%{version}/tcping
%configure
make CFLAGS=-std=c99 %{?_smp_mflags}

%install
mkdir -p %{buildroot}%{_bindir}
install -m 0775 %{_builddir}/%{name}-%{version}/searchme/searchme %{buildroot}%{_bindir}/searchme
install -m 0775 %{_builddir}/%{name}-%{version}/tcping/tcping %{buildroot}%{_bindir}/tcping
mkdir -p %{buildroot}%{_sysconfdir}
install -m 0664 %{_builddir}/%{name}-%{version}/searchme/searchme.conf %{buildroot}%{_sysconfdir}/searchme.conf

%files
%{_bindir}/searchme
%{_sysconfdir}/searchme.conf
%{_bindir}/tcping

%changelog
* Fri Dec 30 2022 waitspring <[email protected]>
- Create the package for tcping command
- Create the package for searchme command
* Thu Dec 9 2021 waitspring <[email protected]>
- Create the package for searchme command

39 changes: 39 additions & 0 deletions static/spec/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# RPM 仓库结构

`/srv/morning-tavern-1.0.1` 的目录结构如下:

```
/srv/morning-tavern-1.0.1
├──── searchme
│ ├──── searchme
│ └──── searchme.conf
└──── tcping
├──── aclocal.m4
├──── config.h.in
├──── configure
├──── configure.ac
├──── Makefile.am
├──── Makefile.in
└──── src
├──── tcping
└──── tcping.c
```

`/root/rpmbuild` 的目录结构如下:

```
/root/rpmbuild
├──── BUILD
├──── BUILDROOT
├──── RPMS
├──── SOURCES
│ └──── morning-tavern-1.0.1.tar.gz
├──── SPECS
│ └──── morning-tavern.spec
└──── SRPMS
```

37 changes: 37 additions & 0 deletions tcping/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Tcping

### 一、使用说明

**Tcping** 小工具在 Github 开源社区有很多作者实现过, 但从使用体验的层面看始终存在各种小瑕疵

**Tcping** 小工具由本人重构之后, 具备下述特点:

+ 允许在 `Shell` 脚本内配合 `IFS` 命令与循环结构使用
+ 允许使用静默工作模式
+ 根据执行结果的不同有不同的退出码:
* TCP 连接全部建立成功使用数值 0 作为退出码
* TCP 连接部分建立成功使用数值 1 作为退出码
* TCP 连接全部建立失败使用数值 2 作为退出码

### 二、使用方法

**Tcping** 小工具的安装方法说明如下:

```bash
$ gcc --std=c99 -o /usr/bin/tcping /path/to/tcping.c
$ chmod a+x /usr/bin/tcping
```

**Tcping** 小工具的使用方法说明如下:

```bash
$ tcping [option...] socket

-c, --count=TIMES # 配置命令发起 TIMES 次 TCP 连接, 默认值为 86400 (保持长 TCPING)
-i, --interval=NUM # 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 1 秒钟
-q, --quiet # 开启静默执行模式, 命令屏蔽正常输出
-h, --help # 列出命令的帮助信息
-v, --version # 列出命令的版本信息

```

70 changes: 41 additions & 29 deletions tcping/tcping.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
/**********************************************************************************************************************
* *
* main.c *
* Fu Xuanming (2022-2023) *
* ______ *
* (_) | o *
* | __ _ _ _ __, *
* _ |/ |/ \_| / |/ | / | *
* (_/ \___/|__/ |_/ | |_/\_/|/ *
* /| /| *
* \| \| *
* *
**********************************************************************************************************************
*
*
* 文件名称: tcping.c
* 编译方法: gcc --std=c99 -o /usr/bin/tcping /path/to/tcping.c
* 作者信息: Fu Xuanming (2022-2023)
*/

#include <arpa/inet.h>
#include <errno.h>
#include <getopt.h>
#include <netdb.h>
#include <stdio.h>
Expand All @@ -28,14 +33,13 @@
*/
void usage(void) {
puts("Usage: tcping [option...] socket");
puts(" -c, --count=TIMES 配置命令发起 TIMES 次 TCP 连接, 默认值为 -1 (保持长 TCPING)");
puts(" -i, --interval=NUM 配置两次连接中的停顿时间为 NUM 秒钟, 默认值为 1 秒钟");
puts(" -q, --quiet 开启静默执行模式, 命令屏蔽正常输出");
puts(" -h, --help 列出命令的帮助信息");
puts(" -v, --version 列出命令的版本信息");
puts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
puts("Examp: tcping -c 1 127.0.0.1:22");
puts(" tcping -c 1 [::1]:22");
puts("");
puts(" -c, --count=NUM make NUM times TCP connection, default 86400");
puts(" -i, --interval=NUM pause time for two connections as NUM seconds, default 1");
puts(" -q, --quiet enable the silent execution mode");
puts(" -h, --help list this help information");
puts(" -v, --version list this command version information");
puts("");
}

void version(void) {
Expand Down Expand Up @@ -85,10 +89,11 @@ void error(const char *func, const char *error) {
**********************************************************************************************************************
*/
int judge_ip(char *ip, char **ipp, struct sockaddr_in *addr) {
/* Todo: 分切套接字得到 IPv4/IPv6 地址, 验证 IPv4/IPv6 地址是否符合书写规范
* Todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 sockaddr_in.sin_addr.s_addr 数据字段
* Todo: 已经验证通过的 IPv4/IPv6 地址, 赋予 ipp 字符串指针
* Return: IPv4/IPv6 地址校验成功返回值为 1, IPv4/IPv6 地址校验失败返回值为 0
/* Todo: 分切套接字得到 IPv4 地址, 验证 IPv4 地址是否符合书写规范
* Todo: 已经验证通过的 IPv4 地址, 赋予 sockaddr_in.sin_addr.s_addr 数据字段
* Todo: 已经验证通过的 IPv4 地址, 赋予 ipp 字符串指针
* Todo: 如果传入参数为 IPv6 地址, 抛出错误信息
* Return: IPv4 地址校验成功返回值为 1, IPv4 地址校验失败返回值为 0
*/
struct in_addr ipv4;
struct in6_addr ipv6;
Expand All @@ -109,13 +114,13 @@ int judge_ip(char *ip, char **ipp, struct sockaddr_in *addr) {
return 1;
}
if (inet_pton(AF_INET6, (char *)ip, &ipv6)) {
addr->sin_family = AF_INET6;
addr->sin_addr.s_addr = inet_addr(ip);
*ipp = ip;
return 1;
error("judge_ip", "check target address error");
error("judge_ip", "target address is IPv6 address, maybe you can use tcping6 command");
return 0;
}

error("judge_ip", "目标地址检查失败, 目标地址不符合 IPv4/ IPv6 的书写规范");
error("judge_ip", "check target address error");
error("judge_ip", "target address does not conform to the IPv4 writing specification");
return 0;
}

Expand All @@ -132,12 +137,14 @@ int judge_po(char *po, char **pop, struct sockaddr_in *addr) {
if (po[i] >= '0' && po[i] <='9') {
continue;
} else {
error("judge_po", "目标端口检查失败, 目标端口不符合书写规范");
error("judge_po", "check target port error");
error("judge_po", "target port does not conform to the port writing specification");
return 0;
}
}
if (atoi(po) > 65535) {
error("judge_po", "目标端口检查失败, 目标端口已超过取值范围");
error("judge_po", "check target port error");
error("judge_po", "target port has exceeded the value range");
return 0;
}

Expand Down Expand Up @@ -255,13 +262,15 @@ int main(int argc, char *argv[]) {
version();
return 0;
case '?': // getopt 函数提供给用户捕获无效的命令选项
error("main", "选项类型检查失败, 请使用 $ tcping -h 查阅命令的帮助信息");
error("main", "option type check error");
error("main", "exeute $ tcping -h find help information");
return 1;
}
}

if ((argc - optind) != 1) {
error("main", "参数数量检查失败, 请使用 $ tcping -h 查阅命令的帮助信息");
error("main", "option number check error");
error("main", "exeute $ tcping -h find help information");
return 1;
} else {
parameter = argv[optind];
Expand All @@ -273,16 +282,17 @@ int main(int argc, char *argv[]) {
/* judge_ip() 执行结束时, 字符数组变量 ip 仍然存储完整的目标套接字 (:port 部分被切割)
* judge_po() 执行结束时, 字符数组变量 po 仍然存储完整的目标套接字
*/
error("main", "参数赋值检查失败, 请使用 $ tcping -h 查阅命令的帮助信息");
error("main", "option value check error");
error("main", "exeute $ tcping -h find help information");
return 1;
}

int ms[count];
int max_ms = 0;
int min_ms = 0;
int avg_ms = 0;
int counts = 0; // 统计成功次数
int counte = 0; // 统计失败次数
int counts = 0; // 统计成功次数 (count success)
int counte = 0; // 统计失败次数 (count error)

for (int i = 0; i < count; i++) {
struct timeval begin;
Expand All @@ -307,10 +317,12 @@ int main(int argc, char *argv[]) {
min_ms = min(ms, count);
avg_ms = avg(ms, count, counts);
if (quiet == 0) {
printf("\n");
printf("Tcping statistics tcp://%s:%s\n", ipp, pop);
printf(" %d times request success, %d times request error\n", counts, counte);
printf("Approximate trip times:\n");
printf(" Maximum = %d(ms), Minimum = %d(ms), Average = %d(ms)\n", max_ms, min_ms, avg_ms);
printf("\n");
}

if (counte == count) {
Expand Down

0 comments on commit b3476c4

Please sign in to comment.