// File: /workspace/github_c_makefile_star2_O1/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, %r12
movq %rdi, %rbx
cmpl $0x0, 0x219f3(%rip)     # 0x2c38c
jle 0xa9b8
leaq 0xc241(%rip), %rdi      # 0x16be3
leaq 0xa905(%rip), %rsi      # 0x152ae
movl $0xac0, %edx            # imm = 0xAC0
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc960
movq %r12, %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 0x22b0
movq %rax, 0x8(%rsp)
movq %rax, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0xbfb6
cmpl $0x0, 0x2198f(%rip)     # 0x2c38c
jle 0xaa1c
leaq 0xc210(%rip), %rdi      # 0x16c16
leaq 0xa8a1(%rip), %rsi      # 0x152ae
movl $0xacb, %edx            # imm = 0xACB
movl %r14d, %ecx
xorl %eax, %eax
callq 0xc960
movq %r12, %rdi
callq 0x8368
sarq $0x20, %r13
testq %r12, %r12
setne %al
testq %r13, %r13
setns %cl
andb %al, %cl
cmpb $0x1, %cl
jne 0xad79
addq %r12, %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)
leaq 0xc1b9(%rip), %rbp      # 0x16c4a
cmpl $0x0, 0x218f4(%rip)     # 0x2c38c
jle 0xaab3
movq %rbp, %rdi
leaq 0xa80a(%rip), %rsi      # 0x152ae
movl $0xada, %edx            # imm = 0xADA
movq %r12, %rcx
xorl %eax, %eax
callq 0xc960
movq %r12, %rdi
leaq 0xc1c0(%rip), %rsi      # 0x16c7d
callq 0x2300
movq %rax, %r14
testq %rax, %rax
jne 0xab30
cmpl $0x0, 0x218bb(%rip)     # 0x2c38c
jle 0xaaf0
leaq 0xc1a7(%rip), %rdi      # 0x16c81
leaq 0xa7cd(%rip), %rsi      # 0x152ae
movl $0xaea, %edx            # imm = 0xAEA
movq %r12, %rcx
xorl %eax, %eax
callq 0xc960
movq %r12, %rdi
leaq 0xbabf(%rip), %rsi      # 0x165b9
callq 0x2300
movq %rax, %r14
testq %rax, %rax
jne 0xab30
cmpl $0x0, 0x2187e(%rip)     # 0x2c38c
jle 0xab30
leaq 0xc1cc(%rip), %rdi      # 0x16ce3
leaq 0xa790(%rip), %rsi      # 0x152ae
movl $0xaee, %edx            # imm = 0xAEE
movq %r12, %rcx
xorl %eax, %eax
callq 0xc960
xorl %r14d, %r14d
movq %r12, %rdi
leaq 0xd270(%rip), %rsi      # 0x17daa
callq 0x2300
testq %rax, %rax
je 0xab98
movq %rax, %r15
movzbl (%r15), %eax
cmpl $0xd, %eax
je 0xab55
cmpl $0xa, %eax
jne 0xab5a
incq %r15
jmp 0xab47
testq %r14, %r14
setne %al
cmpq %r15, %r14
setbe %cl
testb %cl, %al
jne 0xaba0
cmpl $0x0, 0x2181b(%rip)     # 0x2c38c
jle 0xab90
leaq 0xc1b9(%rip), %rdi      # 0x16d33
leaq 0xa72d(%rip), %rsi      # 0x152ae
movl $0xb15, %edx            # imm = 0xB15
movq %r15, %rcx
xorl %eax, %eax
callq 0xc960
movq %r15, %r12
jmp 0xad6b
xorl %r12d, %r12d
jmp 0xad6b
leaq 0x1(%r14), %rbp
movq %rbp, %rdi
leaq 0xd1fc(%rip), %rsi      # 0x17daa
callq 0x2300
testq %rax, %rax
je 0xad3e
xorl %ecx, %ecx
movb %cl, (%r14)
movb %cl, (%rax)
cmpl $0x0, 0x217c2(%rip)     # 0x2c38c
jle 0xac05
leaq 0xc1ae(%rip), %rdi      # 0x16d81
leaq 0xa6d4(%rip), %r14      # 0x152ae
movq %r14, %rsi
movl $0xb26, %edx            # imm = 0xB26
movq %r12, %rcx
xorl %eax, %eax
callq 0xc960
leaq 0xc1c1(%rip), %rdi      # 0x16db4
movq %r14, %rsi
movl $0xb27, %edx            # imm = 0xB27
movq %rbp, %rcx
xorl %eax, %eax
callq 0xc960
movq %r12, %rdi
callq 0xbf91
movl $0x501, %r9d            # imm = 0x501
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
leaq 0xbf59(%rip), %rcx      # 0x16b7c
movq 0x38(%rsp), %r14
movq %r14, %r8
callq 0xa744
movl $0x27f7, %esi           # imm = 0x27F7
leaq 0x1ef3a(%rip), %rdi     # 0x29b76
leaq 0xd44a(%rip), %rdx      # 0x1808d
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x9928
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa208
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa487
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
leaq 0xbef7(%rip), %rcx      # 0x16b84
movq 0x30(%rsp), %r8
callq 0xa744
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
leaq 0xbedc(%rip), %rcx      # 0x16b89
movq 0x28(%rsp), %r8
callq 0xa744
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
leaq 0xbec1(%rip), %rcx      # 0x16b8e
movq 0x20(%rsp), %r8
callq 0xa744
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
leaq 0xbea4(%rip), %rcx      # 0x16b91
movq 0x18(%rsp), %r8
callq 0xa744
movl $0x27f7, %r9d           # imm = 0x27F7
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
leaq 0xbe8f(%rip), %rcx      # 0x16b9c
movq 0x10(%rsp), %r8
callq 0xa744
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa92b
cmpb $0x0, 0x5efd(%rbx)
jne 0xad61
movq %r12, %rdi
movq %rbp, %rsi
movq %rbx, %rdx
callq 0xa0e7
jmp 0xad61
cmpl $0x0, 0x21647(%rip)     # 0x2c38c
jle 0xad61
leaq 0xc099(%rip), %rdi      # 0x16de7
leaq 0xa559(%rip), %rsi      # 0x152ae
movl $0xb46, %edx            # imm = 0xB46
xorl %eax, %eax
callq 0xc960
movq %r15, %r12
leaq 0xbedf(%rip), %rbp      # 0x16c4a
testq %r12, %r12
je 0xad79
cmpq %r13, %r12
jbe 0xaa91
cmpl $0x66, 0x27f8(%rbx)
jne 0xaddc
leaq 0x5efd(%rbx), %r14
leaq 0xc09b(%rip), %rdx      # 0x16e2b
leaq 0x40(%rsp), %r15
movl $0x80, %esi
movq %r15, %rdi
movq %r14, %rcx
xorl %eax, %eax
callq 0x2140
leaq 0xd2df(%rip), %r12      # 0x1808d
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
cmpl $0x320, 0x27f8(%rbx)    # imm = 0x320
movq 0x8(%rsp), %rdi
jne 0xae0f
movl 0x166f8(%rbx), %eax
incl %eax
cmpl $0x2, %eax
jae 0xae06
movl $0x68, 0x166f8(%rbx)
jmp 0xae0f
cmpb $0x0, 0x166fc(%rbx)
je 0xadfa
testq %rdi, %rdi
je 0xae1b
callq 0x2030
jmp 0xae35
leaq 0xc010(%rip), %rdi      # 0x16e32
leaq 0xa485(%rip), %rsi      # 0x152ae
movl $0xb6d, %edx            # imm = 0xB6D
xorl %eax, %eax
callq 0xc960
cmpl $0x0, 0x21550(%rip)     # 0x2c38c
jle 0xae5b
leaq 0xc038(%rip), %rdi      # 0x16e7d
leaq 0xa462(%rip), %rsi      # 0x152ae
movl $0xb6f, %edx            # imm = 0xB6F
movq %rbx, %rcx
xorl %eax, %eax
callq 0xc960
xorl %eax, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq