示例#1
0
int main(int argc, char * argv[])
{
    signal(SIGPIPE, SIG_IGN);
    loop = uv_default_loop();
    int result;
    http_server_init(&srv);
    srv.sock_listen_data = NULL; // should be null by default

    http_server_handler_init(&handler);
    handler.on_message_complete = &on_message_complete;

    result = http_server_setopt(&srv, HTTP_SERVER_OPT_HANDLER, &handler);
    result = http_server_setopt(&srv, HTTP_SERVER_OPT_HANDLER_DATA, &srv);

    // Set options
    //result = http_server_setopt(&srv, HTTP_SERVER_OPT_OPEN_SOCKET_DATA, NULL);
    
    //result = http_server_setopt(&srv, HTTP_SERVER_OPT_OPEN_SOCKET_FUNCTION, &_opensocket_function);

    result = http_server_setopt(&srv, HTTP_SERVER_OPT_SOCKET_DATA, NULL);
    result = http_server_setopt(&srv, HTTP_SERVER_OPT_SOCKET_FUNCTION, &_socket_function);

    http_server_start(&srv);
    result = uv_run(loop, UV_RUN_DEFAULT);
    http_server_free(&srv);
    return result;
}
示例#2
0
文件: helloworld.c 项目: Abioy/ribs2
int main(void) {
    /* must use the initializer or set all the values in http_server */
    struct http_server server = HTTP_SERVER_INITIALIZER;
    /* port number */
    server.port = 8080;
    /* call my_server upon receiving http request */
    server.user_func = my_server;
    /* init and check for errors */
    if (0 > http_server_init(&server)) {
        printf("http_server_init failed\n");
        exit(EXIT_FAILURE);
    }

    /* initialize the event loop */
    if (0 > epoll_worker_init()) {
        printf("epoll_worker_init failed\n");
        exit(EXIT_FAILURE);
    }

    /* tell http server to start accepting connections */
    if (0 > http_server_init_acceptor(&server)) {
        printf("http_server_init_acceptor failed\n");
        exit(EXIT_FAILURE);
    }

    /* lastly, we need to handle events */
    epoll_worker_loop();
    return 0;
}
int hs20_web_browser(const char *url)
{
	char cmd[2000];
	int ret;
	struct http_server *http;
	struct in_addr addr;
	struct browser_data data;

	wpa_printf(MSG_INFO, "Launching wpadebug browser to %s", url);

	os_memset(&data, 0, sizeof(data));

	ret = os_snprintf(cmd, sizeof(cmd),
			  "start -a android.action.MAIN "
			  "-c android.intent.category.LAUNCHER "
			  "-n w1.fi.wpadebug/.WpaWebViewActivity "
			  "-e w1.fi.wpadebug.URL '%s'", url);
	if (ret < 0 || (size_t) ret >= sizeof(cmd)) {
		wpa_printf(MSG_ERROR, "Too long URL");
		return -1;
	}

	if (eloop_init() < 0) {
		wpa_printf(MSG_ERROR, "eloop_init failed");
		return -1;
	}
	addr.s_addr = htonl((127 << 24) | 1);
	http = http_server_init(&addr, 12345, http_req, &data);
	if (http == NULL) {
		wpa_printf(MSG_ERROR, "http_server_init failed");
		eloop_destroy();
		return -1;
	}

	if (os_exec("/system/bin/am", cmd, 1) != 0) {
		wpa_printf(MSG_INFO, "Failed to launch wpadebug browser");
		eloop_cancel_timeout(browser_timeout, NULL, NULL);
		http_server_deinit(http);
		eloop_destroy();
		return -1;
	}

	eloop_register_timeout(300, 0, browser_timeout, &data, NULL);
	eloop_run();
	eloop_cancel_timeout(browser_timeout, &data, NULL);
	http_server_deinit(http);
	eloop_destroy();

	wpa_printf(MSG_INFO, "Closing Android browser");
	if (os_exec("/system/bin/am",
		    "start -a android.action.MAIN "
		    "-c android.intent.category.LAUNCHER "
		    "-n w1.fi.wpadebug/.WpaWebViewActivity "
		    "-e w1.fi.wpadebug.URL FINISH", 1) != 0) {
		wpa_printf(MSG_INFO, "Failed to close wpadebug browser");
	}

	return data.success;
}
示例#4
0
int hs20_web_browser(const char *url)
{
	struct http_server *http;
	struct in_addr addr;
	struct browser_data data;
	pid_t pid;

	wpa_printf(MSG_INFO, "Launching system browser to %s", url);

	os_memset(&data, 0, sizeof(data));

	if (eloop_init() < 0) {
		wpa_printf(MSG_ERROR, "eloop_init failed");
		return -1;
	}
	addr.s_addr = htonl((127 << 24) | 1);
	http = http_server_init(&addr, 12345, http_req, &data);
	if (http == NULL) {
		wpa_printf(MSG_ERROR, "http_server_init failed");
		eloop_destroy();
		return -1;
	}

	pid = fork();
	if (pid < 0) {
		wpa_printf(MSG_ERROR, "fork: %s", strerror(errno));
		http_server_deinit(http);
		eloop_destroy();
		return -1;
	}

	if (pid == 0) {
		/* run the external command in the child process */
		char *argv[3];

		argv[0] = "browser-system";
		argv[1] = (void *)url;
		argv[2] = NULL;

		execv("/usr/bin/x-www-browser", argv);
		wpa_printf(MSG_ERROR, "execv: %s", strerror(errno));
		exit(0);
		return -1;
	}

	eloop_register_timeout(120, 0, browser_timeout, &data, NULL);
	eloop_run();
	eloop_cancel_timeout(browser_timeout, &data, NULL);
	http_server_deinit(http);
	eloop_destroy();

	/* TODO: Close browser */

	return data.success;
}
示例#5
0
int main(int argc, char**argv)
{
    errval_t err;

    // Parse args
    if (argc != 4) {
        printf("Usage: %s CardName NFSIP NFSpath\n", argv[0]);
        return 1;
    }
//    char *card_name = argv[1];

    struct in_addr server1;
    if (inet_aton(argv[2], &server1) == 0) {
        printf("Invalid IP addr: %s\n", argv[2]);
        return 1;
    }
    serverip.addr = server1.s_addr; // XXX
    serverpath = argv[3];

    // Boot up
    SERVER_DEBUG("init start\n");

    SERVER_DEBUG("lwip_demo: lwip setup\n");
    if (lwip_init_auto() == false) {
        printf("ERROR: lwip_init_auto failed!\n");
        return 1;
    }

//    lwip_benchmark_control(1, BMS_START_REQUEST, 0, 0);
    http_server_init(serverip, serverpath);

    SERVER_DEBUG("Init finished.\n");

    struct waitset *ws = get_default_waitset();
    while (1) {
        // check for any event without blocking
        err = event_dispatch_non_block(ws);
        if (err != LIB_ERR_NO_EVENT) {
            if (err_is_fail(err)) {
                DEBUG_ERR(err, "in event_dispatch");
                break;
            }
        }

        // Check if lwip has any pending work to finish
        wrapper_perform_lwip_work();
        err = event_dispatch(ws);
        if (err_is_fail(err)) {
            DEBUG_ERR(err, "in event_dispatch");
            break;
        }
    }

}
示例#6
0
文件: main.c 项目: eerimoq/simba
static int init()
{
    sys_start();

    http_server_init(&server,
                     &listener,
                     connections,
                     NULL,
                     routes,
                     no_route);

    http_server_start(&server);

    return (0);
}
示例#7
0
void hls_server_test(const char* ip, int port)
{
	aio_socket_init(1);
	http_server_init();
	void* http = http_server_create(ip, port);
	http_server_set_handler(http, hls_server_onhttp, http);

	// http process
	while(aio_socket_process(1000) >= 0)
	{
	}

	http_server_destroy(http);
	http_server_cleanup();
	aio_socket_clean();
}
示例#8
0
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART3_UART_Init();
  MX_LWIP_Init();
  MX_ADC3_Init();

  /* USER CODE BEGIN 2 */
  
  /* Http webserver Init */
  http_server_init();
  
  /* Notify user about the network interface config */
  User_notification(&gnetif);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
    /* Read a received packet from the Ethernet buffers and send it 
       to the lwIP for handling */
    ethernetif_input(&gnetif);

    /* Handle timeouts */
    sys_check_timeouts();
  }
  /* USER CODE END 3 */

}
示例#9
0
文件: main.c 项目: eerimoq/simba
static int init()
{
    struct inet_ip_addr_t ipaddr;
    struct inet_ip_addr_t netmask;
    struct inet_ip_addr_t gw;

    sys_start();

    std_printf(sys_get_info());

    uart_init(&ipuart, &uart_device[1], 115200, iprxbuf, sizeof(iprxbuf));
    uart_start(&ipuart);

    inet_module_init();
    socket_module_init();
    network_interface_slip_module_init();

    inet_aton("169.254.1.2", &ipaddr);
    inet_aton("255.255.255.0", &netmask);
    inet_aton("0.0.0.0", &gw);

    network_interface_slip_init(&slip,
                                &ipaddr,
                                &netmask,
                                &gw,
                                &ipuart.chout);
    network_interface_add(&slip.network_interface);
    network_interface_start(&slip.network_interface);

    thrd_spawn(slip_reader,
               NULL,
               0,
               stack,
               sizeof(stack));

    http_server_init(&server,
                     &listener,
                     connections,
                     NULL,
                     routes,
                     no_route);

    http_server_start(&server);

    return (0);
}
示例#10
0
文件: main.c 项目: TELE-TWIN/htshttpd
int
main(int argc, char **argv)
{
  int c;
  int port = 8000;
  const char *basedir = "./";
  int mode = HF_MODE_RANGES;

  signal(SIGPIPE, handle_sigpipe);

  while((c = getopt(argc, argv, "d:p:m:")) != -1) {
    switch(c) {
    case 'p':
      port = atoi(optarg);
      break;
    case 'd':
      basedir = optarg;
      break;
    case 'm':
      if(!strcmp(optarg, "pipe"))
	mode = HF_MODE_PIPE;
      else if(!strcmp(optarg, "chunked"))
	mode = HF_MODE_CHUNKED;
      else if(!strcmp(optarg, "knowlength"))
	mode = HF_MODE_KNOW_LENGTH;
      else if(!strcmp(optarg, "seekstart"))
	mode = HF_MODE_SEEK_START;
      else if(!strcmp(optarg, "ranges"))
	mode = HF_MODE_RANGES;
      else {
	fprintf(stderr, "Invalid mode %s", optarg);
	exit(1);
      }
      break;
    }
  }

  tcp_server_init();

  http_server_init(port);
  file_over_http_init(basedir, mode);
  while(1) {
    sleep(1000);
  }
  return 0;
}
示例#11
0
文件: app.c 项目: richcj10/USA-FW-IoT
void ICACHE_FLASH_ATTR init_http_server(){

	//general max tcp conns
	espconn_tcp_set_max_con(20);

	http_server_init();
	http_server_bind_domain(INTERFACE_DOMAIN);
	http_server_enable_captive_portal();
	http_server_enable_cors();

	http_server_rewrite(&rewrites);
	http_server_bind_urls((http_server_url *)&api_urls);

	http_server_start();

	//ws
	init_ws_server();

}
示例#12
0
void web_server_init(void) {

  filesystem_init();
  http_server_init(80, process_POST, tag_expand);
}
示例#13
0
int hs20_web_browser(const char *url)
{
	struct http_server *http;
	struct in_addr addr;
	struct browser_data data;
	pid_t pid;

	wpa_printf(MSG_INFO, "Launching Android browser to %s", url);

	os_memset(&data, 0, sizeof(data));

	if (eloop_init() < 0) {
		wpa_printf(MSG_ERROR, "eloop_init failed");
		return -1;
	}
	addr.s_addr = htonl((127 << 24) | 1);
	http = http_server_init(&addr, 12345, http_req, &data);
	if (http == NULL) {
		wpa_printf(MSG_ERROR, "http_server_init failed");
		eloop_destroy();
		return -1;
	}

	pid = fork();
	if (pid < 0) {
		wpa_printf(MSG_ERROR, "fork: %s", strerror(errno));
		http_server_deinit(http);
		eloop_destroy();
		return -1;
	}

	if (pid == 0) {
		/* run the external command in the child process */
		char *argv[7];

		argv[0] = "browser-android";
		argv[1] = "start";
		argv[2] = "-a";
		argv[3] = "android.intent.action.VIEW";
		argv[4] = "-d";
		argv[5] = (void *) url;
		argv[6] = NULL;

		execv("/system/bin/am", argv);
		wpa_printf(MSG_ERROR, "execv: %s", strerror(errno));
		exit(0);
		return -1;
	}

	eloop_register_timeout(30, 0, browser_timeout, &data, NULL);
	eloop_run();
	eloop_cancel_timeout(browser_timeout, &data, NULL);
	http_server_deinit(http);
	eloop_destroy();

	wpa_printf(MSG_INFO, "Closing Android browser");
	if (system("/system/bin/input keyevent KEYCODE_HOME") != 0) {
		wpa_printf(MSG_INFO, "Failed to inject keyevent");
	}

	return data.success;
}
示例#14
0
int
main(int argc, char **argv)
{
  int c;
  int forkaway = 0;
  FILE *pidfile;
  const char *pidpath = "/var/run/tvheadend.pid";
  struct group *grp;
  struct passwd *pw;
  const char *usernam = NULL;
  const char *groupnam = NULL;
  int logfacility = LOG_DAEMON;
  int createdefault = 0;
  sigset_t set;
  const char *homedir;
  const char *rawts_input = NULL;
  const char *join_transport = NULL;
  const char *confpath = NULL;
  char *p, *endp;
  uint32_t adapter_mask = 0xffffffff;
  int crash = 0;

  // make sure the timezone is set
  tzset();

  while((c = getopt(argc, argv, "Aa:fp:u:g:c:Chdr:j:s")) != -1) {
    switch(c) {
    case 'a':
      adapter_mask = 0x0;
      p = strtok(optarg, ",");
      if (p != NULL) {
        do {
          int adapter = strtol(p, &endp, 10);
          if (*endp != 0 || adapter < 0 || adapter > 31) {
              fprintf(stderr, "Invalid adapter number '%s'\n", p);
              return 1;
          }
          adapter_mask |= (1 << adapter);
        } while ((p = strtok(NULL, ",")) != NULL);
        if (adapter_mask == 0x0) {
          fprintf(stderr, "No adapters specified!\n");
          return 1;
        }
      } else {
        usage(argv[0]);
      }
      break;
    case 'A':
      crash = 1;
      break;
    case 'f':
      forkaway = 1;
      break;
    case 'p':
      pidpath = optarg;
      break;
    case 'u':
      usernam = optarg;
      break;
    case 'g':
      groupnam = optarg;
      break;
    case 'c':
      confpath = optarg;
      break;
    case 'd':
      log_debug_to_console = 1;
      break;
    case 's':
      log_debug_to_syslog = 1;
      break;
    case 'C':
      createdefault = 1;
      break;
    case 'r':
      rawts_input = optarg;
      break;
    case 'j':
      join_transport = optarg;
      break;
    default:
      usage(argv[0]);
      break;
    }
  }

  signal(SIGPIPE, handle_sigpipe);

  grp = getgrnam(groupnam ?: "video");
  pw = usernam ? getpwnam(usernam) : NULL;


  if(forkaway) {

    if(daemon(0, 0)) {
      exit(2);
    }
    pidfile = fopen(pidpath, "w+");
    if(pidfile != NULL) {
      fprintf(pidfile, "%d\n", getpid());
      fclose(pidfile);
    }

   if(grp != NULL) {
      setgid(grp->gr_gid);
    } else {
      setgid(1);
    }

   if(pw != NULL) {
      setuid(pw->pw_uid);
    } else {
      setuid(1);
    }

   if(pw != NULL) {
     homedir = pw->pw_dir;
     setenv("HOME", homedir, 1);
   }

    umask(0);
  }

  log_stderr = !forkaway;
  log_decorate = isatty(2);

  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, NULL);

  openlog("tvheadend", LOG_PID, logfacility);

  hts_settings_init(confpath);

  pthread_mutex_init(&ffmpeg_lock, NULL);
  pthread_mutex_init(&fork_lock, NULL);
  pthread_mutex_init(&global_lock, NULL);

  pthread_mutex_lock(&global_lock);

  time(&dispatch_clock);

  trap_init(argv[0]);
  
  /**
   * Initialize subsystems
   */
  xmltv_init();   /* Must be initialized before channels */

  service_init();

  channels_init();

  access_init(createdefault);

  tcp_server_init();
#if ENABLE_LINUXDVB
  dvb_init(adapter_mask);
#endif
  iptv_input_init();
#if ENABLE_V4L
  v4l_init();
#endif
  http_server_init();

  webui_init(tvheadend_dataroot());

  serviceprobe_init();

  cwc_init();

  capmt_init();

  epg_init();

  dvr_init();

  htsp_init();

  ffdecsa_init();
  
  if(rawts_input != NULL)
    rawts_init(rawts_input);

  if(join_transport != NULL)
    subscription_dummy_join(join_transport, 1);

#ifdef CONFIG_AVAHI
  avahi_init();
#endif

  pthread_mutex_unlock(&global_lock);


  /**
   * Wait for SIGTERM / SIGINT, but only in this thread
   */

  running = 1;
  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGINT);

  signal(SIGTERM, doexit);
  signal(SIGINT, doexit);

  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
	 "running as PID:%d UID:%d GID:%d, settings located in '%s', "
	 "dataroot: %s",
	 tvheadend_version,
	 getpid(), getuid(), getgid(), hts_settings_get_root(),
	 tvheadend_dataroot() ?: "<Embedded file system>");

  if(crash)
    abort();

  mainloop();

  epg_save();

  tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend");

  if(forkaway)
    unlink("/var/run/tvheadend.pid");

  return 0;

}
示例#15
0
int
main(int argc, char **argv)
{
  int i;
  sigset_t set;
#if ENABLE_LINUXDVB
  uint32_t adapter_mask;
#endif
  int  log_level   = LOG_INFO;
  int  log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG;
  const char *log_debug = NULL, *log_trace = NULL;
  char buf[512];

  main_tid = pthread_self();

  /* Setup global mutexes */
  pthread_mutex_init(&ffmpeg_lock, NULL);
  pthread_mutex_init(&fork_lock, NULL);
  pthread_mutex_init(&global_lock, NULL);
  pthread_mutex_init(&atomic_lock, NULL);
  pthread_cond_init(&gtimer_cond, NULL);

  /* Defaults */
  tvheadend_webui_port      = 9981;
  tvheadend_webroot         = NULL;
  tvheadend_htsp_port       = 9982;
  tvheadend_htsp_port_extra = 0;

  /* Command line options */
  int         opt_help         = 0,
              opt_version      = 0,
              opt_fork         = 0,
              opt_firstrun     = 0,
              opt_stderr       = 0,
              opt_syslog       = 0,
              opt_uidebug      = 0,
              opt_abort        = 0,
              opt_noacl        = 0,
              opt_fileline     = 0,
              opt_threadid     = 0,
              opt_ipv6         = 0,
              opt_tsfile_tuner = 0,
              opt_dump         = 0;
  const char *opt_config       = NULL,
             *opt_user         = NULL,
             *opt_group        = NULL,
             *opt_logpath      = NULL,
             *opt_log_debug    = NULL,
             *opt_log_trace    = NULL,
             *opt_pidpath      = "/var/run/tvheadend.pid",
#if ENABLE_LINUXDVB
             *opt_dvb_adapters = NULL,
#endif
             *opt_bindaddr     = NULL,
             *opt_subscribe    = NULL;
  str_list_t  opt_tsfile       = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  cmdline_opt_t cmdline_opts[] = {
    {   0, NULL,        "Generic Options",         OPT_BOOL, NULL         },
    { 'h', "help",      "Show this page",          OPT_BOOL, &opt_help    },
    { 'v', "version",   "Show version infomation", OPT_BOOL, &opt_version },

    {   0, NULL,        "Service Configuration",   OPT_BOOL, NULL         },
    { 'c', "config",    "Alternate config path",   OPT_STR,  &opt_config  },
    { 'f', "fork",      "Fork and run as daemon",  OPT_BOOL, &opt_fork    },
    { 'u', "user",      "Run as user",             OPT_STR,  &opt_user    },
    { 'g', "group",     "Run as group",            OPT_STR,  &opt_group   },
    { 'p', "pid",       "Alternate pid path",      OPT_STR,  &opt_pidpath },
    { 'C', "firstrun",  "If no user account exists then create one with\n"
	                      "no username and no password. Use with care as\n"
	                      "it will allow world-wide administrative access\n"
	                      "to your Tvheadend installation until you edit\n"
	                      "the access-control from within the Tvheadend UI",
      OPT_BOOL, &opt_firstrun },
#if ENABLE_LINUXDVB
    { 'a', "adapters",  "Only use specified DVB adapters (comma separated)",
      OPT_STR, &opt_dvb_adapters },
#endif
    {   0, NULL,         "Server Connectivity",    OPT_BOOL, NULL         },
    { '6', "ipv6",       "Listen on IPv6",         OPT_BOOL, &opt_ipv6    },
    { 'b', "bindaddr",   "Specify bind address",   OPT_STR,  &opt_bindaddr},
    {   0, "http_port",  "Specify alternative http port",
      OPT_INT, &tvheadend_webui_port },
    {   0, "http_root",  "Specify alternative http webroot",
      OPT_STR, &tvheadend_webroot },
    {   0, "htsp_port",  "Specify alternative htsp port",
      OPT_INT, &tvheadend_htsp_port },
    {   0, "htsp_port2", "Specify extra htsp port",
      OPT_INT, &tvheadend_htsp_port_extra },

    {   0, NULL,        "Debug Options",           OPT_BOOL, NULL         },
    { 'd', "stderr",    "Enable debug on stderr",  OPT_BOOL, &opt_stderr  },
    { 's', "syslog",    "Enable debug to syslog",  OPT_BOOL, &opt_syslog  },
    { 'l', "logfile",   "Enable debug to file",    OPT_STR,  &opt_logpath },
    {   0, "debug",     "Enable debug subsystems", OPT_STR,  &opt_log_debug },
#if ENABLE_TRACE
    {   0, "trace",     "Enable trace subsystems", OPT_STR,  &opt_log_trace },
#endif
    {   0, "fileline",  "Add file and line numbers to debug", OPT_BOOL, &opt_fileline },
    {   0, "threadid",  "Add the thread ID to debug", OPT_BOOL, &opt_threadid },
    {   0, "uidebug",   "Enable webUI debug (non-minified JS)", OPT_BOOL, &opt_uidebug },
    { 'A', "abort",     "Immediately abort",       OPT_BOOL, &opt_abort   },
    { 'D', "dump",      "Enable coredumps for daemon", OPT_BOOL, &opt_dump },
    {   0, "noacl",     "Disable all access control checks",
      OPT_BOOL, &opt_noacl },
    { 'j', "join",      "Subscribe to a service permanently",
      OPT_STR, &opt_subscribe },


    { 0, NULL, "TODO: testing", OPT_BOOL, NULL },
    { 0, "tsfile_tuners", "Number of tsfile tuners", OPT_INT, &opt_tsfile_tuner },
    { 0, "tsfile", "tsfile input (mux file)", OPT_STR_LIST, &opt_tsfile },

  };

  /* Get current directory */
  tvheadend_cwd = dirname(dirname(tvh_strdupa(argv[0])));

  /* Set locale */
  setlocale(LC_ALL, "");
  setlocale(LC_NUMERIC, "C");

  /* make sure the timezone is set */
  tzset();

  /* Process command line */
  for (i = 1; i < argc; i++) {

    /* Find option */
    cmdline_opt_t *opt
      = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]);
    if (!opt)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 "invalid option specified [%s]", argv[i]);

    /* Process */
    if (opt->type == OPT_BOOL)
      *((int*)opt->param) = 1;
    else if (++i == argc)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 "option %s requires a value", opt->lopt);
    else if (opt->type == OPT_INT)
      *((int*)opt->param) = atoi(argv[i]);
    else if (opt->type == OPT_STR_LIST) {
      str_list_t *strl = opt->param;
      if (strl->num < strl->max)
        strl->str[strl->num++] = argv[i];
    }
    else
      *((char**)opt->param) = argv[i];

    /* Stop processing */
    if (opt_help)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), NULL);
    if (opt_version)
      show_version(argv[0]);
  }

  /* Additional cmdline processing */
#if ENABLE_LINUXDVB
  if (!opt_dvb_adapters) {
    adapter_mask = ~0;
  } else {
    char *p, *e;
    char *r = NULL;
    char *dvb_adapters = strdup(opt_dvb_adapters);
    adapter_mask = 0x0;
    p = strtok_r(dvb_adapters, ",", &r);
    while (p) {
      int a = strtol(p, &e, 10);
      if (*e != 0 || a < 0 || a > 31) {
        tvhlog(LOG_ERR, "START", "Invalid adapter number '%s'", p);
        free(dvb_adapters);
        return 1;
      }
      adapter_mask |= (1 << a);
      p = strtok_r(NULL, ",", &r);
    }
    free(dvb_adapters);
    if (!adapter_mask) {
      tvhlog(LOG_ERR, "START", "No adapters specified!");
      return 1;
    }
  }
#endif
  if (tvheadend_webroot) {
    char *tmp;
    if (*tvheadend_webroot == '/')
      tmp = strdup(tvheadend_webroot);
    else {
      tmp = malloc(strlen(tvheadend_webroot)+2);
      *tmp = '/';
      strcpy(tmp+1, tvheadend_webroot);
    }
    if (tmp[strlen(tmp)-1] == '/')
      tmp[strlen(tmp)-1] = '\0';
    tvheadend_webroot = tmp;
  }
  tvheadend_webui_debug = opt_uidebug;

  /* Setup logging */
  if (isatty(2))
    log_options |= TVHLOG_OPT_DECORATE;
  if (opt_stderr || opt_syslog || opt_logpath) {
    if (!opt_log_trace && !opt_log_debug)
      log_debug      = "all";
    log_level      = LOG_DEBUG;
    if (opt_stderr)
      log_options   |= TVHLOG_OPT_DBG_STDERR;
    if (opt_syslog)
      log_options   |= TVHLOG_OPT_DBG_SYSLOG;
    if (opt_logpath)
      log_options   |= TVHLOG_OPT_DBG_FILE;
  }
  if (opt_fileline)
    log_options |= TVHLOG_OPT_FILELINE;
  if (opt_threadid)
    log_options |= TVHLOG_OPT_THREAD;
  if (opt_log_trace) {
    log_level  = LOG_TRACE;
    log_trace  = opt_log_trace;
  }
  if (opt_log_debug)
    log_debug  = opt_log_debug;
    
  tvhlog_init(log_level, log_options, opt_logpath);
  tvhlog_set_debug(log_debug);
  tvhlog_set_trace(log_trace);
 
  signal(SIGPIPE, handle_sigpipe); // will be redundant later

  /* Daemonise */
  if(opt_fork) {
    const char *homedir;
    gid_t gid;
    uid_t uid;
    struct group  *grp = getgrnam(opt_group ?: "video");
    struct passwd *pw  = opt_user ? getpwnam(opt_user) : NULL;
    FILE   *pidfile    = fopen(opt_pidpath, "w+");

    if(grp != NULL) {
      gid = grp->gr_gid;
    } else {
      gid = 1;
    }

    if (pw != NULL) {
      if (getuid() != pw->pw_uid) {
        gid_t glist[10];
        int gnum;
        gnum = get_user_groups(pw, glist, 10);
        if (setgroups(gnum, glist)) {
          tvhlog(LOG_ALERT, "START",
                 "setgroups() failed, do you have permission?");
          return 1;
        }
      }
      uid     = pw->pw_uid;
      homedir = pw->pw_dir;
      setenv("HOME", homedir, 1);
    } else {
      uid = 1;
    }
    if ((getgid() != gid) && setgid(gid)) {
      tvhlog(LOG_ALERT, "START",
             "setgid() failed, do you have permission?");
      return 1;
    }
    if ((getuid() != uid) && setuid(uid)) {
      tvhlog(LOG_ALERT, "START",
             "setuid() failed, do you have permission?");
      return 1;
    }

    if(daemon(0, 0)) {
      exit(2);
    }
    if(pidfile != NULL) {
      fprintf(pidfile, "%d\n", getpid());
      fclose(pidfile);
    }

    /* Make dumpable */
    if (opt_dump) {
#ifdef PLATFORM_LINUX
      if (chdir("/tmp"))
        tvhwarn("START", "failed to change cwd to /tmp");
      prctl(PR_SET_DUMPABLE, 1);
#else
      tvhwarn("START", "Coredumps not implemented on your platform");
#endif
    }

    umask(0);
  }

  tvheadend_running = 1;

  /* Start log thread (must be done post fork) */
  tvhlog_start();

  /* Alter logging */
  if (opt_fork)
    tvhlog_options &= ~TVHLOG_OPT_STDERR;
  if (!isatty(2))
    tvhlog_options &= ~TVHLOG_OPT_DECORATE;
  
  /* Initialise clock */
  pthread_mutex_lock(&global_lock);
  time(&dispatch_clock);

  /* Signal handling */
  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, NULL);
  trap_init(argv[0]);
  
  /* Initialise configuration */
  uuid_init();
  idnode_init();
  config_init(opt_config);

  /**
   * Initialize subsystems
   */
  
  api_init();

  fsmonitor_init();

#if ENABLE_LIBAV
  libav_init();
  transcoding_init();
#endif

  imagecache_init();

  service_init();

#if ENABLE_TSFILE
  if(opt_tsfile.num) {
    tsfile_init(opt_tsfile_tuner ?: opt_tsfile.num);
    for (i = 0; i < opt_tsfile.num; i++)
      tsfile_add_file(opt_tsfile.str[i]);
  }
#endif
#if ENABLE_MPEGTS_DVB
  dvb_network_init();
#endif
#if ENABLE_IPTV
  iptv_init();
#endif
#if ENABLE_LINUXDVB
  linuxdvb_init(adapter_mask);
#endif

  channel_init();

  subscription_init();

  access_init(opt_firstrun, opt_noacl);

#if ENABLE_TIMESHIFT
  timeshift_init();
#endif

  http_client_init();
  tcp_server_init(opt_ipv6);
  http_server_init(opt_bindaddr);
  webui_init();

  service_mapper_init();

  descrambler_init();

  epggrab_init();
  epg_init();

  dvr_init();

  htsp_init(opt_bindaddr);


  if(opt_subscribe != NULL)
    subscription_dummy_join(opt_subscribe, 1);

  avahi_init();

  epg_updated(); // cleanup now all prev ref's should have been created

  pthread_mutex_unlock(&global_lock);

  /**
   * Wait for SIGTERM / SIGINT, but only in this thread
   */

  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGINT);

  signal(SIGTERM, doexit);
  signal(SIGINT, doexit);

  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
         "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s",
         tvheadend_version,
         getpid(), getuid(), getgid(), getcwd(buf, sizeof(buf)),
         hts_settings_get_root());

  if(opt_abort)
    abort();

  mainloop();

  tvhftrace("main", htsp_done);
  tvhftrace("main", http_server_done);
  tvhftrace("main", webui_done);
  tvhftrace("main", http_client_done);
  tvhftrace("main", fsmonitor_done);
#if ENABLE_MPEGTS_DVB
  tvhftrace("main", dvb_network_done);
#endif
#if ENABLE_IPTV
  tvhftrace("main", iptv_done);
#endif
#if ENABLE_LINUXDVB
  tvhftrace("main", linuxdvb_done);
#endif
#if ENABLE_TSFILE
  tvhftrace("main", tsfile_done);
#endif

  // Note: the locking is obviously a bit redundant, but without
  //       we need to disable the gtimer_arm call in epg_save()
  pthread_mutex_lock(&global_lock);
  tvhftrace("main", epg_save);

#if ENABLE_TIMESHIFT
  tvhftrace("main", timeshift_term);
#endif
  pthread_mutex_unlock(&global_lock);

  tvhftrace("main", epggrab_done);
  tvhftrace("main", tcp_server_done);
  tvhftrace("main", descrambler_done);
  tvhftrace("main", service_mapper_done);
  tvhftrace("main", service_done);
  tvhftrace("main", channel_done);
  tvhftrace("main", dvr_done);
  tvhftrace("main", subscription_done);
  tvhftrace("main", access_done);
  tvhftrace("main", epg_done);
  tvhftrace("main", avahi_done);
  tvhftrace("main", imagecache_done);
  tvhftrace("main", idnode_done);
  tvhftrace("main", lang_code_done);
  tvhftrace("main", api_done);
  tvhftrace("main", config_done);
  tvhftrace("main", hts_settings_done);
  tvhftrace("main", dvb_done);
  tvhftrace("main", lang_str_done);

  tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend");
  tvhlog_end();

  if(opt_fork)
    unlink(opt_pidpath);
    
  free(opt_tsfile.str);

  return 0;
}
示例#16
0
文件: httpd.c 项目: ijz/ribs2
int main(int argc, char *argv[]) {
    static struct option long_options[] = {
        {"port", 1, 0, 'p'},
        {"daemonize", 0, 0, 'd'},
        {"forks", 1, 0, 'f'},
        {0, 0, 0, 0}
    };

    int port = 8080;
    int daemon_mode = 0;
    int forks = 0;
    for (;;) {
        int option_index = 0;
        int c = getopt_long(argc, argv, "p:f:d", long_options, &option_index);
        if (c == -1)
            break;
        switch (c) {
        case 'p':
            port = atoi(optarg);
            break;
        case 'd':
            daemon_mode = 1;
            break;
        case 'f':
            forks = atoi(optarg);
            break;
        }
    }

    /* server config */
    struct http_server server = {
        /* port number */
        .port = port,

        /* call simple_file_server upon receiving http request */
        .user_func = simple_file_server,

        /* set idle connection timeout to 60 seconds */
        .timeout_handler.timeout = 60000,

        /* set fiber's stack size to automatic (0) */
        .stack_size = 0,

        /* start the server with 100 stacks */
        /* more stacks will be created if necessary */
        .num_stacks =  100,

        /* we expect most of our requests to be less than 8K */
        .init_request_size = 8192,

        /* we expect most of our response headers to be less than
           8K */
        .init_header_size = 8192,

        /* we expect most of our response payloads to be less than
           8K */
        .init_payload_size = 8192,

        /* no limit on the request size, this should be set to
           something reasonable if you want to protect your server
           against denial of service attack */
        .max_req_size = 0,

        /* no additional space is needed in the context to store app
           specified data (fiber local storage) */
        .context_size = 0
    };

    /* initialize server, but don't accept connections yet */
    if (0 > http_server_init(&server))
        exit(EXIT_FAILURE);

    /* run as daemon if specified */
    if (daemon_mode)
        daemonize(), daemon_finalize();

    /* assume autoconfiguration if forks is not a positive value */
    if (0 >= forks) {
        forks = sysconf(_SC_NPROCESSORS_CONF);
        if (0 > forks)
            exit(EXIT_FAILURE);
    }

    for(; forks > 1; --forks){
        if (0 >= fork()) {
            break;
        }
    }

    /* initialize the event loop */
    if (0 > epoll_worker_init())
        exit(EXIT_FAILURE);

    /* start accepting connections, must be called after initializing
       epoll worker */
    if (0 > http_server_init_acceptor(&server))
        exit(EXIT_FAILURE);

    epoll_worker_loop();
    return 0;
}
示例#17
0
文件: main.c 项目: bigbig6/tvheadend
int
main(int argc, char **argv)
{
  int i;
  sigset_t set;
#if ENABLE_MPEGTS
  uint32_t adapter_mask = 0;
#endif
  int  log_level   = LOG_INFO;
  int  log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG;
  const char *log_debug = NULL, *log_trace = NULL;
  gid_t gid = -1;
  uid_t uid = -1;
  char buf[512];
  FILE *pidfile = NULL;
  extern int dvb_bouquets_parse;

  main_tid = pthread_self();

  /* Setup global mutexes */
  pthread_mutex_init(&fork_lock, NULL);
  pthread_mutex_init(&global_lock, NULL);
  pthread_mutex_init(&tasklet_lock, NULL);
  pthread_mutex_init(&atomic_lock, NULL);
  pthread_cond_init(&gtimer_cond, NULL);
  pthread_cond_init(&tasklet_cond, NULL);
  TAILQ_INIT(&tasklets);

  /* Defaults */
  tvheadend_webui_port      = 9981;
  tvheadend_webroot         = NULL;
  tvheadend_htsp_port       = 9982;
  tvheadend_htsp_port_extra = 0;
  time(&dispatch_clock);

  /* Command line options */
  int         opt_help         = 0,
              opt_version      = 0,
              opt_fork         = 0,
              opt_firstrun     = 0,
              opt_stderr       = 0,
              opt_syslog       = 0,
              opt_nosyslog     = 0,
              opt_uidebug      = 0,
              opt_abort        = 0,
              opt_noacl        = 0,
              opt_fileline     = 0,
              opt_threadid     = 0,
              opt_libav        = 0,
              opt_ipv6         = 0,
              opt_satip_rtsp   = 0,
#if ENABLE_TSFILE
              opt_tsfile_tuner = 0,
#endif
              opt_dump         = 0,
              opt_xspf         = 0,
              opt_dbus         = 0,
              opt_dbus_session = 0,
              opt_nobackup     = 0,
              opt_nobat        = 0;
  const char *opt_config       = NULL,
             *opt_user         = NULL,
             *opt_group        = NULL,
             *opt_logpath      = NULL,
             *opt_log_debug    = NULL,
             *opt_log_trace    = NULL,
             *opt_pidpath      = "/var/run/tvheadend.pid",
#if ENABLE_LINUXDVB
             *opt_dvb_adapters = NULL,
#endif
             *opt_bindaddr     = NULL,
             *opt_subscribe    = NULL,
             *opt_user_agent   = NULL;
  str_list_t  opt_satip_xml    = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  str_list_t  opt_tsfile       = { .max = 10, .num = 0, .str = calloc(10, sizeof(char*)) };
  cmdline_opt_t cmdline_opts[] = {
    {   0, NULL,        N_("Generic Options"),         OPT_BOOL, NULL         },
    { 'h', "help",      N_("Show this page"),          OPT_BOOL, &opt_help    },
    { 'v', "version",   N_("Show version information"),OPT_BOOL, &opt_version },

    {   0, NULL,        N_("Service Configuration"),   OPT_BOOL, NULL         },
    { 'c', "config",    N_("Alternate config path"),   OPT_STR,  &opt_config  },
    { 'B', "nobackup",  N_("Don't backup config tree at upgrade"), OPT_BOOL, &opt_nobackup },
    { 'f', "fork",      N_("Fork and run as daemon"),  OPT_BOOL, &opt_fork    },
    { 'u', "user",      N_("Run as user"),             OPT_STR,  &opt_user    },
    { 'g', "group",     N_("Run as group"),            OPT_STR,  &opt_group   },
    { 'p', "pid",       N_("Alternate pid path"),      OPT_STR,  &opt_pidpath },
    { 'C', "firstrun",  N_("If no user account exists then create one with\n"
	                   "no username and no password. Use with care as\n"
	                   "it will allow world-wide administrative access\n"
	                   "to your Tvheadend installation until you edit/create\n"
	                   "access-control from within the Tvheadend UI"),
      OPT_BOOL, &opt_firstrun },
#if ENABLE_DBUS_1
    { 'U', "dbus",      N_("Enable DBus"),
      OPT_BOOL, &opt_dbus },
    { 'e', "dbus_session", N_("DBus - use the session message bus instead system one"),
      OPT_BOOL, &opt_dbus_session },
#endif
#if ENABLE_LINUXDVB
    { 'a', "adapters",  N_("Only use specified DVB adapters (comma separated)"),
      OPT_STR, &opt_dvb_adapters },
#endif
#if ENABLE_SATIP_SERVER
    {   0, "satip_rtsp", N_("SAT>IP RTSP port number for server\n"
                            "(default: -1 = disable, 0 = webconfig, standard port is 554)"),
      OPT_INT, &opt_satip_rtsp },
#endif
#if ENABLE_SATIP_CLIENT
    {   0, "satip_xml", N_("URL with the SAT>IP server XML location"),
      OPT_STR_LIST, &opt_satip_xml },
#endif
    {   0, NULL,         N_("Server Connectivity"),    OPT_BOOL, NULL         },
    { '6', "ipv6",       N_("Listen on IPv6"),         OPT_BOOL, &opt_ipv6    },
    { 'b', "bindaddr",   N_("Specify bind address"),   OPT_STR,  &opt_bindaddr},
    {   0, "http_port",  N_("Specify alternative http port"),
      OPT_INT, &tvheadend_webui_port },
    {   0, "http_root",  N_("Specify alternative http webroot"),
      OPT_STR, &tvheadend_webroot },
    {   0, "htsp_port",  N_("Specify alternative htsp port"),
      OPT_INT, &tvheadend_htsp_port },
    {   0, "htsp_port2", N_("Specify extra htsp port"),
      OPT_INT, &tvheadend_htsp_port_extra },
    {   0, "useragent",  N_("Specify User-Agent header for the http client"),
      OPT_STR, &opt_user_agent },
    {   0, "xspf",       N_("Use XSPF playlist instead of M3U"),
      OPT_BOOL, &opt_xspf },

    {   0, NULL,        N_("Debug Options"),           OPT_BOOL, NULL         },
    { 'd', "stderr",    N_("Enable debug on stderr"),  OPT_BOOL, &opt_stderr  },
    { 's', "syslog",    N_("Enable debug to syslog"),  OPT_BOOL, &opt_syslog  },
    { 'S', "nosyslog",  N_("Disable syslog (all msgs)"), OPT_BOOL, &opt_nosyslog },
    { 'l', "logfile",   N_("Enable debug to file"),    OPT_STR,  &opt_logpath },
    {   0, "debug",     N_("Enable debug subsystems"),  OPT_STR,  &opt_log_debug },
#if ENABLE_TRACE
    {   0, "trace",     N_("Enable trace subsystems"), OPT_STR,  &opt_log_trace },
#endif
    {   0, "fileline",  N_("Add file and line numbers to debug"), OPT_BOOL, &opt_fileline },
    {   0, "threadid",  N_("Add the thread ID to debug"), OPT_BOOL, &opt_threadid },
#if ENABLE_LIBAV
    {   0, "libav",     N_("More verbose libav log"),  OPT_BOOL, &opt_libav },
#endif
    {   0, "uidebug",   N_("Enable webUI debug (non-minified JS)"), OPT_BOOL, &opt_uidebug },
    { 'A', "abort",     N_("Immediately abort"),       OPT_BOOL, &opt_abort   },
    { 'D', "dump",      N_("Enable coredumps for daemon"), OPT_BOOL, &opt_dump },
    {   0, "noacl",     N_("Disable all access control checks"),
      OPT_BOOL, &opt_noacl },
    {   0, "nobat",     N_("Disable DVB bouquets"),
      OPT_BOOL, &opt_nobat },
    { 'j', "join",      N_("Subscribe to a service permanently"),
      OPT_STR, &opt_subscribe },


#if ENABLE_TSFILE || ENABLE_TSDEBUG
    { 0, NULL, N_("Testing options"), OPT_BOOL, NULL },
    { 0, "tsfile_tuners", N_("Number of tsfile tuners"), OPT_INT, &opt_tsfile_tuner },
    { 0, "tsfile", N_("tsfile input (mux file)"), OPT_STR_LIST, &opt_tsfile },
#endif
#if ENABLE_TSDEBUG
    { 0, "tsdebug", N_("Output directory for tsdebug"), OPT_STR, &tvheadend_tsdebug },
#endif

  };

  /* Get current directory */
  tvheadend_cwd0 = dirname(tvh_strdupa(argv[0]));
  tvheadend_cwd = dirname(tvh_strdupa(tvheadend_cwd0));

  /* Set locale */
  setlocale(LC_ALL, "");
  setlocale(LC_NUMERIC, "C");

  /* make sure the timezone is set */
  tzset();

  /* Process command line */
  for (i = 1; i < argc; i++) {

    /* Find option */
    cmdline_opt_t *opt
      = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]);
    if (!opt)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 _("invalid option specified [%s]"), argv[i]);

    /* Process */
    if (opt->type == OPT_BOOL)
      *((int*)opt->param) = 1;
    else if (++i == argc)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 _("option %s requires a value"), opt->lopt);
    else if (opt->type == OPT_INT)
      *((int*)opt->param) = atoi(argv[i]);
    else if (opt->type == OPT_STR_LIST) {
      str_list_t *strl = opt->param;
      if (strl->num < strl->max)
        strl->str[strl->num++] = argv[i];
    }
    else
      *((char**)opt->param) = argv[i];

    /* Stop processing */
    if (opt_help)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), NULL);
    if (opt_version)
      show_version(argv[0]);
  }

  /* Additional cmdline processing */
  if (opt_nobat)
    dvb_bouquets_parse = 0;
#if ENABLE_LINUXDVB
  if (!opt_dvb_adapters) {
    adapter_mask = ~0;
  } else {
    char *p, *e;
    char *r = NULL;
    char *dvb_adapters = strdup(opt_dvb_adapters);
    adapter_mask = 0x0;
    p = strtok_r(dvb_adapters, ",", &r);
    while (p) {
      int a = strtol(p, &e, 10);
      if (*e != 0 || a < 0 || a > 31) {
        fprintf(stderr, _("Invalid adapter number '%s'\n"), p);
        free(dvb_adapters);
        return 1;
      }
      adapter_mask |= (1 << a);
      p = strtok_r(NULL, ",", &r);
    }
    free(dvb_adapters);
    if (!adapter_mask) {
      fprintf(stderr, "%s", _("No adapters specified!\n"));
      return 1;
    }
  }
#endif
  if (tvheadend_webroot) {
    char *tmp;
    if (*tvheadend_webroot == '/')
      tmp = strdup(tvheadend_webroot);
    else {
      tmp = malloc(strlen(tvheadend_webroot)+2);
      *tmp = '/';
      strcpy(tmp+1, tvheadend_webroot);
    }
    if (tmp[strlen(tmp)-1] == '/')
      tmp[strlen(tmp)-1] = '\0';
    tvheadend_webroot = tmp;
  }
  tvheadend_webui_debug = opt_uidebug;

  /* Setup logging */
  if (isatty(2))
    log_options |= TVHLOG_OPT_DECORATE;
  if (opt_stderr || opt_syslog || opt_logpath) {
    if (!opt_log_trace && !opt_log_debug)
      log_debug      = "all";
    log_level      = LOG_DEBUG;
    if (opt_stderr)
      log_options   |= TVHLOG_OPT_DBG_STDERR;
    if (opt_syslog)
      log_options   |= TVHLOG_OPT_DBG_SYSLOG;
    if (opt_logpath)
      log_options   |= TVHLOG_OPT_DBG_FILE;
  }
  if (opt_nosyslog)
    log_options &= ~(TVHLOG_OPT_SYSLOG|TVHLOG_OPT_DBG_SYSLOG);
  if (opt_fileline)
    log_options |= TVHLOG_OPT_FILELINE;
  if (opt_threadid)
    log_options |= TVHLOG_OPT_THREAD;
  if (opt_libav)
    log_options |= TVHLOG_OPT_LIBAV;
  if (opt_log_trace) {
    log_level  = LOG_TRACE;
    log_trace  = opt_log_trace;
  }
  if (opt_log_debug)
    log_debug  = opt_log_debug;
    
  tvhlog_init(log_level, log_options, opt_logpath);
  tvhlog_set_debug(log_debug);
  tvhlog_set_trace(log_trace);
  tvhinfo("main", "Log started");
 
  signal(SIGPIPE, handle_sigpipe); // will be redundant later
  signal(SIGILL, handle_sigill);   // see handler..

  /* Set priviledges */
  if(opt_fork || opt_group || opt_user) {
    const char *homedir;
    struct group  *grp = getgrnam(opt_group ?: "video");
    struct passwd *pw  = opt_user ? getpwnam(opt_user) : NULL;

    if(grp != NULL) {
      gid = grp->gr_gid;
    } else {
      gid = 1;
    }

    if (pw != NULL) {
      if (getuid() != pw->pw_uid) {
        gid_t glist[16];
        int gnum;
        gnum = get_user_groups(pw, glist, ARRAY_SIZE(glist));
        if (gnum > 0 && setgroups(gnum, glist)) {
          char buf[256] = "";
          int i;
          for (i = 0; i < gnum; i++)
            snprintf(buf + strlen(buf), sizeof(buf) - 1 - strlen(buf),
                     ",%d", glist[i]);
          tvhlog(LOG_ALERT, "START",
                 "setgroups(%s) failed, do you have permission?", buf+1);
          return 1;
        }
      }
      uid     = pw->pw_uid;
      homedir = pw->pw_dir;
      setenv("HOME", homedir, 1);
    } else {
      uid = 1;
    }
  }

  uuid_init();
  config_boot(opt_config, gid, uid);
  tcp_server_preinit(opt_ipv6);
  http_server_init(opt_bindaddr);    // bind to ports only
  htsp_init(opt_bindaddr);	     // bind to ports only
  satip_server_init(opt_satip_rtsp); // bind to ports only

  if (opt_fork)
    pidfile = tvh_fopen(opt_pidpath, "w+");

  if (gid != -1 && (getgid() != gid) && setgid(gid)) {
    tvhlog(LOG_ALERT, "START",
           "setgid(%d) failed, do you have permission?", gid);
    return 1;
  }
  if (uid != -1 && (getuid() != uid) && setuid(uid)) {
    tvhlog(LOG_ALERT, "START",
           "setuid(%d) failed, do you have permission?", uid);
    return 1;
  }

  /* Daemonise */
  if(opt_fork) {
    if(daemon(0, 0)) {
      exit(2);
    }
    if(pidfile != NULL) {
      fprintf(pidfile, "%d\n", getpid());
      fclose(pidfile);
    }

    /* Make dumpable */
    if (opt_dump) {
#ifdef PLATFORM_LINUX
      if (chdir("/tmp"))
        tvhwarn("START", "failed to change cwd to /tmp");
      prctl(PR_SET_DUMPABLE, 1);
#else
      tvhwarn("START", "Coredumps not implemented on your platform");
#endif
    }

    umask(0);
  }

  tvheadend_running = 1;

  /* Start log thread (must be done post fork) */
  tvhlog_start();

  /* Alter logging */
  if (opt_fork)
    tvhlog_options &= ~TVHLOG_OPT_STDERR;
  if (!isatty(2))
    tvhlog_options &= ~TVHLOG_OPT_DECORATE;
  
  /* Initialise clock */
  pthread_mutex_lock(&global_lock);
  time(&dispatch_clock);

  /* Signal handling */
  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, NULL);
  trap_init(argv[0]);

  /* SSL library init */
  OPENSSL_config(NULL);
  SSL_load_error_strings();
  SSL_library_init();

  /* Initialise configuration */
  notify_init();
  idnode_init();
  spawn_init();
  config_init(opt_nobackup == 0);

  /**
   * Initialize subsystems
   */

  epg_in_load = 1;

  tvhthread_create(&tasklet_tid, NULL, tasklet_thread, NULL);

  dbus_server_init(opt_dbus, opt_dbus_session);

  intlconv_init();
  
  api_init();

  fsmonitor_init();

  libav_init();

  tvhtime_init();

  profile_init();

  imagecache_init();

  http_client_init(opt_user_agent);
  esfilter_init();

  bouquet_init();

  service_init();

  dvb_init();

#if ENABLE_MPEGTS
  mpegts_init(adapter_mask, &opt_satip_xml, &opt_tsfile, opt_tsfile_tuner);
#endif

  channel_init();

  bouquet_service_resolve();

  subscription_init();

  dvr_config_init();

  access_init(opt_firstrun, opt_noacl);

#if ENABLE_TIMESHIFT
  timeshift_init();
#endif

  tcp_server_init();
  webui_init(opt_xspf);
#if ENABLE_UPNP
  upnp_server_init(opt_bindaddr);
#endif

  service_mapper_init();

  descrambler_init();

  epggrab_init();
  epg_init();

  dvr_init();

  dbus_server_start();

  http_server_register();
  satip_server_register();
  htsp_register();

  if(opt_subscribe != NULL)
    subscription_dummy_join(opt_subscribe, 1);

  avahi_init();
  bonjour_init();

  epg_updated(); // cleanup now all prev ref's should have been created
  epg_in_load = 0;

  pthread_mutex_unlock(&global_lock);

  /**
   * Wait for SIGTERM / SIGINT, but only in this thread
   */

  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGINT);

  signal(SIGTERM, doexit);
  signal(SIGINT, doexit);

  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
         "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s",
         tvheadend_version,
         getpid(), getuid(), getgid(), getcwd(buf, sizeof(buf)),
         hts_settings_get_root());

  if(opt_abort)
    abort();

  mainloop();

#if ENABLE_DBUS_1
  tvhftrace("main", dbus_server_done);
#endif
#if ENABLE_UPNP
  tvhftrace("main", upnp_server_done);
#endif
  tvhftrace("main", satip_server_done);
  tvhftrace("main", htsp_done);
  tvhftrace("main", http_server_done);
  tvhftrace("main", webui_done);
  tvhftrace("main", fsmonitor_done);
  tvhftrace("main", http_client_done);
  tvhftrace("main", tcp_server_done);

  // Note: the locking is obviously a bit redundant, but without
  //       we need to disable the gtimer_arm call in epg_save()
  pthread_mutex_lock(&global_lock);
  tvhftrace("main", epg_save);

#if ENABLE_TIMESHIFT
  tvhftrace("main", timeshift_term);
#endif
  pthread_mutex_unlock(&global_lock);

  tvhftrace("main", epggrab_done);
#if ENABLE_MPEGTS
  tvhftrace("main", mpegts_done);
#endif
  tvhftrace("main", descrambler_done);
  tvhftrace("main", service_mapper_done);
  tvhftrace("main", service_done);
  tvhftrace("main", channel_done);
  tvhftrace("main", bouquet_done);
  tvhftrace("main", dvr_done);
  tvhftrace("main", subscription_done);
  tvhftrace("main", access_done);
  tvhftrace("main", epg_done);
  tvhftrace("main", avahi_done);
  tvhftrace("main", bonjour_done);
  tvhftrace("main", imagecache_done);
  tvhftrace("main", lang_code_done);
  tvhftrace("main", api_done);

  tvhtrace("main", "tasklet enter");
  pthread_cond_signal(&tasklet_cond);
  pthread_join(tasklet_tid, NULL);
  tvhtrace("main", "tasklet thread end");
  tasklet_flush();
  tvhtrace("main", "tasklet leave");

  tvhftrace("main", hts_settings_done);
  tvhftrace("main", dvb_done);
  tvhftrace("main", lang_str_done);
  tvhftrace("main", esfilter_done);
  tvhftrace("main", profile_done);
  tvhftrace("main", intlconv_done);
  tvhftrace("main", urlparse_done);
  tvhftrace("main", idnode_done);
  tvhftrace("main", notify_done);
  tvhftrace("main", spawn_done);

  tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend");
  tvhlog_end();

  tvhftrace("main", config_done);

  if(opt_fork)
    unlink(opt_pidpath);
    
#if ENABLE_TSFILE
  free(opt_tsfile.str);
#endif
  free(opt_satip_xml.str);

  /* OpenSSL - welcome to the "cleanup" hell */
  ENGINE_cleanup();
  RAND_cleanup();
  CRYPTO_cleanup_all_ex_data();
  EVP_cleanup();
  CONF_modules_free();
#ifndef OPENSSL_NO_COMP
  COMP_zlib_cleanup();
#endif
  ERR_remove_state(0);
  ERR_free_strings();
#ifndef OPENSSL_NO_COMP
  sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
#endif
  /* end of OpenSSL cleanup code */

#if ENABLE_DBUS_1
  extern void dbus_shutdown(void);
  if (opt_dbus) dbus_shutdown();
#endif
  return 0;
}

/**
 *
 */
void
tvh_str_set(char **strp, const char *src)
{
  free(*strp);
  *strp = src ? strdup(src) : NULL;
}


/**
 *
 */
int
tvh_str_update(char **strp, const char *src)
{
  if(src == NULL)
    return 0;
  free(*strp);
  *strp = strdup(src);
  return 1;
}


/**
 *
 */
void
scopedunlock(pthread_mutex_t **mtxp)
{
  pthread_mutex_unlock(*mtxp);
}
示例#18
0
文件: main.c 项目: shahxeb/tvheadend
int
main(int argc, char **argv)
{
  int i;
  sigset_t set;
#if ENABLE_LINUXDVB
  uint32_t adapter_mask;
#endif

  /* Defaults */
  log_stderr                = 1;
  log_decorate              = isatty(2);
  log_debug_to_syslog       = 0;
  log_debug_to_console      = 0;
  log_debug_to_path         = 0;
  log_path                  = NULL;
  tvheadend_webui_port      = 9981;
  tvheadend_webroot         = NULL;
  tvheadend_htsp_port       = 9982;
  tvheadend_htsp_port_extra = 0;

  /* Command line options */
  int         opt_help         = 0,
              opt_version      = 0,
              opt_fork         = 0,
              opt_firstrun     = 0,
              opt_debug        = 0,
              opt_syslog       = 0,
              opt_uidebug      = 0,
              opt_abort        = 0,
              opt_noacl        = 0,
              opt_ipv6         = 0;
  const char *opt_config       = NULL,
             *opt_user         = NULL,
             *opt_group        = NULL,
             *opt_pidpath      = "/var/run/tvheadend.pid",
#if ENABLE_LINUXDVB
             *opt_dvb_adapters = NULL,
             *opt_dvb_raw      = NULL,
#endif
             *opt_rawts        = NULL,
             *opt_subscribe    = NULL;
  cmdline_opt_t cmdline_opts[] = {
    {   0, NULL,        "Generic Options",         OPT_BOOL, NULL         },
    { 'h', "help",      "Show this page",          OPT_BOOL, &opt_help    },
    { 'v', "version",   "Show version infomation", OPT_BOOL, &opt_version },

    {   0, NULL,        "Service Configuration",   OPT_BOOL, NULL         },
    { 'c', "config",    "Alternate config path",   OPT_STR,  &opt_config  },
    { 'f', "fork",      "Fork and run as daemon",  OPT_BOOL, &opt_fork    },
    { 'u', "user",      "Run as user",             OPT_STR,  &opt_user    },
    { 'g', "group",     "Run as group",            OPT_STR,  &opt_group   },
    { 'p', "pid",       "Alternate pid path",      OPT_STR,  &opt_pidpath },
    { 'C', "firstrun",  "If no useraccount exist then create one with\n"
	                      "no username and no password. Use with care as\n"
	                      "it will allow world-wide administrative access\n"
	                      "to your Tvheadend installation until you edit\n"
	                      "the access-control from within the Tvheadend UI",
      OPT_BOOL, &opt_firstrun },
#if ENABLE_LINUXDVB
    { 'a', "adapters",  "Use only specified DVB adapters",
      OPT_STR, &opt_dvb_adapters },
#endif
    {   0, NULL,         "Server Connectivity",    OPT_BOOL, NULL         },
    { '6', "ipv6",       "Listen on IPv6",         OPT_BOOL, &opt_ipv6    },
    {   0, "http_port",  "Specify alternative http port",
      OPT_INT, &tvheadend_webui_port },
    {   0, "http_root",  "Specify alternative http webroot",
      OPT_STR, &tvheadend_webroot },
    {   0, "htsp_port",  "Specify alternative htsp port",
      OPT_INT, &tvheadend_htsp_port },
    {   0, "htsp_port2", "Specify extra htsp port",
      OPT_INT, &tvheadend_htsp_port_extra },

    {   0, NULL,        "Debug Options",           OPT_BOOL, NULL         },
    { 'd', "debug",     "Enable all debug",        OPT_BOOL, &opt_debug   },
    { 's', "syslog",    "Enable debug to syslog",  OPT_BOOL, &opt_syslog  },
    {   0, "uidebug",   "Enable webUI debug",      OPT_BOOL, &opt_uidebug },
    { 'l', "log",       "Log to file",             OPT_STR,  &log_path    },
    { 'A', "abort",     "Immediately abort",       OPT_BOOL, &opt_abort   },
    {   0, "noacl",     "Disable all access control checks",
      OPT_BOOL, &opt_noacl },
#if ENABLE_LINUXDVB
    { 'R', "dvbraw",    "Use rawts file to create virtual adapter",
      OPT_STR, &opt_dvb_raw },
#endif
    { 'r', "rawts",     "Use rawts file to generate virtual services",
      OPT_STR, &opt_rawts },
    { 'j', "join",      "Subscribe to a service permanently",
      OPT_STR, &opt_subscribe }
  };

  /* Get current directory */
  tvheadend_cwd = dirname(dirname(tvh_strdupa(argv[0])));

  /* Set locale */
  setlocale(LC_ALL, "");

  /* make sure the timezone is set */
  tzset();

  /* Process command line */
  for (i = 1; i < argc; i++) {

    /* Find option */
    cmdline_opt_t *opt
      = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]);
    if (!opt)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 "invalid option specified [%s]", argv[i]);

    /* Process */
    if (opt->type == OPT_BOOL)
      *((int*)opt->param) = 1;
    else if (++i == argc)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts),
                 "option %s requires a value", opt->lopt);
    else if (opt->type == OPT_INT)
      *((int*)opt->param) = atoi(argv[i]);
    else
      *((char**)opt->param) = argv[i];

    /* Stop processing */
    if (opt_help)
      show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), NULL);
    if (opt_version)
      show_version(argv[0]);
  }

  /* Additional cmdline processing */
  log_debug_to_console  = opt_debug;
  log_debug_to_syslog   = opt_syslog;
  log_debug_to_path     = opt_debug;
  tvheadend_webui_debug = opt_debug || opt_uidebug;
  tvhlog(LOG_INFO, "START", "initialising");
#if ENABLE_LINUXDVB
  if (!opt_dvb_adapters) {
    adapter_mask = ~0;
  } else {
    char *p, *r, *e;
    adapter_mask = 0x0;
    p = strtok_r((char*)opt_dvb_adapters, ",", &r);
    while (p) {
      int a = strtol(p, &e, 10);
      if (*e != 0 || a < 0 || a > 31) {
        tvhlog(LOG_ERR, "START", "Invalid adapter number '%s'", p);
        return 1;
      }
      adapter_mask |= (1 << a);
      p = strtok_r(NULL, ",", &r);
    }
    if (!adapter_mask) {
      tvhlog(LOG_ERR, "START", "No adapters specified!");
      return 1;
    }
  }
#endif
  if (tvheadend_webroot) {
    char *tmp;
    if (*tvheadend_webroot == '/')
      tmp = strdup(tvheadend_webroot);
    else {
      tmp = malloc(strlen(tvheadend_webroot)+1);
      *tmp = '/';
      strcpy(tmp+1, tvheadend_webroot);
    }
    if (tmp[strlen(tmp)-1] == '/')
      tmp[strlen(tmp)-1] = '\0';
    tvheadend_webroot = tmp;
  }

  signal(SIGPIPE, handle_sigpipe); // will be redundant later

  /* Daemonise */
  if(opt_fork) {
    const char *homedir;
    gid_t gid;
    uid_t uid;
    struct group  *grp = getgrnam(opt_group ?: "video");
    struct passwd *pw  = opt_user ? getpwnam(opt_user) : NULL;
    FILE   *pidfile    = fopen(opt_pidpath, "w+");

    if(grp != NULL) {
      gid = grp->gr_gid;
    } else {
      gid = 1;
    }

    if (pw != NULL) {
      if (getuid() != pw->pw_uid) {
        gid_t glist[10];
        int gnum;
        gnum = get_user_groups(pw, glist, 10);
        if (setgroups(gnum, glist)) {
          tvhlog(LOG_ALERT, "START",
                 "setgroups() failed, do you have permission?");
          return 1;
        }
      }
      uid     = pw->pw_uid;
      homedir = pw->pw_dir;
      setenv("HOME", homedir, 1);
    } else {
      uid = 1;
    }
    if ((getgid() != gid) && setgid(gid)) {
      tvhlog(LOG_ALERT, "START",
             "setgid() failed, do you have permission?");
      return 1;
    }
    if ((getuid() != uid) && setuid(uid)) {
      tvhlog(LOG_ALERT, "START",
             "setuid() failed, do you have permission?");
      return 1;
    }

    if(daemon(0, 0)) {
      exit(2);
    }
    if(pidfile != NULL) {
      fprintf(pidfile, "%d\n", getpid());
      fclose(pidfile);
    }

    umask(0);
  }

  /* Setup logging */
  log_stderr   = !opt_fork;
  log_decorate = isatty(2);
  openlog("tvheadend", LOG_PID, LOG_DAEMON);

  /* Initialise configuration */
  hts_settings_init(opt_config);

  /* Setup global mutexes */
  pthread_mutex_init(&ffmpeg_lock, NULL);
  pthread_mutex_init(&fork_lock, NULL);
  pthread_mutex_init(&global_lock, NULL);
  pthread_mutex_lock(&global_lock);

  time(&dispatch_clock);

  /* Signal handling */
  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, NULL);
  trap_init(argv[0]);
  
  /**
   * Initialize subsystems
   */

#if ENABLE_LIBAV
  libav_init();
#endif

  config_init();

  imagecache_init();

  service_init();

  channels_init();

  subscription_init();

  access_init(opt_firstrun, opt_noacl);

#if ENABLE_LINUXDVB
  muxes_init();
  dvb_init(adapter_mask, opt_dvb_raw);
#endif

  iptv_input_init();

#if ENABLE_V4L
  v4l_init();
#endif

#if ENABLE_TIMESHIFT
  timeshift_init();
#endif

  tcp_server_init(opt_ipv6);
  http_server_init();
  webui_init();

  serviceprobe_init();

#if ENABLE_CWC
  cwc_init();
  capmt_init();
#if (!ENABLE_DVBCSA)
  ffdecsa_init();
#endif
#endif

  epggrab_init();
  epg_init();

  dvr_init();

  htsp_init();

  if(opt_rawts != NULL)
    rawts_init(opt_rawts);

  if(opt_subscribe != NULL)
    subscription_dummy_join(opt_subscribe, 1);

#ifdef CONFIG_AVAHI
  avahi_init();
#endif

  epg_updated(); // cleanup now all prev ref's should have been created

  pthread_mutex_unlock(&global_lock);

  /**
   * Wait for SIGTERM / SIGINT, but only in this thread
   */

  running = 1;
  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGINT);

  signal(SIGTERM, doexit);
  signal(SIGINT, doexit);

  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
	 "running as PID:%d UID:%d GID:%d, settings located in '%s'",
	 tvheadend_version,
	 getpid(), getuid(), getgid(), hts_settings_get_root());

  if(opt_abort)
    abort();

  mainloop();

  epg_save();

#if ENABLE_TIMESHIFT
  timeshift_term();
#endif

  tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend");

  if(opt_fork)
    unlink(opt_pidpath);

  return 0;

}
示例#19
0
void
showtime_init(void)
{
  int r;

  hts_mutex_init(&gconf.state_mutex);
  hts_cond_init(&gconf.state_cond, &gconf.state_mutex);

  gconf.exit_code = 1;

  unicode_init();

  /* Initialize property tree */
  prop_init();
  init_global_info();

  /* Initiailize logging */
  trace_init();

  /* Callout framework */
  callout_init();

  /* Initialize htsmsg_store() */
  htsmsg_store_init();

  /* Notification framework */
  notifications_init();

  /* Initialize settings */
  settings_init();

  TRACE(TRACE_DEBUG, "core", "Loading resources from %s", showtime_dataroot());

  /* Try to create cache path */
  if(gconf.cache_path != NULL &&
     (r = makedirs(gconf.cache_path)) != 0) {
    TRACE(TRACE_ERROR, "cache", "Unable to create cache path %s -- %s",
	  gconf.cache_path, strerror(r));
    gconf.cache_path = NULL;
  }

  /* Initialize sqlite3 */
  db_init();

  /* Initializte blob cache */
  blobcache_init();

  /* Try to create settings path */
  if(gconf.persistent_path != NULL &&
     (r = makedirs(gconf.persistent_path)) != 0) {
    TRACE(TRACE_ERROR, "settings",
	  "Unable to create path for persistent storage %s -- %s",
	  gconf.persistent_path, strerror(r));
    gconf.persistent_path = NULL;
  }

  /* Metadata init */
  metadata_init();
  metadb_init();
  kvstore_init();

  /* Metadata decoration init */
  decoration_init();

  /* Initialize keyring */
  keyring_init();

#if ENABLE_LIBAV
  /* Initialize libavcodec & libavformat */
  av_lockmgr_register(fflockmgr);
  av_log_set_callback(fflog);
  av_register_all();

  TRACE(TRACE_INFO, "libav", LIBAVFORMAT_IDENT", "LIBAVCODEC_IDENT", "LIBAVUTIL_IDENT);
#endif

  /* Freetype */
#if ENABLE_LIBFREETYPE
  freetype_init();
  rasterizer_ft_init();
#endif

#if ENABLE_GLW
  glw_settings_init();
#endif

  fontstash_init();

  /* Global keymapper */
  keymapper_init();

  /* Initialize media subsystem */
  media_init();

  /* Service handling */
  service_init();

  /* Initialize backend content handlers */
  backend_init();

  /* Initialize navigator */
  nav_init();

  /* Initialize audio subsystem */
  audio_init();

  /* Initialize plugin manager */
  plugins_init(gconf.devplugin);

  /* Start software installer thread (plugins, upgrade, etc) */
  hts_thread_create_detached("swinst", swthread, NULL, THREAD_PRIO_LOW);

  /* Internationalization */
  i18n_init();

  /* Video settings */
  video_settings_init();

  if(gconf.load_jsfile)
    js_load(gconf.load_jsfile);

  /* Various interprocess communication stuff (D-Bus on Linux, etc) */
  init_group(INIT_GROUP_IPC);

  /* Service discovery. Must be after ipc_init() (d-bus and threads, etc) */
  if(!gconf.disable_sd)
    sd_init();

  /* Initialize various external APIs */
  init_group(INIT_GROUP_API);

  /* HTTP server and UPNP */
#if ENABLE_HTTPSERVER
  http_server_init();
  if(!gconf.disable_upnp)
    upnp_init();
#endif

  runcontrol_init();
}
示例#20
0
int
main(int argc, char **argv)
{
  int c;
  int forkaway = 0;
  FILE *pidfile;
  const char *pidpath = "/var/run/tvheadend.pid";
  struct group *grp;
  struct passwd *pw;
  char *webroot;
  const char *usernam = NULL;
  const char *groupnam = NULL;
  int logfacility = LOG_DAEMON;
  int createdefault = 0;
  sigset_t set;
  const char *homedir;
  const char *rawts_input = NULL;
#if ENABLE_LINUXDVB
  const char *dvb_rawts_input = NULL;
#endif
  const char *join_transport = NULL;
  const char *confpath = NULL;
  char *p, *endp;
  uint32_t adapter_mask = 0xffffffff;
  int crash = 0;
  webui_port = 9981;
  htsp_port = 9982;
  gid_t gid;
  uid_t uid;

  /* Get current directory */
  tvheadend_cwd = dirname(dirname(tvh_strdupa(argv[0])));

  /* Set locale */
  setlocale(LC_ALL, "");

  // make sure the timezone is set
  tzset();

  while((c = getopt(argc, argv, "Aa:fp:u:g:c:Chdr:j:sw:e:E:R:W:")) != -1) {
    switch(c) {
    case 'a':
      adapter_mask = 0x0;
      p = strtok(optarg, ",");
      if (p != NULL) {
        do {
          int adapter = strtol(p, &endp, 10);
          if (*endp != 0 || adapter < 0 || adapter > 31) {
              fprintf(stderr, "Invalid adapter number '%s'\n", p);
              return 1;
          }
          adapter_mask |= (1 << adapter);
        } while ((p = strtok(NULL, ",")) != NULL);
        if (adapter_mask == 0x0) {
          fprintf(stderr, "No adapters specified!\n");
          return 1;
        }
      } else {
        usage(argv[0]);
      }
      break;
    case 'A':
      crash = 1;
      break;
    case 'f':
      forkaway = 1;
      break;
    case 'p':
      pidpath = optarg;
      break;
    case 'w':
      webui_port = atoi(optarg);
      break;
    case 'e':
      htsp_port = atoi(optarg);
      break;
    case 'E':
      htsp_port_extra = atoi(optarg);
      break;
    case 'u':
      usernam = optarg;
      break;
    case 'g':
      groupnam = optarg;
      break;
    case 'c':
      confpath = optarg;
      break;
    case 'd':
      log_debug_to_console = 1;
      break;
    case 's':
      log_debug_to_syslog = 1;
      break;
    case 'C':
      createdefault = 1;
      break;
    case 'r':
      rawts_input = optarg;
      break;
#if ENABLE_LINUXDVB
    case 'R':
      dvb_rawts_input = optarg;
      break;
#endif
    case 'j':
      join_transport = optarg;
      break;
    case 'W':
      webroot = malloc(strlen(optarg) + (*optarg == '/' ? 0 : 1));
      if (*optarg != '/') {
        *webroot = '/';
        strcpy(webroot+1, optarg);
      } else {
        strcpy(webroot, optarg);
      }
      if (webroot[strlen(webroot)-1] == '/')
        webroot[strlen(webroot)-1] = '\0';
      tvheadend_webroot = webroot;
      break;
    default:
      usage(argv[0]);
    }
  }

  signal(SIGPIPE, handle_sigpipe);

  log_stderr   = 1;
  log_decorate = isatty(2);

  if(forkaway) {
    grp  = getgrnam(groupnam ?: "video");
    pw   = usernam ? getpwnam(usernam) : NULL;

    pidfile = fopen(pidpath, "w+");

    if(grp != NULL) {
      gid = grp->gr_gid;
    } else {
      gid = 1;
    }

    if (pw != NULL) {
      if (getuid() != pw->pw_uid) {
        gid_t glist[10];
        int gnum;
        gnum = get_user_groups(pw, glist, 10);
        if (setgroups(gnum, glist)) {
          tvhlog(LOG_ALERT, "START", "setgroups() failed, do you have permission?");
          return 1;
        }
      }
      uid     = pw->pw_uid;
      homedir = pw->pw_dir;
      setenv("HOME", homedir, 1);
    } else {
      uid = 1;
    }
    if ((getgid() != gid) && setgid(gid)) {
      tvhlog(LOG_ALERT, "START", "setgid() failed, do you have permission?");
      return 1;
    }
    if ((getuid() != uid) && setuid(uid)) {
      tvhlog(LOG_ALERT, "START", "setuid() failed, do you have permission?");
      return 1;
    }

    if(daemon(0, 0)) {
      exit(2);
    }
    if(pidfile != NULL) {
      fprintf(pidfile, "%d\n", getpid());
      fclose(pidfile);
    }

    umask(0);
  }

  log_stderr = !forkaway;
  log_decorate = isatty(2);

  sigfillset(&set);
  sigprocmask(SIG_BLOCK, &set, NULL);

  openlog("tvheadend", LOG_PID, logfacility);

  hts_settings_init(confpath);

  pthread_mutex_init(&ffmpeg_lock, NULL);
  pthread_mutex_init(&fork_lock, NULL);
  pthread_mutex_init(&global_lock, NULL);

  pthread_mutex_lock(&global_lock);

  time(&dispatch_clock);

  trap_init(argv[0]);
  
  /**
   * Initialize subsystems
   */

  config_init();

  imagecache_init();

  service_init();

  channels_init();

  subscription_init();

  access_init(createdefault);

#if ENABLE_LINUXDVB
  muxes_init();
  dvb_init(adapter_mask, dvb_rawts_input);
#endif

  iptv_input_init();

#if ENABLE_V4L
  v4l_init();
#endif

  tcp_server_init();
  http_server_init();
  webui_init();

  serviceprobe_init();

#if ENABLE_CWC
  cwc_init();
  capmt_init();
#if (!ENABLE_DVBCSA)
  ffdecsa_init();
#endif
#endif

  epggrab_init();
  epg_init();

  dvr_init();

  htsp_init();

  if(rawts_input != NULL)
    rawts_init(rawts_input);

  if(join_transport != NULL)
    subscription_dummy_join(join_transport, 1);

#ifdef CONFIG_AVAHI
  avahi_init();
#endif

  epg_updated(); // cleanup now all prev ref's should have been created

  pthread_mutex_unlock(&global_lock);


  /**
   * Wait for SIGTERM / SIGINT, but only in this thread
   */

  running = 1;
  sigemptyset(&set);
  sigaddset(&set, SIGTERM);
  sigaddset(&set, SIGINT);

  signal(SIGTERM, doexit);
  signal(SIGINT, doexit);

  pthread_sigmask(SIG_UNBLOCK, &set, NULL);

  tvhlog(LOG_NOTICE, "START", "HTS Tvheadend version %s started, "
	 "running as PID:%d UID:%d GID:%d, settings located in '%s'",
	 tvheadend_version,
	 getpid(), getuid(), getgid(), hts_settings_get_root());

  if(crash)
    abort();

  mainloop();

  epg_save();

  tvhlog(LOG_NOTICE, "STOP", "Exiting HTS Tvheadend");

  if(forkaway)
    unlink("/var/run/tvheadend.pid");

  return 0;

}
示例#21
0
int main (int argc, char **argv)
{
	int c;
	int start_event = 0;
	bool foreground = false;

	while (1) {
		c = getopt_long(argc, argv, "fhbgv", long_opts, NULL);
		if (c == EOF)
			break;
		switch (c) {
			case 'b':
				start_event |= START_BOOT;
				break;
			case 'f':
				foreground = true;
				break;
			case 'g':
				start_event |= START_GET_RPC_METHOD;
				break;
			case 'h':
				print_help();
				exit(EXIT_SUCCESS);
			case 'v':
				print_version();
				exit(EXIT_SUCCESS);
			default:
				print_help();
				exit(EXIT_FAILURE);
		}
	}

	log_message(NAME, L_DEBUG, "daemon started\n");

	setlocale(LC_CTYPE, "");
	umask(0037);

	if (getuid() != 0) {
		D("run %s as root\n", NAME);
		exit(EXIT_FAILURE);
	}

	/* run early cwmp initialization */
	cwmp = calloc(1, sizeof(struct cwmp_internal));
	if (!cwmp) return -1;

	INIT_LIST_HEAD(&cwmp->events);
	INIT_LIST_HEAD(&cwmp->notifications);
	INIT_LIST_HEAD(&cwmp->downloads);
	INIT_LIST_HEAD(&cwmp->scheduled_informs);
	uloop_init();
	backup_init();
	config_load();
	cwmp_init_deviceid();
	if (start_event & START_BOOT) {
		cwmp_add_event(EVENT_BOOT, NULL, 0, EVENT_BACKUP);
		cwmp_add_inform_timer();
	}
	if (start_event & START_GET_RPC_METHOD) {
		cwmp->get_rpc_methods = true;
		cwmp_add_event(EVENT_PERIODIC, NULL, 0, EVENT_BACKUP);
		cwmp_add_inform_timer();
	}

	if (netlink_init()) {
		D("netlink initialization failed\n");
		exit(EXIT_FAILURE);
	}

	if (ubus_init()) D("ubus initialization failed\n");

	http_server_init();

	pid_t pid, sid;
	if (!foreground) {
		pid = fork();
		if (pid < 0)
			exit(EXIT_FAILURE);
		if (pid > 0)
			exit(EXIT_SUCCESS);

		sid = setsid();
		if (sid < 0) {
			D("setsid() returned error\n");
			exit(EXIT_FAILURE);
		}

		char *directory = "/";

		if ((chdir(directory)) < 0) {
			D("chdir() returned error\n");
			exit(EXIT_FAILURE);
		}
	}

	log_message(NAME, L_DEBUG, "entering main loop\n");
	uloop_run();

	ubus_exit();
	uloop_done();

	http_client_exit();
	xml_exit();
	config_exit();
	cwmp_free_deviceid();
	free(cwmp);

	closelog();

	log_message(NAME, L_DEBUG, "exiting\n");
	return 0;
}
示例#22
0
struct wps_er *
wps_er_init(struct wps_context *wps, const char *ifname, const char *filter)
{
	struct wps_er *er;
	struct in_addr addr;

	er = os_zalloc(sizeof(*er));
	if (er == NULL)
		return NULL;
	dl_list_init(&er->ap);
	dl_list_init(&er->ap_unsubscribing);
	dl_list_init(&er->ap_settings);

	er->multicast_sd = -1;
	er->ssdp_sd = -1;

	os_strlcpy(er->ifname, ifname, sizeof(er->ifname));
	er->wps = wps;
	if (os_get_random((unsigned char *) &er->event_id,
			  sizeof(er->event_id)) < 0) {
		wps_er_deinit(er, NULL, NULL);
		return NULL;
	}
	/* Limit event_id to < 32 bits to avoid issues with atoi() */
	er->event_id &= 0x0fffffff;

	if (filter) {
		if (inet_aton(filter, &er->filter_addr) == 0) {
			wpa_printf(MSG_INFO, "WPS UPnP: Invalid filter "
				   "address %s", filter);
			wps_er_deinit(er, NULL, NULL);
			return NULL;
		}
		wpa_printf(MSG_DEBUG, "WPS UPnP: Only accepting connections "
			   "with %s", filter);
	}
	if (get_netif_info(ifname, &er->ip_addr, &er->ip_addr_text,
			   er->mac_addr)) {
		wpa_printf(MSG_INFO, "WPS UPnP: Could not get IP/MAC address "
			   "for %s. Does it have IP address?", ifname);
		wps_er_deinit(er, NULL, NULL);
		return NULL;
	}

	if (wps_er_ssdp_init(er) < 0) {
		wpa_printf(MSG_INFO, "WPS UPnP: SSDP initialization failed");
		wps_er_deinit(er, NULL, NULL);
		return NULL;
	}

	addr.s_addr = er->ip_addr;
	er->http_srv = http_server_init(&addr, -1, wps_er_http_req, er);
	if (er->http_srv == NULL) {
		wpa_printf(MSG_INFO, "WPS UPnP: HTTP initialization failed");
		wps_er_deinit(er, NULL, NULL);
		return NULL;
	}
	er->http_port = http_server_get_port(er->http_srv);

	wpa_printf(MSG_DEBUG, "WPS ER: Start (ifname=%s ip_addr=%s)",
		   er->ifname, er->ip_addr_text);

	return er;
}
示例#23
0
int hs20_web_browser(const char *url)
{
	struct http_server *http;
	struct in_addr addr;
	struct browser_data data;
	pid_t pid;

	wpa_printf(MSG_INFO, "Launching wpadebug browser to %s", url);

	os_memset(&data, 0, sizeof(data));

	if (eloop_init() < 0) {
		wpa_printf(MSG_ERROR, "eloop_init failed");
		return -1;
	}
	addr.s_addr = htonl((127 << 24) | 1);
	http = http_server_init(&addr, 12345, http_req, &data);
	if (http == NULL) {
		wpa_printf(MSG_ERROR, "http_server_init failed");
		eloop_destroy();
		return -1;
	}

	pid = fork();
	if (pid < 0) {
		wpa_printf(MSG_ERROR, "fork: %s", strerror(errno));
		http_server_deinit(http);
		eloop_destroy();
		return -1;
	}

	if (pid == 0) {
		/* run the external command in the child process */
		char *argv[14];

		argv[0] = "browser-wpadebug";
		argv[1] = "start";
		argv[2] = "-a";
		argv[3] = "android.action.MAIN";
		argv[4] = "-c";
		argv[5] = "android.intent.category.LAUNCHER";
		argv[6] = "-n";
		argv[7] = "w1.fi.wpadebug/.WpaWebViewActivity";
		argv[8] = "-e";
		argv[9] = "w1.fi.wpadebug.URL";
		argv[10] = (void *) url;
		argv[11] = "--user";
		argv[12] = "-3"; /* USER_CURRENT_OR_SELF */
		argv[13] = NULL;

		execv("/system/bin/am", argv);
		wpa_printf(MSG_ERROR, "execv: %s", strerror(errno));
		exit(0);
		return -1;
	}

	eloop_register_timeout(300, 0, browser_timeout, &data, NULL);
	eloop_run();
	eloop_cancel_timeout(browser_timeout, &data, NULL);
	http_server_deinit(http);
	eloop_destroy();

	wpa_printf(MSG_INFO, "Closing Android browser");
	if (os_exec("/system/bin/am",
		    "start -a android.action.MAIN "
		    "-c android.intent.category.LAUNCHER "
		    "-n w1.fi.wpadebug/.WpaWebViewActivity "
		    "-e w1.fi.wpadebug.URL FINISH", 1) != 0) {
		wpa_printf(MSG_INFO, "Failed to close wpadebug browser");
	}

	return data.success;
}
示例#24
0
/**
 * Showtime main
 */
int
main(int argc, char **argv)
{
    struct timeval tv;
    const char *settingspath = NULL;
    const char *uiargs[16];
    const char *argv0 = argc > 0 ? argv[0] : "showtime";
    const char *forceview = NULL;
    int nuiargs = 0;
    int can_standby = 0;
    int can_poweroff = 0;
    int r;

    trace_level = TRACE_INFO;

    gettimeofday(&tv, NULL);
    srand(tv.tv_usec);

    arch_set_default_paths(argc, argv);

    /* We read options ourselfs since getopt() is broken on some (nintento wii)
       targets */

    argv++;
    argc--;

    while(argc > 0) {
        if(!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) {
            printf("HTS Showtime %s\n"
                   "Copyright (C) 2007-2010 Andreas Öman\n"
                   "\n"
                   "Usage: %s [options] [<url>]\n"
                   "\n"
                   "  Options:\n"
                   "   -h, --help        - This help text.\n"
                   "   -d                - Enable debug output.\n"
                   "   --ffmpeglog       - Print ffmpeg log messages.\n"
                   "   --with-standby    - Enable system standby.\n"
                   "   --with-poweroff   - Enable system power-off.\n"
                   "   -s <path>         - Non-default Showtime settings path.\n"
                   "   --ui <ui>         - Use specified user interface.\n"
                   "   -L <ip:host>      - Send log messages to remote <ip:host>.\n"
                   "   --syslog          - Send log messages to syslog.\n"
#if ENABLE_STDIN
                   "   --stdin           - Listen on stdin for events.\n"
#endif
                   "   -v <view>         - Use specific view for <url>.\n"
                   "   --cache <path>    - Set path for cache [%s].\n"
#if ENABLE_SERDEV
                   "   --serdev          - Probe service ports for devices.\n"
#endif
                   "\n"
                   "  URL is any URL-type supported by Showtime, "
                   "e.g., \"file:///...\"\n"
                   "\n",
                   htsversion_full,
                   argv0,
                   showtime_cache_path);
            exit(0);
            argc--;
            argv++;

        } else if(!strcmp(argv[0], "-d")) {
            trace_level++;
            argc -= 1;
            argv += 1;
            continue;
        } else if(!strcmp(argv[0], "--ffmpeglog")) {
            ffmpeglog = 1;
            argc -= 1;
            argv += 1;
            continue;
        } else if(!strcmp(argv[0], "--syslog")) {
            trace_to_syslog = 1;
            argc -= 1;
            argv += 1;
            continue;
        } else if(!strcmp(argv[0], "--stdin")) {
            listen_on_stdin = 1;
            argc -= 1;
            argv += 1;
            continue;
#if ENABLE_SERDEV
        } else if(!strcmp(argv[0], "--serdev")) {
            enable_serdev = 1;
            argc -= 1;
            argv += 1;
            continue;
#endif
        } else if(!strcmp(argv[0], "--with-standby")) {
            can_standby = 1;
            argc -= 1;
            argv += 1;
            continue;
        } else if(!strcmp(argv[0], "--with-poweroff")) {
            can_poweroff = 1;
            argc -= 1;
            argv += 1;
            continue;
        } else if(!strcmp(argv[0], "-s") && argc > 1) {
            settingspath = argv[1];
            argc -= 2;
            argv += 2;
            continue;
        } else if(!strcmp(argv[0], "--ui") && argc > 1) {
            if(nuiargs < 16)
                uiargs[nuiargs++] = argv[1];
            argc -= 2;
            argv += 2;
            continue;
        } else if(!strcmp(argv[0], "-L") && argc > 1) {
            showtime_logtarget = argv[1];
            argc -= 2;
            argv += 2;
            continue;
        } else if (!strcmp(argv[0], "-v") && argc > 1) {
            forceview = argv[1];
            argc -= 2;
            argv += 2;
        } else if (!strcmp(argv[0], "--cache") && argc > 1) {
            mystrset(&showtime_cache_path, argv[1]);
            argc -= 2;
            argv += 2;
#ifdef __APPLE__
            /* ignore -psn argument, process serial number */
        } else if(!strncmp(argv[0], "-psn", 4)) {
            argc -= 1;
            argv += 1;
            continue;
#endif
        } else
            break;
    }


    unicode_init();

    /* Initialize property tree */
    prop_init();
    init_global_info();

    /* Initiailize logging */
    trace_init();

    /* Callout framework */
    callout_init();

    /* Notification framework */
    notifications_init();

    /* Architecture specific init */
    arch_init();

    htsmsg_store_init();

    /* Try to create cache path */
    if(showtime_cache_path != NULL &&
            (r = makedirs(showtime_cache_path)) != 0) {
        TRACE(TRACE_ERROR, "cache", "Unable to create cache path %s -- %s",
              showtime_cache_path, strerror(r));
        showtime_cache_path = NULL;
    }

    /* Initializte blob cache */
    blobcache_init();

    /* Try to create settings path */
    if(showtime_settings_path != NULL &&
            (r = makedirs(showtime_settings_path)) != 0) {
        TRACE(TRACE_ERROR, "settings", "Unable to create settings path %s -- %s",
              showtime_settings_path, strerror(r));
        showtime_settings_path = NULL;
    }

    /* Initialize keyring */
    keyring_init();

    /* Initialize settings */
    settings_init();

    /* Initialize libavcodec & libavformat */
    av_lockmgr_register(fflockmgr);
    av_log_set_callback(fflog);
    av_register_all();

    /* Freetype keymapper */
#if ENABLE_LIBFREETYPE
    freetype_init();
#endif

    /* Global keymapper */
    keymapper_init();

    /* Initialize media subsystem */
    media_init();

    /* Service handling */
    service_init();

    /* Initialize backend content handlers */
    backend_init();

    /* Initialize navigator */
    nav_init();

    /* Initialize audio subsystem */
    audio_init();

    /* Initialize bookmarks */
    bookmarks_init();

    /* Initialize plugin manager and load plugins */
    plugins_init();

    /* Internationalization */
    i18n_init();


    nav_open(NAV_HOME, NULL);

    /* Open initial page */
    if(argc > 0)
        nav_open(argv[0], forceview);

    /* Various interprocess communication stuff (D-Bus on Linux, etc) */
    ipc_init();

    /* Service discovery. Must be after ipc_init() (d-bus and threads, etc) */
    sd_init();

    /* Initialize various external APIs */
    api_init();

    /* HTTP server and UPNP */
#if ENABLE_HTTPSERVER
    http_server_init();
    upnp_init();
#endif


    /* */
    runcontrol_init(can_standby, can_poweroff);

    TRACE(TRACE_DEBUG, "core", "Starting UI");

    /* Initialize user interfaces */
    ui_start(nuiargs, uiargs, argv0);

    finalize();
}
示例#25
0
文件: poc-http.c 项目: hongbinz/poc
/*M
  \emph{HTTP server main routine.}
**/
int main(int argc, char *argv[]) {
   int            retval = 0;
   
   char *address = NULL;
   unsigned short port = 8000;
   int quiet = 0;
   int max_clients = 0;
   http_server_t server;

   http_server_reset(&server);
   
   if (argc <= 1) {
      usage();
      return 1;
   }

   int c;
   while ((c = getopt(argc, argv, "hs:p:qc:"
#ifdef WITH_IPV6
     "6"
#endif /* WITH_IPV6 */
     )) >= 0) {     
     switch (c) {
#ifdef WITH_IPV6
     case '6':
       use_ipv6 = 1;
       break;
#endif /* WITH_IPV6 */
       
     case 's':
       if (address != NULL)
         free(address);

       address = strdup(optarg);
       break;

     case 'p':
       port = (unsigned short)atoi(optarg);
       break;

     case 'c':
       max_clients = (unsigned short)atoi(optarg);
       break;

     case 'q':
       quiet = 1;
       break;

     case 'h':
     default:
       usage();
       retval = EXIT_FAILURE;
       goto exit;
     }
   }

   if (optind == argc) {
     usage();
     retval = EXIT_FAILURE;
     goto exit;
   }

   if (address == NULL) {
#ifdef WITH_IPV6
     if (use_ipv6)
       address = strdup("0::0");
     else
       address = strdup("0");
#else
     address = strdup("0");
#endif /* WITH_IPV6 */
   }

   /*M
     Open the listening socket.
   **/
   int sock = -1;
#ifdef WITH_IPV6
   if (use_ipv6)
     sock = net_tcp6_listen_socket(address, port);
   else
     sock = net_tcp4_listen_socket(address, port);
#else
   sock  = net_tcp4_listen_socket(address, port);
#endif /* WITH_IPV6 */

   if (sock < 0) {
     perror("Could not create socket");
     retval = EXIT_FAILURE;
     goto exit;
   }

   if (!http_server_init(&server, HTTP_MIN_CLIENTS,
                         max_clients, NULL, sock)) {
     fprintf(stderr, "Could not initialise HTTP server\n");
     retval = EXIT_FAILURE;
     goto exit;
   }

   if (sig_set_handler(SIGINT, sig_int) == SIG_ERR) {
     retval = EXIT_FAILURE;
     goto exit;
   }
   
   /*M
     Read in mp3 files one after the other.
   **/
   int i;
   for (i=optind; (i<argc) && !finished; i++) {
     assert(argv[i] != NULL);
     char filename[MAX_FILENAME];
     strncpy(filename, argv[i], MAX_FILENAME - 1);
     filename[MAX_FILENAME - 1] = '\0';

     if (!poc_mainloop(&server, filename, quiet))
       continue;
   }

exit:
   http_server_close(&server);

   return retval;
}