// File: /workspace/github_c_makefile_star2_O0/icebert[P]pblat/lib/cheapcgi.c
// Function: cgiClientBrowser
enum browserType cgiClientBrowser(char **browserQualifier, enum osType *clientOs,
                                  char **clientOsQualifier)
/* Return client browser type determined from (HTTP_USER_AGENT)
   Optionally requuest the additional info about the client */
{
// WARNING: The specifics of the HTTP_USER_AGENT vary widely.
//          This has only been tested on a few cases.
static enum browserType clientBrowser = btUnknown;
static enum browserType clientOsType  = (enum browserType)osUnknown;
static char *clientBrowserExtra       = NULL;
static char *clientOsExtra            = NULL;

if (clientBrowser == btUnknown)
    {
    char *userAgent = cgiUserAgent();
    if (userAgent != NULL)
        {
        //warn(userAgent);  // Use this to investigate other cases
        char *ptr=NULL;

        // Determine the browser
        if ((ptr = stringIn("Opera",userAgent)) != NULL) // Must be before IE
            {
            clientBrowser = btOpera;
            }
        else if ((ptr = stringIn("MSIE ",userAgent)) != NULL)
            {
            clientBrowser = btIE;
            ptr += strlen("MSIE ");
            clientBrowserExtra = cloneFirstWordByDelimiter(ptr,';');
            }
        else if ((ptr = stringIn("Firefox",userAgent)) != NULL)
            {
            clientBrowser = btFF;
            ptr += strlen("(Firefox/");
            clientBrowserExtra = cloneFirstWordByDelimiter(ptr,' ');
            }
        else if ((ptr = stringIn("Chrome",userAgent)) != NULL)  // Must be before Safari
            {
            clientBrowser = btChrome;
            ptr += strlen("Chrome/");
            clientBrowserExtra = cloneFirstWordByDelimiter(ptr,' ');
            }
        else if ((ptr = stringIn("Safari",userAgent)) != NULL)
            {
            clientBrowser = btSafari;
            ptr += strlen("Safari/");
            clientBrowserExtra = cloneFirstWordByDelimiter(ptr,' ');
            }
        else
            {
            clientBrowser = btOther;
            }

        // Determine the OS
        if ((ptr = stringIn("Windows",userAgent)) != NULL)
            {
            clientOsType = (enum browserType)osWindows;
            ptr += strlen("Windows ");
            clientOsExtra = cloneFirstWordByDelimiter(ptr,';');
            }
        else if ((ptr = stringIn("Linux",userAgent)) != NULL)
            {
            clientOsType = (enum browserType)osLinux;
            ptr += strlen("Linux ");
            clientOsExtra = cloneFirstWordByDelimiter(ptr,';');
            }
        else if ((ptr = stringIn("Mac ",userAgent)) != NULL)
            {
            clientOsType = (enum browserType)osMac;
            ptr += strlen("Mac ");
            clientOsExtra = cloneFirstWordByDelimiter(ptr,';');
            }
        else
            {
            clientOsType = (enum browserType)osOther;
            }
        }
    }
if (browserQualifier != NULL)
    {
    if (clientBrowserExtra != NULL)
        *browserQualifier = cloneString(clientBrowserExtra);
    else
        *browserQualifier = NULL;
    }
if (clientOs != NULL)
    *clientOs = (enum osType)clientOsType;
if (clientOsQualifier != NULL)
    {
    if (clientOsExtra != NULL)
        *clientOsQualifier = cloneString(clientOsExtra);
    else
        *clientOsQualifier = NULL;
    }

return clientBrowser;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
cmpl $0x0, 0xa7a11(%rip)     # 0x10a68c
jne 0x62ee4
callq 0x62c40
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x62ee2
movq $0x0, -0x28(%rbp)
movq -0x20(%rbp), %rdi
leaq 0x7cf1c(%rip), %rsi     # 0xdfbc4
callq 0x6170
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x62cc6
movl $0x1, 0xa79cb(%rip)     # 0x10a68c
jmp 0x62dfa
movq -0x20(%rbp), %rdi
leaq 0x7cef9(%rip), %rsi     # 0xdfbca
callq 0x6170
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x62d10
movl $0x2, 0xa79a2(%rip)     # 0x10a68c
movq -0x28(%rbp), %rax
addq $0x5, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movl $0x3b, %esi
callq 0x2f480
movq %rax, 0xa798d(%rip)     # 0x10a698
jmp 0x62df8
movq -0x20(%rbp), %rdi
leaq 0x7ceb5(%rip), %rsi     # 0xdfbd0
callq 0x6170
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x62d5a
movl $0x3, 0xa7958(%rip)     # 0x10a68c
movq -0x28(%rbp), %rax
addq $0x9, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movl $0x20, %esi
callq 0x2f480
movq %rax, 0xa7943(%rip)     # 0x10a698
jmp 0x62df6
movq -0x20(%rbp), %rdi
leaq 0x7ce73(%rip), %rsi     # 0xdfbd8
callq 0x6170
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x62da1
movl $0x4, 0xa790e(%rip)     # 0x10a68c
movq -0x28(%rbp), %rax
addq $0x7, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movl $0x20, %esi
callq 0x2f480
movq %rax, 0xa78f9(%rip)     # 0x10a698
jmp 0x62df4
movq -0x20(%rbp), %rdi
leaq 0x7ce33(%rip), %rsi     # 0xdfbdf
callq 0x6170
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x62de8
movl $0x5, 0xa78c7(%rip)     # 0x10a68c
movq -0x28(%rbp), %rax
addq $0x7, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movl $0x20, %esi
callq 0x2f480
movq %rax, 0xa78b2(%rip)     # 0x10a698
jmp 0x62df2
movl $0x6, 0xa789a(%rip)     # 0x10a68c
jmp 0x62df4
jmp 0x62df6
jmp 0x62df8
jmp 0x62dfa
movq -0x20(%rbp), %rdi
leaq 0x7cde1(%rip), %rsi     # 0xdfbe6
callq 0x6170
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x62e44
movl $0x1, 0xa7872(%rip)     # 0x10a690
movq -0x28(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movl $0x3b, %esi
callq 0x2f480
movq %rax, 0xa7861(%rip)     # 0x10a6a0
jmp 0x62ee0
movq -0x20(%rbp), %rdi
leaq 0x7cd9f(%rip), %rsi     # 0xdfbee
callq 0x6170
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x62e8b
movl $0x2, 0xa7828(%rip)     # 0x10a690
movq -0x28(%rbp), %rax
addq $0x6, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movl $0x3b, %esi
callq 0x2f480
movq %rax, 0xa7817(%rip)     # 0x10a6a0
jmp 0x62ede
movq -0x20(%rbp), %rdi
leaq 0x7cd5e(%rip), %rsi     # 0xdfbf4
callq 0x6170
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
je 0x62ed2
movl $0x3, 0xa77e1(%rip)     # 0x10a690
movq -0x28(%rbp), %rax
addq $0x4, %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
movl $0x3b, %esi
callq 0x2f480
movq %rax, 0xa77d0(%rip)     # 0x10a6a0
jmp 0x62edc
movl $0x4, 0xa77b4(%rip)     # 0x10a690
jmp 0x62ede
jmp 0x62ee0
jmp 0x62ee2
jmp 0x62ee4
cmpq $0x0, -0x8(%rbp)
je 0x62f1a
cmpq $0x0, 0xa77a5(%rip)     # 0x10a698
je 0x62f0d
movq 0xa779c(%rip), %rdi     # 0x10a698
callq 0x2a450
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
jmp 0x62f18
movq -0x8(%rbp), %rax
movq $0x0, (%rax)
jmp 0x62f1a
cmpq $0x0, -0x10(%rbp)
je 0x62f2d
movl 0xa7769(%rip), %ecx     # 0x10a690
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
cmpq $0x0, -0x18(%rbp)
je 0x62f63
cmpq $0x0, 0xa7764(%rip)     # 0x10a6a0
je 0x62f56
movq 0xa775b(%rip), %rdi     # 0x10a6a0
callq 0x2a450
movq %rax, %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x62f61
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
jmp 0x62f63
movl 0xa7723(%rip), %eax     # 0x10a68c
addq $0x30, %rsp
popq %rbp
retq
nop