// File: /workspace/github_c_makefile_star2_O3/inflex[P]ripMIME/MIME_headers.c
// Function: MIMEH_headers_process
int MIMEH_headers_process( struct MIMEH_header_info *hinfo, char *headers )
{
    /** scan through our headers string looking for information that is
     ** valid **/
    char *safeh, *h, *safehl;
    char *current_header_position;
    int headerlength;

    if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_headers:DEBUG: Start [hinfo=%p]\n",FL, hinfo);

    safeh = h = headers;

    /** Duplicate the headers for processing - this way we don't 'taint' the
     ** original headers during our searching / altering. **/

    headerlength = strlen(h);
    safehl = malloc(sizeof(char) *(headerlength+1));
    PLD_strncpy(safehl, h, headerlength+1);

    if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIME_parse_headers:DEBUG: Header length = %d\n", FL,headerlength);

    MIMEH_strip_comments(h);

    current_header_position = h;

    // Searching through the headers, we seek out header 'name:value;value;value' sets,
    //      Each set is then cleaned up, seperated and parsed.

    while ((current_header_position != NULL)&&( current_header_position <= (h +headerlength) ))
    {
        char *header_name, *header_value;
        char *header_name_end_position;
        char *header_value_end_position;

        DMIMEH LOGGER_log("%s:%d:MIMEH_headers_process:DEBUG: Processing '%s'",FL,current_header_position);

        /** Tokenise for the header 'name', ie, content-type, subject etc **/
        header_name = current_header_position;
        header_name_end_position = strpbrk( header_name, ":\t " );
        if (header_name_end_position == NULL)
        {
            // We couldn't find a terminating :, so, instead we try to find
            //  the first whitespace
            //
            // PLD:DEV:11/08/2004-15H27
            //  Issue: c030804-006a
            //
            // NOTE: this may activate on the true-blank lines, hence why we
            //      dump the source string, just for confirmation

            DMIMEH LOGGER_log("%s:%d:MIMEH_headers_process:DEBUG: Could not locate ':' separator, using whitespace (source='%s')",FL,header_name);
            header_name_end_position = strpbrk( header_name, "\t " );
            if (header_name_end_position == NULL)
            {
                DMIMEH LOGGER_log("%s:%d:MIMEH_headers_process:DEBUG: Cannot find a header name:value pair in '%s'",FL, header_name);
            }
        }

        // Seek forward from the start of our header, looking for the first occurance
        //      of the line end (implying the end of the current header name:value,
        //      we can do this because we know that when the headers were read in, we
        //      have already unfolded them, such that there should only be one header:value
        //      pairing per 'line'.

        current_header_position = strpbrk( current_header_position, "\n\r");
        if ( current_header_position == NULL )
        {
            // Theoretically, this should not happen, as headers are always
            //      terminated with a \n\r\n\r finishing byte sequence, thus
            //      if this _does_ happen, then we will simply jump out of the
            //      current iteration and let the loop try find another pairing
            //
            // There probably should be a logging entry here to indicate that
            //      "something strange happened"

            continue;
        } else {

            // Shuffle our CHP (current-header-position) pointer along the header
            //      data until it is no longer pointing to a \r or \n, this is so
            //      that when the next iteration of this loop comes around, it'll
            //      immediately be in the right place for starting the next parse

            while (( *current_header_position == '\n') ||( *current_header_position == '\r' )) current_header_position++;
        }

        if (( header_name_end_position == NULL )||( header_name_end_position > current_header_position))
        {
            // Some headers can contain various levels of non name/value pairings,
            //      while their presence could be debatable in terms of RFC validity
            //      we will 'ignore' them rather than throwing up our arms.  This
            //      ensures that we are not made to break over spurilous data.

            if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_headers:DEBUG: This line contains no header:value pair (%s)", FL, current_header_position);
            continue;

        } else {

            // Get the header-value string and prepare to
            //      parse the data through our various parsing
            //      functions.

            header_value = header_name_end_position +1;
            header_value_end_position = strpbrk( header_value, "\n\r" );
            if ( header_value_end_position != NULL )
            {
                *header_name_end_position = '\0';
                *header_value_end_position = '\0';
                if (MIMEH_DNORMAL)
                {
                    LOGGER_log("%s:%d:MIMEH_parse_headers:DEBUG: Header Name ='%s'", FL, header_name );
                    LOGGER_log("%s:%d:MIMEH_parse_headers:DEBUG: Header Value='%s'", FL, header_value );
                }

                // To make parsing simpler, convert our
                //      header name to lowercase, that way
                //      we also reduce the CPU requirements for
                //      searching because pre-lowering the header-name
                //      occurs once, but string testing against it
                //      occurs multiple times ( at least once per parsing

                PLD_strlower( header_name );
                MIMEH_parse_subject( header_name, header_value, hinfo );
                MIMEH_parse_contenttype( header_name, header_value, hinfo );
                MIMEH_parse_contenttransferencoding( header_name, header_value, hinfo );
                MIMEH_parse_contentdisposition( header_name, header_value, hinfo );
                /** These items aren't really -imperative- to have, but they do
                 ** help with the sanity checking **/
                MIMEH_parse_date( header_name, header_value, hinfo );
                MIMEH_parse_from( header_name, header_value, hinfo );
                MIMEH_parse_to( header_name, header_value, hinfo );
                MIMEH_parse_messageid( header_name, header_value, hinfo );
                MIMEH_parse_received( header_name, header_value, hinfo );
                MIMEH_parse_charset( header_name, header_value, hinfo );


                if (hinfo->filename[0] == '\0')
                {
                    MIMEH_parse_contentlocation( header_name, header_value, hinfo );
                }

            } else {
                if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_headerss:DEBUG: Header value end position is NULL",FL);
            }
        }



    } // while

    // Final analysis on our headers:
    if ( hinfo->content_type == _CTYPE_MULTIPART_APPLEDOUBLE )
    {
        char tmp[128];
        snprintf( tmp, sizeof(tmp), "mac-%s", hinfo->filename );
        snprintf( hinfo->filename, sizeof(hinfo->filename), "%s", tmp );
        snprintf( hinfo->name, sizeof(hinfo->name), "%s", tmp );
    }

    // PLD:20031205
    // Act like Outlook *God forbid!* and if there's a octect-stream
    //  content-type, but the encoding is still null/empty, then
    //  change the content-encoding to be RAW

    if ( hinfo->content_type == _CTYPE_OCTECT )
    {
        if ((hinfo->content_transfer_encoding == _CTRANS_ENCODING_UNSPECIFIED)
                || (hinfo->content_transfer_encoding == _CTRANS_ENCODING_UNKNOWN)
                || (strlen(hinfo->content_transfer_encoding_string) < 1)
            )
        {
            //LOGGER_log("%s:%d:DEBUG: Encoding pair was octet but no encoding, filename=%s\n",FL,hinfo->filename);
            hinfo->content_transfer_encoding = _CTRANS_ENCODING_RAW;
        }
    }


    if (safehl)
    {
        free(safehl);
    }
    else LOGGER_log("%s:%d:MIME_parse_headers:WARNING: Unable to free HEADERS allocated memory\n", FL);

    if (MIMEH_DNORMAL) LOGGER_log("%s:%d:MIMEH_parse_headers:DEBUG: END [hinfo=%p]\n", FL, hinfo);

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, %rbp
movq %rdi, %rbx
cmpl $0x0, 0x21ab7(%rip)     # 0x2c38c
jle 0xa8f4
leaq 0xc335(%rip), %rdi      # 0x16c13
leaq 0xa9f9(%rip), %rsi      # 0x152de
movl $0xac0, %edx            # imm = 0xAC0
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc84f
movq %rbp, %rdi
callq 0x2110
movq %rax, %r14
movq %rax, %r13
shlq $0x20, %r13
movabsq $0x100000000, %r15      # imm = 0x100000000
addq %r13, %r15
sarq $0x20, %r15
movq %r15, %rdi
callq 0x22a0
movq %rax, 0x8(%rsp)
movq %rax, %rdi
movq %rbp, %rsi
movq %r15, %rdx
callq 0xbede
cmpl $0x0, 0x21a53(%rip)     # 0x2c38c
jle 0xa958
leaq 0xc304(%rip), %rdi      # 0x16c46
leaq 0xa995(%rip), %rsi      # 0x152de
movl $0xacb, %edx            # imm = 0xACB
movl %r14d, %ecx
xorl %eax, %eax
callq 0xc84f
movq %rbp, %rdi
callq 0x82ba
sarq $0x20, %r13
testq %rbp, %rbp
setne %al
testq %r13, %r13
setns %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0xacdb
addq %rbp, %r13
leaq 0x59fc(%rbx), %rax
movq %rax, 0x38(%rsp)
leaq 0xbeec(%rbx), %rax
movq %rax, 0x30(%rsp)
leaq 0x96f5(%rbx), %rax
movq %rax, 0x28(%rsp)
leaq 0xe6e3(%rbx), %rax
movq %rax, 0x20(%rsp)
leaq 0x10eda(%rbx), %rax
movq %rax, 0x18(%rsp)
leaq 0x136d1(%rbx), %rax
movq %rax, 0x10(%rsp)
movq %rbp, %r14
cmpl $0x0, 0x219bc(%rip)     # 0x2c38c
jle 0xa9ef
leaq 0xc2a1(%rip), %rdi      # 0x16c7a
leaq 0xa8fe(%rip), %rsi      # 0x152de
movl $0xada, %edx            # imm = 0xADA
movq %r14, %rcx
xorl %eax, %eax
callq 0xc84f
movq %r14, %rdi
leaq 0xc2b4(%rip), %rsi      # 0x16cad
callq 0x22f0
movq %rax, %r12
testq %rax, %rax
je 0xac1e
movq %r14, %rdi
leaq 0xd369(%rip), %rsi      # 0x17d7d
callq 0x22f0
testq %rax, %rax
je 0xacdb
movq %rax, %rbp
movzbl (%rbp), %eax
cmpl $0xd, %eax
je 0xaa33
cmpl $0xa, %eax
jne 0xaa38
incq %rbp
jmp 0xaa25
testq %r12, %r12
setne %al
cmpq %rbp, %r12
setbe %cl
testb %cl, %al
jne 0xaa77
cmpl $0x0, 0x2193d(%rip)     # 0x2c38c
jle 0xacb9
leaq 0xc307(%rip), %rdi      # 0x16d63
leaq 0xa87b(%rip), %rsi      # 0x152de
movl $0xb15, %edx            # imm = 0xB15
movq %rbp, %rcx
xorl %eax, %eax
callq 0xc84f
jmp 0xacb9
leaq 0x1(%r12), %r15
movq %r15, %rdi
leaq 0xd2f7(%rip), %rsi      # 0x17d7d
callq 0x22f0
testq %rax, %rax
je 0xac96
xorl %ecx, %ecx
movb %cl, (%r12)
movb %cl, (%rax)
cmpl $0x0, 0x218e9(%rip)     # 0x2c38c
jle 0xaade
leaq 0xc305(%rip), %rdi      # 0x16db1
leaq 0xa82b(%rip), %r12      # 0x152de
movq %r12, %rsi
movl $0xb26, %edx            # imm = 0xB26
movq %r14, %rcx
xorl %eax, %eax
callq 0xc84f
leaq 0xc318(%rip), %rdi      # 0x16de4
movq %r12, %rsi
movl $0xb27, %edx            # imm = 0xB27
movq %r15, %rcx
xorl %eax, %eax
callq 0xc84f
movq %r14, %rdi
callq 0xbeb9
movl $0x501, %r9d            # imm = 0x501
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
leaq 0xc0b0(%rip), %rcx      # 0x16bac
movq 0x38(%rsp), %r12
movq %r12, %r8
callq 0xa660
movl $0x27f7, %esi           # imm = 0x27F7
leaq 0x1f061(%rip), %rdi     # 0x29b76
leaq 0xd544(%rip), %rdx      # 0x18060
movq %r12, %rcx
xorl %eax, %eax
callq 0x2140
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x97d2
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0xa13a
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0xa3a8
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
leaq 0xc04e(%rip), %rcx      # 0x16bb4
movq 0x30(%rsp), %r8
callq 0xa660
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
leaq 0xc033(%rip), %rcx      # 0x16bb9
movq 0x28(%rsp), %r8
callq 0xa660
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
leaq 0xc018(%rip), %rcx      # 0x16bbe
movq 0x20(%rsp), %r8
callq 0xa660
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
leaq 0xbffb(%rip), %rcx      # 0x16bc1
movq 0x18(%rsp), %r8
callq 0xa660
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
leaq 0xbfe6(%rip), %rcx      # 0x16bcc
movq 0x10(%rsp), %r8
callq 0xa660
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0xa867
cmpb $0x0, 0x5efd(%rbx)
jne 0xacb9
movq %r14, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0xa01f
jmp 0xacb9
cmpl $0x0, 0x21767(%rip)     # 0x2c38c
jle 0xacc4
leaq 0xc07f(%rip), %rdi      # 0x16cb1
leaq 0xa6a5(%rip), %rsi      # 0x152de
movl $0xaea, %edx            # imm = 0xAEA
movq %r14, %rcx
xorl %eax, %eax
callq 0xc84f
movl 0x2173e(%rip), %ebp     # 0x2c38c
movq %r14, %rdi
leaq 0xb991(%rip), %rsi      # 0x165e9
callq 0x22f0
movq %rax, %r12
testq %rax, %rax
jne 0xaa0a
testl %ebp, %ebp
jle 0xaa0a
leaq 0xc09b(%rip), %rdi      # 0x16d13
leaq 0xa65f(%rip), %rsi      # 0x152de
movl $0xaee, %edx            # imm = 0xAEE
movq %r14, %rcx
xorl %eax, %eax
callq 0xc84f
xorl %r12d, %r12d
jmp 0xaa0a
cmpl $0x0, 0x216ef(%rip)     # 0x2c38c
jle 0xacb9
leaq 0xc171(%rip), %rdi      # 0x16e17
leaq 0xa631(%rip), %rsi      # 0x152de
movl $0xb46, %edx            # imm = 0xB46
xorl %eax, %eax
callq 0xc84f
cmpq %r13, %rbp
jbe 0xa9c6
jmp 0xacdb
movq %r14, %rdi
leaq 0xb91b(%rip), %rsi      # 0x165e9
callq 0x22f0
movq %rax, %r12
jmp 0xaa0a
movl 0x27f8(%rbx), %eax
cmpl $0x66, %eax
jne 0xad46
leaq 0x5efd(%rbx), %r14
leaq 0xc167(%rip), %rdx      # 0x16e5b
leaq 0x40(%rsp), %r15
movl $0x80, %esi
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0xd34e(%rip), %r12      # 0x18060
movl $0x1001, %esi           # imm = 0x1001
movq %r14, %rdi
movq %r12, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0x6efe(%rbx), %rdi
movl $0x27f7, %esi           # imm = 0x27F7
movq %r12, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x2140
movl 0x27f8(%rbx), %eax
cmpl $0x320, %eax            # imm = 0x320
jne 0xad6f
movl 0x166f8(%rbx), %eax
incl %eax
cmpl $0x2, %eax
jae 0xad66
movl $0x68, 0x166f8(%rbx)
jmp 0xad6f
cmpb $0x0, 0x166fc(%rbx)
je 0xad5a
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0xad80
callq 0x2030
jmp 0xad9a
leaq 0xc0db(%rip), %rdi      # 0x16e62
leaq 0xa550(%rip), %rsi      # 0x152de
movl $0xb6d, %edx            # imm = 0xB6D
xorl %eax, %eax
callq 0xc84f
cmpl $0x0, 0x215eb(%rip)     # 0x2c38c
jle 0xadc0
leaq 0xc103(%rip), %rdi      # 0x16ead
leaq 0xa52d(%rip), %rsi      # 0x152de
movl $0xb6f, %edx            # imm = 0xB6F
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc84f
xorl %eax, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq