openssl3.2 - linux腳本(.sh)調(diào)用openssl命令行參數(shù)的簡(jiǎn)單確認(rèn)方法
概述
在琢磨官方工程中的/test/certs中的2個(gè)腳本(setup.sh, mkcert.sh)
這2個(gè)腳本有不到500個(gè)openssl命令行調(diào)用, 應(yīng)該是openssl內(nèi)部測(cè)試證書(shū)操作的腳本.
確定這2個(gè)腳本是好東西(將證書(shū)操作一網(wǎng)打盡, 弄清了這2個(gè)腳本, 就沒(méi)有不會(huì)的證書(shū)操作了).
但是腳本調(diào)用, 到了調(diào)用openssl時(shí), 參數(shù)拼接很煩人, 我只想看具體到了openssl的可執(zhí)行文件, 到底給了啥命令行參數(shù).
有一些參數(shù)是用管道給的, 用stdin給的一個(gè)buffer代表一個(gè)參數(shù)文件, 這很煩啊.
官方給用戶(hù)的正式例子, 都是用 in 參數(shù), 然后給一個(gè)文件名. 這樣多清爽.
.sh又不熟, 想將.sh改成可以傳文件名給openssl的例子, 可能要花多一些時(shí)間.
一直在琢磨是否有更好的方法能確定最終的openssl命令行參數(shù), 突然想到, 為啥不直接將openssl實(shí)現(xiàn)給改了, 在程序入口, 寫(xiě)幾句日志, 將命令行參數(shù)記錄下來(lái), 這不一了百了啊. 研究啥.sh怎么寫(xiě)啊.
只要確定給了啥命令行參數(shù), 那就好辦了.
我已經(jīng)編譯好了在windows下可用的VS2019的openssl.exe的工程, 那就在自己工程中, 舒舒服服的調(diào)試好了(openssl3.2 - 自己構(gòu)建openssl.exe的VS工程(在編譯完的源碼版本上), openssl3.2 - 在VS2019下源碼調(diào)試openssl.exe).
筆記
修改openssl實(shí)現(xiàn)的前置條件
已經(jīng)在debian12.4下, 配置, 編譯, 測(cè)試, 安裝都通過(guò)了.
且配置了debian12.4, 讓本地普通目錄中運(yùn)行openssl命令行已經(jīng)好使(openssl3.2 - 編譯).
修改debian12.4下編譯好的openssl實(shí)現(xiàn), 將入口參數(shù)記錄下來(lái)
參照我重建的win版openssl.exe工程, 可知 main()函數(shù)在openssl.c
去debian12.4下原版源碼目錄中確定是./apps/openssl.c
修改如下, 只在程序入口處, 加了一段日志文件的操作, 將openssl可執(zhí)行文件的命令行參數(shù)附加到日志文件.
static char *help_argv[] = { "help", NULL };
static char *version_argv[] = { "version", NULL };
int main(int argc, char *argv[])
{
FUNCTION f, *fp;
LHASH_OF(FUNCTION) *prog = NULL;
char *pname;
const char *fname;
ARGS arg;
int global_help = 0;
int global_version = 0;
int ret = 0;
int i = 0;
FILE* pfLog = NULL;
// 將入?yún)⑷繉?xiě)入文件待調(diào)試, 去看.sh太繁瑣了
if (1)
{
pfLog = fopen("/home/lostspeed/openssl/my_openssl_log.txt", "a");
if (NULL != pfLog)
{
for (i = 0; i < argc; i++)
{
fwrite(argv[i], sizeof(char), strlen(argv[i]), pfLog);
// 每個(gè)參數(shù)中間加一個(gè)空格
fwrite(" ", sizeof(char), 1, pfLog);
}
// 追加完一次openssl命令行調(diào)用, 換一行
fwrite("\r\n", sizeof(char), 2, pfLog);
fclose(pfLog);
pfLog = NULL;
}
}
arg.argv = NULL;
arg.size = 0;
在正常的工程中, 只進(jìn)行make, make install
測(cè)試效果
在普通目錄中運(yùn)行了2個(gè)命令
openssl version -a
openssl --help
查看自己指定的位置確實(shí)有日志文件.
lostspeed@debian12d4x64:~/openssl$ pwd
/home/lostspeed/openssl
lostspeed@debian12d4x64:~/openssl$ ls -l
總計(jì) 488136
-rw-r--r-- 1 lostspeed lostspeed 38 1月20日 22:29 my_openssl_log.txt
drwxr-xr-x 26 lostspeed lostspeed 4096 1月20日 21:13 openssl-3.2.0_debian
-rw-r--r-- 1 lostspeed lostspeed 482136966 1月20日 21:17 openssl-3.2.0_debian.tar.gz
-rwxr-xr-x 1 root root 17698352 1月20日 13:55 openssl-3.2.0.tar.gz
查看此日志文件
lostspeed@debian12d4x64:~/openssl$ cat ./my_openssl_log.txt
openssl version -a
openssl --help
lostspeed@debian12d4x64:~/openssl$
備注
這方法好使.
那我下一步就將setup.sh改成每次只執(zhí)行一個(gè)命令的版本. e.g. setup1.sh, setup2.sh.
知道了具體的命令行操作, 那么就可以去win版的openssl.exe工程去查, 將stdin給出的參數(shù)文件流內(nèi)容, 改為可以落地的參數(shù)和文件名.
那我也不用去改debian12.4下的那2個(gè).sh腳本了, 調(diào)試強(qiáng)度一下子就降低好多.
補(bǔ)充 - 將管道文件記錄到本地文件
腳本傳遞文件時(shí), 到了openssl入口, 可以看到傳進(jìn)來(lái)的是一個(gè)管道文件名.
openssl req -new -sha256 -key root-key.pem -config /dev/fd/63
需要將這個(gè)管道文件也保存到日志中, 這樣就知道了openssl命令行的所有參數(shù), 就可以在windows下的openssl.exe的vs2019中開(kāi)心的調(diào)試了.
將openssl.c又完善了一下, 對(duì)openssl.c的修改部分如下:
static char *help_argv[] = { "help", NULL };
static char *version_argv[] = { "version", NULL };
// /home/lostspeed/openssl/openssl-3.2.0_debian/test/certs/my_openssl_linux_log.txt
// D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs\\my_openssl_win_log.txt
#ifdef _WIN32
#define MY_LOG_DIR "D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs"
#define MY_LOG_FILE "my_openssl_win_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "\\" MY_LOG_FILE
#define MY_PIPE_FILE "cmd_line_pipe_in_win.txt"
#define MY_PIPE_FILE_OUT_PATH_NAME MY_LOG_DIR "\\" MY_PIPE_FILE
#else
// -config /dev/fd/63
#define MY_LOG_DIR "/home/lostspeed/openssl/openssl-3.2.0_debian/test/certs"
#define MY_LOG_FILE "my_openssl_linux_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "/" MY_LOG_FILE
#define MY_PIPE_FILE "cmd_line_pipe_in_linux.txt"
#define MY_PIPE_FILE_OUT_PATH_NAME MY_LOG_DIR "/" MY_PIPE_FILE
#endif // #ifdef _WIN32
void read_file_write_to_another(const char* pszFileSrc, const char* pszFileDst)
{
FILE* fpSrc = NULL;
FILE* fpDst = NULL;
char szBuf[4096];
size_t nRdBk = 0;
do {
if ((NULL == pszFileSrc) || (NULL == pszFileDst))
{
break;
}
fpSrc = fopen(pszFileSrc, "r");
if (NULL == fpSrc)
{
break;
}
fpDst = fopen(pszFileDst, "a");
if (NULL == fpDst)
{
break;
}
// 在向管道記錄文件附加新內(nèi)容之前, 在每個(gè)文件前面加3個(gè)空行, 可以區(qū)分出多個(gè)文件
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
do {
nRdBk = fread(szBuf, sizeof(char), sizeof(szBuf), fpSrc);
if (nRdBk <= 0)
{
break;
}
fwrite(szBuf, sizeof(char), nRdBk, fpDst);
} while (1);
} while (0);
if (NULL != fpSrc)
{
fclose(fpSrc);
fpSrc = NULL;
}
if (NULL != fpDst)
{
fclose(fpDst);
fpDst = NULL;
}
}
void wirte_cmd_line_param_to_log_file(int argc, char* argv[])
{
int i = 0;
FILE* pfLog = NULL;
const char* psz_argv = NULL;
// 將入?yún)⑷繉?xiě)入文件待調(diào)試, 去看.sh太繁瑣了
if (1)
{
// 將程序的命令行參數(shù)記錄進(jìn)日志文件
pfLog = fopen(MY_LOG_FILE_PATH_NAME, "a");
if (NULL != pfLog)
{
for (i = 0; i < argc; i++)
{
// 程序的名稱(chēng)都為"openssl"
psz_argv = ((0 != i) ? argv[i] : "openssl");
fwrite(psz_argv, sizeof(char), strlen(psz_argv), pfLog);
// 每個(gè)參數(shù)中間加一個(gè)空格
fwrite(" ", sizeof(char), 1, pfLog);
}
// 追加完一次openssl命令行調(diào)用, 換一行
fwrite("\r\n", sizeof(char), 2, pfLog);
fclose(pfLog);
pfLog = NULL;
}
// 將管道文件記錄進(jìn)配置文件
for (i = 0; i < argc; i++)
{
// -config /dev/fd/63
if (0 == strcmp(argv[i], "-config"))
{
if ((i + 1) < argc)
{
if (0 == strcmp(argv[i + 1], "/dev/fd/63"))
{
read_file_write_to_another(argv[i + 1], MY_PIPE_FILE_OUT_PATH_NAME);
}
}
break;
}
}
}
}
int main(int argc, char *argv[])
{
FUNCTION f, *fp;
LHASH_OF(FUNCTION) *prog = NULL;
char *pname;
const char *fname;
ARGS arg;
int global_help = 0;
int global_version = 0;
int ret = 0;
wirte_cmd_line_param_to_log_file(argc, argv);
arg.argv = NULL;
arg.size = 0;
修改后的openssl.c在windows下和debian12.4下是通用的. 編譯安裝后, 好使.
效果
lostspeed@debian12d4x64:~/openssl/openssl-3.2.0_debian/test/certs$ pwd
/home/lostspeed/openssl/openssl-3.2.0_debian/test/certs
lostspeed@debian12d4x64:~/openssl/openssl-3.2.0_debian/test/certs$ ls -l
總計(jì) 104
-rwxr-xr-x 1 lostspeed lostspeed 11679 1月21日 14:05 mkcert.sh
-rwxr-xr-x 1 lostspeed lostspeed 11679 1月21日 14:05 mkcert.sh.bk
-rwxr-xr-x 1 lostspeed lostspeed 111 1月21日 14:05 my_lib.sh
-rwxr-xr-x 1 lostspeed lostspeed 17315 1月21日 14:05 openssl.c
-rwxr-xr-x 1 lostspeed lostspeed 1704 1月21日 14:05 root-key.pem
-rwxr-xr-x 1 lostspeed lostspeed 388 1月21日 14:05 setup001.sh
-rwxr-xr-x 1 lostspeed lostspeed 23948 1月21日 14:05 setup.sh
-rwxr-xr-x 1 lostspeed lostspeed 23948 1月21日 14:05 setup.sh.bk
lostspeed@debian12d4x64:~/openssl/openssl-3.2.0_debian/test/certs$
lostspeed@debian12d4x64:~/openssl/openssl-3.2.0_debian/test/certs$ cat ./setup001.sh
#! /bin/bash
# \file setup001.sh
# printf "%s\n" "hello openssl"
# my_lib.sh fn_to_file <(printf "hello 1")
# ./my_lib.sh fn_to_file param1 param2
# fn_to_file()
#{
# printf ">> fn_to_file\n"
#
# printf "%s\n" "$@"
#}
# printf ">> setup001.sh\n"
# fn_to_file < <(printf "stdin to function\n")
# Primary root: root-cert
./mkcert.sh genroot "Root CA" root-key root-cert
exit 0
lostspeed@debian12d4x64:~/openssl/openssl-3.2.0_debian/test/certs$ ./setup001.sh
lostspeed@debian12d4x64:~/openssl/openssl-3.2.0_debian/test/certs$ ls -l
總計(jì) 112
-rw-r--r-- 1 lostspeed lostspeed 87 1月21日 14:13 cmd_line_pipe_in_linux.txt // 記錄管道輸入給命令行的配置文件
-rwxr-xr-x 1 lostspeed lostspeed 11679 1月21日 14:05 mkcert.sh
-rwxr-xr-x 1 lostspeed lostspeed 11679 1月21日 14:05 mkcert.sh.bk
-rwxr-xr-x 1 lostspeed lostspeed 111 1月21日 14:05 my_lib.sh
-rw-r--r-- 1 lostspeed lostspeed 64 1月21日 14:13 my_openssl_linux_log.txt // 記錄命令行的日志文件
-rwxr-xr-x 1 lostspeed lostspeed 17315 1月21日 14:05 openssl.c
-rwxr-xr-x 1 lostspeed lostspeed 1704 1月21日 14:05 root-key.pem // 干活后的輸出文件
-rwxr-xr-x 1 lostspeed lostspeed 388 1月21日 14:05 setup001.sh
-rwxr-xr-x 1 lostspeed lostspeed 23948 1月21日 14:05 setup.sh
-rwxr-xr-x 1 lostspeed lostspeed 23948 1月21日 14:05 setup.sh.bk
lostspeed@debian12d4x64:~/openssl/openssl-3.2.0_debian/test/certs$ cat ./my_openssl_linux_log.txt
openssl req -new -sha256 -key root-key.pem -config /dev/fd/63
lostspeed@debian12d4x64:~/openssl/openssl-3.2.0_debian/test/certs$ cat ./cmd_line_pipe_in_linux.txt
string_mask=utf8only
[req]
prompt = no
distinguished_name = dn
[dn]
CN = Root CA
備注
調(diào)試材料的準(zhǔn)備:
將cmd_line_pipe_in_linux.txt中的原來(lái)管道傳來(lái)的配置文件內(nèi)容保存成一個(gè)配置文件. e.g. tmp.cfg
將my_openssl_linux_log.txt 記錄的openssl命令行參數(shù)中的管道配置文件 /dev/fd/63 改為tmp.cfg
新的可以在本地單步調(diào)試的命令行為 : openssl req -new -sha256 -key root-key.pem -config tmp.cfg
這就可以正常單步調(diào)試了.
剩下的事情, 就是將官方原來(lái)的/test/certs/setup.sh中的不到500條證書(shū)操作命令, 全部整理成單條的腳本.
然后單獨(dú)運(yùn)行一條腳本, 得到一組openssl的命令行, 自己?jiǎn)尾礁幌? 知道了openssl對(duì)命令行參數(shù)的要求就行了.
一天搞50個(gè), 10天搞定:P
補(bǔ)充 - 要考慮到管道的讀
管道讀, 讀一個(gè)字節(jié), 管道里面少一個(gè)字節(jié).
如果想將管道中的東西保存成文件供調(diào)試用, 那么程序用的管道數(shù)據(jù)就沒(méi)有了.
想了一個(gè)解決方法, 我從管道讀出的內(nèi)容, 我是知道的. 將管道讀出的內(nèi)容保存成文件供調(diào)試.
然后再將自己讀出的buffer, 再寫(xiě)入管道. 模擬自己沒(méi)動(dòng)過(guò)管道的數(shù)據(jù)
試了一下好使, 不影響openssl自帶的功能.
#endif /* OPENSSL_NO_TRACE */
static char *help_argv[] = { "help", NULL };
static char *version_argv[] = { "version", NULL };
// /home/lostspeed/openssl/openssl-3.2.0_debian/test/certs/my_openssl_linux_log.txt
// D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs\\my_openssl_win_log.txt
#ifdef _WIN32
#define MY_LOG_DIR "D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs"
#define MY_LOG_FILE "my_openssl_win_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "\\" MY_LOG_FILE
#define MY_PIPE_FILE "cmd_line_pipe_in_win.txt"
#define MY_PIPE_FILE_OUT_PATH_NAME MY_LOG_DIR "\\" MY_PIPE_FILE
#else
// -config /dev/fd/63
#define MY_LOG_DIR "/home/lostspeed/openssl/openssl-3.2.0_debian/test/certs"
#define MY_LOG_FILE "my_openssl_linux_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "/" MY_LOG_FILE
#define MY_PIPE_FILE "cmd_line_pipe_in_linux.txt"
#define MY_PIPE_FILE_OUT_PATH_NAME MY_LOG_DIR "/" MY_PIPE_FILE
#endif // #ifdef _WIN32
void read_file_write_to_another(const char* pszFileSrc, const char* pszFileDst)
{
#define MY_BUFFER_SIZE (1024 * 1024)
FILE* fpSrc = NULL;
FILE* fpDst = NULL;
char* pSzBuf = NULL; // 開(kāi)個(gè)1MB的空間, 從管道中讀出來(lái)后, 保存進(jìn)文件, 再寫(xiě)進(jìn)管道, 這樣相當(dāng)于沒(méi)有動(dòng)管道
size_t nRdBk = 0;
size_t nWrBk = 0;
size_t nRdBkAll = 0;
do {
if ((NULL == pszFileSrc) || (NULL == pszFileDst))
{
break;
}
pSzBuf = malloc(MY_BUFFER_SIZE);
if (NULL == pSzBuf)
{
break;
}
fpSrc = fopen(pszFileSrc, "r");
if (NULL == fpSrc)
{
break;
}
fpDst = fopen(pszFileDst, "a");
if (NULL == fpDst)
{
break;
}
// 在向管道記錄文件附加新內(nèi)容之前, 在每個(gè)文件前面加3個(gè)空行, 可以區(qū)分出多個(gè)文件
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
nRdBkAll = 0;
do {
nRdBk = fread(pSzBuf + nRdBkAll, sizeof(char), 1024, fpSrc);
if (nRdBk <= 0)
{
break;
}
nWrBk = fwrite(pSzBuf, sizeof(char), nRdBk, fpDst);
if (nWrBk != nRdBk)
{
printf("error : write to fpDst => write to = %zu, return form write = %zu\n", nRdBk, nWrBk);
break;
}
nRdBkAll += nRdBk;
} while (1);
fclose(fpSrc); // 關(guān)掉源文件
// 管道讀之后, 指針挪動(dòng)了. 嘗試將指針移動(dòng)到管道開(kāi)頭
// fseek(fpSrc, 0, 0); // 不好使, 從管道中讀了東西后, 管道中的東西就沒(méi)有了
// 管道中的東西, 讀出來(lái)后, 就消失了, 再模擬將讀出來(lái)的東西, 寫(xiě)進(jìn)入試試. 模擬我沒(méi)動(dòng)管道中的東西
fpSrc = fopen(pszFileSrc, "w");
if (NULL == fpSrc)
{
break;
}
nRdBk = fwrite(pSzBuf, sizeof(char), nRdBkAll, fpSrc);
if (nRdBk != nRdBkAll)
{
printf("error : rewrite to pipe => nRdBkAll = %zu, nRdBk = %zu\n", nRdBkAll, nRdBk);
}
} while (0);
if (NULL != pSzBuf)
{
free(pSzBuf);
pSzBuf = NULL;
}
if (NULL != fpSrc)
{
fclose(fpSrc);
fpSrc = NULL;
}
if (NULL != fpDst)
{
fclose(fpDst);
fpDst = NULL;
}
}
void wirte_cmd_line_param_to_log_file(int argc, char* argv[])
{
int i = 0;
FILE* pfLog = NULL;
const char* psz_argv = NULL;
// 將入?yún)⑷繉?xiě)入文件待調(diào)試, 去看.sh太繁瑣了
if (1)
{
// 將程序的命令行參數(shù)記錄進(jìn)日志文件
pfLog = fopen(MY_LOG_FILE_PATH_NAME, "a");
if (NULL != pfLog)
{
for (i = 0; i < argc; i++)
{
// 程序的名稱(chēng)都為"openssl"
psz_argv = ((0 != i) ? argv[i] : "openssl");
fwrite(psz_argv, sizeof(char), strlen(psz_argv), pfLog);
// 每個(gè)參數(shù)中間加一個(gè)空格
fwrite(" ", sizeof(char), 1, pfLog);
}
// 追加完一次openssl命令行調(diào)用, 換一行
fwrite("\r\n", sizeof(char), 2, pfLog);
fclose(pfLog);
pfLog = NULL;
}
// 將管道文件記錄進(jìn)配置文件
for (i = 0; i < argc; i++)
{
// -config /dev/fd/63
if (0 == strcmp(argv[i], "-config"))
{
if ((i + 1) < argc)
{
if (0 == strcmp(argv[i + 1], "/dev/fd/63"))
{
read_file_write_to_another(argv[i + 1], MY_PIPE_FILE_OUT_PATH_NAME);
// 如果將管道指著移動(dòng)到管道的頭部還好使, 那就和未修改程序前相同
// 管道中的東西, 讀出來(lái)就沒(méi)有了, 不過(guò), 我已經(jīng)又將讀出來(lái)的東西, 又寫(xiě)回去了
// read_file_write_to_another(argv[i + 1], MY_PIPE_FILE_OUT_PATH_NAME);
}
}
break;
}
}
}
}
int main(int argc, char *argv[])
{
FUNCTION f, *fp;
LHASH_OF(FUNCTION) *prog = NULL;
char *pname;
const char *fname;
ARGS arg;
int global_help = 0;
int global_version = 0;
int ret = 0;
// 打印自己的版本號(hào)標(biāo)記
if ((2 == argc) && (0 == strcmp("-v", argv[1])))
{
printf("ls modify openSSL3.2.0_build_002 last build 2024/1/21 17:27:00\n");
}
wirte_cmd_line_param_to_log_file(argc, argv);
arg.argv = NULL;
arg.size = 0;
/* Set up some of the environment. */
bio_in = dup_bio_in(FORMAT_TEXT);
bio_out = dup_bio_out(FORMAT_TEXT);
bio_err = dup_bio_err(FORMAT_TEXT);
bug_fix - 補(bǔ)充-extfile時(shí)的管道
調(diào)試著, 發(fā)現(xiàn)有點(diǎn)不對(duì)勁.
看著官方.sh, 每個(gè)openssl命令行用管道傳進(jìn)來(lái)的東西都不應(yīng)該為空啊.
查了一下, 原來(lái)管道進(jìn)來(lái)時(shí), 前面參數(shù)是 -config 或者 -extfile, 這2個(gè)參數(shù)后面跟的才是管道名.
我看花眼了, 只處理了 -config后面的管道文件內(nèi)容記錄.
修正了一下.
static char *help_argv[] = { "help", NULL };
static char *version_argv[] = { "version", NULL };
// /home/lostspeed/openssl/openssl-3.2.0_debian/test/certs/my_openssl_linux_log.txt
// D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs\\my_openssl_win_log.txt
#ifdef _WIN32
#define MY_LOG_DIR "D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs"
#define MY_LOG_FILE "my_openssl_win_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "\\" MY_LOG_FILE
#define MY_PIPE_FILE "cmd_line_pipe_in_win.txt"
#define MY_PIPE_FILE_OUT_PATH_NAME MY_LOG_DIR "\\" MY_PIPE_FILE
#else
// -config /dev/fd/63
#define MY_LOG_DIR "/home/lostspeed/openssl/openssl-3.2.0_debian/test/certs"
#define MY_LOG_FILE "my_openssl_linux_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "/" MY_LOG_FILE
#define MY_PIPE_FILE "cmd_line_pipe_in_linux.txt"
#define MY_PIPE_FILE_OUT_PATH_NAME MY_LOG_DIR "/" MY_PIPE_FILE
#endif // #ifdef _WIN32
void read_file_write_to_another(const char* pszCfgName, const char* pszFileSrc, const char* pszFileDst)
{
#define MY_BUFFER_SIZE (1024 * 1024)
FILE* fpSrc = NULL;
FILE* fpDst = NULL;
char* pSzBuf = NULL; // 開(kāi)個(gè)1MB的空間, 從管道中讀出來(lái)后, 保存進(jìn)文件, 再寫(xiě)進(jìn)管道, 這樣相當(dāng)于沒(méi)有動(dòng)管道
size_t nRdBk = 0;
size_t nWrBk = 0;
size_t nRdBkAll = 0;
do {
if ((NULL == pszCfgName) || (NULL == pszFileSrc) || (NULL == pszFileDst))
{
break;
}
pSzBuf = malloc(MY_BUFFER_SIZE);
if (NULL == pSzBuf)
{
break;
}
fpSrc = fopen(pszFileSrc, "r");
if (NULL == fpSrc)
{
break;
}
fpDst = fopen(pszFileDst, "a");
if (NULL == fpDst)
{
break;
}
// 在向管道記錄文件附加新內(nèi)容之前, 在每個(gè)文件前面加3個(gè)空行, 可以區(qū)分出多個(gè)文件
fwrite("\r\n", sizeof(char), 2, fpDst);
fprintf(fpDst, "%s %s => %s\n", pszCfgName, pszFileSrc, pszFileDst); // tip msg
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
nRdBkAll = 0;
do {
nRdBk = fread(pSzBuf + nRdBkAll, sizeof(char), 1024, fpSrc);
if (nRdBk <= 0)
{
break;
}
nWrBk = fwrite(pSzBuf, sizeof(char), nRdBk, fpDst);
if (nWrBk != nRdBk)
{
printf("error : write to fpDst => write to = %zu, return form write = %zu\n", nRdBk, nWrBk);
break;
}
nRdBkAll += nRdBk;
} while (1);
fclose(fpSrc); // 關(guān)掉源文件
// 管道讀之后, 指針挪動(dòng)了. 嘗試將指針移動(dòng)到管道開(kāi)頭
// fseek(fpSrc, 0, 0); // 不好使, 從管道中讀了東西后, 管道中的東西就沒(méi)有了
// 管道中的東西, 讀出來(lái)后, 就消失了, 再模擬將讀出來(lái)的東西, 寫(xiě)進(jìn)入試試. 模擬我沒(méi)動(dòng)管道中的東西
fpSrc = fopen(pszFileSrc, "w");
if (NULL == fpSrc)
{
break;
}
nRdBk = fwrite(pSzBuf, sizeof(char), nRdBkAll, fpSrc);
if (nRdBk != nRdBkAll)
{
printf("error : rewrite to pipe => nRdBkAll = %zu, nRdBk = %zu\n", nRdBkAll, nRdBk);
}
} while (0);
if (NULL != pSzBuf)
{
free(pSzBuf);
pSzBuf = NULL;
}
if (NULL != fpSrc)
{
fclose(fpSrc);
fpSrc = NULL;
}
if (NULL != fpDst)
{
fclose(fpDst);
fpDst = NULL;
}
}
void wirte_cmd_line_param_to_log_file(int argc, char* argv[])
{
int i = 0;
FILE* pfLog = NULL;
const char* psz_argv = NULL;
// 將入?yún)⑷繉?xiě)入文件待調(diào)試, 去看.sh太繁瑣了
if (1)
{
// 將程序的命令行參數(shù)記錄進(jìn)日志文件
pfLog = fopen(MY_LOG_FILE_PATH_NAME, "a");
if (NULL != pfLog)
{
for (i = 0; i < argc; i++)
{
// 程序的名稱(chēng)都為"openssl"
psz_argv = ((0 != i) ? argv[i] : "openssl");
fwrite(psz_argv, sizeof(char), strlen(psz_argv), pfLog);
// 每個(gè)參數(shù)中間加一個(gè)空格
fwrite(" ", sizeof(char), 1, pfLog);
}
// 追加完一次openssl命令行調(diào)用, 換一行
fwrite("\r\n", sizeof(char), 2, pfLog);
fclose(pfLog);
pfLog = NULL;
}
// 將管道文件記錄進(jìn)配置文件
for (i = 0; i < argc; i++)
{
// -config /dev/fd/63
if (
(0 == strcmp(argv[i], "-config"))
|| (0 == strcmp(argv[i], "-extfile"))
)
{
if ((i + 1) < argc)
{
// if (0 == strcmp(argv[i + 1], "/dev/fd/63"))
{
read_file_write_to_another(argv[i], argv[i + 1], MY_PIPE_FILE_OUT_PATH_NAME);
// 如果將管道指著移動(dòng)到管道的頭部還好使, 那就和未修改程序前相同
// 管道中的東西, 讀出來(lái)就沒(méi)有了, 不過(guò), 我已經(jīng)又將讀出來(lái)的東西, 又寫(xiě)回去了
// read_file_write_to_another(argv[i + 1], MY_PIPE_FILE_OUT_PATH_NAME);
}
}
break;
}
}
}
}
int main(int argc, char *argv[])
{
FUNCTION f, *fp;
LHASH_OF(FUNCTION) *prog = NULL;
char *pname;
const char *fname;
ARGS arg;
int global_help = 0;
int global_version = 0;
int ret = 0;
// 打印自己的版本號(hào)標(biāo)記
if ((2 == argc) && (0 == strcmp("-v", argv[1])))
{
printf("ls modify openSSL3.2.0_build_003 last build 2024/1/22 10:23:00\n");
}
wirte_cmd_line_param_to_log_file(argc, argv);
arg.argv = NULL;
arg.size = 0;
修正 - 將日志文件改為一個(gè)文件
將openssl程序入口截取的到所有內(nèi)容都記錄到一個(gè)日志文件中, 否則調(diào)試時(shí)太不方便了.文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-812130.html
static char *help_argv[] = { "help", NULL };
static char *version_argv[] = { "version", NULL };
// /home/lostspeed/openssl/openssl-3.2.0_debian/test/certs/my_openssl_linux_log.txt
// D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs\\my_openssl_win_log.txt
// 將命令行和管道內(nèi)容都記錄到一個(gè)日志文件中, 方便調(diào)試
#ifdef _WIN32
#define MY_LOG_DIR "D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs"
#define MY_LOG_FILE "my_openssl_win_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "\\" MY_LOG_FILE
#else
// -config /dev/fd/63
#define MY_LOG_DIR "/home/lostspeed/openssl/openssl-3.2.0_debian/test/certs"
#define MY_LOG_FILE "my_openssl_linux_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "/" MY_LOG_FILE
#endif // #ifdef _WIN32
void read_file_write_to_another(const char* pszCfgName, const char* pszFileSrc, const char* pszFileDst)
{
#define MY_BUFFER_SIZE (1024 * 1024)
FILE* fpSrc = NULL;
FILE* fpDst = NULL;
char* pSzBuf = NULL; // 開(kāi)個(gè)1MB的空間, 從管道中讀出來(lái)后, 保存進(jìn)文件, 再寫(xiě)進(jìn)管道, 這樣相當(dāng)于沒(méi)有動(dòng)管道
size_t nRdBk = 0;
size_t nWrBk = 0;
size_t nRdBkAll = 0;
do {
if ((NULL == pszCfgName) || (NULL == pszFileSrc) || (NULL == pszFileDst))
{
break;
}
pSzBuf = malloc(MY_BUFFER_SIZE);
if (NULL == pSzBuf)
{
break;
}
fpSrc = fopen(pszFileSrc, "r");
if (NULL == fpSrc)
{
break;
}
fpDst = fopen(pszFileDst, "a");
if (NULL == fpDst)
{
break;
}
// 在向管道記錄文件附加新內(nèi)容之前, 在每個(gè)文件前面加3個(gè)空行, 可以區(qū)分出多個(gè)文件
fwrite("\r\n", sizeof(char), 2, fpDst);
fprintf(fpDst, "%s %s => %s\n", pszCfgName, pszFileSrc, pszFileDst); // tip msg
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
nRdBkAll = 0;
do {
nRdBk = fread(pSzBuf + nRdBkAll, sizeof(char), 1024, fpSrc);
if (nRdBk <= 0)
{
break;
}
nWrBk = fwrite(pSzBuf, sizeof(char), nRdBk, fpDst);
if (nWrBk != nRdBk)
{
printf("error : write to fpDst => write to = %zu, return form write = %zu\n", nRdBk, nWrBk);
break;
}
nRdBkAll += nRdBk;
} while (1);
fclose(fpSrc); // 關(guān)掉源文件
// 管道讀之后, 指針挪動(dòng)了. 嘗試將指針移動(dòng)到管道開(kāi)頭
// fseek(fpSrc, 0, 0); // 不好使, 從管道中讀了東西后, 管道中的東西就沒(méi)有了
// 管道中的東西, 讀出來(lái)后, 就消失了, 再模擬將讀出來(lái)的東西, 寫(xiě)進(jìn)入試試. 模擬我沒(méi)動(dòng)管道中的東西
fpSrc = fopen(pszFileSrc, "w");
if (NULL == fpSrc)
{
break;
}
nRdBk = fwrite(pSzBuf, sizeof(char), nRdBkAll, fpSrc);
if (nRdBk != nRdBkAll)
{
printf("error : rewrite to pipe => nRdBkAll = %zu, nRdBk = %zu\n", nRdBkAll, nRdBk);
}
} while (0);
if (NULL != pSzBuf)
{
free(pSzBuf);
pSzBuf = NULL;
}
if (NULL != fpSrc)
{
fclose(fpSrc);
fpSrc = NULL;
}
if (NULL != fpDst)
{
fclose(fpDst);
fpDst = NULL;
}
}
void wirte_cmd_line_param_to_log_file(int argc, char* argv[])
{
int i = 0;
FILE* pfLog = NULL;
const char* psz_argv = NULL;
// 將入?yún)⑷繉?xiě)入文件待調(diào)試, 去看.sh太繁瑣了
if (1)
{
// 將程序的命令行參數(shù)記錄進(jìn)日志文件
pfLog = fopen(MY_LOG_FILE_PATH_NAME, "a");
if (NULL != pfLog)
{
for (i = 0; i < argc; i++)
{
// 程序的名稱(chēng)都為"openssl"
psz_argv = ((0 != i) ? argv[i] : "openssl");
fwrite(psz_argv, sizeof(char), strlen(psz_argv), pfLog);
// 每個(gè)參數(shù)中間加一個(gè)空格
fwrite(" ", sizeof(char), 1, pfLog);
}
// 追加完一次openssl命令行調(diào)用, 換一行
fwrite("\r\n", sizeof(char), 2, pfLog);
fclose(pfLog);
pfLog = NULL;
}
// 將管道文件記錄進(jìn)配置文件
for (i = 0; i < argc; i++)
{
// -config /dev/fd/63
if (
(0 == strcmp(argv[i], "-config"))
|| (0 == strcmp(argv[i], "-extfile"))
)
{
if ((i + 1) < argc)
{
// if (0 == strcmp(argv[i + 1], "/dev/fd/63"))
{
read_file_write_to_another(argv[i], argv[i + 1], MY_LOG_FILE_PATH_NAME);
// 如果將管道指著移動(dòng)到管道的頭部還好使, 那就和未修改程序前相同
// 管道中的東西, 讀出來(lái)就沒(méi)有了, 不過(guò), 我已經(jīng)又將讀出來(lái)的東西, 又寫(xiě)回去了
// read_file_write_to_another(argv[i + 1], MY_PIPE_FILE_OUT_PATH_NAME);
}
}
break;
}
}
}
}
int main(int argc, char *argv[])
{
FUNCTION f, *fp;
LHASH_OF(FUNCTION) *prog = NULL;
char *pname;
const char *fname;
ARGS arg;
int global_help = 0;
int global_version = 0;
int ret = 0;
// 打印自己的版本號(hào)標(biāo)記
if ((2 == argc) && (0 == strcmp("-v", argv[1])))
{
printf("ls modify openSSL3.2.0_build_005 last build 2024/1/22 13:06:00\n");
}
wirte_cmd_line_param_to_log_file(argc, argv);
arg.argv = NULL;
arg.size = 0;
修正 - 需要考慮同一選項(xiàng)出現(xiàn)多次的情況
在調(diào)試官方腳本時(shí)發(fā)現(xiàn), 居然可以同一選項(xiàng)出現(xiàn)多次. e.g. -extfile 在有些腳本調(diào)用openssl時(shí), 一個(gè)命令行中出現(xiàn)了2次.
只能將選項(xiàng)從頭找到尾.文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-812130.html
static char *help_argv[] = { "help", NULL };
static char *version_argv[] = { "version", NULL };
// /home/lostspeed/openssl/openssl-3.2.0_debian/test/certs/my_openssl_linux_log.txt
// D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs\\my_openssl_win_log.txt
// 將命令行和管道內(nèi)容都記錄到一個(gè)日志文件中, 方便調(diào)試
#ifdef _WIN32
#define MY_LOG_DIR "D:\\my_dev\\my_local_git_prj\\study\\openSSL\\test_certs"
#define MY_LOG_FILE "my_openssl_win_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "\\" MY_LOG_FILE
#else
// -config /dev/fd/63
#define MY_LOG_DIR "/home/lostspeed/openssl/openssl-3.2.0_debian/test/certs"
#define MY_LOG_FILE "my_openssl_linux_log.txt"
#define MY_LOG_FILE_PATH_NAME MY_LOG_DIR "/" MY_LOG_FILE
#endif // #ifdef _WIN32
void read_file_write_to_another(const char* pszCfgName, const char* pszFileSrc, const char* pszFileDst)
{
#define MY_BUFFER_SIZE (1024 * 1024)
FILE* fpSrc = NULL;
FILE* fpDst = NULL;
char* pSzBuf = NULL; // 開(kāi)個(gè)1MB的空間, 從管道中讀出來(lái)后, 保存進(jìn)文件, 再寫(xiě)進(jìn)管道, 這樣相當(dāng)于沒(méi)有動(dòng)管道
size_t nRdBk = 0;
size_t nWrBk = 0;
size_t nRdBkAll = 0;
do {
if ((NULL == pszCfgName) || (NULL == pszFileSrc) || (NULL == pszFileDst))
{
break;
}
pSzBuf = malloc(MY_BUFFER_SIZE);
if (NULL == pSzBuf)
{
break;
}
fpSrc = fopen(pszFileSrc, "r");
if (NULL == fpSrc)
{
break;
}
fpDst = fopen(pszFileDst, "a");
if (NULL == fpDst)
{
break;
}
// 在向管道記錄文件附加新內(nèi)容之前, 在每個(gè)文件前面加3個(gè)空行, 可以區(qū)分出多個(gè)文件
fwrite("\r\n", sizeof(char), 2, fpDst);
fprintf(fpDst, "%s %s => %s\n", pszCfgName, pszFileSrc, pszFileDst); // tip msg
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
fwrite("\r\n", sizeof(char), 2, fpDst);
nRdBkAll = 0;
do {
nRdBk = fread(pSzBuf + nRdBkAll, sizeof(char), 1024, fpSrc);
if (nRdBk <= 0)
{
break;
}
nWrBk = fwrite(pSzBuf, sizeof(char), nRdBk, fpDst);
if (nWrBk != nRdBk)
{
printf("error : write to fpDst => write to = %zu, return form write = %zu\n", nRdBk, nWrBk);
break;
}
nRdBkAll += nRdBk;
} while (1);
fclose(fpSrc); // 關(guān)掉源文件
// 管道讀之后, 指針挪動(dòng)了. 嘗試將指針移動(dòng)到管道開(kāi)頭
// fseek(fpSrc, 0, 0); // 不好使, 從管道中讀了東西后, 管道中的東西就沒(méi)有了
// 管道中的東西, 讀出來(lái)后, 就消失了, 再模擬將讀出來(lái)的東西, 寫(xiě)進(jìn)入試試. 模擬我沒(méi)動(dòng)管道中的東西
fpSrc = fopen(pszFileSrc, "w");
if (NULL == fpSrc)
{
break;
}
nRdBk = fwrite(pSzBuf, sizeof(char), nRdBkAll, fpSrc);
if (nRdBk != nRdBkAll)
{
printf("error : rewrite to pipe => nRdBkAll = %zu, nRdBk = %zu\n", nRdBkAll, nRdBk);
}
} while (0);
if (NULL != pSzBuf)
{
free(pSzBuf);
pSzBuf = NULL;
}
if (NULL != fpSrc)
{
fclose(fpSrc);
fpSrc = NULL;
}
if (NULL != fpDst)
{
fclose(fpDst);
fpDst = NULL;
}
}
void wirte_cmd_line_param_to_log_file(int argc, char* argv[])
{
int i = 0;
FILE* pfLog = NULL;
const char* psz_argv = NULL;
// 將入?yún)⑷繉?xiě)入文件待調(diào)試, 去看.sh太繁瑣了
if (1)
{
// 將程序的命令行參數(shù)記錄進(jìn)日志文件
pfLog = fopen(MY_LOG_FILE_PATH_NAME, "a");
if (NULL != pfLog)
{
for (i = 0; i < argc; i++)
{
// 程序的名稱(chēng)都為"openssl"
psz_argv = ((0 != i) ? argv[i] : "openssl");
fwrite(psz_argv, sizeof(char), strlen(psz_argv), pfLog);
// 每個(gè)參數(shù)中間加一個(gè)空格
fwrite(" ", sizeof(char), 1, pfLog);
}
// 追加完一次openssl命令行調(diào)用, 換一行
fwrite("\r\n", sizeof(char), 2, pfLog);
fclose(pfLog);
pfLog = NULL;
}
// 將管道文件記錄進(jìn)配置文件
for (i = 0; i < argc; i++)
{
// -config /dev/fd/63
if (
(0 == strcmp(argv[i], "-config"))
|| (0 == strcmp(argv[i], "-extfile"))
)
{
if ((i + 1) < argc)
{
// if (0 == strcmp(argv[i + 1], "/dev/fd/63"))
{
read_file_write_to_another(argv[i], argv[i + 1], MY_LOG_FILE_PATH_NAME);
// 如果將管道指著移動(dòng)到管道的頭部還好使, 那就和未修改程序前相同
// 管道中的東西, 讀出來(lái)就沒(méi)有了, 不過(guò), 我已經(jīng)又將讀出來(lái)的東西, 又寫(xiě)回去了
// read_file_write_to_another(argv[i + 1], MY_PIPE_FILE_OUT_PATH_NAME);
}
}
// 這里不能break, 發(fā)現(xiàn)一個(gè)openssl命令行可以跟多個(gè) -extfile 選項(xiàng)
}
}
}
}
int main(int argc, char *argv[])
{
FUNCTION f, *fp;
LHASH_OF(FUNCTION) *prog = NULL;
char *pname;
const char *fname;
ARGS arg;
int global_help = 0;
int global_version = 0;
int ret = 0;
// 打印自己的版本號(hào)標(biāo)記
if ((2 == argc) && (0 == strcmp("-v", argv[1])))
{
printf("ls modify openSSL3.2.0_build_006 last build 2024/1/23 18:01:00\n");
}
wirte_cmd_line_param_to_log_file(argc, argv);
arg.argv = NULL;
arg.size = 0;
END
到了這里,關(guān)于openssl3.2 - linux腳本(.sh)調(diào)用openssl命令行參數(shù)的簡(jiǎn)單確認(rèn)方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!