43 #include <sys/select.h> 44 #include <sys/socket.h> 49 #include <sys/types.h> 52 #define SE_CLI_CMDLEN 6 54 static const char* cli_str =
"client";
61 usage(
char* argv0, FILE* out)
63 fprintf(out,
"Usage: %s [<cmd>]\n", argv0);
64 fprintf(out,
"Simple command line interface to control the signer " 65 "engine daemon.\nIf no cmd is given, the tool is going " 66 "into interactive mode.\n");
67 fprintf(out,
"\nBSD licensed, see LICENSE in source package for " 69 fprintf(out,
"Version %s. Report bugs to <%s>.\n",
70 PACKAGE_VERSION, PACKAGE_BUGREPORT);
90 interface_run(FILE* fp,
int sockfd,
char* cmd)
101 char buf[ODS_SE_MAXLINE];
107 FD_SET(fileno(fp), &rset);
109 FD_SET(sockfd, &rset);
110 maxfdp1 = max(fileno(fp), sockfd) + 1;
112 if (!cmd || cmd_written) {
114 ret = select(maxfdp1, &rset, NULL, NULL, NULL);
116 if (errno != EINTR && errno != EWOULDBLOCK) {
117 ods_log_warning(
"[%s] interface select error: %s",
118 cli_str, strerror(errno));
124 ods_writen(sockfd, cmd, strlen(cmd));
128 FD_CLR(fileno(fp), &rset);
132 if (cmd && cmd_written && cmd_response) {
137 if (FD_ISSET(sockfd, &rset)) {
139 for (i=0; i < ODS_SE_MAXLINE; i++) {
142 buf[ODS_SE_MAXLINE-1] =
'\0';
145 if ((n = read(sockfd, buf, ODS_SE_MAXLINE)) <= 0) {
148 fprintf(stderr,
"error: %s\n", strerror(errno));
157 fprintf(stderr,
"signer engine terminated " 167 fprintf(stderr,
"not enough response data received " 185 for (written=0; written < n; written += ret) {
187 ret = (int) write(fileno(stdout), &buf[written], n-written);
190 fprintf(stderr,
"no write\n");
194 if (errno == EINTR || errno == EWOULDBLOCK) {
198 fprintf(stderr,
"\n\nwrite error: %s\n", strerror(errno));
202 if (written+ret > n) {
203 fprintf(stderr,
"\n\nwrite error: more bytes (%d) written " 204 "than required (%d)\n",
210 if (ods_strcmp(buf, ODS_SE_STOP_RESPONSE) == 0 || cmd_response) {
211 fprintf(stdout,
"\n");
216 if (FD_ISSET(fileno(fp), &rset)) {
219 if (cmd && cmd_written) {
222 ret = shutdown(sockfd, SHUT_WR);
224 fprintf(stderr,
"shutdown failed: %s\n",
228 FD_CLR(fileno(fp), &rset);
233 for (i=0; i< ODS_SE_MAXLINE; i++) {
238 if ((n = read(fileno(fp), buf, ODS_SE_MAXLINE)) == 0) {
240 ret = shutdown(sockfd, SHUT_WR);
242 fprintf(stderr,
"shutdown failed: %s\n",
246 FD_CLR(fileno(fp), &rset);
250 buf[ODS_SE_MAXLINE-1] =
'\0';
251 if (strncmp(buf,
"exit", 4) == 0 ||
252 strncmp(buf,
"quit", 4) == 0) {
255 ods_str_trim(buf, 1);
257 ods_writen(sockfd, buf, n);
269 interface_start(
char* cmd)
271 int sockfd, ret, flags;
272 struct sockaddr_un servaddr;
273 const char* servsock_filename = ODS_SE_SOCKFILE;
275 ods_log_init(
"ods-signerd", 0, NULL, 0);
278 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
280 fprintf(stderr,
"Unable to connect to engine. " 281 "socket() failed: %s\n", strerror(errno));
286 bzero(&servaddr,
sizeof(servaddr));
287 servaddr.sun_family = AF_UNIX;
288 strncpy(servaddr.sun_path, servsock_filename,
sizeof(servaddr.sun_path)-1);
291 ret = connect(sockfd, (
const struct sockaddr*) &servaddr,
294 if (cmd && ods_strcmp(cmd,
"start\n") == 0) {
296 if (system(ODS_SE_ENGINE)) {
297 fprintf(stderr,
"Failed to start signer engine\n");
303 if (cmd && ods_strcmp(cmd,
"running\n") == 0) {
304 fprintf(stderr,
"Engine not running.\n");
306 fprintf(stderr,
"Unable to connect to engine: " 307 "connect() failed: %s\n", strerror(errno));
315 flags = fcntl(sockfd, F_GETFL, 0);
317 ods_log_error(
"[%s] unable to start interface, fcntl(F_GETFL) " 318 "failed: %s", cli_str, strerror(errno));
323 if (fcntl(sockfd, F_SETFL, flags) < 0) {
324 ods_log_error(
"[%s] unable to start interface, fcntl(F_SETFL) " 325 "failed: %s", cli_str, strerror(errno));
332 fprintf(stderr,
"cmd> ");
336 ret = interface_run(stdin, sockfd, cmd);
350 int options_size = 0;
351 const char* options[5];
357 if((argv0 = strrchr(argv[0],
'/')) == NULL)
363 fprintf(stderr,
"error, too many arguments (%d)\n", argc);
368 for (c = 0; c < argc; c++) {
369 options[c] = argv[c];
371 options_size += strlen(argv[c]) + 1;
375 CHECKALLOC(cmd = (
char*) malloc((options_size+2)*
sizeof(
char)));
377 fprintf(stderr,
"memory allocation failed\n");
380 (void)strncpy(cmd,
"", 1);
381 for (c = 1; c < argc; c++) {
382 (void)strncat(cmd, options[c], strlen(options[c]));
383 (void)strncat(cmd,
" ", 1);
385 cmd[options_size-1] =
'\n';
389 if (cmd && ods_strcmp(cmd,
"-h\n") == 0) {
390 usage(argv0, stdout);
392 }
else if (cmd && ods_strcmp(cmd,
"--help\n") == 0) {
393 usage(argv0, stdout);
396 ret = interface_start(cmd);
int main(int argc, char *argv[])