// File: OpenFodder[P]SOS_Unpacker/capsimg/Core/DiskFile.cpp
// Function: CDiskFile::FindFile(char*, char const*, char const*)
int CDiskFile::FindFile(char *result, const char *filename, const char *filter)
{
	// result is not valid by default
	int resvalid = 0;

	// copy source as result by default
	int rescopy = 1;

	// stop if no buffer specified for the result
	if (!result)
		return resvalid;

	// the default result is an empty string
	result[0] = 0;

	// stop if the filename is not specified
	if (!filename)
		return resvalid;

	// length of path and file name components separated
	int pathlen = 0, namelen = 0;

	// wildcard usage counter, wildcards enabled
	int wcused = 0;
	int wcenabled = 1;

	// process the entire source filename or pattern
	for (int rpos = 0; wcenabled && filename[rpos]; rpos++) {
		namelen++;

		switch (filename[rpos]) {
			// if path delimiter found
		case '/':
		case '\\':
			// stop if a wilcard has already been used; only allow wildcards in filename part, not in the path
			if (wcused) {
				// disable write card processing; the result will be the path upto the illegal wildcard segment
				wcenabled = 0;
				break;
			}

			// set new path length as the entire name until now including the delimiter
			pathlen = rpos + 1;

			// clear the filename part
			namelen = 0;
			break;

			// count the wildcards
		case '?':
		case '*':
			wcused++;
			break;
		}
	}

	// if wildcards used
	if (wcused) {
		// and wilcardcards are enabled, ie no error in the path
		if (wcenabled) {
			char *pathbuf = NULL;
			const char *dirpath;

			// make a copy of the path if it's defined or use the current directory as the path
			if (pathlen) {
				pathbuf = new char[pathlen + 1];
				memcpy(pathbuf, filename, pathlen);
				pathbuf[pathlen] = 0;
				dirpath = pathbuf;
			} else
				dirpath = ".";

			// open the selected path
			DIR *pdir = opendir(dirpath);
			if (pdir) {
				dirent *pent;
				const char *pattern = filename + pathlen;

				// iterate all directory entries
				while (pent = readdir(pdir)) {
					// skip any entry that is not a regular file
#if defined _DIRENT_HAVE_D_TYPE || defined HAVE_STRUCT_DIRENT_D_TYPE
					if (pent->d_type != DT_REG)
						continue;
#endif

					// check entry to match the filename pattern
					char *fn = pent->d_name;
					if (FileNameMatch(pattern, fn)) {
						// if matches, check entry to match the filter pattern if filter is specified
						if (!filter || FileNameMatch(filter, fn)) {
							// success; copy the original path and add the entry found
							memcpy(result, filename, pathlen);
							strcpy(result + pathlen, fn);

							// keep this result, don't copy the source
							rescopy = 0;

							// result is valid
							resvalid = 1;
							break;
						}
					}
				}

				closedir(pdir);
			}

			// free path buffer
			delete[] pathbuf;
		}
	} else {
		// wilcards unused, result is valid
		resvalid = 1;
	}

	// copy the source if that's the result
	if (rescopy) {
		int reslen = pathlen + namelen;
		memcpy(result, filename, reslen);
		result[reslen] = 0;
	}

	return resvalid;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl $0x1, -0x28(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x17667
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x178c8
movq -0x10(%rbp), %rax
movb $0x0, (%rax)
cmpq $0x0, -0x18(%rbp)
jne 0x17680
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x178c8
movl $0x0, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl $0x1, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x38(%rbp)
movb %al, -0x75(%rbp)
je 0x176c0
movq -0x18(%rbp), %rax
movslq -0x3c(%rbp), %rcx
cmpb $0x0, (%rax,%rcx)
setne %al
movb %al, -0x75(%rbp)
movb -0x75(%rbp), %al
testb $0x1, %al
jne 0x176c9
jmp 0x1773f
movl -0x30(%rbp), %eax
incl %eax
movl %eax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movslq -0x3c(%rbp), %rcx
movsbl (%rax,%rcx), %eax
movl %eax, -0x7c(%rbp)
subl $0x2a, %eax
je 0x17726
jmp 0x176e7
movl -0x7c(%rbp), %eax
subl $0x2f, %eax
je 0x17705
jmp 0x176f1
movl -0x7c(%rbp), %eax
subl $0x3f, %eax
je 0x17726
jmp 0x176fb
movl -0x7c(%rbp), %eax
subl $0x5c, %eax
jne 0x1772f
jmp 0x17705
cmpl $0x0, -0x34(%rbp)
je 0x17714
movl $0x0, -0x38(%rbp)
jmp 0x1772f
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
jmp 0x1772f
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x17731
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x176a3
cmpl $0x0, -0x34(%rbp)
je 0x1788f
cmpl $0x0, -0x38(%rbp)
je 0x1788d
movq $0x0, -0x48(%rbp)
cmpl $0x0, -0x2c(%rbp)
je 0x1779a
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdi
callq 0x4040
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
movq -0x18(%rbp), %rsi
movslq -0x2c(%rbp), %rdx
callq 0x41a0
movq -0x48(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x48(%rbp), %rax
movq %rax, -0x50(%rbp)
jmp 0x177a5
leaq 0x6b08(%rip), %rax      # 0x1e2a9
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
callq 0x4390
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
je 0x1786e
movq -0x18(%rbp), %rax
movslq -0x2c(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x58(%rbp), %rdi
callq 0x43a0
movq %rax, -0x60(%rbp)
cmpq $0x0, %rax
je 0x17865
movq -0x60(%rbp), %rax
movzbl 0x12(%rax), %eax
cmpl $0x8, %eax
je 0x177f2
jmp 0x177cc
movq -0x60(%rbp), %rax
addq $0x13, %rax
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x178e0
cmpl $0x0, %eax
je 0x17860
cmpq $0x0, -0x20(%rbp)
je 0x17829
movq -0x20(%rbp), %rdi
movq -0x70(%rbp), %rsi
callq 0x178e0
cmpl $0x0, %eax
je 0x1785e
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movslq -0x2c(%rbp), %rdx
callq 0x41a0
movq -0x10(%rbp), %rdi
movslq -0x2c(%rbp), %rax
addq %rax, %rdi
movq -0x70(%rbp), %rsi
callq 0x4200
movl $0x0, -0x28(%rbp)
movl $0x1, -0x24(%rbp)
jmp 0x17865
jmp 0x17860
jmp 0x177cc
movq -0x58(%rbp), %rdi
callq 0x43c0
movq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
je 0x1788b
movq -0x88(%rbp), %rdi
callq 0x42e0
jmp 0x1788d
jmp 0x17896
movl $0x1, -0x24(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0x178c2
movl -0x2c(%rbp), %eax
addl -0x30(%rbp), %eax
movl %eax, -0x74(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movslq -0x74(%rbp), %rdx
callq 0x41a0
movq -0x10(%rbp), %rax
movslq -0x74(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)