// File: /workspace/github_c_makefile_star2_O2/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 %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq %rsi, %r14
movq %rdi, %r15
cmpl $0x0, 0x7a203(%rip)     # 0xb8268
jne 0x3e1bd
callq 0x3e041
testq %rax, %rax
je 0x3e1bd
movq %rax, %r12
leaq 0x46bb4(%rip), %rsi     # 0x84c37
movq %rax, %rdi
callq 0x6180
testq %rax, %rax
je 0x3e09f
movl $0x1, 0x7a1ce(%rip)     # 0xb8268
jmp 0x3e141
leaq 0x46b97(%rip), %rsi     # 0x84c3d
movq %r12, %rdi
callq 0x6180
testq %rax, %rax
je 0x3e0c5
movl $0x2, 0x7a1ab(%rip)     # 0xb8268
addq $0x5, %rax
pushq $0x3b
jmp 0x3e131
leaq 0x46b77(%rip), %rsi     # 0x84c43
movq %r12, %rdi
callq 0x6180
testq %rax, %rax
je 0x3e0e9
movl $0x3, 0x7a185(%rip)     # 0xb8268
addq $0x9, %rax
jmp 0x3e12f
leaq 0x46b5b(%rip), %rsi     # 0x84c4b
movq %r12, %rdi
callq 0x6180
testq %rax, %rax
je 0x3e109
movl $0x4, 0x7a161(%rip)     # 0xb8268
jmp 0x3e12b
leaq 0x46b42(%rip), %rsi     # 0x84c52
movq %r12, %rdi
callq 0x6180
testq %rax, %rax
je 0x3e223
movl $0x5, 0x7a13d(%rip)     # 0xb8268
addq $0x7, %rax
pushq $0x20
popq %rsi
movq %rax, %rdi
callq 0x1eaee
movq %rax, 0x7a12f(%rip)     # 0xb8270
leaq 0x46b11(%rip), %rsi     # 0x84c59
movq %r12, %rdi
callq 0x6180
testq %rax, %rax
je 0x3e165
movl $0x1, 0x7a10d(%rip)     # 0xb826c
addq $0x8, %rax
jmp 0x3e1ab
leaq 0x46af5(%rip), %rsi     # 0x84c61
movq %r12, %rdi
callq 0x6180
testq %rax, %rax
je 0x3e189
movl $0x2, 0x7a0e9(%rip)     # 0xb826c
addq $0x6, %rax
jmp 0x3e1ab
leaq 0x46ad7(%rip), %rsi     # 0x84c67
movq %r12, %rdi
callq 0x6180
testq %rax, %rax
je 0x3e217
movl $0x3, 0x7a0c5(%rip)     # 0xb826c
addq $0x4, %rax
pushq $0x3b
popq %rsi
movq %rax, %rdi
callq 0x1eaee
movq %rax, 0x7a0bb(%rip)     # 0xb8278
testq %r15, %r15
je 0x3e1da
movq 0x7a0a7(%rip), %rdi     # 0xb8270
testq %rdi, %rdi
je 0x3e1d5
callq 0x1c306
jmp 0x3e1d7
xorl %eax, %eax
movq %rax, (%r15)
testq %r14, %r14
je 0x3e1e8
movl 0x7a087(%rip), %eax     # 0xb826c
movl %eax, (%r14)
testq %rbx, %rbx
je 0x3e205
movq 0x7a084(%rip), %rdi     # 0xb8278
testq %rdi, %rdi
je 0x3e200
callq 0x1c306
jmp 0x3e202
xorl %eax, %eax
movq %rax, (%rbx)
movl 0x7a05d(%rip), %eax     # 0xb8268
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
movl $0x4, 0x7a04b(%rip)     # 0xb826c
jmp 0x3e1bd
movl $0x6, 0x7a03b(%rip)     # 0xb8268
jmp 0x3e141