// File: /workspace/github_c_makefile_star2_O2/hansvanstaveren[P]BigDeal/main.c
// Function: main
int
main (int argc, char *argv[])
{
	int i;
	char message[MESSLEN];
	byte *hashcode;
	unsigned long seqno;
	dl_num dnumber;
	char filename[MESSLEN] = "";
	int c;
	char *formats = 0;
	char *ownerp;
#ifdef BIGDEALX
	int only_arg_entropy = 0;
	char *hashstr = 0;
	char *wizard = 0;
	int dangerous_code_used = 0;
#else
#define only_arg_entropy 0
#define wizard 0
#endif

	/*
	 * Some systems (looking at you MinGW) suck at unbuffering stdout
	 */

	setbuf(stdout, NULL);

	/*
	 * Say hi to operator
	 */
	printf("Big Deal version %d.%d%s%s\n\n",
		VERSION_MAJOR, VERSION_MINOR, VERSION_PAREN, VERSION_COMMENT);

#ifdef BIGDEALX
	flog = fopen(LOGNAME, "a");
#endif
	os_start();
	collect_start();

	while ((c = getopt(argc, argv, OPTION_STRING)) != -1) {
		switch(c) {
#ifdef BIGDEALX
		case 'E':
			read_entropy_from_file(optarg);
			dangerous_code_used = 1;
			break;
		case 'e':
			collect_more((byte *) optarg, strlen(optarg), 4*strlen(optarg));
			dangerous_code_used = 1;
			break;
		case 'h':
			hashstr = optarg;
			/* fall through */
		case 'o':
			only_arg_entropy = 1;
			dangerous_code_used = 1;
			break;
		case 'W': /* Wizard mode */
			only_arg_entropy = 1;
			wizard = optarg;
			break;
#endif
		case 'p':
			strncpy(filename, optarg, MESSLEN-1);
			break;
		case 'f':
			formats = optarg;
			break;
		case 'n':
			setboards(optarg);
			break;
		case 'R':
			read_init_file(os_init_file_name(), 0);
			write_init_file(os_init_file_name());
			exit(0);
		case '?':
			fprintf(stderr, "Usage: %s %s\n", argv[0], USAGE_STRING);
			exit(-1);
		}
	}

	if (!only_arg_entropy)
		os_collect();

	read_init_file(os_init_file_name(), 1);
	binomial_start();
	init_goedel();
	/*
	 * Read number of boards to generate
	 */
	while(parameters.pp_nboards <= 0 || parameters.pp_nboards > MAXDEALS) {
		/*
		 * If we are asked to generate more than 100 boards refuse
		 * We only have 160 bits entropy, and no one plays sessions
		 * of more than 100 boards anyhow
		 */
		if (parameters.pp_nboards > MAXDEALS) {
			parameters.pp_nboards = 0;
			printf("The maximum is %d, run program again for more\n",
				MAXDEALS);
		}
		printf("Number of boards to deal(1-%d): ", MAXDEALS);
		(void) readline(stdin, message, MESSLEN);
		setboards(message);
		/*
		 * Collect the string, no entropy assumed
		 */
		if (!only_arg_entropy)
			collect_more( (byte*)message, strlen(message), 0);
	}

	/*
	 * Read part of filename before the .
	 */
	while(!legal_filename_prefix(filename)) { 
		printf("Output filename(without suffix): ");
		(void) readline(stdin, message, MESSLEN);
		/*
		 * Collect the string, 5 bits entropy assumed
		 */
		if (!only_arg_entropy)
			collect_more( (byte*)message, strlen(message), 5);
		strcpy(filename,message);
	}

	/*
	 * Get output formats
	 */
	if (formats == 0) {
		/*
		 * Not specified on command line
		 */
		if (!wizard && strcmp(default_askformats, "yes")==0) {
			printf("Hand format(s) to generate: [%s] ",
				default_formats);
			(void) readline(stdin, message, MESSLEN);
			if (message[0]) {
				strcpy(default_formats, message);
			}
		}
		formats = default_formats;
	}

	/*
	 * If we do not have enough entropy collected (very likely)
	 * let the user supply it by rattling his keyboard
	 */
	if (!only_arg_entropy && nrandombits < ENTROPY_TO_COLLECT) {
		get_entropy_from_keyboard();
	}


	/*
	 * Extract the entropy into the random part of the seed
	 */
	collect_finish(seed.seed_random);
#ifdef BIGDEALX
	if (!wizard && nrandombits < ENTROPY_TO_COLLECT) {
		/*
		 * Can only happen when only_arg_entropy is set
		 */
		printf("WARNING: entropy supplied is dangerously low!!!\n");
	}
	if (!wizard && dangerous_code_used) {
		printf("You used features in this extended version of Big Deal\n");
		printf("that might defeat the purpose(generating unique sequences).\n");
		printf("Use hands for actual play only with permission from your national authority.\n\n");
	}

	/*
	 * Did someone use the -h flag ?
	 */
	if (hashstr)
		random_set(hashstr, seed.seed_random);

	/*
	 * Start checking for duplicate hashes, and log current hash
	 */
	for (i=0; i<RMDbytes; i++) {
		message[2*i  ] = "0123456789ABCDEF"[seed.seed_random[i]/16];
		message[2*i+1] = "0123456789ABCDEF"[seed.seed_random[i]%16];
	}
	message[2*RMDbytes] = 0;
	if (!hashstr && !wizard)
		checkduphash(message);		/* If this fails .... */

	fprintf(flog, "Deal %d boards to file %s, hash = %s\n",
		parameters.pp_nboards, filename, message);
#endif
	(void) output_specify_formats(formats, 1);
	output_createfiles(filename, &parameters);

	/*
	 * Generate a sequence of 160 bit pseudo random numbers
	 * by running the random bits with an increasing
	 * counter through the cryptographical hash.
	 * This according to Carl Ellison's recommendation for P1363
	 *
	 * But first put hash of owner ident into seed
	 *
	 * In Wizard mode use wizard string iso owner
	 */
	ownerp = wizard ? wizard : default_owner;
	hashcode = RMDhash((byte *) ownerp, strlen(ownerp));
	memcpy(seed.seed_owner, hashcode, RMDbytes);

	seqno = 0;
	for(i = parameters.pp_lowboard; i <= parameters.pp_highboard; i++) { 
		/*
		 * Next do loop executed as long as we have the misfortune
		 * to make 96 bit numbers above the number of hands
		 */
		do {
			seqno++;
			/*
			 * The next code guarantees the same sequence on
			 * litle endian and big endian machines, which
			 * makes it possible to reproduce sequences on each
			 */
			seed.seed_sequence[0] = seqno & 0xFF;
			seed.seed_sequence[1] = (seqno>>8) & 0xFF;
			seed.seed_sequence[2] = (seqno>>16) & 0xFF;
			seed.seed_sequence[3] = (seqno>>24) & 0xFF;
			/*
			 * Run all the bits through the hash
			 */
			hashcode = RMDhash((byte *) &seed, sizeof(seed));
			/*
			 * Take the first L bytes(96 bits) as a candidate
			 * hand number
			 */
			memcpy(dnumber.dn_num, hashcode, L);
		} while(!goedel(dnumber.dn_num));
		/*
		 * Ok, got one
		 * Print it in all desired formats
		 */
		/* fprintf(stderr, "Hand %d made from hash %ld\n", i, seqno); */
		output_hand(i, &dnumber);
	}

	/*
	 * Finished, close output files
	 */
	output_closefiles();
#ifdef BIGDEALX
	fclose(flog);
#endif

	/*
	 * Do whatever our OS wants us to do at the end, and then exit
	 */
	os_finish();
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movq %rsi, %r14
movl %edi, %ebp
xorps %xmm0, %xmm0
leaq 0x90(%rsp), %r15
movaps %xmm0, 0x50(%r15)
movaps %xmm0, 0x40(%r15)
movaps %xmm0, 0x30(%r15)
movaps %xmm0, 0x20(%r15)
andl $0x0, 0x60(%r15)
movaps %xmm0, 0x10(%r15)
movaps %xmm0, (%r15)
movq 0x510f(%rip), %rax      # 0x8fc0
movq (%rax), %rdi
movq $0x0, 0x18(%rsp)
xorl %esi, %esi
callq 0x20a0
leaq 0x226a(%rip), %rdi      # 0x6135
leaq 0x250b(%rip), %rcx      # 0x63dd
pushq $0x2
popq %rsi
xorl %edx, %edx
movq %rcx, %r8
xorl %eax, %eax
callq 0x20c0
callq 0x550f
callq 0x4348
leaq 0x2260(%rip), %r12      # 0x6152
movq 0x50d7(%rip), %rbx      # 0x8fd0
pushq $0x63
popq %r13
movl %ebp, %edi
movq %r14, %rsi
movq %r12, %rdx
callq 0x21a0
cmpl $0x6e, %eax
je 0x3f31
cmpl $0x70, %eax
je 0x3f3b
cmpl $-0x1, %eax
je 0x3f55
cmpl $0x66, %eax
je 0x3f4b
cmpl $0x3f, %eax
je 0x4269
cmpl $0x52, %eax
jne 0x3efd
jmp 0x4293
movq (%rbx), %rdi
callq 0x3e03
jmp 0x3efd
movq (%rbx), %rsi
movq %r15, %rdi
movq %r13, %rdx
callq 0x2040
jmp 0x3efd
movq (%rbx), %rax
movq %rax, 0x18(%rsp)
jmp 0x3efd
callq 0x53f3
callq 0x556a
pushq $0x1
popq %rsi
movq %rax, %rdi
callq 0x3cc9
callq 0x37fc
pushq $0x34
popq %rdi
pushq $0xd
popq %rbp
leaq 0x20(%rsp), %r14
movl %ebp, %esi
movq %r14, %rdx
callq 0x3884
pushq $0x27
popq %rdi
leaq 0x8(%rsp), %r15
movl %ebp, %esi
movq %r15, %rdx
callq 0x3884
movq %r14, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x374d
pushq $0x1a
popq %rdi
movl %ebp, %esi
movq %r15, %rdx
callq 0x3884
movq %r14, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x374d
leaq 0x7c22(%rip), %rdi      # 0xbbe8
movq %r14, %rsi
callq 0x36c6
leaq 0x21e5(%rip), %r15      # 0x61ba
pushq $0x64
popq %rbp
leaq 0x220a(%rip), %r12      # 0x61e9
movq 0x4fe2(%rip), %rbx      # 0x8fc8
movl 0x7bcc(%rip), %eax      # 0xbbb8
leal -0x65(%rax), %ecx
cmpl $-0x64, %ecx
jae 0x4043
cmpl $0x65, %eax
jl 0x400c
andl $0x0, 0x7bb8(%rip)      # 0xbbb8
movq %r15, %rdi
movl %ebp, %esi
xorl %eax, %eax
callq 0x20c0
movq %r12, %rdi
movl %ebp, %esi
xorl %eax, %eax
callq 0x20c0
movq (%rbx), %rdi
movq %r14, %rsi
movl %ebp, %edx
callq 0x3c91
movq %r14, %rdi
callq 0x3e03
movq %r14, %rdi
callq 0x2090
movq %r14, %rdi
movl %eax, %esi
xorl %edx, %edx
callq 0x436c
jmp 0x3fe6
leaq 0x90(%rsp), %r14
leaq 0x21b8(%rip), %r15      # 0x620a
leaq 0x20(%rsp), %r12
pushq $0x64
popq %rbp
pushq $0x5
popq %r13
movq %r14, %rdi
callq 0x5529
testl %eax, %eax
jne 0x40a3
movq %r15, %rdi
xorl %eax, %eax
callq 0x20c0
movq (%rbx), %rdi
movq %r12, %rsi
movl %ebp, %edx
callq 0x3c91
movq %r12, %rdi
callq 0x2090
movq %r12, %rdi
movl %eax, %esi
movl %r13d, %edx
callq 0x436c
movq %r14, %rdi
movq %r12, %rsi
callq 0x2050
jmp 0x405e
movq 0x18(%rsp), %r13
testq %r13, %r13
jne 0x4107
cmpl $0x736579, 0x50c9(%rip) # imm = 0x736579
jne 0x4100
leaq 0x216c(%rip), %rdi      # 0x622c
leaq 0x5049(%rip), %r13      # 0x9110
movq %r13, %rsi
xorl %eax, %eax
callq 0x20c0
movq (%rbx), %rdi
leaq 0x20(%rsp), %r14
pushq $0x64
popq %rdx
movq %r14, %rsi
callq 0x3c91
cmpb $0x0, (%r14)
je 0x4107
leaq 0x501f(%rip), %r13      # 0x9110
leaq 0x20(%rsp), %rsi
movq %r13, %rdi
callq 0x2050
jmp 0x4107
leaq 0x5009(%rip), %r13      # 0x9110
leaq 0x7b2e(%rip), %rbx      # 0xbc3c
cmpl $0xd4, (%rbx)
jg 0x4179
callq 0x54ab
leaq 0x212c(%rip), %rdi      # 0x624e
xorl %r12d, %r12d
xorl %eax, %eax
callq 0x20c0
leaq 0x14(%rsp), %r14
leaq 0x8(%rsp), %r15
pushq $0x4
popq %rbp
movq %r14, %rdi
callq 0x532f
movl %eax, 0x8(%rsp)
cmpl %r12d, %eax
je 0x4160
movl 0x14(%rsp), %edx
addl $0x2, %edx
movq %r15, %rdi
movl %ebp, %esi
callq 0x436c
movl 0x8(%rsp), %r12d
cmpl $0xd5, (%rbx)
jl 0x4139
leaq 0x225e(%rip), %rdi      # 0x63cd
callq 0x2060
callq 0x54fa
leaq 0x7a40(%rip), %rdi      # 0xbbc0
callq 0x43f7
pushq $0x1
popq %rsi
movq %r13, %rdi
callq 0x452b
leaq 0x7a19(%rip), %rsi      # 0xbbb0
leaq 0x90(%rsp), %rdi
callq 0x46c2
leaq 0x5045(%rip), %rbx      # 0x91f0
movq %rbx, %rdi
callq 0x2090
movq %rbx, %rdi
movl %eax, %esi
callq 0x42b6
movl 0x7a4d(%rip), %eax      # 0xbc10
movl %eax, 0x7a1b(%rip)      # 0xbbe4
movaps 0x7a30(%rip), %xmm0     # 0xbc00
movups %xmm0, 0x79fd(%rip)     # 0xbbd4
xorl %r13d, %r13d
movl 0x79d0(%rip), %ebx      # 0xbbb0
leaq 0x79d5(%rip), %r14      # 0xbbbc
pushq $0x2c
popq %rbp
leaq 0x79f7(%rip), %r15      # 0xbbe8
leaq 0x8(%rsp), %r12
cmpl 0x79b8(%rip), %ebx      # 0xbbb4
jg 0x424b
incq %r13
movl %r13d, 0x79b4(%rip)     # 0xbbbc
movq %r14, %rdi
movl %ebp, %esi
callq 0x42b6
movl 0x79f0(%rip), %eax      # 0xbc08
movl %eax, 0x10(%rsp)
movq 0x79dd(%rip), %rax      # 0xbc00
movq %rax, 0x8(%rsp)
movq %r12, %rdi
movq %r15, %rsi
callq 0x3732
incq %r13
testl %eax, %eax
jns 0x4201
movl %ebx, %edi
movq %r12, %rsi
callq 0x486b
incl %ebx
decq %r13
jmp 0x41f6
callq 0x4831
callq 0x5524
xorl %eax, %eax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x4d80(%rip), %rax      # 0x8ff0
movq (%rax), %rdi
movq (%r14), %rdx
leaq 0x1edd(%rip), %rsi      # 0x615a
leaq 0x1ee4(%rip), %rcx      # 0x6168
xorl %eax, %eax
callq 0x2170
pushq $-0x1
popq %rdi
callq 0x21d0
callq 0x556a
movq %rax, %rdi
xorl %esi, %esi
callq 0x3cc9
callq 0x556a
movq %rax, %rdi
callq 0x3ab4
xorl %edi, %edi
callq 0x21d0