// File: merelin[P]mediasmartserverd/src/mediasmartserverd.cpp
// Function: main
int main( int argc, char* argv[] ) try {
	int brightness = -1;
	int light_show = 0;
	int mount_usb = -1;
	bool run_as_daemon = false;
	bool xmas = false;
	bool run_update_monitor = false;
	
	// long command line arguments
	const struct option long_opts[] = {
		{ "brightness",     required_argument, 0, 'b' },
		{ "daemon",         no_argument,       0, 'D' },
		{ "activity",       no_argument,       0, 'a' },
		{ "debug",          no_argument,       0, 'd' },
		{ "help",           no_argument,       0, 'h' },
		{ "light-show",     required_argument, 0, 'S' },
		{ "update-monitor", no_argument,       0, 'u' },
		{ "usb",            required_argument, 0, 'U' },
		{ "verbose",        no_argument,       0, 'v' },
		{ "version",        no_argument,       0, 'V' },
		{ "xmas",           no_argument,       0, 'X' },
		{ 0, 0, 0, 0 },
	};
	
	// pass command line arguments
	while ( true ) {
		const int c = getopt_long( argc, argv, "aDuvV", long_opts, 0 );
		if ( -1 == c ) break;
		
		switch ( c ) {
		case 'b': // brightness
			if ( optarg ) brightness = atoi( optarg );
			break;
		case 'd': // debug
			++debug;
			break;
		case 'D': // run as a daemon (background)
			run_as_daemon = true;
			break;
		case 'a': // run as a daemon (background)
			activity = true;
			break;
		case 'h': // help!
			return show_help( );
		case 'S': // light-show
			if ( optarg ) light_show = atoi( optarg );
			break;
		case 'u': //Use system LED as update notification light.
			run_update_monitor = true;
			break;
		case 'U': // mount/unmount USB device
			if ( optarg ) mount_usb = atoi( optarg );
			break;
		case 'v': // verbose, more verbose, even more verbose
			++verbose;
			break;
		case 'V': // our version
			return show_version( );
		case 'X': // light all the LEDs up like a xmas tree
			xmas = true;
			break;
		case '?': // no idea
			cout << "Try `" << argv[0] << " --help' for more information.\n";
			return 1;
		default:
			cout << "+++ '" << (char)c << "'\n";
		}
	}
	
	
	// register signal handlers
	init_signals( );
	
	// find led control interface
	LedControlPtr leds = get_led_interface( );
	if ( !leds ) throw std::runtime_error( "Failed to find an LED control interface" );
	
	// drop root priviledges
	drop_priviledges( );
	
	// mount USB?
	if ( mount_usb >= 0 ) {
		if ( debug || verbose > 0 ) cout << ( (mount_usb) ? "M" : "Unm" ) << "ounting USB device\n";
		leds->MountUsb( !!mount_usb );
	}
	
	// run as a daemon?
	if ( run_as_daemon && daemon( 0, 0 ) ) throw ErrnoException( "daemon" );
	
	cout << "Found: " << leds->Desc( ) << '\n';
	
	// disable annoying blinking guy // changed to disabling completely
	leds->SetSystemLed( LED_RED, false );
	leds->SetSystemLed( LED_BLUE, false );
	
	//
	if ( brightness >= 0 ) leds->SetBrightness( brightness );
	
	// clear out LEDs
	leds->Set( LED_BLUE | LED_RED, 0, xmas );
	leds->Set( LED_BLUE | LED_RED, 1, xmas );
	leds->Set( LED_BLUE | LED_RED, 2, xmas );
	leds->Set( LED_BLUE | LED_RED, 3, xmas );
	if ( xmas ) return 0;
	
	if ( light_show > 0 ) return run_light_show( leds, light_show );
	
	// initialise update monitor
	UpdateMonitor update_monitor(leds);
	if (run_update_monitor) update_monitor.Start();
	
	// initialise device monitor
	DeviceMonitor device_monitor;
	device_monitor.Init( leds );
	
	// begin monitoring
	device_monitor.Main( );
	
	if (run_update_monitor) update_monitor.Stop();
	
	// re-enable annoying blinking // leaving it disabled
	//leds->SetSystemLed( LED_BLUE, LED_BLINK );
    for( int i = 0; i < device_monitor.numDisks(); ++i )
    {
        int led_idx = device_monitor.ledIndex(i);
        leds->Set( LED_RED, led_idx, false );
        leds->Set( LED_BLUE, led_idx, false );
    }
	
	return 0;
	
} catch ( std::exception& e ) {
	std::cerr << e.what() << '\n';
	if ( 0 != getuid() ) cout << "Try running as root\n";
	
	return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x490, %rsp            # imm = 0x490
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0xffffffff, -0x14(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x18(%rbp)
movl $0xffffffff, -0x1c(%rbp) # imm = 0xFFFFFFFF
movb $0x0, -0x1d(%rbp)
movb $0x0, -0x1e(%rbp)
movb $0x0, -0x1f(%rbp)
leaq -0x1a0(%rbp), %rdi
leaq 0xd0a8(%rip), %rsi      # 0x177a0
movl $0x180, %edx            # imm = 0x180
callq 0x52f0
jmp 0xa704
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq -0x1a0(%rbp), %rcx
leaq 0x8439(%rip), %rdx      # 0x12b52
xorl %eax, %eax
movl %eax, %r8d
callq 0x5660
movl %eax, -0x1a4(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl -0x1a4(%rbp), %eax
jne 0xa73b
jmp 0xa922
movl -0x1a4(%rbp), %eax
addl $-0x3f, %eax
movl %eax, %ecx
movq %rcx, -0x3b0(%rbp)
subl $0x37, %eax
ja 0xa8ce
movq -0x3b0(%rbp), %rax
leaq 0x7ea0(%rip), %rcx      # 0x12604
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0xd81c(%rip), %rax      # 0x17f90
cmpq $0x0, (%rax)
je 0xa78c
movq 0xd80f(%rip), %rax      # 0x17f90
movq (%rax), %rdi
callq 0x5610
movl %eax, -0x14(%rbp)
jmp 0xa91d
movl 0xdc81(%rip), %eax      # 0x18418
addl $0x1, %eax
movl %eax, 0xdc78(%rip)      # 0x18418
jmp 0xa91d
movb $0x1, -0x1d(%rbp)
jmp 0xa91d
movb $0x1, 0xdc6b(%rip)      # 0x18420
jmp 0xa91d
callq 0xa020
movl %eax, -0x3b4(%rbp)
jmp 0xa7c7
movl -0x3b4(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xb043
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
jmp 0xaf8b
movq 0xd79d(%rip), %rax      # 0x17f90
cmpq $0x0, (%rax)
je 0xa80b
movq 0xd790(%rip), %rax      # 0x17f90
movq (%rax), %rdi
callq 0x5610
movl %eax, -0x18(%rbp)
jmp 0xa91d
movb $0x1, -0x1f(%rbp)
jmp 0xa91d
movq 0xd770(%rip), %rax      # 0x17f90
cmpq $0x0, (%rax)
je 0xa838
movq 0xd763(%rip), %rax      # 0x17f90
movq (%rax), %rdi
callq 0x5610
movl %eax, -0x1c(%rbp)
jmp 0xa91d
movl 0xdbd9(%rip), %eax      # 0x1841c
addl $0x1, %eax
movl %eax, 0xdbd0(%rip)      # 0x1841c
jmp 0xa91d
callq 0xa0c0
movl %eax, -0x3b8(%rbp)
jmp 0xa85e
movl -0x3b8(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0xb043
movb $0x1, -0x1e(%rbp)
jmp 0xa91d
movq 0xd734(%rip), %rdi      # 0x17fb0
leaq 0x82d5(%rip), %rsi      # 0x12b58
callq 0x5380
movq %rax, -0x3c0(%rbp)
jmp 0xa891
movq -0x3c0(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x5380
movq %rax, -0x3c8(%rbp)
jmp 0xa8ad
movq -0x3c8(%rbp), %rdi
leaq 0x82a3(%rip), %rsi      # 0x12b5e
callq 0x5380
jmp 0xa8c2
movl $0x1, -0x4(%rbp)
jmp 0xb043
movq 0xd6db(%rip), %rdi      # 0x17fb0
leaq 0x82a2(%rip), %rsi      # 0x12b7e
callq 0x5380
movq %rax, -0x3d0(%rbp)
jmp 0xa8ea
movq -0x3d0(%rbp), %rdi
movsbl -0x1a4(%rbp), %esi
callq 0x5470
movq %rax, -0x3d8(%rbp)
jmp 0xa906
movq -0x3d8(%rbp), %rdi
leaq 0x8270(%rip), %rsi      # 0x12b84
callq 0x5380
jmp 0xa91b
jmp 0xa91d
jmp 0xa702
callq 0x92f0
jmp 0xa929
leaq -0x1c8(%rbp), %rdi
callq 0x9990
jmp 0xa937
leaq -0x1c8(%rbp), %rdi
callq 0x7850
movq %rax, -0x3e0(%rbp)
jmp 0xa94c
movq -0x3e0(%rbp), %rax
cmpq $-0x1, %rax
jne 0xa9d7
movl $0x10, %edi
callq 0x51b0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x3e8(%rbp)
leaq 0x8210(%rip), %rsi      # 0x12b87
callq 0x5140
jmp 0xa97e
movq -0x3e8(%rbp), %rdi
movq 0xd65c(%rip), %rsi      # 0x17fe8
movq 0xd60d(%rip), %rdx      # 0x17fa0
callq 0x5680
jmp 0xb063
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
jmp 0xaf7f
movq -0x3e8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
callq 0x52a0
jmp 0xaf7f
callq 0x9550
jmp 0xa9de
cmpl $0x0, -0x1c(%rbp)
jl 0xaa71
cmpl $0x0, 0xda29(%rip)      # 0x18418
jne 0xa9fa
cmpl $0x0, 0xda24(%rip)      # 0x1841c
jle 0xaa3d
movl -0x1c(%rbp), %eax
testl %eax, %eax
leaq 0x81a9(%rip), %rax      # 0x12baf
leaq 0x81a4(%rip), %rsi      # 0x12bb1
cmovneq %rax, %rsi
movq 0xd598(%rip), %rdi      # 0x17fb0
callq 0x5380
movq %rax, -0x3f0(%rbp)
jmp 0xaa26
movq -0x3f0(%rbp), %rdi
leaq 0x8181(%rip), %rsi      # 0x12bb5
callq 0x5380
jmp 0xaa3b
jmp 0xaa3d
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x3f8(%rbp)
jmp 0xaa52
movq -0x3f8(%rbp), %rdi
movl -0x1c(%rbp), %eax
testl %eax, %eax
setne %cl
movq (%rdi), %rax
movq 0x20(%rax), %rax
movzbl %cl, %esi
callq *%rax
jmp 0xaa6f
jmp 0xaa71
testb $0x1, -0x1d(%rbp)
je 0xab70
xorl %esi, %esi
movl %esi, %edi
callq 0x54a0
cmpl $0x0, %eax
je 0xab70
movb $0x1, -0x1ea(%rbp)
movl $0x10, %edi
callq 0x51b0
movq %rax, -0x408(%rbp)
leaq -0x1e9(%rbp), %rdi
movq %rdi, -0x400(%rbp)
callq 0x56c0
movq -0x400(%rbp), %rdx
leaq 0x803e(%rip), %rsi      # 0x12b04
leaq -0x1e8(%rbp), %rdi
callq 0x7600
jmp 0xaad4
callq 0x5030
movq -0x408(%rbp), %rdi
movl (%rax), %edx
leaq -0x1e8(%rbp), %rsi
callq 0x76b0
jmp 0xaaf0
movq -0x408(%rbp), %rdi
movb $0x0, -0x1ea(%rbp)
leaq 0xcafb(%rip), %rsi      # 0x17600
leaq -0x338c(%rip), %rdx     # 0x7780
callq 0x5680
jmp 0xb063
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
jmp 0xab48
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0x5230
leaq -0x1e9(%rbp), %rdi
callq 0x53f0
testb $0x1, -0x1ea(%rbp)
jne 0xab5f
jmp 0xab6b
movq -0x408(%rbp), %rdi
callq 0x52a0
jmp 0xaf7f
movq 0xd439(%rip), %rdi      # 0x17fb0
leaq 0x804b(%rip), %rsi      # 0x12bc9
callq 0x5380
movq %rax, -0x410(%rbp)
jmp 0xab8c
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x418(%rbp)
jmp 0xaba1
movq -0x418(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, -0x420(%rbp)
jmp 0xabba
movq -0x420(%rbp), %rsi
movq -0x410(%rbp), %rdi
callq 0x5380
movq %rax, -0x428(%rbp)
jmp 0xabd6
movq -0x428(%rbp), %rdi
movl $0xa, %esi
callq 0x5470
jmp 0xabe9
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x430(%rbp)
jmp 0xabfe
movq -0x430(%rbp), %rdi
movq (%rdi), %rax
movq 0x40(%rax), %rax
movl $0x2, %esi
xorl %edx, %edx
callq *%rax
jmp 0xac17
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x438(%rbp)
jmp 0xac2c
movq -0x438(%rbp), %rdi
movq (%rdi), %rax
movq 0x40(%rax), %rax
movl $0x1, %esi
xorl %edx, %edx
callq *%rax
jmp 0xac45
cmpl $0x0, -0x14(%rbp)
jl 0xac77
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x440(%rbp)
jmp 0xac60
movq -0x440(%rbp), %rdi
movl -0x14(%rbp), %esi
movq (%rdi), %rax
movq 0x30(%rax), %rax
callq *%rax
jmp 0xac75
jmp 0xac77
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x448(%rbp)
jmp 0xac8c
movq -0x448(%rbp), %rdi
movq (%rdi), %rax
movq 0x28(%rax), %rax
movzbl -0x1e(%rbp), %ecx
andl $0x1, %ecx
xorl %edx, %edx
movl $0x3, %esi
callq *%rax
jmp 0xacac
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x450(%rbp)
jmp 0xacc1
movq -0x450(%rbp), %rdi
movq (%rdi), %rax
movq 0x28(%rax), %rax
movzbl -0x1e(%rbp), %ecx
andl $0x1, %ecx
movl $0x3, %esi
movl $0x1, %edx
callq *%rax
jmp 0xace4
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x458(%rbp)
jmp 0xacf9
movq -0x458(%rbp), %rdi
movq (%rdi), %rax
movq 0x28(%rax), %rax
movzbl -0x1e(%rbp), %ecx
andl $0x1, %ecx
movl $0x3, %esi
movl $0x2, %edx
callq *%rax
jmp 0xad1c
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x460(%rbp)
jmp 0xad31
movq -0x460(%rbp), %rdi
movq (%rdi), %rax
movq 0x28(%rax), %rax
movzbl -0x1e(%rbp), %ecx
andl $0x1, %ecx
movl $0x3, %esi
movl $0x3, %edx
callq *%rax
jmp 0xad54
testb $0x1, -0x1e(%rbp)
je 0xad70
movl $0x0, -0x4(%rbp)
movl $0x1, -0x1f0(%rbp)
jmp 0xaf6e
cmpl $0x0, -0x18(%rbp)
jle 0xada5
movl -0x18(%rbp), %esi
leaq -0x1c8(%rbp), %rdi
callq 0xa0e0
movl %eax, -0x464(%rbp)
jmp 0xad8d
movl -0x464(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x1f0(%rbp)
jmp 0xaf6e
leaq -0x1f8(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x85a0
jmp 0xadba
testb $0x1, -0x1f(%rbp)
je 0xade7
leaq -0x1f8(%rbp), %rdi
callq 0x8840
jmp 0xadce
jmp 0xade7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
jmp 0xaf60
leaq -0x398(%rbp), %rdi
callq 0x5990
jmp 0xadf5
leaq -0x398(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x5ab0
jmp 0xae0a
leaq -0x398(%rbp), %rdi
callq 0x6470
jmp 0xae18
testb $0x1, -0x1f(%rbp)
je 0xae51
leaq -0x1f8(%rbp), %rdi
callq 0x8610
jmp 0xae2c
jmp 0xae51
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
leaq -0x398(%rbp), %rdi
callq 0x5a10
jmp 0xaf60
movl $0x0, -0x39c(%rbp)
movl -0x39c(%rbp), %eax
movl %eax, -0x46c(%rbp)
leaq -0x398(%rbp), %rdi
callq 0xb580
movl %eax, -0x468(%rbp)
jmp 0xae7b
movl -0x46c(%rbp), %eax
movl -0x468(%rbp), %ecx
cmpl %ecx, %eax
jge 0xaf35
movl -0x39c(%rbp), %esi
leaq -0x398(%rbp), %rdi
callq 0x7830
movl %eax, -0x470(%rbp)
jmp 0xaea9
movl -0x470(%rbp), %eax
movl %eax, -0x3a0(%rbp)
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x478(%rbp)
jmp 0xaeca
movq -0x478(%rbp), %rdi
movslq -0x3a0(%rbp), %rdx
movq (%rdi), %rax
movq 0x28(%rax), %rax
movl $0x2, %esi
xorl %ecx, %ecx
callq *%rax
jmp 0xaeea
leaq -0x1c8(%rbp), %rdi
callq 0x7880
movq %rax, -0x480(%rbp)
jmp 0xaeff
movq -0x480(%rbp), %rdi
movslq -0x3a0(%rbp), %rdx
movq (%rdi), %rax
movq 0x28(%rax), %rax
movl $0x1, %esi
xorl %ecx, %ecx
callq *%rax
jmp 0xaf1f
jmp 0xaf21
movl -0x39c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x39c(%rbp)
jmp 0xae5b
movl $0x0, -0x4(%rbp)
movl $0x1, -0x1f0(%rbp)
leaq -0x398(%rbp), %rdi
callq 0x5a10
leaq -0x1f8(%rbp), %rdi
callq 0x85d0
jmp 0xaf6e
leaq -0x1f8(%rbp), %rdi
callq 0x85d0
jmp 0xaf7f
leaq -0x1c8(%rbp), %rdi
callq 0x75b0
jmp 0xb043
leaq -0x1c8(%rbp), %rdi
callq 0x75b0
movl -0x1b4(%rbp), %eax
movl $0x1, %ecx
cmpl %ecx, %eax
jne 0xb04f
movq -0x1b0(%rbp), %rdi
callq 0x5160
movq %rax, -0x3a8(%rbp)
movq -0x3a8(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
movq %rax, %rsi
movq 0xd015(%rip), %rdi      # 0x17fe0
callq 0x5380
movq %rax, -0x488(%rbp)
jmp 0xafd9
movq -0x488(%rbp), %rdi
movl $0xa, %esi
callq 0x5470
jmp 0xafec
callq 0x51c0
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
je 0xb029
movq 0xcfb0(%rip), %rdi      # 0x17fb0
leaq 0x7bca(%rip), %rsi      # 0x12bd1
callq 0x5380
jmp 0xb00e
jmp 0xb029
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x1b0(%rbp)
movl %eax, -0x1b4(%rbp)
callq 0x5640
jmp 0xb041
movl $0x1, -0x4(%rbp)
movl $0x1, -0x1f0(%rbp)
callq 0x5640
jmp 0xb043
jmp 0xb04f
movl -0x4(%rbp), %eax
addq $0x490, %rsp            # imm = 0x490
popq %rbp
retq
movq -0x1b0(%rbp), %rdi
callq 0x56b0
movq %rax, %rdi
callq 0x75a0
nopw %cs:(%rax,%rax)