| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-01-21 07:06:25 +00:00
										 |  |  |  * Copyright (C) 1999 - 2005, Digium, Inc. | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2004-08-27 03:28:32 +00:00
										 |  |  |  * Mark Spencer <markster@digium.com> | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  |  * This program is free software, distributed under the terms of | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Doxygenified Copyright Header */ | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |  * \mainpage Asterisk -- An Open Source Telephony Toolkit | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-11-14 19:00:38 +00:00
										 |  |  |  * \par Developer Documentation for Asterisk | 
					
						
							|  |  |  |  * This is the main developer documentation for Asterisk. It is  | 
					
						
							|  |  |  |  * generated by running "make progdocs". | 
					
						
							|  |  |  |  * \par Additional documentation | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  |  * \arg \ref DevDoc  | 
					
						
							|  |  |  |  * \arg \ref ConfigFiles | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \section copyright Copyright and author | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Copyright (C) 1999 - 2005, Digium, Inc. | 
					
						
							|  |  |  |  * Asterisk is a trade mark registered by Digium, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \author Mark Spencer <markster@digium.com> | 
					
						
							|  |  |  |  * Also see \ref AstCREDITS | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \section license License | 
					
						
							|  |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  |  * This program is free software, distributed under the terms of | 
					
						
							|  |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * \verbinclude LICENSE | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*! \file
 | 
					
						
							|  |  |  |   \brief Top level source file for Asterisk  - the Open Source PBX. Implementation | 
					
						
							|  |  |  |   of PBX core functions and CLI interface. | 
					
						
							|  |  |  |    | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-29 17:24:58 +00:00
										 |  |  | #include <sys/time.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-22 13:11:34 +00:00
										 |  |  | #include <fcntl.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <signal.h>
 | 
					
						
							|  |  |  | #include <sched.h>
 | 
					
						
							|  |  |  | #include <sys/socket.h>
 | 
					
						
							|  |  |  | #include <sys/un.h>
 | 
					
						
							|  |  |  | #include <sys/wait.h>
 | 
					
						
							|  |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							|  |  |  | #include <ctype.h>
 | 
					
						
							|  |  |  | #include <sys/resource.h>
 | 
					
						
							|  |  |  | #include <grp.h>
 | 
					
						
							|  |  |  | #include <pwd.h>
 | 
					
						
							|  |  |  | #include <sys/stat.h>
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | #include <regex.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-22 13:11:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-14 18:49:37 +00:00
										 |  |  | #ifdef linux
 | 
					
						
							|  |  |  | #include <sys/prctl.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-22 13:11:34 +00:00
										 |  |  | #if  defined(__FreeBSD__) || defined( __NetBSD__ ) || defined(SOLARIS)
 | 
					
						
							|  |  |  | #include <netdb.h>
 | 
					
						
							| 
									
										
										
										
											2006-03-02 22:27:50 +00:00
										 |  |  | #if defined(SOLARIS)
 | 
					
						
							|  |  |  | extern int daemon(int, int);  /* defined in libresolv of all places */ | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-04-22 13:11:34 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 03:04:58 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 22:12:19 +00:00
										 |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/logger.h"
 | 
					
						
							|  |  |  | #include "asterisk/options.h"
 | 
					
						
							|  |  |  | #include "asterisk/cli.h"
 | 
					
						
							|  |  |  | #include "asterisk/channel.h"
 | 
					
						
							|  |  |  | #include "asterisk/ulaw.h"
 | 
					
						
							|  |  |  | #include "asterisk/alaw.h"
 | 
					
						
							|  |  |  | #include "asterisk/callerid.h"
 | 
					
						
							|  |  |  | #include "asterisk/module.h"
 | 
					
						
							|  |  |  | #include "asterisk/image.h"
 | 
					
						
							|  |  |  | #include "asterisk/tdd.h"
 | 
					
						
							|  |  |  | #include "asterisk/term.h"
 | 
					
						
							|  |  |  | #include "asterisk/manager.h"
 | 
					
						
							| 
									
										
										
										
											2005-06-03 01:42:31 +00:00
										 |  |  | #include "asterisk/cdr.h"
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/pbx.h"
 | 
					
						
							|  |  |  | #include "asterisk/enum.h"
 | 
					
						
							|  |  |  | #include "asterisk/rtp.h"
 | 
					
						
							| 
									
										
										
										
											2006-01-12 17:14:58 +00:00
										 |  |  | #if defined(T38_SUPPORT)
 | 
					
						
							|  |  |  | #include "asterisk/udptl.h"
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/app.h"
 | 
					
						
							|  |  |  | #include "asterisk/lock.h"
 | 
					
						
							|  |  |  | #include "asterisk/utils.h"
 | 
					
						
							|  |  |  | #include "asterisk/file.h"
 | 
					
						
							|  |  |  | #include "asterisk/io.h"
 | 
					
						
							|  |  |  | #include "asterisk/lock.h"
 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | #include "editline/histedit.h"
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/config.h"
 | 
					
						
							| 
									
										
										
										
											2005-06-06 03:04:58 +00:00
										 |  |  | #include "asterisk/version.h"
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | #include "asterisk/linkedlists.h"
 | 
					
						
							| 
									
										
										
										
											2005-07-08 21:14:34 +00:00
										 |  |  | #include "asterisk/devicestate.h"
 | 
					
						
							| 
									
										
										
										
											2005-11-08 04:13:19 +00:00
										 |  |  | #include "asterisk/compat.h"
 | 
					
						
							| 
									
										
										
										
											2005-06-06 03:04:58 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | #include "asterisk/doxyref.h"		/* Doxygen documentation */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 03:04:58 +00:00
										 |  |  | #include "defaults.h"
 | 
					
						
							| 
									
										
										
										
											2004-04-28 13:53:01 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | #ifndef AF_LOCAL
 | 
					
						
							|  |  |  | #define AF_LOCAL AF_UNIX
 | 
					
						
							|  |  |  | #define PF_LOCAL PF_UNIX
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | #define AST_MAX_CONNECTS 128
 | 
					
						
							|  |  |  | #define NUM_MSGS 64
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-14 19:00:38 +00:00
										 |  |  | /*! \brief Welcome message when starting a CLI interface */ | 
					
						
							| 
									
										
										
										
											2005-12-23 03:04:38 +00:00
										 |  |  | #define WELCOME_MESSAGE \
 | 
					
						
							| 
									
										
										
										
											2006-01-17 13:13:31 +00:00
										 |  |  | 	ast_verbose("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2006 Digium, Inc. and others.\n"); \ | 
					
						
							| 
									
										
										
										
											2005-12-23 03:04:38 +00:00
										 |  |  | 	ast_verbose("Created by Mark Spencer <markster@digium.com>\n"); \ | 
					
						
							|  |  |  | 	ast_verbose("Asterisk comes with ABSOLUTELY NO WARRANTY; type 'show warranty' for details.\n"); \ | 
					
						
							|  |  |  | 	ast_verbose("This is free software, with components licensed under the GNU General Public\n"); \ | 
					
						
							|  |  |  | 	ast_verbose("License version 2 and other licenses; you are welcome to redistribute it under\n"); \ | 
					
						
							|  |  |  | 	ast_verbose("certain conditions. Type 'show license' for details.\n"); \ | 
					
						
							|  |  |  | 	ast_verbose("=========================================================================\n") | 
					
						
							| 
									
										
										
										
											2004-06-25 21:14:03 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-14 19:00:38 +00:00
										 |  |  | /*! \defgroup main_options 
 | 
					
						
							|  |  |  |  \brief Main configuration options from \ref Config_ast "asterisk.conf" or  | 
					
						
							|  |  |  |   the operating system command line when starting Asterisk  | 
					
						
							|  |  |  |   Some of them can be changed in the CLI  | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | /*! @{ */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-03-14 16:57:35 +00:00
										 |  |  | struct ast_flags ast_options = { AST_DEFAULT_OPTIONS }; | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int option_verbose = 0;				/*!< Verbosity level */ | 
					
						
							|  |  |  | int option_debug = 0;				/*!< Debug level */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-14 19:00:38 +00:00
										 |  |  | double option_maxload = 0.0;			/*!< Max load avg on system */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | int option_maxcalls = 0;			/*!< Max number of active calls */ | 
					
						
							| 
									
										
										
										
											2005-11-14 19:00:38 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*! @} */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-07 15:02:53 +00:00
										 |  |  | char record_cache_dir[AST_CACHE_DIR_LEN] = AST_TMP_DIR; | 
					
						
							| 
									
										
										
										
											2005-03-05 04:04:55 +00:00
										 |  |  | char debug_filename[AST_FILENAME_MAX] = ""; | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | static int ast_socket = -1;		/*!< UNIX Socket for allowing remote control */ | 
					
						
							|  |  |  | static int ast_consock = -1;		/*!< UNIX Socket for controlling another asterisk */ | 
					
						
							| 
									
										
										
										
											2004-03-20 21:13:12 +00:00
										 |  |  | int ast_mainpid; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | struct console { | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | 	int fd;				/*!< File descriptor */ | 
					
						
							|  |  |  | 	int p[2];			/*!< Pipe */ | 
					
						
							|  |  |  | 	pthread_t t;			/*!< Thread of handler */ | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | struct ast_atexit { | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 	void (*func)(void); | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 	AST_LIST_ENTRY(ast_atexit) list; | 
					
						
							|  |  |  | }; | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | static AST_LIST_HEAD_STATIC(atexits, ast_atexit); | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-02 15:37:34 +00:00
										 |  |  | time_t ast_startuptime; | 
					
						
							|  |  |  | time_t ast_lastreloadtime; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | static History *el_hist = NULL; | 
					
						
							|  |  |  | static EditLine *el = NULL; | 
					
						
							|  |  |  | static char *remotehostname; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | struct console consoles[AST_MAX_CONNECTS]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-01-09 19:58:18 +00:00
										 |  |  | char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | static int ast_el_add_history(char *); | 
					
						
							|  |  |  | static int ast_el_read_history(char *); | 
					
						
							|  |  |  | static int ast_el_write_history(char *); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_CONFIG_FILE[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_MODULE_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_SPOOL_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							| 
									
										
										
										
											2005-06-06 03:04:58 +00:00
										 |  |  | char ast_config_AST_MONITOR_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_LOG_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_AGI_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_DB[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_KEY_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_PID[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_SOCKET[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_RUN_DIR[AST_CONFIG_MAX_PATH]; | 
					
						
							| 
									
										
										
										
											2005-11-08 00:30:29 +00:00
										 |  |  | char ast_config_AST_RUN_USER[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_RUN_GROUP[AST_CONFIG_MAX_PATH]; | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | char ast_config_AST_CTL_PERMISSIONS[AST_CONFIG_MAX_PATH]; | 
					
						
							|  |  |  | char ast_config_AST_CTL_OWNER[AST_CONFIG_MAX_PATH] = "\0"; | 
					
						
							|  |  |  | char ast_config_AST_CTL_GROUP[AST_CONFIG_MAX_PATH] = "\0"; | 
					
						
							|  |  |  | char ast_config_AST_CTL[AST_CONFIG_MAX_PATH] = "asterisk.ctl"; | 
					
						
							| 
									
										
										
										
											2006-02-14 23:42:36 +00:00
										 |  |  | char ast_config_AST_SYSTEM_NAME[20]=""; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-23 03:43:21 +00:00
										 |  |  | static char *_argv[256]; | 
					
						
							|  |  |  | static int shuttingdown = 0; | 
					
						
							|  |  |  | static int restartnow = 0; | 
					
						
							| 
									
										
										
										
											2004-03-15 07:51:22 +00:00
										 |  |  | static pthread_t consolethread = AST_PTHREADT_NULL; | 
					
						
							| 
									
										
										
										
											2004-02-23 03:43:21 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-10 00:55:45 +00:00
										 |  |  | static char randompool[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-07 16:07:06 +00:00
										 |  |  | #if !defined(LOW_MEMORY)
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | struct file_version { | 
					
						
							|  |  |  | 	AST_LIST_ENTRY(file_version) list; | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 	const char *file; | 
					
						
							|  |  |  | 	char *version; | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static AST_LIST_HEAD_STATIC(file_versions, file_version); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ast_register_file_version(const char *file, const char *version) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct file_version *new; | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 	char *work; | 
					
						
							|  |  |  | 	size_t version_length; | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 	work = ast_strdupa(version); | 
					
						
							|  |  |  | 	work = ast_strip(ast_strip_quoted(work, "$", "$")); | 
					
						
							|  |  |  | 	version_length = strlen(work) + 1; | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	if (!(new = ast_calloc(1, sizeof(*new) + version_length))) | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	new->file = file; | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 	new->version = (char *) new + sizeof(*new); | 
					
						
							|  |  |  | 	memcpy(new->version, work, version_length); | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 	AST_LIST_LOCK(&file_versions); | 
					
						
							|  |  |  | 	AST_LIST_INSERT_HEAD(&file_versions, new, list); | 
					
						
							|  |  |  | 	AST_LIST_UNLOCK(&file_versions); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ast_unregister_file_version(const char *file) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct file_version *find; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	AST_LIST_LOCK(&file_versions); | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE_SAFE_BEGIN(&file_versions, find, list) { | 
					
						
							|  |  |  | 		if (!strcasecmp(find->file, file)) { | 
					
						
							|  |  |  | 			AST_LIST_REMOVE_CURRENT(&file_versions, list); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE_SAFE_END; | 
					
						
							|  |  |  | 	AST_LIST_UNLOCK(&file_versions); | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 	if (find) | 
					
						
							|  |  |  | 		free(find); | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char show_version_files_help[] =  | 
					
						
							|  |  |  | "Usage: show version files [like <pattern>]\n" | 
					
						
							|  |  |  | "       Shows the revision numbers of the files used to build this copy of Asterisk.\n" | 
					
						
							|  |  |  | "       Optional regular expression pattern is used to filter the file list.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! CLI command to list module versions */ | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | static int handle_show_version_files(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-07-25 22:19:13 +00:00
										 |  |  | #define FORMAT "%-25.25s %-40.40s\n"
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 	struct file_version *iterator; | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 	regex_t regexbuf; | 
					
						
							|  |  |  | 	int havepattern = 0; | 
					
						
							| 
									
										
										
										
											2005-06-06 22:39:32 +00:00
										 |  |  | 	int havename = 0; | 
					
						
							| 
									
										
										
										
											2005-08-22 18:45:41 +00:00
										 |  |  | 	int count_files = 0; | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	switch (argc) { | 
					
						
							|  |  |  | 	case 5: | 
					
						
							|  |  |  | 		if (!strcasecmp(argv[3], "like")) { | 
					
						
							|  |  |  | 			if (regcomp(®exbuf, argv[4], REG_EXTENDED | REG_NOSUB)) | 
					
						
							|  |  |  | 				return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 			havepattern = 1; | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2005-06-06 22:39:32 +00:00
										 |  |  | 	case 4: | 
					
						
							|  |  |  | 		havename = 1; | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 	case 3: | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	default: | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 	ast_cli(fd, FORMAT, "File", "Revision"); | 
					
						
							|  |  |  | 	ast_cli(fd, FORMAT, "----", "--------"); | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 	AST_LIST_LOCK(&file_versions); | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE(&file_versions, iterator, list) { | 
					
						
							| 
									
										
										
										
											2005-06-06 22:39:32 +00:00
										 |  |  | 		if (havename && strcasecmp(iterator->file, argv[3])) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 		if (havepattern && regexec(®exbuf, iterator->file, 0, NULL, 0)) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		ast_cli(fd, FORMAT, iterator->file, iterator->version); | 
					
						
							| 
									
										
										
										
											2005-08-22 18:45:41 +00:00
										 |  |  | 		count_files++; | 
					
						
							| 
									
										
										
										
											2005-06-06 22:39:32 +00:00
										 |  |  | 		if (havename) | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	AST_LIST_UNLOCK(&file_versions); | 
					
						
							| 
									
										
										
										
											2005-08-22 18:45:41 +00:00
										 |  |  | 	if (!havename) { | 
					
						
							|  |  |  | 		ast_cli(fd, "%d files listed.\n", count_files); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (havepattern) | 
					
						
							|  |  |  | 		regfree(®exbuf); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 	return RESULT_SUCCESS; | 
					
						
							| 
									
										
										
										
											2005-06-06 21:09:59 +00:00
										 |  |  | #undef FORMAT
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-18 22:17:31 +00:00
										 |  |  | static char *complete_show_version_files(const char *line, const char *word, int pos, int state) | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct file_version *find; | 
					
						
							|  |  |  | 	int which = 0; | 
					
						
							|  |  |  | 	char *ret = NULL; | 
					
						
							|  |  |  | 	int matchlen = strlen(word); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pos != 3) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	AST_LIST_LOCK(&file_versions); | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE(&file_versions, find, list) { | 
					
						
							|  |  |  | 		if (!strncasecmp(word, find->file, matchlen)) { | 
					
						
							|  |  |  | 			if (++which > state) { | 
					
						
							|  |  |  | 				ret = strdup(find->file); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	AST_LIST_UNLOCK(&file_versions); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-06-07 16:07:06 +00:00
										 |  |  | #endif /* ! LOW_MEMORY */
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | int ast_register_atexit(void (*func)(void)) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int res = -1; | 
					
						
							|  |  |  | 	struct ast_atexit *ae; | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 	ast_unregister_atexit(func);	 | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 	AST_LIST_LOCK(&atexits); | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 	if ((ae = ast_calloc(1, sizeof(*ae)))) { | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 		AST_LIST_INSERT_HEAD(&atexits, ae, list); | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 		ae->func = func; | 
					
						
							|  |  |  | 		res = 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 	AST_LIST_UNLOCK(&atexits); | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ast_unregister_atexit(void (*func)(void)) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 	struct ast_atexit *ae; | 
					
						
							|  |  |  | 	AST_LIST_LOCK(&atexits); | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE_SAFE_BEGIN(&atexits, ae, list) { | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 		if (ae->func == func) { | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 			AST_LIST_REMOVE_CURRENT(&atexits, list); | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 	AST_LIST_TRAVERSE_SAFE_END | 
					
						
							|  |  |  | 	AST_LIST_UNLOCK(&atexits); | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-16 22:37:31 +00:00
										 |  |  | static int fdprint(int fd, const char *s) | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return write(fd, s, strlen(s) + 1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! NULL handler so we can collect the child exit status */ | 
					
						
							| 
									
										
										
										
											2004-08-22 18:33:19 +00:00
										 |  |  | static void null_sig_handler(int signal) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-14 22:40:54 +00:00
										 |  |  | AST_MUTEX_DEFINE_STATIC(safe_system_lock); | 
					
						
							|  |  |  | static unsigned int safe_system_level = 0; | 
					
						
							|  |  |  | static void *safe_system_prev_handler; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | int ast_safe_system(const char *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	pid_t pid; | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	struct rusage rusage; | 
					
						
							|  |  |  | 	int status; | 
					
						
							| 
									
										
										
										
											2005-09-14 22:40:54 +00:00
										 |  |  | 	unsigned int level; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* keep track of how many ast_safe_system() functions
 | 
					
						
							|  |  |  | 	   are running at this moment | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 	ast_mutex_lock(&safe_system_lock); | 
					
						
							|  |  |  | 	level = safe_system_level++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* only replace the handler if it has not already been done */ | 
					
						
							|  |  |  | 	if (level == 0) | 
					
						
							|  |  |  | 		safe_system_prev_handler = signal(SIGCHLD, null_sig_handler); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&safe_system_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 	pid = fork(); | 
					
						
							| 
									
										
										
										
											2005-09-14 22:40:54 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 	if (pid == 0) { | 
					
						
							|  |  |  | 		/* Close file descriptors and launch system command */ | 
					
						
							| 
									
										
										
										
											2005-09-14 22:40:54 +00:00
										 |  |  | 		for (x = STDERR_FILENO + 1; x < 4096; x++) | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 			close(x); | 
					
						
							| 
									
										
										
										
											2005-09-14 22:40:54 +00:00
										 |  |  | 		execl("/bin/sh", "/bin/sh", "-c", s, NULL); | 
					
						
							| 
									
										
										
										
											2004-03-23 21:55:46 +00:00
										 |  |  | 		exit(1); | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 	} else if (pid > 0) { | 
					
						
							|  |  |  | 		for(;;) { | 
					
						
							|  |  |  | 			res = wait4(pid, &status, 0, &rusage); | 
					
						
							|  |  |  | 			if (res > -1) { | 
					
						
							| 
									
										
										
										
											2005-09-14 22:40:54 +00:00
										 |  |  | 				res = WIFEXITED(status) ? WEXITSTATUS(status) : -1; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} else if (errno != EINTR)  | 
					
						
							| 
									
										
										
										
											2004-06-21 19:12:20 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 		res = -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-09-14 22:40:54 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_lock(&safe_system_lock); | 
					
						
							|  |  |  | 	level = --safe_system_level; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* only restore the handler if we are the last one */ | 
					
						
							|  |  |  | 	if (level == 0) | 
					
						
							|  |  |  | 		signal(SIGCHLD, safe_system_prev_handler); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ast_mutex_unlock(&safe_system_lock); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 	return res; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*!
 | 
					
						
							| 
									
										
										
										
											2004-01-12 05:05:35 +00:00
										 |  |  |  * write the string to all attached console clients | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static void ast_network_puts(const char *string) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 	int x; | 
					
						
							|  |  |  | 	for (x=0;x<AST_MAX_CONNECTS; x++) { | 
					
						
							|  |  |  | 		if (consoles[x].fd > -1)  | 
					
						
							|  |  |  | 			fdprint(consoles[x].p[1], string); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-01-12 05:05:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*!
 | 
					
						
							| 
									
										
										
										
											2004-01-12 05:05:35 +00:00
										 |  |  |  * write the string to the console, and all attached | 
					
						
							|  |  |  |  * console clients | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void ast_console_puts(const char *string) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 	fputs(string, stdout); | 
					
						
							|  |  |  | 	fflush(stdout); | 
					
						
							|  |  |  | 	ast_network_puts(string); | 
					
						
							| 
									
										
										
										
											2004-01-12 05:05:35 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-16 22:37:31 +00:00
										 |  |  | static void network_verboser(const char *s, int pos, int replace, int complete) | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 	/* ARGUSED */ | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-08-05 21:22:56 +00:00
										 |  |  | 	if (replace) { | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 		char *t; | 
					
						
							|  |  |  | 		if ((t = alloca(strlen(s) + 2))) { | 
					
						
							| 
									
										
										
										
											2004-08-05 21:22:56 +00:00
										 |  |  | 			sprintf(t, "\r%s", s); | 
					
						
							| 
									
										
										
										
											2004-11-01 01:48:35 +00:00
										 |  |  | 			if (complete) | 
					
						
							|  |  |  | 				ast_network_puts(t); | 
					
						
							| 
									
										
										
										
											2004-08-05 21:22:56 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			ast_log(LOG_ERROR, "Out of memory\n"); | 
					
						
							|  |  |  | 			ast_network_puts(s); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2004-11-01 01:48:35 +00:00
										 |  |  | 		if (complete) | 
					
						
							|  |  |  | 			ast_network_puts(s); | 
					
						
							| 
									
										
										
										
											2004-08-05 21:22:56 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static pthread_t lthread; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void *netconsole(void *vconsole) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct console *con = vconsole; | 
					
						
							| 
									
										
										
										
											2005-05-08 16:44:25 +00:00
										 |  |  | 	char hostname[MAXHOSTNAMELEN]=""; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	char tmp[512]; | 
					
						
							|  |  |  | 	int res; | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 	struct pollfd fds[2]; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2005-05-08 16:44:25 +00:00
										 |  |  | 	if (gethostname(hostname, sizeof(hostname)-1)) | 
					
						
							| 
									
										
										
										
											2005-06-05 16:32:16 +00:00
										 |  |  | 		ast_copy_string(hostname, "<Unknown>", sizeof(hostname)); | 
					
						
							| 
									
										
										
										
											2004-03-20 21:13:12 +00:00
										 |  |  | 	snprintf(tmp, sizeof(tmp), "%s/%d/%s\n", hostname, ast_mainpid, ASTERISK_VERSION); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	fdprint(con->fd, tmp); | 
					
						
							|  |  |  | 	for(;;) { | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 		fds[0].fd = con->fd; | 
					
						
							|  |  |  | 		fds[0].events = POLLIN; | 
					
						
							| 
									
										
										
										
											2005-08-31 22:12:23 +00:00
										 |  |  | 		fds[0].revents = 0; | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 		fds[1].fd = con->p[0]; | 
					
						
							|  |  |  | 		fds[1].events = POLLIN; | 
					
						
							| 
									
										
										
										
											2005-08-31 22:12:23 +00:00
										 |  |  | 		fds[1].revents = 0; | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		res = poll(fds, 2, -1); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		if (res < 0) { | 
					
						
							| 
									
										
										
										
											2004-05-07 14:08:50 +00:00
										 |  |  | 			if (errno != EINTR) | 
					
						
							|  |  |  | 				ast_log(LOG_WARNING, "poll returned < 0: %s\n", strerror(errno)); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 		if (fds[0].revents) { | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			res = read(con->fd, tmp, sizeof(tmp)); | 
					
						
							| 
									
										
										
										
											2001-10-11 18:51:39 +00:00
										 |  |  | 			if (res < 1) { | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2001-10-11 18:51:39 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			tmp[res] = 0; | 
					
						
							|  |  |  | 			ast_cli_command(con->fd, tmp); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 		if (fds[1].revents) { | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			res = read(con->p[0], tmp, sizeof(tmp)); | 
					
						
							|  |  |  | 			if (res < 1) { | 
					
						
							|  |  |  | 				ast_log(LOG_ERROR, "read returned %d\n", res); | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			res = write(con->fd, tmp, res); | 
					
						
							|  |  |  | 			if (res < 1) | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (option_verbose > 2)  | 
					
						
							|  |  |  | 		ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection disconnected\n"); | 
					
						
							|  |  |  | 	close(con->fd); | 
					
						
							|  |  |  | 	close(con->p[0]); | 
					
						
							|  |  |  | 	close(con->p[1]); | 
					
						
							|  |  |  | 	con->fd = -1; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void *listener(void *unused) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | 	struct sockaddr_un sunaddr; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	int s; | 
					
						
							| 
									
										
										
										
											2005-05-15 03:21:51 +00:00
										 |  |  | 	socklen_t len; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	int x; | 
					
						
							| 
									
										
										
										
											2001-10-11 18:51:39 +00:00
										 |  |  | 	int flags; | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 	struct pollfd fds[1]; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	pthread_attr_t attr; | 
					
						
							|  |  |  | 	pthread_attr_init(&attr); | 
					
						
							|  |  |  | 	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); | 
					
						
							|  |  |  | 	for(;;) { | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 		if (ast_socket < 0) | 
					
						
							|  |  |  | 			return NULL; | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 		fds[0].fd = ast_socket; | 
					
						
							|  |  |  | 		fds[0].events= POLLIN; | 
					
						
							|  |  |  | 		s = poll(fds, 1, -1); | 
					
						
							| 
									
										
										
										
											2003-09-29 20:20:04 +00:00
										 |  |  | 		if (s < 0) { | 
					
						
							| 
									
										
										
										
											2004-03-04 21:32:32 +00:00
										 |  |  | 			if (errno != EINTR) | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 				ast_log(LOG_WARNING, "poll returned error: %s\n", strerror(errno)); | 
					
						
							| 
									
										
										
										
											2003-09-29 20:20:04 +00:00
										 |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | 		len = sizeof(sunaddr); | 
					
						
							|  |  |  | 		s = accept(ast_socket, (struct sockaddr *)&sunaddr, &len); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		if (s < 0) { | 
					
						
							| 
									
										
										
										
											2004-03-02 16:58:17 +00:00
										 |  |  | 			if (errno != EINTR) | 
					
						
							| 
									
										
										
										
											2004-03-03 00:05:00 +00:00
										 |  |  | 				ast_log(LOG_WARNING, "Accept returned %d: %s\n", s, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			for (x=0;x<AST_MAX_CONNECTS;x++) { | 
					
						
							|  |  |  | 				if (consoles[x].fd < 0) { | 
					
						
							| 
									
										
										
										
											2001-10-11 18:51:39 +00:00
										 |  |  | 					if (socketpair(AF_LOCAL, SOCK_STREAM, 0, consoles[x].p)) { | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 						ast_log(LOG_ERROR, "Unable to create pipe: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 						consoles[x].fd = -1; | 
					
						
							|  |  |  | 						fdprint(s, "Server failed to create pipe\n"); | 
					
						
							|  |  |  | 						close(s); | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2001-10-11 18:51:39 +00:00
										 |  |  | 					flags = fcntl(consoles[x].p[1], F_GETFL); | 
					
						
							|  |  |  | 					fcntl(consoles[x].p[1], F_SETFL, flags | O_NONBLOCK); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 					consoles[x].fd = s; | 
					
						
							| 
									
										
										
										
											2004-08-08 17:15:02 +00:00
										 |  |  | 					if (ast_pthread_create(&consoles[x].t, &attr, netconsole, &consoles[x])) { | 
					
						
							| 
									
										
										
										
											2004-05-07 14:08:50 +00:00
										 |  |  | 						ast_log(LOG_ERROR, "Unable to spawn thread to handle connection: %s\n", strerror(errno)); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 						consoles[x].fd = -1; | 
					
						
							|  |  |  | 						fdprint(s, "Server failed to spawn thread\n"); | 
					
						
							|  |  |  | 						close(s); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (x >= AST_MAX_CONNECTS) { | 
					
						
							|  |  |  | 				fdprint(s, "No more connections allowed\n"); | 
					
						
							|  |  |  | 				ast_log(LOG_WARNING, "No more connections allowed\n"); | 
					
						
							|  |  |  | 				close(s); | 
					
						
							|  |  |  | 			} else if (consoles[x].fd > -1) { | 
					
						
							|  |  |  | 				if (option_verbose > 2)  | 
					
						
							|  |  |  | 					ast_verbose(VERBOSE_PREFIX_3 "Remote UNIX connection\n"); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ast_makesocket(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | 	struct sockaddr_un sunaddr; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	int res; | 
					
						
							|  |  |  | 	int x; | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 	uid_t uid = -1; | 
					
						
							|  |  |  | 	gid_t gid = -1; | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 	for (x = 0; x < AST_MAX_CONNECTS; x++)	 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		consoles[x].fd = -1; | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 	unlink(ast_config_AST_SOCKET); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	ast_socket = socket(PF_LOCAL, SOCK_STREAM, 0); | 
					
						
							|  |  |  | 	if (ast_socket < 0) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to create control socket: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	}		 | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | 	memset(&sunaddr, 0, sizeof(sunaddr)); | 
					
						
							|  |  |  | 	sunaddr.sun_family = AF_LOCAL; | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 	ast_copy_string(sunaddr.sun_path, ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)); | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | 	res = bind(ast_socket, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	if (res) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Unable to bind socket to %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		close(ast_socket); | 
					
						
							|  |  |  | 		ast_socket = -1; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	res = listen(ast_socket, 2); | 
					
						
							|  |  |  | 	if (res < 0) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Unable to listen on socket %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		close(ast_socket); | 
					
						
							|  |  |  | 		ast_socket = -1; | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ast_register_verbose(network_verboser); | 
					
						
							| 
									
										
										
										
											2004-08-08 17:15:02 +00:00
										 |  |  | 	ast_pthread_create(<hread, NULL, listener, NULL); | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 	if (!ast_strlen_zero(ast_config_AST_CTL_OWNER)) { | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 		struct passwd *pw; | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 		if ((pw = getpwnam(ast_config_AST_CTL_OWNER)) == NULL) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to find uid of user %s\n", ast_config_AST_CTL_OWNER); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			uid = pw->pw_uid; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 	if (!ast_strlen_zero(ast_config_AST_CTL_GROUP)) { | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 		struct group *grp; | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 		if ((grp = getgrnam(ast_config_AST_CTL_GROUP)) == NULL) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to find gid of group %s\n", ast_config_AST_CTL_GROUP); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			gid = grp->gr_gid; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 	if (chown(ast_config_AST_SOCKET, uid, gid) < 0) | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to change ownership of %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!ast_strlen_zero(ast_config_AST_CTL_PERMISSIONS)) { | 
					
						
							| 
									
										
										
										
											2005-12-26 18:35:28 +00:00
										 |  |  | 		int p1; | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 		mode_t p; | 
					
						
							| 
									
										
										
										
											2005-12-26 18:35:28 +00:00
										 |  |  | 		sscanf(ast_config_AST_CTL_PERMISSIONS, "%o", &p1); | 
					
						
							|  |  |  | 		p = p1; | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 		if ((chmod(ast_config_AST_SOCKET, p)) < 0) | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to change file permissions of %s: %s\n", ast_config_AST_SOCKET, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ast_tryconnect(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | 	struct sockaddr_un sunaddr; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	int res; | 
					
						
							|  |  |  | 	ast_consock = socket(PF_LOCAL, SOCK_STREAM, 0); | 
					
						
							|  |  |  | 	if (ast_consock < 0) { | 
					
						
							|  |  |  | 		ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | 	memset(&sunaddr, 0, sizeof(sunaddr)); | 
					
						
							|  |  |  | 	sunaddr.sun_family = AF_LOCAL; | 
					
						
							| 
									
										
										
										
											2005-06-05 16:32:16 +00:00
										 |  |  | 	ast_copy_string(sunaddr.sun_path, (char *)ast_config_AST_SOCKET, sizeof(sunaddr.sun_path)); | 
					
						
							| 
									
										
										
										
											2004-12-14 23:36:30 +00:00
										 |  |  | 	res = connect(ast_consock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	if (res) { | 
					
						
							|  |  |  | 		close(ast_consock); | 
					
						
							|  |  |  | 		ast_consock = -1; | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} else | 
					
						
							|  |  |  | 		return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! Urgent handler
 | 
					
						
							|  |  |  |  Called by soft_hangup to interrupt the poll, read, or other | 
					
						
							|  |  |  |  system call.  We don't actually need to do anything though.   | 
					
						
							|  |  |  |  Remember: Cannot EVER ast_log from within a signal handler  | 
					
						
							|  |  |  |  SLD: seems to be some pthread activity relating to the printf anyway: | 
					
						
							|  |  |  |  which is leading to a deadlock?  | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | static void urg_handler(int num) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2005-09-01 22:03:10 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											2005-08-22 23:06:14 +00:00
										 |  |  | 	if (option_debug > 2)  | 
					
						
							|  |  |  | 		printf("-- Asterisk Urgent handler\n"); | 
					
						
							| 
									
										
										
										
											2005-09-01 22:03:10 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 	signal(num, urg_handler); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	return; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | static void hup_handler(int num) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (option_verbose > 1)  | 
					
						
							| 
									
										
										
										
											2003-12-01 02:47:19 +00:00
										 |  |  | 		printf("Received HUP signal -- Reloading configs\n"); | 
					
						
							| 
									
										
										
										
											2004-02-23 03:43:21 +00:00
										 |  |  | 	if (restartnow) | 
					
						
							|  |  |  | 		execvp(_argv[0], _argv); | 
					
						
							| 
									
										
										
										
											2003-12-01 02:47:19 +00:00
										 |  |  | 	/* XXX This could deadlock XXX */ | 
					
						
							| 
									
										
										
										
											2004-09-02 20:45:24 +00:00
										 |  |  | 	ast_module_reload(NULL); | 
					
						
							| 
									
										
										
										
											2005-07-15 22:12:55 +00:00
										 |  |  | 	signal(num, hup_handler); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-09-16 19:35:57 +00:00
										 |  |  | static void child_handler(int sig) | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-12-01 02:47:19 +00:00
										 |  |  | 	/* Must not ever ast_log or ast_verbose within signal handler */ | 
					
						
							| 
									
										
										
										
											2003-09-16 19:35:57 +00:00
										 |  |  | 	int n, status; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/*
 | 
					
						
							|  |  |  | 	 * Reap all dead children -- not just one | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	for (n = 0; wait4(-1, &status, WNOHANG, NULL) > 0; n++) | 
					
						
							|  |  |  | 		; | 
					
						
							|  |  |  | 	if (n == 0 && option_debug)	 | 
					
						
							| 
									
										
										
										
											2003-12-01 02:47:19 +00:00
										 |  |  | 		printf("Huh?  Child handler, but nobody there?\n"); | 
					
						
							| 
									
										
										
										
											2005-07-15 22:12:55 +00:00
										 |  |  | 	signal(sig, child_handler); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2003-09-16 19:35:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! Set an X-term or screen title */ | 
					
						
							| 
									
										
										
										
											2000-10-25 23:22:50 +00:00
										 |  |  | static void set_title(char *text) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (getenv("TERM") && strstr(getenv("TERM"), "xterm")) | 
					
						
							|  |  |  | 		fprintf(stdout, "\033]2;%s\007", text); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void set_icon(char *text) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (getenv("TERM") && strstr(getenv("TERM"), "xterm")) | 
					
						
							|  |  |  | 		fprintf(stdout, "\033]1;%s\007", text); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! We set ourselves to a high priority, that we might pre-empt everything
 | 
					
						
							|  |  |  |    else.  If your PBX has heavy activity on it, this is a good thing.  */ | 
					
						
							| 
									
										
										
										
											2005-08-23 01:30:22 +00:00
										 |  |  | int ast_set_priority(int pri) | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	struct sched_param sched; | 
					
						
							| 
									
										
										
										
											2001-03-22 04:14:04 +00:00
										 |  |  | 	memset(&sched, 0, sizeof(sched)); | 
					
						
							| 
									
										
										
										
											2003-04-23 20:22:14 +00:00
										 |  |  | #ifdef __linux__
 | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	if (pri) {   | 
					
						
							| 
									
										
										
										
											2001-03-22 04:14:04 +00:00
										 |  |  | 		sched.sched_priority = 10; | 
					
						
							|  |  |  | 		if (sched_setscheduler(0, SCHED_RR, &sched)) { | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 			ast_log(LOG_WARNING, "Unable to set high priority\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2001-03-22 04:14:04 +00:00
										 |  |  | 		} else | 
					
						
							|  |  |  | 			if (option_verbose) | 
					
						
							|  |  |  | 				ast_verbose("Set to realtime thread\n"); | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		sched.sched_priority = 0; | 
					
						
							|  |  |  | 		if (sched_setscheduler(0, SCHED_OTHER, &sched)) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to set normal priority\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-04-23 20:22:14 +00:00
										 |  |  | #else
 | 
					
						
							|  |  |  | 	if (pri) { | 
					
						
							|  |  |  | 		if (setpriority(PRIO_PROCESS, 0, -10) == -1) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to set high priority\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} else | 
					
						
							|  |  |  | 			if (option_verbose) | 
					
						
							|  |  |  | 				ast_verbose("Set to high priority\n"); | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		if (setpriority(PRIO_PROCESS, 0, 0) == -1) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to set normal priority\n"); | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | static void ast_run_atexits(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct ast_atexit *ae; | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 	AST_LIST_LOCK(&atexits); | 
					
						
							|  |  |  | 	AST_LIST_TRAVERSE(&atexits, ae, list) { | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 		if (ae->func)  | 
					
						
							|  |  |  | 			ae->func(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-01-24 20:27:09 +00:00
										 |  |  | 	AST_LIST_UNLOCK(&atexits); | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | static void quit_handler(int num, int nice, int safeshutdown, int restart) | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	char filename[80] = ""; | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	time_t s,e; | 
					
						
							|  |  |  | 	int x; | 
					
						
							| 
									
										
										
										
											2005-06-03 01:42:31 +00:00
										 |  |  | 	/* Try to get as many CDRs as possible submitted to the backend engines (if in batch mode) */ | 
					
						
							|  |  |  | 	ast_cdr_engine_term(); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	if (safeshutdown) { | 
					
						
							|  |  |  | 		shuttingdown = 1; | 
					
						
							|  |  |  | 		if (!nice) { | 
					
						
							|  |  |  | 			/* Begin shutdown routine, hanging up active channels */ | 
					
						
							|  |  |  | 			ast_begin_shutdown(1); | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			if (option_verbose && ast_opt_console) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 				ast_verbose("Beginning asterisk %s....\n", restart ? "restart" : "shutdown"); | 
					
						
							|  |  |  | 			time(&s); | 
					
						
							|  |  |  | 			for(;;) { | 
					
						
							|  |  |  | 				time(&e); | 
					
						
							|  |  |  | 				/* Wait up to 15 seconds for all channels to go away */ | 
					
						
							|  |  |  | 				if ((e - s) > 15) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				if (!ast_active_channels()) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				if (!shuttingdown) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				/* Sleep 1/10 of a second */ | 
					
						
							|  |  |  | 				usleep(100000); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			if (nice < 2) | 
					
						
							|  |  |  | 				ast_begin_shutdown(0); | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			if (option_verbose && ast_opt_console) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 				ast_verbose("Waiting for inactivity to perform %s...\n", restart ? "restart" : "halt"); | 
					
						
							|  |  |  | 			for(;;) { | 
					
						
							|  |  |  | 				if (!ast_active_channels()) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				if (!shuttingdown) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				sleep(1); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (!shuttingdown) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			if (option_verbose && ast_opt_console) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 				ast_verbose("Asterisk %s cancelled.\n", restart ? "restart" : "shutdown"); | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_console || ast_opt_remote) { | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		if (getenv("HOME"))  | 
					
						
							|  |  |  | 			snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); | 
					
						
							| 
									
										
										
										
											2004-05-04 14:54:42 +00:00
										 |  |  | 		if (!ast_strlen_zero(filename)) | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			ast_el_write_history(filename); | 
					
						
							|  |  |  | 		if (el != NULL) | 
					
						
							|  |  |  | 			el_end(el); | 
					
						
							|  |  |  | 		if (el_hist != NULL) | 
					
						
							|  |  |  | 			history_end(el_hist); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 	if (option_verbose) | 
					
						
							|  |  |  | 		ast_verbose("Executing last minute cleanups\n"); | 
					
						
							|  |  |  | 	ast_run_atexits(); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	/* Called on exit */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (option_verbose && ast_opt_console) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 		ast_verbose("Asterisk %s ending (%d).\n", ast_active_channels() ? "uncleanly" : "cleanly", num); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	else if (option_debug) | 
					
						
							|  |  |  | 		ast_log(LOG_DEBUG, "Asterisk ending (%d).\n", num); | 
					
						
							| 
									
										
										
										
											2003-02-20 06:00:14 +00:00
										 |  |  | 	manager_event(EVENT_FLAG_SYSTEM, "Shutdown", "Shutdown: %s\r\nRestart: %s\r\n", ast_active_channels() ? "Uncleanly" : "Cleanly", restart ? "True" : "False"); | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 	if (ast_socket > -1) { | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		close(ast_socket); | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 		ast_socket = -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	if (ast_consock > -1) | 
					
						
							|  |  |  | 		close(ast_consock); | 
					
						
							|  |  |  | 	if (ast_socket > -1) | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		unlink(ast_config_AST_SOCKET); | 
					
						
							|  |  |  | 	if (!ast_opt_remote) | 
					
						
							|  |  |  | 		unlink(ast_config_AST_PID); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	printf(term_quit()); | 
					
						
							|  |  |  | 	if (restart) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		if (option_verbose || ast_opt_console) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 			ast_verbose("Preparing for Asterisk restart...\n"); | 
					
						
							|  |  |  | 		/* Mark all FD's for closing on exec */ | 
					
						
							|  |  |  | 		for (x=3;x<32768;x++) { | 
					
						
							|  |  |  | 			fcntl(x, F_SETFD, FD_CLOEXEC); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		if (option_verbose || ast_opt_console) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 			ast_verbose("Restarting Asterisk NOW...\n"); | 
					
						
							| 
									
										
										
										
											2004-02-23 03:43:21 +00:00
										 |  |  | 		restartnow = 1; | 
					
						
							| 
									
										
										
										
											2004-06-17 01:13:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* close logger */ | 
					
						
							|  |  |  | 		close_logger(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-02-23 03:43:21 +00:00
										 |  |  | 		/* If there is a consolethread running send it a SIGHUP 
 | 
					
						
							|  |  |  | 		   so it can execvp, otherwise we can do it ourselves */ | 
					
						
							| 
									
										
										
										
											2005-09-25 16:52:04 +00:00
										 |  |  | 		if ((consolethread != AST_PTHREADT_NULL) && (consolethread != pthread_self())) { | 
					
						
							| 
									
										
										
										
											2004-02-23 03:43:21 +00:00
										 |  |  | 			pthread_kill(consolethread, SIGHUP); | 
					
						
							| 
									
										
										
										
											2004-03-02 23:50:03 +00:00
										 |  |  | 			/* Give the signal handler some time to complete */ | 
					
						
							|  |  |  | 			sleep(2); | 
					
						
							|  |  |  | 		} else | 
					
						
							| 
									
										
										
										
											2004-02-23 03:43:21 +00:00
										 |  |  | 			execvp(_argv[0], _argv); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-06-17 01:13:10 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		/* close logger */ | 
					
						
							|  |  |  | 		close_logger(); | 
					
						
							| 
									
										
										
										
											2003-08-07 03:48:00 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	exit(0); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void __quit_handler(int num) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	quit_handler(num, 0, 1, 0); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-06-27 23:02:52 +00:00
										 |  |  | static const char *fix_header(char *outbuf, int maxout, const char *s, char *cmp) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-06-27 23:02:52 +00:00
										 |  |  | 	const char *c; | 
					
						
							|  |  |  | 	if (!strncmp(s, cmp, strlen(cmp))) { | 
					
						
							|  |  |  | 		c = s + strlen(cmp); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 		term_color(outbuf, cmp, COLOR_GRAY, 0, maxout); | 
					
						
							| 
									
										
										
										
											2003-06-27 23:02:52 +00:00
										 |  |  | 		return c; | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-06-27 23:02:52 +00:00
										 |  |  | 	return NULL; | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-16 22:37:31 +00:00
										 |  |  | static void console_verboser(const char *s, int pos, int replace, int complete) | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	char tmp[80]; | 
					
						
							| 
									
										
										
										
											2003-06-27 23:02:52 +00:00
										 |  |  | 	const char *c=NULL; | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	/* Return to the beginning of the line */ | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	if (!pos) { | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 		fprintf(stdout, "\r"); | 
					
						
							| 
									
										
										
										
											2003-06-27 23:02:52 +00:00
										 |  |  | 		if ((c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_4)) || | 
					
						
							|  |  |  | 			(c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_3)) || | 
					
						
							|  |  |  | 			(c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_2)) || | 
					
						
							|  |  |  | 			(c = fix_header(tmp, sizeof(tmp), s, VERBOSE_PREFIX_1))) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 			fputs(tmp, stdout); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-06-27 23:02:52 +00:00
										 |  |  | 	if (c) | 
					
						
							|  |  |  | 		fputs(c + pos,stdout); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		fputs(s + pos,stdout); | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 	fflush(stdout); | 
					
						
							| 
									
										
										
										
											2004-10-01 18:35:35 +00:00
										 |  |  | 	if (complete) { | 
					
						
							|  |  |  | 		/* Wake up a poll()ing console */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		if (ast_opt_console && consolethread != AST_PTHREADT_NULL) | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 			pthread_kill(consolethread, SIGURG); | 
					
						
							| 
									
										
										
										
											2004-10-01 18:35:35 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-08-01 18:12:52 +00:00
										 |  |  | static int ast_all_zeros(char *s) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	while(*s) { | 
					
						
							|  |  |  | 		if (*s > 32) | 
					
						
							|  |  |  | 			return 0; | 
					
						
							|  |  |  | 		s++;   | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | static void consolehandler(char *s) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	printf(term_end()); | 
					
						
							|  |  |  | 	fflush(stdout); | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	/* Called when readline data is available */ | 
					
						
							| 
									
										
										
										
											2004-08-01 18:12:52 +00:00
										 |  |  | 	if (s && !ast_all_zeros(s)) | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		ast_el_add_history(s); | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 	/* Give the console access to the shell */ | 
					
						
							|  |  |  | 	if (s) { | 
					
						
							| 
									
										
										
										
											2003-10-22 03:46:36 +00:00
										 |  |  | 		/* The real handler for bang */ | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 		if (s[0] == '!') { | 
					
						
							|  |  |  | 			if (s[1]) | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 				ast_safe_system(s+1); | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 				ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 		} else  | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 		ast_cli_command(STDOUT_FILENO, s); | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 	} else | 
					
						
							|  |  |  | 		fprintf(stdout, "\nUse \"quit\" to exit\n"); | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | static int remoteconsolehandler(char *s) | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	int ret = 0; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	/* Called when readline data is available */ | 
					
						
							| 
									
										
										
										
											2004-08-03 06:31:20 +00:00
										 |  |  | 	if (s && !ast_all_zeros(s)) | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		ast_el_add_history(s); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	/* Give the console access to the shell */ | 
					
						
							|  |  |  | 	if (s) { | 
					
						
							| 
									
										
										
										
											2003-10-22 03:46:36 +00:00
										 |  |  | 		/* The real handler for bang */ | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		if (s[0] == '!') { | 
					
						
							|  |  |  | 			if (s[1]) | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 				ast_safe_system(s+1); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			else | 
					
						
							| 
									
										
										
										
											2004-03-21 18:15:37 +00:00
										 |  |  | 				ast_safe_system(getenv("SHELL") ? getenv("SHELL") : "/bin/sh"); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			ret = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-09-04 03:55:41 +00:00
										 |  |  | 		if ((strncasecmp(s, "quit", 4) == 0 || strncasecmp(s, "exit", 4) == 0) && | 
					
						
							|  |  |  | 		    (s[4] == '\0' || isspace(s[4]))) { | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 			quit_handler(0, 0, 0, 0); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			ret = 1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	} else | 
					
						
							|  |  |  | 		fprintf(stdout, "\nUse \"quit\" to exit\n"); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | static char abort_halt_help[] =  | 
					
						
							|  |  |  | "Usage: abort shutdown\n" | 
					
						
							|  |  |  | "       Causes Asterisk to abort an executing shutdown or restart, and resume normal\n" | 
					
						
							|  |  |  | "       call operations.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char shutdown_now_help[] =  | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | "Usage: stop now\n" | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | "       Shuts down a running Asterisk immediately, hanging up all active calls .\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char shutdown_gracefully_help[] =  | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | "Usage: stop gracefully\n" | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | "       Causes Asterisk to not accept new calls, and exit when all\n" | 
					
						
							|  |  |  | "       active calls have terminated normally.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-23 16:24:09 +00:00
										 |  |  | static char shutdown_when_convenient_help[] =  | 
					
						
							|  |  |  | "Usage: stop when convenient\n" | 
					
						
							|  |  |  | "       Causes Asterisk to perform a shutdown when all active calls have ended.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | static char restart_now_help[] =  | 
					
						
							|  |  |  | "Usage: restart now\n" | 
					
						
							| 
									
										
										
										
											2004-12-28 07:51:25 +00:00
										 |  |  | "       Causes Asterisk to hangup all calls and exec() itself performing a cold\n" | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | "       restart.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char restart_gracefully_help[] =  | 
					
						
							|  |  |  | "Usage: restart gracefully\n" | 
					
						
							| 
									
										
										
										
											2004-12-28 07:51:25 +00:00
										 |  |  | "       Causes Asterisk to stop accepting new calls and exec() itself performing a cold\n" | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | "       restart when all active calls have ended.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char restart_when_convenient_help[] =  | 
					
						
							|  |  |  | "Usage: restart when convenient\n" | 
					
						
							|  |  |  | "       Causes Asterisk to perform a cold restart when all active calls have ended.\n"; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-22 03:46:36 +00:00
										 |  |  | static char bang_help[] = | 
					
						
							|  |  |  | "Usage: !<command>\n" | 
					
						
							|  |  |  | "       Executes a given shell command\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-23 03:04:38 +00:00
										 |  |  | static char show_warranty_help[] = | 
					
						
							|  |  |  | "Usage: show warranty\n" | 
					
						
							|  |  |  | "	Shows the warranty (if any) for this copy of Asterisk.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char show_license_help[] = | 
					
						
							|  |  |  | "Usage: show license\n" | 
					
						
							|  |  |  | "	Shows the license(s) for this copy of Asterisk.\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-16 22:37:31 +00:00
										 |  |  | #if 0
 | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | static int handle_quit(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (argc != 1) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	quit_handler(0, 0, 1, 0); | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-03-16 22:37:31 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static int handle_shutdown_now(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (argc != 2) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 	quit_handler(0, 0 /* Not nice */, 1 /* safely */, 0 /* not restart */); | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int handle_shutdown_gracefully(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (argc != 2) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 	quit_handler(0, 1 /* nicely */, 1 /* safely */, 0 /* no restart */); | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-23 16:24:09 +00:00
										 |  |  | static int handle_shutdown_when_convenient(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (argc != 3) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							| 
									
										
										
										
											2006-01-13 06:49:23 +00:00
										 |  |  | 	ast_cli(fd, "Waiting for inactivity to perform halt\n"); | 
					
						
							| 
									
										
										
										
											2003-04-23 16:24:09 +00:00
										 |  |  | 	quit_handler(0, 2 /* really nicely */, 1 /* safely */, 0 /* don't restart */); | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | static int handle_restart_now(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (argc != 2) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 	quit_handler(0, 0 /* not nicely */, 1 /* safely */, 1 /* restart */); | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int handle_restart_gracefully(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (argc != 2) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 	quit_handler(0, 1 /* nicely */, 1 /* safely */, 1 /* restart */); | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int handle_restart_when_convenient(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (argc != 3) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							| 
									
										
										
										
											2006-01-13 06:49:23 +00:00
										 |  |  | 	ast_cli(fd, "Waiting for inactivity to perform restart\n"); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	quit_handler(0, 2 /* really nicely */, 1 /* safely */, 1 /* restart */); | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int handle_abort_halt(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (argc != 2) | 
					
						
							|  |  |  | 		return RESULT_SHOWUSAGE; | 
					
						
							|  |  |  | 	ast_cancel_shutdown(); | 
					
						
							|  |  |  | 	shuttingdown = 0; | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-10-22 03:46:36 +00:00
										 |  |  | static int handle_bang(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2005-12-23 03:04:38 +00:00
										 |  |  | static const char *warranty_lines[] = { | 
					
						
							|  |  |  | 	"\n", | 
					
						
							|  |  |  | 	"			    NO WARRANTY\n", | 
					
						
							|  |  |  | 	"\n", | 
					
						
							|  |  |  | 	"BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n", | 
					
						
							|  |  |  | 	"FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n", | 
					
						
							|  |  |  | 	"OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n", | 
					
						
							|  |  |  | 	"PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n", | 
					
						
							|  |  |  | 	"OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n", | 
					
						
							|  |  |  | 	"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n", | 
					
						
							|  |  |  | 	"TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n", | 
					
						
							|  |  |  | 	"PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n", | 
					
						
							|  |  |  | 	"REPAIR OR CORRECTION.\n", | 
					
						
							|  |  |  | 	"\n", | 
					
						
							|  |  |  | 	"IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n", | 
					
						
							|  |  |  | 	"WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n", | 
					
						
							|  |  |  | 	"REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n", | 
					
						
							|  |  |  | 	"INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n", | 
					
						
							|  |  |  | 	"OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n", | 
					
						
							|  |  |  | 	"TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n", | 
					
						
							|  |  |  | 	"YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n", | 
					
						
							|  |  |  | 	"PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n", | 
					
						
							|  |  |  | 	"POSSIBILITY OF SUCH DAMAGES.\n", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int show_warranty(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (x = 0; x < sizeof(warranty_lines) / sizeof(warranty_lines[0]); x++) | 
					
						
							|  |  |  | 		ast_cli(fd, (char *) warranty_lines[x]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static const char *license_lines[] = { | 
					
						
							|  |  |  | 	"\n", | 
					
						
							|  |  |  | 	"This program is free software; you can redistribute it and/or modify\n", | 
					
						
							|  |  |  | 	"it under the terms of the GNU General Public License version 2 as\n", | 
					
						
							|  |  |  | 	"published by the Free Software Foundation.\n", | 
					
						
							|  |  |  | 	"\n", | 
					
						
							|  |  |  | 	"This program also contains components licensed under other licenses.\n", | 
					
						
							|  |  |  | 	"They include:\n", | 
					
						
							|  |  |  | 	"\n", | 
					
						
							|  |  |  | 	"This program is distributed in the hope that it will be useful,\n", | 
					
						
							|  |  |  | 	"but WITHOUT ANY WARRANTY; without even the implied warranty of\n", | 
					
						
							|  |  |  | 	"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n", | 
					
						
							|  |  |  | 	"GNU General Public License for more details.\n", | 
					
						
							|  |  |  | 	"\n", | 
					
						
							|  |  |  | 	"You should have received a copy of the GNU General Public License\n", | 
					
						
							|  |  |  | 	"along with this program; if not, write to the Free Software\n", | 
					
						
							|  |  |  | 	"Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n", | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int show_license(int fd, int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int x; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (x = 0; x < sizeof(license_lines) / sizeof(license_lines[0]); x++) | 
					
						
							|  |  |  | 		ast_cli(fd, (char *) license_lines[x]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return RESULT_SUCCESS; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2003-10-22 03:46:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | #define ASTERISK_PROMPT "*CLI> "
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | #define ASTERISK_PROMPT2 "%s*CLI> "
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-03 03:04:08 +00:00
										 |  |  | static struct ast_cli_entry core_cli[] = { | 
					
						
							|  |  |  | 	{ { "abort", "halt", NULL }, handle_abort_halt, | 
					
						
							|  |  |  | 	  "Cancel a running halt", abort_halt_help }, | 
					
						
							|  |  |  | 	{ { "stop", "now", NULL }, handle_shutdown_now, | 
					
						
							|  |  |  | 	  "Shut down Asterisk immediately", shutdown_now_help }, | 
					
						
							|  |  |  | 	{ { "stop", "gracefully", NULL }, handle_shutdown_gracefully, | 
					
						
							|  |  |  | 	  "Gracefully shut down Asterisk", shutdown_gracefully_help }, | 
					
						
							|  |  |  | 	{ { "stop", "when","convenient", NULL }, handle_shutdown_when_convenient, | 
					
						
							|  |  |  | 	  "Shut down Asterisk at empty call volume", shutdown_when_convenient_help }, | 
					
						
							|  |  |  | 	{ { "restart", "now", NULL }, handle_restart_now, | 
					
						
							|  |  |  | 	  "Restart Asterisk immediately", restart_now_help }, | 
					
						
							|  |  |  | 	{ { "restart", "gracefully", NULL }, handle_restart_gracefully, | 
					
						
							|  |  |  | 	  "Restart Asterisk gracefully", restart_gracefully_help }, | 
					
						
							|  |  |  | 	{ { "restart", "when", "convenient", NULL }, handle_restart_when_convenient, | 
					
						
							|  |  |  | 	  "Restart Asterisk at empty call volume", restart_when_convenient_help }, | 
					
						
							| 
									
										
										
										
											2005-12-23 03:04:38 +00:00
										 |  |  | 	{ { "show", "warranty", NULL }, show_warranty, | 
					
						
							|  |  |  | 	  "Show the warranty (if any) for this copy of Asterisk", show_warranty_help }, | 
					
						
							|  |  |  | 	{ { "show", "license", NULL }, show_license, | 
					
						
							|  |  |  | 	  "Show the license(s) for this copy of Asterisk", show_license_help }, | 
					
						
							| 
									
										
										
										
											2005-06-03 03:04:08 +00:00
										 |  |  | 	{ { "!", NULL }, handle_bang, | 
					
						
							|  |  |  | 	  "Execute a shell command", bang_help }, | 
					
						
							| 
									
										
										
										
											2005-06-07 16:07:06 +00:00
										 |  |  | #if !defined(LOW_MEMORY)
 | 
					
						
							| 
									
										
										
										
											2005-06-06 20:27:51 +00:00
										 |  |  | 	{ { "show", "version", "files", NULL }, handle_show_version_files, | 
					
						
							|  |  |  | 	  "Show versions of files used to build Asterisk", show_version_files_help, complete_show_version_files }, | 
					
						
							| 
									
										
										
										
											2005-06-07 16:07:06 +00:00
										 |  |  | #endif /* ! LOW_MEMORY */
 | 
					
						
							| 
									
										
										
										
											2005-06-03 03:04:08 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | static int ast_el_read_char(EditLine *el, char *cp) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 	int num_read=0; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	int lastpos=0; | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 	struct pollfd fds[2]; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	int res; | 
					
						
							|  |  |  | 	int max; | 
					
						
							|  |  |  | 	char buf[512]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 		max = 1; | 
					
						
							|  |  |  | 		fds[0].fd = ast_consock; | 
					
						
							|  |  |  | 		fds[0].events = POLLIN; | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		if (!ast_opt_exec) { | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 			fds[1].fd = STDIN_FILENO; | 
					
						
							|  |  |  | 			fds[1].events = POLLIN; | 
					
						
							|  |  |  | 			max++; | 
					
						
							| 
									
										
										
										
											2003-06-23 16:40:12 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 		res = poll(fds, max, -1); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		if (res < 0) { | 
					
						
							|  |  |  | 			if (errno == EINTR) | 
					
						
							|  |  |  | 				continue; | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 			ast_log(LOG_ERROR, "poll failed: %s\n", strerror(errno)); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		if (!ast_opt_exec && fds[1].revents) { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			num_read = read(STDIN_FILENO, cp, 1); | 
					
						
							|  |  |  | 			if (num_read < 1) { | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} else  | 
					
						
							|  |  |  | 				return (num_read); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-04-25 20:42:45 +00:00
										 |  |  | 		if (fds[0].revents) { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			res = read(ast_consock, buf, sizeof(buf) - 1); | 
					
						
							|  |  |  | 			/* if the remote side disappears exit */ | 
					
						
							|  |  |  | 			if (res < 1) { | 
					
						
							|  |  |  | 				fprintf(stderr, "\nDisconnected from Asterisk server\n"); | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 				if (!ast_opt_reconnect) { | 
					
						
							| 
									
										
										
										
											2004-06-25 14:39:38 +00:00
										 |  |  | 					quit_handler(0, 0, 0, 0); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					int tries; | 
					
						
							| 
									
										
										
										
											2004-06-25 21:14:03 +00:00
										 |  |  | 					int reconnects_per_second = 20; | 
					
						
							|  |  |  | 					fprintf(stderr, "Attempting to reconnect for 30 seconds\n"); | 
					
						
							| 
									
										
										
										
											2004-06-25 14:39:38 +00:00
										 |  |  | 					for (tries=0;tries<30 * reconnects_per_second;tries++) { | 
					
						
							|  |  |  | 						if (ast_tryconnect()) { | 
					
						
							| 
									
										
										
										
											2004-06-25 21:14:03 +00:00
										 |  |  | 							fprintf(stderr, "Reconnect succeeded after %.3f seconds\n", 1.0 / reconnects_per_second * tries); | 
					
						
							| 
									
										
										
										
											2004-06-25 14:39:38 +00:00
										 |  |  | 							printf(term_quit()); | 
					
						
							| 
									
										
										
										
											2004-06-25 21:14:03 +00:00
										 |  |  | 							WELCOME_MESSAGE; | 
					
						
							| 
									
										
										
										
											2004-06-25 14:39:38 +00:00
										 |  |  | 							break; | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							usleep(1000000 / reconnects_per_second); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							| 
									
										
										
										
											2004-12-28 07:51:25 +00:00
										 |  |  | 					if (tries >= 30 * reconnects_per_second) { | 
					
						
							| 
									
										
										
										
											2004-06-25 14:39:38 +00:00
										 |  |  | 						fprintf(stderr, "Failed to reconnect for 30 seconds.  Quitting.\n"); | 
					
						
							|  |  |  | 						quit_handler(0, 0, 0, 0); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			buf[res] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			if (!ast_opt_exec && !lastpos) | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 				write(STDOUT_FILENO, "\r", 1); | 
					
						
							|  |  |  | 			write(STDOUT_FILENO, buf, res); | 
					
						
							| 
									
										
										
										
											2003-12-03 04:55:55 +00:00
										 |  |  | 			if ((buf[res-1] == '\n') || (buf[res-2] == '\n')) { | 
					
						
							| 
									
										
										
										
											2003-03-06 06:00:17 +00:00
										 |  |  | 				*cp = CC_REFRESH; | 
					
						
							|  |  |  | 				return(1); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				lastpos = 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	*cp = '\0'; | 
					
						
							|  |  |  | 	return (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *cli_prompt(EditLine *el) | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 	static char prompt[200]; | 
					
						
							|  |  |  | 	char *pfmt; | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 	int color_used=0; | 
					
						
							|  |  |  | 	char term_code[20]; | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if ((pfmt = getenv("ASTERISK_PROMPT"))) { | 
					
						
							|  |  |  | 		char *t = pfmt, *p = prompt; | 
					
						
							|  |  |  | 		memset(prompt, 0, sizeof(prompt)); | 
					
						
							|  |  |  | 		while (*t != '\0' && *p < sizeof(prompt)) { | 
					
						
							|  |  |  | 			if (*t == '%') { | 
					
						
							| 
									
										
										
										
											2005-05-08 16:44:25 +00:00
										 |  |  | 				char hostname[MAXHOSTNAMELEN]=""; | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 				int i; | 
					
						
							| 
									
										
										
										
											2005-12-26 18:35:28 +00:00
										 |  |  | 				time_t ts; | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 				struct tm tm; | 
					
						
							| 
									
										
										
										
											2004-05-31 16:43:35 +00:00
										 |  |  | #ifdef linux
 | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 				FILE *LOADAVG; | 
					
						
							| 
									
										
										
										
											2004-05-31 16:43:35 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 				int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 				t++; | 
					
						
							|  |  |  | 				switch (*t) { | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 					case 'C': /* color */ | 
					
						
							|  |  |  | 						t++; | 
					
						
							|  |  |  | 						if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) { | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 							strncat(p, term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 							t += i - 1; | 
					
						
							|  |  |  | 						} else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) { | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 							strncat(p, term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 							t += i - 1; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						/* If the color has been reset correctly, then there's no need to reset it later */ | 
					
						
							|  |  |  | 						if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) { | 
					
						
							|  |  |  | 							color_used = 0; | 
					
						
							|  |  |  | 						} else { | 
					
						
							|  |  |  | 							color_used = 1; | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 					case 'd': /* date */ | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 						memset(&tm, 0, sizeof(tm)); | 
					
						
							| 
									
										
										
										
											2005-12-26 18:35:28 +00:00
										 |  |  | 						time(&ts); | 
					
						
							|  |  |  | 						if (localtime_r(&ts, &tm)) { | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 							strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case 'h': /* hostname */ | 
					
						
							|  |  |  | 						if (!gethostname(hostname, sizeof(hostname) - 1)) { | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 							strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 							strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 					case 'H': /* short hostname */ | 
					
						
							|  |  |  | 						if (!gethostname(hostname, sizeof(hostname) - 1)) { | 
					
						
							|  |  |  | 							for (i=0;i<sizeof(hostname);i++) { | 
					
						
							|  |  |  | 								if (hostname[i] == '.') { | 
					
						
							|  |  |  | 									hostname[i] = '\0'; | 
					
						
							|  |  |  | 									break; | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 							strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 							strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | #ifdef linux
 | 
					
						
							|  |  |  | 					case 'l': /* load avg */ | 
					
						
							|  |  |  | 						t++; | 
					
						
							|  |  |  | 						if ((LOADAVG = fopen("/proc/loadavg", "r"))) { | 
					
						
							|  |  |  | 							float avg1, avg2, avg3; | 
					
						
							|  |  |  | 							int actproc, totproc, npid, which; | 
					
						
							|  |  |  | 							fscanf(LOADAVG, "%f %f %f %d/%d %d", | 
					
						
							|  |  |  | 								&avg1, &avg2, &avg3, &actproc, &totproc, &npid); | 
					
						
							|  |  |  | 							if (sscanf(t, "%d", &which) == 1) { | 
					
						
							|  |  |  | 								switch (which) { | 
					
						
							|  |  |  | 									case 1: | 
					
						
							|  |  |  | 										snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1); | 
					
						
							|  |  |  | 										break; | 
					
						
							|  |  |  | 									case 2: | 
					
						
							|  |  |  | 										snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2); | 
					
						
							|  |  |  | 										break; | 
					
						
							|  |  |  | 									case 3: | 
					
						
							|  |  |  | 										snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3); | 
					
						
							|  |  |  | 										break; | 
					
						
							|  |  |  | 									case 4: | 
					
						
							|  |  |  | 										snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc); | 
					
						
							|  |  |  | 										break; | 
					
						
							|  |  |  | 									case 5: | 
					
						
							|  |  |  | 										snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid); | 
					
						
							|  |  |  | 										break; | 
					
						
							|  |  |  | 								} | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 					case 't': /* time */ | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 						memset(&tm, 0, sizeof(tm)); | 
					
						
							| 
									
										
										
										
											2005-12-26 18:35:28 +00:00
										 |  |  | 						time(&ts); | 
					
						
							|  |  |  | 						if (localtime_r(&ts, &tm)) { | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 							strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm); | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case '#': /* process console or remote? */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 						if (!ast_opt_remote) { | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 							strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 						} else { | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 							strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 						} | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 					case '%': /* literal % */ | 
					
						
							| 
									
										
										
										
											2004-07-09 10:08:09 +00:00
										 |  |  | 						strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1); | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 						break; | 
					
						
							|  |  |  | 					case '\0': /* % is last character - prevent bug */ | 
					
						
							|  |  |  | 						t--; | 
					
						
							|  |  |  | 						break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				while (*p != '\0') { | 
					
						
							|  |  |  | 					p++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				t++; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				*p = *t; | 
					
						
							|  |  |  | 				p++; | 
					
						
							|  |  |  | 				t++; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-05-02 19:13:16 +00:00
										 |  |  | 		if (color_used) { | 
					
						
							|  |  |  | 			/* Force colors back to normal at end */ | 
					
						
							|  |  |  | 			term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code)); | 
					
						
							|  |  |  | 			if (strlen(term_code) > sizeof(prompt) - strlen(prompt)) { | 
					
						
							|  |  |  | 				strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code)); | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				strncat(p, term_code, sizeof(term_code)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-03-26 04:59:41 +00:00
										 |  |  | 	} else if (remotehostname) | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT2, remotehostname); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		snprintf(prompt, sizeof(prompt), ASTERISK_PROMPT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-04-08 13:45:36 +00:00
										 |  |  | 	return(prompt);	 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char **ast_el_strtoarr(char *buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char **match_list = NULL, *retstr; | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 	size_t match_list_len; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	int matches = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 	match_list_len = 1; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	while ( (retstr = strsep(&buf, " ")) != NULL) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-06 07:42:01 +00:00
										 |  |  | 		if (!strcmp(retstr, AST_CLI_COMPLETE_EOF)) | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 		if (matches + 1 >= match_list_len) { | 
					
						
							|  |  |  | 			match_list_len <<= 1; | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 			if (!(match_list = ast_realloc(match_list, match_list_len * sizeof(char *)))) { | 
					
						
							|  |  |  | 				/* TODO: Handle memory allocation failure */ | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-07 18:26:24 +00:00
										 |  |  | 		match_list[matches++] = strdup(retstr); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 	if (!match_list) | 
					
						
							|  |  |  | 		return (char **) NULL; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 	if (matches >= match_list_len) { | 
					
						
							|  |  |  | 		if (!(match_list = ast_realloc(match_list, (match_list_len + 1) * sizeof(char *)))) { | 
					
						
							|  |  |  | 			/* TODO: Handle memory allocation failure */ | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	match_list[matches] = (char *) NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return match_list; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ast_el_sort_compare(const void *i1, const void *i2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char *s1, *s2; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	s1 = ((char **)i1)[0]; | 
					
						
							|  |  |  | 	s2 = ((char **)i2)[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return strcasecmp(s1, s2); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ast_cli_display_match_list(char **matches, int len, int max) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int i, idx, limit, count; | 
					
						
							|  |  |  | 	int screenwidth = 0; | 
					
						
							|  |  |  | 	int numoutput = 0, numoutputline = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	screenwidth = ast_get_termcols(STDOUT_FILENO); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* find out how many entries can be put on one line, with two spaces between strings */ | 
					
						
							|  |  |  | 	limit = screenwidth / (max + 2); | 
					
						
							|  |  |  | 	if (limit == 0) | 
					
						
							|  |  |  | 		limit = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* how many lines of output */ | 
					
						
							|  |  |  | 	count = len / limit; | 
					
						
							|  |  |  | 	if (count * limit < len) | 
					
						
							|  |  |  | 		count++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	idx = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-07 15:17:10 +00:00
										 |  |  | 	qsort(&matches[0], (size_t)(len), sizeof(char *), ast_el_sort_compare); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	for (; count > 0; count--) { | 
					
						
							|  |  |  | 		numoutputline = 0; | 
					
						
							|  |  |  | 		for (i=0; i < limit && matches[idx]; i++, idx++) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			/* Don't print dupes */ | 
					
						
							|  |  |  | 			if ( (matches[idx+1] != NULL && strcmp(matches[idx], matches[idx+1]) == 0 ) ) { | 
					
						
							|  |  |  | 				i--; | 
					
						
							| 
									
										
										
										
											2004-07-16 20:41:17 +00:00
										 |  |  | 				free(matches[idx]); | 
					
						
							|  |  |  | 				matches[idx] = NULL; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-01 18:35:35 +00:00
										 |  |  | 			numoutput++; | 
					
						
							|  |  |  | 			numoutputline++; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			fprintf(stdout, "%-*s  ", max, matches[idx]); | 
					
						
							| 
									
										
										
										
											2004-07-16 20:41:17 +00:00
										 |  |  | 			free(matches[idx]); | 
					
						
							|  |  |  | 			matches[idx] = NULL; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (numoutputline > 0) | 
					
						
							|  |  |  | 			fprintf(stdout, "\n"); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return numoutput; | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char *cli_complete(EditLine *el, int ch) | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	int len=0; | 
					
						
							|  |  |  | 	char *ptr; | 
					
						
							|  |  |  | 	int nummatches = 0; | 
					
						
							|  |  |  | 	char **matches; | 
					
						
							|  |  |  | 	int retval = CC_ERROR; | 
					
						
							| 
									
										
										
										
											2004-03-24 08:09:01 +00:00
										 |  |  | 	char buf[2048]; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	int res; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	LineInfo *lf = (LineInfo *)el_line(el); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-09-04 03:55:41 +00:00
										 |  |  | 	*(char *)lf->cursor = '\0'; | 
					
						
							| 
									
										
										
										
											2003-02-21 06:00:08 +00:00
										 |  |  | 	ptr = (char *)lf->cursor; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	if (ptr) { | 
					
						
							|  |  |  | 		while (ptr > lf->buffer) { | 
					
						
							|  |  |  | 			if (isspace(*ptr)) { | 
					
						
							|  |  |  | 				ptr++; | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			ptr--; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	len = lf->cursor - ptr; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_remote) { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr);  | 
					
						
							|  |  |  | 		fdprint(ast_consock, buf); | 
					
						
							|  |  |  | 		res = read(ast_consock, buf, sizeof(buf)); | 
					
						
							|  |  |  | 		buf[res] = '\0'; | 
					
						
							|  |  |  | 		nummatches = atoi(buf); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (nummatches > 0) { | 
					
						
							| 
									
										
										
										
											2004-04-06 07:42:01 +00:00
										 |  |  | 			char *mbuf; | 
					
						
							|  |  |  | 			int mlen = 0, maxmbuf = 2048; | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 			/* Start with a 2048 byte buffer */			 | 
					
						
							|  |  |  | 			if (!(mbuf = ast_malloc(maxmbuf))) | 
					
						
							| 
									
										
										
										
											2004-04-07 18:26:24 +00:00
										 |  |  | 				return (char *)(CC_ERROR); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr);  | 
					
						
							|  |  |  | 			fdprint(ast_consock, buf); | 
					
						
							| 
									
										
										
										
											2004-04-06 07:42:01 +00:00
										 |  |  | 			res = 0; | 
					
						
							| 
									
										
										
										
											2004-04-09 17:46:04 +00:00
										 |  |  | 			mbuf[0] = '\0'; | 
					
						
							| 
									
										
										
										
											2004-04-06 07:42:01 +00:00
										 |  |  | 			while (!strstr(mbuf, AST_CLI_COMPLETE_EOF) && res != -1) { | 
					
						
							|  |  |  | 				if (mlen + 1024 > maxmbuf) { | 
					
						
							|  |  |  | 					/* Every step increment buffer 1024 bytes */ | 
					
						
							| 
									
										
										
										
											2006-02-14 22:28:01 +00:00
										 |  |  | 					maxmbuf += 1024;					 | 
					
						
							|  |  |  | 					if (!(mbuf = ast_realloc(mbuf, maxmbuf))) | 
					
						
							| 
									
										
										
										
											2004-04-07 18:26:24 +00:00
										 |  |  | 						return (char *)(CC_ERROR); | 
					
						
							| 
									
										
										
										
											2004-04-06 07:42:01 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 				/* Only read 1024 bytes at a time */ | 
					
						
							|  |  |  | 				res = read(ast_consock, mbuf + mlen, 1024); | 
					
						
							|  |  |  | 				if (res > 0) | 
					
						
							|  |  |  | 					mlen += res; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			mbuf[mlen] = '\0'; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-04-06 07:42:01 +00:00
										 |  |  | 			matches = ast_el_strtoarr(mbuf); | 
					
						
							|  |  |  | 			free(mbuf); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} else | 
					
						
							|  |  |  | 			matches = (char **) NULL; | 
					
						
							| 
									
										
										
										
											2004-10-01 18:35:35 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2006-01-07 15:17:10 +00:00
										 |  |  | 		char **p, *oldbuf=NULL; | 
					
						
							|  |  |  | 		nummatches = 0; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		matches = ast_cli_completion_matches((char *)lf->buffer,ptr); | 
					
						
							| 
									
										
										
										
											2006-01-07 15:17:10 +00:00
										 |  |  | 		for (p = matches; p && *p; p++) { | 
					
						
							|  |  |  | 			if (!oldbuf || strcmp(*p,oldbuf)) | 
					
						
							|  |  |  | 				nummatches++; | 
					
						
							|  |  |  | 			oldbuf = *p; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (matches) { | 
					
						
							|  |  |  | 		int i; | 
					
						
							|  |  |  | 		int matches_num, maxlen, match_len; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (matches[0][0] != '\0') { | 
					
						
							|  |  |  | 			el_deletestr(el, (int) len); | 
					
						
							|  |  |  | 			el_insertstr(el, matches[0]); | 
					
						
							|  |  |  | 			retval = CC_REFRESH; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (nummatches == 1) { | 
					
						
							|  |  |  | 			/* Found an exact match */ | 
					
						
							| 
									
										
										
										
											2003-04-08 13:45:36 +00:00
										 |  |  | 			el_insertstr(el, " "); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			retval = CC_REFRESH; | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			/* Must be more than one match */ | 
					
						
							|  |  |  | 			for (i=1, maxlen=0; matches[i]; i++) { | 
					
						
							|  |  |  | 				match_len = strlen(matches[i]); | 
					
						
							|  |  |  | 				if (match_len > maxlen) | 
					
						
							|  |  |  | 					maxlen = match_len; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			matches_num = i - 1; | 
					
						
							|  |  |  | 			if (matches_num >1) { | 
					
						
							|  |  |  | 				fprintf(stdout, "\n"); | 
					
						
							|  |  |  | 				ast_cli_display_match_list(matches, nummatches, maxlen); | 
					
						
							|  |  |  | 				retval = CC_REDISPLAY; | 
					
						
							|  |  |  | 			} else {  | 
					
						
							| 
									
										
										
										
											2003-04-08 13:45:36 +00:00
										 |  |  | 				el_insertstr(el," "); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 				retval = CC_REFRESH; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-12-27 17:24:54 +00:00
										 |  |  | 		free(matches); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-13 21:25:10 +00:00
										 |  |  | 	return (char *)(long)retval; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ast_el_initialize(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	HistEvent ev; | 
					
						
							| 
									
										
										
										
											2004-07-31 02:23:27 +00:00
										 |  |  | 	char *editor = getenv("AST_EDITOR"); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (el != NULL) | 
					
						
							|  |  |  | 		el_end(el); | 
					
						
							|  |  |  | 	if (el_hist != NULL) | 
					
						
							|  |  |  | 		history_end(el_hist); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	el = el_init("asterisk", stdin, stdout, stderr); | 
					
						
							|  |  |  | 	el_set(el, EL_PROMPT, cli_prompt); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	el_set(el, EL_EDITMODE, 1);		 | 
					
						
							| 
									
										
										
										
											2004-07-30 18:30:48 +00:00
										 |  |  | 	el_set(el, EL_EDITOR, editor ? editor : "emacs");		 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	el_hist = history_init(); | 
					
						
							|  |  |  | 	if (!el || !el_hist) | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* setup history with 100 entries */ | 
					
						
							|  |  |  | 	history(el_hist, &ev, H_SETSIZE, 100); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	el_set(el, EL_HIST, history, el_hist); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete); | 
					
						
							|  |  |  | 	/* Bind <tab> to command completion */ | 
					
						
							|  |  |  | 	el_set(el, EL_BIND, "^I", "ed-complete", NULL); | 
					
						
							|  |  |  | 	/* Bind ? to command completion */ | 
					
						
							|  |  |  | 	el_set(el, EL_BIND, "?", "ed-complete", NULL); | 
					
						
							| 
									
										
										
										
											2004-03-29 04:12:13 +00:00
										 |  |  | 	/* Bind ^D to redisplay */ | 
					
						
							|  |  |  | 	el_set(el, EL_BIND, "^D", "ed-redisplay", NULL); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ast_el_add_history(char *buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	HistEvent ev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (el_hist == NULL || el == NULL) | 
					
						
							|  |  |  | 		ast_el_initialize(); | 
					
						
							| 
									
										
										
										
											2004-01-23 19:12:44 +00:00
										 |  |  | 	if (strlen(buf) > 256) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	return (history(el_hist, &ev, H_ENTER, buf)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ast_el_write_history(char *filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	HistEvent ev; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (el_hist == NULL || el == NULL) | 
					
						
							|  |  |  | 		ast_el_initialize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return (history(el_hist, &ev, H_SAVE, filename)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int ast_el_read_history(char *filename) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char buf[256]; | 
					
						
							|  |  |  | 	FILE *f; | 
					
						
							|  |  |  | 	int ret = -1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (el_hist == NULL || el == NULL) | 
					
						
							|  |  |  | 		ast_el_initialize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if ((f = fopen(filename, "r")) == NULL) | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (!feof(f)) { | 
					
						
							|  |  |  | 		fgets(buf, sizeof(buf), f); | 
					
						
							|  |  |  | 		if (!strcmp(buf, "_HiStOrY_V2_\n")) | 
					
						
							|  |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2004-08-03 06:31:20 +00:00
										 |  |  | 		if (ast_all_zeros(buf)) | 
					
						
							|  |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		if ((ret = ast_el_add_history(buf)) == -1) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fclose(f); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void ast_remotecontrol(char * data) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char buf[80]; | 
					
						
							|  |  |  | 	int res; | 
					
						
							|  |  |  | 	char filename[80] = ""; | 
					
						
							|  |  |  | 	char *hostname; | 
					
						
							|  |  |  | 	char *cpid; | 
					
						
							|  |  |  | 	char *version; | 
					
						
							|  |  |  | 	int pid; | 
					
						
							|  |  |  | 	char tmp[80]; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	char *stringp=NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	char *ebuf; | 
					
						
							|  |  |  | 	int num = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	read(ast_consock, buf, sizeof(buf)); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	if (data) | 
					
						
							|  |  |  | 		write(ast_consock, data, strlen(data) + 1); | 
					
						
							|  |  |  | 	stringp=buf; | 
					
						
							|  |  |  | 	hostname = strsep(&stringp, "/"); | 
					
						
							|  |  |  | 	cpid = strsep(&stringp, "/"); | 
					
						
							| 
									
										
										
										
											2003-09-05 04:36:58 +00:00
										 |  |  | 	version = strsep(&stringp, "\n"); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	if (!version) | 
					
						
							|  |  |  | 		version = "<Version Unknown>"; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	stringp=hostname; | 
					
						
							|  |  |  | 	strsep(&stringp, "."); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	if (cpid) | 
					
						
							|  |  |  | 		pid = atoi(cpid); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		pid = -1; | 
					
						
							| 
									
										
										
										
											2004-12-29 07:46:10 +00:00
										 |  |  | 	snprintf(tmp, sizeof(tmp), "set verbose atleast %d", option_verbose); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	fdprint(ast_consock, tmp); | 
					
						
							| 
									
										
										
										
											2004-12-29 07:46:10 +00:00
										 |  |  | 	snprintf(tmp, sizeof(tmp), "set debug atleast %d", option_debug); | 
					
						
							| 
									
										
										
										
											2004-09-13 18:19:15 +00:00
										 |  |  | 	fdprint(ast_consock, tmp); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	ast_verbose("Connected to Asterisk %s currently running on %s (pid = %d)\n", version, hostname, pid); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	remotehostname = hostname; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	if (getenv("HOME"))  | 
					
						
							|  |  |  | 		snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	if (el_hist == NULL || el == NULL) | 
					
						
							|  |  |  | 		ast_el_initialize(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	el_set(el, EL_GETCFN, ast_el_read_char); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-05-04 14:54:42 +00:00
										 |  |  | 	if (!ast_strlen_zero(filename)) | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		ast_el_read_history(filename); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_exec && data) {  /* hack to print output then exit if asterisk -rx is used */ | 
					
						
							| 
									
										
										
										
											2003-06-23 16:40:12 +00:00
										 |  |  | 		char tempchar; | 
					
						
							| 
									
										
										
										
											2004-08-07 14:22:09 +00:00
										 |  |  | 		struct pollfd fds[0]; | 
					
						
							|  |  |  | 		fds[0].fd = ast_consock; | 
					
						
							|  |  |  | 		fds[0].events = POLLIN; | 
					
						
							|  |  |  | 		fds[0].revents = 0; | 
					
						
							|  |  |  | 		while(poll(fds, 1, 100) > 0) { | 
					
						
							|  |  |  | 			ast_el_read_char(el, &tempchar); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-06-23 16:40:12 +00:00
										 |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	for(;;) { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		ebuf = (char *)el_gets(el, &num); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-26 18:54:24 +00:00
										 |  |  | 		if (!ast_strlen_zero(ebuf)) { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			if (ebuf[strlen(ebuf)-1] == '\n') | 
					
						
							|  |  |  | 				ebuf[strlen(ebuf)-1] = '\0'; | 
					
						
							|  |  |  | 			if (!remoteconsolehandler(ebuf)) { | 
					
						
							|  |  |  | 				res = write(ast_consock, ebuf, strlen(ebuf) + 1); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 				if (res < 1) { | 
					
						
							|  |  |  | 					ast_log(LOG_WARNING, "Unable to write: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	printf("\nDisconnected from Asterisk server\n"); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 17:58:05 +00:00
										 |  |  | static int show_version(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	printf("Asterisk " ASTERISK_VERSION "\n"); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | static int show_cli_help(void) { | 
					
						
							| 
									
										
										
										
											2005-12-23 03:04:38 +00:00
										 |  |  | 	printf("Asterisk " ASTERISK_VERSION ", Copyright (C) 1999 - 2005, Digium, Inc. and others.\n"); | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 	printf("Usage: asterisk [OPTIONS]\n"); | 
					
						
							|  |  |  | 	printf("Valid Options:\n"); | 
					
						
							| 
									
										
										
										
											2004-07-18 17:58:05 +00:00
										 |  |  | 	printf("   -V              Display version number and exit\n"); | 
					
						
							| 
									
										
										
										
											2004-05-13 19:57:45 +00:00
										 |  |  | 	printf("   -C <configfile> Use an alternate configuration file\n"); | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 	printf("   -G <group>      Run as a group other than the caller\n"); | 
					
						
							|  |  |  | 	printf("   -U <user>       Run as a user other than the caller\n"); | 
					
						
							| 
									
										
										
										
											2004-05-13 19:57:45 +00:00
										 |  |  | 	printf("   -c              Provide console CLI\n"); | 
					
						
							|  |  |  | 	printf("   -d              Enable extra debugging\n"); | 
					
						
							|  |  |  | 	printf("   -f              Do not fork\n"); | 
					
						
							|  |  |  | 	printf("   -g              Dump core in case of a crash\n"); | 
					
						
							|  |  |  | 	printf("   -h              This help screen\n"); | 
					
						
							| 
									
										
										
										
											2004-12-28 07:51:25 +00:00
										 |  |  | 	printf("   -i              Initialize crypto keys at startup\n"); | 
					
						
							| 
									
										
										
										
											2004-05-13 19:57:45 +00:00
										 |  |  | 	printf("   -n              Disable console colorization\n"); | 
					
						
							|  |  |  | 	printf("   -p              Run as pseudo-realtime thread\n"); | 
					
						
							| 
									
										
										
										
											2004-12-28 07:51:25 +00:00
										 |  |  | 	printf("   -q              Quiet mode (suppress output)\n"); | 
					
						
							| 
									
										
										
										
											2004-05-13 19:57:45 +00:00
										 |  |  | 	printf("   -r              Connect to Asterisk on this machine\n"); | 
					
						
							| 
									
										
										
										
											2004-06-25 14:39:38 +00:00
										 |  |  | 	printf("   -R              Connect to Asterisk, and attempt to reconnect if disconnected\n"); | 
					
						
							| 
									
										
										
										
											2004-12-28 07:51:25 +00:00
										 |  |  | 	printf("   -t              Record soundfiles in /var/tmp and move them where they belong after they are done.\n"); | 
					
						
							| 
									
										
										
										
											2005-03-11 07:24:10 +00:00
										 |  |  | 	printf("   -T              Display the time in [Mmm dd hh:mm:ss] format for each line of output to the CLI.\n"); | 
					
						
							| 
									
										
										
										
											2004-05-13 19:57:45 +00:00
										 |  |  | 	printf("   -v              Increase verbosity (multiple v's = more verbose)\n"); | 
					
						
							|  |  |  | 	printf("   -x <cmd>        Execute command <cmd> (only valid with -r)\n"); | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 	printf("\n"); | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-03-16 22:37:31 +00:00
										 |  |  | static void ast_readconfig(void) { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	struct ast_config *cfg; | 
					
						
							|  |  |  | 	struct ast_variable *v; | 
					
						
							| 
									
										
										
										
											2005-06-06 03:04:58 +00:00
										 |  |  | 	char *config = AST_CONFIG_FILE; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_override_config) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 		cfg = ast_config_load(ast_config_AST_CONFIG_FILE); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:12:01 +00:00
										 |  |  | 		if (!cfg) | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			ast_log(LOG_WARNING, "Unable to open specified master config file '%s', using built-in defaults\n", ast_config_AST_CONFIG_FILE); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2005-01-25 06:10:20 +00:00
										 |  |  | 		cfg = ast_config_load(config); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* init with buildtime config */ | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 	ast_copy_string(ast_config_AST_CONFIG_DIR, AST_CONFIG_DIR, sizeof(ast_config_AST_CONFIG_DIR)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_SPOOL_DIR, AST_SPOOL_DIR, sizeof(ast_config_AST_SPOOL_DIR)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_MODULE_DIR, AST_MODULE_DIR, sizeof(ast_config_AST_VAR_DIR)); | 
					
						
							|  |  |  |  	snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", ast_config_AST_SPOOL_DIR); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_VAR_DIR, AST_VAR_DIR, sizeof(ast_config_AST_VAR_DIR)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_LOG_DIR, AST_LOG_DIR, sizeof(ast_config_AST_LOG_DIR)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_AGI_DIR, AST_AGI_DIR, sizeof(ast_config_AST_AGI_DIR)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_DB, AST_DB, sizeof(ast_config_AST_DB)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_KEY_DIR, AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_PID, AST_PID, sizeof(ast_config_AST_PID)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_SOCKET, AST_SOCKET, sizeof(ast_config_AST_SOCKET)); | 
					
						
							|  |  |  | 	ast_copy_string(ast_config_AST_RUN_DIR, AST_RUN_DIR, sizeof(ast_config_AST_RUN_DIR)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	/* no asterisk.conf? no problem, use buildtime config! */ | 
					
						
							|  |  |  | 	if (!cfg) { | 
					
						
							| 
									
										
										
										
											2004-09-07 14:36:56 +00:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 	v = ast_variable_browse(cfg, "files"); | 
					
						
							|  |  |  | 	while (v) { | 
					
						
							|  |  |  | 		if (!strcasecmp(v->name, "astctlpermissions")) { | 
					
						
							|  |  |  | 			ast_copy_string(ast_config_AST_CTL_PERMISSIONS, v->value, sizeof(ast_config_AST_CTL_PERMISSIONS)); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "astctlowner")) { | 
					
						
							|  |  |  | 			ast_copy_string(ast_config_AST_CTL_OWNER, v->value, sizeof(ast_config_AST_CTL_OWNER)); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "astctlgroup")) { | 
					
						
							|  |  |  | 			ast_copy_string(ast_config_AST_CTL_GROUP, v->value, sizeof(ast_config_AST_CTL_GROUP)); | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "astctl")) { | 
					
						
							|  |  |  | 			ast_copy_string(ast_config_AST_CTL, v->value, sizeof(ast_config_AST_CTL)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		v = v->next; | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	v = ast_variable_browse(cfg, "directories"); | 
					
						
							|  |  |  | 	while(v) { | 
					
						
							|  |  |  | 		if (!strcasecmp(v->name, "astetcdir")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			ast_copy_string(ast_config_AST_CONFIG_DIR, v->value, sizeof(ast_config_AST_CONFIG_DIR)); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "astspooldir")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			ast_copy_string(ast_config_AST_SPOOL_DIR, v->value, sizeof(ast_config_AST_SPOOL_DIR)); | 
					
						
							|  |  |  | 			snprintf(ast_config_AST_MONITOR_DIR, sizeof(ast_config_AST_MONITOR_DIR) - 1, "%s/monitor", v->value); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "astvarlibdir")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			ast_copy_string(ast_config_AST_VAR_DIR, v->value, sizeof(ast_config_AST_VAR_DIR)); | 
					
						
							| 
									
										
										
										
											2006-02-28 19:32:39 +00:00
										 |  |  | 			snprintf(ast_config_AST_DB, sizeof(ast_config_AST_DB), "%s/astdb", v->value); | 
					
						
							|  |  |  | 			snprintf(ast_config_AST_KEY_DIR, sizeof(ast_config_AST_KEY_DIR), "%s/keys", v->value); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "astlogdir")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			ast_copy_string(ast_config_AST_LOG_DIR, v->value, sizeof(ast_config_AST_LOG_DIR)); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "astagidir")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			ast_copy_string(ast_config_AST_AGI_DIR, v->value, sizeof(ast_config_AST_AGI_DIR)); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "astrundir")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			snprintf(ast_config_AST_PID, sizeof(ast_config_AST_PID), "%s/%s", v->value, "asterisk.pid"); | 
					
						
							|  |  |  | 			snprintf(ast_config_AST_SOCKET, sizeof(ast_config_AST_SOCKET), "%s/%s", v->value, ast_config_AST_CTL); | 
					
						
							|  |  |  | 			ast_copy_string(ast_config_AST_RUN_DIR, v->value, sizeof(ast_config_AST_RUN_DIR)); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "astmoddir")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			ast_copy_string(ast_config_AST_MODULE_DIR, v->value, sizeof(ast_config_AST_MODULE_DIR)); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		v = v->next; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 	v = ast_variable_browse(cfg, "options"); | 
					
						
							|  |  |  | 	while(v) { | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* verbose level (-v at startup) */ | 
					
						
							| 
									
										
										
										
											2004-10-01 18:35:35 +00:00
										 |  |  | 		if (!strcasecmp(v->name, "verbose")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			option_verbose = atoi(v->value); | 
					
						
							| 
									
										
										
										
											2005-03-11 07:24:10 +00:00
										 |  |  | 		/* whether or not to force timestamping. (-T at startup) */ | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "timestamp")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TIMESTAMP); | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* whether or not to support #exec in config files */ | 
					
						
							| 
									
										
										
										
											2005-02-02 03:38:24 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "execincludes")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_EXEC_INCLUDES); | 
					
						
							| 
									
										
										
										
											2005-02-09 21:17:34 +00:00
										 |  |  | 		/* debug level (-d at startup) */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "debug")) { | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 			option_debug = 0; | 
					
						
							|  |  |  | 			if (sscanf(v->value, "%d", &option_debug) != 1) { | 
					
						
							|  |  |  | 				option_debug = ast_true(v->value); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		/* Disable forking (-f at startup) */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "nofork")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_FORK); | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* Run quietly (-q at startup ) */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "quiet")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_QUIET); | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* Run as console (-c at startup, implies nofork) */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "console")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CONSOLE); | 
					
						
							| 
									
										
										
										
											2006-01-16 17:37:44 +00:00
										 |  |  | 		/* Run with high priority if the O/S permits (-p at startup) */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "highpriority")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIGH_PRIORITY); | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* Initialize RSA auth keys (IAX2) (-i at startup) */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "initcrypto")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INIT_KEYS); | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* Disable ANSI colors for console (-c at startup) */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "nocolor")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_NO_COLOR); | 
					
						
							| 
									
										
										
										
											2005-05-19 01:57:19 +00:00
										 |  |  | 		/* Disable some usage warnings for picky people :p */ | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "dontwarn")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DONT_WARN); | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* Dump core in case of crash (-g) */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "dumpcore")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_DUMP_CORE); | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* Cache recorded sound files to another directory during recording */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "cache_record_files")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_CACHE_RECORD_FILES); | 
					
						
							| 
									
										
										
										
											2005-02-09 00:13:52 +00:00
										 |  |  | 		/* Specify cache directory */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		}  else if (!strcasecmp(v->name, "record_cache_dir")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			ast_copy_string(record_cache_dir, v->value, AST_CACHE_DIR_LEN); | 
					
						
							| 
									
										
										
										
											2005-04-04 03:28:38 +00:00
										 |  |  | 		/* Build transcode paths via SLINEAR, instead of directly */ | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "transcode_via_sln")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSCODE_VIA_SLIN); | 
					
						
							| 
									
										
										
										
											2005-11-01 17:22:25 +00:00
										 |  |  | 		/* Transmit SLINEAR silence while a channel is being recorded */ | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "transmit_silence_during_record")) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE); | 
					
						
							| 
									
										
										
										
											2005-05-18 01:49:13 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "maxcalls")) { | 
					
						
							| 
									
										
										
										
											2005-07-25 23:09:13 +00:00
										 |  |  | 			if ((sscanf(v->value, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) { | 
					
						
							| 
									
										
										
										
											2005-05-18 01:49:13 +00:00
										 |  |  | 				option_maxcalls = 0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2005-10-26 03:58:32 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "maxload")) { | 
					
						
							| 
									
										
										
										
											2005-10-31 21:25:21 +00:00
										 |  |  | 			double test[1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (getloadavg(test, 1) == -1) { | 
					
						
							|  |  |  | 				ast_log(LOG_ERROR, "Cannot obtain load average on this system. 'maxload' option disabled.\n"); | 
					
						
							|  |  |  | 				option_maxload = 0.0; | 
					
						
							|  |  |  | 			} else if ((sscanf(v->value, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) { | 
					
						
							| 
									
										
										
										
											2005-10-26 03:58:32 +00:00
										 |  |  | 				option_maxload = 0.0; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2005-11-08 00:30:29 +00:00
										 |  |  | 		/* What user to run as */ | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "runuser")) { | 
					
						
							|  |  |  | 			ast_copy_string(ast_config_AST_RUN_USER, v->value, sizeof(ast_config_AST_RUN_USER)); | 
					
						
							|  |  |  | 		/* What group to run as */ | 
					
						
							|  |  |  | 		} else if (!strcasecmp(v->name, "rungroup")) { | 
					
						
							|  |  |  | 			ast_copy_string(ast_config_AST_RUN_GROUP, v->value, sizeof(ast_config_AST_RUN_GROUP)); | 
					
						
							| 
									
										
										
										
											2006-02-14 23:42:36 +00:00
										 |  |  | 		} else if (!strcasecmp(v->name, "systemname")) { | 
					
						
							|  |  |  | 			ast_copy_string(ast_config_AST_SYSTEM_NAME, v->value, sizeof(ast_config_AST_SYSTEM_NAME)); | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		v = v->next; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-01-25 06:10:20 +00:00
										 |  |  | 	ast_config_destroy(cfg); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | int main(int argc, char *argv[]) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2004-01-28 21:32:48 +00:00
										 |  |  | 	int c; | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	char filename[80] = ""; | 
					
						
							| 
									
										
										
										
											2005-05-08 16:44:25 +00:00
										 |  |  | 	char hostname[MAXHOSTNAMELEN]=""; | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	char tmp[80]; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	char * xarg = NULL; | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	int x; | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 	FILE *f; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	sigset_t sigs; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	int num; | 
					
						
							| 
									
										
										
										
											2005-08-23 01:37:26 +00:00
										 |  |  | 	int is_child_of_nonroot=0; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	char *buf; | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 	char *runuser=NULL, *rungroup=NULL; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	/* Remember original args for restart */ | 
					
						
							|  |  |  | 	if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) { | 
					
						
							| 
									
										
										
										
											2004-06-13 21:25:10 +00:00
										 |  |  | 		fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 		argc = sizeof(_argv) / sizeof(_argv[0]) - 1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for (x=0;x<argc;x++) | 
					
						
							|  |  |  | 		_argv[x] = argv[x]; | 
					
						
							|  |  |  | 	_argv[x] = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-03-20 07:26:54 +00:00
										 |  |  | 	/* if the progname is rasterisk consider it a remote console */ | 
					
						
							| 
									
										
										
										
											2004-10-01 18:35:35 +00:00
										 |  |  | 	if (argv[0] && (strstr(argv[0], "rasterisk")) != NULL) { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); | 
					
						
							| 
									
										
										
										
											2004-03-20 07:26:54 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-05-08 16:44:25 +00:00
										 |  |  | 	if (gethostname(hostname, sizeof(hostname)-1)) | 
					
						
							| 
									
										
										
										
											2005-06-05 16:32:16 +00:00
										 |  |  | 		ast_copy_string(hostname, "<Unknown>", sizeof(hostname)); | 
					
						
							| 
									
										
										
										
											2004-03-20 21:13:12 +00:00
										 |  |  | 	ast_mainpid = getpid(); | 
					
						
							| 
									
										
										
										
											2001-03-22 04:14:04 +00:00
										 |  |  | 	ast_ulaw_init(); | 
					
						
							| 
									
										
										
										
											2001-12-25 21:12:07 +00:00
										 |  |  | 	ast_alaw_init(); | 
					
						
							| 
									
										
										
										
											2001-03-22 04:14:04 +00:00
										 |  |  | 	callerid_init(); | 
					
						
							| 
									
										
										
										
											2004-06-25 04:07:52 +00:00
										 |  |  | 	ast_utils_init(); | 
					
						
							| 
									
										
										
										
											2001-12-25 21:12:07 +00:00
										 |  |  | 	tdd_init(); | 
					
						
							| 
									
										
										
										
											2005-08-23 01:37:26 +00:00
										 |  |  | 	/* When Asterisk restarts after it has dropped the root privileges,
 | 
					
						
							|  |  |  | 	 * it can't issue setuid(), setgid(), setgroups() or set_priority()  | 
					
						
							|  |  |  | 	 * */ | 
					
						
							|  |  |  | 	if (getenv("ASTERISK_ALREADY_NONROOT")) | 
					
						
							|  |  |  | 		is_child_of_nonroot=1; | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 	if (getenv("HOME"))  | 
					
						
							|  |  |  | 		snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	/* Check if we're root */ | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	if (geteuid()) { | 
					
						
							|  |  |  | 		ast_log(LOG_ERROR, "Must be run as root\n"); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	*/ | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	/* Check for options */ | 
					
						
							| 
									
										
										
										
											2005-10-26 03:58:32 +00:00
										 |  |  | 	while((c=getopt(argc, argv, "tThfdvVqprRgcinx:U:G:C:L:M:")) != -1) { | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 		switch(c) { | 
					
						
							|  |  |  | 		case 'd': | 
					
						
							|  |  |  | 			option_debug++; | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 		case 'c': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_CONSOLE); | 
					
						
							| 
									
										
										
										
											2001-03-22 04:14:04 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		case 'f': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 		case 'n': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_COLOR); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		case 'r': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-06-25 14:39:38 +00:00
										 |  |  | 		case 'R': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK | AST_OPT_FLAG_REMOTE | AST_OPT_FLAG_RECONNECT); | 
					
						
							| 
									
										
										
										
											2004-06-25 14:39:38 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											1999-12-19 22:38:55 +00:00
										 |  |  | 		case 'p': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_HIGH_PRIORITY); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case 'v': | 
					
						
							|  |  |  | 			option_verbose++; | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_NO_FORK); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2005-05-18 01:49:13 +00:00
										 |  |  | 		case 'M': | 
					
						
							|  |  |  | 			if ((sscanf(optarg, "%d", &option_maxcalls) != 1) || (option_maxcalls < 0)) | 
					
						
							|  |  |  | 				option_maxcalls = 0; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2005-10-26 03:58:32 +00:00
										 |  |  | 		case 'L': | 
					
						
							|  |  |  | 			if ((sscanf(optarg, "%lf", &option_maxload) != 1) || (option_maxload < 0.0)) | 
					
						
							|  |  |  | 				option_maxload = 0.0; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 		case 'q': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_QUIET); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 		case 't': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_CACHE_RECORD_FILES); | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2005-03-11 07:24:10 +00:00
										 |  |  | 		case 'T': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_TIMESTAMP); | 
					
						
							| 
									
										
										
										
											2005-03-11 07:24:10 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		case 'x': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_EXEC); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			xarg = optarg; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		case 'C': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_copy_string(ast_config_AST_CONFIG_FILE, optarg, sizeof(ast_config_AST_CONFIG_FILE)); | 
					
						
							|  |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_OVERRIDE_CONFIG); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-12-25 21:12:07 +00:00
										 |  |  | 		case 'i': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS); | 
					
						
							| 
									
										
										
										
											2001-12-25 21:12:07 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		case'g': | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_set_flag(&ast_options, AST_OPT_FLAG_DUMP_CORE); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 		case 'h': | 
					
						
							|  |  |  | 			show_cli_help(); | 
					
						
							|  |  |  | 			exit(0); | 
					
						
							| 
									
										
										
										
											2004-07-18 17:58:05 +00:00
										 |  |  | 		case 'V': | 
					
						
							|  |  |  | 			show_version(); | 
					
						
							|  |  |  | 			exit(0); | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 		case 'U': | 
					
						
							|  |  |  | 			runuser = optarg; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case 'G': | 
					
						
							|  |  |  | 			rungroup = optarg; | 
					
						
							|  |  |  | 			break; | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 		case '?': | 
					
						
							|  |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-29 02:38:24 +00:00
										 |  |  | 	/* For remote connections, change the name of the remote connection.
 | 
					
						
							|  |  |  | 	 * We do this for the benefit of init scripts (which need to know if/when | 
					
						
							|  |  |  | 	 * the main asterisk process has died yet). */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_remote) { | 
					
						
							| 
									
										
										
										
											2005-09-29 02:38:24 +00:00
										 |  |  | 		strcpy(argv[0], "rasterisk"); | 
					
						
							|  |  |  | 		for (x = 1; x < argc; x++) { | 
					
						
							|  |  |  | 			argv[x] = argv[0] + 10; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-16 23:52:51 +00:00
										 |  |  | 	if (ast_opt_console && !option_verbose)  | 
					
						
							|  |  |  | 		ast_verbose("[ Reading Master Configuration ]"); | 
					
						
							|  |  |  | 	ast_readconfig(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_dump_core) { | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		struct rlimit l; | 
					
						
							|  |  |  | 		memset(&l, 0, sizeof(l)); | 
					
						
							|  |  |  | 		l.rlim_cur = RLIM_INFINITY; | 
					
						
							|  |  |  | 		l.rlim_max = RLIM_INFINITY; | 
					
						
							|  |  |  | 		if (setrlimit(RLIMIT_CORE, &l)) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno)); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-08 00:30:29 +00:00
										 |  |  | 	if ((!rungroup) && !ast_strlen_zero(ast_config_AST_RUN_GROUP)) | 
					
						
							|  |  |  | 		rungroup = ast_config_AST_RUN_GROUP; | 
					
						
							|  |  |  | 	if ((!runuser) && !ast_strlen_zero(ast_config_AST_RUN_USER)) | 
					
						
							|  |  |  | 		runuser = ast_config_AST_RUN_USER; | 
					
						
							| 
									
										
										
										
											2005-11-01 21:53:30 +00:00
										 |  |  | #ifndef __CYGWIN__
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-08 02:19:53 +00:00
										 |  |  | 	if (!is_child_of_nonroot)  | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		ast_set_priority(ast_opt_high_priority); | 
					
						
							| 
									
										
										
										
											2005-03-26 07:16:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-23 01:37:26 +00:00
										 |  |  | 	if (!is_child_of_nonroot && rungroup) { | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 		struct group *gr; | 
					
						
							|  |  |  | 		gr = getgrnam(rungroup); | 
					
						
							|  |  |  | 		if (!gr) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup); | 
					
						
							|  |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-07-18 18:52:36 +00:00
										 |  |  | 		if (setgid(gr->gr_gid)) { | 
					
						
							| 
									
										
										
										
											2006-03-02 22:27:50 +00:00
										 |  |  | 			ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", (int)gr->gr_gid, rungroup); | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-11-08 00:30:29 +00:00
										 |  |  | 		if (setgroups(0, NULL)) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to drop unneeded groups\n"); | 
					
						
							|  |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 		if (option_verbose) | 
					
						
							|  |  |  | 			ast_verbose("Running as group '%s'\n", rungroup); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-23 01:37:26 +00:00
										 |  |  | 	if (!is_child_of_nonroot && runuser) { | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 		struct passwd *pw; | 
					
						
							|  |  |  | 		pw = getpwnam(runuser); | 
					
						
							|  |  |  | 		if (!pw) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "No such user '%s'!\n", runuser); | 
					
						
							|  |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-01-08 20:27:22 +00:00
										 |  |  | 		if (!rungroup) { | 
					
						
							|  |  |  | 			if (setgid(pw->pw_gid)) { | 
					
						
							| 
									
										
										
										
											2006-03-02 22:27:50 +00:00
										 |  |  | 				ast_log(LOG_WARNING, "Unable to setgid to %d!\n", (int)pw->pw_gid); | 
					
						
							| 
									
										
										
										
											2006-01-08 20:27:22 +00:00
										 |  |  | 				exit(1); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-01-07 20:08:51 +00:00
										 |  |  | 			if (initgroups(pw->pw_name, pw->pw_gid)) { | 
					
						
							|  |  |  | 				ast_log(LOG_WARNING, "Unable to init groups for '%s'\n", runuser); | 
					
						
							|  |  |  | 				exit(1); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2006-01-07 19:42:05 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 		if (setuid(pw->pw_uid)) { | 
					
						
							| 
									
										
										
										
											2006-03-02 22:27:50 +00:00
										 |  |  | 			ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", (int)pw->pw_uid, runuser); | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-08-23 01:37:26 +00:00
										 |  |  | 		setenv("ASTERISK_ALREADY_NONROOT","yes",1); | 
					
						
							| 
									
										
										
										
											2004-07-18 16:20:54 +00:00
										 |  |  | 		if (option_verbose) | 
					
						
							|  |  |  | 			ast_verbose("Running as user '%s'\n", runuser); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-01 21:53:30 +00:00
										 |  |  | #endif /* __CYGWIN__ */
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-02-14 18:47:16 +00:00
										 |  |  | #ifdef linux
 | 
					
						
							| 
									
										
										
										
											2006-02-14 02:41:42 +00:00
										 |  |  | 	if (geteuid() && ast_opt_dump_core) { | 
					
						
							|  |  |  | 		if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) { | 
					
						
							|  |  |  | 			ast_log(LOG_WARNING, "Unable to set the process for core dumps after changing to a non-root user. %s\n", strerror(errno)); | 
					
						
							|  |  |  | 		}	 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-02-14 18:47:16 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-02-14 02:41:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	term_init(); | 
					
						
							|  |  |  | 	printf(term_end()); | 
					
						
							|  |  |  | 	fflush(stdout); | 
					
						
							| 
									
										
										
										
											2004-06-22 17:42:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_console && !option_verbose)  | 
					
						
							| 
									
										
										
										
											2005-01-25 06:10:20 +00:00
										 |  |  | 		ast_verbose("[ Initializing Custom Configuration Options ]"); | 
					
						
							| 
									
										
										
										
											2004-06-11 00:12:35 +00:00
										 |  |  | 	/* custom config setup */ | 
					
						
							|  |  |  | 	register_config_cli(); | 
					
						
							| 
									
										
										
										
											2005-01-25 06:10:20 +00:00
										 |  |  | 	read_config_maps(); | 
					
						
							| 
									
										
										
										
											2004-06-11 00:12:35 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_console) { | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 		if (el_hist == NULL || el == NULL) | 
					
						
							|  |  |  | 			ast_el_initialize(); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-29 04:42:19 +00:00
										 |  |  | 		if (!ast_strlen_zero(filename)) | 
					
						
							|  |  |  | 			ast_el_read_history(filename); | 
					
						
							| 
									
										
										
										
											2003-04-16 13:43:11 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	if (ast_tryconnect()) { | 
					
						
							|  |  |  | 		/* One is already running */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		if (ast_opt_remote) { | 
					
						
							|  |  |  | 			if (ast_opt_exec) { | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 				ast_remotecontrol(xarg); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 				quit_handler(0, 0, 0, 0); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 				exit(0); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 			printf(term_quit()); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			ast_register_verbose(console_verboser); | 
					
						
							| 
									
										
										
										
											2004-06-25 21:14:03 +00:00
										 |  |  | 			WELCOME_MESSAGE; | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			ast_remotecontrol(NULL); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 			quit_handler(0, 0, 0, 0); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			exit(0); | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_log(LOG_ERROR, "Asterisk already running on %s.  Use 'asterisk -r' to connect.\n", ast_config_AST_SOCKET); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 			printf(term_quit()); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 			exit(1); | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	} else if (ast_opt_remote || ast_opt_exec) { | 
					
						
							| 
									
										
										
										
											2005-02-11 21:16:34 +00:00
										 |  |  | 		ast_log(LOG_ERROR, "Unable to connect to remote asterisk (does %s exist?)\n",ast_config_AST_SOCKET); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 		printf(term_quit()); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 	/* Blindly write pid file since we couldn't connect */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	unlink(ast_config_AST_PID); | 
					
						
							|  |  |  | 	f = fopen(ast_config_AST_PID, "w"); | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 	if (f) { | 
					
						
							| 
									
										
										
										
											2006-03-02 22:27:50 +00:00
										 |  |  | 		fprintf(f, "%d\n", (int)getpid()); | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 		fclose(f); | 
					
						
							|  |  |  | 	} else | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2001-12-25 21:12:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (!option_verbose && !option_debug && !ast_opt_no_fork && !ast_opt_console) { | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 		daemon(0,0); | 
					
						
							| 
									
										
										
										
											2003-10-16 10:27:41 +00:00
										 |  |  | 		/* Blindly re-write pid file since we are forking */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 		unlink(ast_config_AST_PID); | 
					
						
							|  |  |  | 		f = fopen(ast_config_AST_PID, "w"); | 
					
						
							| 
									
										
										
										
											2003-10-16 10:27:41 +00:00
										 |  |  | 		if (f) { | 
					
						
							| 
									
										
										
										
											2006-03-02 22:27:50 +00:00
										 |  |  | 			fprintf(f, "%d\n", (int)getpid()); | 
					
						
							| 
									
										
										
										
											2003-10-16 10:27:41 +00:00
										 |  |  | 			fclose(f); | 
					
						
							|  |  |  | 		} else | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 			ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", ast_config_AST_PID, strerror(errno)); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-12-25 21:12:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-09-28 17:11:30 +00:00
										 |  |  | 	/* Test recursive mutex locking. */ | 
					
						
							|  |  |  | 	if (test_for_thread_safety()) | 
					
						
							|  |  |  | 		ast_verbose("Warning! Asterisk is not thread safe.\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	ast_makesocket(); | 
					
						
							|  |  |  | 	sigemptyset(&sigs); | 
					
						
							|  |  |  | 	sigaddset(&sigs, SIGHUP); | 
					
						
							|  |  |  | 	sigaddset(&sigs, SIGTERM); | 
					
						
							|  |  |  | 	sigaddset(&sigs, SIGINT); | 
					
						
							|  |  |  | 	sigaddset(&sigs, SIGPIPE); | 
					
						
							|  |  |  | 	sigaddset(&sigs, SIGWINCH); | 
					
						
							|  |  |  | 	pthread_sigmask(SIG_BLOCK, &sigs, NULL); | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_console || option_verbose || ast_opt_remote) | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 		ast_register_verbose(console_verboser); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	/* Print a welcome message if desired */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (option_verbose || ast_opt_console) { | 
					
						
							| 
									
										
										
										
											2004-06-25 21:14:03 +00:00
										 |  |  | 		WELCOME_MESSAGE; | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_console && !option_verbose)  | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 		ast_verbose("[ Booting..."); | 
					
						
							| 
									
										
										
										
											2003-09-16 19:35:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	signal(SIGURG, urg_handler); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	signal(SIGINT, __quit_handler); | 
					
						
							|  |  |  | 	signal(SIGTERM, __quit_handler); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	signal(SIGHUP, hup_handler); | 
					
						
							| 
									
										
										
										
											2003-09-16 19:35:57 +00:00
										 |  |  | 	signal(SIGCHLD, child_handler); | 
					
						
							|  |  |  | 	signal(SIGPIPE, SIG_IGN); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-13 04:47:39 +00:00
										 |  |  | 	/* ensure that the random number generators are seeded with a different value every time
 | 
					
						
							|  |  |  | 	   Asterisk is started | 
					
						
							|  |  |  | 	*/ | 
					
						
							|  |  |  | 	srand((unsigned int) getpid() + (unsigned int) time(NULL)); | 
					
						
							| 
									
										
										
										
											2006-01-10 00:55:45 +00:00
										 |  |  | 	initstate((unsigned int) getpid() * 65536 + (unsigned int) time(NULL), randompool, sizeof(randompool)); | 
					
						
							| 
									
										
										
										
											2005-04-13 04:47:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	if (init_logger()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 		exit(1); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-08-14 23:47:40 +00:00
										 |  |  | 	if (dnsmgr_init()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-05 22:11:43 +00:00
										 |  |  | 	/* load 'preload' modules, required for access to Realtime-mapped configuration files */ | 
					
						
							|  |  |  | 	if (load_modules(1)) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-12-31 00:04:41 +00:00
										 |  |  | 	ast_channels_init(); | 
					
						
							| 
									
										
										
										
											2002-09-12 03:22:07 +00:00
										 |  |  | 	if (init_manager()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-06-03 01:42:31 +00:00
										 |  |  | 	if (ast_cdr_engine_init()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-08 21:14:34 +00:00
										 |  |  | 	if (ast_device_state_engine_init()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-05-16 02:50:46 +00:00
										 |  |  | 	ast_rtp_init(); | 
					
						
							| 
									
										
										
										
											2006-01-12 17:14:58 +00:00
										 |  |  | #if defined(T38_SUPPORT)
 | 
					
						
							|  |  |  | 	ast_udptl_init(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	if (ast_image_init()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							| 
									
										
										
										
											2001-10-11 18:51:39 +00:00
										 |  |  | 		exit(1); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-06-30 03:22:29 +00:00
										 |  |  | 	if (ast_file_init()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	if (load_pbx()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 		exit(1); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-05 22:11:43 +00:00
										 |  |  | 	if (load_modules(0)) { | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 		printf(term_quit()); | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 		exit(1); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if (init_framer()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							| 
									
										
										
										
											2001-10-11 18:51:39 +00:00
										 |  |  | 		exit(1); | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 	if (astdb_init()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2003-05-01 04:29:25 +00:00
										 |  |  | 	if (ast_enum_init()) { | 
					
						
							|  |  |  | 		printf(term_quit()); | 
					
						
							|  |  |  | 		exit(1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-11-08 01:29:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	dnsmgr_start_refresh(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-05 06:46:11 +00:00
										 |  |  | #if 0
 | 
					
						
							|  |  |  | 	/* This should no longer be necessary */ | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 	/* sync cust config and reload some internals in case a custom config handler binded to them */ | 
					
						
							|  |  |  | 	read_ast_cust_config(); | 
					
						
							| 
									
										
										
										
											2004-06-15 19:31:25 +00:00
										 |  |  | 	reload_logger(0); | 
					
						
							| 
									
										
										
										
											2004-09-07 14:36:56 +00:00
										 |  |  | 	reload_manager(); | 
					
						
							|  |  |  | 	ast_enum_reload(); | 
					
						
							|  |  |  | 	ast_rtp_reload(); | 
					
						
							| 
									
										
										
										
											2004-10-05 06:46:11 +00:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2004-09-07 01:49:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-06-15 18:48:07 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	/* We might have the option of showing a console, but for now just
 | 
					
						
							|  |  |  | 	   do nothing... */ | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_console && !option_verbose) | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 		ast_verbose(" ]\n"); | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (option_verbose || ast_opt_console) | 
					
						
							| 
									
										
										
										
											2002-05-14 14:43:52 +00:00
										 |  |  | 		ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp))); | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_no_fork) | 
					
						
							| 
									
										
										
										
											2004-03-02 23:50:03 +00:00
										 |  |  | 		consolethread = pthread_self(); | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	ast_set_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED); | 
					
						
							| 
									
										
										
										
											2001-05-09 03:11:22 +00:00
										 |  |  | 	pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); | 
					
						
							| 
									
										
										
										
											2003-04-28 19:58:43 +00:00
										 |  |  | #ifdef __AST_DEBUG_MALLOC
 | 
					
						
							|  |  |  | 	__ast_mm_init(); | 
					
						
							|  |  |  | #endif	
 | 
					
						
							| 
									
										
										
										
											2003-05-02 15:37:34 +00:00
										 |  |  | 	time(&ast_startuptime); | 
					
						
							| 
									
										
										
										
											2005-06-03 03:04:08 +00:00
										 |  |  | 	ast_cli_register_multiple(core_cli, sizeof(core_cli) / sizeof(core_cli[0])); | 
					
						
							| 
									
										
										
										
											2005-12-04 20:40:46 +00:00
										 |  |  | 	if (ast_opt_console) { | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 		/* Console stuff now... */ | 
					
						
							|  |  |  | 		/* Register our quit function */ | 
					
						
							| 
									
										
										
										
											2000-10-25 23:22:50 +00:00
										 |  |  | 		char title[256]; | 
					
						
							|  |  |  | 		set_icon("Asterisk"); | 
					
						
							| 
									
										
										
										
											2004-03-20 21:13:12 +00:00
										 |  |  | 		snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, ast_mainpid); | 
					
						
							| 
									
										
										
										
											2000-10-25 23:22:50 +00:00
										 |  |  | 		set_title(title); | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-05-22 14:24:06 +00:00
										 |  |  | 		for (;;) { | 
					
						
							|  |  |  | 			buf = (char *)el_gets(el, &num); | 
					
						
							|  |  |  | 			if (buf) { | 
					
						
							|  |  |  | 				if (buf[strlen(buf)-1] == '\n') | 
					
						
							|  |  |  | 					buf[strlen(buf)-1] = '\0'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				consolehandler((char *)buf); | 
					
						
							| 
									
										
										
										
											2003-08-21 02:34:03 +00:00
										 |  |  | 			} else { | 
					
						
							| 
									
										
										
										
											2005-01-15 08:53:28 +00:00
										 |  |  | 				if (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n", | 
					
						
							|  |  |  | 								  strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0) { | 
					
						
							|  |  |  | 					/* Whoa, stdout disappeared from under us... Make /dev/null's */ | 
					
						
							|  |  |  | 					int fd; | 
					
						
							|  |  |  | 					fd = open("/dev/null", O_RDWR); | 
					
						
							|  |  |  | 					if (fd > -1) { | 
					
						
							|  |  |  | 						dup2(fd, STDOUT_FILENO); | 
					
						
							|  |  |  | 						dup2(fd, STDIN_FILENO); | 
					
						
							|  |  |  | 					} else | 
					
						
							|  |  |  | 						ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console.  Bad things will happen!\n"); | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2003-08-21 02:34:03 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-02-06 06:15:25 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-01-02 20:59:00 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-01-15 08:53:28 +00:00
										 |  |  | 	/* Do nothing */ | 
					
						
							| 
									
										
										
										
											2005-06-03 02:41:59 +00:00
										 |  |  | 	for(;;)  {	/* apparently needed for the MACos */ | 
					
						
							|  |  |  | 		struct pollfd p = { -1 /* no descriptor */, 0, 0 }; | 
					
						
							|  |  |  | 		poll(&p, 0, -1); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											1999-11-15 04:57:28 +00:00
										 |  |  | 	return 0; | 
					
						
							|  |  |  | } |