; _______________________________________________________________________________________
;|                                                                                       |
;| ..::FreshLib::..  Free, open source. Licensed under "BSD 2-clause" license."          |
;|_______________________________________________________________________________________|
;
;  Description: Linux environment management library.
;
;  Target OS: Linux
;
;  Dependencies:
;
;  Notes:
;_________________________________________________________________________________________


uglobal
  var _ptrEnvironment = ?
endg


if used _ptrEnvironment
initialize LinuxEnvironmentLibrary
begin
        lea     eax, [esp+4]
        mov     [_ptrEnvironment], eax
        return
endp
end if



proc GetAllEnvironment
.return dd ?
begin
        pushad

        mov     [.return], 0
        mov     eax, [_ptrEnvironment]
        test    eax, eax
        jz      .finish

        mov     ecx, [eax]              ; argument count

        lea     eax, [eax+4*ecx+8]      ; env table.

        mov     esi, [eax]
        test    esi, esi
        jz      .finish

        push    esi

.end_loop:
        cmp     word [esi], 0
        lea     esi, [esi+1]
        jne     .end_loop

        stc
        sbb     esi, [esp]
        lea     ecx, [esi+8]

        stdcall GetMem, ecx
        mov     [.return], eax
        mov     edi, eax
        mov     ecx, esi
        pop     esi
        rep movsb
        xor     eax, eax
        stosd

.finish:
        popad
        mov     eax, [.return]
        return
endp



proc GetEnvVariable, .varname
begin
        push    ebx ecx edx esi edi

        mov     esi, [_ptrEnvironment]         ; points to argc
        mov     eax, [esi]                     ; argc
        lea     esi, [esi+4*eax+8]             ; pointer to the first env pointer.

        stdcall StrPtr, [.varname]
        mov     ebx, eax

.outer:
        mov     edx, [esi]
        lea     esi, [esi+4]

        test    edx, edx                       ; last env element?
        jz      .not_found

        mov     edi, ebx                       ; ptr to name.

.inner:
        mov     al, [edx]
        mov     ah, [edi]
        lea     edx, [edx+1]
        lea     edi, [edi+1]

        test    ah, ah
        jnz     .check_al

        cmp     al, '='
        je      .found

.check_al:
        test    al, al
        jz      .outer

        cmp     al, ah
        je      .inner
        jmp     .outer

.not_found:
        xor     eax, eax
        stc
        pop     edi esi edx ecx ebx
        return

.found:
        stdcall StrDupMem, edx
        pop     edi esi edx ecx ebx
        clc
        return
endp