#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 | ast_atexit |
| struct | console |
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. More... | |
| 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] |
|
|
Definition at line 61 of file asterisk.c. |
|
|
Definition at line 858 of file asterisk.c. |
|
|
Definition at line 860 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. References string. 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(), LOG_WARNING, and s. 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 1571 of file asterisk.c. References __ast_mm_init(), ast_alaw_init(), ast_cli(), 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.
01572 {
01573 int c;
01574 char filename[80] = "";
01575 char hostname[256];
01576 char tmp[80];
01577 char * xarg = NULL;
01578 int x;
01579 FILE *f;
01580 sigset_t sigs;
01581 int num;
01582 char *buf;
01583 char *runuser=NULL, *rungroup=NULL;
01584
01585 /* Remember original args for restart */
01586 if (argc > sizeof(_argv) / sizeof(_argv[0]) - 1) {
01587 fprintf(stderr, "Truncating argument size to %d\n", (int)(sizeof(_argv) / sizeof(_argv[0])) - 1);
01588 argc = sizeof(_argv) / sizeof(_argv[0]) - 1;
01589 }
01590 for (x=0;x<argc;x++)
01591 _argv[x] = argv[x];
01592 _argv[x] = NULL;
01593
01594 /* if the progname is rasterisk consider it a remote console */
01595 if ( argv[0] && (strstr(argv[0], "rasterisk")) != NULL) {
01596 option_remote++;
01597 option_nofork++;
01598 }
01599 if (gethostname(hostname, sizeof(hostname)))
01600 strncpy(hostname, "<Unknown>", sizeof(hostname)-1);
01601 ast_mainpid = getpid();
01602 ast_ulaw_init();
01603 ast_alaw_init();
01604 callerid_init();
01605 ast_utils_init();
01606 tdd_init();
01607 if (getenv("HOME"))
01608 snprintf(filename, sizeof(filename), "%s/.asterisk_history", getenv("HOME"));
01609 /* Check for options */
01610 while((c=getopt(argc, argv, "thfdvVqprRgcinx:U:G:C:")) != -1) {
01611 switch(c) {
01612 case 'd':
01613 option_debug++;
01614 option_nofork++;
01615 break;
01616 case 'c':
01617 option_console++;
01618 option_nofork++;
01619 break;
01620 case 'f':
01621 option_nofork++;
01622 break;
01623 case 'n':
01624 option_nocolor++;
01625 break;
01626 case 'r':
01627 option_remote++;
01628 option_nofork++;
01629 break;
01630 case 'R':
01631 option_remote++;
01632 option_nofork++;
01633 option_reconnect++;
01634 break;
01635 case 'p':
01636 option_highpriority++;
01637 break;
01638 case 'v':
01639 option_verbose++;
01640 option_nofork++;
01641 break;
01642 case 'q':
01643 option_quiet++;
01644 break;
01645 case 't':
01646 option_cache_record_files++;
01647 break;
01648 case 'x':
01649 option_exec++;
01650 xarg = optarg;
01651 break;
01652 case 'C':
01653 strncpy((char *)ast_config_AST_CONFIG_FILE,optarg,sizeof(ast_config_AST_CONFIG_FILE) - 1);
01654 option_overrideconfig++;
01655 break;
01656 case 'i':
01657 option_initcrypto++;
01658 break;
01659 case'g':
01660 option_dumpcore++;
01661 break;
01662 case 'h':
01663 show_cli_help();
01664 exit(0);
01665 case 'V':
01666 show_version();
01667 exit(0);
01668 case 'U':
01669 runuser = optarg;
01670 break;
01671 case 'G':
01672 rungroup = optarg;
01673 break;
01674 case '?':
01675 exit(1);
01676 }
01677 }
01678
01679 if (option_dumpcore) {
01680 struct rlimit l;
01681 memset(&l, 0, sizeof(l));
01682 l.rlim_cur = RLIM_INFINITY;
01683 l.rlim_max = RLIM_INFINITY;
01684 if (setrlimit(RLIMIT_CORE, &l)) {
01685 ast_log(LOG_WARNING, "Unable to disable core size resource limit: %s\n", strerror(errno));
01686 }
01687 }
01688
01689 if (rungroup) {
01690 struct group *gr;
01691 gr = getgrnam(rungroup);
01692 if (!gr) {
01693 ast_log(LOG_WARNING, "No such group '%s'!\n", rungroup);
01694 exit(1);
01695 }
01696 if (setgid(gr->gr_gid)) {
01697 ast_log(LOG_WARNING, "Unable to setgid to %d (%s)\n", gr->gr_gid, rungroup);
01698 exit(1);
01699 }
01700 if (option_verbose)
01701 ast_verbose("Running as group '%s'\n", rungroup);
01702 }
01703
01704 if (set_priority(option_highpriority)) {
01705 exit(1);
01706 }
01707 if (runuser) {
01708 struct passwd *pw;
01709 pw = getpwnam(runuser);
01710 if (!pw) {
01711 ast_log(LOG_WARNING, "No such user '%s'!\n", runuser);
01712 exit(1);
01713 }
01714 if (setuid(pw->pw_uid)) {
01715 ast_log(LOG_WARNING, "Unable to setuid to %d (%s)\n", pw->pw_uid, runuser);
01716 exit(1);
01717 }
01718 if (option_verbose)
01719 ast_verbose("Running as user '%s'\n", runuser);
01720 }
01721
01722 term_init();
01723 printf(term_end());
01724 fflush(stdout);
01725
01726 if (option_console && !option_verbose)
01727 ast_verbose("[ Reading Master Configuration ]");
01728 ast_readconfig();
01729
01730 if (option_console && !option_verbose)
01731 ast_verbose("[ Initializing Custom Configuration Options]");
01732 /* custom config setup */
01733 register_config_cli();
01734 read_ast_cust_config();
01735
01736
01737 if (option_console) {
01738 if (el_hist == NULL || el == NULL)
01739 ast_el_initialize();
01740
01741 if (!ast_strlen_zero(filename))
01742 ast_el_read_history(filename);
01743 }
01744
01745 if (ast_tryconnect()) {
01746 /* One is already running */
01747 if (option_remote) {
01748 if (option_exec) {
01749 ast_remotecontrol(xarg);
01750 quit_handler(0, 0, 0, 0);
01751 exit(0);
01752 }
01753 printf(term_quit());
01754 ast_register_verbose(console_verboser);
01755 WELCOME_MESSAGE;
01756 ast_remotecontrol(NULL);
01757 quit_handler(0, 0, 0, 0);
01758 exit(0);
01759 } else {
01760 ast_log(LOG_ERROR, "Asterisk already running on %s. Use 'asterisk -r' to connect.\n", (char *)ast_config_AST_SOCKET);
01761 printf(term_quit());
01762 exit(1);
01763 }
01764 } else if (option_remote || option_exec) {
01765 ast_log(LOG_ERROR, "Unable to connect to remote asterisk\n");
01766 printf(term_quit());
01767 exit(1);
01768 }
01769 /* Blindly write pid file since we couldn't connect */
01770 unlink((char *)ast_config_AST_PID);
01771 f = fopen((char *)ast_config_AST_PID, "w");
01772 if (f) {
01773 fprintf(f, "%d\n", getpid());
01774 fclose(f);
01775 } else
01776 ast_log(LOG_WARNING, "Unable to open pid file '%s': %s\n", (char *)ast_config_AST_PID, strerror(errno));
01777
01778 if (!option_verbose && !option_debug && !option_nofork && !option_console) {
01779 daemon(0,0);
01780 /* Blindly re-write pid file since we are forking */
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
01790 /* Test recursive mutex locking. */
01791 if (test_for_thread_safety())
01792 ast_verbose("Warning! Asterisk is not thread safe.\n");
01793
01794 ast_makesocket();
01795 sigemptyset(&sigs);
01796 sigaddset(&sigs, SIGHUP);
01797 sigaddset(&sigs, SIGTERM);
01798 sigaddset(&sigs, SIGINT);
01799 sigaddset(&sigs, SIGPIPE);
01800 sigaddset(&sigs, SIGWINCH);
01801 pthread_sigmask(SIG_BLOCK, &sigs, NULL);
01802 if (option_console || option_verbose || option_remote)
01803 ast_register_verbose(console_verboser);
01804 /* Print a welcome message if desired */
01805 if (option_verbose || option_console) {
01806 WELCOME_MESSAGE;
01807 }
01808 if (option_console && !option_verbose)
01809 ast_verbose("[ Booting...");
01810
01811 signal(SIGURG, urg_handler);
01812 signal(SIGINT, __quit_handler);
01813 signal(SIGTERM, __quit_handler);
01814 signal(SIGHUP, hup_handler);
01815 signal(SIGCHLD, child_handler);
01816 signal(SIGPIPE, SIG_IGN);
01817
01818 if (init_logger()) {
01819 printf(term_quit());
01820 exit(1);
01821 }
01822 if (init_manager()) {
01823 printf(term_quit());
01824 exit(1);
01825 }
01826 ast_rtp_init();
01827 if (ast_image_init()) {
01828 printf(term_quit());
01829 exit(1);
01830 }
01831 if (ast_file_init()) {
01832 printf(term_quit());
01833 exit(1);
01834 }
01835 if (load_pbx()) {
01836 printf(term_quit());
01837 exit(1);
01838 }
01839 if (load_modules()) {
01840 printf(term_quit());
01841 exit(1);
01842 }
01843 if (init_framer()) {
01844 printf(term_quit());
01845 exit(1);
01846 }
01847 if (astdb_init()) {
01848 printf(term_quit());
01849 exit(1);
01850 }
01851 if (ast_enum_init()) {
01852 printf(term_quit());
01853 exit(1);
01854 }
01855 /* sync cust config and reload some internals in case a custom config handler binded to them */
01856 read_ast_cust_config();
01857 reload_logger(0);
01858 reload_manager();
01859 ast_enum_reload();
01860 ast_rtp_reload();
01861
01862
01863 /* We might have the option of showing a console, but for now just
01864 do nothing... */
01865 if (option_console && !option_verbose)
01866 ast_verbose(" ]\n");
01867 if (option_verbose || option_console)
01868 ast_verbose(term_color(tmp, "Asterisk Ready.\n", COLOR_BRWHITE, COLOR_BLACK, sizeof(tmp)));
01869 if (option_nofork)
01870 consolethread = pthread_self();
01871 fully_booted = 1;
01872 pthread_sigmask(SIG_UNBLOCK, &sigs, NULL);
01873 #ifdef __AST_DEBUG_MALLOC
01874 __ast_mm_init();
01875 #endif
01876 time(&ast_startuptime);
01877 ast_cli_register(&astshutdownnow);
01878 ast_cli_register(&astshutdowngracefully);
01879 ast_cli_register(&astrestartnow);
01880 ast_cli_register(&astrestartgracefully);
01881 ast_cli_register(&astrestartwhenconvenient);
01882 ast_cli_register(&astshutdownwhenconvenient);
01883 ast_cli_register(&aborthalt);
01884 ast_cli_register(&astbang);
01885 if (option_console) {
01886 /* Console stuff now... */
01887 /* Register our quit function */
01888 char title[256];
01889 set_icon("Asterisk");
01890 snprintf(title, sizeof(title), "Asterisk Console on '%s' (pid %d)", hostname, ast_mainpid);
01891 set_title(title);
01892 ast_cli_register(&quit);
01893 ast_cli_register(&astexit);
01894
01895 for (;;) {
01896 buf = (char *)el_gets(el, &num);
01897 if (buf) {
01898 if (buf[strlen(buf)-1] == '\n')
01899 buf[strlen(buf)-1] = '\0';
01900
01901 consolehandler((char *)buf);
01902 } else {
01903 if (option_remote)
01904 ast_cli(STDOUT_FILENO, "\nUse EXIT or QUIT to exit the asterisk console\n");
01905 }
01906 }
01907
01908 } else {
01909 /* Do nothing */
01910 for(;;)
01911 poll(NULL,0, -1);
01912 }
01913 return 0;
01914 }
|
|
|
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. |
|
|
Definition at line 117 of file asterisk.c. |
|
|
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. |
|
|
Definition at line 119 of file asterisk.c. |
|
|
Definition at line 101 of file asterisk.c. |
|
|
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. |
|
|
Definition at line 82 of file asterisk.c. Referenced by main(). |
|
|
Definition at line 79 of file asterisk.c. Referenced by main(). |
|
|
Definition at line 72 of file asterisk.c. Referenced by main(). |
|
|
Definition at line 69 of file asterisk.c. Referenced by 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(). |
|
|
Definition at line 70 of file asterisk.c. Referenced by main(). |
|
|
Definition at line 80 of file asterisk.c. Referenced by main(). |
|
|
Definition at line 71 of file asterisk.c. Referenced by 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 68 of file asterisk.c. Referenced by main(). |
|
|
Definition at line 83 of file asterisk.c. |
1.2.15