int main(int argc, char **argv) { int rc; int result = EXIT_FAILURE; struct device *upnp_renderer; if (!g_thread_supported()) { g_thread_init(NULL); } rc = process_cmdline(argc, argv); if (rc != 0) { goto out; } if (show_version) { do_show_version(); exit(EXIT_SUCCESS); } if (show_connmgr_scpd) { upnp_renderer_dump_connmgr_scpd(); exit(EXIT_SUCCESS); } if (show_control_scpd) { upnp_renderer_dump_control_scpd(); exit(EXIT_SUCCESS); } if (show_transport_scpd) { upnp_renderer_dump_transport_scpd(); exit(EXIT_SUCCESS); } upnp_renderer = upnp_renderer_new(friendly_name, uuid); if (upnp_renderer == NULL) { goto out; } if (show_devicedesc) { fputs(upnp_get_device_desc(upnp_renderer), stdout); exit(EXIT_SUCCESS); } rc = output_gstreamer_init(); if (rc != 0) { goto out; } rc = upnp_device_init(upnp_renderer, ip_address); if (rc != 0) { goto out; } printf("Ready for rendering..\n"); output_loop(); result = EXIT_SUCCESS; out: return result; }
int main(int argc, char **argv) { int rc; int result = EXIT_FAILURE; struct device *upnp_renderer; rc = process_cmdline(argc, argv); if (rc != 0) { goto out; } if (show_version) { do_show_version(); exit(EXIT_SUCCESS); } if (show_connmgr_scpd) { upnp_renderer_dump_connmgr_scpd(); exit(EXIT_SUCCESS); } if (show_control_scpd) { upnp_renderer_dump_control_scpd(); exit(EXIT_SUCCESS); } if (show_transport_scpd) { upnp_renderer_dump_transport_scpd(); exit(EXIT_SUCCESS); } if (show_outputs) { output_dump_modules(); exit(EXIT_SUCCESS); } if (pid_file && pid_file[0] != '/') { // We need to canonicalize the filename because our // cwd will change after becoming a daemon. char *buf = (char*) malloc(PATH_MAX); // will leak. Ok. char *result = getcwd(buf, PATH_MAX); result = strcat(result, "/"); pid_file = strcat(result, pid_file); } if (daemon_mode) { daemon(0, 0); // TODO: check for daemon() in configure. } if (pid_file) { FILE *p = fopen(pid_file, "w+"); if (p) { fprintf(p, "%d\n", getpid()); fclose(p); } else { perror("Failed to write pid file"); } } if (!g_thread_get_initialized()) { g_thread_init(NULL); } upnp_renderer = upnp_renderer_new(friendly_name, uuid); if (upnp_renderer == NULL) { goto out; } if (show_devicedesc) { char *buf; buf = upnp_get_device_desc(upnp_renderer); assert(buf != NULL); fputs(buf, stdout); exit(EXIT_SUCCESS); } rc = output_init(output); if (rc != 0) { fprintf(stderr,"ERROR: Failed to initialize Output subsystem\n"); goto out; } struct device_private *device; device = upnp_device_init(upnp_renderer, ip_address); if (device == NULL) { fprintf(stderr,"ERROR: Failed to initialize UPnP device\n"); goto out; } upnp_transport_init(device); upnp_control_init(); printf("Ready for rendering..\n"); output_loop(); result = EXIT_SUCCESS; out: return result; }
struct device_private *upnp_device_init(struct device *device_def, const char *ip_address) { int rc; #ifdef HAVE_LIBUPNP short int port = 0; #endif struct service *srv; struct icon *icon_entry; char *buf; struct device_private *priv = NULL; int i; assert(device_def != NULL); if (device_def->init_function) { rc = device_def->init_function(); if (rc != 0) { goto out; } } priv = malloc(sizeof(*priv)); priv->upnp_device = device_def; #ifdef HAVE_LIBUPNP ithread_mutex_init(&(priv->device_mutex), NULL); #endif //upnp_device = device_def; /* register icons in web server */ for (i=0; (icon_entry = device_def->icons[i]); i++) { webserver_register_file(icon_entry->url, "image/png"); } /* generate and register service schemas in web server */ for (i=0; (srv = device_def->services[i]); i++) { buf = upnp_get_scpd(srv); assert(buf != NULL); printf("registering '%s'\n", srv->scpd_url); webserver_register_buf(srv->scpd_url,buf,"text/xml"); } #ifdef HAVE_LIBUPNP rc = UpnpInit(ip_address, port); if (UPNP_E_SUCCESS != rc) { printf("UpnpInit() Error: %d\n", rc); goto upnp_err_out; } rc = UpnpEnableWebserver(TRUE); if (UPNP_E_SUCCESS != rc) { printf("UpnpEnableWebServer() Error: %d\n", rc); goto upnp_err_out; } rc = UpnpSetVirtualDirCallbacks(&virtual_dir_callbacks); if (UPNP_E_SUCCESS != rc) { printf("UpnpSetVirtualDirCallbacks() Error: %d\n", rc); goto upnp_err_out; } rc = UpnpAddVirtualDir("/upnp"); if (UPNP_E_SUCCESS != rc) { printf("UpnpAddVirtualDir() Error: %d\n", rc); goto upnp_err_out; } buf = upnp_get_device_desc(device_def); rc = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC, buf, strlen(buf), 1, &event_handler, priv, &(priv->device_handle)); if (UPNP_E_SUCCESS != rc) { printf("UpnpRegisterRootDevice2() Error: %d\n", rc); goto upnp_err_out; } rc = UpnpSendAdvertisement(priv->device_handle, 100); if (UPNP_E_SUCCESS != rc) { fprintf(stderr, "Error sending advertisements: %d\n", rc); goto upnp_err_out; } #endif goto out; #ifdef HAVE_LIBUPNP upnp_err_out: UpnpFinish(); #endif out: return priv; }
int main(int argc, char **argv) { int rc, cnt; struct device *upnp_renderer; char mac_addr[18]; char eth_name[sizeof(ether_tmpl) + 10]; char **eth; FILE *fh = NULL; #if defined(__i386__) && defined(DEBUG) struct sigaction sigact; sigact.sa_sigaction = crit_err_hdlr; sigact.sa_flags = SA_RESTART | SA_SIGINFO; if (sigaction(SIGSEGV, &sigact, (struct sigaction *)NULL) != 0) { fprintf(stderr, "error setting signal handler for %d (%s)\n", SIGSEGV, strsignal(SIGSEGV)); exit(EXIT_FAILURE); } #endif // Init glib threads if (!g_thread_supported()) { g_thread_init(NULL); } // Parse args early (may set debug-level) rc = process_cmdline(argc, argv); if (rc != 0) { exit(EXIT_FAILURE); } // Some commands are valid only if interactive if (!run_as_daemon) { // Info commenads (non-daemon) if (show_version) { do_show_version(); return EXIT_SUCCESS; } if (show_connmgr_scpd) { upnp_renderer_dump_connmgr_scpd(); return EXIT_SUCCESS; } if (show_control_scpd) { upnp_renderer_dump_control_scpd(); return EXIT_SUCCESS; } if (show_transport_scpd) { upnp_renderer_dump_transport_scpd(); return EXIT_SUCCESS; } } else { if (show_version || show_control_scpd || show_connmgr_scpd || show_transport_scpd || show_devicedesc) { // Info commands not allow in daemon mode fprintf(stderr, "Info options incompatible with daemon\n"); exit(EXIT_FAILURE); } rc = daemon(0, 0); if (rc != 0) { fprintf(stderr, "Failed to detach process\n"); exit(EXIT_FAILURE); } } // Read and parse config file, OK if none if (config_file == NULL) config_file = CFG_FILE_NAME; config_init(&upnpmpd_cfg); rc = config_read_file(&upnpmpd_cfg, (config_file) ? config_file : CFG_FILE_NAME); if (rc != CONFIG_TRUE) { if (config_error_line(&upnpmpd_cfg) == 0) { printf("Config not found (%s), continuing...\n", config_file); } else { printf ("Error parsing config file: %s\nLine %d: %s", config_file, config_error_line(&upnpmpd_cfg), config_error_text(&upnpmpd_cfg)); exit(EXIT_FAILURE); } } // Use bound interface if given if (if_name[0]) eth = &if_name[0]; else eth = ðers[0]; while (*eth) { sprintf(eth_name, ether_tmpl, *eth); // Obtain MAC address from interface fh = fopen(eth_name, "r"); if (fh) break; // Try next eth++; } // anything? if (fh == NULL) { fprintf(stderr, "No usable network interface found\n"); exit(EXIT_FAILURE); } // Read 6 groups of 3 chars cnt = fread(mac_addr, 3, 6, fh); fclose(fh); // Valid looking MAC? if (cnt != 6) { fprintf(stderr, "Bad MAC address %d\n", cnt); exit(EXIT_FAILURE); } mac_addr[17] = '\0'; DBG_PRINT(DBG_LVL2, "Found MAC at %s: %s\n", eth_name, mac_addr); upnp_renderer = upnp_renderer_new(friendly_name, mac_addr, serial, &upnpmpd_cfg); if (upnp_renderer == NULL) exit(EXIT_FAILURE); if (show_devicedesc) { fputs(upnp_get_device_desc(upnp_renderer), stdout); return EXIT_SUCCESS; } // Connect to MPD rc = output_mpd_init(&upnpmpd_cfg); if (rc != 0) exit(EXIT_FAILURE); // Create UPnP device and broadcast rc = getIfInfo(if_name[0]); if (rc != 0) exit(EXIT_FAILURE); rc = upnp_device_init(upnp_renderer, gIF_IPV4); if (rc != 0) exit(EXIT_FAILURE); printf("UPnPMPD ready at IP: %s\n", gIF_IPV4); // Run main event loop // Process glib evnets output_loop(); return EXIT_SUCCESS; }
int upnp_device_init(struct device *device_def, char *ip_address) { int rc; int result = -1; short int port = 0; struct service *srv; struct icon *icon_entry; char *buf; int i; if (device_def->init_function) { rc = device_def->init_function(); if (rc != 0) { goto out; } } upnp_device = device_def; /* register icons in web server */ for (i=0; (icon_entry = upnp_device->icons[i]); i++) { webserver_register_file(icon_entry->url, "image/png"); } /* generate and register service schemas in web server */ for (i=0; (srv = upnp_device->services[i]); i++) { buf = upnp_get_scpd(srv); debug_printf(MSG_INFO, "registering '%s'\n", srv->scpd_url); webserver_register_buf(srv->scpd_url,buf,"text/xml"); } rc = UpnpInit(ip_address, port); if (UPNP_E_SUCCESS != rc) { debug_printf(MSG_ERROR, "UpnpInit() Error: %d\n", rc); goto upnp_err_out; } rc = UpnpEnableWebserver(TRUE); if (UPNP_E_SUCCESS != rc) { debug_printf(MSG_ERROR, "UpnpEnableWebServer() Error: %d\n", rc); goto upnp_err_out; } rc = UpnpSetVirtualDirCallbacks(&virtual_dir_callbacks); if (UPNP_E_SUCCESS != rc) { debug_printf(MSG_ERROR, "UpnpSetVirtualDirCallbacks() Error: %d\n", rc); goto upnp_err_out; } rc = UpnpAddVirtualDir("/upnp"); if (UPNP_E_SUCCESS != rc) { debug_printf(MSG_ERROR, "UpnpAddVirtualDir() Error: %d\n", rc); goto upnp_err_out; } buf = upnp_get_device_desc(device_def); rc = UpnpRegisterRootDevice2(UPNPREG_BUF_DESC, buf, strlen(buf), 1, &event_handler, &device_def, &device_handle); if (UPNP_E_SUCCESS != rc) { debug_printf(MSG_ERROR, "UpnpRegisterRootDevice2() Error: %d\n", rc); goto upnp_err_out; } rc = UpnpSendAdvertisement(device_handle, 100); if (UPNP_E_SUCCESS != rc) { debug_printf(MSG_ERROR, "Error sending advertisements: %d\n", rc); goto upnp_err_out; } result = 0; goto out; upnp_err_out: UpnpFinish(); out: return result; }