290 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			290 lines
		
	
	
		
			6.2 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;
 | |
|     }
 | |
|     int len;
 | |
|     len = strlen(user);
 | |
|     if (write(so, user, len) != len)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
|     if (read(so, buf, 8) != 8)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
|     len = strlen(password);
 | |
|     if (write(so, password, len) != len)
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
|     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;
 | |
| }
 | 
