// File: /workspace/github_c_makefile_star2_O3/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 $0xe8, %rsp
movq %rsi, %r14
movl %edi, %ebp
xorps %xmm0, %xmm0
leaq 0x80(%rsp), %r15
movaps %xmm0, 0x50(%r15)
movaps %xmm0, 0x40(%r15)
movaps %xmm0, 0x30(%r15)
movaps %xmm0, 0x20(%r15)
movaps %xmm0, 0x10(%r15)
movaps %xmm0, (%r15)
movl $0x0, 0x60(%r15)
movq 0x4fdd(%rip), %rax      # 0x8fc0
movq (%rax), %rdi
xorl %ebx, %ebx
xorl %esi, %esi
callq 0x20a0
leaq 0x213f(%rip), %rdi      # 0x6135
leaq 0x23e0(%rip), %rcx      # 0x63dd
movl $0x2, %esi
xorl %edx, %edx
movq %rcx, %r8
xorl %eax, %eax
callq 0x20c0
callq 0x5875
callq 0x44c0
leaq 0x2133(%rip), %r12      # 0x6152
movq 0x4faa(%rip), %r13      # 0x8fd0
movl %ebp, %edi
movq %r14, %rsi
movq %r12, %rdx
callq 0x21b0
cmpl $0x6d, %eax
jg 0x404c
cmpl $0x51, %eax
jg 0x4069
cmpl $-0x1, %eax
je 0x4089
cmpl $0x3f, %eax
jne 0x4026
jmp 0x43e6
cmpl $0x6e, %eax
je 0x4078
cmpl $0x70, %eax
jne 0x4026
movq (%r13), %rsi
movl $0x63, %edx
movq %r15, %rdi
callq 0x2040
jmp 0x4026
cmpl $0x66, %eax
je 0x4083
cmpl $0x52, %eax
jne 0x4026
jmp 0x43ee
movq (%r13), %rdi
callq 0x3f2e
jmp 0x4026
movq (%r13), %rbx
jmp 0x4026
callq 0x574f
callq 0x58e2
movq %rax, %rdi
movl $0x1, %esi
callq 0x3dee
callq 0x38f0
leaq 0x10(%rsp), %r14
movl $0x34, %edi
movl $0xd, %esi
movq %r14, %rdx
callq 0x397f
movq %rsp, %r15
movl $0x27, %edi
movl $0xd, %esi
movq %r15, %rdx
callq 0x397f
movq %r14, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x3816
movl $0x1a, %edi
movl $0xd, %esi
movq %r15, %rdx
callq 0x397f
movq %r14, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x3816
leaq 0x7ae2(%rip), %rdi      # 0xbbe8
movq %r14, %rsi
callq 0x3792
movl 0x7aa4(%rip), %eax      # 0xbbb8
leal -0x65(%rax), %ecx
cmpl $-0x65, %ecx
ja 0x41a2
leaq 0x2093(%rip), %r14      # 0x61ba
leaq 0x20bb(%rip), %r15      # 0x61e9
movq 0x4e93(%rip), %r13      # 0x8fc8
leaq 0x10(%rsp), %r12
cmpl $0x65, %eax
jl 0x4158
movl $0x0, 0x7a6f(%rip)      # 0xbbb8
movq %r14, %rdi
movl $0x64, %esi
xorl %eax, %eax
callq 0x20c0
movq %r15, %rdi
movl $0x64, %esi
xorl %eax, %eax
callq 0x20c0
movq (%r13), %rdi
movq %r12, %rsi
movl $0x64, %edx
callq 0x3db2
movq %r12, %rdi
callq 0x3f2e
movq %r12, %rdi
callq 0x2090
movq %r12, %rdi
movl %eax, %esi
xorl %edx, %edx
callq 0x44e3
movl 0x7a1e(%rip), %eax      # 0xbbb8
leal -0x65(%rax), %ecx
cmpl $-0x64, %ecx
jb 0x413a
leaq 0x80(%rsp), %rdi
callq 0x589f
testl %eax, %eax
jne 0x4217
leaq 0x2050(%rip), %r14      # 0x620a
movq 0x4e07(%rip), %r13      # 0x8fc8
leaq 0x10(%rsp), %r15
leaq 0x80(%rsp), %r12
movq %r14, %rdi
xorl %eax, %eax
callq 0x20c0
movq (%r13), %rdi
movq %r15, %rsi
movl $0x64, %edx
callq 0x3db2
movq %r15, %rdi
callq 0x2090
movq %r15, %rdi
movl %eax, %esi
movl $0x5, %edx
callq 0x44e3
movq %r12, %rdi
movq %r15, %rsi
callq 0x2050
movq %r12, %rdi
callq 0x589f
testl %eax, %eax
je 0x41ce
testq %rbx, %rbx
jne 0x427f
cmpl $0x736579, 0x4f5a(%rip) # imm = 0x736579
jne 0x4278
leaq 0x1ffd(%rip), %rdi      # 0x622c
leaq 0x4eda(%rip), %rbx      # 0x9110
movq %rbx, %rsi
xorl %eax, %eax
callq 0x20c0
movq 0x4d81(%rip), %rax      # 0x8fc8
movq (%rax), %rdi
leaq 0x10(%rsp), %r14
movq %r14, %rsi
movl $0x64, %edx
callq 0x3db2
cmpb $0x0, (%r14)
je 0x427f
leaq 0x4ea7(%rip), %rbx      # 0x9110
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x2050
jmp 0x427f
leaq 0x4e91(%rip), %rbx      # 0x9110
leaq 0x79b6(%rip), %r12      # 0xbc3c
cmpl $0xd4, (%r12)
jg 0x42ee
callq 0x5811
leaq 0x1fb2(%rip), %rdi      # 0x624e
xorl %ebp, %ebp
xorl %eax, %eax
callq 0x20c0
leaq 0xc(%rsp), %r14
movq %rsp, %r15
movq %r14, %rdi
callq 0x5678
movl %eax, (%rsp)
cmpl %ebp, %eax
je 0x42d3
movl 0xc(%rsp), %edx
addl $0x2, %edx
movq %r15, %rdi
movl $0x4, %esi
callq 0x44e3
movl (%rsp), %ebp
cmpl $0xd5, (%r12)
jl 0x42ad
leaq 0x20e9(%rip), %rdi      # 0x63cd
callq 0x2060
callq 0x5860
leaq 0x78cb(%rip), %rdi      # 0xbbc0
callq 0x45a8
movq %rbx, %rdi
movl $0x1, %esi
callq 0x46d1
leaq 0x78a2(%rip), %rsi      # 0xbbb0
leaq 0x80(%rsp), %rdi
callq 0x4885
leaq 0x4ece(%rip), %rbx      # 0x91f0
movq %rbx, %rdi
callq 0x2090
movq %rbx, %rdi
movl %eax, %esi
callq 0x4411
movl 0x78d6(%rip), %eax      # 0xbc10
movl %eax, 0x78a4(%rip)      # 0xbbe4
movaps 0x78b9(%rip), %xmm0     # 0xbc00
movups %xmm0, 0x7886(%rip)     # 0xbbd4
movl 0x785c(%rip), %ebx      # 0xbbb0
cmpl 0x785a(%rip), %ebx      # 0xbbb4
jg 0x43c8
xorl %r13d, %r13d
leaq 0x7856(%rip), %r14      # 0xbbbc
leaq 0x787b(%rip), %r15      # 0xbbe8
movq %rsp, %r12
incq %r13
movl %r13d, 0x7842(%rip)     # 0xbbbc
movq %r14, %rdi
movl $0x2c, %esi
callq 0x4411
movl 0x787b(%rip), %eax      # 0xbc08
movl %eax, 0x8(%rsp)
movq 0x7868(%rip), %rax      # 0xbc00
movq %rax, (%rsp)
movq %r12, %rdi
movq %r15, %rsi
callq 0x37f8
incq %r13
testl %eax, %eax
jns 0x4373
movl %ebx, %edi
movq %r12, %rsi
callq 0x4a12
leal 0x1(%rbx), %eax
decq %r13
cmpl 0x77f0(%rip), %ebx      # 0xbbb4
movl %eax, %ebx
jl 0x4370
callq 0x49d1
callq 0x588a
xorl %eax, %eax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
callq 0x223f
callq 0x58e2
movq %rax, %rdi
xorl %esi, %esi
callq 0x3dee
callq 0x58e2
movq %rax, %rdi
callq 0x3bd4
xorl %edi, %edi
callq 0x21e0