NOEXPORT void CALLBACK timer_proc(HWND hwnd, UINT msg, UINT_PTR id, DWORD t) { (void)hwnd; /* squash the unused parameter warning */ (void)msg; /* squash the unused parameter warning */ (void)id; /* squash the unused parameter warning */ (void)t; /* squash the unused parameter warning */ if(visible) update_logs(); tray_update(num_clients); /* needed when explorer.exe (re)starts */ }
void tray_reset(HWND hWnd, struct th_data *data) { odprintf("tray[reset]"); /* Try this anyway... */ tray_remove(hWnd, data); /* Assume it has been removed */ data->tray_ok = 0; /* Add it again */ tray_add(hWnd, data); tray_update(hWnd, data); }
NOEXPORT void valid_config() { /* update the main window title */ win32_name=TEXT("stunnel ") TEXT(STUNNEL_VERSION) TEXT(" on ") TEXT(STUNNEL_PLATFORM); SetWindowText(hwnd, win32_name); tray_update(num_clients); /* idle or busy icon (on reload) */ update_peer_menu(); /* one menu item per section */ /* enable IDM_REOPEN_LOG menu if a log file is used, disable otherwise */ #ifndef _WIN32_WCE EnableMenuItem(main_menu_handle, IDM_REOPEN_LOG, (UINT)(global_options.output_file ? MF_ENABLED : MF_GRAYED)); #endif if(tray_menu_handle) EnableMenuItem(tray_menu_handle, IDM_REOPEN_LOG, (UINT)(global_options.output_file ? MF_ENABLED : MF_GRAYED)); }
NOEXPORT void invalid_config() { /* update the main window title */ win32_name=TEXT("stunnel ") TEXT(STUNNEL_VERSION) TEXT(" on ") TEXT(STUNNEL_PLATFORM) TEXT(" (invalid configuration file)"); SetWindowText(hwnd, win32_name); /* log window is hidden by default */ ShowWindow(hwnd, SW_SHOWNORMAL); /* show window */ SetForegroundWindow(hwnd); /* bring on top */ tray_update(-1); /* error icon */ update_peer_menu(); /* purge the list of sections */ win_log(TEXT("")); s_log(LOG_ERR, "Server is down"); message_box(TEXT("Stunnel server is down due to an error.\n") TEXT("You need to exit and correct the problem.\n") TEXT("Click OK to see the error log window."), MB_ICONERROR); }
void prof_run(char *log_level, char *account_name) { _init(log_level); plugins_on_start(); _connect_default(account_name); ui_update(); log_info("Starting main event loop"); session_init_activity(); char *line = NULL; while(cont && !force_quit) { log_stderr_handler(); session_check_autoaway(); line = inp_readline(); if (line) { ProfWin *window = wins_get_current(); cont = cmd_process_input(window, line); free(line); line = NULL; } else { cont = TRUE; } #ifdef HAVE_LIBOTR otr_poll(); #endif plugins_run_timed(); notify_remind(); session_process_events(); iq_autoping_check(); ui_update(); #ifdef HAVE_GTK tray_update(); #endif } }
int comms_connect(HWND hWnd, struct th_data *data) { struct tray_status *status = &data->status; struct tcp_keepalive ka_get; struct tcp_keepalive ka_set = { .onoff = 1, .keepalivetime = 5000, /* 5 seconds */ .keepaliveinterval = 5000 /* 5 seconds */ }; int timeout = 5000; /* 5 seconds */ INT ret; DWORD retd; DWORD err; odprintf("comms[connect]"); if (!data->running) return 0; if (data->s != INVALID_SOCKET) return 0; status->conn = NOT_CONNECTED; tray_update(hWnd, data); #if HAVE_GETADDRINFO if (data->addrs_cur == NULL && data->addrs_res != NULL) { freeaddrinfo(data->addrs_res); data->addrs_res = NULL; } if (data->addrs_res == NULL) { SetLastError(0); ret = getaddrinfo(data->node, data->service, &data->hints, &data->addrs_res); err = GetLastError(); odprintf("getaddrinfo: %d (%ld)", ret, err); if (ret != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to resolve node \"%s\" service \"%s\" (%d)", data->node, data->service, ret); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); return 1; } if (data->addrs_res == NULL) { odprintf("no results"); ret = snprintf(status->msg, sizeof(status->msg), "No results resolving node \"%s\" service \"%s\"", data->node, data->service); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); return 1; } data->addrs_cur = data->addrs_res; } SetLastError(0); ret = getnameinfo(data->addrs_cur->ai_addr, data->addrs_cur->ai_addrlen, data->hbuf, sizeof(data->hbuf), data->sbuf, sizeof(data->sbuf), NI_NUMERICHOST|NI_NUMERICSERV); err = GetLastError(); odprintf("getnameinfo: %d (%ld)", ret, err); if (ret == 0) { odprintf("trying to connect to node \"%s\" service \"%s\"", data->hbuf, data->sbuf); } else { data->hbuf[0] = 0; data->sbuf[0] = 0; } #else odprintf("trying to connect to node \"%s\" service \"%s\"", data->node, data->service); #endif SetLastError(0); #if HAVE_GETADDRINFO data->s = socket(data->addrs_cur->ai_family, SOCK_STREAM, IPPROTO_TCP); #else data->s = socket(data->family, SOCK_STREAM, IPPROTO_TCP); #endif err = GetLastError(); odprintf("socket: %d (%ld)", data->s, err); if (data->s == INVALID_SOCKET) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to create socket (%ld)", err); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } SetLastError(0); ret = setsockopt(data->s, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout)); err = GetLastError(); odprintf("setsockopt: %d (%ld)", ret, err); if (ret != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to set socket timeout (%ld)", err); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } SetLastError(0); ret = WSAIoctl(data->s, SIO_KEEPALIVE_VALS, (void*)&ka_set, sizeof(ka_set), (void*)&ka_get, sizeof(ka_get), &retd, NULL, NULL); err = GetLastError(); odprintf("WSAIoctl: %d, %d (%ld)", ret, retd, err); if (ret != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to set socket keepalive options (%ld)", err); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } SetLastError(0); ret = WSAAsyncSelect(data->s, hWnd, WM_APP_SOCK, FD_CONNECT|FD_READ|FD_CLOSE); err = GetLastError(); odprintf("WSAAsyncSelect: %d (%ld)", ret, err); if (ret != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Unable to async select on socket (%ld)", err); if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } status->conn = CONNECTING; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "node \"%s\" service \"%s\" (%ld)", data->hbuf, data->sbuf, err); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "node \"%s\" service \"%s\" (%ld)", data->node, data->service, err); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); #if HAVE_GETADDRINFO ret = connect(data->s, data->addrs_cur->ai_addr, data->addrs_cur->ai_addrlen); #else ret = connect(data->s, data->sa, data->sa_len); #endif err = GetLastError(); odprintf("connect: %d (%ld)", ret, err); if (ret == 0 || err == WSAEWOULDBLOCK) { return 0; } else { status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Error connecting to node \"%s\" service \"%s\"", data->hbuf, data->sbuf); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Error connecting to node \"%s\" service \"%s\"", data->node, data->service); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } } int comms_activity(HWND hWnd, struct th_data *data, SOCKET s, WORD sEvent, WORD sError) { struct tray_status *status = &data->status; INT ret; DWORD err; odprintf("comms[activity]: s=%p sEvent=%d sError=%d", s, sEvent, sError); if (!data->running) return 0; if (data->s != s) return 0; switch (sEvent) { case FD_CONNECT: odprintf("FD_CONNECT %s", status->conn == CONNECTING ? "OK" : "?"); if (status->conn != CONNECTING) return 0; if (sError == 0) { status->conn = CONNECTED; status->msg[0] = 0; status->temperature_celsius = NAN; status->relative_humidity = NAN; status->dew_point = NAN; tray_update(hWnd, data); #if HAVE_GETADDRINFO freeaddrinfo(data->addrs_res); data->addrs_res = NULL; #endif data->parse_pos = 0; data->def_sensor = 0; return 0; } else { status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Error connecting to node \"%s\" service \"%s\" (%d)", data->hbuf, data->sbuf, sError); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Error connecting to node \"%s\" service \"%s\" (%d)", data->node, data->service, sError); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; #if HAVE_GETADDRINFO data->addrs_cur = data->addrs_cur->ai_next; #endif return 1; } case FD_READ: odprintf("FD_READ %s", status->conn == CONNECTED ? "OK" : "?"); if (status->conn != CONNECTED) return 0; if (sError == 0) { char recv_buf[128]; SetLastError(0); ret = recv(data->s, recv_buf, sizeof(recv_buf), 0); err = GetLastError(); odprintf("recv: %d (%ld)", ret, err); if (ret <= 0) { status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Error reading from node \"%s\" service \"%s\" (%ld)", data->hbuf, data->sbuf, err); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Error reading from node \"%s\" service \"%s\" (%ld)", data->node, data->service, err); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; return 1; } else if (err == WSAEWOULDBLOCK) { return 0; } else { int size, i; size = ret; for (i = 0; i < size; i++) { /* find a newline and parse the buffer */ if (recv_buf[i] == '\n') { comms_parse(hWnd, data); /* clear buffer */ data->parse_pos = 0; /* buffer overflow */ } else if (data->parse_pos == sizeof(data->parse_buf)/sizeof(char) - 1) { odprintf("parse: sender overflowed buffer waiting for '\\n'"); data->parse_buf[0] = 0; data->parse_pos++; /* ignore */ } else if (data->parse_pos > sizeof(data->parse_buf)/sizeof(char) - 1) { /* append to buffer */ } else { data->parse_buf[data->parse_pos++] = recv_buf[i]; data->parse_buf[data->parse_pos] = 0; } } return 0; } } else { status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Error reading from node \"%s\" service \"%s\" (%d)", data->hbuf, data->sbuf, sError); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Error reading from node \"%s\" service \"%s\" (%d)", data->node, data->service, sError); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; return 1; } case FD_CLOSE: odprintf("FD_CLOSE %s", status->conn == CONNECTED ? "OK" : "?"); if (status->conn != CONNECTED) return 0; status->conn = NOT_CONNECTED; #if HAVE_GETADDRINFO if (data->hbuf[0] != 0 && data->sbuf[0] != 0) { ret = snprintf(status->msg, sizeof(status->msg), "Lost connection to node \"%s\" service \"%s\" (%d)", data->hbuf, data->sbuf, sError); } else { #endif ret = snprintf(status->msg, sizeof(status->msg), "Lost connection to node \"%s\" service \"%s\" (%d)", data->node, data->service, sError); #if HAVE_GETADDRINFO } #endif if (ret < 0) status->msg[0] = 0; tray_update(hWnd, data); SetLastError(0); ret = closesocket(data->s); err = GetLastError(); odprintf("closesocket: %d (%ld)", ret, err); data->s = INVALID_SOCKET; return 1; default: return 0; } } void comms_parse(HWND hWnd, struct th_data *data) { struct tray_status *status = &data->status; char msg_type[16]; if (sscanf(data->parse_buf, "%16s", msg_type) == 1) { odprintf("msg_type: %s", msg_type); if (!strcmp(msg_type, "SENSD")) { data->def_sensor = 1; } else if (!strcmp(msg_type, "SENSR")) { data->def_sensor = 0; } else if (data->def_sensor) { if (!strcmp(msg_type, "TEMPC")) { if (sscanf(data->parse_buf, "%*s %lf", &status->temperature_celsius) != 1) status->temperature_celsius = NAN; } else if (!strcmp(msg_type, "RHUM%")) { if (sscanf(data->parse_buf, "%*s %lf", &status->relative_humidity) != 1) status->relative_humidity = NAN; } else if (!strcmp(msg_type, "DEWPC")) { if (sscanf(data->parse_buf, "%*s %lf", &status->dew_point) != 1) status->dew_point = NAN; } else if (!strcmp(msg_type, "SENSF")) { tray_update(hWnd, data); } } } }
NOEXPORT LRESULT CALLBACK window_proc(HWND main_window_handle, UINT message, WPARAM wParam, LPARAM lParam) { POINT pt; RECT rect; PAINTSTRUCT ps; SERVICE_OPTIONS *section; unsigned section_number; LPTSTR txt; #if 0 switch(message) { case WM_CTLCOLORSTATIC: case WM_TIMER: case WM_LOG: break; default: s_log(LOG_DEBUG, "Window message: 0x%x(0x%hx,0x%lx)", message, wParam, lParam); } #endif switch(message) { case WM_CREATE: #ifdef _WIN32_WCE /* create command bar */ command_bar_handle=CommandBar_Create(ghInst, main_window_handle, 1); if(!command_bar_handle) error_box(TEXT("CommandBar_Create")); if(!CommandBar_InsertMenubar(command_bar_handle, ghInst, IDM_MAINMENU, 0)) error_box(TEXT("CommandBar_InsertMenubar")); if(!CommandBar_AddAdornments(command_bar_handle, 0, 0)) error_box(TEXT("CommandBar_AddAdornments")); #endif /* create child edit window */ edit_handle=CreateWindowEx(WS_EX_STATICEDGE, TEXT("EDIT"), NULL, WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL|ES_MULTILINE|ES_READONLY, 0, 0, 0, 0, main_window_handle, (HMENU)IDE_EDIT, ghInst, NULL); #ifndef _WIN32_WCE SendMessage(edit_handle, WM_SETFONT, (WPARAM)CreateFont(-12, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_RASTER_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, DEFAULT_PITCH, TEXT("Courier")), MAKELPARAM(FALSE, 0)); /* no need to redraw right now */ #endif /* NOTE: there's no return statement here -> proceeding with resize */ case WM_SIZE: GetClientRect(main_window_handle, &rect); #ifdef _WIN32_WCE MoveWindow(edit_handle, 0, CommandBar_Height(command_bar_handle), rect.right, rect.bottom-CommandBar_Height(command_bar_handle), TRUE); SendMessage(command_bar_handle, TB_AUTOSIZE, 0L, 0L); CommandBar_AlignAdornments(command_bar_handle); #else MoveWindow(edit_handle, 0, 0, rect.right, rect.bottom, TRUE); #endif UpdateWindow(edit_handle); /* CommandBar_Show(command_bar_handle, TRUE); */ return 0; case WM_SETFOCUS: SetFocus(edit_handle); return 0; case WM_PAINT: BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); break; case WM_CLOSE: ShowWindow(main_window_handle, SW_HIDE); return 0; #ifdef WM_SHOWWINDOW case WM_SHOWWINDOW: visible=(BOOL)wParam; #else /* this works for Pierre Delaage, but not for me... */ case WM_WINDOWPOSCHANGED: visible=IsWindowVisible(main_window_handle); #endif if(tray_menu_handle) CheckMenuItem(tray_menu_handle, IDM_SHOW_LOG, visible ? MF_CHECKED : MF_UNCHECKED); if(visible) update_logs(); #ifdef WM_SHOWWINDOW return 0; #else break; /* proceed to DefWindowProc() */ #endif case WM_DESTROY: #ifdef _WIN32_WCE CommandBar_Destroy(command_bar_handle); #else if(main_menu_handle) { if(!DestroyMenu(main_menu_handle)) ioerror("DestroyMenu"); main_menu_handle=NULL; } #endif tray_delete(); /* remove the taskbark icon if exists */ PostQuitMessage(0); return 0; case WM_COMMAND: if(wParam>=IDM_PEER_MENU && wParam<IDM_PEER_MENU+number_of_sections) { for(section=service_options.next, section_number=0; section && wParam!=IDM_PEER_MENU+section_number; section=section->next, ++section_number) ; if(!section) return 0; if(save_text_file(section->file, section->chain)) return 0; #ifndef _WIN32_WCE if(main_menu_handle) CheckMenuItem(main_menu_handle, (UINT)wParam, MF_CHECKED); #endif if(tray_menu_handle) CheckMenuItem(tray_menu_handle, (UINT)wParam, MF_CHECKED); message_box(section->help, MB_ICONINFORMATION); return 0; } switch(wParam) { case IDM_ABOUT: DialogBox(ghInst, TEXT("AboutBox"), main_window_handle, (DLGPROC)about_proc); break; case IDM_SHOW_LOG: if(visible) { ShowWindow(main_window_handle, SW_HIDE); /* hide window */ } else { ShowWindow(main_window_handle, SW_SHOWNORMAL); /* show window */ SetForegroundWindow(main_window_handle); /* bring on top */ } break; case IDM_CLOSE: ShowWindow(main_window_handle, SW_HIDE); /* hide window */ break; case IDM_EXIT: if(num_clients>=0) /* signal_pipe is active */ signal_post(SIGNAL_TERMINATE); DestroyWindow(main_window_handle); break; case IDM_SAVE_LOG: if(!cmdline.service) /* security */ save_log(); break; case IDM_EDIT_CONFIG: #ifndef _WIN32_WCE if(!cmdline.service) /* security */ edit_config(main_window_handle); #endif break; case IDM_RELOAD_CONFIG: if(num_clients>=0) /* signal_pipe is active */ signal_post(SIGNAL_RELOAD_CONFIG); else SetEvent(config_ready); /* unlock daemon_thread() */ break; case IDM_REOPEN_LOG: signal_post(SIGNAL_REOPEN_LOG); break; case IDM_MANPAGE: #ifndef _WIN32_WCE if(!cmdline.service) /* security */ ShellExecute(main_window_handle, TEXT("open"), TEXT("..\\doc\\stunnel.html"), NULL, NULL, SW_SHOWNORMAL); #endif break; case IDM_HOMEPAGE: #ifndef _WIN32_WCE if(!cmdline.service) /* security */ ShellExecute(main_window_handle, TEXT("open"), TEXT("http://www.stunnel.org/"), NULL, NULL, SW_SHOWNORMAL); #endif break; } return 0; case WM_SYSTRAY: /* a taskbar event */ switch(lParam) { #ifdef _WIN32_WCE case WM_LBUTTONDOWN: /* no right mouse button on Windows CE */ GetWindowRect(GetDesktopWindow(), &rect); /* no cursor position */ pt.x=rect.right; pt.y=rect.bottom-25; #else case WM_RBUTTONDOWN: GetCursorPos(&pt); #endif SetForegroundWindow(main_window_handle); if(tray_menu_handle) TrackPopupMenuEx(GetSubMenu(tray_menu_handle, 0), TPM_BOTTOMALIGN, pt.x, pt.y, main_window_handle, NULL); PostMessage(main_window_handle, WM_NULL, 0, 0); break; #ifndef _WIN32_WCE case WM_LBUTTONDBLCLK: /* switch log window visibility */ if(visible) { ShowWindow(main_window_handle, SW_HIDE); /* hide window */ } else { ShowWindow(main_window_handle, SW_SHOWNORMAL); /* show window */ SetForegroundWindow(main_window_handle); /* bring on top */ } break; #endif } return 0; case WM_VALID_CONFIG: valid_config(); return 0; case WM_INVALID_CONFIG: invalid_config(); return 0; case WM_LOG: txt=(LPTSTR)wParam; win_log(txt); str_free(txt); return 0; case WM_NEW_CHAIN: #ifndef _WIN32_WCE if(main_menu_handle) EnableMenuItem(main_menu_handle, (UINT)(IDM_PEER_MENU+wParam), MF_ENABLED); #endif if(tray_menu_handle) EnableMenuItem(tray_menu_handle, (UINT)(IDM_PEER_MENU+wParam), MF_ENABLED); return 0; case WM_CLIENTS: tray_update((int)wParam); return 0; } return DefWindowProc(main_window_handle, message, wParam, lParam); }