Example #1
0
/* 
 * UPnP portable main loop.
 * It initializes the UPnP protocol and event variables.
 * And loop handler the UPnP incoming requests.
 */
void
upnp_mainloop()
{
	UPNP_CONTEXT *context = &upnp_context;

	/* initialize upnp */
	upnp_init(context);

	/* main loop */
	while (1) {
		switch (upnp_flag) {
		case UPNP_FLAG_SHUTDOWN:
			upnp_shutdown(context);

			upnp_syslog(LOG_INFO, "UPnP shutdown!");
			return;

		case UPNP_FLAG_RESTART:
			upnp_shutdown(context);
			upnp_init(context);

			upnp_syslog(LOG_INFO, "UPnP restart!");
			break;

		case 0:
		default:
			upnp_dispatch(context);
			break;
		}
	}

	return;
}
Example #2
0
int
dlna_dms_init (dlna_t *dlna)
{
  if (!dlna)
    return DLNA_ST_ERROR;

  if (!dlna->inited)
    return DLNA_ST_ERROR;

  dlna_service_register (dlna, &cms_service);
  dlna_service_register (dlna, &cds_service);
  dlna_service_register (dlna, &avts_service);
  if (dlna->mode == DLNA_CAPABILITY_UPNP_AV_XBOX)
    dlna_service_register (dlna, &msr_service);
  
  return upnp_init (dlna, DLNA_DEVICE_DMS);
}
Example #3
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();
}
Example #4
0
static void
xchat_init (void)
{
	char buf[3068];
	const char *cs = NULL;

#ifdef USE_SIGACTION
	struct sigaction act;

	/* ignore SIGPIPE's */
	act.sa_handler = SIG_IGN;
	act.sa_flags = 0;
	sigemptyset (&act.sa_mask);
	sigaction (SIGPIPE, &act, NULL);

	/* Deal with SIGUSR1's & SIGUSR2's */
	act.sa_sigaction = sigusr1_handler;
	act.sa_flags = 0;
	sigemptyset (&act.sa_mask);
	sigaction (SIGUSR1, &act, NULL);

	act.sa_sigaction = sigusr2_handler;
	act.sa_flags = 0;
	sigemptyset (&act.sa_mask);
	sigaction (SIGUSR2, &act, NULL);
#else
	/* good enough for these old systems */
	signal (SIGPIPE, SIG_IGN);
#endif

	if (g_get_charset (&cs))
		prefs.utf8_locale = TRUE;

	command_init ();
	load_text_events ();
	notify_load ();
	ignore_load ();
	signal_printer_init();
	proto_irc_init();
	upnp_init();
	sasl_init();

	snprintf (buf, sizeof (buf),
		"NAME %s\n"                         "CMD query %%s\n\n"\
		"NAME %s\n"                         "CMD send %%s\n\n"\
		"NAME %s\n"                         "CMD whois %%s %%s\n\n"\
		"NAME SUB\n"                        "CMD %s\n\n"\
			"NAME %s\n"                     "CMD op %%a\n\n"\
			"NAME %s\n"                     "CMD deop %%a\n\n"\
			"NAME SEP\n"                    "CMD \n\n"\
			"NAME %s\n"                     "CMD voice %%a\n\n"\
			"NAME %s\n"                     "CMD devoice %%a\n"\
			"NAME SEP\n"                    "CMD \n\n"\
			"NAME SUB\n"                    "CMD %s\n\n"\
				"NAME %s\n"                 "CMD kick %%s\n\n"\
				"NAME %s\n"                 "CMD ban %%s\n\n"\
				"NAME SEP\n"                "CMD \n\n"\
				"NAME %s *!*@*.host\n"      "CMD ban %%s 0\n\n"\
				"NAME %s *!*@domain\n"      "CMD ban %%s 1\n\n"\
				"NAME %s *!*user@*.host\n"  "CMD ban %%s 2\n\n"\
				"NAME %s *!*user@domain\n"  "CMD ban %%s 3\n\n"\
				"NAME SEP\n"                "CMD \n\n"\
				"NAME %s *!*@*.host\n"      "CMD kickban %%s 0\n\n"\
				"NAME %s *!*@domain\n"      "CMD kickban %%s 1\n\n"\
				"NAME %s *!*user@*.host\n"  "CMD kickban %%s 2\n\n"\
				"NAME %s *!*user@domain\n"  "CMD kickban %%s 3\n\n"\
			"NAME ENDSUB\n"                 "CMD \n\n"\
		"NAME ENDSUB\n"                     "CMD \n\n",

		_("Open Query"),
		_("Send a File"),
		_("User Info (WHOIS)"),
		_("Operator Actions"),

		_("Give Ops"),
		_("Take Ops"),
		_("Give Voice"),
		_("Take Voice"),

		_("Kick/Ban"),
		_("Kick"),
		_("Ban"),
		_("Ban"),
		_("Ban"),
		_("Ban"),
		_("Ban"),
		_("KickBan"),
		_("KickBan"),
		_("KickBan"),
		_("KickBan"));

	list_loadconf ("popup.conf", &popup_list, buf);

	snprintf (buf, sizeof (buf),
		"NAME %s\n"           "CMD part\n\n"
		"NAME %s\n"           "CMD getstr # join \"%s\"\n\n"
		"NAME %s\n"           "CMD quote LINKS\n\n"
		"NAME %s\n"           "CMD ping\n\n"
		"NAME TOGGLE %s\n"    "CMD irc_hide_version\n\n",
				_("Leave Channel"),
				_("Join Channel..."),
				_("Enter Channel to Join:"),
				_("Server Links"),
				_("Ping Server"),
				_("Hide Version"));
	list_loadconf ("usermenu.conf", &usermenu_list, buf);

	snprintf (buf, sizeof (buf),
		"NAME %s\n"     "CMD op %%a\n\n"
		"NAME %s\n"     "CMD deop %%a\n\n"
		"NAME %s\n"     "CMD ban %%s\n\n"
		"NAME %s\n"     "CMD getstr \"%s\" \"kick %%s\" \"%s\"\n\n"
		"NAME %s\n"     "CMD send %%s\n\n"
		"NAME %s\n"     "CMD query %%s\n\n",
				_("Op"),
				_("DeOp"),
				_("Ban"),
				_("Kick"),
				_("bye"),
				_("Enter reason to kick %s:"),
				_("Sendfile"),
				_("Query"));
	list_loadconf ("buttons.conf", &button_list, buf);

	snprintf (buf, sizeof (buf),
		"NAME %s\n"     "CMD whois %%s %%s\n\n"
		"NAME %s\n"     "CMD send %%s\n\n"
		"NAME %s\n"     "CMD dcc chat %%s\n\n"
		"NAME %s\n"     "CMD clear\n\n"
		"NAME %s\n"     "CMD ping %%s\n\n",
				_("WhoIs"),
				_("Send"),
				_("Chat"),
				_("Clear"),
				_("Ping"));
	list_loadconf ("dlgbuttons.conf", &dlgbutton_list, buf);

	list_loadconf ("tabmenu.conf", &tabmenu_list, NULL);
	list_loadconf ("ctcpreply.conf", &ctcp_list, defaultconf_ctcp);
	list_loadconf ("commands.conf", &command_list, defaultconf_commands);
	list_loadconf ("replace.conf", &replace_list, defaultconf_replace);
#ifdef REGEX_SUBSTITUTION
	regex_list_loadconf("regex_replace.conf", &regex_replace_list, defaultconf_regex_replace);
#endif
	list_loadconf ("urlhandlers.conf", &urlhandler_list,
						defaultconf_urlhandlers);

	servlist_init ();							/* load server list */

	main_sess = new_ircwindow_fake (NULL, _(DISPLAY_NAME), SESS_SERVER, 0);
    main_sess->immutable = TRUE;

	/* turned OFF via -a arg */
	if (!arg_dont_autoconnect && servlist_have_auto())
		g_idle_add ((GSourceFunc) servlist_auto_connect, NULL);

	/* if we got a URL, don't open the server list GUI */
	if (!prefs.skip_serverlist && !servlist_have_auto() && !arg_url)
		fe_serverlist_open (NULL);
}
Example #5
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();
}
Example #6
0
/**
 * Kick off the daap server and wait for events.
 *
 * This starts the initial db scan, sets up the signal
 * handling, starts the webserver, then sits back and waits
 * for events, as notified by the signal handler and the
 * web interface.  These events are communicated via flags
 * in the config structure.
 *
 * \param argc count of command line arguments
 * \param argv command line argument pointers
 * \returns 0 on success, -1 otherwise
 *
 * \todo split out a ws_init and ws_start, so that the
 * web space handlers can be registered before the webserver
 * starts.
 *
 */
int main(int argc, char *argv[]) {
    int option;
    char *configfile=CONFFILE;
    WSCONFIG ws_config;
    int reload=0;
    int start_time;
    int end_time;
    int rescan_counter=0;
    int old_song_count, song_count;
    int force_non_root=0;
    int skip_initial=1;
    int kill_server=0;
    int convert_conf=0;
    char *db_type,*db_parms,*web_root,*runas, *tmp;
    char **mp3_dir_array;
    char *servername, *iface;
    char *ffid = NULL;
    int appdir = 0;
    char *perr=NULL;
    char txtrecord[255];
    void *phandle;
    char *plugindir;

    int err;
    char *apppath;

    int debuglevel=0;
    int plugins_loaded = 0;

#ifdef ALPHA_CUSTOMIZE
    char *share_path;
    pthread_t thread1;
#endif

    config.use_mdns=1;
    err_setlevel(2);

    config.foreground=0;
    while((option=getopt(argc,argv,"D:d:c:P:mfrysiuvab:Vk")) != -1) {
        switch(option) {
        case 'a':
            appdir = 1;
            break;

        case 'b':
            ffid=optarg;
            break;

        case 'd':
            debuglevel = atoi(optarg);
            err_setlevel(debuglevel);
            break;

        case 'D':
            if(err_setdebugmask(optarg)) {
                usage(argv[0]);
                exit(EXIT_FAILURE);
            }
            break;

        case 'f':
            config.foreground=1;
            err_setdest(err_getdest() | LOGDEST_STDERR);
            break;

        case 'c':
            configfile=optarg;
            break;

        case 'm':
            config.use_mdns=0;
            break;

#ifndef WIN32
        case 'P':
            os_set_pidfile(optarg);
            break;
#endif
        case 'r':
            reload=1;
            break;

        case 's':
            skip_initial=0;
            break;

        case 'y':
            force_non_root=1;
            break;

#ifdef WIN32
        case 'i':
            os_register();
            exit(EXIT_SUCCESS);
            break;

        case 'u':
            os_unregister();
            exit(EXIT_SUCCESS);
            break;
#endif
        case 'v':
            convert_conf=1;
            break;

        case 'k':
            kill_server=1;
            break;

        case 'V':
            fprintf(stderr,"Firefly Media Server: Version %s\n",VERSION);
            exit(EXIT_SUCCESS);
            break;

        default:
            usage(argv[0]);
            exit(EXIT_FAILURE);
            break;
        }
    }

    if((getuid()) && (!force_non_root) && (!convert_conf)) {
        fprintf(stderr,"You are not root.  This is almost certainly wrong.  "
                "If you are\nsure you want to do this, use the -y "
                "command-line switch\n");
        exit(EXIT_FAILURE);
    }


    if(kill_server) {
        os_signal_server(S_STOP);
        exit(0);
    }

    io_init();
    io_set_errhandler(main_io_errhandler);
    ws_set_errhandler(main_ws_errhandler);

    /* read the configfile, if specified, otherwise
     * try defaults */
    config.stats.start_time=start_time=(int)time(NULL);
    config.stop=0;

    /* set appdir first, that way config resolves relative to appdir */
    if(appdir) {
        apppath = os_apppath(argv[0]);
        DPRINTF(E_INF,L_MAIN,"Changing cwd to %s\n",apppath);
        chdir(apppath);
        free(apppath);
        configfile="mt-daapd.conf";
    }

    if(CONF_E_SUCCESS != conf_read(configfile)) {
        fprintf(stderr,"Error reading config file (%s)\n",configfile);
        exit(EXIT_FAILURE);
    }

    if(debuglevel) /* was specified, should override the config file */
        err_setlevel(debuglevel);

    if(convert_conf) {
        fprintf(stderr,"Converting config file...\n");
        if(CONF_E_SUCCESS != conf_write()) {
            fprintf(stderr,"Error writing config file.\n");
            exit(EXIT_FAILURE);
        }
        exit(EXIT_SUCCESS);
    }

    DPRINTF(E_LOG,L_MAIN,"Firefly Version %s: Starting with debuglevel %d\n",
            VERSION,err_getlevel());


    /* load plugins before we drop privs?  Maybe... let the
     * plugins do stuff they might need to */
    plugin_init();
    if((plugindir=conf_alloc_string("plugins","plugin_dir",NULL)) != NULL) {
        /* instead of specifying plugins, let's walk through the directory
         * and load each of them */
        if(!load_plugin_dir(plugindir)) {
            DPRINTF(E_LOG,L_MAIN,"Warning: Could not load plugins\n");
        } else {
            plugins_loaded = TRUE;
        }
        free(plugindir);
    }

    if(!plugins_loaded) {
        if((!load_plugin_dir("/usr/lib/firefly/plugins")) &&
           (!load_plugin_dir("/usr/lib/mt-daapd/plugins")) &&
           (!load_plugin_dir("/lib/mt-daapd/plugins")) &&
           (!load_plugin_dir("/lib/mt-daapd/plugins")) &&
           (!load_plugin_dir("/usr/local/lib/mt-daapd/plugins")) &&
           (!load_plugin_dir("/usr/local/lib/mt-daapd/plugins")) &&
           (!load_plugin_dir("/opt/share/firefly/plugins")) &&
           (!load_plugin_dir("/opt/share/mt-daapd/plugins")) &&
           (!load_plugin_dir("/opt/lib/firefly/plugins")) &&
           (!load_plugin_dir("/opt/lib/mt-daapd/plugins")) &&
           (!load_plugin_dir("plugins/.libs"))) {
            DPRINTF(E_FATAL,L_MAIN,"plugins/plugin_dir not specified\n");
        }
    }

    phandle=NULL;
    while((phandle=plugin_enum(phandle))) {
        DPRINTF(E_LOG,L_MAIN,"Plugin loaded: %s\n",plugin_get_description(phandle));
    }

    runas = conf_alloc_string("general","runas","nobody");

#ifndef WITHOUT_MDNS
    if(config.use_mdns) {
        DPRINTF(E_LOG,L_MAIN,"Starting rendezvous daemon\n");
        if(rend_init(runas)) {
            DPRINTF(E_FATAL,L_MAIN|L_REND,"Error in rend_init: %s\n",
                    strerror(errno));
        }
    }
#endif

    if(!os_init(config.foreground,runas)) {
        DPRINTF(E_LOG,L_MAIN,"Could not initialize server\n");
        os_deinit();
        exit(EXIT_FAILURE);
    }

    free(runas);

#ifdef UPNP
    upnp_init();
#endif

    /* this will require that the db be readable by the runas user */
    db_type = conf_alloc_string("general","db_type","sqlite");
    db_parms = conf_alloc_string("general","db_parms","/var/cache/mt-daapd");
    err=db_open(&perr,db_type,db_parms);

    if(err) {
        DPRINTF(E_LOG,L_MAIN|L_DB,"Error opening db: %s\n",perr);
#ifndef WITHOUT_MDNS
        if(config.use_mdns) {
            rend_stop();
        }
#endif
        os_deinit();
        exit(EXIT_FAILURE);
    }

    free(db_type);
    free(db_parms);

    /* Initialize the database before starting */
    DPRINTF(E_LOG,L_MAIN|L_DB,"Initializing database\n");
    if(db_init(reload)) {
        DPRINTF(E_FATAL,L_MAIN|L_DB,"Error in db_init: %s\n",strerror(errno));
    }

    err=db_get_song_count(&perr,&song_count);
    if(err != DB_E_SUCCESS) {
        DPRINTF(E_FATAL,L_MISC,"Error getting song count: %s\n",perr);
    }
    /* do a full reload if the db is empty */
    if(!song_count)
        reload = 1;

    if(conf_get_array("general","mp3_dir",&mp3_dir_array)) {
        if((!skip_initial) || (reload)) {
            DPRINTF(E_LOG,L_MAIN|L_SCAN,"Starting mp3 scan\n");
	#ifdef ALPHA_CUSTOMIZE
	    share_path = conf_alloc_string("general", "mp3_dir", "AAA");
		printf("mp3_dir_array[0] = [%s]\n", mp3_dir_array[0]);
	    if (strlen(share_path) > 0)
	    {
		Cnt_total_file(mp3_dir_array[0]);
		pthread_create( &thread1, NULL, (void*)process_bar, NULL);
		free(share_path);
	    }
	#endif
            plugin_event_dispatch(PLUGIN_EVENT_FULLSCAN_START,0,NULL,0);
            start_time=(int) time(NULL);
            if(scan_init(mp3_dir_array)) {
                DPRINTF(E_LOG,L_MAIN|L_SCAN,"Error scanning MP3 files: %s\n",strerror(errno));
            }
            if(!config.stop) { /* don't send popup when shutting down */
                plugin_event_dispatch(PLUGIN_EVENT_FULLSCAN_END,0,NULL,0);
                err=db_get_song_count(&perr,&song_count);
                end_time=(int) time(NULL);
                DPRINTF(E_LOG,L_MAIN|L_SCAN,"Scanned %d songs in %d seconds\n",
                        song_count,end_time - start_time);
            }
        }
        conf_dispose_array(mp3_dir_array);
    }
    
#ifdef ALPHA_CUSTOMIZE
    thread_exit = 1;
#endif

    /* start up the web server */
    web_root = conf_alloc_string("general","web_root",NULL);
    ws_config.web_root=web_root;
    ws_config.port=conf_get_int("general","port",0);

    DPRINTF(E_LOG,L_MAIN|L_WS,"Starting web server from %s on port %d\n",
            ws_config.web_root, ws_config.port);

    config.server=ws_init(&ws_config);
    if(!config.server) {
        /* pthreads or malloc error */
        DPRINTF(E_FATAL,L_MAIN|L_WS,"Error initializing web server\n");
    }

    if(E_WS_SUCCESS != ws_start(config.server)) {
        /* listen or pthread error */
        DPRINTF(E_FATAL,L_MAIN|L_WS,"Error starting web server\n");
    }

    ws_registerhandler(config.server, "/",main_handler,main_auth,
                       0,1);

#ifndef WITHOUT_MDNS
    if(config.use_mdns) { /* register services */
        servername = conf_get_servername();

        memset(txtrecord,0,sizeof(txtrecord));
        txt_add(txtrecord,"txtvers=1");
        txt_add(txtrecord,"Database ID=%0X",util_djb_hash_str(servername));
        txt_add(txtrecord,"Machine ID=%0X",util_djb_hash_str(servername));
        txt_add(txtrecord,"Machine Name=%s",servername);
        txt_add(txtrecord,"mtd-version=" VERSION);
        txt_add(txtrecord,"iTSh Version=131073"); /* iTunes 6.0.4 */
        txt_add(txtrecord,"Version=196610");      /* iTunes 6.0.4 */
        tmp = conf_alloc_string("general","password",NULL);
        if(tmp && (strlen(tmp)==0)) tmp=NULL;

        txt_add(txtrecord,"Password=%s",tmp ? "true" : "false");
        if(tmp) free(tmp);

        srand((unsigned int)time(NULL));

        if(ffid) {
            txt_add(txtrecord,"ffid=%s",ffid);
        } else {
            txt_add(txtrecord,"ffid=%08x",rand());
        }

        DPRINTF(E_LOG,L_MAIN|L_REND,"Registering rendezvous names\n");
        iface = conf_alloc_string("general","interface","");

        rend_register(servername,"_http._tcp",ws_config.port,iface,txtrecord);

        plugin_rend_register(servername,ws_config.port,iface,txtrecord);

        free(servername);
        free(iface);
    }
#endif

    end_time=(int) time(NULL);

    err=db_get_song_count(&perr,&song_count);
    if(err != DB_E_SUCCESS) {
        DPRINTF(E_FATAL,L_MISC,"Error getting song count: %s\n",perr);
    }

    DPRINTF(E_LOG,L_MAIN,"Serving %d songs.  Startup complete in %d seconds\n",
            song_count,end_time-start_time);

    if(conf_get_int("general","rescan_interval",0) && (!reload) &&
       (!conf_get_int("scanning","skip_first",0)))
        config.reload = 1; /* force a reload on start */

    while(!config.stop) {
        if((conf_get_int("general","rescan_interval",0) &&
            (rescan_counter > conf_get_int("general","rescan_interval",0)))) {
            if((conf_get_int("general","always_scan",0)) ||
                (config_get_session_count())) {
                config.reload=1;
            } else {
                DPRINTF(E_DBG,L_MAIN|L_SCAN|L_DB,"Skipped bground scan... no users\n");
            }
            rescan_counter=0;
        }

        if(config.reload) {
            old_song_count = song_count;
            start_time=(int) time(NULL);

            DPRINTF(E_LOG,L_MAIN|L_DB|L_SCAN,"Rescanning database\n");

            if(conf_get_array("general","mp3_dir",&mp3_dir_array)) {
                if(config.full_reload) {
                    config.full_reload=0;
                    db_force_rescan(NULL);
                }

                if(scan_init(mp3_dir_array)) {
                    DPRINTF(E_LOG,L_MAIN|L_DB|L_SCAN,"Error rescanning... bad path?\n");
                }

                conf_dispose_array(mp3_dir_array);
            }
            config.reload=0;
            db_get_song_count(NULL,&song_count);
            DPRINTF(E_LOG,L_MAIN|L_DB|L_SCAN,"Scanned %d songs (was %d) in "
                    "%d seconds\n",song_count,old_song_count,
                    time(NULL)-start_time);
        }

        os_wait(MAIN_SLEEP_INTERVAL);
        rescan_counter += MAIN_SLEEP_INTERVAL;
    }

    DPRINTF(E_LOG,L_MAIN,"Stopping gracefully\n");

#ifndef WITHOUT_MDNS
    if(config.use_mdns) {
        DPRINTF(E_LOG,L_MAIN|L_REND,"Stopping rendezvous daemon\n");
        rend_stop();
    }
#endif

#ifdef UPNP
    upnp_deinit();
#endif


    /* Got to find a cleaner way to stop the web server.
     * Closing the fd of the socking accepting doesn't necessarily
     * cause the accept to fail on some libcs.
     *
    DPRINTF(E_LOG,L_MAIN|L_WS,"Stopping web server\n");
    ws_stop(config.server);
    */
    free(web_root);
    conf_close();

    DPRINTF(E_LOG,L_MAIN|L_DB,"Closing database\n");
    db_deinit();

    DPRINTF(E_LOG,L_MAIN,"Done!\n");

    os_deinit();
    io_deinit();
    mem_dump();
    return EXIT_SUCCESS;
}