// File: /workspace/github_cpp_makefile_star2_O2/cybozu[P]yrmcds/src/main.cpp
// Function: main
int main(int argc, char** argv) {
    std::vector<std::string> args;
    for( int i = 1; i < argc; ++i )
        args.push_back(argv[i]);

    if( std::find(args.begin(), args.end(), "-h") != args.end() ) {
        print_help();
        return 0;
    }

    if( std::find(args.begin(), args.end(), "-v") != args.end() ) {
        print_version();
        return 0;
    }

    using cybozu::logger;

    seed_siphash();

    try {
        if( ! load_config(args) )
            return 1;

        if( yrmcds::g_config.lock_memory() ) {
            if( ::mlockall( MCL_CURRENT | MCL_FUTURE ) == -1 )
                cybozu::throw_unix_error(errno, "mlockall");
        }

        // first, set group id (as root)
        const std::string& g = yrmcds::g_config.group();
        if( ! g.empty() ) {
            if( getuid() != 0 ) {
                std::cerr << "Ignored group configuration." << std::endl;
            } else {
                struct group* grp = getgrnam(g.c_str());
                if( grp == nullptr ) {
                    std::cerr << "No such group: " << g << std::endl;
                    return 1;
                }
                if( setgid(grp->gr_gid) == -1 ) {
                    std::cerr << "Failed to set group id!" << std::endl;
                    return 1;
                }
            }
        }

        const std::string& u = yrmcds::g_config.user();
        if( ! u.empty() ) {
            if( getuid() != 0 ) {
                std::cerr << "Ignored user configuration." << std::endl;
            } else {
                struct passwd* p = getpwnam(u.c_str());
                if( p == nullptr ) {
                    std::cerr << "No such user: " << u << std::endl;
                    return 1;
                }
                if( setuid(p->pw_uid) == -1 ) {
                    std::cerr << "Failed to set user id!" << std::endl;
                    return 1;
                }
            }
        }

        // make it core dumpable
        if( prctl(PR_SET_DUMPABLE, 1) == -1 ) {
            std::cerr << "WARNING: failed to enable core dump!" << std::endl;
        }

        // setup logger
        logger::set_threshold(yrmcds::g_config.threshold());
        if( ! yrmcds::g_config.logfile().empty() )
            logger::instance().open(yrmcds::g_config.logfile());

        yrmcds::server().serve();

    } catch( const std::system_error& e ) {
        cybozu::demangler t( typeid(e).name() );
        logger::error() << "[" << t.name() << "] (" << e.code() << ") "
                        << e.what();
        std::cerr << "Exception [" << t.name() << "] (" << e.code() << ") "
                  << e.what() << std::endl;
        return 1;

    } catch( const std::exception& e ) {
        cybozu::demangler t( typeid(e).name() );
        logger::error() << "[" << t.name() << "] " << e.what();
        std::cerr << "Exception [" << t.name() << "] " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x13e8, %rsp           # imm = 0x13E8
movq %rsi, %rbx
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %r14
movaps %xmm0, (%r14)
andq $0x0, 0x10(%r14)
movslq %edi, %r13
pushq $0x1
popq %rbp
leaq 0x60(%rsp), %r15
leaq 0x40(%rsp), %r12
cmpq %r13, %rbp
jge 0x7dfd
movq (%rbx,%rbp,8), %rsi
movq %r15, %rdi
movq %r12, %rdx
callq 0x84d8
movq %r14, %rdi
movq %r15, %rsi
callq 0x8f82
movq %r15, %rdi
callq 0x71d0
incq %rbp
jmp 0x7dd1
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rsi
leaq 0x1e1f6(%rip), %rdx     # 0x26004
callq 0x9149
movq 0x28(%rsp), %rsi
cmpq %rsi, %rax
je 0x7e3d
movq 0x3316c(%rip), %rdi     # 0x3af90
leaq 0x1e2aa(%rip), %rsi     # 0x260d5
callq 0x7500
movq %rax, %rdi
callq 0x7220
jmp 0x80bd
movq 0x20(%rsp), %rdi
leaq 0x1e1be(%rip), %rdx     # 0x26007
callq 0x9149
cmpq 0x28(%rsp), %rax
je 0x7e8c
movq 0x33134(%rip), %rdi     # 0x3af90
leaq 0x1e3ad(%rip), %rsi     # 0x26210
callq 0x7500
movq %rax, %rdi
callq 0x7220
movq %rax, %rdi
callq 0x7220
leaq 0x336f1(%rip), %rsi     # 0x3b570
movq %rax, %rdi
callq 0x7500
jmp 0x80bd
leaq 0x60(%rsp), %rdi
callq 0x87a2
leaq 0x10(%rsp), %rdi
andq $0x0, (%rdi)
orq $-0x1, 0x8(%rdi)
leaq 0x60(%rsp), %rsi
callq 0x87f8
movq %rax, 0x40(%rsp)
leaq 0x10(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x87f8
leaq 0x40(%rsp), %rdi
movq %rax, 0x8(%rdi)
callq 0xb030
leaq 0x60(%rsp), %rdi
callq 0x8800
movq 0x20(%rsp), %rdi
movq 0x28(%rsp), %rsi
leaq 0x1e22c(%rip), %rdx     # 0x26117
callq 0x88f8
movq 0x28(%rsp), %rcx
cmpq %rcx, %rax
je 0x7f18
addq $0x20, %rax
cmpq %rcx, %rax
je 0x80dd
leaq 0x33cb2(%rip), %rdi     # 0x3bbc0
movq %rax, %rsi
callq 0xba4a
jmp 0x7f5c
leaq 0x1e1fb(%rip), %rsi     # 0x2611a
leaq 0x40(%rsp), %rdi
leaq 0xf(%rsp), %rdx
callq 0x84d8
leaq 0x40(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x9234
testb %al, %al
je 0x7f52
leaq 0x33c78(%rip), %rdi     # 0x3bbc0
leaq 0x40(%rsp), %rsi
callq 0xba4a
leaq 0x40(%rsp), %rdi
callq 0x71d0
leaq 0x33c5d(%rip), %rbx     # 0x3bbc0
cmpb $0x1, 0x100(%rbx)
jne 0x7fc5
movq 0xd8(%rbx), %rax
cmpq 0xe0(%rbx), %rax
jbe 0x7fc5
movq 0x33065(%rip), %rdi     # 0x3afe8
leaq 0x1e1ab(%rip), %rsi     # 0x26135
callq 0x7500
movq %rax, %rdi
callq 0x7220
leaq 0x1e1a1(%rip), %rsi     # 0x2613f
movq %rax, %rdi
callq 0x7500
movq %rax, %rdi
callq 0x7220
leaq 0x1e1d1(%rip), %rsi     # 0x26186
movq %rax, %rdi
callq 0x7500
movq %rax, %rdi
callq 0x7220
cmpb $0x1, 0x101(%rbx)
jne 0x7fdf
pushq $0x3
popq %rdi
callq 0x7960
cmpl $-0x1, %eax
je 0x81cb
cmpq $0x0, 0x90(%rbx)
je 0x8011
callq 0x7250
testl %eax, %eax
je 0x80fd
movq 0x32feb(%rip), %rdi     # 0x3afe8
leaq 0x1e00f(%rip), %rsi     # 0x26013
callq 0x7500
movq %rax, %rdi
callq 0x7220
cmpq $0x0, 0x70(%rbx)
je 0x8040
callq 0x7250
testl %eax, %eax
je 0x8134
movq 0x32fbc(%rip), %rdi     # 0x3afe8
leaq 0x1e025(%rip), %rsi     # 0x26058
callq 0x7500
movq %rax, %rdi
callq 0x7220
pushq $0x4
popq %rdi
pushq $0x1
popq %rsi
xorl %eax, %eax
callq 0x7670
cmpl $-0x1, %eax
jne 0x806d
movq 0x32f8f(%rip), %rdi     # 0x3afe8
leaq 0x1e03a(%rip), %rsi     # 0x2609a
callq 0x7500
movq %rax, %rdi
callq 0x7220
movl 0xa8(%rbx), %eax
leaq 0x33a1e(%rip), %rcx     # 0x3ba98
movl %eax, (%rcx)
cmpq $0x0, 0xb8(%rbx)
je 0x809f
callq 0x856a
movl $0xb0, %esi
addq 0x32ec9(%rip), %rsi     # 0x3af60
movq %rax, %rdi
callq 0x85da
leaq 0x60(%rsp), %rdi
callq 0xe150
leaq 0x60(%rsp), %rdi
callq 0xe2f6
leaq 0x60(%rsp), %rdi
callq 0x8628
xorl %ebx, %ebx
leaq 0x20(%rsp), %rdi
callq 0x8780
movl %ebx, %eax
addq $0x13e8, %rsp           # imm = 0x13E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x32f04(%rip), %rdi     # 0x3afe8
leaq 0x1e015(%rip), %rsi     # 0x26100
callq 0x7500
movq %rax, %rdi
callq 0x7220
jmp 0x81c3
movq 0x88(%rbx), %rdi
callq 0x74e0
testq %rax, %rax
je 0x8168
movl 0x10(%rax), %edi
callq 0x79a0
cmpl $-0x1, %eax
jne 0x8011
movq 0x32ec2(%rip), %rdi     # 0x3afe8
leaq 0x1df13(%rip), %rsi     # 0x26040
callq 0x7500
jmp 0x818f
movq 0x68(%rbx), %rdi
callq 0x7400
testq %rax, %rax
je 0x8199
movl 0x10(%rax), %edi
callq 0x7a30
cmpl $-0x1, %eax
jne 0x8040
movq 0x32e8e(%rip), %rdi     # 0x3afe8
leaq 0x1df22(%rip), %rsi     # 0x26083
callq 0x7500
jmp 0x81bb
movq 0x32e79(%rip), %rdi     # 0x3afe8
leaq 0x1deba(%rip), %rsi     # 0x26030
callq 0x7500
movl $0x88, %esi
addq 0x32dd9(%rip), %rsi     # 0x3af60
movq %rax, %rdi
callq 0x7470
movq %rax, %rdi
callq 0x7220
jmp 0x81c3
movq 0x32e48(%rip), %rdi     # 0x3afe8
leaq 0x1decd(%rip), %rsi     # 0x26074
callq 0x7500
addq $0x68, %rbx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x7470
movq %rax, %rdi
callq 0x7220
pushq $0x1
popq %rbx
jmp 0x80bf
callq 0x7030
movl (%rax), %edi
leaq 0x1de31(%rip), %rsi     # 0x2600a
callq 0x8513
jmp 0x8223
jmp 0x8223
movq %rdx, %r14
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x71d0
jmp 0x8229
movq %rdx, %r14
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x8628
jmp 0x8229
jmp 0x8223
jmp 0x8223
jmp 0x8223
jmp 0x84c2
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x8800
jmp 0x84c5
movq %rdx, %r14
movq %rax, %rbx
cmpl $0x2, %r14d
jne 0x8356
movq %rbx, %rdi
callq 0x71a0
movq %rax, %rbx
movq (%rax), %rax
movq -0x8(%rax), %rax
movq 0x8(%rax), %rax
xorl %esi, %esi
cmpb $0x2a, (%rax)
sete %sil
addq %rax, %rsi
leaq 0x60(%rsp), %rdi
callq 0xb294
leaq 0x10(%rsp), %rdi
callq 0x865e
leaq 0x1de5c(%rip), %rsi     # 0x260cc
leaq 0x10(%rsp), %rdi
callq 0x8682
leaq 0x60(%rsp), %rsi
movq %rax, %rdi
callq 0x869a
leaq 0x1de40(%rip), %rsi     # 0x260ce
movq %rax, %rdi
callq 0x8716
leaq 0x10(%rbx), %r14
movq %rax, %rdi
movq %r14, %rsi
callq 0x872e
leaq 0x1de26(%rip), %rsi     # 0x260d2
movq %rax, %rdi
callq 0x86b2
movq %rax, %r15
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
leaq 0x38(%rsp), %rsi
movq %rax, (%rsi)
movq %r15, %rdi
callq 0x86ca
leaq 0x10(%rsp), %rdi
callq 0x86e4
movq 0x32d07(%rip), %rdi     # 0x3afe8
leaq 0x1ddda(%rip), %rsi     # 0x260c2
callq 0x7500
leaq 0x60(%rsp), %rsi
movq %rax, %rdi
callq 0x7470
leaq 0x1ddcd(%rip), %rsi     # 0x260ce
movq %rax, %rdi
callq 0x7500
movq %rax, %rdi
movq %r14, %rsi
callq 0x8745
leaq 0x1ddb7(%rip), %rsi     # 0x260d2
movq %rax, %rdi
callq 0x7500
movq %rax, %r14
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x7500
movq %rax, %rdi
callq 0x7220
leaq 0x60(%rsp), %rdi
callq 0x71d0
callq 0x78e0
jmp 0x81c3
cmpl $0x1, %r14d
jne 0x84c5
movq %rbx, %rdi
callq 0x71a0
movq %rax, %rbx
movq (%rax), %rax
movq -0x8(%rax), %rax
movq 0x8(%rax), %rax
xorl %esi, %esi
cmpb $0x2a, (%rax)
sete %sil
addq %rax, %rsi
leaq 0x60(%rsp), %rdi
callq 0xb294
leaq 0x10(%rsp), %rdi
callq 0x865e
leaq 0x1dd2f(%rip), %rsi     # 0x260cc
leaq 0x10(%rsp), %rdi
callq 0x8682
leaq 0x60(%rsp), %rsi
movq %rax, %rdi
callq 0x869a
leaq 0x1dd04(%rip), %rsi     # 0x260bf
movq %rax, %rdi
callq 0x86b2
movq %rax, %r14
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
leaq 0x38(%rsp), %rsi
movq %rax, (%rsi)
movq %r14, %rdi
callq 0x86ca
leaq 0x10(%rsp), %rdi
callq 0x86e4
movq 0x32bf8(%rip), %rdi     # 0x3afe8
leaq 0x1dccb(%rip), %rsi     # 0x260c2
callq 0x7500
leaq 0x60(%rsp), %rsi
movq %rax, %rdi
callq 0x7470
leaq 0x1dcaf(%rip), %rsi     # 0x260bf
movq %rax, %rdi
callq 0x7500
movq %rax, %r14
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
movq %r14, %rdi
movq %rax, %rsi
callq 0x7500
movq %rax, %rdi
callq 0x7220
leaq 0x60(%rsp), %rdi
callq 0x71d0
callq 0x78e0
jmp 0x81c3
jmp 0x84c2
jmp 0x8461
jmp 0x8470
movq %rax, %rbx
jmp 0x847d
jmp 0x84c2
jmp 0x8484
jmp 0x8493
movq %rax, %rbx
jmp 0x84a0
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x86e4
jmp 0x8473
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x71d0
callq 0x78e0
jmp 0x84c5
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x86e4
jmp 0x8496
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x71d0
callq 0x78e0
jmp 0x84c5
movq %rax, %rdi
callq 0x870a
jmp 0x84c2
jmp 0x84c2
movq %rax, %rbx
leaq 0x60(%rsp), %rdi
callq 0x71d0
jmp 0x84c5
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x8780
movq %rbx, %rdi
callq 0x7990
nop