// File: jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_env_open
int ESECT
mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
{
	int		oflags, rc, len, excl = -1;
	char *lpath, *dpath;

	if (env->me_fd!=INVALID_HANDLE_VALUE || (flags & ~(CHANGEABLE|CHANGELESS)))
		return EINVAL;

	len = strlen(path);
	if (flags & MDB_NOSUBDIR) {
		rc = len + sizeof(LOCKSUFF) + len + 1;
	} else {
		rc = len + sizeof(LOCKNAME) + len + sizeof(DATANAME);
	}
	lpath = malloc(rc);
	if (!lpath)
		return ENOMEM;
	if (flags & MDB_NOSUBDIR) {
		dpath = lpath + len + sizeof(LOCKSUFF);
		sprintf(lpath, "%s" LOCKSUFF, path);
		strcpy(dpath, path);
	} else {
		dpath = lpath + len + sizeof(LOCKNAME);
		sprintf(lpath, "%s" LOCKNAME, path);
		sprintf(dpath, "%s" DATANAME, path);
	}

	rc = MDB_SUCCESS;
	flags |= env->me_flags;
	if (flags & MDB_RDONLY) {
		/* silently ignore WRITEMAP when we're only getting read access */
		flags &= ~MDB_WRITEMAP;
	} else {
		if (!((env->me_free_pgs = mdb_midl_alloc(MDB_IDL_UM_MAX)) &&
			  (env->me_dirty_list = calloc(MDB_IDL_UM_SIZE, sizeof(MDB_ID2)))))
			rc = ENOMEM;
	}
	env->me_flags = flags |= MDB_ENV_ACTIVE;
	if (rc)
		goto leave;

	env->me_path = strdup(path);
	env->me_dbxs = calloc(env->me_maxdbs, sizeof(MDB_dbx));
	env->me_dbflags = calloc(env->me_maxdbs, sizeof(uint16_t));
	env->me_dbiseqs = calloc(env->me_maxdbs, sizeof(unsigned int));
	if (!(env->me_dbxs && env->me_path && env->me_dbflags && env->me_dbiseqs)) {
		rc = ENOMEM;
		goto leave;
	}
	env->me_dbxs[FREE_DBI].md_cmp = mdb_cmp_long; /* aligned MDB_INTEGERKEY */

	/* For RDONLY, get lockfile after we know datafile exists */
	if (!(flags & (MDB_RDONLY|MDB_NOLOCK))) {
		rc = mdb_env_setup_locks(env, lpath, mode, &excl);
		if (rc)
			goto leave;
	}

#ifdef _WIN32
	if (F_ISSET(flags, MDB_RDONLY)) {
		oflags = GENERIC_READ;
		len = OPEN_EXISTING;
	} else {
		oflags = GENERIC_READ|GENERIC_WRITE;
		len = OPEN_ALWAYS;
	}
	mode = FILE_ATTRIBUTE_NORMAL;
	env->me_fd = CreateFileA(dpath, oflags, FILE_SHARE_READ|FILE_SHARE_WRITE,
		NULL, len, mode, NULL);
#else
	if (F_ISSET(flags, MDB_RDONLY))
		oflags = O_RDONLY;
	else
		oflags = O_RDWR | O_CREAT;

	env->me_fd = open(dpath, oflags, mode);
#endif
	if (env->me_fd == INVALID_HANDLE_VALUE) {
		rc = ErrCode();
		goto leave;
	}

	if ((flags & (MDB_RDONLY|MDB_NOLOCK)) == MDB_RDONLY) {
		rc = mdb_env_setup_locks(env, lpath, mode, &excl);
		if (rc)
			goto leave;
	}

	if ((rc = mdb_env_open2(env)) == MDB_SUCCESS) {
		if (flags & (MDB_RDONLY|MDB_WRITEMAP)) {
			env->me_mfd = env->me_fd;
		} else {
			/* Synchronous fd for meta writes. Needed even with
			 * MDB_NOSYNC/MDB_NOMETASYNC, in case these get reset.
			 */
#ifdef _WIN32
			len = OPEN_EXISTING;
			env->me_mfd = CreateFileA(dpath, oflags,
				FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, len,
				mode | FILE_FLAG_WRITE_THROUGH, NULL);
#else
			oflags &= ~O_CREAT;
			env->me_mfd = open(dpath, oflags | MDB_DSYNC, mode);
#endif
			if (env->me_mfd == INVALID_HANDLE_VALUE) {
				rc = ErrCode();
				goto leave;
			}
		}
		DPRINTF(("opened dbenv %p", (void *) env));
		if (excl > 0) {
			rc = mdb_env_share_locks(env, &excl);
			if (rc)
				goto leave;
		}
		if (!(flags & MDB_RDONLY)) {
			MDB_txn *txn;
			int tsize = sizeof(MDB_txn), size = tsize + env->me_maxdbs *
				(sizeof(MDB_db)+sizeof(MDB_cursor *)+sizeof(unsigned int)+1);
			if ((env->me_pbuf = calloc(1, env->me_psize)) &&
				(txn = calloc(1, size)))
			{
				txn->mt_dbs = (MDB_db *)((char *)txn + tsize);
				txn->mt_cursors = (MDB_cursor **)(txn->mt_dbs + env->me_maxdbs);
				txn->mt_dbiseqs = (unsigned int *)(txn->mt_cursors + env->me_maxdbs);
				txn->mt_dbflags = (unsigned char *)(txn->mt_dbiseqs + env->me_maxdbs);
				txn->mt_env = env;
				txn->mt_dbxs = env->me_dbxs;
				txn->mt_flags = MDB_TXN_FINISHED;
				env->me_txn0 = txn;
			} else {
				rc = ENOMEM;
			}
		}
	}

leave:
	if (rc) {
		mdb_env_close0(env, excl);
	}
	free(lpath);
	return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rax
cmpl $-0x1, (%rax)
jne 0x13863
movl -0x1c(%rbp), %eax
andl $0xfe00bffe, %eax       # imm = 0xFE00BFFE
cmpl $0x0, %eax
je 0x1386f
movl $0x16, -0x4(%rbp)
jmp 0x13d42
movq -0x18(%rbp), %rdi
callq 0x2100
movl %eax, -0x2c(%rbp)
movl -0x1c(%rbp), %eax
andl $0x4000, %eax           # imm = 0x4000
cmpl $0x0, %eax
je 0x138a0
movslq -0x2c(%rbp), %rax
addq $0x6, %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
addq $0x1, %rax
movl %eax, -0x28(%rbp)
jmp 0x138b6
movslq -0x2c(%rbp), %rax
addq $0xa, %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
addq $0xa, %rax
movl %eax, -0x28(%rbp)
movslq -0x28(%rbp), %rdi
callq 0x2260
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
jne 0x138d6
movl $0xc, -0x4(%rbp)
jmp 0x13d42
movl -0x1c(%rbp), %eax
andl $0x4000, %eax           # imm = 0x4000
cmpl $0x0, %eax
je 0x1391b
movq -0x38(%rbp), %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
addq $0x6, %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
movq -0x18(%rbp), %rdx
leaq 0x3b10(%rip), %rsi      # 0x17415
movb $0x0, %al
callq 0x2360
movq -0x40(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x2080
jmp 0x1395a
movq -0x38(%rbp), %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
addq $0xa, %rax
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rdi
movq -0x18(%rbp), %rdx
leaq 0x3ae0(%rip), %rsi      # 0x1741d
movb $0x0, %al
callq 0x2360
movq -0x40(%rbp), %rdi
movq -0x18(%rbp), %rdx
leaq 0x3ad6(%rip), %rsi      # 0x17429
movb $0x0, %al
callq 0x2360
movl $0x0, -0x28(%rbp)
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
orl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
andl $0x20000, %eax          # imm = 0x20000
cmpl $0x0, %eax
je 0x13988
movl -0x1c(%rbp), %eax
andl $0xfff7ffff, %eax       # imm = 0xFFF7FFFF
movl %eax, -0x1c(%rbp)
jmp 0x139cc
movl $0x1ffff, %edi          # imm = 0x1FFFF
callq 0x126b0
movq -0x10(%rbp), %rcx
movq %rax, 0xc8(%rcx)
cmpq $0x0, %rax
je 0x139c3
movl $0x20000, %edi          # imm = 0x20000
movl $0x10, %esi
callq 0x21f0
movq -0x10(%rbp), %rcx
movq %rax, 0xd0(%rcx)
cmpq $0x0, %rax
jne 0x139ca
movl $0xc, -0x28(%rbp)
jmp 0x139cc
movl -0x1c(%rbp), %ecx
orl $0x20000000, %ecx       # imm = 0x20000000
movl %ecx, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movl %ecx, 0xc(%rax)
cmpl $0x0, -0x28(%rbp)
je 0x139ea
jmp 0x13d24
movq -0x18(%rbp), %rdi
callq 0x23b0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, %edi
movl $0x30, %esi
callq 0x21f0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x88(%rax)
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, %edi
movl $0x2, %esi
callq 0x21f0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x90(%rax)
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, %edi
movl $0x4, %esi
callq 0x21f0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x98(%rax)
movq -0x10(%rbp), %rax
cmpq $0x0, 0x88(%rax)
je 0x13a96
movq -0x10(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x13a96
movq -0x10(%rbp), %rax
cmpq $0x0, 0x90(%rax)
je 0x13a96
movq -0x10(%rbp), %rax
cmpq $0x0, 0x98(%rax)
jne 0x13aa2
movl $0xc, -0x28(%rbp)
jmp 0x13d24
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rax
leaq -0x107d4(%rip), %rcx    # 0x32e0
movq %rcx, 0x10(%rax)
movl -0x1c(%rbp), %eax
andl $0x420000, %eax         # imm = 0x420000
cmpl $0x0, %eax
jne 0x13ae9
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl -0x20(%rbp), %edx
leaq -0x30(%rbp), %rcx
callq 0x13d50
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0x13ae7
jmp 0x13d24
jmp 0x13ae9
movl -0x1c(%rbp), %eax
andl $0x20000, %eax          # imm = 0x20000
cmpl $0x20000, %eax          # imm = 0x20000
jne 0x13b01
movl $0x0, -0x24(%rbp)
jmp 0x13b08
movl $0x42, -0x24(%rbp)
movq -0x40(%rbp), %rdi
movl -0x24(%rbp), %esi
movl -0x20(%rbp), %edx
movb $0x0, %al
callq 0x2300
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
cmpl $-0x1, (%rax)
jne 0x13b39
callq 0x2050
movl (%rax), %eax
movl %eax, -0x28(%rbp)
jmp 0x13d24
movl -0x1c(%rbp), %eax
andl $0x420000, %eax         # imm = 0x420000
cmpl $0x20000, %eax          # imm = 0x20000
jne 0x13b6c
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
movl -0x20(%rbp), %edx
leaq -0x30(%rbp), %rcx
callq 0x13d50
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0x13b6a
jmp 0x13d24
jmp 0x13b6c
movq -0x10(%rbp), %rdi
callq 0x14050
movl %eax, -0x28(%rbp)
cmpl $0x0, %eax
jne 0x13d22
movl -0x1c(%rbp), %eax
andl $0xa0000, %eax          # imm = 0xA0000
cmpl $0x0, %eax
je 0x13b9d
movq -0x10(%rbp), %rax
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
jmp 0x13be1
movl -0x24(%rbp), %eax
andl $-0x41, %eax
movl %eax, -0x24(%rbp)
movq -0x40(%rbp), %rdi
movl -0x24(%rbp), %esi
orl $0x1000, %esi           # imm = 0x1000
movl -0x20(%rbp), %edx
movb $0x0, %al
callq 0x2300
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x10(%rbp), %rax
cmpl $-0x1, 0x8(%rax)
jne 0x13bdf
callq 0x2050
movl (%rax), %eax
movl %eax, -0x28(%rbp)
jmp 0x13d24
jmp 0x13be1
cmpl $0x0, -0x30(%rbp)
jle 0x13c04
movq -0x10(%rbp), %rdi
leaq -0x30(%rbp), %rsi
callq 0x14450
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0x13c02
jmp 0x13d24
jmp 0x13c04
movl -0x1c(%rbp), %eax
andl $0x20000, %eax          # imm = 0x20000
cmpl $0x0, %eax
jne 0x13d20
movl $0x88, -0x4c(%rbp)
movslq -0x4c(%rbp), %rax
movq -0x10(%rbp), %rcx
movl 0x24(%rcx), %ecx
imulq $0x3d, %rcx, %rcx
addq %rcx, %rax
movl %eax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, %esi
movl $0x1, %edi
callq 0x21f0
movq -0x10(%rbp), %rcx
movq %rax, 0x58(%rcx)
cmpq $0x0, %rax
je 0x13d17
movslq -0x50(%rbp), %rsi
movl $0x1, %edi
callq 0x21f0
movq %rax, -0x48(%rbp)
cmpq $0x0, %rax
je 0x13d17
movq -0x48(%rbp), %rcx
movslq -0x4c(%rbp), %rax
addq %rax, %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x58(%rax)
movq -0x48(%rbp), %rax
movq 0x58(%rax), %rcx
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
imulq $0x30, %rax, %rax
addq %rax, %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x48(%rbp), %rax
movq 0x68(%rax), %rcx
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
shlq $0x3, %rax
addq %rax, %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x60(%rax)
movq -0x48(%rbp), %rax
movq 0x60(%rax), %rcx
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
shlq $0x2, %rax
addq %rax, %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0x10(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rax
movq 0x88(%rax), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x50(%rax)
movq -0x48(%rbp), %rax
movl $0x1, 0x7c(%rax)
movq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x68(%rax)
jmp 0x13d1e
movl $0xc, -0x28(%rbp)
jmp 0x13d20
jmp 0x13d22
jmp 0x13d24
cmpl $0x0, -0x28(%rbp)
je 0x13d33
movq -0x10(%rbp), %rdi
callq 0x14520
movq -0x38(%rbp), %rdi
callq 0x2030
movl -0x28(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax,%rax)