- Fix: avoid infinite loop on mulitcast read thread if no data to read

Pre-ci test passed

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4000 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
Cedric Roux
2013-06-25 09:05:02 +00:00
commit 56c66c09aa
4111 changed files with 2133103 additions and 0 deletions
+348
View File
@@ -0,0 +1,348 @@
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2011 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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 St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file cli.c
* \brief oai main cli core
* \author Navid Nikaein
* \date 2011
* \version 0.1
* \warning This component can be runned only in user-space
* @ingroup util
*/
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <ctype.h>
#include "cli.h"
extern cli_config *cli_cfg;
command commands[] = {
{0, "help",NULL,com_help, NULL,"Display this text" },
{0, "?",NULL,com_help, NULL, "help at any point" },
{2, "prompt",NULL,prompt, prompt_usage,"Set/get cli prompt" },
{2, "info",NULL,info, NULL,"get software information" },
{1, "start",NULL,start, start_usage,"Start eNB/UE instance" },
{1, "set",NULL,set, set_usage,"set log for a give component" },
{0, "exit",NULL,com_exit, NULL,"Exit using OpenAir CLI Interface" },
{0, (char *)NULL,NULL, NULL,NULL, (char *)NULL }
};
static uid_t real_uid;
void priv_init(void) {
real_uid = getuid();
}
void priv_up(void) {
if (seteuid(0) != 0) {
printf("[CLI] Error setting uid to %d\n", real_uid);
}
}
void priv_down(void) {
if (seteuid(real_uid) != 0) {
printf("[CLI] Error setting uid to %d\n", 0);
}
}
int cli_start(void) {
priv_init();
priv_down();
putenv("REMADDR=");
// get username
if ((username = getlogin()) == NULL) {
username = getenv("USER");
}
set_permissions_map();
// set login info
cli_login(username, CLI_MAX_NODES, CLI_MAX_CMDS);
// send welcome msg to the client
sprintf(buffer, "%s", WELCOME_MSG);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
printf(WELCOME_MSG);
printf("[CLI] started...\n");
sprintf(cli_cfg->prompt,"%s%c ", cli_prompt(), cli_cfg->promptchar);
send(cli_cfg->cfd,cli_cfg->prompt, strlen(cli_cfg->prompt), 0);
return 1;
}
int cli_loop(char * msg) {
char *s;
/* Remove leading and trailing whitespace from the line.
Then, if there is anything left, add it to the history list
and execute it. */
s = stripwhite(msg);
if (*s) {
//add_history(s);
execute_line(s);
}
send(cli_cfg->cfd, cli_cfg->prompt, strlen(cli_cfg->prompt), 0);
return 0;
}
/**
* The permissions map is a bit map which defines which modes are available
* to a user. The permissions groups map to linux groups in the following
* way: subtract 1000. The remainder is the bit number.
* Thus unix groups 1000, 1001, 1002 etc represent the permissions groups
* default, config and admin respectively.
*
*/
int set_permissions_map(void) {
gid_t group[10];
int n, i;
int perm_num;
// get the number of supplementary group IDs
n = getgroups(10, group);
// give show permissions even if user has none
map_permissions = ADMIN_PERMISSION;
for (i=0; i<n; i++) {
perm_num = group[i] - 1000;
if (perm_num < 0 || perm_num > 31) {
continue;
}
//map_permissions |= (1 << perm_num);
map_permissions |= ((1 << (perm_num+1)) - 1);
}
printf("[CLI] Permissions %04x for this session\n", map_permissions);
return 0;
}
int cli_login(const char *username, int maxnodes, int maxcmds) {
cli_set_prompt_char();
printf("[CLI] Client initialised\n");
// log the connection
// telnets use REMADDR
host = getenv("REMADDR");
if (host) {
snprintf(g_sid, MAX_SID, "%s#%s", username, host);
printf("[CLI] login via telnet by user %s from address %s\n", username, host);
} else {
host = getenv("SSH_CLIENT");
if (host) {
char *cp;
// format is <rem_addr> <rem_port> <local_port>
// replace first space with ':', second terminates the string
cp = strchr(host, ' ');
if (cp) {
*cp = ':';
}
cp = strchr(host, ' ');
if (cp) {
*cp = '\0';
}
snprintf(g_sid, MAX_SID, "%s$%s", username, host);
printf("[CLI] login via SSH by user %s from address %s", username, host);
} else {
host = getenv("HOST");
if (host) {
snprintf(g_sid, MAX_SID, "%s$%s", username, host);
printf("[CLI] by user %s from host %s", username, host);
} else {
printf("[CLI]Login by user %s from unknown destination\n", username);
}
}
}
//register an exit function
atexit(cli_finish);
return 0;
}
char *cli_prompt(void) {
static char promptstr[200];
promptstr[0]='\0';
snprintf(promptstr, 200,"%s@%s",username, cli_cfg->prompt);
return promptstr;
}
int cli_set_prompt_char(void) {
if (map_permissions & ADMIN_PERMISSION) {
cli_cfg->promptchar = '#';
} else if (map_permissions & CONFIG_PERMISSION) {
cli_cfg->promptchar = '%';
} else if (map_permissions & SHOW_PERMISSION) {
cli_cfg->promptchar = '$';
}
return 0;
}
void cli_finish(void) {
char *cp;
if ((cp = strchr(g_sid, '#'))) {
*cp = '\0';
printf("[CLI] logout via telnet by user %s from address %s\n", g_sid, cp+1);
} else if ((cp = strchr(g_sid, '$'))) {
*cp = '\0';
printf("[CLI] logout via SSH by user %s from address %s\n", g_sid, cp+1);
} else {
printf("[CLI] logout from %s\n", g_sid);
}
return;
}
/* Execute a command line. */
int execute_line (char *line) {
register int i;
command *command;
char *word;
/* Isolate the command word. */
i = 0;
while (line[i] && whitespace (line[i]))
i++;
word = line + i;
while (line[i] && !whitespace (line[i]))
i++;
if (line[i])
line[i++] = '\0';
command = find_command(word);
if (!command) {
sprintf(buffer, "%s: %s \n", word, NOCOMMAND_MSG);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
printf("[CLI] commnad %s does not exist !\n", word);
return (-1);
}
/* Get argument to command, if any. */
while (whitespace (line[i]))
i++;
word = line + i;
/* Call the function. */
return ((*(command->func)) (word));
}
/* Look up NAME as the name of a command, and return a pointer to that
command. Return a NULL pointer if NAME isn't a command name. */
command * find_command (char *name) {
register int i;
for (i = 0; commands[i].name; i++){
if (strcmp (name, commands[i].name) == 0)
return (&commands[i]);
}
return ((command *)NULL);
}
/* Strip whitespace from the start and end of STRING. Return a pointer
into STRING. */
char * stripwhite (char *string) {
register char *s, *t;
for (s = string; whitespace (*s); s++)
;
if (*s == 0)
return (s);
t = s + strlen (s) - 1;
while (t > s && whitespace (*t))
t--;
*++t = '\0';
return s;
}
/* Generator function for command completion. STATE lets us know whether
to start from scratch; without any state (i.e. STATE == 0), then we
start at the top of the list. */
/* Print out help for ARG, or for all of the commands if ARG is
not present. */
int com_help (char *arg) {
register int i;
int printed = 0;
for (i = 0; commands[i].name != NULL; i++){
// if (!*arg || (strcmp (arg, commands[i].name) == 0)){
sprintf (buffer,"%s\t\t<%s>\n", commands[i].name, commands[i].doc);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
printed++;
// }
}
if (!printed) {
printf("No commands match `%s'. Possibilties are:\n", arg);
for (i = 0; commands[i].name; i++){
/* Print in six columns. */
if (printed == 6) {
printed = 0;
printf("\n");
}
printf("%s\t", commands[i].name);
printed++;
}
if (printed)
printf("\n");
}
return (0);
}
int whitespace (char c) {
return (isspace((int)c));
}