File "zrok launcher.bas"

Path: /zrok launcher/zrok launcher.bas
File size: 22.39 KB
MIME-type:
Charset: utf-8

#COMPILE EXE
#DIM ALL
#RESOURCE "zrl.pbr"

#INCLUDE ONCE "win32api.inc"
#INCLUDE ONCE "inc\conspawn.inc"
#INCLUDE ONCE "inc\savepos.inc"
#INCLUDE ONCE "inc\pb_ftp.inc"
#INCLUDE ONCE "inc\ini.inc"
#INCLUDE ONCE "inc\centermsgbox.inc"

'------------------------
$VER = "1.0"
'------------------------
%IDC_GRAPHIC1 = 1001
%IDC_LABEL1   = 1002
%IDC_LABEL2   = 1003
%IDC_ICOCON   = 1004
%IDC_ICOINI   = 1005
%IDC_ICOPHP   = 1006
%IDC_ICOLOG   = 1007
'------------------------
GLOBAL g_hDlg   AS DWORD
GLOBAL g_FntN   AS DWORD
GLOBAL g_FntU   AS DWORD
GLOBAL g_FntS   AS DWORD
GLOBAL g_ftpUL  AS LONG
GLOBAL g_status AS LONG
GLOBAL g_stuck  AS LONG
GLOBAL g_msg    AS STRING
GLOBAL g_zParam AS STRING
GLOBAL g_phpSrc AS STRING
GLOBAL g_phpRpl AS STRING
GLOBAL g_ftpTgt AS STRING
GLOBAL g_ftpSrv AS STRING
GLOBAL g_ftpUsr AS STRING
GLOBAL g_ftpPwd AS STRING
GLOBAL g_AcoTkn AS STRING
GLOBAL g_editor AS STRING
'---------------------------------------------------------------------
MACRO DlgBgCol = GETSYSCOLOR(%COLOR_BTNFACE)
MACRO Npp_x86  = RTRIM$(ENVIRON$("ProgramFiles"), "\") + "\Notepad++\"
MACRO Npp_w64  = RTRIM$(ENVIRON$("ProgramW6432"), "\") + "\Notepad++\"
MACRO This_Bat = ENVIRON$("APPDATA") + "\" + EXE.NAME$ + ".bat"
'---------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Main Application Entry Point **
'------------------------------------------------------------------------------
FUNCTION PBMAIN () AS LONG
    LOCAL npp AS STRING

    ' Reset some files
    KILL EXE.NAME$ + ".log"
    KILL This_Bat

    ' Find Notepad++ if installed on the system
    npp = "notepad++.exe"
    g_editor = DIR$(Npp_w64 + npp) : DIR$ CLOSE     ' try Npp_w64 first
    IF g_editor <> "" THEN
        g_editor = Npp_w64 + npp + $SPC
    ELSE
        g_editor = DIR$(Npp_x86 + npp) : DIR$ CLOSE ' then try Npp_x86
        IF g_editor <> "" THEN
            g_editor = Npp_x86 + npp + $SPC
        ELSE
            g_editor = "notepad "                   ' none found: use windows notepad
        END IF
    END IF

    ' Start dialog
    ShowDIALOG()
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
SUB CON_HANDLER(BYVAL txt AS STRING)
    STATIC otxt AS STRING
    LOCAL zurl, buf AS STRING
    LOCAL i, ff, hSocket AS LONG

    IF txt = "<end>" THEN           ' zrok failure (fatal)
        g_msg = "zrok internal error"
        LogMe g_msg
        LogMe "Last zrok content received:"
        IF TRIM$(otxt) = "" THEN    ' nothing happened > try to learn a little more
            ff = FREEFILE
            OPEN "ztemp.bat" FOR OUTPUT AS #ff
            PRINT #ff, "zrok.exe share public localhost:80 > ztemp.out 2>&1"
            CLOSE #ff
            SHELL "ztemp.bat", 0
            KILL "ztemp.bat"
            ff = FREEFILE
            OPEN "ztemp.out" FOR BINARY AS #ff
            GET$ #ff, LOF(#ff), otxt
            CLOSE #ff
            KILL "ztemp.out"
            IF INSTR(otxt, "shareUnauthorized") > 0 THEN g_stuck = 1
        END IF
        LogMe TRIM$(otxt)
        '>>>>><<<<<'
        g_status = 9
        '>>>>><<<<<'
        GOTO skip
    END IF

    IF g_status <> 1 THEN GOTO skip ' only continue if zrok is in starting phase

    ' Try to get url assigned by zrok
    i = INSTR(txt, "http")
    IF i = 0 THEN GOTO skip ' url not assigned yet > wait
    txt = MID$(txt, i)
    i = INSTR(txt, ".io")
    IF i = 0 THEN GOTO skip ' url not fully assigned yet > wait some more
    zurl = LEFT$(txt, i+LEN(".io")-1)
    LogMe "zrok correctly connected and serving at " + zurl
    g_msg = zurl

    ' No ftp upload requested > we're all good!
    IF ISFALSE g_ftpUL THEN
        LogMe "ftp upload disabled by user > skipping"
        '>>>>><<<<<'
        g_status = 2
        '>>>>><<<<<'
        GOTO skip
    END IF

    ' prepare proxy page for upload
    IF NOT EXISTS(g_phpSrc) THEN
        LogMe "ftp upload error: template " + $DQ + g_phpSrc + $DQ + " not found"
        g_msg += $CR + "service running but ftp uload failed"
        '>>>>><<<<<'
        g_status = 7 ' semi-error: zrok running but ftp upload failed
        '>>>>><<<<<'
        GOTO skip
    END IF

    ' bufferize template
    ff = FREEFILE
    OPEN g_phpSrc FOR BINARY AS #ff
    GET$ #ff, LOF(#ff), buf
    CLOSE #ff
    IF INSTR(buf, g_phpRpl) = 0 THEN
        LogMe "ftp upload error: replaced string " + $DQ + g_phpRpl + $DQ _
            + " not found in template " + $DQ + g_phpSrc + $DQ
        g_msg += $CR + "service running but ftp uload failed"
        '>>>>><<<<<'
        g_status = 7 ' semi-error: zrok running but ftp upload failed
        '>>>>><<<<<'
        GOTO skip
    END IF

    ' fill template into temp file
    REPLACE g_phpRpl WITH zurl IN buf
    KILL "zrltmp.php"
    ff = FREEFILE
    OPEN "zrltmp.php" FOR BINARY AS #ff
    PUT$ #ff, buf
    CLOSE #ff

    ' upload it to ftp server
    hSocket = ftpConnect(g_ftpSrv, g_ftpUsr, g_ftpPwd)
    IF hSocket = %INVALID_SOCKET THEN
        LogMe "ftp upload error: could not connect to " + g_ftpSrv _
            + " - invalid credentials ?"
        g_msg += $CR + "service running but ftp uload failed"
        '>>>>><<<<<'
        g_status = 7 ' semi-error: zrok running but ftp upload failed
        '>>>>><<<<<'
        GOTO skip
    END IF
    ftpPutFile hSocket, 0, g_ftpSrv, g_ftpTgt, "zrltmp.php"
    ftpQuit hSocket
    KILL "zrltmp.php"

    LogMe "Correctly changed zrok url in " + $DQ + g_phpSrc + $DQ _
        + " and uploaded it to " + g_ftpTgt + " @" + g_ftpSrv

    ' all done
    '>>>>><<<<<'
    g_status = 2
    '>>>>><<<<<'

    skip:
    otxt = txt

END SUB
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** CallBacks **
'------------------------------------------------------------------------------
CALLBACK FUNCTION ProcDialog()
    STATIC blink AS LONG
    STATIC zconv AS LONG
    LOCAL ctl, i, ff AS LONG
    LOCAL e AS STRING

    CB_SAVEPOS
    CON_CALLBACK

    SELECT CASE AS LONG CB.MSG

        CASE %WM_INITDIALOG
        '----------------------------------------------
            g_status = 0
            IF NOT EXISTS("zrok launcher.ini") THEN     ' First run > create ini and php
                MakeIni "zrok launcher.ini"
                MakePhp "zrok launcher.php"
                ?"This is your first time running zrok launcher."+$CR _
                    +$CR _
                    +"Click OK to open the settings file in an editor:"+$CR _
                    +"make sure to change the settings as needed, then"+$CR _
                    +"re-launch zrok launcher.", %MB_ICONINFORMATION, EXE.NAME$
                ctl = SHELL(g_editor + $DQ + "zrok launcher.ini" + $DQ)
                DIALOG END CB.HNDL
                EXIT FUNCTION
            ELSE
                ff = FREEFILE                           ' Following runs: simplify ini
                OPEN "zrok launcher.ini" FOR BINARY AS #ff
                GET$ #ff, LOF(#ff), e
                CLOSE #ff
                IF INSTR(e, "first time") > 0 THEN
                    i = INSTR(e, "zrok launcher")
                    IF i > 0 THEN
                        i = INSTR(i, e, $CR)
                        e = "# Make sure the following settings are correct: " + MID$(e, i)
                        KILL "zrok launcher.ini"
                        ff = FREEFILE
                        OPEN "zrok launcher.ini" FOR BINARY AS #ff
                        PUT$ #ff, e
                        CLOSE #ff
                    END IF
                END IF
            END IF
            ' In any case: read ini
            GetIni()
            ' And prepare launch of zrok
            SetTimer CB.HNDL, 0, 200, 0

        CASE %WM_TIMER
        '----------------------------------------------
            IF CB.WPARAM <> 0 THEN EXIT FUNCTION

            IF g_status = 0 THEN ' Init: launch zrok
                g_status = 1
                LogMe "Launching ""zrok.exe " + g_zParam + $DQ + " ..."
                CONTROL SET TEXT  CB.HNDL, %IDC_LABEL1, "launching zrok client"
                CONTROL SET FONT  CB.HNDL, %IDC_LABEL1, g_FntN
                CONTROL SET COLOR CB.HNDL, %IDC_LABEL1, -1, -1
                CON_LAUNCH CB.HNDL, "zrok.exe " + g_zParam, 0, 500

            ELSEIF g_status = 1 THEN ' Zrok launching: blinking orange light
                blink = 1 - blink
                GRAPHIC ATTACH CB.HNDL, %IDC_GRAPHIC1, REDRAW
                GRAPHIC CLEAR DlgBgCol
                GRAPHIC WIDTH 2
                IF ISTRUE blink THEN GRAPHIC ELLIPSE (8, 8) - (32, 32), %BLACK, %RGB_ORANGE
                GRAPHIC REDRAW

            ELSEIF g_status = 2 THEN ' Zrok running correctly in background - fixed green light
                KillTimer CB.HNDL, 0
                CONTROL SET TEXT CB.HNDL, %IDC_LABEL1, g_msg
                CONTROL SET FONT  CB.HNDL, %IDC_LABEL1, g_FntU
                CONTROL SET COLOR CB.HNDL, %IDC_LABEL1, %RGB_DARKGREEN, -1
                GRAPHIC ATTACH CB.HNDL, %IDC_GRAPHIC1, REDRAW
                GRAPHIC CLEAR DlgBgCol
                GRAPHIC WIDTH 2
                GRAPHIC ELLIPSE (8, 8) - (32, 32), %BLACK, %RGB_LIME
                GRAPHIC REDRAW

            ELSEIF g_status = 7 THEN ' Zrok running but ftp upload failed (init)
                KillTimer CB.HNDL, 0
                GRAPHIC ATTACH CB.HNDL, %IDC_GRAPHIC1, REDRAW
                GRAPHIC CLEAR DlgBgCol
                GRAPHIC WIDTH 2
                GRAPHIC ELLIPSE (8, 8) - (32, 32), %BLACK, %YELLOW
                GRAPHIC REDRAW
                blink = 0
                g_status = 8
                SetTimer CB.HNDL, 0, 500, 0

            ELSEIF g_status = 8 THEN ' Zrok running but ftp upload failed (permanent)
                blink = (blink + 1) MOD 8
                GRAPHIC ATTACH CB.HNDL, %IDC_ICOLOG
                IF ISTRUE blink MOD 2 THEN
                    GRAPHIC CLEAR DlgBgCol
                ELSE
                    GRAPHIC RENDER "BMPLOG", (2,2)-(22,22)
                END IF
                IF blink = 1 THEN
                    CONTROL SET TEXT  CB.HNDL, %IDC_LABEL1, PARSE$(g_msg, $CR, 1)
                    CONTROL SET FONT  CB.HNDL, %IDC_LABEL1, g_FntU
                    CONTROL SET COLOR CB.HNDL, %IDC_LABEL1, %RGB_DARKGREEN, -1
                    DIALOG REDRAW CB.HNDL
                ELSEIF blink = 5 THEN
                    CONTROL SET TEXT  CB.HNDL, %IDC_LABEL1, PARSE$(g_msg, $CR, 2)
                    CONTROL SET FONT  CB.HNDL, %IDC_LABEL1, g_FntN
                    CONTROL SET COLOR CB.HNDL, %IDC_LABEL1, %RGB_ORANGE, -1
                    DIALOG REDRAW CB.HNDL
                END IF

            ELSEIF g_status = 9 THEN ' Fatal error - fixed red light (init)
                KillTimer CB.HNDL, 0
                CONTROL SET TEXT  CB.HNDL, %IDC_LABEL1, "zrok internal error - see log"
                CONTROL SET FONT  CB.HNDL, %IDC_LABEL1, g_FntN
                CONTROL SET COLOR CB.HNDL, %IDC_LABEL1, %RED, -1
                GRAPHIC ATTACH CB.HNDL, %IDC_GRAPHIC1, REDRAW
                GRAPHIC CLEAR DlgBgCol
                GRAPHIC WIDTH 2
                GRAPHIC ELLIPSE (8, 8) - (32, 32), %BLACK, %RED
                GRAPHIC REDRAW
                blink = 0
                g_status = 10
                SetTimer CB.HNDL, 0, 500, 0
                IF ISTRUE g_stuck THEN
                    IF CenterMessageBox (CB.HNDL, _
                            "zrok is stuck in a known error state." _
                            + $CRLF + $CRLF _
                            + "Do you want to reset it?" + $CRLF _
                            + "(you need to have filled your" + $CRLF _
                            + "acount_token in the .ini file)", _
                            EXE.NAME$, %MB_ICONWARNING OR %MB_YESNO) = %IDYES THEN
                        LogMe "resetting zrok with account token " + g_AcoTkn
                        CONTROL SET TEXT  CB.HNDL, %IDC_LABEL1, "resetting zrok... pls be patient"
                        ff = FREEFILE
                        OPEN "zrok_reset.bat" FOR OUTPUT AS #ff
                        PRINT #ff, "zrok disable"
                        PRINT #ff, "zrok enable " + g_AcoTkn
                        CLOSE #ff
                        SHELL "zrok_reset.bat", 0
                        KILL  "zrok_reset.bat"
                        LogMe "done. if the account token is correct, it should have worked"
                        LogMe "zrok launcher needs to be restarted"
                        CONTROL SET TEXT  CB.HNDL, %IDC_LABEL1, "zrok has been reset - see log"
                        CenterMessageBox CB.HNDL, "Zrok has been reset" _
                                + $CR + $CR _
                                + "Click OK to restart zrok launcher", _
                                EXE.NAME$, %MB_ICONINFORMATION
                        ' Create batch file to restart ourselves
                        ff = FREEFILE
                        OPEN This_Bat FOR OUTPUT AS #ff
                            PRINT #ff, "TimeOut 1"
                            PRINT #ff, "start " + $DQ+$DQ + $SPC + $DQ+EXE.FULL$+$DQ
                        CLOSE #ff
                        ff = SHELL(This_Bat, 6) ' minimized without focus
                        ' Close ourselves
                        PostMessage CB.HNDL, %WM_SYSCOMMAND, %SC_CLOSE, 0
                        SLEEP 500
                        ExitProcess(12345)

                    END IF
                END IF

            ELSEIF g_status = 10 THEN ' Fatal error - fixed red light (permanent)
                blink = 1 - blink
                GRAPHIC ATTACH CB.HNDL, %IDC_ICOLOG
                IF ISTRUE blink THEN
                    GRAPHIC CLEAR DlgBgCol
                ELSE
                    GRAPHIC RENDER "BMPLOG", (2,2)-(22,22)
                END IF

            END IF

        CASE %WM_SETCURSOR ' change cursor to link-hand when hovering over controls
        '----------------------------------------------
            ctl = GetDlgCtrlId(CB.WPARAM)
            IF ctl = %IDC_LABEL1 OR ctl = %IDC_LABEL2 OR ctl = %IDC_GRAPHIC1 _
            OR ctl = %IDC_ICOCON OR ctl = %IDC_ICOINI OR ctl = %IDC_ICOPHP _
            OR ctl = %IDC_ICOLOG THEN
                IF ctl = %IDC_LABEL1 THEN
                    CONTROL GET TEXT CB.HNDL, ctl TO e
                    IF LEFT$(e, 4) <> "http" THEN EXIT FUNCTION
                END IF
                SetCursor LoadCursor(%NULL, BYVAL %IDC_HAND)
                SetWindowLong CB.HNDL, %dwl_msgresult, 1
                FUNCTION = 1
            END IF

        CASE %WM_COMMAND
        '----------------------------------------------
            SELECT CASE AS LONG CB.CTL

                CASE %IDC_ICOCON ' view/hide zrok console window
                    IF g_status <> 2 AND g_status <> 8 THEN EXIT FUNCTION
                    zconv = 1 - zconv
                    GRAPHIC ATTACH       g_hDlg, %IDC_ICOCON
                    GRAPHIC CLEAR DlgBgCol
                    GRAPHIC RENDER IIF$(zconv,"BMPCOF","BMPCON"), (2,2)-(22,22)
                    DIALOG POST CB.HNDL, %WM_APP + 1, 0, 0

                CASE %IDC_ICOINI ' edit ini file
                    ctl = SHELL(g_editor + $DQ + "zrok launcher.ini" + $DQ)

                CASE %IDC_ICOPHP ' edit php file
                    ctl = SHELL(g_editor + $DQ + g_phpSrc + $DQ)

                CASE %IDC_ICOLOG ' view logs
                    ctl = SHELL(g_editor + $DQ + EXE.NAME$ + ".log" + $DQ)

                CASE %IDC_LABEL1
                    CONTROL GET TEXT CB.HNDL, CB.CTL TO e
                    IF LEFT$(e, 4) <> "http" THEN EXIT FUNCTION
                    ShellExecute %NULL, "open", (e), "", "", %SW_SHOW

                CASE %IDC_LABEL2
                    ShellExecute %NULL, "open", "http://mougino.free.fr/freeware", "", "", %SW_SHOW

            END SELECT

    END SELECT
END FUNCTION
'------------------------------------------------------------------------------

'------------------------------------------------------------------------------
'   ** Dialogs **
'------------------------------------------------------------------------------
FUNCTION ShowDIALOG() AS LONG
    LOCAL lRslt  AS LONG

    FONT NEW "MS Sans Serif", 8, 0, %ANSI_CHARSET TO g_FntN
    FONT NEW "MS Sans Serif", 8, 4, %ANSI_CHARSET TO g_FntU
    FONT NEW "", 6 TO g_FntS

    DIALOG NEW PIXELS, 0, EXE.NAME$, , , 240, 75, %WS_POPUP OR %WS_BORDER _
        OR %WS_DLGFRAME OR %WS_CAPTION OR %WS_SYSMENU OR %WS_MINIMIZEBOX OR _
        %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME OR %DS_3DLOOK OR _
        %DS_NOFAILCREATE OR %DS_SETFONT, %WS_EX_CONTROLPARENT OR %WS_EX_LEFT _
        OR %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR, TO g_hDlg
    DIALOG SET ICON      g_Hdlg, "AICO"

    CONTROL ADD GRAPHIC, g_hDlg, %IDC_GRAPHIC1, "", 0, 0, 32, 32
    CONTROL ADD LABEL,   g_hDlg, %IDC_LABEL1, "Ready.", 40, 12, 195, 16, %SS_NOTIFY

    CONTROL ADD GRAPHIC, g_hDlg, %IDC_ICOCON, "", 8+32*0, 50, 24, 24, %SS_NOTIFY
    GRAPHIC ATTACH       g_hDlg, %IDC_ICOCON
    GRAPHIC RENDER "BMPCON", (2,2)-(22,22)
    CONTROL ADD GRAPHIC, g_hDlg, %IDC_ICOINI, "", 8+32*1, 50, 24, 24, %SS_NOTIFY
    GRAPHIC ATTACH       g_hDlg, %IDC_ICOINI
    GRAPHIC RENDER "BMPINI", (2,2)-(22,22)
    CONTROL ADD GRAPHIC, g_hDlg, %IDC_ICOPHP, "", 8+32*2, 50, 24, 24, %SS_NOTIFY
    GRAPHIC ATTACH       g_hDlg, %IDC_ICOPHP
    GRAPHIC RENDER "BMPPHP", (2,2)-(22,22)
    CONTROL ADD GRAPHIC, g_hDlg, %IDC_ICOLOG, "", 8+32*3, 50, 24, 24, %SS_NOTIFY
    GRAPHIC ATTACH       g_hDlg, %IDC_ICOLOG
    GRAPHIC RENDER "BMPLOG", (2,2)-(22,22)

    lRslt = 8+32*3+24
    CONTROL ADD LABEL,   g_hDlg, 111, "v" + $VER, lRslt, 51, 236-lRslt, 8, %SS_NOTIFY OR %SS_RIGHT
    CONTROL SET COLOR    g_hDlg, 111, RGB(80,80,80), -1
    CONTROL SET FONT     g_hDlg, 111, g_FntS
    CONTROL ADD LABEL,   g_hDlg, %IDC_LABEL2, "http://mougino.free.fr", lRslt, 60, 236-lRslt, 16, %SS_NOTIFY OR %SS_RIGHT
    CONTROL SET COLOR    g_hDlg, %IDC_LABEL2, %BLUE, -1
    CONTROL SET FONT     g_hDlg, %IDC_LABEL2, g_FntU
    CONTROL ADD LINE,    g_hDlg, 999, "", 0, 49, 240, 1

    DIALOG SHOW MODAL    g_hDlg, CALL ProcDialog TO lRslt

    FUNCTION = lRslt
END FUNCTION
'------------------------------------------------------------------------------

'----------------------------------------------------
FUNCTION EXISTS(BYVAL f AS STRING) AS LONG
 LOCAL i AS LONG
 i = GETATTR(f)
 FUNCTION = (ERRCLEAR = 0)
END FUNCTION
'----------------------------------------------------

'----------------------------------------------------
SUB MakeIni(BYVAL inifile AS STRING)
 LOCAL ff AS LONG

 ff = FREEFILE
 OPEN inifile FOR OUTPUT AS #ff
 PRINT #ff, "# This is the first time you run the program:"
 PRINT #ff, "# please change the following settings, then"
 PRINT #ff, "# re-launch zrok launcher"
 PRINT #ff, ""
 PRINT #ff, "[ZrokSettings]"
 PRINT #ff, "zrok_param=share public localhost:80"
 PRINT #ff, "account_token=A1b2C3d4e5F6"
 PRINT #ff, "# The account token is needed when zrok gets stuck (happens frequently)"
 PRINT #ff, "ftp_upload=1"
 PRINT #ff, "# 1 to enable ftp upload ; 0 to disable it"
 PRINT #ff, "# if ftp_upload disabled, you can ignore the following sections
 PRINT #ff, ""
 PRINT #ff, "[TemplateToFill]"
 PRINT #ff, "source_file=""zrok launcher.php"""
 PRINT #ff, "replace_string=XXX"
 PRINT #ff, "# This string will be replaced with your zrok proxy url once assigned"
 PRINT #ff, ""
 PRINT #ff, "[UploadTo]"
 PRINT #ff, "ftp_target=/proxy/index.php"
 PRINT #ff, "ftp_server=ftp.mydomain.com"
 PRINT #ff, "ftp_username=mougino"
 PRINT #ff, "ftp_password=zrok_r0cks!"

 CLOSE #ff
END SUB
'----------------------------------------------------

'----------------------------------------------------
SUB GetIni()
    ' [ZrokSettings]
    g_zParam = GetIniS("zrok launcher.ini", "ZrokSettings", "zrok_param")
    g_AcoTkn = GetIniS("zrok launcher.ini", "ZrokSettings", "account_token")
    g_ftpUL  = GetIniV("zrok launcher.ini", "ZrokSettings", "ftp_upload")
    ' [TemplateToFill]
    g_phpSrc = GetIniS("zrok launcher.ini", "TemplateToFill", "source_file")
    g_phpSrc = TRIM$(g_phpSrc, ANY $DQ+$SPC)
    g_phpRpl = GetIniS("zrok launcher.ini", "TemplateToFill", "replace_string")
    g_phpRpl = TRIM$(g_phpRpl, ANY $DQ+$SPC)
    ' [UploadTo]
    g_ftpTgt = GetIniS("zrok launcher.ini", "UploadTo", "ftp_target")
    g_ftpTgt = TRIM$(g_ftpTgt, ANY $DQ+$SPC)
    g_ftpSrv = GetIniS("zrok launcher.ini", "UploadTo", "ftp_server")
    g_ftpUsr = GetIniS("zrok launcher.ini", "UploadTo", "ftp_username")
    g_ftpPwd = GetIniS("zrok launcher.ini", "UploadTo", "ftp_password")
    'CheckIni() ' Debug: show all parameters in a MsgBox
END SUB
'----------------------------------------------------

'----------------------------------------------------
SUB CheckIni()
    ?"[ZrokSettings]"+$CR _
    +"zrok_param="+g_zParam+$CR _
    +"account_token="+g_AcoTkn+$CR _
    +"ftp_upload="+FORMAT$(g_ftpUL)+$CR _
    +$CR _
    +"[TemplateToFill]"+$CR _
    +"source_file="+g_phpSrc+$CR _
    +"replace_string="+g_phpRpl+$CR _
    +$CR _
    +"[UploadTo]"+$CR _
    +"ftp_target="+g_ftpTgt+$CR _
    +"ftp_server="+g_ftpSrv+$CR _
    +"ftp_username="+g_ftpUsr+$CR _
    +"ftp_password="+g_ftpPwd,,EXE.NAME$
END SUB
'----------------------------------------------------

'----------------------------------------------------
SUB MakePhp(BYVAL inifile AS STRING)
 LOCAL ff AS LONG

 ff = FREEFILE
 OPEN inifile FOR OUTPUT AS #ff
 PRINT #ff, "<?php"
 PRINT #ff, " header(""Location: XXX"");"
 PRINT #ff, " die();"
 PRINT #ff, "?>"

 CLOSE #ff
END SUB
'----------------------------------------------------

'----------------------------------------------------
SUB LogMe(BYVAL e AS STRING)
    LOCAL ff AS LONG
    LOCAL t AS STRING

    ' Timestamp
    t  = DATE$
    t  = "["+RIGHT$(t,4)+LEFT$(t,2)+MID$(t,4,2)
    t += "-"+REMOVE$(TIME$,":")
    t += ","+FORMAT$((TIMER*1000) MOD 1000, "000")+"] "

    ' Append to existing log
    ff = FREEFILE
    OPEN EXE.NAME$ + ".log" FOR APPEND AS #ff
    PRINT #ff, t + e
    CLOSE #ff

END SUB
'----------------------------------------------------