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 (FD_ISSET(sockfd, &rset)) {
154 for (i=0; i < ODS_SE_MAXLINE; i++) {
157 buf[ODS_SE_MAXLINE-1] =
'\0';
160 if ((n = read(sockfd, buf, ODS_SE_MAXLINE)) <= 0) {
163 fprintf(stderr,
"error: %s\n", strerror(errno));
172 fprintf(stderr,
"signer engine terminated "
182 fprintf(stderr,
"not enough response data received "
200 for (written=0; written < n; written += ret) {
202 ret = (int) write(fileno(stdout), &buf[written], n-written);
205 fprintf(stderr,
"no write\n");
209 if (errno == EINTR || errno == EWOULDBLOCK) {
213 fprintf(stderr,
"\n\nwrite error: %s\n", strerror(errno));
217 if (written+ret > n) {
218 fprintf(stderr,
"\n\nwrite error: more bytes (%d) written "
219 "than required (%d)\n",
225 if (
ods_strcmp(buf, ODS_SE_STOP_RESPONSE) == 0 || cmd_response) {
226 fprintf(stdout,
"\n");
231 if (FD_ISSET(fileno(fp), &rset)) {
234 if (cmd && cmd_written) {
237 ret = shutdown(sockfd, SHUT_WR);
239 fprintf(stderr,
"shutdown failed: %s\n",
243 FD_CLR(fileno(fp), &rset);
248 for (i=0; i< ODS_SE_MAXLINE; i++) {
253 if ((n = read(fileno(fp), buf, ODS_SE_MAXLINE)) == 0) {
255 ret = shutdown(sockfd, SHUT_WR);
257 fprintf(stderr,
"shutdown failed: %s\n",
261 FD_CLR(fileno(fp), &rset);
265 buf[ODS_SE_MAXLINE-1] =
'\0';
266 if (strncmp(buf,
"exit", 4) == 0 ||
267 strncmp(buf,
"quit", 4) == 0) {
286 int sockfd, ret, flags;
287 struct sockaddr_un servaddr;
295 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
297 fprintf(stderr,
"Unable to connect to engine. "
298 "socket() failed: %s\n", strerror(errno));
303 bzero(&servaddr,
sizeof(servaddr));
304 servaddr.sun_family = AF_UNIX;
305 strncpy(servaddr.sun_path, servsock_filename,
306 sizeof(servaddr.sun_path) - 1);
309 ret = connect(sockfd, (
const struct sockaddr*) &servaddr,
313 size_t len = strlen(ODS_SE_ENGINE) + strlen(config->
cfg_filename) + 5;
315 (void) snprintf(start_cmd, len,
"%s -c %s", ODS_SE_ENGINE,
318 return system(start_cmd);
320 fprintf(stderr,
"Unable to start engine: cmd too long\n");
326 if (cmd &&
ods_strcmp(cmd,
"running\n") == 0) {
327 fprintf(stderr,
"Engine not running.\n");
329 fprintf(stderr,
"Unable to connect to engine: "
330 "connect() failed: %s\n", strerror(errno));
338 flags = fcntl(sockfd, F_GETFL, 0);
340 ods_log_error(
"[%s] unable to start interface, fcntl(F_GETFL) "
341 "failed: %s", cli_str, strerror(errno));
346 if (fcntl(sockfd, F_SETFL, flags) < 0) {
347 ods_log_error(
"[%s] unable to start interface, fcntl(F_SETFL) "
348 "failed: %s", cli_str, strerror(errno));
355 fprintf(stderr,
"cmd> ");
359 ret = interface_run(stdin, sockfd, cmd);
373 int options_size = 0;
374 int options_count = 0;
375 const char* options[10];
376 const char* cfgfile = ODS_SE_CFGFILE;
377 int cfgfile_expected = 0;
386 fprintf(stderr,
"error, too many arguments (%d)\n", argc);
389 for (c = 1; c < argc; c++) {
391 if (cfgfile_expected) {
393 cfgfile_expected = 0;
403 }
else if (!
ods_strcmp(argv[c],
"--version")) {
407 cfgfile_expected = 1;
408 }
else if (!
ods_strcmp(argv[c],
"--cfgfile")) {
409 cfgfile_expected = 1;
411 options[options_count] = argv[c];
412 options_size += strlen(argv[c]) + 1;
416 if (cfgfile_expected) {
417 fprintf(stderr,
"error, missing config file\n");
422 fprintf(stderr,
"error, malloc failed for client\n");
427 cmd = (
char*)
allocator_alloc(clialloc, (options_size+2)*
sizeof(char));
429 fprintf(stderr,
"error, memory allocation failed\n");
432 (void)strncpy(cmd,
"", 1);
433 for (c = 0; c < options_count; c++) {
434 (void)strncat(cmd, options[c], strlen(options[c]));
435 (void)strncat(cmd,
" ", 1);
437 cmd[options_size-1] =
'\n';
443 ods_log_error(
"[%s] cfgfile %s has errors", cli_str, cfgfile);
450 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,...)