46 #include <sys/select.h>
47 #include <sys/socket.h>
52 #include <sys/types.h>
55 #define SE_CLI_CMDLEN 6
57 static const char* cli_str =
"client";
66 fprintf(out,
"Usage: %s [<cmd>]\n",
"ods-signer");
67 fprintf(out,
"Simple command line interface to control the signer "
68 "engine daemon.\nIf no cmd is given, the tool is going "
69 "into interactive mode.\n\n");
70 fprintf(out,
"Supported options:\n");
71 fprintf(out,
" -c | --config <cfgfile> Read configuration from file.\n");
72 fprintf(out,
" -h | --help Show this help and exit.\n");
73 fprintf(out,
" -V | --version Show version and exit.\n");
74 fprintf(out,
"\nBSD licensed, see LICENSE in source package for "
76 fprintf(out,
"Version %s. Report bugs to <%s>.\n",
77 PACKAGE_VERSION, PACKAGE_BUGREPORT);
88 fprintf(out,
"%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
109 interface_run(FILE* fp,
int sockfd,
char* cmd)
117 int cmd_response = 0;
120 char buf[ODS_SE_MAXLINE];
127 FD_SET(fileno(fp), &rset);
129 FD_SET(sockfd, &rset);
130 maxfdp1 = max(fileno(fp), sockfd) + 1;
132 if (!cmd || cmd_written) {
134 ret = select(maxfdp1, &rset, NULL, NULL, NULL);
136 if (errno != EINTR && errno != EWOULDBLOCK) {
138 cli_str, strerror(errno));
148 FD_CLR(fileno(fp), &rset);
152 if (cmd && cmd_written && cmd_response) {
157 if (FD_ISSET(sockfd, &rset)) {
159 for (i=0; i < ODS_SE_MAXLINE; i++) {
162 buf[ODS_SE_MAXLINE-1] =
'\0';
165 if ((n = read(sockfd, buf, ODS_SE_MAXLINE)) <= 0) {
168 fprintf(stderr,
"error: %s\n", strerror(errno));
177 fprintf(stderr,
"signer engine terminated "
187 fprintf(stderr,
"not enough response data received "
205 for (written=0; written < n; written += ret) {
207 ret = (int) write(fileno(stdout), &buf[written], n-written);
210 fprintf(stderr,
"no write\n");
214 if (errno == EINTR || errno == EWOULDBLOCK) {
218 fprintf(stderr,
"\n\nwrite error: %s\n", strerror(errno));
222 if (written+ret > n) {
223 fprintf(stderr,
"\n\nwrite error: more bytes (%d) written "
224 "than required (%d)\n",
230 if (
ods_strcmp(buf, ODS_SE_STOP_RESPONSE) == 0 || cmd_response) {
231 fprintf(stdout,
"\n");
236 if (FD_ISSET(fileno(fp), &rset)) {
239 if (cmd && cmd_written) {
242 ret = shutdown(sockfd, SHUT_WR);
244 fprintf(stderr,
"shutdown failed: %s\n",
248 FD_CLR(fileno(fp), &rset);
253 for (i=0; i< ODS_SE_MAXLINE; i++) {
258 if ((n = read(fileno(fp), buf, ODS_SE_MAXLINE)) == 0) {
260 ret = shutdown(sockfd, SHUT_WR);
262 fprintf(stderr,
"shutdown failed: %s\n",
266 FD_CLR(fileno(fp), &rset);
270 buf[ODS_SE_MAXLINE-1] =
'\0';
271 if (strncmp(buf,
"exit", 4) == 0 ||
272 strncmp(buf,
"quit", 4) == 0) {
291 int sockfd, ret, flags;
292 struct sockaddr_un servaddr;
300 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
302 fprintf(stderr,
"Unable to connect to engine. "
303 "socket() failed: %s\n", strerror(errno));
308 bzero(&servaddr,
sizeof(servaddr));
309 servaddr.sun_family = AF_UNIX;
310 strncpy(servaddr.sun_path, servsock_filename,
311 sizeof(servaddr.sun_path) - 1);
314 ret = connect(sockfd, (
const struct sockaddr*) &servaddr,
318 size_t len = strlen(ODS_SE_ENGINE) + strlen(config->
cfg_filename) + 5;
320 (void) snprintf(start_cmd, len,
"%s -c %s", ODS_SE_ENGINE,
323 return system(start_cmd);
325 fprintf(stderr,
"Unable to start engine: cmd too long\n");
331 if (cmd &&
ods_strcmp(cmd,
"running\n") == 0) {
332 fprintf(stderr,
"Engine not running.\n");
334 fprintf(stderr,
"Unable to connect to engine: "
335 "connect() failed: %s\n", strerror(errno));
343 flags = fcntl(sockfd, F_GETFL, 0);
345 ods_log_error(
"[%s] unable to start interface, fcntl(F_GETFL) "
346 "failed: %s", cli_str, strerror(errno));
351 if (fcntl(sockfd, F_SETFL, flags) < 0) {
352 ods_log_error(
"[%s] unable to start interface, fcntl(F_SETFL) "
353 "failed: %s", cli_str, strerror(errno));
360 fprintf(stderr,
"cmd> ");
364 ret = interface_run(stdin, sockfd, cmd);
378 int options_size = 0;
379 int options_count = 0;
380 const char* options[10];
381 const char* cfgfile = ODS_SE_CFGFILE;
382 int cfgfile_expected = 0;
391 fprintf(stderr,
"error, too many arguments (%d)\n", argc);
394 for (c = 1; c < argc; c++) {
396 if (cfgfile_expected) {
398 cfgfile_expected = 0;
408 }
else if (!
ods_strcmp(argv[c],
"--version")) {
412 cfgfile_expected = 1;
413 }
else if (!
ods_strcmp(argv[c],
"--cfgfile")) {
414 cfgfile_expected = 1;
416 options[options_count] = argv[c];
417 options_size += strlen(argv[c]) + 1;
421 if (cfgfile_expected) {
422 fprintf(stderr,
"error, missing config file\n");
427 fprintf(stderr,
"error, malloc failed for client\n");
432 cmd = (
char*)
allocator_alloc(clialloc, (options_size+2)*
sizeof(char));
434 fprintf(stderr,
"error, memory allocation failed\n");
437 (void)strncpy(cmd,
"", 1);
438 for (c = 0; c < options_count; c++) {
439 (void)strncat(cmd, options[c], strlen(options[c]));
440 (void)strncat(cmd,
" ", 1);
442 cmd[options_size-1] =
'\n';
448 ods_log_error(
"[%s] cfgfile %s has errors", cli_str, cfgfile);
455 ret = interface_start(cmd, config);
void engine_config_cleanup(engineconfig_type *config)
const char * cfg_filename
void * allocator_alloc(allocator_type *allocator, size_t size)
enum ods_enum_status ods_status
void ods_log_error(const char *format,...)
int ods_strcmp(const char *s1, const char *s2)
const char * clisock_filename
engineconfig_type * engine_config(allocator_type *allocator, const char *cfgfile, int cmdline_verbosity)
void ods_str_trim(char *str)
allocator_type * allocator_create(void *(*allocator)(size_t size), void(*deallocator)(void *))
ssize_t ods_writen(int fd, const void *vptr, size_t n)
int main(int argc, char *argv[])
ods_status engine_config_check(engineconfig_type *config)
void allocator_cleanup(allocator_type *allocator)
void allocator_deallocate(allocator_type *allocator, void *data)
void ods_log_init(const char *filename, int use_syslog, int verbosity)
void ods_log_warning(const char *format,...)