Add libmpathcmd library and use it internally
[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 <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 (isatty(1)) {
32                 printf("%s", s);
33                 return;
34         }
35         /* strip ANSI color markers */
36         while (*s != '\0') {
37                 if ((*s == 0x1b) && (*(s+1) == '['))
38                         while ((*s++ != 'm') && (*s != '\0')) {};
39                 putchar(*s++);
40         }
41 }
42
43 static int need_quit(char *str, size_t len)
44 {
45         char *ptr, *start;
46         size_t trimed_len = len;
47
48         for (ptr = str; trimed_len && isspace(*ptr);
49              trimed_len--, ptr++)
50                 ;
51
52         start = ptr;
53
54         for (ptr = str + len - 1; trimed_len && isspace(*ptr);
55              trimed_len--, ptr--)
56                 ;
57
58         if ((trimed_len == 4 && !strncmp(start, "exit", 4)) ||
59             (trimed_len == 4 && !strncmp(start, "quit", 4)))
60                 return 1;
61
62         return 0;
63 }
64
65 /*
66  * process the client
67  */
68 static void process(int fd, unsigned int timeout)
69 {
70         char *line;
71         char *reply;
72         int ret;
73
74         cli_init();
75         rl_readline_name = "multipathd";
76         rl_completion_entry_function = key_generator;
77         while ((line = readline("multipathd> "))) {
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) != 0) break;
89                 ret = recv_packet(fd, &reply, 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         int ret;
106
107         if (send_packet(fd, inbuf) != 0) {
108                 printf("cannot send packet\n");
109                 return;
110         }
111         ret = recv_packet(fd, &reply, timeout);
112         if (ret < 0) {
113                 if (ret == -ETIMEDOUT)
114                         printf("timeout receiving packet\n");
115                 else
116                         printf("error %d receiving packet\n", ret);
117         } else {
118                 printf("%s", reply);
119                 FREE(reply);
120         }
121 }
122
123 /*
124  * entry point
125  */
126 int uxclnt(char * inbuf, unsigned int timeout)
127 {
128         int fd;
129
130         fd = mpath_connect();
131         if (fd == -1)
132                 exit(1);
133
134         if (inbuf)
135                 process_req(fd, inbuf, timeout);
136         else
137                 process(fd, timeout);
138
139         return 0;
140 }