Return error when receiving CLI packet
[multipath-tools/.git] / multipathd / uxclnt.c
1 /*
2  * Original author : tridge@samba.org, January 2002
3  *
4  * Copyright (c) 2005 Christophe Varoqui
5  * Copyright (c) 2005 Benjamin Marzinski, Redhat
6  */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <stdarg.h>
11 #include <fcntl.h>
12 #include <errno.h>
13 #include <sys/ioctl.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/un.h>
17 #include <sys/poll.h>
18 #include <readline/readline.h>
19 #include <readline/history.h>
20
21 #include <uxsock.h>
22 #include <memory.h>
23 #include <defaults.h>
24
25 #include <vector.h>
26 #include "cli.h"
27
28 static void print_reply(char *s)
29 {
30         if (isatty(1)) {
31                 printf("%s", s);
32                 return;
33         }
34         /* strip ANSI color markers */
35         while (*s != '\0') {
36                 if ((*s == 0x1b) && (*(s+1) == '['))
37                         while ((*s++ != 'm') && (*s != '\0')) {};
38                 putchar(*s++);
39         }
40 }
41
42 static int need_quit(char *str, size_t len)
43 {
44         char *ptr, *start;
45         size_t trimed_len = len;
46
47         for (ptr = str; trimed_len && isspace(*ptr);
48              trimed_len--, ptr++)
49                 ;
50
51         start = ptr;
52
53         for (ptr = str + len - 1; trimed_len && isspace(*ptr);
54              trimed_len--, ptr--)
55                 ;
56
57         if ((trimed_len == 4 && !strncmp(start, "exit", 4)) ||
58             (trimed_len == 4 && !strncmp(start, "quit", 4)))
59                 return 1;
60
61         return 0;
62 }
63
64 /*
65  * process the client
66  */
67 static void process(int fd, unsigned int timeout)
68 {
69         char *line;
70         char *reply;
71         int ret;
72
73         cli_init();
74         rl_readline_name = "multipathd";
75         rl_completion_entry_function = key_generator;
76         while ((line = readline("multipathd> "))) {
77                 size_t len;
78                 size_t llen = strlen(line);
79
80                 if (!llen) {
81                         free(line);
82                         continue;
83                 }
84
85                 if (need_quit(line, llen))
86                         break;
87
88                 if (send_packet(fd, line, llen + 1) != 0) break;
89                 ret = recv_packet(fd, &reply, &len, timeout);
90                 if (ret != 0) break;
91
92                 print_reply(reply);
93
94                 if (line && *line)
95                         add_history(line);
96
97                 free(line);
98                 FREE(reply);
99         }
100 }
101
102 static void process_req(int fd, char * inbuf, unsigned int timeout)
103 {
104         char *reply;
105         size_t len;
106         int ret;
107
108         if (send_packet(fd, inbuf, strlen(inbuf) + 1) != 0) {
109                 printf("cannot send packet\n");
110                 return;
111         }
112         ret = recv_packet(fd, &reply, &len, timeout);
113         if (ret < 0) {
114                 if (ret == -ETIMEDOUT)
115                         printf("timeout receiving packet\n");
116                 else
117                         printf("error %d receiving packet\n", ret);
118         } else {
119                 printf("%s", reply);
120                 FREE(reply);
121         }
122 }
123
124 /*
125  * entry point
126  */
127 int uxclnt(char * inbuf, unsigned int timeout)
128 {
129         int fd;
130
131         fd = ux_socket_connect(DEFAULT_SOCKET);
132         if (fd == -1)
133                 exit(1);
134
135         if (inbuf)
136                 process_req(fd, inbuf, timeout);
137         else
138                 process(fd, timeout);
139
140         return 0;
141 }