1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-09-22 04:15:54 -04:00

kh12. A couple of leaks plugged on relay restarting, a possible crash on xml

reload or server exit. small changes for win32, the icecast service should
be working better and I've updated the libogg to 1.1.4 for the build.

svn path=/icecast/branches/kh/icecast/; revision=16352
This commit is contained in:
Karl Heyes 2009-07-28 14:44:15 +00:00
parent 165f64a9a9
commit 9565edee8e
17 changed files with 261 additions and 186 deletions

8
NEWS
View File

@ -16,6 +16,14 @@ Feature differences from SVN trunk
any extra tags are show in the conf/icecast.xml.dist file
2.3.2-kh12
. xml based relays could cause a crash on server exit or xml reload
. avoid memory/fd leak on active relay restart.
. cleaner worker thread shutdown.
. win32 update. Prevent Esc closing the GUI. Make the service work better and
is now able to take an alternative xml as parameter. Update libogg in the
build to 1.1.4 and refer to the current directory for dependent DLLs.
2.3.2-kh11
. busy looping caused by truncation on 32bit setups
. avoid possible deadlock between file release and open

View File

@ -95,7 +95,7 @@
#define PACKAGE_NAME "Icecast"
/* Version number of package */
#define VERSION "2.3.2-kh11"
#define VERSION "2.3.2-kh12"
/* Define to the version of this package. */
#define PACKAGE_VERSION VERSION

View File

@ -1,4 +1,4 @@
AC_INIT([Icecast], [2.3.2-kh11], [karl@xiph.org])
AC_INIT([Icecast], [2.3.2-kh12], [karl@xiph.org])
AC_PREREQ(2.59)
AC_CONFIG_SRCDIR(src/main.c)

View File

@ -372,8 +372,10 @@ void *worker (void *arg)
wakeup_time = handler->current_time;
prevp = &handler->clients;
while (handler->running)
while (1)
{
if (handler->running == 0 && handler->count == 0)
break;
if (prev_count != handler->count)
{
DEBUG2 ("%p now has %d clients", handler, handler->count);
@ -425,8 +427,9 @@ void *worker (void *arg)
client = *prevp;
}
handler->wakeup_ms += 10; /* allow a small sleep */
wakeup_time.tv_sec = handler->wakeup_ms/1000;
wakeup_time.tv_nsec = (handler->wakeup_ms%1000) *1000000;
wakeup_time.tv_sec = (long)(handler->wakeup_ms/1000);
wakeup_time.tv_nsec = (long)((handler->wakeup_ms - (wakeup_time.tv_sec*1000))*1000000);
}
thread_mutex_unlock (&handler->lock);
INFO0 ("shutting down");
@ -459,34 +462,41 @@ static void worker_stop (void)
workers = handler->next;
worker_count--;
thread_rwlock_unlock (&workers_lock);
handler->running = 0;
thread_mutex_lock (&handler->lock);
handler->running = 0;
thread_cond_signal (&handler->cond);
thread_mutex_unlock (&handler->lock);
thread_sleep (10000);
thread_mutex_lock (&handler->lock);
clients = handler->clients;
handler->clients = NULL;
handler->count = 0;
thread_cond_signal (&handler->cond);
thread_mutex_unlock (&handler->lock);
// move clients to another handler
if (worker_count > 1 && clients)
if (clients)
{
client_t *endp = clients;
int count = 0;
thread_mutex_lock (&workers->lock);
while (endp->next_on_worker)
if (worker_count == 0)
WARN0 ("clients left unprocessed");
else
{
endp = endp->next_on_worker;
count++;
}
endp->next_on_worker = workers->clients;
workers->clients = clients;
workers->count += count;
thread_mutex_unlock (&workers->lock);
}
if (handler->count)
WARN1 ("%d clients left", handler->count);
// move clients to another worker
client_t *endp = clients;
int count = 0;
thread_mutex_lock (&workers->lock);
while (endp->next_on_worker)
{
endp = endp->next_on_worker;
count++;
}
endp->next_on_worker = workers->clients;
workers->clients = clients;
workers->count += count;
thread_mutex_unlock (&workers->lock);
}
}
thread_join (handler->thread);
thread_mutex_destroy (&handler->lock);
thread_cond_destroy (&handler->cond);

View File

@ -14,9 +14,15 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef WIN32_SERVICE
#define _WIN32_WINNT 0x0400
#include <windows.h>
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
@ -35,7 +41,6 @@
#include <sys/types.h>
#include <grp.h>
#include <pwd.h>
#include <errno.h>
#endif
#include "cfgfile.h"
@ -69,7 +74,9 @@ static char *pidfile = NULL;
static void _fatal_error(char *perr)
{
#ifdef WIN32
#ifdef WIN32_SERVICE
MessageBox(NULL, perr, "Error", MB_SERVICE_NOTIFICATION);
#elif defined(WIN32)
MessageBox(NULL, perr, "Error", MB_OK);
#else
fprintf(stdout, "%s\n", perr);
@ -115,13 +122,13 @@ void _initialize_subsystems(void)
void _shutdown_subsystems(void)
{
fserve_shutdown();
refbuf_shutdown();
slave_shutdown();
auth_shutdown();
yp_shutdown();
stats_shutdown();
fserve_shutdown();
connection_shutdown();
config_shutdown();
resolver_shutdown();
@ -431,12 +438,14 @@ int main(int argc, char **argv)
_fatal_error("XML config parsing error");
break;
}
#if !defined(_WIN32) || defined(_CONSOLE)
_shutdown_subsystems();
return 1;
#endif
return -1;
}
} else if (res == -1) {
_print_usage();
return 1;
return -1;
}
/* override config file options with commandline options */
@ -446,7 +455,7 @@ int main(int argc, char **argv)
if(!_server_proc_init()) {
_fatal_error("Server startup failed. Exiting");
_shutdown_subsystems();
return 1;
return -1;
}
_ch_root_uid_setup(); /* Change user id and root if requested/possible */
@ -469,7 +478,7 @@ int main(int argc, char **argv)
if (!_start_logging()) {
_fatal_error("FATAL: Could not start logging");
_shutdown_subsystems();
return 1;
return -1;
}
INFO1 ("%s server started", ICECAST_VERSION_STRING);

View File

@ -228,7 +228,6 @@ void slave_shutdown(void)
thread_rwlock_destroy (&slaves_lock);
thread_rwlock_destroy (&workers_lock);
thread_spin_destroy (&relay_start_lock);
slave_running = 0;
}
@ -550,6 +549,7 @@ static void *start_relay_stream (void *arg)
config_release_config();
INFO2 ("listener count still on %s is %d", src->mount, src->listeners);
source_clear_listeners (src);
source_clear_source (src);
relay->start = client->worker->current_time.tv_sec + relay->interval;
client->schedule_ms = timing_get_time() + 1000;
@ -725,6 +725,7 @@ static void relay_check_streams (relay_server *to_start,
{
release->cleanup = 1;
release->start = 0;
release->source->client->schedule_ms = 0;
if (release->running)
{
/* relay has been removed from xml/streamlist, shut down active relay */
@ -1253,8 +1254,15 @@ static int relay_read (client_t *client)
client->ops = &relay_startup_ops;
relay->running = 0;
global_reduce_bitrate_sampling (global.out_bitrate);
thread_mutex_unlock (&source->lock);
if (client->con)
connection_close (client->con);
client->con = NULL;
if (client->parser)
httpp_destroy (client->parser);
client->parser = NULL;
source_clear_source (source);
thread_rwlock_unlock (&global.shutdown_lock);
slave_update_all_mounts();
return 0;
}
if ((source->flags & SOURCE_TERMINATING) == 0)
@ -1272,6 +1280,7 @@ static int relay_read (client_t *client)
stats_event (relay->localmount, NULL, NULL);
global_reduce_bitrate_sampling (global.out_bitrate);
thread_rwlock_unlock (&global.shutdown_lock);
slave_update_all_mounts();
return -1;
}
@ -1288,7 +1297,7 @@ static int relay_startup (client_t *client)
{
relay_server *relay = client->shared_data;
if (global.running != ICE_RUNNING || relay->cleanup)
if (relay->cleanup)
return -1;
if (relay->enable == 0 || relay->start > client->worker->current_time.tv_sec)
{
@ -1300,11 +1309,6 @@ static int relay_startup (client_t *client)
{
source_t *src = relay->source;
src->flags |= SOURCE_ON_DEMAND;
if (src->listeners == 0)
{
client->schedule_ms = client->worker->time_ms + 1000;
return 0;
}
if (client->worker->current_time.tv_sec % 10 == 0)
{
mount_proxy * mountinfo = config_find_mount (config_get_config(), src->mount);
@ -1312,6 +1316,11 @@ static int relay_startup (client_t *client)
source_set_override (mountinfo->fallback_mount, src->mount);
config_release_config();
}
if (src->listeners == 0)
{
client->schedule_ms = client->worker->time_ms + 1000;
return 0;
}
DEBUG1 ("Detected listeners on relay %s", relay->localmount);
}

View File

@ -229,21 +229,11 @@ int source_compare_sources(void *arg, void *a, void *b)
}
void source_clear_source (source_t *source)
void source_clear_listeners (source_t *source)
{
int i, do_twice = 0;
int i;
ice_config_t *config;
mount_proxy *mountinfo;
refbuf_t *p;
DEBUG1 ("clearing source \"%s\"", source->mount);
if (source->dumpfile)
{
INFO1 ("Closing dumpfile for %s", source->mount);
fclose (source->dumpfile);
source->dumpfile = NULL;
}
/* lets drop any listeners still connected */
DEBUG2 ("source %s has %d clients to release", source->mount, source->listeners);
@ -268,6 +258,24 @@ void source_clear_source (source_t *source)
stats_event_sub (NULL, "listeners", i);
stats_event_sub (source->mount, "listeners", i);
}
source->listeners = 0;
source->prev_listeners = 0;
}
void source_clear_source (source_t *source)
{
int do_twice = 0;
refbuf_t *p;
DEBUG1 ("clearing source \"%s\"", source->mount);
if (source->dumpfile)
{
INFO1 ("Closing dumpfile for %s", source->mount);
fclose (source->dumpfile);
source->dumpfile = NULL;
}
format_free_plugin (source->format);
source->format = NULL;
@ -301,8 +309,6 @@ void source_clear_source (source_t *source)
source->burst_offset = 0;
source->queue_size = 0;
source->queue_size_limit = 0;
source->listeners = 0;
source->prev_listeners = 0;
source->client_stats_update = 0;
util_dict_free (source->audio_info);
source->audio_info = NULL;
@ -326,6 +332,7 @@ void source_clear_source (source_t *source)
static int _free_source (void *p)
{
source_t *source = p;
source_clear_listeners (source);
source_clear_source (source);
/* make sure all YP entries have gone */
@ -598,7 +605,6 @@ static int source_client_read (client_t *client)
client->ops = &source_client_halt_ops;
free (source->fallback.mount);
source->fallback.mount = NULL;
stats_event (source->mount, NULL, NULL);
}
thread_mutex_unlock (&source->lock);
}
@ -992,6 +998,7 @@ void source_shutdown (source_t *source, int with_fallback)
global.sources--;
stats_event_args (NULL, "sources", "%d", global.sources);
global_unlock();
stats_event (source->mount, NULL, NULL);
}

View File

@ -94,6 +94,7 @@ void *source_client_thread (void *arg);
int source_startup (client_t *client, const char *uri);
int source_client_callback (client_t *client, void *source);
void source_update_settings (ice_config_t *config, source_t *source, mount_proxy *mountinfo);
void source_clear_listeners (source_t *source);
void source_clear_source (source_t *source);
source_t *source_find_mount(const char *mount);
source_t *source_find_mount_raw(const char *mount);

View File

@ -47,14 +47,14 @@
struct rate_calc_node
{
uint64_t index;
long value;
int64_t index;
uint64_t value;
struct rate_calc_node *next;
};
struct rate_calc
{
uint64_t total;
int64_t total;
struct rate_calc_node *current;
unsigned int samples;
unsigned int ssec;
@ -755,7 +755,7 @@ void rate_add (struct rate_calc *calc, long value, uint64_t sid)
*/
long rate_avg (struct rate_calc *calc)
{
uint64_t range;
float range;
if (calc == NULL || calc->blocks < 2)
return 0;

View File

@ -12,7 +12,7 @@ Class1=CIcecast2winApp
Class2=CIcecast2winDlg
Class3=CAboutDlg
ResourceCount=10
ResourceCount=19
Resource1=IDR_MENU2
Resource2=IDR_MAINFRAME
Resource3=IDR_TRAY
@ -26,6 +26,15 @@ Resource7=IDD_STATSDIALOG
Resource8=IDR_MENU3
Resource9=IDD_ABOUTBOX
Resource10=IDR_MENU4
Resource11=IDD_SSTATUS (English (U.S.))
Resource12=IDD_CONFIGDIALOG (English (U.S.))
Resource13=IDD_STATSDIALOG (English (U.S.))
Resource14=IDR_MENU2 (English (U.S.))
Resource15=IDR_MENU3 (English (U.S.))
Resource16=IDR_TRAY (English (U.S.))
Resource17=IDD_ABOUTBOX (English (U.S.))
Resource18=IDD_ICECAST2WIN_DIALOG (English (U.S.))
Resource19=IDR_MENU4 (English (U.S.))
[CLS:CIcecast2winApp]
Type=0
@ -147,3 +156,75 @@ Command3=ID_ABOUT_HELP
Command4=ID_ABOUT_CREDITS
CommandCount=4
[DLG:IDD_ABOUTBOX (English (U.S.))]
Type=1
Class=?
ControlCount=2
Control1=IDOK,button,1342373889
Control2=IDC_STATIC,static,1350572046
[DLG:IDD_ICECAST2WIN_DIALOG (English (U.S.))]
Type=1
Class=?
ControlCount=7
Control1=IDC_MAINTAB,SysTabControl32,1342177280
Control2=IDC_START,button,1342242816
Control3=IDC_AUTOSTART,button,1342251011
Control4=IDC_STATIC,static,1342177294
Control5=IDC_SERVERSTATUS,static,1342177294
Control6=IDC_STATIC_SS,static,1342308865
Control7=IDC_HIDESYSTRAY,button,1342242816
[DLG:IDD_SSTATUS (English (U.S.))]
Type=1
Class=?
ControlCount=5
Control1=IDC_FILLER2,static,1342308352
Control2=IDC_GLOBALSTAT_LIST,SysListView32,1350631425
Control3=IDC_STATIC_GS,static,1342308352
Control4=IDC_STATIC_RUN,static,1342308352
Control5=IDC_RUNNINGFOR,static,1342308352
[DLG:IDD_CONFIGDIALOG (English (U.S.))]
Type=1
Class=?
ControlCount=1
Control1=IDC_CONFIG,edit,1352732868
[DLG:IDD_STATSDIALOG (English (U.S.))]
Type=1
Class=?
ControlCount=4
Control1=IDC_STATSLIST,SysListView32,1350631425
Control2=IDC_SOURCELIST,SysListView32,1350631425
Control3=IDC_STATIC_SLS,static,1342308352
Control4=IDC_STATIC,static,1342308352
[MNU:IDR_MENU2 (English (U.S.))]
Type=1
Class=?
Command1=ID_POPUP_ADDTOGLOBALSTATLIST
CommandCount=1
[MNU:IDR_MENU3 (English (U.S.))]
Type=1
Class=?
Command1=ID__DELETEFROMGLOBALSTATS
Command2=ID__MAKETHISSTATTHEWINDOWTITLE
CommandCount=2
[MNU:IDR_TRAY (English (U.S.))]
Type=1
Class=?
Command1=ID_BLANK_RESTORE
CommandCount=1
[MNU:IDR_MENU4 (English (U.S.))]
Type=1
Class=?
Command1=ID_FILE_EXIT
Command2=ID_FILE_EDITCONFIGURATION
Command3=ID_ABOUT_HELP
Command4=ID_ABOUT_CREDITS
CommandCount=4

View File

@ -53,7 +53,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /machine:I386
# ADD LINK32 libspeex.lib theora_static_d.lib ogg_static.lib vorbis_static.lib pthreadVSE.lib ssleay32MT.lib libcurl.lib libxml2.lib libxslt.lib iconv.lib ws2_32.lib winmm.lib /nologo /version:2.3 /subsystem:windows /pdb:none /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmtd.lib"
# ADD LINK32 libspeex.lib theora_static_d.lib ogg.lib vorbis_static.lib pthreadVSE.lib ssleay32MT.lib libcurl.lib libxml2.lib libxslt.lib iconv.lib ws2_32.lib winmm.lib /nologo /version:2.3 /subsystem:windows /pdb:none /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmtd.lib"
!ELSEIF "$(CFG)" == "Icecast2win - Win32 Debug"
@ -79,7 +79,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 libspeex.lib theora_static_d.lib ogg_static.lib vorbis_static.lib pthreadVSE.lib ssleay32MT.lib libcurl.lib libxml2.lib libxslt.lib iconv.lib ws2_32.lib winmm.lib /nologo /version:2.3 /subsystem:windows /incremental:no /debug /machine:I386 /nodefaultlib:"libcd.lib libcmt.lib" /pdbtype:sept
# ADD LINK32 libspeex.lib theora_static_d.lib ogg.lib vorbis_static.lib pthreadVSE.lib ssleay32MT.lib libcurl.lib libxml2.lib libxslt.lib iconv.lib ws2_32.lib winmm.lib /nologo /version:2.3 /subsystem:windows /incremental:no /debug /machine:I386 /nodefaultlib:"libcd.lib libcmt.lib" /pdbtype:sept
# SUBTRACT LINK32 /verbose
!ENDIF

View File

@ -549,7 +549,7 @@ void StartStats(void *dummy)
if (cur == NULL) {
MessageBox(NULL, "empty XML document", "Error", MB_OK);
xmlFreeDoc(doc);
return;
break;
}
cur = cur->xmlChildrenNode;
@ -1202,3 +1202,8 @@ void CIcecast2winDlg::OnAboutCredits()
CAboutDlg about;
about.DoModal();
}
void CIcecast2winDlg::OnCancel()
{
}

View File

@ -95,6 +95,7 @@ protected:
// Generated message map functions
//{{AFX_MSG(CIcecast2winDlg)
virtual BOOL OnInitDialog();
virtual void OnCancel();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();

View File

@ -3,7 +3,7 @@
[Setup]
AppName=Icecast2-KH
AppVerName=Icecast v2.3.2-kh11
AppVerName=Icecast v2.3.2-kh12
AppPublisherURL=http://www.icecast.org
AppSupportURL=http://www.icecast.org
AppUpdatesURL=http://www.icecast.org
@ -13,9 +13,11 @@ AllowNoIcons=yes
LicenseFile=..\COPYING
InfoAfterFile=..\README
OutputDir=.
OutputBaseFilename=icecast2_win32_v2.3.2-kh11_setup
OutputBaseFilename=icecast2_win32_v2.3.2-kh12_setup
WizardImageFile=icecast2logo2.bmp
WizardImageStretch=no
VersionInfoProductVersion=kh12
VersionInfoVersion=2.3.2
; uncomment the following line if you want your installation to run on NT 3.51 too.
; MinVersion=4,3.51
@ -34,8 +36,8 @@ Name: "{app}\examples"
Source: "win_release\icecast2win.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "console_release\icecast2_console.exe"; DestDir: "{app}"; DestName: "icecast2console.exe"; Flags: ignoreversion
Source: "service_Release\icecastService.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\examples\*"; DestDir: "{app}\examples"; Flags: ignoreversion
Source: "..\doc\*"; DestDir: "{app}\doc"; Flags: ignoreversion
Source: "..\examples\*"; DestDir: "{app}\examples"; Excludes: "*~"; Flags: ignoreversion
Source: "..\doc\*"; DestDir: "{app}\doc"; Excludes: "*Makefile*"; Flags: ignoreversion
Source: "..\web\*.xsl"; DestDir: "{app}\web"; Flags: ignoreversion
Source: "..\web\*.html"; DestDir: "{app}\web"; Flags: ignoreversion
Source: "..\web\images\*.png"; DestDir: "{app}\web\images"; Flags: ignoreversion
@ -43,16 +45,18 @@ Source: "..\web\images\*.jpg"; DestDir: "{app}\web\images"; Flags: ignoreversion
Source: "..\web\*.css"; DestDir: "{app}\web"; Flags: ignoreversion
Source: "..\admin\*.xsl"; DestDir: "{app}\admin"; Flags: ignoreversion
Source: "..\admin\flashpolicy"; DestDir: "{app}\admin"; Flags: ignoreversion
Source: "c:\xiph\lib\pthreadVSE.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\conf\*.dist"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\examples\icecast_shoutcast_compat.xml"; DestDir: "{app}"; DestName: "icecast.xml"; Flags: ignoreversion confirmoverwrite
Source: "c:\xiph\lib\iconv.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "c:\xiph\lib\libxslt.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "c:\xiph\lib\libxml2.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "c:\xiph\lib\libcurl.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "c:\xiph\lib\libeay32.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "c:\xiph\lib\ssleay32.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: "c:\xiph\lib\zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\pthreadVSE.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\iconv.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\ogg.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\libspeex.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\libxslt.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\libxml2.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\libcurl.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\libeay32.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\ssleay32.dll"; DestDir: "{app}"; Flags: ignoreversion
Source: ".\zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion
[Icons]

View File

@ -50,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 theora_static_d.lib libspeex.lib ogg_static.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libcurl.lib vorbis_static.lib libxml2.lib libxslt.lib iconv.lib pthreadVSE.lib ws2_32.lib winmm.lib ssleay32MT.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmt.lib"
# ADD LINK32 theora_static_d.lib libspeex.lib ogg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libcurl.lib vorbis_static.lib libxml2.lib libxslt.lib iconv.lib pthreadVSE.lib ws2_32.lib winmm.lib ssleay32MT.lib /nologo /subsystem:console /machine:I386 /nodefaultlib:"libc.lib" /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmt.lib"
# SUBTRACT LINK32 /pdb:none
!ELSEIF "$(CFG)" == "icecast2 console - Win32 Debug"
@ -75,7 +75,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 theora_static_d.lib libspeex.lib ogg_static.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libcurl.lib vorbis_static.lib libxml2.lib libxslt.lib iconv.lib pthreadVSE.lib ws2_32.lib winmm.lib ssleay32MT.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /nodefaultlib:"libcmt.lib" /nodefaultlib:"libcmtd.lib" /pdbtype:sept
# ADD LINK32 theora_static_d.lib libspeex.lib ogg.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libcurl.lib vorbis_static.lib libxml2.lib libxslt.lib iconv.lib pthreadVSE.lib ws2_32.lib winmm.lib ssleay32MT.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /nodefaultlib:"libcmt.lib" /nodefaultlib:"libcmtd.lib" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
!ENDIF

View File

@ -1,6 +1,9 @@
#include <config.h>
#define _WIN32_WINNT 0x0400
#include <windows.h>
#include <stdio.h>
#include <direct.h>
extern "C" {
#include "thread/thread.h"
#include "avl/avl.h"
@ -24,19 +27,13 @@ SERVICE_STATUS_HANDLE hStatus;
void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();
extern "C" int mainService(int argc, char **argv);
int InitService()
{
int result = 0;
return(result);
}
void installService (const char *path)
{
if (path) {
char buffer[8096*2] = "\"";
TCHAR buffer [MAX_PATH] = "\"";
int len = GetModuleFileName (NULL, buffer+1, sizeof (buffer)-1);
_snprintf (buffer+len+1, sizeof (buffer)-len, "\" \"%s\"", path);
@ -44,21 +41,7 @@ void installService (const char *path)
SC_HANDLE manager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if (manager == NULL)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
printf ("OpenSCManager: %s\n", (LPCTSTR)lpMsgBuf);
LocalFree( lpMsgBuf );
MessageBox (NULL, "OpenSCManager failed", NULL, MB_SERVICE_NOTIFICATION);
return;
}
@ -79,21 +62,7 @@ void installService (const char *path)
);
if (service == NULL)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
printf ("CreateService: %s\n", (LPCTSTR)lpMsgBuf);
LocalFree( lpMsgBuf );
MessageBox (NULL, "CreateService failed", NULL, MB_SERVICE_NOTIFICATION);
CloseServiceHandle (manager);
return;
}
@ -108,94 +77,67 @@ void removeService()
SC_HANDLE manager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );
if (manager == NULL)
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
printf ("OpenSCManager: %s\n", (LPCTSTR)lpMsgBuf);
LocalFree( lpMsgBuf );
MessageBox (NULL, "OpenSCManager failed", NULL, MB_SERVICE_NOTIFICATION);
return;
}
SC_HANDLE service = OpenService (manager, PACKAGE_STRING, DELETE);
if (service) {
DeleteService(service);
printf ("Service Removed\n");
CloseServiceHandle (service);
printf ("Service deleted, may require reboot to complete removal\n");
}
else
else
printf ("Service not found\n");
CloseServiceHandle (manager);
Sleep (1500);
}
void ControlHandler(DWORD request)
{
switch(request) {
case SERVICE_CONTROL_STOP:
global.running = ICE_HALTING;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
if (ServiceStatus.dwCurrentState != SERVICE_STOP)
{
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus (hStatus, &ServiceStatus);
global.running = ICE_HALTING;
return;
}
case SERVICE_CONTROL_SHUTDOWN:
global.running = ICE_HALTING;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
default:
break;
}
// Report current status
SetServiceStatus (hStatus, &ServiceStatus);
return;
}
void ServiceMain(int argc, char** argv)
{
int error;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(PACKAGE_STRING, (LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0) {
// Registering Control Handler failed
return;
}
// Initialize Service
error = InitService();
if (error) {
// Initialization failed
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);
/* Here we do the work */
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
int argc2 = 3;
char* argv2 [3];
hStatus = RegisterServiceCtrlHandler(PACKAGE_STRING, (LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0) {
// Registering Control Handler failed
MessageBox (NULL, "RegisterServiceCtrlHandler failed", NULL, MB_SERVICE_NOTIFICATION);
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
SetServiceStatus (hStatus, &ServiceStatus);
/* Here we do the work */
int argc2 = 3;
char* argv2 [3];
argv2 [0] = argv[0];
argv2 [1] = "-c";
@ -204,12 +146,10 @@ void ServiceMain(int argc, char** argv)
else
argv2 [2] = argv[1];
int ret = mainService(argc2, (char **)argv2);
ServiceStatus.dwWin32ExitCode = mainService(argc2, (char **)argv2);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(hStatus, &ServiceStatus);
}
@ -232,15 +172,14 @@ void main(int argc, char *argv[])
if (!strcmp(argv[1], "remove") || !strcmp(argv[1], "uninstall"))
{
removeService();
printf ("service removed, may require a reboot\n");
Sleep (1000);
return;
}
if (_chdir(argv[1]) < 0)
{
printf ("unable to change to directory %s\n", argv[1]);
Sleep (1000);
char buffer [256];
_snprintf (buffer, sizeof(buffer), "Unable to change to directory %s", argv[1]);
MessageBox (NULL, buffer, NULL, MB_SERVICE_NOTIFICATION);
return;
}
@ -251,5 +190,6 @@ void main(int argc, char *argv[])
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
if (StartServiceCtrlDispatcher (ServiceTable) == 0)
MessageBox (NULL, "StartServiceCtrlDispatcher failed", NULL, MB_SERVICE_NOTIFICATION);
}

View File

@ -50,7 +50,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 libspeex.lib theora_static_d.lib ogg_static.lib vorbis_static.lib pthreadVSE.lib ssleay32MT.lib libcurl.lib libxml2.lib libxslt.lib ws2_32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /machine:I386 /nodefaultlib:"libcmt.lib" /nodefaultlib:"libcmtd.lib" /nodefaultlib:"libcd.lib"
# ADD LINK32 libspeex.lib theora_static_d.lib ogg.lib vorbis_static.lib pthreadVSE.lib ssleay32MT.lib libcurl.lib libxml2.lib libxslt.lib ws2_32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /pdb:none /machine:I386 /nodefaultlib:"libcmt.lib" /nodefaultlib:"libcmtd.lib" /nodefaultlib:"libcd.lib"
!ELSEIF "$(CFG)" == "icecastService - Win32 Debug"
@ -66,7 +66,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /GX /Zd /Od /I ".." /I "..\src" /D "_DEBUG" /D HAVE_CONFIG_H=1 /D "_CONSOLE" /D "WIN32_SERVICE" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD CPP /nologo /W3 /GX /Zd /Od /I ".." /I "..\src" /D "_DEBUG" /D HAVE_CONFIG_H=1 /D "_CONSOLE" /D "WIN32_SERVICE" /D "WIN32" /D "_MBCS" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
@ -74,7 +74,7 @@ BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
# ADD LINK32 vorbis_static.lib iconv.lib libspeex.lib theora_static_d.lib ogg_static_d.lib vorbis_static_d.lib pthreadVSE.lib ssleay32MT.lib libcurl.lib libxml2.lib libxslt.lib ws2_32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /nodefaultlib:"libcd.lib" /nodefaultlib:"libcmt.lib" /out:"service_debug/icecast2service.exe" /pdbtype:sept
# ADD LINK32 vorbis_static.lib iconv.lib libspeex.lib theora_static_d.lib ogg.lib vorbis_static_d.lib pthreadVSE.lib ssleay32MT.lib libcurl.lib libxml2.lib libxslt.lib ws2_32.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /nodefaultlib:"libcmtd" /nodefaultlib:"libcmt" /force /out:"service_debug/icecast2service.exe" /pdbtype:sept
# SUBTRACT LINK32 /pdb:none
!ENDIF