mirror of
https://github.com/RubyMetric/chsrc.git
synced 2025-02-02 15:51:02 +08:00
Use better output
This commit is contained in:
parent
bc7c76e161
commit
e564239fed
320
include/chsrc.h
320
include/chsrc.h
|
@ -3,7 +3,7 @@
|
||||||
* License : GPLv3
|
* License : GPLv3
|
||||||
* Authors : Aoran Zeng <ccmywish@qq.com>
|
* Authors : Aoran Zeng <ccmywish@qq.com>
|
||||||
* Created on : <2023-08-29>
|
* Created on : <2023-08-29>
|
||||||
* Last modified : <2023-10-05>
|
* Last modified : <2024-05-25>
|
||||||
*
|
*
|
||||||
* chsrc:
|
* chsrc:
|
||||||
*
|
*
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
* @param progname 要检测的二进制程序名
|
* @param progname 要检测的二进制程序名
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
query_program_exist (char* check_cmd, char* progname)
|
query_program_exist (char *check_cmd, char *progname)
|
||||||
{
|
{
|
||||||
char* which = check_cmd;
|
char* which = check_cmd;
|
||||||
|
|
||||||
|
@ -41,10 +41,10 @@ query_program_exist (char* check_cmd, char* progname)
|
||||||
|
|
||||||
if (0!=ret) {
|
if (0!=ret) {
|
||||||
// xy_warn (xy_strjoin(4, "× 命令 ", progname, " 不存在,", buf));
|
// xy_warn (xy_strjoin(4, "× 命令 ", progname, " 不存在,", buf));
|
||||||
xy_warn (xy_strjoin(3, "× 命令 ", progname, " 不存在"));
|
puts (xy_strjoin (4, xy_str_to_red ("x "), "命令 ", xy_str_to_red (progname), " 不存在"));
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
xy_success (xy_strjoin(3, "√ 命令 ", progname, " 存在"));
|
puts (xy_strjoin (4, xy_str_to_green ("√ "), "命令 ", xy_str_to_green (progname), " 存在"));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,40 +58,45 @@ query_program_exist (char* check_cmd, char* progname)
|
||||||
*/
|
*/
|
||||||
#define find_mirror(s, input) query_mirror_exist(s##_sources, s##_sources_n, (char*)#s+3, input)
|
#define find_mirror(s, input) query_mirror_exist(s##_sources, s##_sources_n, (char*)#s+3, input)
|
||||||
int
|
int
|
||||||
query_mirror_exist (SourceInfo* sources, size_t size, char* target, char* input)
|
query_mirror_exist (SourceInfo *sources, size_t size, char *target, char *input)
|
||||||
{
|
{
|
||||||
if (0==size) {
|
if (0==size)
|
||||||
xy_error(xy_strjoin(3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
|
{
|
||||||
exit(1);
|
xy_error (xy_strjoin (3, "当前 ", target, " 无任何可用源,请联系维护者"));
|
||||||
}
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
if (1==size) {
|
if (1==size)
|
||||||
xy_success(xy_strjoin(5, "chsrc: ", sources[0].mirror->name, " 是 ", target, " 目前唯一可用镜像站,感谢他们的慷慨支持"));
|
{
|
||||||
}
|
xy_success(xy_strjoin(4, sources[0].mirror->name, " 是 ", target, " 目前唯一可用镜像站,感谢他们的慷慨支持"));
|
||||||
|
}
|
||||||
|
|
||||||
if (xy_streql("default", input) || xy_streql("def", input)) {
|
if (xy_streql("default", input) || xy_streql("def", input))
|
||||||
xy_info ("chsrc: 默认使用维护团队测速第一的源");
|
{
|
||||||
return 0;
|
puts ("默认使用维护团队测速第一的源");
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
SourceInfo source = sources[0];
|
SourceInfo source = sources[0];
|
||||||
|
|
||||||
bool exist = false;
|
bool exist = false;
|
||||||
for (int i=0; i<size; i++)
|
for (int i=0; i<size; i++)
|
||||||
{
|
{
|
||||||
source = sources[i];
|
source = sources[i];
|
||||||
if (xy_streql(source.mirror->code, input)) {
|
if (xy_streql(source.mirror->code, input))
|
||||||
idx = i;
|
{
|
||||||
exist = true;
|
idx = i;
|
||||||
break;
|
exist = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!exist)
|
||||||
|
{
|
||||||
|
xy_error (xy_strjoin(3, "镜像站 ", input, " 不存在"));
|
||||||
|
xy_error (xy_2strjoin("查看可使用源,请使用 chsrc list ", target));
|
||||||
|
exit (1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (!exist) {
|
|
||||||
xy_error (xy_strjoin(3, "chsrc: 镜像站 ", input, " 不存在"));
|
|
||||||
xy_error (xy_2strjoin("chsrc: 查看可使用源,请使用 chsrc list ", target));
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,26 +104,26 @@ query_mirror_exist (SourceInfo* sources, size_t size, char* target, char* input)
|
||||||
/**
|
/**
|
||||||
* 该函数来自 oh-my-mirrorz.py,由 @ccmywish 翻译为C语言,但功劳和版权属于原作者
|
* 该函数来自 oh-my-mirrorz.py,由 @ccmywish 翻译为C语言,但功劳和版权属于原作者
|
||||||
*/
|
*/
|
||||||
char*
|
char *
|
||||||
to_human_readable_speed (double speed)
|
to_human_readable_speed (double speed)
|
||||||
{
|
{
|
||||||
char* scale[] = {"Byte/s", "KByte/s", "MByte/s", "GByte/s", "TByte/s"};
|
char *scale[] = {"Byte/s", "KByte/s", "MByte/s", "GByte/s", "TByte/s"};
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (speed > 1024.0)
|
while (speed > 1024.0)
|
||||||
{
|
{
|
||||||
i += 1;
|
i += 1;
|
||||||
speed /= 1024.0;
|
speed /= 1024.0;
|
||||||
}
|
}
|
||||||
char* buf = xy_malloc0(64);
|
char *buf = xy_malloc0 (64);
|
||||||
sprintf(buf, "%.2f %s", speed, scale[i]);
|
sprintf (buf, "%.2f %s", speed, scale[i]);
|
||||||
|
|
||||||
char* new = NULL;
|
char *new = NULL;
|
||||||
if (i <= 1 ) new = xy_str_to_red(buf);
|
if (i <= 1 ) new = xy_str_to_red (buf);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (i == 2 && speed < 2.00) new = xy_str_to_yellow(buf);
|
if (i == 2 && speed < 2.00) new = xy_str_to_yellow (buf);
|
||||||
else new = xy_str_to_green(buf);
|
else new = xy_str_to_green (buf);
|
||||||
}
|
}
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,9 +135,9 @@ to_human_readable_speed (double speed)
|
||||||
* @return 返回测得的速度,若出错,返回-1
|
* @return 返回测得的速度,若出错,返回-1
|
||||||
*/
|
*/
|
||||||
double
|
double
|
||||||
test_speed_url (const char* url)
|
test_speed_url (const char *url)
|
||||||
{
|
{
|
||||||
char* time_sec = "6";
|
char *time_sec = "6";
|
||||||
|
|
||||||
/* 现在我们切换至跳转后的链接来测速,不再使用下述判断
|
/* 现在我们切换至跳转后的链接来测速,不再使用下述判断
|
||||||
if (xy_str_start_with(url, "https://registry.npmmirror"))
|
if (xy_str_start_with(url, "https://registry.npmmirror"))
|
||||||
|
@ -144,47 +149,52 @@ test_speed_url (const char* url)
|
||||||
|
|
||||||
// 我们用 —L,因为Ruby China源会跳转到其他地方
|
// 我们用 —L,因为Ruby China源会跳转到其他地方
|
||||||
// npmmirror 也会跳转
|
// npmmirror 也会跳转
|
||||||
char* curl_cmd = xy_strjoin(6, "curl -qsL -o ", xy_os_devnull,
|
char *curl_cmd = xy_strjoin (6, "curl -qsL -o ", xy_os_devnull,
|
||||||
" -w \"%{http_code} %{speed_download}\" -m", time_sec ,
|
" -w \"%{http_code} %{speed_download}\" -m", time_sec ,
|
||||||
" -A chsrc/" Chsrc_Version " ", url);
|
" -A chsrc/" Chsrc_Version " ", url);
|
||||||
|
|
||||||
// xy_info (xy_2strjoin("chsrc: 测速 ", url));
|
// xy_info (xy_2strjoin("chsrc: 测速 ", url));
|
||||||
|
|
||||||
char* buf = xy_getcmd (curl_cmd, 0, NULL);
|
char *buf = xy_getcmd (curl_cmd, 0, NULL);
|
||||||
// 如果尾部有换行,删除
|
// 如果尾部有换行,删除
|
||||||
buf = xy_str_strip (buf);
|
buf = xy_str_strip (buf);
|
||||||
|
|
||||||
// 分隔两部分数据
|
// 分隔两部分数据
|
||||||
char* split = strchr(buf, ' ');
|
char *split = strchr (buf, ' ');
|
||||||
if (split) *split = '\0';
|
if (split) *split = '\0';
|
||||||
|
|
||||||
// puts(buf); puts(split+1);
|
// puts(buf); puts(split+1);
|
||||||
int http_code = atoi(buf);
|
int http_code = atoi (buf);
|
||||||
double speed = atof(split+1);
|
double speed = atof (split+1);
|
||||||
char* speedstr = to_human_readable_speed(speed);
|
char *speedstr = to_human_readable_speed (speed);
|
||||||
|
|
||||||
if (200!=http_code) {
|
if (200!=http_code)
|
||||||
char* httpcodestr = xy_str_to_yellow (xy_2strjoin("HTTP码 ", buf));
|
{
|
||||||
puts (xy_strjoin (3, speedstr, " | ", httpcodestr));
|
char* httpcodestr = xy_str_to_yellow (xy_2strjoin ("HTTP码 ", buf));
|
||||||
} else {
|
puts (xy_strjoin (3, speedstr, " | ", httpcodestr));
|
||||||
puts (speedstr);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
puts (speedstr);
|
||||||
|
}
|
||||||
return speed;
|
return speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
get_max_ele_idx_in_dbl_ary (double* array, int size)
|
get_max_ele_idx_in_dbl_ary (double *array, int size)
|
||||||
{
|
{
|
||||||
double maxval = array[0];
|
double maxval = array[0];
|
||||||
int maxidx = 0;
|
int maxidx = 0;
|
||||||
|
|
||||||
for (int i=1; i<size; i++) {
|
for (int i=1; i<size; i++)
|
||||||
if (array[i]>maxval) {
|
{
|
||||||
maxval = array[i];
|
if (array[i]>maxval)
|
||||||
maxidx = i;
|
{
|
||||||
|
maxval = array[i];
|
||||||
|
maxidx = i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return maxidx;
|
return maxidx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,12 +203,13 @@ get_max_ele_idx_in_dbl_ary (double* array, int size)
|
||||||
*/
|
*/
|
||||||
#define auto_select(s) auto_select_(s##_sources, s##_sources_n, (char*)#s+3)
|
#define auto_select(s) auto_select_(s##_sources, s##_sources_n, (char*)#s+3)
|
||||||
int
|
int
|
||||||
auto_select_ (SourceInfo* sources, size_t size, const char* target)
|
auto_select_ (SourceInfo *sources, size_t size, const char *target)
|
||||||
{
|
{
|
||||||
if (0==size) {
|
if (0==size)
|
||||||
xy_error(xy_strjoin(3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
|
{
|
||||||
exit(1);
|
xy_error (xy_strjoin (3, "chsrc: 当前 ", target, " 无任何可用源,请联系维护者"));
|
||||||
}
|
exit (1);
|
||||||
|
}
|
||||||
|
|
||||||
bool onlyone = false;
|
bool onlyone = false;
|
||||||
if (1==size) onlyone = true;
|
if (1==size) onlyone = true;
|
||||||
|
@ -209,22 +220,25 @@ auto_select_ (SourceInfo* sources, size_t size, const char* target)
|
||||||
{
|
{
|
||||||
SourceInfo src = sources[i];
|
SourceInfo src = sources[i];
|
||||||
const char* url = src.mirror->__bigfile_url;
|
const char* url = src.mirror->__bigfile_url;
|
||||||
if (NULL==url) {
|
if (NULL==url)
|
||||||
chsrc_warn ( xy_strjoin(3, "开发者未提供 ", src.mirror->code, " 镜像站测速链接,跳过该站点"));
|
{
|
||||||
speed = 0;
|
chsrc_warn ( xy_strjoin(3, "开发者未提供 ", src.mirror->code, " 镜像站测速链接,跳过该站点"));
|
||||||
} else {
|
speed = 0;
|
||||||
printf ("%s",xy_strjoin(3, "chsrc: 测速 ", src.mirror->site , " ... "));
|
}
|
||||||
fflush(stdout);
|
else
|
||||||
speed = test_speed_url (url);
|
{
|
||||||
}
|
printf ("%s",xy_strjoin(3, "测速 ", src.mirror->site , " ... "));
|
||||||
|
fflush (stdout);
|
||||||
|
speed = test_speed_url (url);
|
||||||
|
}
|
||||||
speeds[i] = speed;
|
speeds[i] = speed;
|
||||||
}
|
}
|
||||||
int fastidx = get_max_ele_idx_in_dbl_ary (speeds, size);
|
int fastidx = get_max_ele_idx_in_dbl_ary (speeds, size);
|
||||||
|
|
||||||
if (onlyone)
|
if (onlyone)
|
||||||
xy_success(xy_strjoin(5, "chsrc: ", sources[fastidx].mirror->name, " 是 ", target, " 目前唯一可用镜像站,感谢他们的慷慨支持"));
|
xy_success (xy_strjoin (4, sources[fastidx].mirror->name, " 是 ", target, " 目前唯一可用镜像站,感谢他们的慷慨支持"));
|
||||||
else
|
else
|
||||||
xy_success (xy_2strjoin("chsrc: 最快镜像站: ", sources[fastidx].mirror->name));
|
puts (xy_2strjoin ("最快镜像站: ", xy_str_to_green (sources[fastidx].mirror->name)));
|
||||||
|
|
||||||
return fastidx;
|
return fastidx;
|
||||||
}
|
}
|
||||||
|
@ -239,16 +253,18 @@ auto_select_ (SourceInfo* sources, size_t size, const char* target)
|
||||||
* 用于 _setsrc 函数
|
* 用于 _setsrc 函数
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
chsrc_say_selection (SourceInfo* source)
|
chsrc_say_selection (SourceInfo *source)
|
||||||
{
|
{
|
||||||
xy_info (xy_strjoin(5, "chsrc: 选中镜像站: ", source->mirror->abbr, " (", source->mirror->code, ")"));
|
puts (xy_strjoin (5, "选中镜像站: ", xy_str_to_green (source->mirror->abbr), " (", xy_str_to_green (source->mirror->code), ")"));
|
||||||
|
// puts ("--------------------------------");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
chsrc_say_thanks (SourceInfo* source)
|
chsrc_say_thanks (SourceInfo *source)
|
||||||
{
|
{
|
||||||
xy_success(xy_2strjoin("chsrc: 感谢镜像提供方: ", source->mirror->name));
|
puts ("--------------------------------");
|
||||||
|
puts (xy_2strjoin ("换源完成,感谢镜像提供方: ", xy_str_to_purple (source->mirror->name)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,117 +272,135 @@ chsrc_say_thanks (SourceInfo* source)
|
||||||
void
|
void
|
||||||
chsrc_ensure_root ()
|
chsrc_ensure_root ()
|
||||||
{
|
{
|
||||||
char* euid = getenv("$EUID");
|
char *euid = getenv ("$EUID");
|
||||||
if (NULL==euid) {
|
if (NULL==euid)
|
||||||
char* buf = xy_getcmd("id -u", 0, NULL);
|
{
|
||||||
if (0!=atoi(buf)) goto not_root;
|
char *buf = xy_getcmd ("id -u", 0, NULL);
|
||||||
else return;
|
if (0!=atoi(buf)) goto not_root;
|
||||||
} else {
|
else return;
|
||||||
if (0!=atoi(euid)) goto not_root;
|
}
|
||||||
else return;
|
else
|
||||||
}
|
{
|
||||||
|
if (0!=atoi(euid)) goto not_root;
|
||||||
|
else return;
|
||||||
|
}
|
||||||
not_root:
|
not_root:
|
||||||
xy_error("chsrc: 请在命令前使用 sudo 来保证必要的权限");
|
xy_error ("chsrc: 请在命令前使用 sudo 来保证必要的权限");
|
||||||
exit(1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chsrc_run (const char* cmd)
|
chsrc_run (const char *cmd)
|
||||||
{
|
{
|
||||||
xy_info (xy_2strjoin ("chsrc: 运行 ", cmd));
|
puts ("~~~~~~~~~~~");
|
||||||
system(cmd);
|
puts (xy_2strjoin ("运行 ", xy_str_to_blue (cmd)));
|
||||||
|
system (cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chsrc_check_file (const char* path)
|
chsrc_check_file (const char *path)
|
||||||
{
|
{
|
||||||
char* cmd = NULL;
|
char *cmd = NULL;
|
||||||
path = xy_uniform_path (path);
|
path = xy_uniform_path (path);
|
||||||
if(xy_on_windows) {
|
if(xy_on_windows)
|
||||||
cmd = xy_2strjoin ("type ", path);
|
{
|
||||||
} else {
|
cmd = xy_2strjoin ("type ", path);
|
||||||
cmd = xy_2strjoin ("cat ", path);
|
}
|
||||||
}
|
else
|
||||||
|
{
|
||||||
|
cmd = xy_2strjoin ("cat ", path);
|
||||||
|
}
|
||||||
chsrc_run (cmd);
|
chsrc_run (cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chsrc_ensure_dir (const char* dir)
|
chsrc_ensure_dir (const char *dir)
|
||||||
{
|
{
|
||||||
dir = xy_uniform_path (dir);
|
dir = xy_uniform_path (dir);
|
||||||
char* mkdir_cmd = NULL;
|
char *mkdir_cmd = NULL;
|
||||||
if (xy_on_windows) {
|
if (xy_on_windows)
|
||||||
mkdir_cmd = "md ";
|
{
|
||||||
} else {
|
mkdir_cmd = "md ";
|
||||||
mkdir_cmd = "mkdir -p ";
|
}
|
||||||
}
|
else
|
||||||
char* cmd = xy_2strjoin (mkdir_cmd, dir);
|
{
|
||||||
|
mkdir_cmd = "mkdir -p ";
|
||||||
|
}
|
||||||
|
char *cmd = xy_2strjoin (mkdir_cmd, dir);
|
||||||
cmd = xy_str_to_quietcmd (cmd);
|
cmd = xy_str_to_quietcmd (cmd);
|
||||||
chsrc_run (cmd);
|
chsrc_run (cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chsrc_append_to_file (const char* str, const char* file)
|
chsrc_append_to_file (const char *str, const char *file)
|
||||||
{
|
{
|
||||||
file = xy_uniform_path (file);
|
file = xy_uniform_path (file);
|
||||||
char* dir = xy_parent_dir (file);
|
char *dir = xy_parent_dir (file);
|
||||||
chsrc_ensure_dir (dir);
|
chsrc_ensure_dir (dir);
|
||||||
|
|
||||||
char* cmd = NULL;
|
char *cmd = NULL;
|
||||||
if (xy_on_windows) {
|
if (xy_on_windows)
|
||||||
cmd = xy_strjoin (4, "echo ", str, " >> ", file);
|
{
|
||||||
} else {
|
cmd = xy_strjoin (4, "echo ", str, " >> ", file);
|
||||||
cmd = xy_strjoin (4, "echo '", str, "' >> ", file);
|
}
|
||||||
}
|
else
|
||||||
chsrc_run(cmd);
|
{
|
||||||
|
cmd = xy_strjoin (4, "echo '", str, "' >> ", file);
|
||||||
|
}
|
||||||
|
chsrc_run (cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chsrc_overwrite_file (const char* str, const char* file)
|
chsrc_overwrite_file (const char *str, const char *file)
|
||||||
{
|
{
|
||||||
file = xy_uniform_path (file);
|
file = xy_uniform_path (file);
|
||||||
char* dir = xy_parent_dir (file);
|
char *dir = xy_parent_dir (file);
|
||||||
chsrc_ensure_dir (dir);
|
chsrc_ensure_dir (dir);
|
||||||
|
|
||||||
char* cmd = NULL;
|
char *cmd = NULL;
|
||||||
if (xy_on_windows) {
|
if (xy_on_windows)
|
||||||
cmd = xy_strjoin (4, "echo ", str, " > ", file);
|
{
|
||||||
} else {
|
cmd = xy_strjoin (4, "echo ", str, " > ", file);
|
||||||
cmd = xy_strjoin (4, "echo '", str, "' > ", file);
|
}
|
||||||
}
|
else
|
||||||
chsrc_run(cmd);
|
{
|
||||||
|
cmd = xy_strjoin (4, "echo '", str, "' > ", file);
|
||||||
|
}
|
||||||
|
chsrc_run (cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
chsrc_backup (const char* path)
|
chsrc_backup (const char *path)
|
||||||
{
|
{
|
||||||
char* cmd = NULL;
|
char *cmd = NULL;
|
||||||
|
|
||||||
if (xy_on_bsd)
|
if (xy_on_bsd)
|
||||||
{
|
{
|
||||||
// 似乎BSD的cp并没有 --backup='t' 选项
|
// 似乎BSD的cp并没有 --backup='t' 选项
|
||||||
cmd = xy_strjoin(5, "cp -f ", path, " ", path, ".bak");
|
cmd = xy_strjoin (5, "cp -f ", path, " ", path, ".bak");
|
||||||
}
|
}
|
||||||
else if (xy_on_windows) {
|
else if (xy_on_windows)
|
||||||
// /Y 表示覆盖
|
{
|
||||||
cmd = xy_strjoin(5, "copy /Y ", path, " ", path, ".bak" );
|
// /Y 表示覆盖
|
||||||
}
|
cmd = xy_strjoin (5, "copy /Y ", path, " ", path, ".bak" );
|
||||||
else {
|
}
|
||||||
cmd = xy_strjoin(5, "cp ", path, " ", path, ".bak --backup='t'");
|
else
|
||||||
}
|
{
|
||||||
|
cmd = xy_strjoin (5, "cp ", path, " ", path, ".bak --backup='t'");
|
||||||
|
}
|
||||||
|
|
||||||
chsrc_run (cmd);
|
chsrc_run (cmd);
|
||||||
chsrc_info ( xy_strjoin (3, "备份文件名 ", path, ".bak"));
|
chsrc_info (xy_strjoin (3, "备份文件名 ", path, ".bak"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Target Info */
|
/* Target Info */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void (*setfn)(char* option);
|
void (*setfn)(char *option);
|
||||||
void (*getfn)(char* option);
|
void (*getfn)(char *option);
|
||||||
SourceInfo* sources;
|
SourceInfo *sources;
|
||||||
size_t sources_n;
|
size_t sources_n;
|
||||||
} TargetInfo;
|
} TargetInfo;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user