如何根据命令行参数运行程序的不同“模式”?

时间:2014-12-26 18:46:58

标签: openssl command-line-arguments autosuggest

我正在研究Openssl的源代码,以了解程序员如何根据命令行参数运行不同的应用程序。例如:我可以运行openssl speed,它有自己的选项,我可以运行openssl s_server,它也有自己的选项,依此类推。这一切都像许多操作系统上的魅力。此外,Openssl还有一些我称之为“命令行建议”的内容。当我按下制表键时,它会建议可用的选项。

我正在研究源代码,但有任何线索如何在我的应用程序中实现类似的东西。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

  

程序员如何根据命令行参数运行不同的应用程序。

这些在OpenSSL中称为子命令。它们包括s_cients_serverdigestencdecx509speed等。

  

有什么想法吗?

OpenSSL为main命令和所有子命令提供了一个openssl。子命令中的main包含在宏中,因此如果构建openssl命令,则子命令可以成为自己的独立程序。

以下是宏的使用方式。所有子命令都执行此操作:

int MAIN(int, char **);

int MAIN(int argc, char **argv)
    {
        ...
    }

OpenSSL知道它包含所有带有openssl命令的子命令的时间,并定义MONOLITH来关闭子命令中的mains

来自apps.h

#ifndef MONOLITH

#define MAIN(a,v)   main(a,v)

#ifndef NON_MAIN
CONF *config=NULL;
BIO *bio_err=NULL;
#else
extern CONF *config;
extern BIO *bio_err;
#endif

#else

#define MAIN(a,v)   PROG(a,v)
extern CONF *config;
extern char *default_config_file;
extern BIO *bio_err;

#endif

如果您构建了独立的子命令,那么您还需要构建apps.c并链接到apps.o,因为它们是共同的。

如果我没记错的话,PROG在使用预处理器魔术定义prog_xxx时展开MONOLITH之类的内容,其中xxx是相关的子命令。所以它们看起来像一堆函数:prog_s_cientprog_s_serverprog_digest等。


$ cd apps
$ grep -R MAIN *
app_rand.c:#define NON_MAIN
app_rand.c:#undef NON_MAIN
apps.c:#define NON_MAIN
apps.c:#undef NON_MAIN
apps.h:#define MAIN(a,v)    main(a,v)
apps.h:#ifndef NON_MAIN
apps.h:#define MAIN(a,v)    PROG(a,v)
asn1pars.c:int MAIN(int, char **);
asn1pars.c:int MAIN(int argc, char **argv)
ca.c:int MAIN(int, char **);
ca.c:int MAIN(int argc, char **argv)
ciphers.c:int MAIN(int, char **);
ciphers.c:int MAIN(int argc, char **argv)
cms.c:int MAIN(int, char **);
cms.c:int MAIN(int argc, char **argv)
crl.c:int MAIN(int, char **);
crl.c:int MAIN(int argc, char **argv)
crl2p7.c:int MAIN(int, char **);
crl2p7.c:int MAIN(int argc, char **argv)
dgst.c:int MAIN(int, char **);
dgst.c:int MAIN(int argc, char **argv)
dh.c:int MAIN(int, char **);
dh.c:int MAIN(int argc, char **argv)
dhparam.c:int MAIN(int, char **);
dhparam.c:int MAIN(int argc, char **argv)
dsa.c:int MAIN(int, char **);
dsa.c:int MAIN(int argc, char **argv)
dsaparam.c:int MAIN(int, char **);
dsaparam.c:int MAIN(int argc, char **argv)
ec.c:int MAIN(int, char **);
ec.c:int MAIN(int argc, char **argv)
ecparam.c:int MAIN(int, char **);
ecparam.c:int MAIN(int argc, char **argv)
enc.c:int MAIN(int, char **);
enc.c:int MAIN(int argc, char **argv)
engine.c:int MAIN(int, char **);
engine.c:int MAIN(int argc, char **argv)
errstr.c:int MAIN(int, char **);
errstr.c:int MAIN(int argc, char **argv)
gendh.c:int MAIN(int, char **);
gendh.c:int MAIN(int argc, char **argv)
gendsa.c:int MAIN(int, char **);
gendsa.c:int MAIN(int argc, char **argv)
genpkey.c:int MAIN(int, char **);
genpkey.c:int MAIN(int argc, char **argv)
genrsa.c:int MAIN(int, char **);
genrsa.c:int MAIN(int argc, char **argv)
nseq.c:int MAIN(int, char **);
nseq.c:int MAIN(int argc, char **argv)
ocsp.c:int MAIN(int, char **);
ocsp.c:int MAIN(int argc, char **argv)
passwd.c:int MAIN(int, char **);
passwd.c:int MAIN(int argc, char **argv)
passwd.c:int MAIN(int argc, char **argv)
pkcs12.c:int MAIN(int, char **);
pkcs12.c:int MAIN(int argc, char **argv)
pkcs7.c:int MAIN(int, char **);
pkcs7.c:int MAIN(int argc, char **argv)
pkcs8.c:int MAIN(int, char **);
pkcs8.c:int MAIN(int argc, char **argv)
pkey.c:int MAIN(int, char **);
pkey.c:int MAIN(int argc, char **argv)
pkeyparam.c:int MAIN(int, char **);
pkeyparam.c:int MAIN(int argc, char **argv)
pkeyutl.c:int MAIN(int argc, char **);
pkeyutl.c:int MAIN(int argc, char **argv)
prime.c:int MAIN(int, char **);
prime.c:int MAIN(int argc, char **argv)
rand.c:int MAIN(int, char **);
rand.c:int MAIN(int argc, char **argv)
req.c:int MAIN(int, char **);
req.c:int MAIN(int argc, char **argv)
rsa.c:int MAIN(int, char **);
rsa.c:int MAIN(int argc, char **argv)
rsautl.c:int MAIN(int argc, char **);
rsautl.c:int MAIN(int argc, char **argv)
s_cb.c:#define NON_MAIN
s_cb.c:#undef NON_MAIN
s_client.c:int MAIN(int, char **);
s_client.c:int MAIN(int argc, char **argv)
s_server.c:int MAIN(int, char **);
s_server.c:int MAIN(int argc, char *argv[])
s_socket.c:#define NON_MAIN
s_socket.c:#undef NON_MAIN
s_time.c: * MAIN - main processing area for client
s_time.c:int MAIN(int, char **);
s_time.c:int MAIN(int argc, char **argv)
sess_id.c:int MAIN(int, char **);
sess_id.c:int MAIN(int argc, char **argv)
smime.c:int MAIN(int, char **);
smime.c:int MAIN(int argc, char **argv)
speed.c:int MAIN(int, char **);
speed.c:int MAIN(int argc, char **argv)
spkac.c:int MAIN(int, char **);
spkac.c:int MAIN(int argc, char **argv)
srp.c:int MAIN(int, char **);
srp.c:int MAIN(int argc, char **argv)
ts.c:int MAIN(int, char **);
ts.c:int MAIN(int argc, char **argv)
verify.c:int MAIN(int, char **);
verify.c:int MAIN(int argc, char **argv)
version.c:int MAIN(int, char **);
version.c:int MAIN(int argc, char **argv)
x509.c:int MAIN(int, char **);
x509.c:int MAIN(int argc, char **argv)