Refactor this C code:

#include <windows.h>
#include <stdio.h>
#include <time.h>

HANDLE g_hMutex = NULL;

int file_exists(const char *path) {
    DWORD attrs = GetFileAttributesA(path);
    return (attrs != INVALID_FILE_ATTRIBUTES) && !(attrs & FILE_ATTRIBUTE_DIRECTORY);
}

void WriteTimestampToFile(FILE *logFile, const char *label) {
    SYSTEMTIME st;
    GetLocalTime(&st);
    fprintf(logFile, "\n=== [%04d-%02d-%02d %02d:%02d:%02d] %s ===\n",
        st.wYear, st.wMonth, st.wDay,
        st.wHour, st.wMinute, st.wSecond, label);
    fflush(logFile);
}

void WriteTimestamp(const char *label) {
    SYSTEMTIME st;
    GetLocalTime(&st);
    printf("\n=== [%04d-%02d-%02d %02d:%02d:%02d] %s ===\n",
        st.wYear, st.wMonth, st.wDay,
        st.wHour, st.wMinute, st.wSecond, label);
}

unsigned int crc32(const unsigned char *s) {
    unsigned int crc = 0xFFFFFFFF;
    while (*s) {
        unsigned char b = *s++;
        for (int i = 0; i < 8; ++i) {
            unsigned int mask = -((crc ^ b) & 1);
            crc = (crc >> 1) ^ (0xEDB88320 & mask);
            b >>= 1;
        }
    }
    return ~crc;
}


void make_mutex_name_from_path(const char *folderPath, char *mutexNameOut) {
    unsigned int hash = crc32((const unsigned char *)folderPath);
    sprintf(mutexNameOut, "Local\\FtpConnMutex_%08X", hash);
}


void exitApp() {
    // Countdown before exit
    for (int i = 60; i > 0; --i) {
        printf("Exiting in %d seconds...\r", i);
        fflush(stdout);
        Sleep(1000);
    }
    printf("\n");
}

int main() {
    system("title Recursive folder synchronization with server (v2025-06-18-Libor)");

    char exePath[MAX_PATH];
    char exeDir[MAX_PATH];
    char scriptPath[MAX_PATH];
    char logPath[MAX_PATH];
    char winSCPPath[MAX_PATH];
    char winExePath[MAX_PATH];
    char commandLine[1024];
    // Record the start time
  clock_t start_time = clock();

    printf("Recursive folder synchronization with server (v2025-06-18-Libor)");
    printf("\n\n");

    // Get path to this EXE
    GetModuleFileNameA(NULL, exePath, MAX_PATH);
    strcpy(exeDir, exePath);
    char *lastSlash = strrchr(exeDir, '\\');
    if (lastSlash) *lastSlash = '\0';

        char mutexName[64];
make_mutex_name_from_path(exeDir, mutexName);
HANDLE g_hMutex = CreateMutexA(NULL, FALSE, mutexName);

if (g_hMutex == NULL) {
    fprintf(stderr, "Error: Failed to create mutex %s.\n\n", mutexName);
    exitApp();
    return 1;
}

if (GetLastError() == ERROR_ALREADY_EXISTS) {
    fprintf(stderr, "Error: Another instance of ftpconn.exe is already running...\n\n");
    CloseHandle(g_hMutex);
    exitApp();
    return 1;
}

    // Build paths
    sprintf(scriptPath, "%s\\ftpconn.exe.config", exeDir);

    sprintf(winSCPPath, "%s\\WinSCP.com", exeDir);
    sprintf(winExePath, "%s\\WinSCP.exe", exeDir);

    if (!file_exists(winExePath)) {
        fprintf(stderr, "Error: WinSCP.exe portable file not found at %s\n\n", exeDir);
        exitApp();
        return 1;
    }

    if (!file_exists(winSCPPath)) {
        fprintf(stderr, "Error: WinSCP.com portable file not found at %s\n\n", exeDir);
        exitApp();
        return 1;
    }

    if (!file_exists(scriptPath)) {
        fprintf(stderr, "Error: ftpconn.exe.config file not found at %s\n\n", exeDir);
        exitApp();
        return 1;
    }



    SYSTEMTIME st;
    GetLocalTime(&st);
    sprintf(logPath, "%s\\FtpConn.%04d-%02d-%02d.log", exeDir, st.wYear, st.wMonth, st.wDay);

    printf("Log file: ");
    printf(logPath);
    printf("\n\n");

    // Open log file
    FILE *logFile = fopen(logPath, "a");
    if (!logFile) {
        fprintf(stderr, "Error: Failed to open log file: %s\n", logPath);
        exitApp();
        return 1;
    }
    WriteTimestampToFile(logFile, "START");
    WriteTimestamp("START");
    printf("\n");

    // Set up pipes
    SECURITY_ATTRIBUTES sa = { sizeof(sa), NULL, TRUE };
    HANDLE readPipe, writePipe;
    CreatePipe(&readPipe, &writePipe, &sa, 0);
    SetHandleInformation(readPipe, HANDLE_FLAG_INHERIT, 0); // prevent child from inheriting read

    // Set up process startup info
    STARTUPINFOA si = { sizeof(si) };
    si.dwFlags = STARTF_USESTDHANDLES;
    si.hStdOutput = writePipe;
    si.hStdError = writePipe;
    si.hStdInput = NULL;

    PROCESS_INFORMATION pi;

    // Build command line for WinSCP
    sprintf(commandLine, "\"%s\" /script=\"%s\"", winSCPPath, scriptPath);

    // Launch WinSCP
    if (!CreateProcessA(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
        fprintf(stderr, "Error: Failed to start portable WinSCP. Files needed: WinSCP.com, WinSCP.exe\n\n");
        fclose(logFile);
        CloseHandle(writePipe);
        CloseHandle(readPipe);
        exitApp();
        return 1;
    }

    CloseHandle(writePipe); // parent doesn't write

    // Read from child process output and write to log and console
    char buffer[4096];
    DWORD bytesRead;
    while (ReadFile(readPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead > 0) {
        buffer[bytesRead] = '\0';
        fputs(buffer, stdout);      // show in console
        fputs(buffer, logFile);     // write to log
        fflush(stdout);
        fflush(logFile);
    }

    // Cleanup
    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);
    CloseHandle(pi.hThread);
    CloseHandle(readPipe);

    printf("\n");
    WriteTimestampToFile(logFile, "FINISH");
    WriteTimestamp("FINISH");

    // Record the end time
  clock_t end_time = clock();

  // Calculate the execution time in seconds
  double cpu_time_used = ((double) (end_time - start_time)) / CLOCKS_PER_SEC;

  fprintf(logFile, "\nTotal execution time: %f seconds\n\n", cpu_time_used);
  printf("\nTotal execution time: %f seconds\n\n", cpu_time_used);

    fclose(logFile);

exitApp();


    return 0;
}