#include <unistd.h>
#include <stdlib.h>
#include <sys/poll.h>
#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>
#include <asterisk/pbx.h>
#include <asterisk/enum.h>
#include <asterisk/rtp.h>
#include <asterisk/app.h>
#include <asterisk/lock.h>
#include <asterisk/utils.h>
#include <asterisk/file.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <stdio.h>
#include <signal.h>
#include <sched.h>
#include <asterisk/io.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/wait.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "editline/histedit.h"
#include "asterisk.h"
#include <asterisk/config.h>
#include <asterisk/config_pvt.h>
#include <grp.h>
#include <pwd.h>
Go to the source code of this file.
Defines | |
#define | AST_MAX_CONNECTS 128 |
#define | NUM_MSGS 64 |
#define | WELCOME_MESSAGE |
#define | ASTERISK_PROMPT "*CLI> " |
#define | ASTERISK_PROMPT2 "%s*CLI> " |
Functions | |
AST_MUTEX_DEFINE_STATIC (atexitslock) | |
int | ast_register_atexit (void(*func)(void)) |
void | ast_unregister_atexit (void(*func)(void)) |
int | ast_safe_system (const char *s) |
Safely spawn an external program while closingn file descriptors. | |
void | ast_console_puts (const char *string) |
int | main (int argc, char *argv[]) |
Variables | |
int | option_verbose = 0 |
int | option_debug = 0 |
int | option_nofork = 0 |
int | option_quiet = 0 |
int | option_console = 0 |
int | option_highpriority = 0 |
int | option_remote = 0 |
int | option_exec = 0 |
int | option_initcrypto = 0 |
int | option_nocolor |
int | option_dumpcore = 0 |
int | option_cache_record_files = 0 |
int | option_overrideconfig = 0 |
int | option_reconnect = 0 |
int | fully_booted = 0 |
char | record_cache_dir [AST_CACHE_DIR_LEN] = AST_TMP_DIR |
int | ast_mainpid |
time_t | ast_startuptime |
time_t | ast_lastreloadtime |
console | consoles [AST_MAX_CONNECTS] |
char | defaultlanguage [MAX_LANGUAGE] = DEFAULT_LANGUAGE |
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] |
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] |
char | ast_config_AST_DATA_DIR [AST_CONFIG_MAX_PATH] |
char | ast_config_AST_SYMBOLIC_NAME [20] |
|
Definition at line 61 of file asterisk.c. |
|
Definition at line 861 of file asterisk.c. |
|
Definition at line 863 of file asterisk.c. |
|
Definition at line 62 of file asterisk.c. |
|
Value: ast_verbose( "Asterisk " ASTERISK_VERSION ", Copyright (C) 1999-2004 Digium.\n"); \ ast_verbose( "Written by Mark Spencer <markster@digium.com>\n"); \ ast_verbose( "=========================================================================\n") Definition at line 64 of file asterisk.c. Referenced by main(). |
|
Definition at line 238 of file asterisk.c. References string. Referenced by ast_log(). 00239 { 00240 fputs(string, stdout); 00241 fflush(stdout); 00242 ast_network_puts(string); 00243 }
|
|
|
|
Definition at line 135 of file asterisk.c. References ast_mutex_lock, ast_mutex_unlock, ast_unregister_atexit(), and malloc. 00136 { 00137 int res = -1; 00138 struct ast_atexit *ae; 00139 ast_unregister_atexit(func); 00140 ae = malloc(sizeof(struct ast_atexit)); 00141 ast_mutex_lock(&atexitslock); 00142 if (ae) { 00143 memset(ae, 0, sizeof(struct ast_atexit)); 00144 ae->next = atexits; 00145 ae->func = func; 00146 atexits = ae; 00147 res = 0; 00148 } 00149 ast_mutex_unlock(&atexitslock); 00150 return res; 00151 }
|
|
Safely spawn an external program while closingn file descriptors.
Definition at line 183 of file asterisk.c. References ast_log(), LOG_WARNING, and s. Referenced by ast_closestream(). 00184 { 00185 /* XXX This function needs some optimization work XXX */ 00186 pid_t pid; 00187 int x; 00188 int res; 00189 struct rusage rusage; 00190 int status; 00191 void (*prev_handler) = signal(SIGCHLD, null_sig_handler); 00192 pid = fork(); 00193 if (pid == 0) { 00194 /* Close file descriptors and launch system command */ 00195 for (x=STDERR_FILENO + 1; x<4096;x++) { 00196 close(x); 00197 } 00198 res = execl("/bin/sh", "/bin/sh", "-c", s, NULL); 00199 exit(1); 00200 } else if (pid > 0) { 00201 for(;;) { 00202 res = wait4(pid, &status, 0, &rusage); 00203 if (res > -1) { 00204 if (WIFEXITED(status)) 00205 res = WEXITSTATUS(status); 00206 else 00207 res = -1; 00208 break; 00209 } else { 00210 if (errno != EINTR) 00211 break; 00212 } 00213 } 00214 } else { 00215 ast_log(LOG_WARNING, "Fork failed: %s\n", strerror(errno)); 00216 res = -1; 00217 } 00218 signal(SIGCHLD, prev_handler); 00219 return res; 00220 }
|
|
Definition at line 153 of file asterisk.c. References ast_mutex_lock, and ast_mutex_unlock. Referenced by ast_register_atexit(). 00154 { 00155 struct ast_atexit *ae, *prev = NULL; 00156 ast_mutex_lock(&atexitslock); 00157 ae = atexits; 00158 while(ae) { 00159 if (ae->func == func) { 00160 if (prev) 00161 prev->next = ae->next; 00162 else 00163 atexits = ae->next; 00164 break; 00165 } 00166 prev = ae; 00167 ae = ae->next; 00168 } 00169 ast_mutex_unlock(&atexitslock); 00170 }
|
|
Definition at line 1577 of file asterisk.c. References __ast_mm_init(), ast_alaw_init(), ast_cli_register(), ast_config_AST_CONFIG_FILE, ast_config_AST_PID, ast_config_AST_SOCKET, ast_enum_init(), ast_enum_reload(), ast_file_init(), ast_image_init(), ast_log(), ast_mainpid, ast_register_verbose(), ast_rtp_init(), ast_rtp_reload(), ast_startuptime, ast_ulaw_init(), ast_utils_init(), ast_verbose(), astdb_init(), callerid_init(), COLOR_BLACK, COLOR_BRWHITE, fully_booted, init_framer(), init_logger(), init_manager(), load_modules(), load_pbx(), LOG_ERROR, LOG_WARNING, option_cache_record_files, option_console, option_debug, option_dumpcore, option_exec, option_highpriority, option_initcrypto, option_nocolor, option_nofork, option_overrideconfig, option_quiet, option_reconnect, option_remote, option_verbose, poll(), read_ast_cust_config(), register_config_cli(), reload_logger(), reload_manager(), tdd_init(), term_color(), term_end(), term_init(), term_quit(), test_for_thread_safety(), and WELCOME_MESSAGE. 01578 { 01579 int c; 01580 char filename[80] = ""; 01581 char hostname[256]; 01582 char tmp[80]; 01583 char * xarg = NULL; 01584 int x; 01585 FILE *f; 01586 sigset_t sigs; 01587 int num; 01588 char *buf; 01589 char *runuser=NULL, *rungroup=NULL; 01590 struct pollfd silly_macos[1]; 01591 01592 /* Remember original args for restart */ 01593 if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) { 01594 fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1); 01595 argc = sizeof(_argv) / sizeof(_argv[0]) - 1; 01596 } 01597 for (x=0;x<argc;x++) 01598 _argv[x] = argv[x]; 01599 _argv[x] = NULL; 01600 01601 /* if the progname is rasterisk consider it a remote console */ 01602 if ( argv[0] && (strstr(argv[0], "rasterisk")) != NULL) { 01603 option_remote++; 01604 option_nofork++; 01605 } 01606 if (gethostname(hostname, sizeof(hostname))) 01607 strncpy(hostname, "<Unknown>", sizeof(hostname)-1); 01608 ast_mainpid = getpid(); 01609 ast_ulaw_init(); 01610 ast_alaw_init(); 01611 callerid_init(); 01612 ast_utils_init(); 01613 tdd_init(); 01614 if (getenv("HOME")) 01615 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME")); 01616 /* Check for options */ 01617 while((c=getopt(argc, argv, "thfdvVqprRgcinx:U:G:C:")) != -1) { 01618 switch(c) { 01619 case 'd': 01620 option_debug++; 01621 option_nofork++; 01622 break; 01623 case 'c': 01624 option_console++; 01625 option_nofork++; 01626 break; 01627 case 'f': 01628 option_nofork++; 01629 break; 01630 case 'n': 01631 option_nocolor++; 01632 break; 01633 case 'r': 01634 option_remote++; 01635 option_nofork++; 01636 break; 01637 case 'R': 01638 option_remote++; 01639 option_nofork++; 01640 option_reconnect++; 01641 break; 01642 case 'p': 01643 option_highpriority++; 01644 break; 01645 case 'v': 01646 option_verbose++; 01647 option_nofork++; 01648 break; 01649 case 'q': 01650 option_quiet++; 01651 break; 01652 case 't': 01653 option_cache_record_files++; 01654 break; 01655 case 'x': 01656 option_exec++; 01657 xarg = optarg; 01658 break; 01659 case 'C': 01660 strncpy((char *)ast_config_AST_CONFIG_FILE,optarg,sizeof(ast_config_AST_CONFIG_FILE) - 1); 01661 option_overrideconfig++; 01662 break; 01663 case 'i': 01664 option_initcrypto++; 01665 break; 01666 case'g': 01667 option_dumpcore++; 01668 break; 01669 case 'h': 01670 show_cli_help(); 01671 exit(0); 01672 case 'V': 01673 show_version(); 01674 exit(0); 01675 case 'U': 01676 runuser = optarg; 01677 break; 01678 case 'G': 01679 rungroup = optarg; 01680 break; 01681 case '?': 01682 exit(1); 01683 } 01684 } 01685 01686 if (option_dumpcore) { 01687 struct rlimit l; 01688 memset(&l, 0, sizeof(l)); 01689 l.rlim_cur = RLIM_INFINITY; 01690 l.rlim_max = RLIM_INFINITY; 01691 if (setrlimit(RLIMIT_CORE, &l)) { 01692 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno)); 01693 } 01694 } 01695 01696 if (rungroup) { 01697 struct group *gr; 01698 gr = getgrnam(rungroup); 01699 if (!gr) { 01700 ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup); 01701 exit(1); 01702 } 01703 if (setgid(gr->gr_gid)) { 01704 ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", gr->gr_gid, rungroup); 01705 exit(1); 01706 } 01707 if (option_verbose) 01708 ast_verbose("Running as group '%s'\n", rungroup); 01709 } 01710 01711 if (set_priority(option_highpriority)) { 01712 exit(1); 01713 } 01714 if (runuser) { 01715 struct passwd *pw; 01716 pw = getpwnam(runuser); 01717 if (!pw) { 01718 ast_log(LOG_WARNING, "No such user '%s'!\n", runuser); 01719 exit(1); 01720 } 01721 if (!rungroup && initgroups(runuser, pw->pw_gid)) { 01722 ast_log(LOG_WARNING, "Unable to initialize supplementary group list for %s\n", runuser); 01723 exit(1); 01724 } 01725 if (setuid(pw->pw_uid)) { 01726 ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", pw->pw_uid, runuser); 01727 exit(1); 01728 } 01729 if (option_verbose) 01730 ast_verbose("Running as user '%s'\n", runuser); 01731 } 01732 01733 term_init(); 01734 printf(term_end()); 01735 fflush(stdout); 01736 01737 if (option_console && !option_verbose) 01738 ast_verbose("[ Reading Master Configuration ]"); 01739 ast_readconfig(); 01740 01741 if (option_console && !option_verbose) 01742 ast_verbose("[ Initializing Custom Configuration Options]"); 01743 /* custom config setup */ 01744 register_config_cli(); 01745 read_ast_cust_config(); 01746 01747 01748 if (option_console) { 01749 if (el_hist == NULL || el == NULL) 01750 ast_el_initialize(); 01751 01752 if (!ast_strlen_zero(filename)) 01753 ast_el_read_history(filename); 01754 } 01755 01756 if (ast_tryconnect()) { 01757 /* One is already running */ 01758 if (option_remote) { 01759 if (option_exec) { 01760 ast_remotecontrol(xarg); 01761 quit_handler(0, 0, 0, 0); 01762 exit(0); 01763 } 01764 printf(term_quit()); 01765 ast_register_verbose(console_verboser); 01766 WELCOME_MESSAGE; 01767 ast_remotecontrol(NULL); 01768 quit_handler(0, 0, 0, 0); 01769 exit(0); 01770 } else { 01771 ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", (char *)ast_config_AST_SOCKET); 01772 printf(term_quit()); 01773 exit(1); 01774 } 01775 } else if (option_remote || option_exec) { 01776 ast_log(LOG_ERROR, "Unable to connect to remote asterisk\n"); 01777 printf(term_quit()); 01778 exit(1); 01779 } 01780 /* Blindly write pid file since we couldn't connect */ 01781 unlink((char *)ast_config_AST_PID); 01782 f = fopen((char *)ast_config_AST_PID, "w"); 01783 if (f) { 01784 fprintf(f, "%d\n", getpid()); 01785 fclose(f); 01786 } else 01787 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", (char *)ast_config_AST_PID, strerror(errno)); 01788 01789 if (!option_verbose && !option_debug && !option_nofork && !option_console) { 01790 daemon(0,0); 01791 /* Blindly re-write pid file since we are forking */ 01792 unlink((char *)ast_config_AST_PID); 01793 f = fopen((char *)ast_config_AST_PID, "w"); 01794 if (f) { 01795 fprintf(f, "%d\n", getpid()); 01796 fclose(f); 01797 } else 01798 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", (char *)ast_config_AST_PID, strerror(errno)); 01799 } 01800 01801 /* Test recursive mutex locking. */ 01802 if (test_for_thread_safety()) 01803 ast_verbose("Warning! Asterisk is not thread safe.\n"); 01804 01805 ast_makesocket(); 01806 sigemptyset(&sigs); 01807 sigaddset(&sigs, SIGHUP); 01808 sigaddset(&sigs, SIGTERM); 01809 sigaddset(&sigs, SIGINT); 01810 sigaddset(&sigs, SIGPIPE); 01811 sigaddset(&sigs, SIGWINCH); 01812 pthread_sigmask(SIG_BLOCK, &sigs, NULL); 01813 if (option_console || option_verbose || option_remote) 01814 ast_register_verbose(console_verboser); 01815 /* Print a welcome message if desired */ 01816 if (option_verbose || option_console) { 01817 WELCOME_MESSAGE; 01818 } 01819 if (option_console && !option_verbose) 01820 ast_verbose("[ Booting..."); 01821 01822 signal(SIGURG, urg_handler); 01823 signal(SIGINT, __quit_handler); 01824 signal(SIGTERM, __quit_handler); 01825 signal(SIGHUP, hup_handler); 01826 signal(SIGCHLD, child_handler); 01827 signal(SIGPIPE, SIG_IGN); 01828 01829 if (init_logger()) { 01830 printf(term_quit()); 01831 exit(1); 01832 } 01833 if (init_manager()) { 01834 printf(term_quit()); 01835 exit(1); 01836 } 01837 ast_rtp_init(); 01838 if (ast_image_init()) { 01839 printf(term_quit()); 01840 exit(1); 01841 } 01842 if (ast_file_init()) { 01843 printf(term_quit()); 01844 exit(1); 01845 } 01846 if (load_pbx()) { 01847 printf(term_quit()); 01848 exit(1); 01849 } 01850 if (load_modules()) { 01851 printf(term_quit()); 01852 exit(1); 01853 } 01854 if (init_framer()) { 01855 printf(term_quit()); 01856 exit(1); 01857 } 01858 if (astdb_init()) { 01859 printf(term_quit()); 01860 exit(1); 01861 } 01862 if (ast_enum_init()) { 01863 printf(term_quit()); 01864 exit(1); 01865 } 01866 /* sync cust config and reload some internals in case a custom config handler binded to them */ 01867 read_ast_cust_config(); 01868 reload_logger(0); 01869 reload_manager(); 01870 ast_enum_reload(); 01871 ast_rtp_reload(); 01872 01873 01874 /* We might have the option of showing a console, but for now just 01875 do nothing... */ 01876 if (option_console && !option_verbose) 01877 ast_verbose(" ]\n"); 01878 if (option_verbose || option_console) 01879 ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp))); 01880 if (option_nofork) 01881 consolethread = pthread_self(); 01882 fully_booted = 1; 01883 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); 01884 #ifdef __AST_DEBUG_MALLOC 01885 __ast_mm_init(); 01886 #endif 01887 time(&ast_startuptime); 01888 ast_cli_register(&astshutdownnow); 01889 ast_cli_register(&astshutdowngracefully); 01890 ast_cli_register(&astrestartnow); 01891 ast_cli_register(&astrestartgracefully); 01892 ast_cli_register(&astrestartwhenconvenient); 01893 ast_cli_register(&astshutdownwhenconvenient); 01894 ast_cli_register(&aborthalt); 01895 ast_cli_register(&astbang); 01896 if (option_console) { 01897 /* Console stuff now... */ 01898 /* Register our quit function */ 01899 char title[256]; 01900 set_icon("Asterisk"); 01901 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, ast_mainpid); 01902 set_title(title); 01903 ast_cli_register(&quit); 01904 ast_cli_register(&astexit); 01905 01906 for (;;) { 01907 buf = (char *)el_gets(el, &num); 01908 if (buf) { 01909 if (buf[strlen(buf)-1] == '\n') 01910 buf[strlen(buf)-1] = '\0'; 01911 01912 consolehandler((char *)buf); 01913 } else { 01914 if (write(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n", 01915 strlen("\nUse EXIT or QUIT to exit the asterisk console\n")) < 0) { 01916 /* Whoa, stdout disappeared from under us... Make /dev/null's */ 01917 int fd; 01918 fd = open("/dev/null", O_RDWR); 01919 if (fd > -1) { 01920 dup2(fd, STDOUT_FILENO); 01921 dup2(fd, STDIN_FILENO); 01922 } else 01923 ast_log(LOG_WARNING, "Failed to open /dev/null to recover from dead console. Bad things will happen!\n"); 01924 break; 01925 } 01926 } 01927 } 01928 01929 } 01930 /* Do nothing */ 01931 for(;;) 01932 poll(silly_macos,0, -1); 01933 return 0; 01934 }
|
|
Definition at line 121 of file asterisk.c. |
|
Definition at line 115 of file asterisk.c. |
|
Definition at line 116 of file asterisk.c. Referenced by main(). |
|
Definition at line 127 of file asterisk.c. |
|
Definition at line 122 of file asterisk.c. |
|
Definition at line 123 of file asterisk.c. |
|
Definition at line 120 of file asterisk.c. Referenced by init_logger(), and reload_logger(). |
|
Definition at line 117 of file asterisk.c. Referenced by ast_load_resource(), and load_modules(). |
|
Definition at line 124 of file asterisk.c. Referenced by main(). |
|
Definition at line 126 of file asterisk.c. |
|
Definition at line 125 of file asterisk.c. Referenced by main(). |
|
Definition at line 118 of file asterisk.c. Referenced by ast_app_has_voicemail(), and ast_app_messagecount(). |
|
Definition at line 128 of file asterisk.c. Referenced by ast_alloc_uniqueid(). |
|
Definition at line 119 of file asterisk.c. Referenced by ast_linear_stream(). |
|
Definition at line 101 of file asterisk.c. Referenced by ast_module_reload(). |
|
Definition at line 87 of file asterisk.c. Referenced by ast_alloc_uniqueid(), and main(). |
|
Definition at line 100 of file asterisk.c. Referenced by main(). |
|
Definition at line 107 of file asterisk.c. |
|
Definition at line 109 of file asterisk.c. Referenced by ast_channel_alloc(). |
|
Definition at line 82 of file asterisk.c. Referenced by ast_load_resource(), and main(). |
|
Definition at line 79 of file asterisk.c. Referenced by ast_writefile(), and main(). |
|
Definition at line 72 of file asterisk.c. Referenced by ast_load_resource(), main(), and term_init(). |
|
Definition at line 69 of file asterisk.c. Referenced by ast_channel_register_ex(), ast_channel_unregister(), ast_context_create(), ast_hangup(), ast_log(), ast_pbx_run(), ast_rtcp_read(), ast_save(), ast_set_read_format(), ast_set_write_format(), ast_softhangup_nolock(), load_modules(), and main(). |
|
Definition at line 78 of file asterisk.c. Referenced by main(). |
|
Definition at line 75 of file asterisk.c. Referenced by main(). |
|
Definition at line 73 of file asterisk.c. Referenced by main(). |
|
Definition at line 76 of file asterisk.c. Referenced by main(). |
|
Definition at line 77 of file asterisk.c. Referenced by main(), and term_init(). |
|
Definition at line 70 of file asterisk.c. Referenced by main(), and term_init(). |
|
Definition at line 80 of file asterisk.c. Referenced by main(). |
|
Definition at line 71 of file asterisk.c. Referenced by load_modules(), and main(). |
|
Definition at line 81 of file asterisk.c. Referenced by main(). |
|
Definition at line 74 of file asterisk.c. Referenced by main(). |
|
|
Definition at line 83 of file asterisk.c. Referenced by ast_writefile(). |