X-Recipient: archive-cygwin AT delorie DOT com DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:in-reply-to:references:date:subject :from:to:mime-version:content-type; q=dns; s=default; b=iEH8oGiZ ZiipUwrOG9ALBsDQuU4C04qYwurH0BRTlaCXoRqpQWDtE+lbHW8NerRik51G/FGt A4GhlBZ76Pz5EndahCvzcakvHqPhCnEAjgXIq7wmIRijImFb1p9EtRrnXdtUTkyo OkqEnrJ0N202pQqeV6qERwJ6PuOQgUfhD9c= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:in-reply-to:references:date:subject :from:to:mime-version:content-type; s=default; bh=W0NAsrLyUDTBin knBL525k2/8fA=; b=CdNLMn22IRzwAUqIqU4z36Uev/Ce5QQ7ybkylNv7ms1uDz X3kN5T/NuuopRZqh2V4bL01AqaFsx9JnM9wofpswsygNMi8MNHxPntgnuck8z0tZ a0zgDnxEbUR1Kz3hzbwOVy1WSI74EU81LqQzQZYyaWaOWsHOzW8ctPTj7JCJs= Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=0.0 required=5.0 tests=AWL,BAYES_50,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: lb3-smtp-cloud6.xs4all.net Message-ID: <20bcab2c7a6ca2aa1990f8a421b674ae.squirrel@oude-webmail.xs4all.nl> In-Reply-To: <994a85838723f326327975650e214a79.squirrel@oude-webmail.xs4all.nl> References: <63a08c60771faffa23bc1c029235301d DOT squirrel AT oude-webmail DOT xs4all DOT nl> <55B22422 DOT 6000601 AT towo DOT net> <55B2B644 DOT 8010506 AT towo DOT net> <10d3a46960f8ec71784bdf15a0ee6b58 DOT squirrel AT oude-webmail DOT xs4all DOT nl> <1e17310bb0689632cd19fd7648bd9907 DOT squirrel AT oude-webmail DOT xs4all DOT nl> <55B5109A DOT 4010700 AT towo DOT net> <4afa07869c07cd6a57441b221ca5fdf7 DOT squirrel AT oude-webmail DOT xs4all DOT nl> <994a85838723f326327975650e214a79 DOT squirrel AT oude-webmail DOT xs4all DOT nl> Date: Mon, 27 Jul 2015 17:58:07 +0200 Subject: Re: [ANNOUNCEMENT] Update: mintty 2.1.2 From: "Houder" To: cygwin AT cygwin DOT com User-Agent: SquirrelMail/1.4.22 MIME-Version: 1.0 Content-Type: multipart/mixed;boundary="----=_20150727175807_31619" X-IsSubscribed: yes ------=_20150727175807_31619 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 8bit Hi Thomas, Moving load_dwm_funcs() did the trick ... Tested on 32-bits and 64-bits, W7 See appendix (winmain.c) Henri ------=_20150727175807_31619 Content-Type: text/x-c; name="winmain.c" Content-Transfer-Encoding: 8bit Content-Disposition: attachment; filename="winmain.c" // win.c (part of mintty) // Copyright 2008-13 Andy Koppe // Based on code from PuTTY-0.60 by Simon Tatham and team. // Licensed under the terms of the GNU General Public License v3 or later. #include "winpriv.h" #include "term.h" #include "appinfo.h" #include "child.h" #include "charset.h" #include #include #include #include #include HINSTANCE inst; HWND wnd; HIMC imc; bool win_is_full_screen; static char **main_argv; static int main_argc; static ATOM class_atom; static int extra_width, extra_height; static bool fullscr_on_max; static bool resizing; static bool title_settable = true; static bool daemonize = false; static string border_style = 0; static HBITMAP caretbm; #if WINVER < 0x600 typedef struct { int cxLeftWidth; int cxRightWidth; int cyTopHeight; int cyBottomHeight; } MARGINS; #endif static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *); static HRESULT (WINAPI *pDwmExtendFrameIntoClientArea)(HWND, const MARGINS *); // Helper for loading a system library. Using LoadLibrary() directly is insecure // because Windows might be searching the current working directory first. static HMODULE load_sys_library(string name) { char path[MAX_PATH]; uint len = GetSystemDirectory(path, MAX_PATH); if (len && len + strlen(name) + 1 < MAX_PATH) { path[len] = '\\'; strcpy(&path[len + 1], name); return LoadLibrary(path); } else return 0; } static void load_dwm_funcs(void) { HMODULE dwm = load_sys_library("dwmapi.dll"); if (dwm) { pDwmIsCompositionEnabled = (void *)GetProcAddress(dwm, "DwmIsCompositionEnabled"); pDwmExtendFrameIntoClientArea = (void *)GetProcAddress(dwm, "DwmExtendFrameIntoClientArea"); } } void win_set_timer(void (*cb)(void), uint ticks) { SetTimer(wnd, (UINT_PTR)cb, ticks, null); } void win_set_title(char *title) { if (title_settable) { wchar wtitle[strlen(title) + 1]; if (cs_mbstowcs(wtitle, title, lengthof(wtitle)) >= 0) SetWindowTextW(wnd, wtitle); } } void win_copy_title(void) { int len = GetWindowTextLengthW(wnd); wchar title[len + 1]; len = GetWindowTextW(wnd, title, len + 1); win_copy(title, 0, len + 1); } void win_prefix_title(const char * prefix) { int len = GetWindowTextLengthW(wnd); wchar ptitle[strlen(prefix) + len + 1]; int plen = cs_mbstowcs(ptitle, prefix, lengthof(ptitle)); wchar * title = & ptitle[plen]; len = GetWindowTextW(wnd, title, len + 1); SetWindowTextW(wnd, ptitle); } /* * Title stack (implemented as fixed-size circular buffer) */ static wstring titles[16]; static uint titles_i; void win_save_title(void) { int len = GetWindowTextLengthW(wnd); wchar *title = newn(wchar, len + 1); GetWindowTextW(wnd, title, len + 1); delete(titles[titles_i]); titles[titles_i++] = title; if (titles_i == lengthof(titles)) titles_i = 0; } void win_restore_title(void) { if (!titles_i) titles_i = lengthof(titles); wstring title = titles[--titles_i]; if (title) { SetWindowTextW(wnd, title); delete(title); titles[titles_i] = 0; } } /* * Switch to next or previous application window in z-order */ static HWND first_wnd, last_wnd; static BOOL CALLBACK wnd_enum_proc(HWND curr_wnd, LPARAM unused(lp)) { if (curr_wnd != wnd && !IsIconic(curr_wnd)) { WINDOWINFO curr_wnd_info; curr_wnd_info.cbSize = sizeof(WINDOWINFO); GetWindowInfo(curr_wnd, &curr_wnd_info); if (class_atom == curr_wnd_info.atomWindowType) { first_wnd = first_wnd ?: curr_wnd; last_wnd = curr_wnd; } } return true; } void win_switch(bool back, bool alternate) { first_wnd = 0, last_wnd = 0; EnumWindows(wnd_enum_proc, 0); if (first_wnd) { if (back) first_wnd = last_wnd; else SetWindowPos(wnd, last_wnd, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | (alternate ? SWP_NOZORDER : SWP_NOREPOSITION)); BringWindowToTop(first_wnd); } } static void get_monitor_info(MONITORINFO *mip) { HMONITOR mon = MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST); mip->cbSize = sizeof(MONITORINFO); GetMonitorInfo(mon, mip); } /* * Minimise or restore the window in response to a server-side * request. */ void win_set_iconic(bool iconic) { if (iconic ^ IsIconic(wnd)) ShowWindow(wnd, iconic ? SW_MINIMIZE : SW_RESTORE); } /* * Move the window in response to a server-side request. */ void win_set_pos(int x, int y) { trace_resize(("--- win_set_pos %d %d\n", x, y)); if (!IsZoomed(wnd)) SetWindowPos(wnd, null, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); } /* * Move the window to the top or bottom of the z-order in response * to a server-side request. */ void win_set_zorder(bool top) { SetWindowPos(wnd, top ? HWND_TOP : HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } bool win_is_iconic(void) { return IsIconic(wnd); } void win_get_pos(int *xp, int *yp) { RECT r; GetWindowRect(wnd, &r); *xp = r.left; *yp = r.top; } void win_get_pixels(int *height_p, int *width_p) { RECT r; GetWindowRect(wnd, &r); *height_p = r.bottom - r.top; *width_p = r.right - r.left; } void win_get_screen_chars(int *rows_p, int *cols_p) { MONITORINFO mi; get_monitor_info(&mi); RECT fr = mi.rcMonitor; *rows_p = (fr.bottom - fr.top) / font_height; *cols_p = (fr.right - fr.left) / font_width; } void win_set_pixels(int height, int width) { trace_resize(("--- win_set_pixels %d %d\n", height, width)); SetWindowPos(wnd, null, 0, 0, width + 2 * PADDING + extra_width, height + 2 * PADDING + extra_height, SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER); } static void win_fix_position(void) { RECT wr; GetWindowRect(wnd, &wr); MONITORINFO mi; get_monitor_info(&mi); RECT ar = mi.rcWork; // Correct edges. Top and left win if the window is too big. wr.left -= max(0, wr.right - ar.right); wr.top -= max(0, wr.bottom - ar.bottom); wr.left = max(wr.left, ar.left); wr.top = max(wr.top, ar.top); SetWindowPos(wnd, 0, wr.left, wr.top, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE); } void win_set_chars(int rows, int cols) { trace_resize(("--- win_set_chars %d×%d\n", rows, cols)); win_set_pixels(rows * font_height, cols * font_width); win_fix_position(); } // Clockwork int get_tick_count(void) { return GetTickCount(); } int cursor_blink_ticks(void) { return GetCaretBlinkTime(); } static void flash_taskbar(bool enable) { static bool enabled; if (enable != enabled) { FlashWindowEx(&(FLASHWINFO){ .cbSize = sizeof(FLASHWINFO), .hwnd = wnd, .dwFlags = enable ? FLASHW_TRAY | FLASHW_TIMER : FLASHW_STOP, .uCount = 1, .dwTimeout = 0 }); enabled = enable; } } /* * Bell. */ void win_bell(void) { if (cfg.bell_sound || cfg.bell_type) { if (cfg.bell_freq) Beep(cfg.bell_freq, cfg.bell_len); else { // 0 MB_OK Default Beep // 1 MB_ICONSTOP Critical Stop // 2 MB_ICONQUESTION Question // 3 MB_ICONEXCLAMATION Exclamation // 4 MB_ICONASTERISK Asterisk // ? 0xFFFFFFFF Simple Beep MessageBeep((cfg.bell_type - 1) * 16); } } if (cfg.bell_taskbar && !term.has_focus) flash_taskbar(true); } void win_invalidate_all(void) { InvalidateRect(wnd, null, true); } void win_adapt_term_size(bool sync_size_with_font, bool scale_font_with_size) { trace_resize(("--- win_adapt_term_size full %d Zoomed %d\n", win_is_fullscreen, IsZoomed(wnd))); if (IsIconic(wnd)) return; if (sync_size_with_font && !win_is_fullscreen) { win_set_chars(term.rows, term.cols); //win_fix_position(); win_invalidate_all(); return; } /* Current window sizes ... */ RECT cr, wr; GetClientRect(wnd, &cr); GetWindowRect(wnd, &wr); int client_width = cr.right - cr.left; int client_height = cr.bottom - cr.top; extra_width = wr.right - wr.left - client_width; extra_height = wr.bottom - wr.top - client_height; int term_width = client_width - 2 * PADDING; int term_height = client_height - 2 * PADDING; if (scale_font_with_size) { // calc preliminary size (without font scaling), as below // should use term_height rather than rows; calc and store in term_resize int cols0 = max(1, term_width / font_width); int rows0 = max(1, term_height / font_height); // rows0/term.rows gives a rough scaling factor for font_height // cols0/term.cols gives a rough scaling factor for font_width // font_height, font_width give a rough scaling indication for font_size // height or width could be considered more according to preference bool bigger = rows0 * cols0 > term.rows * term.cols; int font_size1 = // heuristic best approach taken... // bigger // ? max(font_size * rows0 / term.rows, font_size * cols0 / term.cols) // : min(font_size * rows0 / term.rows, font_size * cols0 / term.cols); // bigger // ? font_size * rows0 / term.rows + 2 // : font_size * rows0 / term.rows; bigger ? (font_size * rows0 / term.rows + font_size * cols0 / term.cols) / 2 + 1 : (font_size * rows0 / term.rows + font_size * cols0 / term.cols) / 2; // bigger // ? font_size * rows0 * cols0 / (term.rows * term.cols) // : font_size * rows0 * cols0 / (term.rows * term.cols); trace_resize(("term size %d %d -> %d %d\n", term.rows, term.cols, rows0, cols0)); trace_resize(("font size %d -> %d\n", font_size, font_size1)); if (font_size1 != font_size) win_set_font_size(font_size1, false); } int cols = max(1, term_width / font_width); int rows = max(1, term_height / font_height); if (rows != term.rows || cols != term.cols) { term_resize(rows, cols); struct winsize ws = {rows, cols, cols * font_width, rows * font_height}; child_resize(&ws); } win_invalidate_all(); } bool win_is_glass_available(void) { BOOL result = false; if (pDwmIsCompositionEnabled) pDwmIsCompositionEnabled(&result); return result; } static void update_glass(void) { if (pDwmExtendFrameIntoClientArea) { bool enabled = cfg.transparency == TR_GLASS && !win_is_fullscreen && !(cfg.opaque_when_focused && term.has_focus); pDwmExtendFrameIntoClientArea(wnd, &(MARGINS){enabled ? -1 : 0, 0, 0, 0}); } } /* * Go full-screen. This should only be called when we are already * maximised. */ static void make_fullscreen(void) { win_is_fullscreen = true; /* Remove the window furniture. */ LONG style = GetWindowLong(wnd, GWL_STYLE); style &= ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME); SetWindowLong(wnd, GWL_STYLE, style); /* The glass effect doesn't work for fullscreen windows */ update_glass(); /* Resize ourselves to exactly cover the nearest monitor. */ MONITORINFO mi; get_monitor_info(&mi); RECT fr = mi.rcMonitor; SetWindowPos(wnd, HWND_TOP, fr.left, fr.top, fr.right - fr.left, fr.bottom - fr.top, SWP_FRAMECHANGED); } /* * Clear the full-screen attributes. */ static void clear_fullscreen(void) { win_is_fullscreen = false; update_glass(); /* Reinstate the window furniture. */ LONG style = GetWindowLong(wnd, GWL_STYLE); if (border_style) { if (strcmp (border_style, "void") != 0) { style |= WS_THICKFRAME; } } else { style |= WS_CAPTION | WS_BORDER | WS_THICKFRAME; } SetWindowLong(wnd, GWL_STYLE, style); SetWindowPos(wnd, null, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } /* * Maximise or restore the window in response to a server-side request. * Argument value of 2 means go fullscreen. */ void win_maximise(int max) { if (max == -2) // toggle full screen max = win_is_fullscreen ? 0 : 2; if (IsZoomed(wnd)) { if (!max) ShowWindow(wnd, SW_RESTORE); else if (max == 2 && !win_is_fullscreen) make_fullscreen(); } else if (max) { if (max == 2) fullscr_on_max = true; ShowWindow(wnd, SW_MAXIMIZE); } } /* * Go back to configured window size. */ static void default_size(void) { if (IsZoomed(wnd)) ShowWindow(wnd, SW_RESTORE); win_set_chars(cfg.rows, cfg.cols); } static void update_transparency(void) { int trans = cfg.transparency; if (trans == TR_GLASS) trans = 0; LONG style = GetWindowLong(wnd, GWL_EXSTYLE); style = trans ? style | WS_EX_LAYERED : style & ~WS_EX_LAYERED; SetWindowLong(wnd, GWL_EXSTYLE, style); if (trans) { if (cfg.opaque_when_focused && term.has_focus) trans = 0; SetLayeredWindowAttributes(wnd, 0, 255 - (uchar)trans, LWA_ALPHA); } update_glass(); } void win_update_scrollbar(void) { int scrollbar = term.show_scrollbar ? cfg.scrollbar : 0; LONG style = GetWindowLong(wnd, GWL_STYLE); SetWindowLong(wnd, GWL_STYLE, scrollbar ? style | WS_VSCROLL : style & ~WS_VSCROLL); LONG exstyle = GetWindowLong(wnd, GWL_EXSTYLE); SetWindowLong(wnd, GWL_EXSTYLE, scrollbar < 0 ? exstyle | WS_EX_LEFTSCROLLBAR : exstyle & ~WS_EX_LEFTSCROLLBAR); SetWindowPos(wnd, null, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } void win_reconfig(void) { trace_resize(("--- win_reconfig\n")); /* Pass new config data to the terminal */ term_reconfig(); bool font_changed = strcmp(new_cfg.font.name, cfg.font.name) || new_cfg.font.size != cfg.font.size || new_cfg.font.isbold != cfg.font.isbold || new_cfg.bold_as_font != cfg.bold_as_font || new_cfg.bold_as_colour != cfg.bold_as_colour || new_cfg.font_smoothing != cfg.font_smoothing; if (new_cfg.fg_colour != cfg.fg_colour) win_set_colour(FG_COLOUR_I, new_cfg.fg_colour); if (new_cfg.bg_colour != cfg.bg_colour) win_set_colour(BG_COLOUR_I, new_cfg.bg_colour); if (new_cfg.cursor_colour != cfg.cursor_colour) win_set_colour(CURSOR_COLOUR_I, new_cfg.cursor_colour); /* Copy the new config and refresh everything */ copy_config(&cfg, &new_cfg); if (font_changed) { win_init_fonts(cfg.font.size); trace_resize((" (win_reconfig -> win_adapt_term_size)\n")); win_adapt_term_size(true, false); } win_update_scrollbar(); update_transparency(); win_update_mouse(); bool old_ambig_wide = cs_ambig_wide; cs_reconfig(); if (term.report_font_changed && font_changed) if (term.report_ambig_width) child_write(cs_ambig_wide ? "\e[2W" : "\e[1W", 4); else child_write("\e[0W", 4); else if (term.report_ambig_width && old_ambig_wide != cs_ambig_wide) child_write(cs_ambig_wide ? "\e[2W" : "\e[1W", 4); } static bool confirm_exit(void) { if (!child_is_parent()) return true; /* retrieve list of child processes */ char * pscmd = "procps -o pid,ruser=USER -o comm -t %s 2> /dev/null || ps -ef"; char * tty = child_tty(); if (strrchr (tty, '/')) tty = strrchr (tty, '/') + 1; char cmd[strlen(pscmd) + strlen(tty) + 1]; sprintf (cmd, pscmd, tty, tty); FILE * procps = popen (cmd, "r"); char * msg_pre = "Processes are running in session:\n"; char * msg_post = "Close anyway?"; char * msg = malloc (strlen (msg_pre) + 1); strcpy (msg, msg_pre); if (procps) { char line[999]; // use very long input despite narrow msg box // to avoid high risk of clipping within UTF-8 // and failing the wide character transformation bool first = true; bool filter_tty = false; while (fgets(line, sizeof line, procps)) { line[strcspn(line, "\r\n")] = 0; /* trim newline */ if (first || !filter_tty || strstr (line, tty)) // should check column position too... { if (first) { if (strstr (line, "TTY")) { filter_tty = true; } first = false; } msg = realloc (msg, strlen (msg) + strlen (line) + 2); strcat (msg, line); strcat (msg, "\n"); } } fclose(procps); } msg = realloc (msg, strlen (msg) + strlen (msg_post) + 1); strcat (msg, msg_post); size_t size = cs_mbstowcs(0, msg, 0) + 1; int ret; if (size) { wchar msgw[size]; cs_mbstowcs(msgw, msg, size); wchar appn[strlen(APPNAME) + 1]; cs_mbstowcs(appn, APPNAME, sizeof appn); ret = MessageBoxW( wnd, msgw, appn, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 ); } else { ret = MessageBox( wnd, msg, APPNAME, MB_ICONWARNING | MB_OKCANCEL | MB_DEFBUTTON2 ); } // Treat failure to show the dialog as confirmation. return !ret || ret == IDOK; } static LRESULT CALLBACK win_proc(HWND wnd, UINT message, WPARAM wp, LPARAM lp) { switch (message) { when WM_TIMER: { KillTimer(wnd, wp); void_fn cb = (void_fn)wp; cb(); return 0; } when WM_CLOSE: if (!cfg.confirm_exit || confirm_exit()) child_kill((GetKeyState(VK_SHIFT) & 0x80) != 0); return 0; when WM_COMMAND or WM_SYSCOMMAND: switch (wp & ~0xF) { /* low 4 bits reserved to Windows */ when IDM_OPEN: term_open(); when IDM_COPY: term_copy(); when IDM_PASTE: win_paste(); when IDM_SELALL: term_select_all(); win_update(); when IDM_RESET: term_reset(); win_update(); when IDM_DEFSIZE: default_size(); when IDM_FULLSCREEN: win_maximise(win_is_fullscreen ? 0 : 2); when IDM_FLIPSCREEN: term_flip_screen(); when IDM_OPTIONS: win_open_config(); when IDM_NEW: child_fork(main_argc, main_argv); when IDM_COPYTITLE: win_copy_title(); } when WM_VSCROLL: switch (LOWORD(wp)) { when SB_BOTTOM: term_scroll(-1, 0); when SB_TOP: term_scroll(+1, 0); when SB_LINEDOWN: term_scroll(0, +1); when SB_LINEUP: term_scroll(0, -1); when SB_PAGEDOWN: term_scroll(0, +max(1, term.rows - 1)); when SB_PAGEUP: term_scroll(0, -max(1, term.rows - 1)); when SB_THUMBPOSITION or SB_THUMBTRACK: { SCROLLINFO info; info.cbSize = sizeof(SCROLLINFO); info.fMask = SIF_TRACKPOS; GetScrollInfo(wnd, SB_VERT, &info); term_scroll(1, info.nTrackPos); } } when WM_LBUTTONDOWN: win_mouse_click(MBT_LEFT, lp); when WM_RBUTTONDOWN: win_mouse_click(MBT_RIGHT, lp); when WM_MBUTTONDOWN: win_mouse_click(MBT_MIDDLE, lp); when WM_LBUTTONUP: win_mouse_release(MBT_LEFT, lp); when WM_RBUTTONUP: win_mouse_release(MBT_RIGHT, lp); when WM_MBUTTONUP: win_mouse_release(MBT_MIDDLE, lp); when WM_MOUSEMOVE: win_mouse_move(false, lp); when WM_NCMOUSEMOVE: win_mouse_move(true, lp); when WM_MOUSEWHEEL: win_mouse_wheel(wp, lp); when WM_KEYDOWN or WM_SYSKEYDOWN: if (win_key_down(wp, lp)) return 0; when WM_KEYUP or WM_SYSKEYUP: if (win_key_up(wp, lp)) return 0; when WM_CHAR or WM_SYSCHAR: child_sendw(&(wchar){wp}, 1); return 0; when WM_INPUTLANGCHANGE: win_set_ime_open(ImmIsIME(GetKeyboardLayout(0)) && ImmGetOpenStatus(imc)); when WM_IME_NOTIFY: if (wp == IMN_SETOPENSTATUS) win_set_ime_open(ImmGetOpenStatus(imc)); when WM_IME_STARTCOMPOSITION: ImmSetCompositionFont(imc, &lfont); when WM_IME_COMPOSITION: if (lp & GCS_RESULTSTR) { LONG len = ImmGetCompositionStringW(imc, GCS_RESULTSTR, null, 0); if (len > 0) { char buf[len]; ImmGetCompositionStringW(imc, GCS_RESULTSTR, buf, len); child_sendw((wchar *)buf, len / 2); } return 1; } when WM_PAINT: win_paint(); return 0; when WM_SETFOCUS: term_set_focus(true); CreateCaret(wnd, caretbm, 0, 0); flash_taskbar(false); /* stop */ win_update(); update_transparency(); ShowCaret(wnd); when WM_KILLFOCUS: win_show_mouse(); term_set_focus(false); DestroyCaret(); win_update(); update_transparency(); when WM_ENTERSIZEMOVE: trace_resize(("--- WM_ENTERSIZEMOVE VK_SHIFT %02X\n", GetKeyState(VK_SHIFT))); resizing = true; when WM_EXITSIZEMOVE or WM_CAPTURECHANGED: // after mouse-drag resizing trace_resize(("--- WM_EXITSIZEMOVE (resizing %d) VK_SHIFT %02X\n", resizing, GetKeyState(VK_SHIFT))); if (resizing) { resizing = false; win_destroy_tip(); trace_resize((" (win_proc -> win_adapt_term_size)\n")); win_adapt_term_size(GetKeyState(VK_SHIFT) & 0x80, false); } when WM_SIZING: { // mouse-drag window resizing trace_resize(("--- WM_SIZING (resizing %d) VK_SHIFT %02X\n", resizing, GetKeyState(VK_SHIFT))); /* * This does two jobs: * 1) Keep the tip uptodate * 2) Make sure the window size is _stepped_ in units of the font size. */ LPRECT r = (LPRECT) lp; int width = r->right - r->left - extra_width - 2 * PADDING; int height = r->bottom - r->top - extra_height - 2 * PADDING; int cols = max(1, (float)width / font_width + 0.5); int rows = max(1, (float)height / font_height + 0.5); int ew = width - cols * font_width; int eh = height - rows * font_height; if (wp >= WMSZ_BOTTOM) { wp -= WMSZ_BOTTOM; r->bottom -= eh; } else if (wp >= WMSZ_TOP) { wp -= WMSZ_TOP; r->top += eh; } if (wp == WMSZ_RIGHT) r->right -= ew; else if (wp == WMSZ_LEFT) r->left += ew; win_show_tip(r->left + extra_width, r->top + extra_height, cols, rows); return ew || eh; } when WM_SIZE: { trace_resize(("--- WM_SIZE (resizing %d) VK_SHIFT %02X\n", resizing, GetKeyState(VK_SHIFT))); if (wp == SIZE_RESTORED && win_is_fullscreen) clear_fullscreen(); else if (wp == SIZE_MAXIMIZED && fullscr_on_max) { fullscr_on_max = false; make_fullscreen(); } if (!resizing) { trace_resize((" (win_proc -> win_adapt_term_size)\n")); win_adapt_term_size(false, GetKeyState(VK_SHIFT) & 0x80); } return 0; } when WM_INITMENU: win_update_menus(); return 0; } /* * Any messages we don't process completely above are passed through to * DefWindowProc() for default processing. */ return DefWindowProcW(wnd, message, wp, lp); } static const char help[] = "Usage: " APPNAME " [OPTION]... [ PROGRAM [ARG]... | - ]\n" "\n" "Start a new terminal session running the specified program or the user's shell.\n" "If a dash is given instead of a program, invoke the shell as a login shell.\n" "\n" "Options:\n" " -c, --config FILE Load specified config file\n" " -e, --exec Treat remaining arguments as the command to execute\n" " -h, --hold never|start|error|always Keep window open after command finishes\n" " -i, --icon FILE[,IX] Load window icon from file, optionally with index\n" " -l, --log FILE|- Log output to file or stdout\n" " -o, --option OPT=VAL Override config file option with given value\n" " -p, --position X,Y Open window at specified coordinates\n" " -s, --size COLS,ROWS Set screen size in characters\n" " -t, --title TITLE Set window title (default: the invoked command)\n" " -u, --utmp Create a utmp entry\n" " -w, --window normal|min|max|full|hide Set initial window state\n" " --class CLASS Set window class name (default: " APPNAME ")\n" " -H, --help Display help and exit\n" " -V, --version Print version information and exit\n" ; static const char short_opts[] = "+:c:eh:i:l:o:p:s:t:T:B:uw:HV:D"; static const struct option opts[] = { {"config", required_argument, 0, 'c'}, {"exec", no_argument, 0, 'e'}, {"hold", required_argument, 0, 'h'}, {"icon", required_argument, 0, 'i'}, {"log", required_argument, 0, 'l'}, {"utmp", no_argument, 0, 'u'}, {"option", required_argument, 0, 'o'}, {"position", required_argument, 0, 'p'}, {"size", required_argument, 0, 's'}, {"title", required_argument, 0, 't'}, {"Title", required_argument, 0, 'T'}, {"Border", required_argument, 0, 'B'}, {"window", required_argument, 0, 'w'}, {"class", required_argument, 0, 'C'}, {"help", no_argument, 0, 'H'}, {"version", no_argument, 0, 'V'}, {"daemon", no_argument, 0, 'D'}, {0, 0, 0, 0} }; static void show_msg(FILE *stream, string msg) { if (fputs(msg, stream) < 0 || fflush(stream) < 0) MessageBox(0, msg, APPNAME, MB_OK); } static no_return __attribute__((format(printf, 1, 2))) error(char *format, ...) { char *msg; va_list va; va_start(va, format); vasprintf(&msg, format, va); va_end(va); msg = asform("%s: %s\nTry '--help' for more information.\n", main_argv[0], msg); show_msg(stderr, msg); exit(1); } static void __attribute__((format(printf, 1, 2))) warn(char *format, ...) { char *msg; va_list va; va_start(va, format); vasprintf(&msg, format, va); va_end(va); msg = asform("%s: %s\n", main_argv[0], msg); show_msg(stderr, msg); } int main(int argc, char *argv[]) { main_argv = argv; main_argc = argc; // Henri: too early! #if 0 load_dwm_funcs(); #endif init_config(); cs_init(); // Determine home directory. home = getenv("HOME"); #if CYGWIN_VERSION_DLL_MAJOR >= 1005 // Before Cygwin 1.5, the passwd structure is faked. struct passwd *pw = getpwuid(getuid()); #endif home = home ? strdup(home) : #if CYGWIN_VERSION_DLL_MAJOR >= 1005 (pw && pw->pw_dir && *pw->pw_dir) ? strdup(pw->pw_dir) : #endif asform("/home/%s", getlogin()); // Set size and position defaults. STARTUPINFO sui; GetStartupInfo(&sui); cfg.window = sui.dwFlags & STARTF_USESHOWWINDOW ? sui.wShowWindow : SW_SHOW; cfg.x = cfg.y = CW_USEDEFAULT; load_config("/etc/minttyrc"); string rc_file = asform("%s/.minttyrc", home); load_config(rc_file); delete(rc_file); if (getenv("MINTTY_ROWS")) { set_arg_option("Rows", getenv("MINTTY_ROWS")); } if (getenv("MINTTY_COLS")) { set_arg_option("Columns", getenv("MINTTY_COLS")); } for (;;) { int opt = getopt_long(argc, argv, short_opts, opts, 0); if (opt == -1 || opt == 'e') break; char *longopt = argv[optind - 1], *shortopt = (char[]){'-', optopt, 0}; switch (opt) { when 'c': load_config(optarg); when 'h': set_arg_option("Hold", optarg); when 'i': set_arg_option("Icon", optarg); when 'l': set_arg_option("Log", optarg); when 'o': parse_arg_option(optarg); when 'p': if (sscanf(optarg, "%i,%i%1s", &cfg.x, &cfg.y, (char[2]){}) != 2) error("syntax error in position argument '%s'", optarg); when 's': if (sscanf(optarg, "%u,%u%1s", &cfg.cols, &cfg.rows, (char[2]){}) != 2) error("syntax error in size argument '%s'", optarg); remember_arg("Columns"); remember_arg("Rows"); when 't': set_arg_option("Title", optarg); when 'T': set_arg_option("Title", optarg); title_settable = false; when 'B': border_style = strdup (optarg); when 'u': cfg.utmp = true; when 'w': set_arg_option("Window", optarg); when 'C': set_arg_option("Class", optarg); when 'D': daemonize = true; when 'H': show_msg(stdout, help); return 0; when 'V': show_msg(stdout, VERSION_TEXT); return 0; when '?': error("unknown option '%s'", optopt ? shortopt : longopt); when ':': error("option '%s' requires an argument", longopt[1] == '-' ? longopt : shortopt); } } finish_config(); // if started from console, try to detach from caller's terminal (~daemonize) // in order to not suppress signals // (indicated by isatty if linked with -mwindows) #if 0 // Thomas if (daemonize && !isatty(0)) { if (fork() > 0) exit(0); setsid(); } #endif #if 1 // Henri if (getppid() != (pid_t)1) { if (getpgrp() == getpid()) { switch (fork()) { case -1: error("fork"); case 0: /* child */ break; default: /* parent */ return 0; } } if (setsid() < 0) { error("setsid"); } } // if (getppid() != (pid_t)1) #endif // Henri: load dwmapi.dll when it makes sense (after fork()) #if 1 load_dwm_funcs(); #endif // Work out what to execute. argv += optind; if (*argv && (argv[1] || strcmp(*argv, "-"))) cmd = *argv; else { // Look up the user's shell. cmd = getenv("SHELL"); cmd = cmd ? strdup(cmd) : #if CYGWIN_VERSION_DLL_MAJOR >= 1005 (pw && pw->pw_shell && *pw->pw_shell) ? strdup(pw->pw_shell) : #endif "/bin/sh"; // Determine the program name argument. char *slash = strrchr(cmd, '/'); char *arg0 = slash ? slash + 1 : cmd; // Prepend '-' if a login shell was requested. if (*argv) arg0 = asform("-%s", arg0); // Create new argument array. argv = newn(char *, 2); *argv = arg0; } // Load icon if specified. HICON large_icon = 0, small_icon = 0; if (*cfg.icon) { string icon_file = strdup(cfg.icon); uint icon_index = 0; char *comma = strrchr(icon_file, ','); if (comma) { char *start = comma + 1, *end; icon_index = strtoul(start, &end, 0); if (start != end && !*end) *comma = 0; else icon_index = 0; } SetLastError(0); #if CYGWIN_VERSION_API_MINOR >= 181 wchar *win_icon_file = cygwin_create_path(CCP_POSIX_TO_WIN_W, icon_file); if (win_icon_file) { ExtractIconExW(win_icon_file, icon_index, &large_icon, &small_icon, 1); free(win_icon_file); } #else char win_icon_file[MAX_PATH]; cygwin_conv_to_win32_path(icon_file, win_icon_file); ExtractIconExA(win_icon_file, icon_index, &large_icon, &small_icon, 1); #endif if (!large_icon) { small_icon = 0; uint error = GetLastError(); if (error) { char msg[1024]; FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_MAX_WIDTH_MASK, 0, error, 0, msg, sizeof msg, 0 ); warn("could not load icon from '%s': %s", cfg.icon, msg); } else warn("could not load icon from '%s'", cfg.icon); } delete(icon_file); } // Set the AppID if specified and the required function is available. if (*cfg.app_id) { HMODULE shell = load_sys_library("shell32.dll"); HRESULT (WINAPI *pSetAppID)(PCWSTR) = (void *)GetProcAddress(shell, "SetCurrentProcessExplicitAppUserModelID"); if (pSetAppID) { size_t size = cs_mbstowcs(0, cfg.app_id, 0) + 1; if (size) { wchar buf[size]; cs_mbstowcs(buf, cfg.app_id, size); pSetAppID(buf); } } } inst = GetModuleHandle(NULL); // Window class name. wstring wclass = _W(APPNAME); if (*cfg.class) { size_t size = cs_mbstowcs(0, cfg.class, 0) + 1; if (size) { wchar *buf = newn(wchar, size); cs_mbstowcs(buf, cfg.class, size); wclass = buf; } else fputs("Using default class name due to invalid characters.\n", stderr); } // Put child command line into window title if we haven't got one already. string title = cfg.title; if (!*title) { size_t len; char *argz; argz_create(argv, &argz, &len); argz_stringify(argz, len, ' '); title = argz; } // Convert title to Unicode. Default to application name if unsuccessful. wstring wtitle = _W(APPNAME); { size_t size = cs_mbstowcs(0, title, 0) + 1; if (size) { wchar *buf = newn(wchar, size); cs_mbstowcs(buf, title, size); wtitle = buf; } else fputs("Using default title due to invalid characters.\n", stderr); } // The window class. class_atom = RegisterClassExW(&(WNDCLASSEXW){ .cbSize = sizeof(WNDCLASSEXW), .style = 0, .lpfnWndProc = win_proc, .cbClsExtra = 0, .cbWndExtra = 0, .hInstance = inst, .hIcon = large_icon ?: LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON)), .hIconSm = small_icon, .hCursor = LoadCursor(null, IDC_IBEAM), .hbrBackground = null, .lpszMenuName = null, .lpszClassName = wclass, }); // Initialise the fonts, thus also determining their width and height. win_init_fonts(cfg.font.size); // Reconfigure the charset module now that arguments have been converted, // the locale/charset settings have been loaded, and the font width has // been determined. cs_reconfig(); // Determine window sizes. int term_width = font_width * cfg.cols; int term_height = font_height * cfg.rows; RECT cr = {0, 0, term_width + 2 * PADDING, term_height + 2 * PADDING}; RECT wr = cr; AdjustWindowRect(&wr, WS_OVERLAPPEDWINDOW, false); int width = wr.right - wr.left; int height = wr.bottom - wr.top; if (cfg.scrollbar) width += GetSystemMetrics(SM_CXVSCROLL); extra_width = width - (cr.right - cr.left); extra_height = height - (cr.bottom - cr.top); // Having x == CW_USEDEFAULT but not still triggers the default positioning, // whereas y==CW_USEFAULT but not x results in an invisible window, so to // avoid the latter, require both x and y to be set for custom positioning. if (cfg.y == (int)CW_USEDEFAULT) cfg.x = CW_USEDEFAULT; // Create initial window. wnd = CreateWindowExW(cfg.scrollbar < 0 ? WS_EX_LEFTSCROLLBAR : 0, wclass, wtitle, WS_OVERLAPPEDWINDOW | (cfg.scrollbar ? WS_VSCROLL : 0), cfg.x, cfg.y, width, height, null, null, inst, null); if (border_style) { LONG style = GetWindowLong(wnd, GWL_STYLE); if (strcmp (border_style, "void") == 0) { style &= ~(WS_CAPTION | WS_BORDER | WS_THICKFRAME); } else { style &= ~(WS_CAPTION | WS_BORDER); } SetWindowLong(wnd, GWL_STYLE, style); SetWindowPos(wnd, null, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); } // The input method context. imc = ImmGetContext(wnd); // Correct autoplacement, which likes to put part of the window under the // taskbar when the window size approaches the work area size. if (cfg.x == (int)CW_USEDEFAULT) { win_fix_position(); } // Initialise the terminal. term_reset(); term_resize(cfg.rows, cfg.cols); // Initialise the scroll bar. SetScrollInfo( wnd, SB_VERT, &(SCROLLINFO){ .cbSize = sizeof(SCROLLINFO), .fMask = SIF_ALL | SIF_DISABLENOSCROLL, .nMin = 0, .nMax = cfg.rows - 1, .nPage = cfg.rows, .nPos = 0, }, false ); // Set up an empty caret bitmap. We're painting the cursor manually. caretbm = CreateBitmap(1, font_height, 1, 1, newn(short, font_height)); CreateCaret(wnd, caretbm, 0, 0); // Initialise various other stuff. win_init_drop_target(); win_init_menus(); update_transparency(); // Create child process. child_create( argv, &(struct winsize){cfg.rows, cfg.cols, term_width, term_height} ); // Finally show the window! fullscr_on_max = (cfg.window == -1); ShowWindow(wnd, fullscr_on_max ? SW_SHOWMAXIMIZED : cfg.window); // Message loop. for (;;) { MSG msg; while (PeekMessage(&msg, null, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) return msg.wParam; if (!IsDialogMessage(config_wnd, &msg)) DispatchMessage(&msg); } child_proc(); } } ------=_20150727175807_31619 Content-Type: application/octet-stream; name="winmain.c.orig" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="winmain.c.orig" Ly8gd2luLmMgKHBhcnQgb2YgbWludHR5KQovLyBDb3B5cmlnaHQgMjAwOC0x MyBBbmR5IEtvcHBlCi8vIEJhc2VkIG9uIGNvZGUgZnJvbSBQdVRUWS0wLjYw IGJ5IFNpbW9uIFRhdGhhbSBhbmQgdGVhbS4KLy8gTGljZW5zZWQgdW5kZXIg dGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2 MyBvciBsYXRlci4KCiNpbmNsdWRlICJ3aW5wcml2LmgiCgojaW5jbHVkZSAi dGVybS5oIgojaW5jbHVkZSAiYXBwaW5mby5oIgojaW5jbHVkZSAiY2hpbGQu aCIKI2luY2x1ZGUgImNoYXJzZXQuaCIKCiNpbmNsdWRlIDxsb2NhbGUuaD4K I2luY2x1ZGUgPGdldG9wdC5oPgojaW5jbHVkZSA8cHdkLmg+CiNpbmNsdWRl IDxzaGVsbGFwaS5oPgoKI2luY2x1ZGUgPHN5cy9jeWd3aW4uaD4KCkhJTlNU QU5DRSBpbnN0OwpIV05EIHduZDsKSElNQyBpbWM7Cgpib29sIHdpbl9pc19m dWxsX3NjcmVlbjsKCnN0YXRpYyBjaGFyICoqbWFpbl9hcmd2OwpzdGF0aWMg aW50IG1haW5fYXJnYzsKc3RhdGljIEFUT00gY2xhc3NfYXRvbTsKCnN0YXRp YyBpbnQgZXh0cmFfd2lkdGgsIGV4dHJhX2hlaWdodDsKc3RhdGljIGJvb2wg ZnVsbHNjcl9vbl9tYXg7CnN0YXRpYyBib29sIHJlc2l6aW5nOwpzdGF0aWMg Ym9vbCB0aXRsZV9zZXR0YWJsZSA9IHRydWU7CnN0YXRpYyBib29sIGRhZW1v bml6ZSA9IGZhbHNlOwpzdGF0aWMgc3RyaW5nIGJvcmRlcl9zdHlsZSA9IDA7 CgpzdGF0aWMgSEJJVE1BUCBjYXJldGJtOwoKI2lmIFdJTlZFUiA8IDB4NjAw Cgp0eXBlZGVmIHN0cnVjdCB7CiAgaW50IGN4TGVmdFdpZHRoOwogIGludCBj eFJpZ2h0V2lkdGg7CiAgaW50IGN5VG9wSGVpZ2h0OwogIGludCBjeUJvdHRv bUhlaWdodDsKfSBNQVJHSU5TOwoKI2VuZGlmCgpzdGF0aWMgSFJFU1VMVCAo V0lOQVBJICpwRHdtSXNDb21wb3NpdGlvbkVuYWJsZWQpKEJPT0wgKik7CnN0 YXRpYyBIUkVTVUxUIChXSU5BUEkgKnBEd21FeHRlbmRGcmFtZUludG9DbGll bnRBcmVhKShIV05ELCBjb25zdCBNQVJHSU5TICopOwoKLy8gSGVscGVyIGZv ciBsb2FkaW5nIGEgc3lzdGVtIGxpYnJhcnkuIFVzaW5nIExvYWRMaWJyYXJ5 KCkgZGlyZWN0bHkgaXMgaW5zZWN1cmUKLy8gYmVjYXVzZSBXaW5kb3dzIG1p Z2h0IGJlIHNlYXJjaGluZyB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9y eSBmaXJzdC4Kc3RhdGljIEhNT0RVTEUKbG9hZF9zeXNfbGlicmFyeShzdHJp bmcgbmFtZSkKewogIGNoYXIgcGF0aFtNQVhfUEFUSF07CiAgdWludCBsZW4g PSBHZXRTeXN0ZW1EaXJlY3RvcnkocGF0aCwgTUFYX1BBVEgpOwogIGlmIChs ZW4gJiYgbGVuICsgc3RybGVuKG5hbWUpICsgMSA8IE1BWF9QQVRIKSB7CiAg ICBwYXRoW2xlbl0gPSAnXFwnOwogICAgc3RyY3B5KCZwYXRoW2xlbiArIDFd LCBuYW1lKTsKICAgIHJldHVybiBMb2FkTGlicmFyeShwYXRoKTsKICB9CiAg ZWxzZQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkCmxvYWRfZHdtX2Z1 bmNzKHZvaWQpCnsKICBITU9EVUxFIGR3bSA9IGxvYWRfc3lzX2xpYnJhcnko ImR3bWFwaS5kbGwiKTsKICBpZiAoZHdtKSB7CiAgICBwRHdtSXNDb21wb3Np dGlvbkVuYWJsZWQgPQogICAgICAodm9pZCAqKUdldFByb2NBZGRyZXNzKGR3 bSwgIkR3bUlzQ29tcG9zaXRpb25FbmFibGVkIik7CiAgICBwRHdtRXh0ZW5k RnJhbWVJbnRvQ2xpZW50QXJlYSA9CiAgICAgICh2b2lkICopR2V0UHJvY0Fk ZHJlc3MoZHdtLCAiRHdtRXh0ZW5kRnJhbWVJbnRvQ2xpZW50QXJlYSIpOwog IH0KfQoKdm9pZAp3aW5fc2V0X3RpbWVyKHZvaWQgKCpjYikodm9pZCksIHVp bnQgdGlja3MpCnsgU2V0VGltZXIod25kLCAoVUlOVF9QVFIpY2IsIHRpY2tz LCBudWxsKTsgfQoKdm9pZAp3aW5fc2V0X3RpdGxlKGNoYXIgKnRpdGxlKQp7 CiAgaWYgKHRpdGxlX3NldHRhYmxlKSB7CiAgICB3Y2hhciB3dGl0bGVbc3Ry bGVuKHRpdGxlKSArIDFdOwogICAgaWYgKGNzX21ic3Rvd2NzKHd0aXRsZSwg dGl0bGUsIGxlbmd0aG9mKHd0aXRsZSkpID49IDApCiAgICAgIFNldFdpbmRv d1RleHRXKHduZCwgd3RpdGxlKTsKICB9Cn0KCnZvaWQKd2luX2NvcHlfdGl0 bGUodm9pZCkKewogIGludCBsZW4gPSBHZXRXaW5kb3dUZXh0TGVuZ3RoVyh3 bmQpOwogIHdjaGFyIHRpdGxlW2xlbiArIDFdOwogIGxlbiA9IEdldFdpbmRv d1RleHRXKHduZCwgdGl0bGUsIGxlbiArIDEpOwogIHdpbl9jb3B5KHRpdGxl LCAwLCBsZW4gKyAxKTsKfQoKdm9pZAp3aW5fcHJlZml4X3RpdGxlKGNvbnN0 IGNoYXIgKiBwcmVmaXgpCnsKICBpbnQgbGVuID0gR2V0V2luZG93VGV4dExl bmd0aFcod25kKTsKICB3Y2hhciBwdGl0bGVbc3RybGVuKHByZWZpeCkgKyBs ZW4gKyAxXTsKICBpbnQgcGxlbiA9IGNzX21ic3Rvd2NzKHB0aXRsZSwgcHJl Zml4LCBsZW5ndGhvZihwdGl0bGUpKTsKICB3Y2hhciAqIHRpdGxlID0gJiBw dGl0bGVbcGxlbl07CiAgbGVuID0gR2V0V2luZG93VGV4dFcod25kLCB0aXRs ZSwgbGVuICsgMSk7CiAgU2V0V2luZG93VGV4dFcod25kLCBwdGl0bGUpOwp9 CgovKgogKiBUaXRsZSBzdGFjayAoaW1wbGVtZW50ZWQgYXMgZml4ZWQtc2l6 ZSBjaXJjdWxhciBidWZmZXIpCiAqLwpzdGF0aWMgd3N0cmluZyB0aXRsZXNb MTZdOwpzdGF0aWMgdWludCB0aXRsZXNfaTsKCnZvaWQKd2luX3NhdmVfdGl0 bGUodm9pZCkKewogIGludCBsZW4gPSBHZXRXaW5kb3dUZXh0TGVuZ3RoVyh3 bmQpOwogIHdjaGFyICp0aXRsZSA9IG5ld24od2NoYXIsIGxlbiArIDEpOwog IEdldFdpbmRvd1RleHRXKHduZCwgdGl0bGUsIGxlbiArIDEpOwogIGRlbGV0 ZSh0aXRsZXNbdGl0bGVzX2ldKTsKICB0aXRsZXNbdGl0bGVzX2krK10gPSB0 aXRsZTsKICBpZiAodGl0bGVzX2kgPT0gbGVuZ3Rob2YodGl0bGVzKSkKICAg IHRpdGxlc19pID0gMDsKfQoKdm9pZAp3aW5fcmVzdG9yZV90aXRsZSh2b2lk KQp7CiAgaWYgKCF0aXRsZXNfaSkKICAgIHRpdGxlc19pID0gbGVuZ3Rob2Yo dGl0bGVzKTsKICB3c3RyaW5nIHRpdGxlID0gdGl0bGVzWy0tdGl0bGVzX2ld OwogIGlmICh0aXRsZSkgewogICAgU2V0V2luZG93VGV4dFcod25kLCB0aXRs ZSk7CiAgICBkZWxldGUodGl0bGUpOwogICAgdGl0bGVzW3RpdGxlc19pXSA9 IDA7CiAgfQp9CgovKgogKiAgU3dpdGNoIHRvIG5leHQgb3IgcHJldmlvdXMg YXBwbGljYXRpb24gd2luZG93IGluIHotb3JkZXIKICovCgpzdGF0aWMgSFdO RCBmaXJzdF93bmQsIGxhc3Rfd25kOwoKc3RhdGljIEJPT0wgQ0FMTEJBQ0sK d25kX2VudW1fcHJvYyhIV05EIGN1cnJfd25kLCBMUEFSQU0gdW51c2VkKGxw KSkgewogIGlmIChjdXJyX3duZCAhPSB3bmQgJiYgIUlzSWNvbmljKGN1cnJf d25kKSkgewogICAgV0lORE9XSU5GTyBjdXJyX3duZF9pbmZvOwogICAgY3Vy cl93bmRfaW5mby5jYlNpemUgPSBzaXplb2YoV0lORE9XSU5GTyk7CiAgICBH ZXRXaW5kb3dJbmZvKGN1cnJfd25kLCAmY3Vycl93bmRfaW5mbyk7CiAgICBp ZiAoY2xhc3NfYXRvbSA9PSBjdXJyX3duZF9pbmZvLmF0b21XaW5kb3dUeXBl KSB7CiAgICAgIGZpcnN0X3duZCA9IGZpcnN0X3duZCA/OiBjdXJyX3duZDsK ICAgICAgbGFzdF93bmQgPSBjdXJyX3duZDsKICAgIH0KICB9CiAgcmV0dXJu IHRydWU7Cn0KCnZvaWQKd2luX3N3aXRjaChib29sIGJhY2ssIGJvb2wgYWx0 ZXJuYXRlKQp7CiAgZmlyc3Rfd25kID0gMCwgbGFzdF93bmQgPSAwOwogIEVu dW1XaW5kb3dzKHduZF9lbnVtX3Byb2MsIDApOwogIGlmIChmaXJzdF93bmQp IHsKICAgIGlmIChiYWNrKQogICAgICBmaXJzdF93bmQgPSBsYXN0X3duZDsK ICAgIGVsc2UKICAgICAgU2V0V2luZG93UG9zKHduZCwgbGFzdF93bmQsIDAs IDAsIDAsIDAsIFNXUF9OT01PVkUgfCBTV1BfTk9TSVpFCiAgICAgICAgICAg ICAgICAgICAgICAgfCAoYWx0ZXJuYXRlID8gU1dQX05PWk9SREVSIDogU1dQ X05PUkVQT1NJVElPTikpOwogICAgQnJpbmdXaW5kb3dUb1RvcChmaXJzdF93 bmQpOwogIH0KfQoKc3RhdGljIHZvaWQKZ2V0X21vbml0b3JfaW5mbyhNT05J VE9SSU5GTyAqbWlwKQp7CiAgSE1PTklUT1IgbW9uID0gTW9uaXRvckZyb21X aW5kb3cod25kLCBNT05JVE9SX0RFRkFVTFRUT05FQVJFU1QpOwogIG1pcC0+ Y2JTaXplID0gc2l6ZW9mKE1PTklUT1JJTkZPKTsKICBHZXRNb25pdG9ySW5m byhtb24sIG1pcCk7Cn0KCi8qCiAqIE1pbmltaXNlIG9yIHJlc3RvcmUgdGhl IHdpbmRvdyBpbiByZXNwb25zZSB0byBhIHNlcnZlci1zaWRlCiAqIHJlcXVl c3QuCiAqLwp2b2lkCndpbl9zZXRfaWNvbmljKGJvb2wgaWNvbmljKQp7CiAg aWYgKGljb25pYyBeIElzSWNvbmljKHduZCkpCiAgICBTaG93V2luZG93KHdu ZCwgaWNvbmljID8gU1dfTUlOSU1JWkUgOiBTV19SRVNUT1JFKTsKfQoKLyoK ICogTW92ZSB0aGUgd2luZG93IGluIHJlc3BvbnNlIHRvIGEgc2VydmVyLXNp ZGUgcmVxdWVzdC4KICovCnZvaWQKd2luX3NldF9wb3MoaW50IHgsIGludCB5 KQp7CiAgdHJhY2VfcmVzaXplKCgiLS0tIHdpbl9zZXRfcG9zICVkICVkXG4i LCB4LCB5KSk7CiAgaWYgKCFJc1pvb21lZCh3bmQpKQogICAgU2V0V2luZG93 UG9zKHduZCwgbnVsbCwgeCwgeSwgMCwgMCwgU1dQX05PU0laRSB8IFNXUF9O T1pPUkRFUik7Cn0KCi8qCiAqIE1vdmUgdGhlIHdpbmRvdyB0byB0aGUgdG9w IG9yIGJvdHRvbSBvZiB0aGUgei1vcmRlciBpbiByZXNwb25zZQogKiB0byBh IHNlcnZlci1zaWRlIHJlcXVlc3QuCiAqLwp2b2lkCndpbl9zZXRfem9yZGVy KGJvb2wgdG9wKQp7CiAgU2V0V2luZG93UG9zKHduZCwgdG9wID8gSFdORF9U T1AgOiBIV05EX0JPVFRPTSwgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAg U1dQX05PTU9WRSB8IFNXUF9OT1NJWkUpOwp9Cgpib29sCndpbl9pc19pY29u aWModm9pZCkKewogIHJldHVybiBJc0ljb25pYyh3bmQpOwp9Cgp2b2lkCndp bl9nZXRfcG9zKGludCAqeHAsIGludCAqeXApCnsKICBSRUNUIHI7CiAgR2V0 V2luZG93UmVjdCh3bmQsICZyKTsKICAqeHAgPSByLmxlZnQ7CiAgKnlwID0g ci50b3A7Cn0KCnZvaWQKd2luX2dldF9waXhlbHMoaW50ICpoZWlnaHRfcCwg aW50ICp3aWR0aF9wKQp7CiAgUkVDVCByOwogIEdldFdpbmRvd1JlY3Qod25k LCAmcik7CiAgKmhlaWdodF9wID0gci5ib3R0b20gLSByLnRvcDsKICAqd2lk dGhfcCA9IHIucmlnaHQgLSByLmxlZnQ7Cn0KCnZvaWQKd2luX2dldF9zY3Jl ZW5fY2hhcnMoaW50ICpyb3dzX3AsIGludCAqY29sc19wKQp7CiAgTU9OSVRP UklORk8gbWk7CiAgZ2V0X21vbml0b3JfaW5mbygmbWkpOwogIFJFQ1QgZnIg PSBtaS5yY01vbml0b3I7CiAgKnJvd3NfcCA9IChmci5ib3R0b20gLSBmci50 b3ApIC8gZm9udF9oZWlnaHQ7CiAgKmNvbHNfcCA9IChmci5yaWdodCAtIGZy LmxlZnQpIC8gZm9udF93aWR0aDsKfQoKdm9pZAp3aW5fc2V0X3BpeGVscyhp bnQgaGVpZ2h0LCBpbnQgd2lkdGgpCnsKICB0cmFjZV9yZXNpemUoKCItLS0g d2luX3NldF9waXhlbHMgJWQgJWRcbiIsIGhlaWdodCwgd2lkdGgpKTsKICBT ZXRXaW5kb3dQb3Mod25kLCBudWxsLCAwLCAwLAogICAgICAgICAgICAgICB3 aWR0aCArIDIgKiBQQURESU5HICsgZXh0cmFfd2lkdGgsCiAgICAgICAgICAg ICAgIGhlaWdodCArIDIgKiBQQURESU5HICsgZXh0cmFfaGVpZ2h0LAogICAg ICAgICAgICAgICBTV1BfTk9BQ1RJVkFURSB8IFNXUF9OT0NPUFlCSVRTIHwg U1dQX05PTU9WRSB8IFNXUF9OT1pPUkRFUik7Cn0KCnN0YXRpYyB2b2lkCndp bl9maXhfcG9zaXRpb24odm9pZCkKewogICAgUkVDVCB3cjsKICAgIEdldFdp bmRvd1JlY3Qod25kLCAmd3IpOwogICAgTU9OSVRPUklORk8gbWk7CiAgICBn ZXRfbW9uaXRvcl9pbmZvKCZtaSk7CiAgICBSRUNUIGFyID0gbWkucmNXb3Jr OwoKICAgIC8vIENvcnJlY3QgZWRnZXMuIFRvcCBhbmQgbGVmdCB3aW4gaWYg dGhlIHdpbmRvdyBpcyB0b28gYmlnLgogICAgd3IubGVmdCAtPSBtYXgoMCwg d3IucmlnaHQgLSBhci5yaWdodCk7CiAgICB3ci50b3AgLT0gbWF4KDAsIHdy LmJvdHRvbSAtIGFyLmJvdHRvbSk7CiAgICB3ci5sZWZ0ID0gbWF4KHdyLmxl ZnQsIGFyLmxlZnQpOwogICAgd3IudG9wID0gbWF4KHdyLnRvcCwgYXIudG9w KTsKCiAgICBTZXRXaW5kb3dQb3Mod25kLCAwLCB3ci5sZWZ0LCB3ci50b3As IDAsIDAsCiAgICAgICAgICAgICAgICAgU1dQX05PU0laRSB8IFNXUF9OT1pP UkRFUiB8IFNXUF9OT0FDVElWQVRFKTsKfQoKdm9pZAp3aW5fc2V0X2NoYXJz KGludCByb3dzLCBpbnQgY29scykKewogIHRyYWNlX3Jlc2l6ZSgoIi0tLSB3 aW5fc2V0X2NoYXJzICVkw5clZFxuIiwgcm93cywgY29scykpOwogIHdpbl9z ZXRfcGl4ZWxzKHJvd3MgKiBmb250X2hlaWdodCwgY29scyAqIGZvbnRfd2lk dGgpOwogIHdpbl9maXhfcG9zaXRpb24oKTsKfQoKCi8vIENsb2Nrd29yawpp bnQgZ2V0X3RpY2tfY291bnQodm9pZCkgeyByZXR1cm4gR2V0VGlja0NvdW50 KCk7IH0KaW50IGN1cnNvcl9ibGlua190aWNrcyh2b2lkKSB7IHJldHVybiBH ZXRDYXJldEJsaW5rVGltZSgpOyB9CgpzdGF0aWMgdm9pZApmbGFzaF90YXNr YmFyKGJvb2wgZW5hYmxlKQp7CiAgc3RhdGljIGJvb2wgZW5hYmxlZDsKICBp ZiAoZW5hYmxlICE9IGVuYWJsZWQpIHsKICAgIEZsYXNoV2luZG93RXgoJihG TEFTSFdJTkZPKXsKICAgICAgLmNiU2l6ZSA9IHNpemVvZihGTEFTSFdJTkZP KSwKICAgICAgLmh3bmQgPSB3bmQsCiAgICAgIC5kd0ZsYWdzID0gZW5hYmxl ID8gRkxBU0hXX1RSQVkgfCBGTEFTSFdfVElNRVIgOiBGTEFTSFdfU1RPUCwK ICAgICAgLnVDb3VudCA9IDEsCiAgICAgIC5kd1RpbWVvdXQgPSAwCiAgICB9 KTsKICAgIGVuYWJsZWQgPSBlbmFibGU7CiAgfQp9CgovKgogKiBCZWxsLgog Ki8Kdm9pZAp3aW5fYmVsbCh2b2lkKQp7CiAgaWYgKGNmZy5iZWxsX3NvdW5k IHx8IGNmZy5iZWxsX3R5cGUpIHsKICAgIGlmIChjZmcuYmVsbF9mcmVxKQog ICAgICBCZWVwKGNmZy5iZWxsX2ZyZXEsIGNmZy5iZWxsX2xlbik7CiAgICBl bHNlIHsKICAgICAgLy8gMCAgTUJfT0sgICAgICAgICAgICAgICBEZWZhdWx0 IEJlZXAKICAgICAgLy8gMSAgTUJfSUNPTlNUT1AgICAgICAgICBDcml0aWNh bCBTdG9wCiAgICAgIC8vIDIgIE1CX0lDT05RVUVTVElPTiAgICAgUXVlc3Rp b24KICAgICAgLy8gMyAgTUJfSUNPTkVYQ0xBTUFUSU9OICBFeGNsYW1hdGlv bgogICAgICAvLyA0ICBNQl9JQ09OQVNURVJJU0sgICAgIEFzdGVyaXNrCiAg ICAgIC8vID8gIDB4RkZGRkZGRkYgICAgICAgICAgU2ltcGxlIEJlZXAKICAg ICAgTWVzc2FnZUJlZXAoKGNmZy5iZWxsX3R5cGUgLSAxKSAqIDE2KTsKICAg IH0KICB9CiAgaWYgKGNmZy5iZWxsX3Rhc2tiYXIgJiYgIXRlcm0uaGFzX2Zv Y3VzKQogICAgZmxhc2hfdGFza2Jhcih0cnVlKTsKfQoKdm9pZAp3aW5faW52 YWxpZGF0ZV9hbGwodm9pZCkKewogIEludmFsaWRhdGVSZWN0KHduZCwgbnVs bCwgdHJ1ZSk7Cn0KCnZvaWQKd2luX2FkYXB0X3Rlcm1fc2l6ZShib29sIHN5 bmNfc2l6ZV93aXRoX2ZvbnQsIGJvb2wgc2NhbGVfZm9udF93aXRoX3NpemUp CnsKICB0cmFjZV9yZXNpemUoKCItLS0gd2luX2FkYXB0X3Rlcm1fc2l6ZSBm dWxsICVkIFpvb21lZCAlZFxuIiwgd2luX2lzX2Z1bGxzY3JlZW4sIElzWm9v bWVkKHduZCkpKTsKICBpZiAoSXNJY29uaWMod25kKSkKICAgIHJldHVybjsK CiAgaWYgKHN5bmNfc2l6ZV93aXRoX2ZvbnQgJiYgIXdpbl9pc19mdWxsc2Ny ZWVuKSB7CiAgICB3aW5fc2V0X2NoYXJzKHRlcm0ucm93cywgdGVybS5jb2xz KTsKICAgIC8vd2luX2ZpeF9wb3NpdGlvbigpOwogICAgd2luX2ludmFsaWRh dGVfYWxsKCk7CiAgICByZXR1cm47CiAgfQoKIC8qIEN1cnJlbnQgd2luZG93 IHNpemVzIC4uLiAqLwogIFJFQ1QgY3IsIHdyOwogIEdldENsaWVudFJlY3Qo d25kLCAmY3IpOwogIEdldFdpbmRvd1JlY3Qod25kLCAmd3IpOwogIGludCBj bGllbnRfd2lkdGggPSBjci5yaWdodCAtIGNyLmxlZnQ7CiAgaW50IGNsaWVu dF9oZWlnaHQgPSBjci5ib3R0b20gLSBjci50b3A7CiAgZXh0cmFfd2lkdGgg PSB3ci5yaWdodCAtIHdyLmxlZnQgLSBjbGllbnRfd2lkdGg7CiAgZXh0cmFf aGVpZ2h0ID0gd3IuYm90dG9tIC0gd3IudG9wIC0gY2xpZW50X2hlaWdodDsK ICBpbnQgdGVybV93aWR0aCA9IGNsaWVudF93aWR0aCAtIDIgKiBQQURESU5H OwogIGludCB0ZXJtX2hlaWdodCA9IGNsaWVudF9oZWlnaHQgLSAyICogUEFE RElORzsKCiAgaWYgKHNjYWxlX2ZvbnRfd2l0aF9zaXplKSB7CiAgICAvLyBj YWxjIHByZWxpbWluYXJ5IHNpemUgKHdpdGhvdXQgZm9udCBzY2FsaW5nKSwg YXMgYmVsb3cKICAgIC8vIHNob3VsZCB1c2UgdGVybV9oZWlnaHQgcmF0aGVy IHRoYW4gcm93czsgY2FsYyBhbmQgc3RvcmUgaW4gdGVybV9yZXNpemUKICAg IGludCBjb2xzMCA9IG1heCgxLCB0ZXJtX3dpZHRoIC8gZm9udF93aWR0aCk7 CiAgICBpbnQgcm93czAgPSBtYXgoMSwgdGVybV9oZWlnaHQgLyBmb250X2hl aWdodCk7CgogICAgLy8gcm93czAvdGVybS5yb3dzIGdpdmVzIGEgcm91Z2gg c2NhbGluZyBmYWN0b3IgZm9yIGZvbnRfaGVpZ2h0CiAgICAvLyBjb2xzMC90 ZXJtLmNvbHMgZ2l2ZXMgYSByb3VnaCBzY2FsaW5nIGZhY3RvciBmb3IgZm9u dF93aWR0aAogICAgLy8gZm9udF9oZWlnaHQsIGZvbnRfd2lkdGggZ2l2ZSBh IHJvdWdoIHNjYWxpbmcgaW5kaWNhdGlvbiBmb3IgZm9udF9zaXplCiAgICAv LyBoZWlnaHQgb3Igd2lkdGggY291bGQgYmUgY29uc2lkZXJlZCBtb3JlIGFj Y29yZGluZyB0byBwcmVmZXJlbmNlCiAgICBib29sIGJpZ2dlciA9IHJvd3Mw ICogY29sczAgPiB0ZXJtLnJvd3MgKiB0ZXJtLmNvbHM7CiAgICBpbnQgZm9u dF9zaXplMSA9CiAgICAgIC8vIGhldXJpc3RpYyBiZXN0IGFwcHJvYWNoIHRh a2VuLi4uCiAgICAgIC8vIGJpZ2dlcgogICAgICAvLyAgID8gbWF4KGZvbnRf c2l6ZSAqIHJvd3MwIC8gdGVybS5yb3dzLCBmb250X3NpemUgKiBjb2xzMCAv IHRlcm0uY29scykKICAgICAgLy8gICA6IG1pbihmb250X3NpemUgKiByb3dz MCAvIHRlcm0ucm93cywgZm9udF9zaXplICogY29sczAgLyB0ZXJtLmNvbHMp OwogICAgICAvLyBiaWdnZXIKICAgICAgLy8gICA/IGZvbnRfc2l6ZSAqIHJv d3MwIC8gdGVybS5yb3dzICsgMgogICAgICAvLyAgIDogZm9udF9zaXplICog cm93czAgLyB0ZXJtLnJvd3M7CiAgICAgIGJpZ2dlcgogICAgICAgID8gKGZv bnRfc2l6ZSAqIHJvd3MwIC8gdGVybS5yb3dzICsgZm9udF9zaXplICogY29s czAgLyB0ZXJtLmNvbHMpIC8gMiArIDEKICAgICAgICA6IChmb250X3NpemUg KiByb3dzMCAvIHRlcm0ucm93cyArIGZvbnRfc2l6ZSAqIGNvbHMwIC8gdGVy bS5jb2xzKSAvIDI7CiAgICAgIC8vIGJpZ2dlcgogICAgICAvLyAgID8gZm9u dF9zaXplICogcm93czAgKiBjb2xzMCAvICh0ZXJtLnJvd3MgKiB0ZXJtLmNv bHMpCiAgICAgIC8vICAgOiBmb250X3NpemUgKiByb3dzMCAqIGNvbHMwIC8g KHRlcm0ucm93cyAqIHRlcm0uY29scyk7CiAgICAgIHRyYWNlX3Jlc2l6ZSgo InRlcm0gc2l6ZSAlZCAlZCAtPiAlZCAlZFxuIiwgdGVybS5yb3dzLCB0ZXJt LmNvbHMsIHJvd3MwLCBjb2xzMCkpOwogICAgICB0cmFjZV9yZXNpemUoKCJm b250IHNpemUgJWQgLT4gJWRcbiIsIGZvbnRfc2l6ZSwgZm9udF9zaXplMSkp OwoKICAgIGlmIChmb250X3NpemUxICE9IGZvbnRfc2l6ZSkKICAgICAgd2lu X3NldF9mb250X3NpemUoZm9udF9zaXplMSwgZmFsc2UpOwogIH0KCiAgaW50 IGNvbHMgPSBtYXgoMSwgdGVybV93aWR0aCAvIGZvbnRfd2lkdGgpOwogIGlu dCByb3dzID0gbWF4KDEsIHRlcm1faGVpZ2h0IC8gZm9udF9oZWlnaHQpOwog IGlmIChyb3dzICE9IHRlcm0ucm93cyB8fCBjb2xzICE9IHRlcm0uY29scykg ewogICAgdGVybV9yZXNpemUocm93cywgY29scyk7CiAgICBzdHJ1Y3Qgd2lu c2l6ZSB3cyA9IHtyb3dzLCBjb2xzLCBjb2xzICogZm9udF93aWR0aCwgcm93 cyAqIGZvbnRfaGVpZ2h0fTsKICAgIGNoaWxkX3Jlc2l6ZSgmd3MpOwogIH0K ICB3aW5faW52YWxpZGF0ZV9hbGwoKTsKfQoKYm9vbAp3aW5faXNfZ2xhc3Nf YXZhaWxhYmxlKHZvaWQpCnsKICBCT09MIHJlc3VsdCA9IGZhbHNlOwogIGlm IChwRHdtSXNDb21wb3NpdGlvbkVuYWJsZWQpCiAgICBwRHdtSXNDb21wb3Np dGlvbkVuYWJsZWQoJnJlc3VsdCk7CiAgcmV0dXJuIHJlc3VsdDsKfQoKc3Rh dGljIHZvaWQKdXBkYXRlX2dsYXNzKHZvaWQpCnsKICBpZiAocER3bUV4dGVu ZEZyYW1lSW50b0NsaWVudEFyZWEpIHsKICAgIGJvb2wgZW5hYmxlZCA9CiAg ICAgIGNmZy50cmFuc3BhcmVuY3kgPT0gVFJfR0xBU1MgJiYgIXdpbl9pc19m dWxsc2NyZWVuICYmCiAgICAgICEoY2ZnLm9wYXF1ZV93aGVuX2ZvY3VzZWQg JiYgdGVybS5oYXNfZm9jdXMpOwogICAgcER3bUV4dGVuZEZyYW1lSW50b0Ns aWVudEFyZWEod25kLCAmKE1BUkdJTlMpe2VuYWJsZWQgPyAtMSA6IDAsIDAs IDAsIDB9KTsKICB9Cn0KCi8qCiAqIEdvIGZ1bGwtc2NyZWVuLiBUaGlzIHNo b3VsZCBvbmx5IGJlIGNhbGxlZCB3aGVuIHdlIGFyZSBhbHJlYWR5CiAqIG1h eGltaXNlZC4KICovCnN0YXRpYyB2b2lkCm1ha2VfZnVsbHNjcmVlbih2b2lk KQp7CiAgd2luX2lzX2Z1bGxzY3JlZW4gPSB0cnVlOwoKIC8qIFJlbW92ZSB0 aGUgd2luZG93IGZ1cm5pdHVyZS4gKi8KICBMT05HIHN0eWxlID0gR2V0V2lu ZG93TG9uZyh3bmQsIEdXTF9TVFlMRSk7CiAgc3R5bGUgJj0gfihXU19DQVBU SU9OIHwgV1NfQk9SREVSIHwgV1NfVEhJQ0tGUkFNRSk7CiAgU2V0V2luZG93 TG9uZyh3bmQsIEdXTF9TVFlMRSwgc3R5bGUpOwoKIC8qIFRoZSBnbGFzcyBl ZmZlY3QgZG9lc24ndCB3b3JrIGZvciBmdWxsc2NyZWVuIHdpbmRvd3MgKi8K ICB1cGRhdGVfZ2xhc3MoKTsKCiAvKiBSZXNpemUgb3Vyc2VsdmVzIHRvIGV4 YWN0bHkgY292ZXIgdGhlIG5lYXJlc3QgbW9uaXRvci4gKi8KICBNT05JVE9S SU5GTyBtaTsKICBnZXRfbW9uaXRvcl9pbmZvKCZtaSk7CiAgUkVDVCBmciA9 IG1pLnJjTW9uaXRvcjsKICBTZXRXaW5kb3dQb3Mod25kLCBIV05EX1RPUCwg ZnIubGVmdCwgZnIudG9wLAogICAgICAgICAgICAgICBmci5yaWdodCAtIGZy LmxlZnQsIGZyLmJvdHRvbSAtIGZyLnRvcCwgU1dQX0ZSQU1FQ0hBTkdFRCk7 Cn0KCi8qCiAqIENsZWFyIHRoZSBmdWxsLXNjcmVlbiBhdHRyaWJ1dGVzLgog Ki8Kc3RhdGljIHZvaWQKY2xlYXJfZnVsbHNjcmVlbih2b2lkKQp7CiAgd2lu X2lzX2Z1bGxzY3JlZW4gPSBmYWxzZTsKICB1cGRhdGVfZ2xhc3MoKTsKCiAv KiBSZWluc3RhdGUgdGhlIHdpbmRvdyBmdXJuaXR1cmUuICovCiAgTE9ORyBz dHlsZSA9IEdldFdpbmRvd0xvbmcod25kLCBHV0xfU1RZTEUpOwogIGlmIChi b3JkZXJfc3R5bGUpIHsKICAgIGlmIChzdHJjbXAgKGJvcmRlcl9zdHlsZSwg InZvaWQiKSAhPSAwKSB7CiAgICAgIHN0eWxlIHw9IFdTX1RISUNLRlJBTUU7 CiAgICB9CiAgfQogIGVsc2UgewogICAgc3R5bGUgfD0gV1NfQ0FQVElPTiB8 IFdTX0JPUkRFUiB8IFdTX1RISUNLRlJBTUU7CiAgfQogIFNldFdpbmRvd0xv bmcod25kLCBHV0xfU1RZTEUsIHN0eWxlKTsKICBTZXRXaW5kb3dQb3Mod25k LCBudWxsLCAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICBTV1BfTk9NT1ZF IHwgU1dQX05PU0laRSB8IFNXUF9OT1pPUkRFUiB8IFNXUF9GUkFNRUNIQU5H RUQpOwp9CgovKgogKiBNYXhpbWlzZSBvciByZXN0b3JlIHRoZSB3aW5kb3cg aW4gcmVzcG9uc2UgdG8gYSBzZXJ2ZXItc2lkZSByZXF1ZXN0LgogKiBBcmd1 bWVudCB2YWx1ZSBvZiAyIG1lYW5zIGdvIGZ1bGxzY3JlZW4uCiAqLwp2b2lk Cndpbl9tYXhpbWlzZShpbnQgbWF4KQp7CiAgaWYgKG1heCA9PSAtMikgLy8g dG9nZ2xlIGZ1bGwgc2NyZWVuCiAgICBtYXggPSB3aW5faXNfZnVsbHNjcmVl biA/IDAgOiAyOwogIGlmIChJc1pvb21lZCh3bmQpKSB7CiAgICBpZiAoIW1h eCkKICAgICAgU2hvd1dpbmRvdyh3bmQsIFNXX1JFU1RPUkUpOwogICAgZWxz ZSBpZiAobWF4ID09IDIgJiYgIXdpbl9pc19mdWxsc2NyZWVuKQogICAgICBt YWtlX2Z1bGxzY3JlZW4oKTsKICB9CiAgZWxzZSBpZiAobWF4KSB7CiAgICBp ZiAobWF4ID09IDIpCiAgICAgIGZ1bGxzY3Jfb25fbWF4ID0gdHJ1ZTsKICAg IFNob3dXaW5kb3cod25kLCBTV19NQVhJTUlaRSk7CiAgfQp9CgovKgogKiBH byBiYWNrIHRvIGNvbmZpZ3VyZWQgd2luZG93IHNpemUuCiAqLwpzdGF0aWMg dm9pZApkZWZhdWx0X3NpemUodm9pZCkKewogIGlmIChJc1pvb21lZCh3bmQp KQogICAgU2hvd1dpbmRvdyh3bmQsIFNXX1JFU1RPUkUpOwogIHdpbl9zZXRf Y2hhcnMoY2ZnLnJvd3MsIGNmZy5jb2xzKTsKfQoKc3RhdGljIHZvaWQKdXBk YXRlX3RyYW5zcGFyZW5jeSh2b2lkKQp7CiAgaW50IHRyYW5zID0gY2ZnLnRy YW5zcGFyZW5jeTsKICBpZiAodHJhbnMgPT0gVFJfR0xBU1MpCiAgICB0cmFu cyA9IDA7CiAgTE9ORyBzdHlsZSA9IEdldFdpbmRvd0xvbmcod25kLCBHV0xf RVhTVFlMRSk7CiAgc3R5bGUgPSB0cmFucyA/IHN0eWxlIHwgV1NfRVhfTEFZ RVJFRCA6IHN0eWxlICYgfldTX0VYX0xBWUVSRUQ7CiAgU2V0V2luZG93TG9u Zyh3bmQsIEdXTF9FWFNUWUxFLCBzdHlsZSk7CiAgaWYgKHRyYW5zKSB7CiAg ICBpZiAoY2ZnLm9wYXF1ZV93aGVuX2ZvY3VzZWQgJiYgdGVybS5oYXNfZm9j dXMpCiAgICAgIHRyYW5zID0gMDsKICAgIFNldExheWVyZWRXaW5kb3dBdHRy aWJ1dGVzKHduZCwgMCwgMjU1IC0gKHVjaGFyKXRyYW5zLCBMV0FfQUxQSEEp OwogIH0KCiAgdXBkYXRlX2dsYXNzKCk7Cn0KCnZvaWQKd2luX3VwZGF0ZV9z Y3JvbGxiYXIodm9pZCkKewogIGludCBzY3JvbGxiYXIgPSB0ZXJtLnNob3df c2Nyb2xsYmFyID8gY2ZnLnNjcm9sbGJhciA6IDA7CiAgTE9ORyBzdHlsZSA9 IEdldFdpbmRvd0xvbmcod25kLCBHV0xfU1RZTEUpOwogIFNldFdpbmRvd0xv bmcod25kLCBHV0xfU1RZTEUsCiAgICAgICAgICAgICAgICBzY3JvbGxiYXIg PyBzdHlsZSB8IFdTX1ZTQ1JPTEwgOiBzdHlsZSAmIH5XU19WU0NST0xMKTsK ICBMT05HIGV4c3R5bGUgPSBHZXRXaW5kb3dMb25nKHduZCwgR1dMX0VYU1RZ TEUpOwogIFNldFdpbmRvd0xvbmcod25kLCBHV0xfRVhTVFlMRSwKICAgICAg ICAgICAgICAgIHNjcm9sbGJhciA8IDAgPyBleHN0eWxlIHwgV1NfRVhfTEVG VFNDUk9MTEJBUgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGV4 c3R5bGUgJiB+V1NfRVhfTEVGVFNDUk9MTEJBUik7CiAgU2V0V2luZG93UG9z KHduZCwgbnVsbCwgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAgU1dQX05P QUNUSVZBVEUgfCBTV1BfTk9NT1ZFIHwKICAgICAgICAgICAgICAgU1dQX05P U0laRSB8IFNXUF9OT1pPUkRFUiB8IFNXUF9GUkFNRUNIQU5HRUQpOwp9Cgp2 b2lkCndpbl9yZWNvbmZpZyh2b2lkKQp7CiAgdHJhY2VfcmVzaXplKCgiLS0t IHdpbl9yZWNvbmZpZ1xuIikpOwogLyogUGFzcyBuZXcgY29uZmlnIGRhdGEg dG8gdGhlIHRlcm1pbmFsICovCiAgdGVybV9yZWNvbmZpZygpOwoKICBib29s IGZvbnRfY2hhbmdlZCA9CiAgICBzdHJjbXAobmV3X2NmZy5mb250Lm5hbWUs IGNmZy5mb250Lm5hbWUpIHx8CiAgICBuZXdfY2ZnLmZvbnQuc2l6ZSAhPSBj ZmcuZm9udC5zaXplIHx8CiAgICBuZXdfY2ZnLmZvbnQuaXNib2xkICE9IGNm Zy5mb250LmlzYm9sZCB8fAogICAgbmV3X2NmZy5ib2xkX2FzX2ZvbnQgIT0g Y2ZnLmJvbGRfYXNfZm9udCB8fAogICAgbmV3X2NmZy5ib2xkX2FzX2NvbG91 ciAhPSBjZmcuYm9sZF9hc19jb2xvdXIgfHwKICAgIG5ld19jZmcuZm9udF9z bW9vdGhpbmcgIT0gY2ZnLmZvbnRfc21vb3RoaW5nOwoKICBpZiAobmV3X2Nm Zy5mZ19jb2xvdXIgIT0gY2ZnLmZnX2NvbG91cikKICAgIHdpbl9zZXRfY29s b3VyKEZHX0NPTE9VUl9JLCBuZXdfY2ZnLmZnX2NvbG91cik7CgogIGlmIChu ZXdfY2ZnLmJnX2NvbG91ciAhPSBjZmcuYmdfY29sb3VyKQogICAgd2luX3Nl dF9jb2xvdXIoQkdfQ09MT1VSX0ksIG5ld19jZmcuYmdfY29sb3VyKTsKCiAg aWYgKG5ld19jZmcuY3Vyc29yX2NvbG91ciAhPSBjZmcuY3Vyc29yX2NvbG91 cikKICAgIHdpbl9zZXRfY29sb3VyKENVUlNPUl9DT0xPVVJfSSwgbmV3X2Nm Zy5jdXJzb3JfY29sb3VyKTsKCiAgLyogQ29weSB0aGUgbmV3IGNvbmZpZyBh bmQgcmVmcmVzaCBldmVyeXRoaW5nICovCiAgY29weV9jb25maWcoJmNmZywg Jm5ld19jZmcpOwogIGlmIChmb250X2NoYW5nZWQpIHsKICAgIHdpbl9pbml0 X2ZvbnRzKGNmZy5mb250LnNpemUpOwogICAgdHJhY2VfcmVzaXplKCgiICh3 aW5fcmVjb25maWcgLT4gd2luX2FkYXB0X3Rlcm1fc2l6ZSlcbiIpKTsKICAg IHdpbl9hZGFwdF90ZXJtX3NpemUodHJ1ZSwgZmFsc2UpOwogIH0KICB3aW5f dXBkYXRlX3Njcm9sbGJhcigpOwogIHVwZGF0ZV90cmFuc3BhcmVuY3koKTsK ICB3aW5fdXBkYXRlX21vdXNlKCk7CgogIGJvb2wgb2xkX2FtYmlnX3dpZGUg PSBjc19hbWJpZ193aWRlOwogIGNzX3JlY29uZmlnKCk7CiAgaWYgKHRlcm0u cmVwb3J0X2ZvbnRfY2hhbmdlZCAmJiBmb250X2NoYW5nZWQpCiAgICBpZiAo dGVybS5yZXBvcnRfYW1iaWdfd2lkdGgpCiAgICAgIGNoaWxkX3dyaXRlKGNz X2FtYmlnX3dpZGUgPyAiXGVbMlciIDogIlxlWzFXIiwgNCk7CiAgICBlbHNl CiAgICAgIGNoaWxkX3dyaXRlKCJcZVswVyIsIDQpOwogIGVsc2UgaWYgKHRl cm0ucmVwb3J0X2FtYmlnX3dpZHRoICYmIG9sZF9hbWJpZ193aWRlICE9IGNz X2FtYmlnX3dpZGUpCiAgICBjaGlsZF93cml0ZShjc19hbWJpZ193aWRlID8g IlxlWzJXIiA6ICJcZVsxVyIsIDQpOwp9CgpzdGF0aWMgYm9vbApjb25maXJt X2V4aXQodm9pZCkKewogIGlmICghY2hpbGRfaXNfcGFyZW50KCkpCiAgICBy ZXR1cm4gdHJ1ZTsKCiAgLyogcmV0cmlldmUgbGlzdCBvZiBjaGlsZCBwcm9j ZXNzZXMgKi8KICBjaGFyICogcHNjbWQgPSAicHJvY3BzIC1vIHBpZCxydXNl cj1VU0VSIC1vIGNvbW0gLXQgJXMgMj4gL2Rldi9udWxsIHx8IHBzIC1lZiI7 CiAgY2hhciAqIHR0eSA9IGNoaWxkX3R0eSgpOwogIGlmIChzdHJyY2hyICh0 dHksICcvJykpCiAgICB0dHkgPSBzdHJyY2hyICh0dHksICcvJykgKyAxOwog IGNoYXIgY21kW3N0cmxlbihwc2NtZCkgKyBzdHJsZW4odHR5KSArIDFdOwog IHNwcmludGYgKGNtZCwgcHNjbWQsIHR0eSwgdHR5KTsKICBGSUxFICogcHJv Y3BzID0gcG9wZW4gKGNtZCwgInIiKTsKICBjaGFyICogbXNnX3ByZSA9ICJQ cm9jZXNzZXMgYXJlIHJ1bm5pbmcgaW4gc2Vzc2lvbjpcbiI7CiAgY2hhciAq IG1zZ19wb3N0ID0gIkNsb3NlIGFueXdheT8iOwogIGNoYXIgKiBtc2cgPSBt YWxsb2MgKHN0cmxlbiAobXNnX3ByZSkgKyAxKTsKICBzdHJjcHkgKG1zZywg bXNnX3ByZSk7CiAgaWYgKHByb2NwcykgewogICAgY2hhciBsaW5lWzk5OV07 ICAvLyB1c2UgdmVyeSBsb25nIGlucHV0IGRlc3BpdGUgbmFycm93IG1zZyBi b3gKICAgICAgICAgICAgICAgICAgICAgLy8gdG8gYXZvaWQgaGlnaCByaXNr IG9mIGNsaXBwaW5nIHdpdGhpbiBVVEYtOCAKICAgICAgICAgICAgICAgICAg ICAgLy8gYW5kIGZhaWxpbmcgdGhlIHdpZGUgY2hhcmFjdGVyIHRyYW5zZm9y bWF0aW9uCiAgICBib29sIGZpcnN0ID0gdHJ1ZTsKICAgIGJvb2wgZmlsdGVy X3R0eSA9IGZhbHNlOwogICAgd2hpbGUgKGZnZXRzKGxpbmUsIHNpemVvZiBs aW5lLCBwcm9jcHMpKSB7CiAgICAgIGxpbmVbc3RyY3NwbihsaW5lLCAiXHJc biIpXSA9IDA7ICAvKiB0cmltIG5ld2xpbmUgKi8KICAgICAgaWYgKGZpcnN0 IHx8ICFmaWx0ZXJfdHR5IHx8IHN0cnN0ciAobGluZSwgdHR5KSkgIC8vIHNo b3VsZCBjaGVjayBjb2x1bW4gcG9zaXRpb24gdG9vLi4uCiAgICAgIHsKICAg ICAgICBpZiAoZmlyc3QpIHsKICAgICAgICAgIGlmIChzdHJzdHIgKGxpbmUs ICJUVFkiKSkgewogICAgICAgICAgICBmaWx0ZXJfdHR5ID0gdHJ1ZTsKICAg ICAgICAgIH0KICAgICAgICAgIGZpcnN0ID0gZmFsc2U7CiAgICAgICAgfQog ICAgICAgIG1zZyA9IHJlYWxsb2MgKG1zZywgc3RybGVuIChtc2cpICsgc3Ry bGVuIChsaW5lKSArIDIpOwogICAgICAgIHN0cmNhdCAobXNnLCBsaW5lKTsK ICAgICAgICBzdHJjYXQgKG1zZywgIlxuIik7CiAgICAgIH0KICAgIH0KICAg IGZjbG9zZShwcm9jcHMpOwogIH0KICBtc2cgPSByZWFsbG9jIChtc2csIHN0 cmxlbiAobXNnKSArIHN0cmxlbiAobXNnX3Bvc3QpICsgMSk7CiAgc3RyY2F0 IChtc2csIG1zZ19wb3N0KTsKCiAgc2l6ZV90IHNpemUgPSBjc19tYnN0b3dj cygwLCBtc2csIDApICsgMTsKICBpbnQgcmV0OwogIGlmIChzaXplKSB7CiAg ICB3Y2hhciBtc2d3W3NpemVdOwogICAgY3NfbWJzdG93Y3MobXNndywgbXNn LCBzaXplKTsKICAgIHdjaGFyIGFwcG5bc3RybGVuKEFQUE5BTUUpICsgMV07 CiAgICBjc19tYnN0b3djcyhhcHBuLCBBUFBOQU1FLCBzaXplb2YgYXBwbik7 CiAgICByZXQgPQogICAgICBNZXNzYWdlQm94VygKICAgICAgICB3bmQsIG1z Z3csCiAgICAgICAgYXBwbiwgTUJfSUNPTldBUk5JTkcgfCBNQl9PS0NBTkNF TCB8IE1CX0RFRkJVVFRPTjIKICAgICAgKTsKICB9CiAgZWxzZSB7CiAgICBy ZXQgPQogICAgICBNZXNzYWdlQm94KAogICAgICAgIHduZCwgbXNnLAogICAg ICAgIEFQUE5BTUUsIE1CX0lDT05XQVJOSU5HIHwgTUJfT0tDQU5DRUwgfCBN Ql9ERUZCVVRUT04yCiAgICAgICk7CiAgfQoKICAvLyBUcmVhdCBmYWlsdXJl IHRvIHNob3cgdGhlIGRpYWxvZyBhcyBjb25maXJtYXRpb24uCiAgcmV0dXJu ICFyZXQgfHwgcmV0ID09IElET0s7Cn0KCnN0YXRpYyBMUkVTVUxUIENBTExC QUNLCndpbl9wcm9jKEhXTkQgd25kLCBVSU5UIG1lc3NhZ2UsIFdQQVJBTSB3 cCwgTFBBUkFNIGxwKQp7CiAgc3dpdGNoIChtZXNzYWdlKSB7CiAgICB3aGVu IFdNX1RJTUVSOiB7CiAgICAgIEtpbGxUaW1lcih3bmQsIHdwKTsKICAgICAg dm9pZF9mbiBjYiA9ICh2b2lkX2ZuKXdwOwogICAgICBjYigpOwogICAgICBy ZXR1cm4gMDsKICAgIH0KICAgIHdoZW4gV01fQ0xPU0U6CiAgICAgIGlmICgh Y2ZnLmNvbmZpcm1fZXhpdCB8fCBjb25maXJtX2V4aXQoKSkKICAgICAgICBj aGlsZF9raWxsKChHZXRLZXlTdGF0ZShWS19TSElGVCkgJiAweDgwKSAhPSAw KTsKICAgICAgcmV0dXJuIDA7CiAgICB3aGVuIFdNX0NPTU1BTkQgb3IgV01f U1lTQ09NTUFORDoKICAgICAgc3dpdGNoICh3cCAmIH4weEYpIHsgIC8qIGxv dyA0IGJpdHMgcmVzZXJ2ZWQgdG8gV2luZG93cyAqLwogICAgICAgIHdoZW4g SURNX09QRU46IHRlcm1fb3BlbigpOwogICAgICAgIHdoZW4gSURNX0NPUFk6 IHRlcm1fY29weSgpOwogICAgICAgIHdoZW4gSURNX1BBU1RFOiB3aW5fcGFz dGUoKTsKICAgICAgICB3aGVuIElETV9TRUxBTEw6IHRlcm1fc2VsZWN0X2Fs bCgpOyB3aW5fdXBkYXRlKCk7CiAgICAgICAgd2hlbiBJRE1fUkVTRVQ6IHRl cm1fcmVzZXQoKTsgd2luX3VwZGF0ZSgpOwogICAgICAgIHdoZW4gSURNX0RF RlNJWkU6IGRlZmF1bHRfc2l6ZSgpOwogICAgICAgIHdoZW4gSURNX0ZVTExT Q1JFRU46IHdpbl9tYXhpbWlzZSh3aW5faXNfZnVsbHNjcmVlbiA/IDAgOiAy KTsKICAgICAgICB3aGVuIElETV9GTElQU0NSRUVOOiB0ZXJtX2ZsaXBfc2Ny ZWVuKCk7CiAgICAgICAgd2hlbiBJRE1fT1BUSU9OUzogd2luX29wZW5fY29u ZmlnKCk7CiAgICAgICAgd2hlbiBJRE1fTkVXOiBjaGlsZF9mb3JrKG1haW5f YXJnYywgbWFpbl9hcmd2KTsKICAgICAgICB3aGVuIElETV9DT1BZVElUTEU6 IHdpbl9jb3B5X3RpdGxlKCk7CiAgICAgIH0KICAgIHdoZW4gV01fVlNDUk9M TDoKICAgICAgc3dpdGNoIChMT1dPUkQod3ApKSB7CiAgICAgICAgd2hlbiBT Ql9CT1RUT006ICAgdGVybV9zY3JvbGwoLTEsIDApOwogICAgICAgIHdoZW4g U0JfVE9QOiAgICAgIHRlcm1fc2Nyb2xsKCsxLCAwKTsKICAgICAgICB3aGVu IFNCX0xJTkVET1dOOiB0ZXJtX3Njcm9sbCgwLCArMSk7CiAgICAgICAgd2hl biBTQl9MSU5FVVA6ICAgdGVybV9zY3JvbGwoMCwgLTEpOwogICAgICAgIHdo ZW4gU0JfUEFHRURPV046IHRlcm1fc2Nyb2xsKDAsICttYXgoMSwgdGVybS5y b3dzIC0gMSkpOwogICAgICAgIHdoZW4gU0JfUEFHRVVQOiAgIHRlcm1fc2Ny b2xsKDAsIC1tYXgoMSwgdGVybS5yb3dzIC0gMSkpOwogICAgICAgIHdoZW4g U0JfVEhVTUJQT1NJVElPTiBvciBTQl9USFVNQlRSQUNLOiB7CiAgICAgICAg ICBTQ1JPTExJTkZPIGluZm87CiAgICAgICAgICBpbmZvLmNiU2l6ZSA9IHNp emVvZihTQ1JPTExJTkZPKTsKICAgICAgICAgIGluZm8uZk1hc2sgPSBTSUZf VFJBQ0tQT1M7CiAgICAgICAgICBHZXRTY3JvbGxJbmZvKHduZCwgU0JfVkVS VCwgJmluZm8pOwogICAgICAgICAgdGVybV9zY3JvbGwoMSwgaW5mby5uVHJh Y2tQb3MpOwogICAgICAgIH0KICAgICAgfQogICAgd2hlbiBXTV9MQlVUVE9O RE9XTjogd2luX21vdXNlX2NsaWNrKE1CVF9MRUZULCBscCk7CiAgICB3aGVu IFdNX1JCVVRUT05ET1dOOiB3aW5fbW91c2VfY2xpY2soTUJUX1JJR0hULCBs cCk7CiAgICB3aGVuIFdNX01CVVRUT05ET1dOOiB3aW5fbW91c2VfY2xpY2so TUJUX01JRERMRSwgbHApOwogICAgd2hlbiBXTV9MQlVUVE9OVVA6IHdpbl9t b3VzZV9yZWxlYXNlKE1CVF9MRUZULCBscCk7CiAgICB3aGVuIFdNX1JCVVRU T05VUDogd2luX21vdXNlX3JlbGVhc2UoTUJUX1JJR0hULCBscCk7CiAgICB3 aGVuIFdNX01CVVRUT05VUDogd2luX21vdXNlX3JlbGVhc2UoTUJUX01JRERM RSwgbHApOwogICAgd2hlbiBXTV9NT1VTRU1PVkU6IHdpbl9tb3VzZV9tb3Zl KGZhbHNlLCBscCk7CiAgICB3aGVuIFdNX05DTU9VU0VNT1ZFOiB3aW5fbW91 c2VfbW92ZSh0cnVlLCBscCk7CiAgICB3aGVuIFdNX01PVVNFV0hFRUw6IHdp bl9tb3VzZV93aGVlbCh3cCwgbHApOwogICAgd2hlbiBXTV9LRVlET1dOIG9y IFdNX1NZU0tFWURPV046CiAgICAgIGlmICh3aW5fa2V5X2Rvd24od3AsIGxw KSkKICAgICAgICByZXR1cm4gMDsKICAgIHdoZW4gV01fS0VZVVAgb3IgV01f U1lTS0VZVVA6CiAgICAgIGlmICh3aW5fa2V5X3VwKHdwLCBscCkpCiAgICAg ICAgcmV0dXJuIDA7CiAgICB3aGVuIFdNX0NIQVIgb3IgV01fU1lTQ0hBUjoK ICAgICAgY2hpbGRfc2VuZHcoJih3Y2hhcil7d3B9LCAxKTsKICAgICAgcmV0 dXJuIDA7CiAgICB3aGVuIFdNX0lOUFVUTEFOR0NIQU5HRToKICAgICAgd2lu X3NldF9pbWVfb3BlbihJbW1Jc0lNRShHZXRLZXlib2FyZExheW91dCgwKSkg JiYgSW1tR2V0T3BlblN0YXR1cyhpbWMpKTsKICAgIHdoZW4gV01fSU1FX05P VElGWToKICAgICAgaWYgKHdwID09IElNTl9TRVRPUEVOU1RBVFVTKQogICAg ICAgIHdpbl9zZXRfaW1lX29wZW4oSW1tR2V0T3BlblN0YXR1cyhpbWMpKTsK ICAgIHdoZW4gV01fSU1FX1NUQVJUQ09NUE9TSVRJT046CiAgICAgIEltbVNl dENvbXBvc2l0aW9uRm9udChpbWMsICZsZm9udCk7CiAgICB3aGVuIFdNX0lN RV9DT01QT1NJVElPTjoKICAgICAgaWYgKGxwICYgR0NTX1JFU1VMVFNUUikg ewogICAgICAgIExPTkcgbGVuID0gSW1tR2V0Q29tcG9zaXRpb25TdHJpbmdX KGltYywgR0NTX1JFU1VMVFNUUiwgbnVsbCwgMCk7CiAgICAgICAgaWYgKGxl biA+IDApIHsKICAgICAgICAgIGNoYXIgYnVmW2xlbl07CiAgICAgICAgICBJ bW1HZXRDb21wb3NpdGlvblN0cmluZ1coaW1jLCBHQ1NfUkVTVUxUU1RSLCBi dWYsIGxlbik7CiAgICAgICAgICBjaGlsZF9zZW5kdygod2NoYXIgKilidWYs IGxlbiAvIDIpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gMTsKICAgICAg fQogICAgd2hlbiBXTV9QQUlOVDoKICAgICAgd2luX3BhaW50KCk7CiAgICAg IHJldHVybiAwOwogICAgd2hlbiBXTV9TRVRGT0NVUzoKICAgICAgdGVybV9z ZXRfZm9jdXModHJ1ZSk7CiAgICAgIENyZWF0ZUNhcmV0KHduZCwgY2FyZXRi bSwgMCwgMCk7CiAgICAgIGZsYXNoX3Rhc2tiYXIoZmFsc2UpOyAgLyogc3Rv cCAqLwogICAgICB3aW5fdXBkYXRlKCk7CiAgICAgIHVwZGF0ZV90cmFuc3Bh cmVuY3koKTsKICAgICAgU2hvd0NhcmV0KHduZCk7CiAgICB3aGVuIFdNX0tJ TExGT0NVUzoKICAgICAgd2luX3Nob3dfbW91c2UoKTsKICAgICAgdGVybV9z ZXRfZm9jdXMoZmFsc2UpOwogICAgICBEZXN0cm95Q2FyZXQoKTsKICAgICAg d2luX3VwZGF0ZSgpOwogICAgICB1cGRhdGVfdHJhbnNwYXJlbmN5KCk7CiAg ICB3aGVuIFdNX0VOVEVSU0laRU1PVkU6CiAgICAgIHRyYWNlX3Jlc2l6ZSgo Ii0tLSBXTV9FTlRFUlNJWkVNT1ZFIFZLX1NISUZUICUwMlhcbiIsIEdldEtl eVN0YXRlKFZLX1NISUZUKSkpOwogICAgICByZXNpemluZyA9IHRydWU7CiAg ICB3aGVuIFdNX0VYSVRTSVpFTU9WRSBvciBXTV9DQVBUVVJFQ0hBTkdFRDog IC8vIGFmdGVyIG1vdXNlLWRyYWcgcmVzaXppbmcKICAgICAgdHJhY2VfcmVz aXplKCgiLS0tIFdNX0VYSVRTSVpFTU9WRSAocmVzaXppbmcgJWQpIFZLX1NI SUZUICUwMlhcbiIsIHJlc2l6aW5nLCBHZXRLZXlTdGF0ZShWS19TSElGVCkp KTsKICAgICAgaWYgKHJlc2l6aW5nKSB7CiAgICAgICAgcmVzaXppbmcgPSBm YWxzZTsKICAgICAgICB3aW5fZGVzdHJveV90aXAoKTsKICAgICAgICB0cmFj ZV9yZXNpemUoKCIgKHdpbl9wcm9jIC0+IHdpbl9hZGFwdF90ZXJtX3NpemUp XG4iKSk7CiAgICAgICAgd2luX2FkYXB0X3Rlcm1fc2l6ZShHZXRLZXlTdGF0 ZShWS19TSElGVCkgJiAweDgwLCBmYWxzZSk7CiAgICAgIH0KICAgIHdoZW4g V01fU0laSU5HOiB7ICAvLyBtb3VzZS1kcmFnIHdpbmRvdyByZXNpemluZwog ICAgICB0cmFjZV9yZXNpemUoKCItLS0gV01fU0laSU5HIChyZXNpemluZyAl ZCkgVktfU0hJRlQgJTAyWFxuIiwgcmVzaXppbmcsIEdldEtleVN0YXRlKFZL X1NISUZUKSkpOwogICAgIC8qCiAgICAgICogVGhpcyBkb2VzIHR3byBqb2Jz OgogICAgICAqIDEpIEtlZXAgdGhlIHRpcCB1cHRvZGF0ZQogICAgICAqIDIp IE1ha2Ugc3VyZSB0aGUgd2luZG93IHNpemUgaXMgX3N0ZXBwZWRfIGluIHVu aXRzIG9mIHRoZSBmb250IHNpemUuCiAgICAgICovCiAgICAgIExQUkVDVCBy ID0gKExQUkVDVCkgbHA7CiAgICAgIGludCB3aWR0aCA9IHItPnJpZ2h0IC0g ci0+bGVmdCAtIGV4dHJhX3dpZHRoIC0gMiAqIFBBRERJTkc7CiAgICAgIGlu dCBoZWlnaHQgPSByLT5ib3R0b20gLSByLT50b3AgLSBleHRyYV9oZWlnaHQg LSAyICogUEFERElORzsKICAgICAgaW50IGNvbHMgPSBtYXgoMSwgKGZsb2F0 KXdpZHRoIC8gZm9udF93aWR0aCArIDAuNSk7CiAgICAgIGludCByb3dzID0g bWF4KDEsIChmbG9hdCloZWlnaHQgLyBmb250X2hlaWdodCArIDAuNSk7Cgog ICAgICBpbnQgZXcgPSB3aWR0aCAtIGNvbHMgKiBmb250X3dpZHRoOwogICAg ICBpbnQgZWggPSBoZWlnaHQgLSByb3dzICogZm9udF9oZWlnaHQ7CgogICAg ICBpZiAod3AgPj0gV01TWl9CT1RUT00pIHsKICAgICAgICB3cCAtPSBXTVNa X0JPVFRPTTsKICAgICAgICByLT5ib3R0b20gLT0gZWg7CiAgICAgIH0KICAg ICAgZWxzZSBpZiAod3AgPj0gV01TWl9UT1ApIHsKICAgICAgICB3cCAtPSBX TVNaX1RPUDsKICAgICAgICByLT50b3AgKz0gZWg7CiAgICAgIH0KCiAgICAg IGlmICh3cCA9PSBXTVNaX1JJR0hUKQogICAgICAgIHItPnJpZ2h0IC09IGV3 OwogICAgICBlbHNlIGlmICh3cCA9PSBXTVNaX0xFRlQpCiAgICAgICAgci0+ bGVmdCArPSBldzsKCiAgICAgIHdpbl9zaG93X3RpcChyLT5sZWZ0ICsgZXh0 cmFfd2lkdGgsIHItPnRvcCArIGV4dHJhX2hlaWdodCwgY29scywgcm93cyk7 CgogICAgICByZXR1cm4gZXcgfHwgZWg7CiAgICB9CiAgICB3aGVuIFdNX1NJ WkU6IHsKICAgICAgdHJhY2VfcmVzaXplKCgiLS0tIFdNX1NJWkUgKHJlc2l6 aW5nICVkKSBWS19TSElGVCAlMDJYXG4iLCByZXNpemluZywgR2V0S2V5U3Rh dGUoVktfU0hJRlQpKSk7CiAgICAgIGlmICh3cCA9PSBTSVpFX1JFU1RPUkVE ICYmIHdpbl9pc19mdWxsc2NyZWVuKQogICAgICAgIGNsZWFyX2Z1bGxzY3Jl ZW4oKTsKICAgICAgZWxzZSBpZiAod3AgPT0gU0laRV9NQVhJTUlaRUQgJiYg ZnVsbHNjcl9vbl9tYXgpIHsKICAgICAgICBmdWxsc2NyX29uX21heCA9IGZh bHNlOwogICAgICAgIG1ha2VfZnVsbHNjcmVlbigpOwogICAgICB9CgogICAg ICBpZiAoIXJlc2l6aW5nKSB7CiAgICAgICAgdHJhY2VfcmVzaXplKCgiICh3 aW5fcHJvYyAtPiB3aW5fYWRhcHRfdGVybV9zaXplKVxuIikpOwogICAgICAg IHdpbl9hZGFwdF90ZXJtX3NpemUoZmFsc2UsIEdldEtleVN0YXRlKFZLX1NI SUZUKSAmIDB4ODApOwogICAgICB9CgogICAgICByZXR1cm4gMDsKICAgIH0K ICAgIHdoZW4gV01fSU5JVE1FTlU6CiAgICAgIHdpbl91cGRhdGVfbWVudXMo KTsKICAgICAgcmV0dXJuIDA7CiAgfQogLyoKICAqIEFueSBtZXNzYWdlcyB3 ZSBkb24ndCBwcm9jZXNzIGNvbXBsZXRlbHkgYWJvdmUgYXJlIHBhc3NlZCB0 aHJvdWdoIHRvCiAgKiBEZWZXaW5kb3dQcm9jKCkgZm9yIGRlZmF1bHQgcHJv Y2Vzc2luZy4KICAqLwogIHJldHVybiBEZWZXaW5kb3dQcm9jVyh3bmQsIG1l c3NhZ2UsIHdwLCBscCk7Cn0KCnN0YXRpYyBjb25zdCBjaGFyIGhlbHBbXSA9 CiAgIlVzYWdlOiAiIEFQUE5BTUUgIiBbT1BUSU9OXS4uLiBbIFBST0dSQU0g W0FSR10uLi4gfCAtIF1cbiIKICAiXG4iCiAgIlN0YXJ0IGEgbmV3IHRlcm1p bmFsIHNlc3Npb24gcnVubmluZyB0aGUgc3BlY2lmaWVkIHByb2dyYW0gb3Ig dGhlIHVzZXIncyBzaGVsbC5cbiIKICAiSWYgYSBkYXNoIGlzIGdpdmVuIGlu c3RlYWQgb2YgYSBwcm9ncmFtLCBpbnZva2UgdGhlIHNoZWxsIGFzIGEgbG9n aW4gc2hlbGwuXG4iCiAgIlxuIgogICJPcHRpb25zOlxuIgogICIgIC1jLCAt LWNvbmZpZyBGSUxFICAgICBMb2FkIHNwZWNpZmllZCBjb25maWcgZmlsZVxu IgogICIgIC1lLCAtLWV4ZWMgICAgICAgICAgICBUcmVhdCByZW1haW5pbmcg YXJndW1lbnRzIGFzIHRoZSBjb21tYW5kIHRvIGV4ZWN1dGVcbiIKICAiICAt aCwgLS1ob2xkIG5ldmVyfHN0YXJ0fGVycm9yfGFsd2F5cyAgS2VlcCB3aW5k b3cgb3BlbiBhZnRlciBjb21tYW5kIGZpbmlzaGVzXG4iCiAgIiAgLWksIC0t aWNvbiBGSUxFWyxJWF0gIExvYWQgd2luZG93IGljb24gZnJvbSBmaWxlLCBv cHRpb25hbGx5IHdpdGggaW5kZXhcbiIKICAiICAtbCwgLS1sb2cgRklMRXwt ICAgICAgTG9nIG91dHB1dCB0byBmaWxlIG9yIHN0ZG91dFxuIgogICIgIC1v LCAtLW9wdGlvbiBPUFQ9VkFMICBPdmVycmlkZSBjb25maWcgZmlsZSBvcHRp b24gd2l0aCBnaXZlbiB2YWx1ZVxuIgogICIgIC1wLCAtLXBvc2l0aW9uIFgs WSAgICBPcGVuIHdpbmRvdyBhdCBzcGVjaWZpZWQgY29vcmRpbmF0ZXNcbiIK ICAiICAtcywgLS1zaXplIENPTFMsUk9XUyAgU2V0IHNjcmVlbiBzaXplIGlu IGNoYXJhY3RlcnNcbiIKICAiICAtdCwgLS10aXRsZSBUSVRMRSAgICAgU2V0 IHdpbmRvdyB0aXRsZSAoZGVmYXVsdDogdGhlIGludm9rZWQgY29tbWFuZClc biIKICAiICAtdSwgLS11dG1wICAgICAgICAgICAgQ3JlYXRlIGEgdXRtcCBl bnRyeVxuIgogICIgIC13LCAtLXdpbmRvdyBub3JtYWx8bWlufG1heHxmdWxs fGhpZGUgIFNldCBpbml0aWFsIHdpbmRvdyBzdGF0ZVxuIgogICIgICAgICAt LWNsYXNzIENMQVNTICAgICBTZXQgd2luZG93IGNsYXNzIG5hbWUgKGRlZmF1 bHQ6ICIgQVBQTkFNRSAiKVxuIgogICIgIC1ILCAtLWhlbHAgICAgICAgICAg ICBEaXNwbGF5IGhlbHAgYW5kIGV4aXRcbiIKICAiICAtViwgLS12ZXJzaW9u ICAgICAgICAgUHJpbnQgdmVyc2lvbiBpbmZvcm1hdGlvbiBhbmQgZXhpdFxu Igo7CgpzdGF0aWMgY29uc3QgY2hhciBzaG9ydF9vcHRzW10gPSAiKzpjOmVo Omk6bDpvOnA6czp0OlQ6Qjp1dzpIVjpEIjsKCnN0YXRpYyBjb25zdCBzdHJ1 Y3Qgb3B0aW9uCm9wdHNbXSA9IHsKICB7ImNvbmZpZyIsICAgcmVxdWlyZWRf YXJndW1lbnQsIDAsICdjJ30sCiAgeyJleGVjIiwgICAgIG5vX2FyZ3VtZW50 LCAgICAgICAwLCAnZSd9LAogIHsiaG9sZCIsICAgICByZXF1aXJlZF9hcmd1 bWVudCwgMCwgJ2gnfSwKICB7Imljb24iLCAgICAgcmVxdWlyZWRfYXJndW1l bnQsIDAsICdpJ30sCiAgeyJsb2ciLCAgICAgIHJlcXVpcmVkX2FyZ3VtZW50 LCAwLCAnbCd9LAogIHsidXRtcCIsICAgICBub19hcmd1bWVudCwgICAgICAg MCwgJ3UnfSwKICB7Im9wdGlvbiIsICAgcmVxdWlyZWRfYXJndW1lbnQsIDAs ICdvJ30sCiAgeyJwb3NpdGlvbiIsIHJlcXVpcmVkX2FyZ3VtZW50LCAwLCAn cCd9LAogIHsic2l6ZSIsICAgICByZXF1aXJlZF9hcmd1bWVudCwgMCwgJ3Mn fSwKICB7InRpdGxlIiwgICAgcmVxdWlyZWRfYXJndW1lbnQsIDAsICd0J30s CiAgeyJUaXRsZSIsICAgIHJlcXVpcmVkX2FyZ3VtZW50LCAwLCAnVCd9LAog IHsiQm9yZGVyIiwgICByZXF1aXJlZF9hcmd1bWVudCwgMCwgJ0InfSwKICB7 IndpbmRvdyIsICAgcmVxdWlyZWRfYXJndW1lbnQsIDAsICd3J30sCiAgeyJj bGFzcyIsICAgIHJlcXVpcmVkX2FyZ3VtZW50LCAwLCAnQyd9LAogIHsiaGVs cCIsICAgICBub19hcmd1bWVudCwgICAgICAgMCwgJ0gnfSwKICB7InZlcnNp b24iLCAgbm9fYXJndW1lbnQsICAgICAgIDAsICdWJ30sCiAgeyJkYWVtb24i LCAgIG5vX2FyZ3VtZW50LCAgICAgICAwLCAnRCd9LAogIHswLCAwLCAwLCAw fQp9OwoKc3RhdGljIHZvaWQKc2hvd19tc2coRklMRSAqc3RyZWFtLCBzdHJp bmcgbXNnKQp7CiAgaWYgKGZwdXRzKG1zZywgc3RyZWFtKSA8IDAgfHwgZmZs dXNoKHN0cmVhbSkgPCAwKQogICAgTWVzc2FnZUJveCgwLCBtc2csIEFQUE5B TUUsIE1CX09LKTsKfQoKc3RhdGljIG5vX3JldHVybiBfX2F0dHJpYnV0ZV9f KChmb3JtYXQocHJpbnRmLCAxLCAyKSkpCmVycm9yKGNoYXIgKmZvcm1hdCwg Li4uKQp7CiAgY2hhciAqbXNnOwogIHZhX2xpc3QgdmE7CiAgdmFfc3RhcnQo dmEsIGZvcm1hdCk7CiAgdmFzcHJpbnRmKCZtc2csIGZvcm1hdCwgdmEpOwog IHZhX2VuZCh2YSk7CiAgbXNnID0gYXNmb3JtKCIlczogJXNcblRyeSAnLS1o ZWxwJyBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiIsCiAgICAgICAgICAgICAg IG1haW5fYXJndlswXSwgbXNnKTsKICBzaG93X21zZyhzdGRlcnIsIG1zZyk7 CiAgZXhpdCgxKTsKfQoKc3RhdGljIHZvaWQgX19hdHRyaWJ1dGVfXygoZm9y bWF0KHByaW50ZiwgMSwgMikpKQp3YXJuKGNoYXIgKmZvcm1hdCwgLi4uKQp7 CiAgY2hhciAqbXNnOwogIHZhX2xpc3QgdmE7CiAgdmFfc3RhcnQodmEsIGZv cm1hdCk7CiAgdmFzcHJpbnRmKCZtc2csIGZvcm1hdCwgdmEpOwogIHZhX2Vu ZCh2YSk7CiAgbXNnID0gYXNmb3JtKCIlczogJXNcbiIsIG1haW5fYXJndlsw XSwgbXNnKTsKICBzaG93X21zZyhzdGRlcnIsIG1zZyk7Cn0KCmludAptYWlu KGludCBhcmdjLCBjaGFyICphcmd2W10pCnsKICBtYWluX2FyZ3YgPSBhcmd2 OwogIG1haW5fYXJnYyA9IGFyZ2M7CiAgbG9hZF9kd21fZnVuY3MoKTsKICBp bml0X2NvbmZpZygpOwogIGNzX2luaXQoKTsKCiAgLy8gRGV0ZXJtaW5lIGhv bWUgZGlyZWN0b3J5LgogIGhvbWUgPSBnZXRlbnYoIkhPTUUiKTsKI2lmIENZ R1dJTl9WRVJTSU9OX0RMTF9NQUpPUiA+PSAxMDA1CiAgLy8gQmVmb3JlIEN5 Z3dpbiAxLjUsIHRoZSBwYXNzd2Qgc3RydWN0dXJlIGlzIGZha2VkLgogIHN0 cnVjdCBwYXNzd2QgKnB3ID0gZ2V0cHd1aWQoZ2V0dWlkKCkpOwojZW5kaWYK ICBob21lID0gaG9tZSA/IHN0cmR1cChob21lKSA6CiNpZiBDWUdXSU5fVkVS U0lPTl9ETExfTUFKT1IgPj0gMTAwNQogICAgKHB3ICYmIHB3LT5wd19kaXIg JiYgKnB3LT5wd19kaXIpID8gc3RyZHVwKHB3LT5wd19kaXIpIDoKI2VuZGlm CiAgICBhc2Zvcm0oIi9ob21lLyVzIiwgZ2V0bG9naW4oKSk7CgogIC8vIFNl dCBzaXplIGFuZCBwb3NpdGlvbiBkZWZhdWx0cy4KICBTVEFSVFVQSU5GTyBz dWk7CiAgR2V0U3RhcnR1cEluZm8oJnN1aSk7CiAgY2ZnLndpbmRvdyA9IHN1 aS5kd0ZsYWdzICYgU1RBUlRGX1VTRVNIT1dXSU5ET1cgPyBzdWkud1Nob3dX aW5kb3cgOiBTV19TSE9XOwogIGNmZy54ID0gY2ZnLnkgPSBDV19VU0VERUZB VUxUOwoKICBsb2FkX2NvbmZpZygiL2V0Yy9taW50dHlyYyIpOwogIHN0cmlu ZyByY19maWxlID0gYXNmb3JtKCIlcy8ubWludHR5cmMiLCBob21lKTsKICBs b2FkX2NvbmZpZyhyY19maWxlKTsKICBkZWxldGUocmNfZmlsZSk7CgogIGlm IChnZXRlbnYoIk1JTlRUWV9ST1dTIikpIHsKICAgIHNldF9hcmdfb3B0aW9u KCJSb3dzIiwgZ2V0ZW52KCJNSU5UVFlfUk9XUyIpKTsKICB9CiAgaWYgKGdl dGVudigiTUlOVFRZX0NPTFMiKSkgewogICAgc2V0X2FyZ19vcHRpb24oIkNv bHVtbnMiLCBnZXRlbnYoIk1JTlRUWV9DT0xTIikpOwogIH0KCiAgZm9yICg7 OykgewogICAgaW50IG9wdCA9IGdldG9wdF9sb25nKGFyZ2MsIGFyZ3YsIHNo b3J0X29wdHMsIG9wdHMsIDApOwogICAgaWYgKG9wdCA9PSAtMSB8fCBvcHQg PT0gJ2UnKQogICAgICBicmVhazsKICAgIGNoYXIgKmxvbmdvcHQgPSBhcmd2 W29wdGluZCAtIDFdLCAqc2hvcnRvcHQgPSAoY2hhcltdKXsnLScsIG9wdG9w dCwgMH07CiAgICBzd2l0Y2ggKG9wdCkgewogICAgICB3aGVuICdjJzogbG9h ZF9jb25maWcob3B0YXJnKTsKICAgICAgd2hlbiAnaCc6IHNldF9hcmdfb3B0 aW9uKCJIb2xkIiwgb3B0YXJnKTsKICAgICAgd2hlbiAnaSc6IHNldF9hcmdf b3B0aW9uKCJJY29uIiwgb3B0YXJnKTsKICAgICAgd2hlbiAnbCc6IHNldF9h cmdfb3B0aW9uKCJMb2ciLCBvcHRhcmcpOwogICAgICB3aGVuICdvJzogcGFy c2VfYXJnX29wdGlvbihvcHRhcmcpOwogICAgICB3aGVuICdwJzoKICAgICAg ICBpZiAoc3NjYW5mKG9wdGFyZywgIiVpLCVpJTFzIiwgJmNmZy54LCAmY2Zn LnksIChjaGFyWzJdKXt9KSAhPSAyKQogICAgICAgICAgZXJyb3IoInN5bnRh eCBlcnJvciBpbiBwb3NpdGlvbiBhcmd1bWVudCAnJXMnIiwgb3B0YXJnKTsK ICAgICAgd2hlbiAncyc6CiAgICAgICAgaWYgKHNzY2FuZihvcHRhcmcsICIl dSwldSUxcyIsICZjZmcuY29scywgJmNmZy5yb3dzLCAoY2hhclsyXSl7fSkg IT0gMikKICAgICAgICAgIGVycm9yKCJzeW50YXggZXJyb3IgaW4gc2l6ZSBh cmd1bWVudCAnJXMnIiwgb3B0YXJnKTsKICAgICAgICByZW1lbWJlcl9hcmco IkNvbHVtbnMiKTsKICAgICAgICByZW1lbWJlcl9hcmcoIlJvd3MiKTsKICAg ICAgd2hlbiAndCc6IHNldF9hcmdfb3B0aW9uKCJUaXRsZSIsIG9wdGFyZyk7 CiAgICAgIHdoZW4gJ1QnOgogICAgICAgIHNldF9hcmdfb3B0aW9uKCJUaXRs ZSIsIG9wdGFyZyk7CiAgICAgICAgdGl0bGVfc2V0dGFibGUgPSBmYWxzZTsK ICAgICAgd2hlbiAnQic6CiAgICAgICAgYm9yZGVyX3N0eWxlID0gc3RyZHVw IChvcHRhcmcpOwogICAgICB3aGVuICd1JzogY2ZnLnV0bXAgPSB0cnVlOwog ICAgICB3aGVuICd3Jzogc2V0X2FyZ19vcHRpb24oIldpbmRvdyIsIG9wdGFy Zyk7CiAgICAgIHdoZW4gJ0MnOiBzZXRfYXJnX29wdGlvbigiQ2xhc3MiLCBv cHRhcmcpOwogICAgICB3aGVuICdEJzoKICAgICAgICBkYWVtb25pemUgPSB0 cnVlOwogICAgICB3aGVuICdIJzoKICAgICAgICBzaG93X21zZyhzdGRvdXQs IGhlbHApOwogICAgICAgIHJldHVybiAwOwogICAgICB3aGVuICdWJzoKICAg ICAgICBzaG93X21zZyhzdGRvdXQsIFZFUlNJT05fVEVYVCk7CiAgICAgICAg cmV0dXJuIDA7CiAgICAgIHdoZW4gJz8nOgogICAgICAgIGVycm9yKCJ1bmtu b3duIG9wdGlvbiAnJXMnIiwgb3B0b3B0ID8gc2hvcnRvcHQgOiBsb25nb3B0 KTsKICAgICAgd2hlbiAnOic6CiAgICAgICAgZXJyb3IoIm9wdGlvbiAnJXMn IHJlcXVpcmVzIGFuIGFyZ3VtZW50IiwKICAgICAgICAgICAgICBsb25nb3B0 WzFdID09ICctJyA/IGxvbmdvcHQgOiBzaG9ydG9wdCk7CiAgICB9CiAgfQoK ICBmaW5pc2hfY29uZmlnKCk7CgogIC8vIGlmIHN0YXJ0ZWQgZnJvbSBjb25z b2xlLCB0cnkgdG8gZGV0YWNoIGZyb20gY2FsbGVyJ3MgdGVybWluYWwgKH5k YWVtb25pemUpCiAgLy8gaW4gb3JkZXIgdG8gbm90IHN1cHByZXNzIHNpZ25h bHMKICAvLyAoaW5kaWNhdGVkIGJ5IGlzYXR0eSBpZiBsaW5rZWQgd2l0aCAt bXdpbmRvd3MpCiAgaWYgKGRhZW1vbml6ZSAmJiAhaXNhdHR5KDApKSB7CiAg ICBpZiAoZm9yaygpID4gMCkgZXhpdCgwKTsKICAgIHNldHNpZCgpOwogIH0K CiAgLy8gV29yayBvdXQgd2hhdCB0byBleGVjdXRlLgogIGFyZ3YgKz0gb3B0 aW5kOwogIGlmICgqYXJndiAmJiAoYXJndlsxXSB8fCBzdHJjbXAoKmFyZ3Ys ICItIikpKQogICAgY21kID0gKmFyZ3Y7CiAgZWxzZSB7CiAgICAvLyBMb29r IHVwIHRoZSB1c2VyJ3Mgc2hlbGwuCiAgICBjbWQgPSBnZXRlbnYoIlNIRUxM Iik7CiAgICBjbWQgPSBjbWQgPyBzdHJkdXAoY21kKSA6CiNpZiBDWUdXSU5f VkVSU0lPTl9ETExfTUFKT1IgPj0gMTAwNQogICAgICAocHcgJiYgcHctPnB3 X3NoZWxsICYmICpwdy0+cHdfc2hlbGwpID8gc3RyZHVwKHB3LT5wd19zaGVs bCkgOgojZW5kaWYKICAgICAgIi9iaW4vc2giOwoKICAgIC8vIERldGVybWlu ZSB0aGUgcHJvZ3JhbSBuYW1lIGFyZ3VtZW50LgogICAgY2hhciAqc2xhc2gg PSBzdHJyY2hyKGNtZCwgJy8nKTsKICAgIGNoYXIgKmFyZzAgPSBzbGFzaCA/ IHNsYXNoICsgMSA6IGNtZDsKCiAgICAvLyBQcmVwZW5kICctJyBpZiBhIGxv Z2luIHNoZWxsIHdhcyByZXF1ZXN0ZWQuCiAgICBpZiAoKmFyZ3YpCiAgICAg IGFyZzAgPSBhc2Zvcm0oIi0lcyIsIGFyZzApOwoKICAgIC8vIENyZWF0ZSBu ZXcgYXJndW1lbnQgYXJyYXkuCiAgICBhcmd2ID0gbmV3bihjaGFyICosIDIp OwogICAgKmFyZ3YgPSBhcmcwOwogIH0KCiAgLy8gTG9hZCBpY29uIGlmIHNw ZWNpZmllZC4KICBISUNPTiBsYXJnZV9pY29uID0gMCwgc21hbGxfaWNvbiA9 IDA7CiAgaWYgKCpjZmcuaWNvbikgewogICAgc3RyaW5nIGljb25fZmlsZSA9 IHN0cmR1cChjZmcuaWNvbik7CiAgICB1aW50IGljb25faW5kZXggPSAwOwog ICAgY2hhciAqY29tbWEgPSBzdHJyY2hyKGljb25fZmlsZSwgJywnKTsKICAg IGlmIChjb21tYSkgewogICAgICBjaGFyICpzdGFydCA9IGNvbW1hICsgMSwg KmVuZDsKICAgICAgaWNvbl9pbmRleCA9IHN0cnRvdWwoc3RhcnQsICZlbmQs IDApOwogICAgICBpZiAoc3RhcnQgIT0gZW5kICYmICEqZW5kKQogICAgICAg ICpjb21tYSA9IDA7CiAgICAgIGVsc2UKICAgICAgICBpY29uX2luZGV4ID0g MDsKICAgIH0KICAgIFNldExhc3RFcnJvcigwKTsKI2lmIENZR1dJTl9WRVJT SU9OX0FQSV9NSU5PUiA+PSAxODEKICAgIHdjaGFyICp3aW5faWNvbl9maWxl ID0gY3lnd2luX2NyZWF0ZV9wYXRoKENDUF9QT1NJWF9UT19XSU5fVywgaWNv bl9maWxlKTsKICAgIGlmICh3aW5faWNvbl9maWxlKSB7CiAgICAgIEV4dHJh Y3RJY29uRXhXKHdpbl9pY29uX2ZpbGUsIGljb25faW5kZXgsICZsYXJnZV9p Y29uLCAmc21hbGxfaWNvbiwgMSk7CiAgICAgIGZyZWUod2luX2ljb25fZmls ZSk7CiAgICB9CiNlbHNlCiAgICBjaGFyIHdpbl9pY29uX2ZpbGVbTUFYX1BB VEhdOwogICAgY3lnd2luX2NvbnZfdG9fd2luMzJfcGF0aChpY29uX2ZpbGUs IHdpbl9pY29uX2ZpbGUpOwogICAgRXh0cmFjdEljb25FeEEod2luX2ljb25f ZmlsZSwgaWNvbl9pbmRleCwgJmxhcmdlX2ljb24sICZzbWFsbF9pY29uLCAx KTsKI2VuZGlmCiAgICBpZiAoIWxhcmdlX2ljb24pIHsKICAgICAgc21hbGxf aWNvbiA9IDA7CiAgICAgIHVpbnQgZXJyb3IgPSBHZXRMYXN0RXJyb3IoKTsK ICAgICAgaWYgKGVycm9yKSB7CiAgICAgICAgY2hhciBtc2dbMTAyNF07CiAg ICAgICAgRm9ybWF0TWVzc2FnZSgKICAgICAgICAgIEZPUk1BVF9NRVNTQUdF X0ZST01fU1lTVEVNIHwgRk9STUFUX01FU1NBR0VfTUFYX1dJRFRIX01BU0ss CiAgICAgICAgICAwLCBlcnJvciwgMCwgbXNnLCBzaXplb2YgbXNnLCAwCiAg ICAgICAgKTsKICAgICAgICB3YXJuKCJjb3VsZCBub3QgbG9hZCBpY29uIGZy b20gJyVzJzogJXMiLCBjZmcuaWNvbiwgbXNnKTsKICAgICAgfQogICAgICBl bHNlCiAgICAgICAgd2FybigiY291bGQgbm90IGxvYWQgaWNvbiBmcm9tICcl cyciLCBjZmcuaWNvbik7CiAgICB9CiAgICBkZWxldGUoaWNvbl9maWxlKTsK ICB9CgogIC8vIFNldCB0aGUgQXBwSUQgaWYgc3BlY2lmaWVkIGFuZCB0aGUg cmVxdWlyZWQgZnVuY3Rpb24gaXMgYXZhaWxhYmxlLgogIGlmICgqY2ZnLmFw cF9pZCkgewogICAgSE1PRFVMRSBzaGVsbCA9IGxvYWRfc3lzX2xpYnJhcnko InNoZWxsMzIuZGxsIik7CiAgICBIUkVTVUxUIChXSU5BUEkgKnBTZXRBcHBJ RCkoUENXU1RSKSA9CiAgICAgICh2b2lkICopR2V0UHJvY0FkZHJlc3Moc2hl bGwsICJTZXRDdXJyZW50UHJvY2Vzc0V4cGxpY2l0QXBwVXNlck1vZGVsSUQi KTsKCiAgICBpZiAocFNldEFwcElEKSB7CiAgICAgIHNpemVfdCBzaXplID0g Y3NfbWJzdG93Y3MoMCwgY2ZnLmFwcF9pZCwgMCkgKyAxOwogICAgICBpZiAo c2l6ZSkgewogICAgICAgIHdjaGFyIGJ1ZltzaXplXTsKICAgICAgICBjc19t YnN0b3djcyhidWYsIGNmZy5hcHBfaWQsIHNpemUpOwogICAgICAgIHBTZXRB cHBJRChidWYpOwogICAgICB9CiAgICB9CiAgfQoKICBpbnN0ID0gR2V0TW9k dWxlSGFuZGxlKE5VTEwpOwoKICAvLyBXaW5kb3cgY2xhc3MgbmFtZS4KICB3 c3RyaW5nIHdjbGFzcyA9IF9XKEFQUE5BTUUpOwogIGlmICgqY2ZnLmNsYXNz KSB7CiAgICBzaXplX3Qgc2l6ZSA9IGNzX21ic3Rvd2NzKDAsIGNmZy5jbGFz cywgMCkgKyAxOwogICAgaWYgKHNpemUpIHsKICAgICAgd2NoYXIgKmJ1ZiA9 IG5ld24od2NoYXIsIHNpemUpOwogICAgICBjc19tYnN0b3djcyhidWYsIGNm Zy5jbGFzcywgc2l6ZSk7CiAgICAgIHdjbGFzcyA9IGJ1ZjsKICAgIH0KICAg IGVsc2UKICAgICAgZnB1dHMoIlVzaW5nIGRlZmF1bHQgY2xhc3MgbmFtZSBk dWUgdG8gaW52YWxpZCBjaGFyYWN0ZXJzLlxuIiwgc3RkZXJyKTsKICB9Cgog IC8vIFB1dCBjaGlsZCBjb21tYW5kIGxpbmUgaW50byB3aW5kb3cgdGl0bGUg aWYgd2UgaGF2ZW4ndCBnb3Qgb25lIGFscmVhZHkuCiAgc3RyaW5nIHRpdGxl ID0gY2ZnLnRpdGxlOwogIGlmICghKnRpdGxlKSB7CiAgICBzaXplX3QgbGVu OwogICAgY2hhciAqYXJnejsKICAgIGFyZ3pfY3JlYXRlKGFyZ3YsICZhcmd6 LCAmbGVuKTsKICAgIGFyZ3pfc3RyaW5naWZ5KGFyZ3osIGxlbiwgJyAnKTsK ICAgIHRpdGxlID0gYXJnejsKICB9CgogIC8vIENvbnZlcnQgdGl0bGUgdG8g VW5pY29kZS4gRGVmYXVsdCB0byBhcHBsaWNhdGlvbiBuYW1lIGlmIHVuc3Vj Y2Vzc2Z1bC4KICB3c3RyaW5nIHd0aXRsZSA9IF9XKEFQUE5BTUUpOwogIHsK ICAgIHNpemVfdCBzaXplID0gY3NfbWJzdG93Y3MoMCwgdGl0bGUsIDApICsg MTsKICAgIGlmIChzaXplKSB7CiAgICAgIHdjaGFyICpidWYgPSBuZXduKHdj aGFyLCBzaXplKTsKICAgICAgY3NfbWJzdG93Y3MoYnVmLCB0aXRsZSwgc2l6 ZSk7CiAgICAgIHd0aXRsZSA9IGJ1ZjsKICAgIH0KICAgIGVsc2UKICAgICAg ZnB1dHMoIlVzaW5nIGRlZmF1bHQgdGl0bGUgZHVlIHRvIGludmFsaWQgY2hh cmFjdGVycy5cbiIsIHN0ZGVycik7CiAgfQoKICAvLyBUaGUgd2luZG93IGNs YXNzLgogIGNsYXNzX2F0b20gPSBSZWdpc3RlckNsYXNzRXhXKCYoV05EQ0xB U1NFWFcpewogICAgLmNiU2l6ZSA9IHNpemVvZihXTkRDTEFTU0VYVyksCiAg ICAuc3R5bGUgPSAwLAogICAgLmxwZm5XbmRQcm9jID0gd2luX3Byb2MsCiAg ICAuY2JDbHNFeHRyYSA9IDAsCiAgICAuY2JXbmRFeHRyYSA9IDAsCiAgICAu aEluc3RhbmNlID0gaW5zdCwKICAgIC5oSWNvbiA9IGxhcmdlX2ljb24gPzog TG9hZEljb24oaW5zdCwgTUFLRUlOVFJFU09VUkNFKElESV9NQUlOSUNPTikp LAogICAgLmhJY29uU20gPSBzbWFsbF9pY29uLAogICAgLmhDdXJzb3IgPSBM b2FkQ3Vyc29yKG51bGwsIElEQ19JQkVBTSksCiAgICAuaGJyQmFja2dyb3Vu ZCA9IG51bGwsCiAgICAubHBzek1lbnVOYW1lID0gbnVsbCwKICAgIC5scHN6 Q2xhc3NOYW1lID0gd2NsYXNzLAogIH0pOwoKCiAgLy8gSW5pdGlhbGlzZSB0 aGUgZm9udHMsIHRodXMgYWxzbyBkZXRlcm1pbmluZyB0aGVpciB3aWR0aCBh bmQgaGVpZ2h0LgogIHdpbl9pbml0X2ZvbnRzKGNmZy5mb250LnNpemUpOwoK ICAvLyBSZWNvbmZpZ3VyZSB0aGUgY2hhcnNldCBtb2R1bGUgbm93IHRoYXQg YXJndW1lbnRzIGhhdmUgYmVlbiBjb252ZXJ0ZWQsCiAgLy8gdGhlIGxvY2Fs ZS9jaGFyc2V0IHNldHRpbmdzIGhhdmUgYmVlbiBsb2FkZWQsIGFuZCB0aGUg Zm9udCB3aWR0aCBoYXMKICAvLyBiZWVuIGRldGVybWluZWQuCiAgY3NfcmVj b25maWcoKTsKCiAgLy8gRGV0ZXJtaW5lIHdpbmRvdyBzaXplcy4KICBpbnQg dGVybV93aWR0aCA9IGZvbnRfd2lkdGggKiBjZmcuY29sczsKICBpbnQgdGVy bV9oZWlnaHQgPSBmb250X2hlaWdodCAqIGNmZy5yb3dzOwoKICBSRUNUIGNy ID0gezAsIDAsIHRlcm1fd2lkdGggKyAyICogUEFERElORywgdGVybV9oZWln aHQgKyAyICogUEFERElOR307CiAgUkVDVCB3ciA9IGNyOwogIEFkanVzdFdp bmRvd1JlY3QoJndyLCBXU19PVkVSTEFQUEVEV0lORE9XLCBmYWxzZSk7CiAg aW50IHdpZHRoID0gd3IucmlnaHQgLSB3ci5sZWZ0OwogIGludCBoZWlnaHQg PSB3ci5ib3R0b20gLSB3ci50b3A7CgogIGlmIChjZmcuc2Nyb2xsYmFyKQog ICAgd2lkdGggKz0gR2V0U3lzdGVtTWV0cmljcyhTTV9DWFZTQ1JPTEwpOwoK ICBleHRyYV93aWR0aCA9IHdpZHRoIC0gKGNyLnJpZ2h0IC0gY3IubGVmdCk7 CiAgZXh0cmFfaGVpZ2h0ID0gaGVpZ2h0IC0gKGNyLmJvdHRvbSAtIGNyLnRv cCk7CgogIC8vIEhhdmluZyB4ID09IENXX1VTRURFRkFVTFQgYnV0IG5vdCBz dGlsbCB0cmlnZ2VycyB0aGUgZGVmYXVsdCBwb3NpdGlvbmluZywKICAvLyB3 aGVyZWFzIHk9PUNXX1VTRUZBVUxUIGJ1dCBub3QgeCByZXN1bHRzIGluIGFu IGludmlzaWJsZSB3aW5kb3csIHNvIHRvCiAgLy8gYXZvaWQgdGhlIGxhdHRl ciwgcmVxdWlyZSBib3RoIHggYW5kIHkgdG8gYmUgc2V0IGZvciBjdXN0b20g cG9zaXRpb25pbmcuCiAgaWYgKGNmZy55ID09IChpbnQpQ1dfVVNFREVGQVVM VCkKICAgIGNmZy54ID0gQ1dfVVNFREVGQVVMVDsKCiAgLy8gQ3JlYXRlIGlu aXRpYWwgd2luZG93LgogIHduZCA9IENyZWF0ZVdpbmRvd0V4VyhjZmcuc2Ny b2xsYmFyIDwgMCA/IFdTX0VYX0xFRlRTQ1JPTExCQVIgOiAwLAogICAgICAg ICAgICAgICAgICAgICAgICB3Y2xhc3MsIHd0aXRsZSwKICAgICAgICAgICAg ICAgICAgICAgICAgV1NfT1ZFUkxBUFBFRFdJTkRPVyB8IChjZmcuc2Nyb2xs YmFyID8gV1NfVlNDUk9MTCA6IDApLAogICAgICAgICAgICAgICAgICAgICAg ICBjZmcueCwgY2ZnLnksIHdpZHRoLCBoZWlnaHQsCiAgICAgICAgICAgICAg ICAgICAgICAgIG51bGwsIG51bGwsIGluc3QsIG51bGwpOwoKICBpZiAoYm9y ZGVyX3N0eWxlKSB7CiAgICBMT05HIHN0eWxlID0gR2V0V2luZG93TG9uZyh3 bmQsIEdXTF9TVFlMRSk7CiAgICBpZiAoc3RyY21wIChib3JkZXJfc3R5bGUs ICJ2b2lkIikgPT0gMCkgewogICAgICBzdHlsZSAmPSB+KFdTX0NBUFRJT04g fCBXU19CT1JERVIgfCBXU19USElDS0ZSQU1FKTsKICAgIH0KICAgIGVsc2Ug ewogICAgICBzdHlsZSAmPSB+KFdTX0NBUFRJT04gfCBXU19CT1JERVIpOwog ICAgfQogICAgU2V0V2luZG93TG9uZyh3bmQsIEdXTF9TVFlMRSwgc3R5bGUp OwogICAgU2V0V2luZG93UG9zKHduZCwgbnVsbCwgMCwgMCwgMCwgMCwKICAg ICAgICAgICAgICAgICBTV1BfTk9NT1ZFIHwgU1dQX05PU0laRSB8IFNXUF9O T1pPUkRFUiB8IFNXUF9GUkFNRUNIQU5HRUQpOwogIH0KCiAgLy8gVGhlIGlu cHV0IG1ldGhvZCBjb250ZXh0LgogIGltYyA9IEltbUdldENvbnRleHQod25k KTsKCiAgLy8gQ29ycmVjdCBhdXRvcGxhY2VtZW50LCB3aGljaCBsaWtlcyB0 byBwdXQgcGFydCBvZiB0aGUgd2luZG93IHVuZGVyIHRoZQogIC8vIHRhc2ti YXIgd2hlbiB0aGUgd2luZG93IHNpemUgYXBwcm9hY2hlcyB0aGUgd29yayBh cmVhIHNpemUuCiAgaWYgKGNmZy54ID09IChpbnQpQ1dfVVNFREVGQVVMVCkg ewogICAgd2luX2ZpeF9wb3NpdGlvbigpOwogIH0KCiAgLy8gSW5pdGlhbGlz ZSB0aGUgdGVybWluYWwuCiAgdGVybV9yZXNldCgpOwogIHRlcm1fcmVzaXpl KGNmZy5yb3dzLCBjZmcuY29scyk7CgogIC8vIEluaXRpYWxpc2UgdGhlIHNj cm9sbCBiYXIuCiAgU2V0U2Nyb2xsSW5mbygKICAgIHduZCwgU0JfVkVSVCwK ICAgICYoU0NST0xMSU5GTyl7CiAgICAgIC5jYlNpemUgPSBzaXplb2YoU0NS T0xMSU5GTyksCiAgICAgIC5mTWFzayA9IFNJRl9BTEwgfCBTSUZfRElTQUJM RU5PU0NST0xMLAogICAgICAubk1pbiA9IDAsIC5uTWF4ID0gY2ZnLnJvd3Mg LSAxLAogICAgICAublBhZ2UgPSBjZmcucm93cywgLm5Qb3MgPSAwLAogICAg fSwKICAgIGZhbHNlCiAgKTsKCiAgLy8gU2V0IHVwIGFuIGVtcHR5IGNhcmV0 IGJpdG1hcC4gV2UncmUgcGFpbnRpbmcgdGhlIGN1cnNvciBtYW51YWxseS4K ICBjYXJldGJtID0gQ3JlYXRlQml0bWFwKDEsIGZvbnRfaGVpZ2h0LCAxLCAx LCBuZXduKHNob3J0LCBmb250X2hlaWdodCkpOwogIENyZWF0ZUNhcmV0KHdu ZCwgY2FyZXRibSwgMCwgMCk7CgogIC8vIEluaXRpYWxpc2UgdmFyaW91cyBv dGhlciBzdHVmZi4KICB3aW5faW5pdF9kcm9wX3RhcmdldCgpOwogIHdpbl9p bml0X21lbnVzKCk7CiAgdXBkYXRlX3RyYW5zcGFyZW5jeSgpOwoKICAvLyBD cmVhdGUgY2hpbGQgcHJvY2Vzcy4KICBjaGlsZF9jcmVhdGUoCiAgICBhcmd2 LCAmKHN0cnVjdCB3aW5zaXplKXtjZmcucm93cywgY2ZnLmNvbHMsIHRlcm1f d2lkdGgsIHRlcm1faGVpZ2h0fQogICk7CgogIC8vIEZpbmFsbHkgc2hvdyB0 aGUgd2luZG93IQogIGZ1bGxzY3Jfb25fbWF4ID0gKGNmZy53aW5kb3cgPT0g LTEpOwogIFNob3dXaW5kb3cod25kLCBmdWxsc2NyX29uX21heCA/IFNXX1NI T1dNQVhJTUlaRUQgOiBjZmcud2luZG93KTsKCiAgLy8gTWVzc2FnZSBsb29w LgogIGZvciAoOzspIHsKICAgIE1TRyBtc2c7CiAgICB3aGlsZSAoUGVla01l c3NhZ2UoJm1zZywgbnVsbCwgMCwgMCwgUE1fUkVNT1ZFKSkgewogICAgICBp ZiAobXNnLm1lc3NhZ2UgPT0gV01fUVVJVCkKICAgICAgICByZXR1cm4gbXNn LndQYXJhbTsKICAgICAgaWYgKCFJc0RpYWxvZ01lc3NhZ2UoY29uZmlnX3du ZCwgJm1zZykpCiAgICAgICAgRGlzcGF0Y2hNZXNzYWdlKCZtc2cpOwogICAg fQogICAgY2hpbGRfcHJvYygpOwogIH0KfQo= ------=_20150727175807_31619 Content-Type: text/plain; charset=us-ascii -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple ------=_20150727175807_31619--