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