WebServer::~WebServer() { clearFiles(); UpnpRemoveAllVirtualDirs(); UpnpSetWebServerRootDir(nullptr); }
WebServer::WebServer(const std::string& webRoot) : m_webRoot(webRoot) { handleUPnPResult(UpnpSetWebServerRootDir(m_webRoot.c_str())); UpnpVirtualDirCallbacks cbs; cbs.get_info = &getInfoCallback; cbs.open = &openCallback; cbs.read = &readCallback; cbs.write = &writeCallback; cbs.seek = &seekCallback; cbs.close = &closeCallback; if (UPNP_E_SUCCESS != UpnpSetVirtualDirCallbacks(&cbs)) { throw std::logic_error("Failed to create webserver"); } }
int TvDeviceStart(char *ip_address, unsigned short port, const char *desc_doc_name, const char *web_dir_path, print_string pfun, int combo) { int ret = UPNP_E_SUCCESS; char desc_doc_url[DESC_URL_SIZE]; ithread_mutex_init(&TVDevMutex, NULL); SampleUtil_Initialize(pfun); SampleUtil_Print("Initializing UPnP Sdk with\n" "\tipaddress = %s port = %u\n", ip_address ? ip_address : "{NULL}", port); ret = UpnpInit2(ip_address, port); if (ret != UPNP_E_SUCCESS) { SampleUtil_Print("Error with UpnpInit2 -- %d\n", ret); UpnpFinish(); return ret; } ip_address = UpnpGetServerIpAddress(); port = UpnpGetServerPort(); SampleUtil_Print("UPnP Initialized\n" "\tipaddress = %s port = %u\n", ip_address ? ip_address : "{NULL}", port); if (!desc_doc_name) { if (combo) { desc_doc_name = "tvcombodesc.xml"; } else { desc_doc_name = "tvdevicedesc.xml"; } } if (!web_dir_path) { web_dir_path = DEFAULT_WEB_DIR; } snprintf(desc_doc_url, DESC_URL_SIZE, "http://%s:%d/%s", ip_address, port, desc_doc_name); SampleUtil_Print("Specifying the webserver root directory -- %s\n", web_dir_path); ret = UpnpSetWebServerRootDir(web_dir_path); if (ret != UPNP_E_SUCCESS) { SampleUtil_Print ("Error specifying webserver root directory -- %s: %d\n", web_dir_path, ret); UpnpFinish(); return ret; } SampleUtil_Print("Registering the RootDevice\n" "\t with desc_doc_url: %s\n", desc_doc_url); ret = UpnpRegisterRootDevice(desc_doc_url, TvDeviceCallbackEventHandler, &device_handle, &device_handle); if (ret != UPNP_E_SUCCESS) { SampleUtil_Print("Error registering the rootdevice : %d\n", ret); UpnpFinish(); return ret; } else { SampleUtil_Print("RootDevice Registered\n" "Initializing State Table\n"); TvDeviceStateTableInit(desc_doc_url); SampleUtil_Print("State Table Initialized\n"); ret = UpnpSendAdvertisement(device_handle, default_advr_expire); if (ret != UPNP_E_SUCCESS) { SampleUtil_Print("Error sending advertisements : %d\n", ret); UpnpFinish(); return ret; } SampleUtil_Print("Advertisements Sent\n"); } return UPNP_E_SUCCESS; }
int main (int argc, char** argv) { int ret = UPNP_E_SUCCESS; int signal; char descDocUrl[50]; char descDocName[20]; char xmlPath[50]; char intIpAddress[32]; // Server internal ip address char extIpAddress[32]; sigset_t sigsToCatch; pid_t pid,sid; if (argc != 3) { printf("Usage: upnpd <external ifname> <internal ifname>\n"); printf("Example: upnpd ppp0 eth0\n"); printf("Example: upnpd eth1 eth0\n"); exit(0); } parseConfigFile(&g_forwardRules,&g_debug,g_iptables, g_forwardChainName,g_preroutingChainName, g_upstreamBitrate,g_downstreamBitrate, descDocName,xmlPath); // Save the interface names for later uses strcpy(g_extInterfaceName, argv[1]); strcpy(g_intInterfaceName, argv[2]); // Get the internal and external ip address to start the daemon on /* Added by Yanhua */ while( (GetIpAddressStr(intIpAddress, g_intInterfaceName)==0) || (GetIpAddressStr(extIpAddress, g_extInterfaceName)==0) ) { sleep(2); } #if 0 // Put igd in the background as a daemon process. pid = vfork(); if (pid < 0) { perror("Error forking a new process."); exit(EXIT_FAILURE); } if (pid > 0) exit(EXIT_SUCCESS); if ((sid = setsid()) < 0) { perror("Error running setsid"); exit(EXIT_FAILURE); } if ((chdir("/")) < 0) { perror("Error setting root directory"); exit(EXIT_FAILURE); } umask(0); close(STDERR_FILENO); close (STDIN_FILENO); close (STDOUT_FILENO); #endif // End Daemon initialization // Initialize UPnP SDK on the internal Interface if (g_debug) syslog(LOG_DEBUG, "Initializing UPnP SDK ... "); if ( (ret = UpnpInit(intIpAddress,0) ) != UPNP_E_SUCCESS) { syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s ",intIpAddress); syslog (LOG_ERR, " UpnpInit returned %d", ret); UpnpFinish(); exit(1); } if (g_debug) syslog(LOG_DEBUG, "UPnP SDK Successfully Initialized."); // Set the Device Web Server Base Directory if (g_debug) syslog(LOG_DEBUG, "Setting the Web Server Root Directory to %s",xmlPath); if ( (ret = UpnpSetWebServerRootDir(xmlPath)) != UPNP_E_SUCCESS ) { syslog (LOG_ERR, "Error Setting Web Server Root Directory to: %s", xmlPath); syslog (LOG_ERR, " UpnpSetWebServerRootDir returned %d", ret); UpnpFinish(); exit(1); } if (g_debug) syslog(LOG_DEBUG, "Succesfully set the Web Server Root Directory."); // Form the Description Doc URL to pass to RegisterRootDevice sprintf(descDocUrl, "http://%s:%d/%s", UpnpGetServerIpAddress(), UpnpGetServerPort(), descDocName); // Register our IGD as a valid UPnP Root device if (g_debug) syslog(LOG_DEBUG, "Registering the root device with descDocUrl %s", descDocUrl); if ( (ret = UpnpRegisterRootDevice(descDocUrl, EventHandler, &deviceHandle, &deviceHandle)) != UPNP_E_SUCCESS ) { syslog(LOG_ERR, "Error registering the root device with descDocUrl: %s", descDocUrl); syslog(LOG_ERR, " UpnpRegisterRootDevice returned %d", ret); UpnpFinish(); exit(1); } syslog (LOG_DEBUG, "IGD root device successfully registered."); // Initialize the state variable table. StateTableInit(descDocUrl); // Record the startup time, for uptime /* Modified by Yanhua */ #if 0 startup_time = time(NULL); #endif { struct sysinfo info; sysinfo(&info); startup_time = (long int)info.uptime; } // Send out initial advertisements of our device's services with timeouts of 30 minutes if ( (ret = UpnpSendAdvertisement(deviceHandle, 1800) != UPNP_E_SUCCESS )) { syslog(LOG_ERR, "Error Sending Advertisements. Exiting ..."); UpnpFinish(); exit(1); } syslog(LOG_DEBUG, "Advertisements Sent. Listening for requests ... "); // Loop until program exit signals recieved sigemptyset(&sigsToCatch); sigaddset(&sigsToCatch, SIGINT); sigaddset(&sigsToCatch, SIGTERM); //sigwait(&sigsToCatch, &signal); pthread_sigmask(SIG_SETMASK, &sigsToCatch, NULL); sigwait(&sigsToCatch, &signal); syslog(LOG_DEBUG, "Shutting down on signal %d...\n", signal); // Cleanup UPnP SDK and free memory pmlist_FreeList(); UpnpUnRegisterRootDevice(deviceHandle); UpnpFinish(); // Exit normally return (1); }
int main (int argc, char** argv) { char descDocUrl[7+15+1+5+1+sizeof(g_vars.descDocName)+1]; // http://ipaddr:port/docName<null> char intIpAddress[16]; // Server internal ip address sigset_t sigsToCatch; int ret, signum, arg = 1, foreground = 0; if (argc < 3 || argc > 4) { printf("Usage: upnpd [-f] <external ifname> <internal ifname>\n"); printf(" -f\tdon't daemonize\n"); printf("Example: upnpd ppp0 eth0\n"); exit(0); } parseConfigFile(&g_vars); // check for '-f' option if (strcmp(argv[arg], "-f") == 0) { foreground = 1; arg++; } // Save interface names for later use strncpy(g_vars.extInterfaceName, argv[arg++], IFNAMSIZ); strncpy(g_vars.intInterfaceName, argv[arg++], IFNAMSIZ); // Get the internal ip address to start the daemon on if (GetIpAddressStr(intIpAddress, g_vars.intInterfaceName) == 0) { fprintf(stderr, "Invalid internal interface name '%s'\n", g_vars.intInterfaceName); exit(EXIT_FAILURE); } if (!foreground) { struct rlimit resourceLimit = { 0, 0 }; pid_t pid, sid; unsigned int i; // Put igd in the background as a daemon process. pid = fork(); if (pid < 0) { perror("Error forking a new process."); exit(EXIT_FAILURE); } if (pid > 0) exit(EXIT_SUCCESS); // become session leader if ((sid = setsid()) < 0) { perror("Error running setsid"); exit(EXIT_FAILURE); } // close all file handles resourceLimit.rlim_max = 0; ret = getrlimit(RLIMIT_NOFILE, &resourceLimit); if (ret == -1) /* shouldn't happen */ { perror("error in getrlimit()"); exit(EXIT_FAILURE); } if (0 == resourceLimit.rlim_max) { fprintf(stderr, "Max number of open file descriptors is 0!!\n"); exit(EXIT_FAILURE); } for (i = 0; i < resourceLimit.rlim_max; i++) close(i); // fork again so child can never acquire a controlling terminal pid = fork(); if (pid < 0) { perror("Error forking a new process."); exit(EXIT_FAILURE); } if (pid > 0) exit(EXIT_SUCCESS); if ((chdir("/")) < 0) { perror("Error setting root directory"); exit(EXIT_FAILURE); } } umask(0); // End Daemon initialization openlog("upnpd", LOG_CONS | LOG_NDELAY | LOG_PID | (foreground ? LOG_PERROR : 0), LOG_LOCAL6); // Initialize UPnP SDK on the internal Interface trace(3, "Initializing UPnP SDK ... "); if ( (ret = UpnpInit(intIpAddress,0) ) != UPNP_E_SUCCESS) { syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s ",intIpAddress); syslog (LOG_ERR, " UpnpInit returned %d", ret); UpnpFinish(); exit(1); } trace(2, "UPnP SDK Successfully Initialized."); // Set the Device Web Server Base Directory trace(3, "Setting the Web Server Root Directory to %s",g_vars.xmlPath); if ( (ret = UpnpSetWebServerRootDir(g_vars.xmlPath)) != UPNP_E_SUCCESS ) { syslog (LOG_ERR, "Error Setting Web Server Root Directory to: %s", g_vars.xmlPath); syslog (LOG_ERR, " UpnpSetWebServerRootDir returned %d", ret); UpnpFinish(); exit(1); } trace(2, "Succesfully set the Web Server Root Directory."); //initialize the timer thread for expiration of mappings if (ExpirationTimerThreadInit()!=0) { syslog(LOG_ERR,"ExpirationTimerInit failed"); UpnpFinish(); exit(1); } // Form the Description Doc URL to pass to RegisterRootDevice sprintf(descDocUrl, "http://%s:%d/%s", UpnpGetServerIpAddress(), UpnpGetServerPort(), g_vars.descDocName); // Register our IGD as a valid UPnP Root device trace(3, "Registering the root device with descDocUrl %s", descDocUrl); if ( (ret = UpnpRegisterRootDevice(descDocUrl, EventHandler, &deviceHandle, &deviceHandle)) != UPNP_E_SUCCESS ) { syslog(LOG_ERR, "Error registering the root device with descDocUrl: %s", descDocUrl); syslog(LOG_ERR, " UpnpRegisterRootDevice returned %d", ret); UpnpFinish(); exit(1); } trace(2, "IGD root device successfully registered."); // Initialize the state variable table. StateTableInit(descDocUrl); // Record the startup time, for uptime startup_time = time(NULL); // Send out initial advertisements of our device's services with timeouts of 30 minutes if ( (ret = UpnpSendAdvertisement(deviceHandle, 1800) != UPNP_E_SUCCESS )) { syslog(LOG_ERR, "Error Sending Advertisements. Exiting ..."); UpnpFinish(); exit(1); } trace(2, "Advertisements Sent. Listening for requests ... "); // Loop until program exit signals received do { sigemptyset(&sigsToCatch); sigaddset(&sigsToCatch, SIGINT); sigaddset(&sigsToCatch, SIGTERM); sigaddset(&sigsToCatch, SIGUSR1); pthread_sigmask(SIG_SETMASK, &sigsToCatch, NULL); sigwait(&sigsToCatch, &signum); trace(3, "Caught signal %d...\n", signum); switch (signum) { case SIGUSR1: DeleteAllPortMappings(); break; default: break; } } while (signum!=SIGTERM && signum!=SIGINT); trace(2, "Shutting down on signal %d...\n", signum); // Cleanup UPnP SDK and free memory DeleteAllPortMappings(); ExpirationTimerThreadShutdown(); UpnpUnRegisterRootDevice(deviceHandle); UpnpFinish(); // Exit normally return (0); }
int main (int argc, char** argv) { int ret = UPNP_E_SUCCESS; int signal; char descDocUrl[50]; char descDocName[20]; char xmlPath[50]; char intIpAddress[16]; // Server internal ip address char extIpAddress[16]; // Server internal ip address sigset_t sigsToCatch; FILE *f; pid_t pid,sid; if (argc != 3) { printf("Usage: upnpd <external ifname> <internal ifname>\n"); printf("Example: upnpd ppp0 eth0\n"); printf("Example: upnpd eth1 eth0\n"); exit(0); } parseConfigFile(&g_forwardRules,&g_debug,g_iptables, g_forwardChainName,g_preroutingChainName, g_upstreamBitrate,g_downstreamBitrate, descDocName,xmlPath); // Save the interface names for later uses strcpy(g_extInterfaceName, argv[1]); strcpy(g_intInterfaceName, argv[2]); openlog("upnpd", LOG_PID | LOG_CONS, LOG_USER); // Get the internal ip address to start the daemon on GetIpAddressStr(intIpAddress, g_intInterfaceName); GetIpAddressStr(extIpAddress, g_extInterfaceName); // Put igd in the background as a daemon process. pid = fork(); if (pid < 0) { perror("Error forking a new process."); cleanup(); exit(EXIT_FAILURE); } if (pid > 0) exit(EXIT_SUCCESS); /* if we are here, we know we are the demonized version */ //open a state file f = fopen(STATE_FILE, "w"); if (!f) { syslog(LOG_ERR, "failed to open %s: %m", STATE_FILE); } else { fprintf(f, "external %s %s\ninternal %s %s\n", g_extInterfaceName, extIpAddress, g_intInterfaceName, intIpAddress); fclose(f); } atexit(cleanup); if ((sid = setsid()) < 0) { perror("Error running setsid"); exit(EXIT_FAILURE); } if ((chdir("/")) < 0) { perror("Error setting root directory"); exit(EXIT_FAILURE); } umask(0); close(STDERR_FILENO); close (STDIN_FILENO); close (STDOUT_FILENO); // End Daemon initialization // Initialize UPnP SDK on the internal Interface if (g_debug) syslog(LOG_DEBUG, "Initializing UPnP SDK ... "); if ( (ret = UpnpInit(intIpAddress,0) ) != UPNP_E_SUCCESS) { syslog (LOG_ERR, "Error Initializing UPnP SDK on IP %s ",intIpAddress); syslog (LOG_ERR, " UpnpInit returned %d", ret); UpnpFinish(); exit(1); } if (g_debug) syslog(LOG_DEBUG, "UPnP SDK Successfully Initialized."); // Set the Device Web Server Base Directory if (g_debug) syslog(LOG_DEBUG, "Setting the Web Server Root Directory to %s",xmlPath); if ( (ret = UpnpSetWebServerRootDir(xmlPath)) != UPNP_E_SUCCESS ) { syslog (LOG_ERR, "Error Setting Web Server Root Directory to: %s", xmlPath); syslog (LOG_ERR, " UpnpSetWebServerRootDir returned %d", ret); UpnpFinish(); exit(1); } if (g_debug) syslog(LOG_DEBUG, "Succesfully set the Web Server Root Directory."); // Form the Description Doc URL to pass to RegisterRootDevice sprintf(descDocUrl, "http://%s:%d/%s", UpnpGetServerIpAddress(), UpnpGetServerPort(), descDocName); // Register our IGD as a valid UPnP Root device if (g_debug) syslog(LOG_DEBUG, "Registering the root device with descDocUrl %s", descDocUrl); if ( (ret = UpnpRegisterRootDevice(descDocUrl, EventHandler, &deviceHandle, &deviceHandle)) != UPNP_E_SUCCESS ) { syslog(LOG_ERR, "Error registering the root device with descDocUrl: %s", descDocUrl); syslog(LOG_ERR, " UpnpRegisterRootDevice returned %d", ret); UpnpFinish(); exit(1); } syslog (LOG_DEBUG, "IGD root device successfully registered."); // Initialize the state variable table. StateTableInit(descDocUrl); // Record the startup time, for uptime startup_time = time(NULL); // Send out initial advertisements of our device's services with timeouts of 30 minutes if ( (ret = UpnpSendAdvertisement(deviceHandle, 1800) != UPNP_E_SUCCESS )) { syslog(LOG_ERR, "Error Sending Advertisements. Exiting ..."); UpnpFinish(); exit(1); } syslog(LOG_DEBUG, "Advertisements Sent. Listening for requests ... "); // Loop until program exit signals recieved // and now also recreate the current portmappings on SIGUSR1 while (1) { sigemptyset(&sigsToCatch); sigaddset(&sigsToCatch, SIGINT); sigaddset(&sigsToCatch, SIGTERM); sigaddset(&sigsToCatch, SIGQUIT); sigaddset(&sigsToCatch, SIGABRT); sigaddset(&sigsToCatch, SIGHUP); sigaddset(&sigsToCatch, SIGUSR1); sigaddset(&sigsToCatch, SIGUSR2); //sigwait(&sigsToCatch, &signal); pthread_sigmask(SIG_SETMASK, &sigsToCatch, NULL); sigwait(&sigsToCatch, &signal); if (signal == SIGUSR1) { syslog(LOG_DEBUG, "signal SIGUSR1 received - rebuilding portmappings\n"); //rebuild all the portmappings pmlist_RecreateAll(); } else if (signal == SIGHUP || signal == SIGUSR2) { //nothing } else { break; } } syslog(LOG_DEBUG, "Shutting down on signal %d...\n", signal); // Cleanup UPnP SDK and free memory pmlist_FreeList(); UpnpUnRegisterRootDevice(deviceHandle); UpnpFinish(); // Exit normally return (1); }
ERROR_TYPE IUpnp::SetWebServerRootDir(IN const char* rootDir) { return (ERROR_TYPE)UpnpSetWebServerRootDir(rootDir); }