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