// File: /workspace/github_c_makefile_star2_O2/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 $0x98, %rsp
movq %rsi, %r14
movq %rdi, %rbx
cmpl $0x0, 0x20d8b(%rip)     # 0x2b38c
jle 0xa620
leaq 0xb609(%rip), %rdi      # 0x15c13
leaq 0x9ccd(%rip), %rsi      # 0x142de
movl $0xac0, %edx            # imm = 0xAC0
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc2a1
movq %r14, %rdi
callq 0x2110
movq %rax, %r15
movq %rax, %r13
shlq $0x20, %r13
movabsq $0x100000000, %r12      # imm = 0x100000000
addq %r13, %r12
sarq $0x20, %r12
movq %r12, %rdi
callq 0x22a0
movq %rax, 0x8(%rsp)
movq %rax, %rdi
movq %r14, %rsi
movq %r12, %rdx
callq 0xba3e
cmpl $0x0, 0x20d27(%rip)     # 0x2b38c
jle 0xa684
leaq 0xb5d8(%rip), %rdi      # 0x15c46
leaq 0x9c69(%rip), %rsi      # 0x142de
movl $0xacb, %edx            # imm = 0xACB
movl %r15d, %ecx
xorl %eax, %eax
callq 0xc2a1
movq %r14, %rdi
callq 0x803b
sarq $0x20, %r13
addq %r14, %r13
leaq 0x5efd(%rbx), %rax
movq %rax, (%rsp)
testq %r14, %r14
je 0xa919
movq %r14, %r12
cmpq %r13, %r14
ja 0xa919
cmpl $0x0, 0x20cd2(%rip)     # 0x2b38c
jle 0xa6d9
leaq 0xb5b7(%rip), %rdi      # 0x15c7a
leaq 0x9c14(%rip), %rsi      # 0x142de
movl $0xada, %edx            # imm = 0xADA
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
movq %r12, %rdi
leaq 0xb5ca(%rip), %rsi      # 0x15cad
callq 0x2300
movq %rax, %r15
testq %rax, %rax
jne 0xa761
cmpl $0x0, 0x20c95(%rip)     # 0x2b38c
jle 0xa723
leaq 0xb5b1(%rip), %rdi      # 0x15cb1
leaq 0x9bd7(%rip), %rsi      # 0x142de
movl $0xaea, %edx            # imm = 0xAEA
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
cmpl $0x0, 0x20c6f(%rip)     # 0x2b38c
setg %bpl
jmp 0xa725
xorl %ebp, %ebp
movq %r12, %rdi
leaq 0xaeba(%rip), %rsi      # 0x155e9
callq 0x2300
movq %rax, %r15
testq %rax, %rax
jne 0xa761
testb %bpl, %bpl
je 0xa761
leaq 0xb5cb(%rip), %rdi      # 0x15d13
leaq 0x9b8f(%rip), %rsi      # 0x142de
movl $0xaee, %edx            # imm = 0xAEE
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
xorl %r15d, %r15d
movq %r12, %rdi
leaq 0xc612(%rip), %rsi      # 0x16d7d
callq 0x2300
movl $0x0, %r14d
testq %rax, %rax
je 0xa69e
movq %rax, %r14
movzbl (%r14), %eax
cmpl $0xd, %eax
je 0xa790
cmpl $0xa, %eax
jne 0xa795
incq %r14
jmp 0xa782
testq %r15, %r15
setne %al
cmpq %r14, %r15
setbe %cl
testb %cl, %al
jne 0xa7d4
cmpl $0x0, 0x20be0(%rip)     # 0x2b38c
jle 0xa69e
leaq 0xb5aa(%rip), %rdi      # 0x15d63
leaq 0x9b1e(%rip), %rsi      # 0x142de
movl $0xb15, %edx            # imm = 0xB15
movq %r14, %rcx
xorl %eax, %eax
callq 0xc2a1
jmp 0xa69e
leaq 0x1(%r15), %rbp
movq %rbp, %rdi
leaq 0xc59b(%rip), %rsi      # 0x16d7d
callq 0x2300
testq %rax, %rax
je 0xa8ed
xorl %ecx, %ecx
movb %cl, (%r15)
movb %cl, (%rax)
cmpl $0x0, 0x20b8e(%rip)     # 0x2b38c
jle 0xa839
leaq 0xb5aa(%rip), %rdi      # 0x15db1
leaq 0x9ad0(%rip), %r15      # 0x142de
movq %r15, %rsi
movl $0xb26, %edx            # imm = 0xB26
movq %r12, %rcx
xorl %eax, %eax
callq 0xc2a1
leaq 0xb5bd(%rip), %rdi      # 0x15de4
movq %r15, %rsi
movl $0xb27, %edx            # imm = 0xB27
movq %rbp, %rcx
xorl %eax, %eax
callq 0xc2a1
movq %r12, %rdi
callq 0xba23
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa4cf
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x9590
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x9e71
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa0df
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa516
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa52f
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa548
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa561
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa57a
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa593
cmpb $0x0, 0x5efd(%rbx)
jne 0xa69e
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x9d4d
jmp 0xa69e
cmpl $0x0, 0x20a98(%rip)     # 0x2b38c
jle 0xa69e
leaq 0xb516(%rip), %rdi      # 0x15e17
leaq 0x99d6(%rip), %rsi      # 0x142de
movl $0xb46, %edx            # imm = 0xB46
xorl %eax, %eax
callq 0xc2a1
jmp 0xa69e
movl 0x27f8(%rbx), %eax
cmpl $0x66, %eax
jne 0xa981
leaq 0xb530(%rip), %rdx      # 0x15e5b
leaq 0x10(%rsp), %r14
movl $0x80, %esi
movq %r14, %rdi
movq (%rsp), %r12
movq %r12, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0xc713(%rip), %r15      # 0x17060
movl $0x1001, %esi           # imm = 0x1001
movq %r12, %rdi
movq %r15, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0x6efe(%rbx), %rdi
movl $0x27f7, %esi           # imm = 0x27F7
movq %r15, %rdx
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movl 0x27f8(%rbx), %eax
cmpl $0x320, %eax            # imm = 0x320
jne 0xa9aa
movl 0x166f8(%rbx), %eax
incl %eax
cmpl $0x2, %eax
jae 0xa9a1
movl $0x68, 0x166f8(%rbx)
jmp 0xa9aa
cmpb $0x0, 0x166fc(%rbx)
je 0xa995
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0xa9bb
callq 0x2030
jmp 0xa9d5
leaq 0xb4a0(%rip), %rdi      # 0x15e62
leaq 0x9915(%rip), %rsi      # 0x142de
movl $0xb6d, %edx            # imm = 0xB6D
xorl %eax, %eax
callq 0xc2a1
cmpl $0x0, 0x209b0(%rip)     # 0x2b38c
jle 0xa9fb
leaq 0xb4c8(%rip), %rdi      # 0x15ead
leaq 0x98f2(%rip), %rsi      # 0x142de
movl $0xb6f, %edx            # imm = 0xB6F
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc2a1
xorl %eax, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq