#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. Referenced by ast_log().
|
|
|
|
|
|
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(), and LOG_WARNING. 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_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, 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_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. |
|
|
Definition at line 126 of file asterisk.c. |
|
|
Definition at line 125 of file asterisk.c. |
|
|
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. |
|
|
|
Definition at line 83 of file asterisk.c. Referenced by ast_writefile(). |
1.4.2