278 lines
6.0 KiB
C++
278 lines
6.0 KiB
C++
/*
|
|
* This file is distributed as part of MaxScale. It is free
|
|
* software: you can redistribute it and/or modify it under the terms of the
|
|
* GNU General Public License as published by the Free Software Foundation,
|
|
* version 2.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Copyright MariaDB Corporation Ab 2014
|
|
*/
|
|
|
|
#include "maxadmin_operations.h"
|
|
|
|
int
|
|
connectMaxScale(char *hostname, char *port)
|
|
{
|
|
struct sockaddr_in addr;
|
|
int so;
|
|
int keepalive = 1;
|
|
|
|
if ((so = socket(AF_INET, SOCK_STREAM, 0)) < 0)
|
|
{
|
|
fprintf(stderr, "Unable to create socket: %s\n",
|
|
strerror(errno));
|
|
return -1;
|
|
}
|
|
memset(&addr, 0, sizeof addr);
|
|
addr.sin_family = AF_INET;
|
|
setipaddress(&addr.sin_addr, hostname);
|
|
addr.sin_port = htons(atoi(port));
|
|
if (connect(so, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
|
{
|
|
fprintf(stderr, "Unable to connect to MaxScale at %s, %s: %s\n",
|
|
hostname, port, strerror(errno));
|
|
close(so);
|
|
return -1;
|
|
}
|
|
if (setsockopt(so, SOL_SOCKET,
|
|
SO_KEEPALIVE, &keepalive , sizeof(keepalive )))
|
|
{
|
|
perror("setsockopt");
|
|
}
|
|
|
|
return so;
|
|
}
|
|
|
|
|
|
int
|
|
setipaddress(struct in_addr *a, char *p)
|
|
{
|
|
#ifdef __USE_POSIX
|
|
struct addrinfo *ai = NULL, hint;
|
|
int rc;
|
|
struct sockaddr_in * res_addr;
|
|
memset(&hint, 0, sizeof (hint));
|
|
|
|
hint.ai_socktype = SOCK_STREAM;
|
|
hint.ai_flags = AI_CANONNAME;
|
|
hint.ai_family = AF_INET;
|
|
|
|
if ((rc = getaddrinfo(p, NULL, &hint, &ai)) != 0)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
/* take the first one */
|
|
if (ai != NULL)
|
|
{
|
|
res_addr = (struct sockaddr_in *)(ai->ai_addr);
|
|
memcpy(a, &res_addr->sin_addr, sizeof(struct in_addr));
|
|
|
|
freeaddrinfo(ai);
|
|
|
|
return 1;
|
|
}
|
|
#else
|
|
struct hostent *h;
|
|
|
|
spinlock_acquire(&tmplock);
|
|
h = gethostbyname(p);
|
|
spinlock_release(&tmplock);
|
|
|
|
if (h == NULL)
|
|
{
|
|
if ((a->s_addr = inet_addr(p)) == -1)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* take the first one */
|
|
memcpy(a, h->h_addr, h->h_length);
|
|
|
|
return 1;
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
authMaxScale(int so, char *user, char *password)
|
|
{
|
|
char buf[20];
|
|
|
|
if (read(so, buf, 4) != 4)
|
|
{
|
|
return 0;
|
|
}
|
|
write(so, user, strlen(user));
|
|
if (read(so, buf, 8) != 8)
|
|
{
|
|
return 0;
|
|
}
|
|
write(so, password, strlen(password));
|
|
if (read(so, buf, 6) != 6)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return strncmp(buf, "FAILED", 6);
|
|
}
|
|
|
|
int
|
|
sendCommand(int so, char *cmd, char *buf)
|
|
{
|
|
char buf1[80];
|
|
int i, j, newline = 1;
|
|
int k = 0;
|
|
|
|
if (write(so, cmd, strlen(cmd)) == -1)
|
|
{
|
|
return 0;
|
|
}
|
|
while (1)
|
|
{
|
|
if ((i = read(so, buf1, 80)) <= 0)
|
|
{
|
|
return 0;
|
|
}
|
|
for (j = 0; j < i; j++)
|
|
{
|
|
if (newline == 1 && buf1[j] == 'O')
|
|
{
|
|
newline = 2;
|
|
}
|
|
else if (newline == 2 && buf1[j] == 'K' && j == i - 1)
|
|
{
|
|
return 1;
|
|
}
|
|
else if (newline == 2)
|
|
{
|
|
buf[k] = 'O';
|
|
k++;
|
|
buf[k] = buf1[j];
|
|
k++;
|
|
newline = 0;
|
|
}
|
|
else if (buf1[j] == '\n' || buf1[j] == '\r')
|
|
{
|
|
buf[k] = buf1[j];
|
|
k++;
|
|
newline = 1;
|
|
}
|
|
else
|
|
{
|
|
buf[k] = buf1[j];
|
|
k++;
|
|
newline = 0;
|
|
}
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
get_maxadmin_param_tcp(char * hostname, char *user, char *password, char * cmd, char *param, char *result)
|
|
{
|
|
|
|
char buf[10240];
|
|
char *port = (char *) "6603";
|
|
int so;
|
|
|
|
if ((so = connectMaxScale(hostname, port)) == -1)
|
|
{
|
|
return 1;
|
|
}
|
|
if (!authMaxScale(so, user, password))
|
|
{
|
|
fprintf(stderr, "Failed to connect to MaxScale. "
|
|
"Incorrect username or password.\n");
|
|
close(so);
|
|
return 1;
|
|
}
|
|
|
|
sendCommand(so, cmd, buf);
|
|
|
|
//printf("%s\n", buf);
|
|
|
|
char * x = strstr(buf, param);
|
|
if (x == NULL )
|
|
{
|
|
return 1;
|
|
}
|
|
//char f_field[100];
|
|
int param_len = strlen(param);
|
|
int cnt = 0;
|
|
while (x[cnt + param_len] != '\n')
|
|
{
|
|
result[cnt] = x[cnt + param_len];
|
|
cnt++;
|
|
}
|
|
result[cnt] = '\0';
|
|
//sprintf(f_field, "%s %%s", param);
|
|
//sscanf(x, f_field, result);
|
|
close(so);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
execute_maxadmin_command_tcp(char * hostname, char *user, char *password, char * cmd)
|
|
{
|
|
|
|
char buf[10240];
|
|
char *port = (char *) "6603";
|
|
int so;
|
|
|
|
if ((so = connectMaxScale(hostname, port)) == -1)
|
|
{
|
|
return 1;
|
|
}
|
|
if (!authMaxScale(so, user, password))
|
|
{
|
|
fprintf(stderr, "Failed to connect to MaxScale. "
|
|
"Incorrect username or password.\n");
|
|
close(so);
|
|
return 1;
|
|
}
|
|
|
|
sendCommand(so, cmd, buf);
|
|
|
|
close(so);
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
execute_maxadmin_command_print_tcp(char * hostname, char *user, char *password, char * cmd)
|
|
{
|
|
|
|
char buf[10240];
|
|
char *port = (char *) "6603";
|
|
int so;
|
|
|
|
if ((so = connectMaxScale(hostname, port)) == -1)
|
|
{
|
|
return 1;
|
|
}
|
|
if (!authMaxScale(so, user, password))
|
|
{
|
|
fprintf(stderr, "Failed to connect to MaxScale. "
|
|
"Incorrect username or password.\n");
|
|
close(so);
|
|
return 1;
|
|
}
|
|
|
|
sendCommand(so, cmd, buf);
|
|
printf("%s\n", buf);
|
|
close(so);
|
|
return 0;
|
|
}
|