Files
openbts/apps/OpenBTSCLI.cpp
Kurtis Heimerl 5289a229d9 sync of openbts
git-svn-id: http://wush.net/svn/range/software/public/openbts/trunk@6168 19bc5d8c-e614-43d4-8b26-e1612bc8e597
2013-08-14 00:52:14 +00:00

191 lines
4.8 KiB
C++

/*
* Copyright 2011, 2012 Range Networks, Inc.
*
* This software is distributed under the terms of the GNU Affero Public License.
* See the COPYING file in the main directory for details.
*
* This use of this software may be subject to additional restrictions.
* See the LEGAL file in the main directory for details.
This program 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, either version 2 of the License, or
(at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// KEEP THIS FILE CLEAN FOR GPL PUBLIC RELEASE.
#include <config.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <time.h>
#define HAVE_LIBREADLINE
#ifdef HAVE_LIBREADLINE
# include <readline/readline.h>
# include <readline/history.h>
#endif
#define DEFAULT_CMD_PATH "/var/run/command"
#define DEFAULT_RSP_PATH "./response"
int main(int argc, char *argv[])
{
printf("OpenBTS Commnd Line Interface (CLI) utility\n");
printf("Copyright 2012, 2013 Range Networks, Inc.\n");
printf("Licensed under GPLv2.\n");
#ifdef HAVE_LIBREADLINE
printf("Includes libreadline, GPLv2.\n");
#endif
const char* cmdPath = DEFAULT_CMD_PATH;
if (argc!=1) {
cmdPath = argv[1];
}
char rspPath[200];
sprintf(rspPath,"/tmp/OpenBTS.console.%d.%8lx",getpid(),time(NULL));
printf("command socket path is %s\n", cmdPath);
char prompt[strlen(cmdPath) + 20];
sprintf(prompt,"OpenBTS> ");
// the socket
int sock = socket(AF_UNIX,SOCK_DGRAM,0);
if (sock<0) {
perror("opening datagram socket");
exit(1);
}
// destination address
struct sockaddr_un cmdSockName;
cmdSockName.sun_family = AF_UNIX;
strcpy(cmdSockName.sun_path,cmdPath);
// locally bound address
struct sockaddr_un rspSockName;
rspSockName.sun_family = AF_UNIX;
char rmcmd[strlen(rspPath)+10];
sprintf(rmcmd,"rm -f %s",rspPath);
system(rmcmd);
strcpy(rspSockName.sun_path,rspPath);
if (bind(sock, (struct sockaddr *) &rspSockName, sizeof(struct sockaddr_un))) {
perror("binding name to datagram socket");
exit(1);
}
printf("response socket bound to %s\n",rspSockName.sun_path);
#ifdef HAVE_LIBREADLINE
// start console
using_history();
static const char * const history_file_name = "/.openbts_history";
char *history_name = 0;
char *home_dir = getenv("HOME");
if(home_dir) {
size_t home_dir_len = strlen(home_dir);
size_t history_file_len = strlen(history_file_name);
size_t history_len = home_dir_len + history_file_len + 1;
if(history_len > home_dir_len) {
if(!(history_name = (char *)malloc(history_len))) {
perror("malloc failed");
exit(2);
}
memcpy(history_name, home_dir, home_dir_len);
memcpy(history_name + home_dir_len, history_file_name,
history_file_len + 1);
read_history(history_name);
}
}
#endif
printf("Remote Interface Ready.\nType:\n \"help\" to see commands,\n \"version\" for version information,\n \"notices\" for licensing information.\n \"quit\" to exit console interface\n");
while (1) {
#ifdef HAVE_LIBREADLINE
char *cmd = readline(prompt);
if (!cmd) break;
if (*cmd) add_history(cmd);
#else // HAVE_LIBREADLINE
printf("%s",prompt);
fflush(stdout);
char *inbuf = (char*)malloc(200);
char *cmd = fgets(inbuf,199,stdin);
if (!cmd) continue;
// strip trailing CR
cmd[strlen(cmd)-1] = '\0';
#endif
// local quit?
if (strcmp(cmd,"quit")==0) {
printf("closing remote console\n");
break;
}
// shell escape?
if (cmd[0]=='!') {
system(cmd+1);
continue;
}
// use the socket
if (sendto(sock,cmd,strlen(cmd)+1,0,(struct sockaddr*)&cmdSockName,sizeof(cmdSockName))<0) {
perror("sending datagram");
printf("Is the remote application running?\n");
continue;
}
free(cmd);
const int bufsz = 100000;
char resbuf[bufsz];
int nread = recv(sock,resbuf,bufsz-1,0);
if (nread<0) {
perror("receiving response");
continue;
}
resbuf[nread] = '\0';
printf("%s\n",resbuf);
if (nread==(bufsz-1)) printf("(response truncated at %d characters)\n",nread);
}
#ifdef HAVE_LIBREADLINE
if(history_name) {
int e = write_history(history_name);
if(e) {
fprintf(stderr, "error: history: %s\n", strerror(e));
}
free(history_name);
history_name = 0;
}
#endif
close(sock);
// Delete the path to limit clutter in /tmp.
sprintf(rmcmd,"rm -f %s",rspPath);
system(rmcmd);
}