multipathd: fix some small bugs for cli socket
[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 <poll.h>
18 #include <readline/readline.h>
19 #include <readline/history.h>
20
21 #include "mpath_cmd.h"
22 #include "uxsock.h"
23 #include "memory.h"
24 #include "defaults.h"
25
26 #include "vector.h"
27 #include "cli.h"
28
29 static void print_reply(char *s)
30 {
31         if (!s)
32                 return;
33
34         if (isatty(1)) {
35                 printf("%s", s);
36                 return;
37         }
38         /* strip ANSI color markers */
39         while (*s != '\0') {
40                 if ((*s == 0x1b) && (*(s+1) == '['))
41                         while ((*s++ != 'm') && (*s != '\0')) {};
42                 putchar(*s++);
43         }
44 }
45
46 static int need_quit(char *str, size_t len)
47 {
48         char *ptr, *start;
49         size_t trimed_len = len;
50
51         for (ptr = str; trimed_len && isspace(*ptr);
52              trimed_len--, ptr++)
53                 ;
54
55         start = ptr;
56
57         for (ptr = str + len - 1; trimed_len && isspace(*ptr);
58              trimed_len--, ptr--)
59                 ;
60
61         if ((trimed_len == 4 && !strncmp(start, "exit", 4)) ||
62             (trimed_len == 4 && !strncmp(start, "quit", 4)))
63                 return 1;
64
65         return 0;
66 }
67
68 /*
69  * process the client
70  */
71 static void process(int fd, unsigned int timeout)
72 {
73         char *line;
74         char *reply;
75         int ret;
76
77         cli_init();
78         rl_readline_name = "multipathd";
79         rl_completion_entry_function = key_generator;
80         while ((line = readline("multipathd> "))) {
81                 size_t llen = strlen(line);
82
83                 if (!llen) {
84                         free(line);
85                         continue;
86                 }
87
88                 if (need_quit(line, llen))
89                         break;
90
91                 if (send_packet(fd, line) != 0) break;
92                 ret = recv_packet(fd, &reply, timeout);
93                 if (ret != 0) break;
94
95                 print_reply(reply);
96
97                 if (line && *line)
98                         add_history(line);
99
100                 free(line);
101                 FREE(reply);
102         }
103 }
104
105 static void process_req(int fd, char * inbuf, unsigned int timeout)
106 {
107         char *reply;
108         int ret;
109
110         if (send_packet(fd, inbuf) != 0) {
111                 printf("cannot send packet\n");
112                 return;
113         }
114         ret = recv_packet(fd, &reply, timeout);
115         if (ret < 0) {
116                 if (ret == -ETIMEDOUT)
117                         printf("timeout receiving packet\n");
118                 else
119                         printf("error %d receiving packet\n", ret);
120         } else {
121                 printf("%s", reply);
122                 FREE(reply);
123         }
124 }
125
126 /*
127  * entry point
128  */
129 int uxclnt(char * inbuf, unsigned int timeout)
130 {
131         int fd;
132
133         fd = mpath_connect();
134         if (fd == -1)
135                 exit(1);
136
137         if (inbuf)
138                 process_req(fd, inbuf, timeout);
139         else
140                 process(fd, timeout);
141         mpath_disconnect(fd);
142         return 0;
143 }