/* Copyright (C), 2007 by Stephen Hurd */ /* $Id: syncterm.c,v 1.261 2020/06/27 00:04:50 deuce Exp $ */ #if defined(__APPLE__) && defined(__MACH__) #include // FSFindFolder() and friends #endif #define NOCRYPT /* Stop windows.h from loading wincrypt.h */ /* Is windows.h REALLY necessary?!?! */ #define __WINCRYPT_H__ /* Really REALLY stop wincrypt.h har har * This is to workaround an issue in MinGW-w64 headers where * shlobj.h (which we need to include) unconditionally * includes wincrypt.h (which we need to not be included). */ #define WIN32_LEAN_AND_MEAN #include #ifdef _WIN32 #include #ifndef REFKNOWNFOLDERID typedef GUID KNOWNFOLDERID; #define REFKNOWNFOLDERID const KNOWNFOLDERID* // Not shared static const KNOWNFOLDERID FOLDERID_Downloads = {0x374DE290,0x123F,0x4565,{0x91,0x64,0x39,0xC4,0x92,0x5E,0x46,0x7B}}; static const KNOWNFOLDERID FOLDERID_RoamingAppData = {0x3EB685DB,0x65F9,0x4CF6,{0xA0,0x3A,0xE3,0xEF,0x65,0x72,0x9F,0x3D}}; static const KNOWNFOLDERID FOLDERID_InternetCache = {0x352481E8,0x33BE,0x4251,{0xBA,0x85,0x60,0x07,0xCA,0xED,0xCF,0x9D}}; // Shared static const KNOWNFOLDERID FOLDERID_PublicDownloads = {0x3D644C9B,0x1FB8,0x4f30,{0x9B,0x45,0xF6,0x70,0x23,0x5F,0x79,0xC0}}; static const KNOWNFOLDERID FOLDERID_ProgramData = {0x62AB5D82,0xFDC1,0x4DC3,{0xA9,0xDD,0x07,0x0D,0x1D,0x49,0x5D,0x97}}; #endif #ifndef KF_FLAG_CREATE #define KF_FLAG_CREATE 0x00008000 #endif #include /* xp_dlopen() and friends */ #endif #include #include #include #include #include #include // STDOUT_FILENO #include #include #if !(defined __BORLANDC__ || defined _MSC_VER) #include #else #define bool int enum { false, true }; #endif #include "st_crypt.h" #include "fonts.h" #include "syncterm.h" #include "bbslist.h" #include "conn.h" #include "term.h" #include "uifcinit.h" #include "window.h" #include "scale.h" char* syncterm_version = "SyncTERM 1.2b" //#define ALPHA #ifdef _DEBUG " Debug ("__DATE__")" #endif ; char *usage = "\nusage: syncterm [options] [URL]" "\n\noptions:\n\n" "-e# = set escape delay to #msec\n" "-iX = set interface mode to X (default=auto) where X is one of:\n" " S[W|F] = SDL surface mode W for windowed and F for fullscreen\n" #ifdef __unix__ " X = X11 mode\n" " C = Curses mode\n" " I = Curses mode with forced ASCII charset\n" " F = Curses mode with forced IBM charset\n" #else " W[F] = Win32 native mode, F for fullscreen\n" #endif " A = ANSI mode\n" "-l# = set screen lines to # (default=auto-detect)\n" "-t = use telnet mode if URL does not include the scheme\n" "-r = use rlogin mode if URL does not include the scheme\n" "-h = use SSH mode if URL does not include the scheme\n" "-4 = Only resolve IPv4 addresses\n" "-6 = Only resolve IPv6 addresses\n" "-s = enable \"Safe Mode\" which prevents writing/browsing local files\n" "-T = when the ONLY argument, dumps the terminfo entry to stdout and exits\n" "-v = when the ONLY argument, dumps the version info to stdout and exits\n" "-c = Hide the status line\n" "-q = Quiet mode (Hide various popups such as this during a connect)\n" "\n" "URL format is: [(rlogin|telnet|ssh|raw)://][user[:password]@]domainname[:port]\n" "raw:// URLs MUST include a port.\n" "shell:command URLs are supported on *nix.\n" "examples: rlogin://deuce:password@nix.synchro.net:5885\n" " telnet://deuce@nix.synchro.net\n" " nix.synchro.net\n" " telnet://nix.synchro.net\n" " raw://nix.synchro.net:23\n" " shell:/usr/bin/sh\n" ; char *inpath=NULL; int default_font=0; struct syncterm_settings settings; char *font_names[sizeof(conio_fontdata)/sizeof(struct conio_font_data_struct)]; struct vmem_cell *scrollback_buf=NULL; unsigned int scrollback_lines=0; unsigned int scrollback_mode=C80; unsigned int scrollback_cols=80; int safe_mode=0; FILE* log_fp; extern ini_style_t ini_style; BOOL quitting=FALSE; int fake_mode = -1; #ifdef _WINSOCKAPI_ static WSADATA WSAData; #define SOCKLIB_DESC WSAData.szDescription static BOOL WSAInitialized=FALSE; static BOOL winsock_startup(void) { int status; /* Status Code */ if((status = WSAStartup(MAKEWORD(1,1), &WSAData))==0) { fprintf(stderr,"%s %s",WSAData.szDescription, WSAData.szSystemStatus); WSAInitialized=TRUE; return (TRUE); } fprintf(stderr,"!WinSock startup ERROR %d", status); return (FALSE); } #else /* No WINSOCK */ #define winsock_startup() (TRUE) #define SOCKLIB_DESC NULL #endif /* GIMP RGBA C-Source image dump (syncterm-icon.c) */ static const struct { unsigned int width; unsigned int height; unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */ unsigned char pixel_data[64 * 64 * 4 + 1]; } syncterm_icon = { 64, 64, 4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0xxx\377ppp\377hh" "h\377bbb\377]]]\377ZZZ\377WWW\377VVV\377VVV\377WWW\377ZZZ\377]]]\377bbb\377" "hhh\377ppp\377xxx\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0rrr\377" "bbb\377UUU\377JJJ\377AAA\377:::\377333\377---\377(((\377$$$\377\"\"\"\377" "\37\37\37\377\36\36\36\377\36\36\36\377\36\36\36\377\36\36\36\377\37\37\37" "\377\"\"\"\377$$$\377(((\377---\377333\377:::\377AAA\377JJJ\377UUU\377bb" "b\377rrr\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ooo\377ZZZ\377III\377" "<<<\377///\377%%%\377\36\36\36\377\36\36\36\377\37\37\37\377\40\40\40\377" "!!!\377\"\"\"\377!!!\377\33\33\33\377\36\36\36\377###\377###\377###\377#" "##\377###\377###\377\36\36\36\377\33\33\33\377!!!\377\"\"\"\377!!!\377\40" "\40\40\377\37\37\37\377\36\36\36\377\36\36\36\377%%%\377///\377;;;\377II" "I\377ZZZ\377ooo\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0jjj\377RRR\377>>>\377---\377\"\"\"\377\36\36\36\377\40\40\40\377\"\"\"" "\377\33\33\33\377###\377###\377\26\26\26\377\15\15\15\377\15\15\15\377\15" "\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\15\15" "\15\377\15\15\15\377\26\26\26\377\26\26\26\377###\377\33\33\33\377\"\"\"" "\377\40\40\40\377\36\36\36\377\"\"\"\377---\377>>>\377QQQ\377jjj\377\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0uuu\377WWW\377???\377,,,\377\36\36\36\377\37\37\37\377\"\"\"\377\33\33" "\33\377###\377\26\26\26\377\15\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\15\15\15\377\26\26\26\377###\377\36\36\36\377\"\"\"\377\37\37" "\37\377\36\36\36\377,,,\377???\377WWW\377uuu\377\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0mmm\377MMM\377333\377\"\"\"\377\37\37\37\377\"\"\"\377##" "#\377\26\26\26\377\15\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\14\377" "\0\0z\377\0\0t\377\0\0\0\377\0\0\0\377\0\0j\377\0\0\6\377\0\0\0\377\0\0\0" "\377\15\15\15\377\26\26\26\377###\377\"\"\"\377\37\37\37\377!!!\377333\377" "LLL\377mmm\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0ppp\377KKK\377///\377\36\36\36\377!!!\377\33\33\33" "\377\26\26\26\377\15\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\7\377\0\0" "\12\377\0\0\0\377\0\0\20\377\0\0\26\377\0\0)\377\0\0\17\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\20\377\0\0\177\377\0\0G\377\0\0""2\377\0\0\0\377\0\0\0" "\377\0\0-\377\0\0\2\377\0\0\0\377\6\6\6\377\10\10\10\377\14\14\14\377\7\7" "\7\377\33\34\33\377\26\26\26\377\33\33\33\377!!!\377\36\36\36\377///\377" "KKK\377ppp\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0}}}\377SSS" "\377222\377\36\36\36\377!!!\377\36\36\36\377\26\26\26\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\2\2\2\377" "\3\3\3\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0;\377\0\0T\377\0\0\3\377\0\0" "\214\377\0\0\223\377\0\0;\377\0\0!\377\0\0\16\377\0\0\3\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\2\377\0\0\224" "\377\0\0Q\377\0\0\3\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\25\25\25\377\33\34\33\377\27\27\27\377\27\27\27\377\21\21\21\377" "\0\0\0\377\0\0\0\377\15\15\15\377\36\36\36\377!!!\377\36\36\36\377222\377" "SSS\377}}}\377\0\0\0\0\0\0\0\0\0\0\0\0aaa\377>>>\377###\377\40\40\40\377" "\36\36\36\377\26\26\26\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\1\1\1\377\26\26\26\377\25\25\25\377\21\22\21\377" "\27\30\27\377\0\0\0\377\0\0\7\377\0\0:\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0,\377\0\0\213\377\0\0\300\377\0\0_\377\0\0=\377\0" "\0\0\377\0\0\0\377\0\0/\377\0\0H\377\0\0\1\377\0\0\0\377\0\0!\377\0\0\237" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\26\26\26\377\36\36\36\377\40\40\40\377###\377" "===\377aaa\377\0\0\0\0;;;\377)))\377\36\36\36\377!!!\377\26\26\26\377\0\0" "\1\377\0\0\2\377\0\0\4\377\0\0\0\377\0\0\0\377\0\0\0\377\1\1\1\377\1\1\1" "\377&&&\377OPO\377QRQ\377#$#\377\0\0\0\377\0\0\0\377\0\0\1\377\0\0\2\377" "\0\0\14\377\0\0\36\377\0\0V\377\0\0V\377\0\0V\377\0\0X\377\0\0""9\377\0\0" """6\377\0\0\300\377\0\0\274\377\0\0\250\377\0\0:\377\0\0\6\377\0\0\251\377" "\0\0\327\377\0\0)\377\0\0\21\377\0\0\24\377\0\4\240\377\7\7\34\377???\377" "-.-\377WWW\377`_`\377`_`\377`_`\377TST\377\"\"\"\377\0\0\0\377\0\0\6\377" "\0\0A\377\0\0\0\377\0\0%\377\0\0U\377\0\0\24\377\0\0\1\377\0\0\0\377\0\0" "\0\377\26\26\26\377!!!\377\36\36\36\377)))\377;;;\377\40\40\40\377!!!\377" "###\377\15\15\15\377\0\0\6\377\0\0q\377\0\0\25\377\0\0""2\377\0\0\0\377\0" "\0\0\377\17\20\17\377xyx\377\203\203\203\377\230\230\230\377\272\273\272" "\377lll\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0a\377\0\0\216\377\0\0\216\377" "\0\0\244\377\0\0\337\377\0\0\334\377\0\0\315\377\0\0\342\377\0\0\270\377" "\0\0d\377\0\0\301\377\0\0\242\377\0\0\214\377\0\0+\377\0\0\16\377\0\0\333" "\377\0\0\346\377\0\0^\377\0\0S\377\0\0\236\377\0\12\340\377\5\5""7\377//" "/\377HIH\377\303\303\303\377\312\311\312\377\312\311\312\377\312\311\312" "\377\265\265\265\377QRQ\377\0\0\0\377\0\0\5\377\0\0""0\377\0\0\0\377\0\0" "\34\377\0\0?\377\0\0|\377\0\0y\377\0\0\7\377\0\0\0\377\0\0\0\377\15\15\15" "\377###\377!!!\377\40\40\40\377\26\26\26\377\15\15\15\377\0\0\10\377\0\0" "W\377\0\0)\377\0\0&\377\3\3\3\377\17\17\17\377ede\377\231\231\231\377\226" "\227\226\377\271\272\271\377\275\276\275\377\274\275\274\377\200\200\200" "\377&&&\377\0\0\3\377\0\0D\377\0\0\241\377\0\0\331\377\0\0\344\377\0\0\330" "\377\0\0\214\377\10\10>\377\17\17D\377\17\17?\377\0\0""3\377\0\0s\377\0\0" "\305\377\0\0\277\377\1\1?\377\16\16-\377\17\17\17\377\10\10\13\377\0\0X\377" "\0\0\360\377\0\5>\377\0+\225\377\0\20\333\377\0\3\352\377\0\0\223\377\0\0" "\20\377\15\15\15\377xwx\377\343\342\343\377\357\360\357\377\357\360\357\377" "\340\341\340\377~~~\377\0\0\0\377\14\14\14\377\17\17\17\377\17\17\17\377" "\17\17\17\377\17\17\17\377\4\4(\377\0\0\210\377\0\0Q\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\15\15\15\377\0\0\0\377\0\0\0\377\0\0j" "\377\0\0c\377\0\0\2\377\0\0\0\377222\377\266\267\266\377\273\274\273\377" "\275\276\275\377\275\276\275\377\275\276\275\377\275\276\275\377\275\276" "\275\377sss\377\16\16\16\377\0\1F\377\2\3\335\377\0\2\375\377\0\0\374\377" "\4\4H\377\35\35'\377\36\36#\377klk\377\264\265\264\377\235\236\235\377\0" "\0&\377\0\0\317\377\0\0\307\377\26\26V\377--.\377\246\247\246\377\266\267" "\266\377jjj\377\0\0)\377\0\32\347\377\0\7\302\377\0/\220\377\0\22_\377\25" "\25\37\377!!)\377!!\"\377!!!\377121\377\262\262\262\377\365\365\365\377\365" "\365\365\377\352\352\352\377\213\213\213\377\6\6\6\377\216\217\216\377\266" "\267\266\377\266\267\266\377\252\253\252\377\230\231\230\377##<\377\0\0\216" "\377\0\0Y\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\246\377\0\0\33\377\0\0\0\377\0\0\0\377klk\377\276" "\277\276\377\275\276\275\377\275\276\275\377\311\311\311\377\312\311\312" "\377\275\276\275\377\275\276\275\377\207\210\207\377\1\1\4\377\0\5\352\377" "\13\20\373\377\0\12\375\377\0\0\363\377\30\27?\377\260\257\260\377\265\266" "\265\377\271\272\271\377\260\261\260\377)))\377\0\0~\377\0\0\317\377%%i\377" "\237\236\242\377\271\271\271\377\274\275\274\377\275\276\275\377\255\255" "\255\377\0\1\4\377\0\\\251\377\0\3\201\377\11\14\25\377237\377\234\234\234" "\377\310\307\310\377\310\307\310\377\310\307\310\377\217\216\217\377\225" "\226\225\377\302\302\302\377\300\301\300\377\277\300\277\377\210\211\210" "\377###\377\224\224\224\377\275\276\275\377\301\301\301\377xwx\377\10\10" """9\377\2\2n\377\0\0\225\377\0\0r\377\0\0[\377\0\0\40\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\11d\377\0\13\27\377\0\0\0" "\377\24\24\24\377\261\261\261\377\334\334\334\377\333\334\333\377\324\324" "\324\377\205\203\205\377\211\210\211\377\275\276\275\377\275\276\275\377" "\236\237\236\377\17\17\21\377\0\3\233\377\7\12\375\377\0\6\301\377\0\0\313" "\377\31\30?\377\270\267\270\377\275\276\275\377\271\272\271\377\240\241\240" "\377\22\23D\377\0\4\350\377\0\0]\377RRR\377\300\300\300\377\301\301\301\377" "\275\276\275\377\275\276\275\377\261\261\261\377\36\36\37\377\0\0Z\377\21" "\21\23\377iii\377\235\236\235\377\305\305\305\377\310\310\310\377\310\310" "\310\377\310\310\310\377\303\303\303\377\207\207\207\377\243\243\243\377" "\331\332\331\377\333\334\333\377\270\270\270\377@@@\377qqq\377\303\304\303" "\377\277\300\277\377\224\224\224\377\0\0|\377\0\0\177\377\2\2\211\377\2\2" "\370\377\0\0\354\377\0\0\207\377\0\0""1\377\0\0\7\377\0\0\24\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\25\25\377\0\24\27\377\0\0\1\377*+*\377\372\372\372" "\377\375\375\375\377\376\376\376\377\372\371\372\377\211\211\211\377\31\31" "\31\377nmn\377\326\323\326\377\300\300\300\377\214\215\214\377\0\0\15\377" "\0\0C\377\2\2\"\377\0\0\240\377\31\30?\377\270\267\270\377\275\276\275\377" "\263\264\263\377\214\215\214\377\0\1i\377\0\16\315\377\22\22\26\377\\]\\" "\377TTT\377\246\246\246\377\276\277\276\377\275\276\275\377\264\265\264\377" "BCB\377\1\1\1\377\226\226\226\377\314\313\314\377\277\300\277\377\275\276" "\275\377\275\276\275\377\275\276\275\377\275\276\275\377\275\276\275\377" "EEE\377~}~\377\373\373\373\377\377\377\377\377\362\362\362\377bbb\377FGF" "\377\312\311\312\377\275\276\275\377\271\272\271\377\2\2#\377\0\0\267\377" "\6\6\367\377\6\6\371\377\0\0\355\377\0\0\274\377\0\0l\377\0\0\16\377\0\0" ",\377\0\0\1\377\0\0\0\377\0\0\5\377\0\5\35\377\0\4p\377\0\0B\377\14\14\17" "\377yzy\377\300\300\300\377\320\320\320\377\315\315\315\377\274\274\274\377" "\220\216\220\377\40\40\40\377212\377222\377;;;\377\25\26\25\377\40\40\40" "\377<=<\377\6\6c\377\31\30""0\377\270\267\270\377\275\276\275\377\262\263" "\262\377\200\200\200\377\37\40""6\377\0q\234\377\5\10\10\377\26\27\"\377" "\13\13\23\377LML\377\263\263\263\377\275\276\275\377\301\302\301\377HGH\377" "555\377\276\277\276\377\301\302\301\377\276\277\276\377\300\300\300\377\276" "\277\276\377\275\276\275\377\266\267\266\377\266\267\266\377\17\17\17\377" "111\377\367\367\367\377\377\377\377\377\375\375\375\377ooo\377...\377\260" "\261\260\377\275\276\275\377\264\265\264\377UUU\377\25\26;\377\27\27L\377" "\27\27L\377\25\26J\377\11\11""2\377\17\17'\377\3\3\6\377\0\0^\377\0\0\26" "\377\0\0\4\377\0\0D\377\0\0\314\377\0\0\305\377\0\0\303\377\0\1A\377\3\11" "\35\377MKM\377\300\275\300\377\276\276\276\377\275\276\275\377\275\276\275" "\377\201\201\201\377\21\21\21\377./.\377\243\243\243\377\267\270\267\377" "\225\226\225\377Z[Z\377\10\10F\377\34\34,\377\277\277\277\377\307\310\307" "\377\263\264\263\377\213\213\213\377\264\264\264\377(--\377\31\30\31\377" "\0\0S\377\0\0""8\377111\377\270\270\270\377\307\310\307\377\314\314\314\377" "MMM\377[\\[\377\310\311\310\377\310\311\310\377\302\303\302\377\274\272\274" "\377\261\261\261\377\273\274\273\377\265\266\265\377\252\252\252\377\0\0" "\0\377\27\30\27\377\343\343\343\377\376\376\376\377\377\377\377\377\331\332" "\331\377\302\303\302\377\307\310\307\377\307\310\307\377\277\300\277\377" "\304\305\304\377\242\243\242\377\231\232\231\377\231\232\231\377\231\232" "\231\377>?>\377kkk\377\25\25\30\377\0\0t\377\0\0\27\377\0\0\32\377\0\0\300" "\377\0\0\355\377\0\0r\377\0\0\257\377\0\5\363\377\0%\263\377\1\1X\377\1\1" ")\377MMM\377xxx\377\307\305\307\377\316\315\316\377\216\215\216\377\37\40" "\37\377\236\237\236\377\275\276\275\377\275\276\275\377\240\241\240\377\11" "\11\12\377111\377\346\345\346\377\377\377\377\377\261\261\261\377\310\310" "\310\377\376\376\376\377\374\373\374\377\305\304\305\377__`\377\33\33\34" "\377\30\30\30\377\343\343\343\377\377\377\377\377\364\362\364\377cbc\377" "\332\332\332\377\375\375\375\377\377\377\377\377\271\271\271\377(((\377K" "KK\377\262\263\262\377\275\276\275\377srs\377\0\0=\377\0\0\16\377\200\200" "\200\377\372\372\372\377\377\377\377\377\377\377\377\377\377\377\377\377" "\377\377\377\377\377\377\377\377\376\376\376\377\377\377\377\377;;;\377\1" "\1W\377\1\30h\377\1""3b\377\1\1a\377\1\1Z\377\0\0k\377\0\0W\377\0\0\0\377" "\0\2>\377\0\30\307\377\0\20\342\377\0\0_\377\0\0\330\377\0\3\364\377\0\22" "g\377\0\0g\377\0\0/\377\0\0\0\377\16\15\16\377jhj\377\266\265\266\377\310" "\307\310\377\202\202\202\377\252\252\252\377\276\277\276\377\275\276\275" "\377\267\267\267\377)()\377AAA\377\322\322\322\377\336\337\336\377\256\257" "\256\377\245\245\245\377\337\337\337\377\336\337\336\377\336\337\336\377" "\316\316\316\377\212\211\212\377)))\377\307\310\307\377\341\341\341\377\336" "\335\336\377\\[\\\377\326\325\326\377\376\375\376\377\376\376\376\377\206" "\206\206\377\0\0\0\377)))\377\202\203\202\377\275\276\275\377\227\230\227" "\377##%\377\0\0\0\377www\377\343\343\343\377\336\337\336\377\313\314\313" "\377\200\200\200\377\212\212\212\377\337\337\337\377\336\337\336\377\336" "\337\336\377Z[Z\377\0\0s\377\0\33\340\377\0:\310\377\0\4\274\377\0\0\207" "\377\0\0q\377\0\0\0\377\0\0\0\377\0\6b\377\0""2\315\377\0\36\330\377\0\0" "M\377\0\0\205\377\0\0""7\377\37\37\37\377\223\223\223\377\223\223\223\377" "+++\377\0\0x\377\0\0\15\377\224\225\224\377\302\302\302\377\275\276\275\377" "\267\270\267\377\277\300\277\377\275\276\275\377\301\301\301\377\243\243" "\243\377hhh\377\275\276\275\377\275\276\275\377\254\255\254\377\202\202\202" "\377\277\300\277\377\275\276\275\377\275\276\275\377\275\276\275\377\302" "\303\302\377\241\241\241\377\272\273\272\377\304\304\304\377\310\307\310" "\377TUT\377\321\320\321\377\375\375\375\377\376\375\376\377\206\206\206\377" "\0\0\0\377\1\1t\377\22\23$\377*+*\377*+*\377\20\20\20\377\0\0\0\377jjj\377" "\316\315\316\377\275\276\275\377\227\230\227\377\0\0\0\377\25\25\25\377\277" "\300\277\377\275\276\275\377\275\276\275\377{{{\377\0\0\7\377\0\0/\377\0" "\0|\377\0\13\345\377\0\0>\377\0\0\0\377\0\0\0\377\0\0\0\377\0\1!\377\0\10" "\263\377\0\21\366\377\0\21\337\377\0\0\274\377+++\377\231\227\231\377\265" "\266\265\377wxw\377'('\377\37\37""7\377@?B\377\304\303\304\377\275\276\275" "\377\320\316\320\377[Z[\377\310\306\310\377\331\331\331\377\361\360\361\377" "\363\364\363\377\351\351\351\377\365\365\365\377\365\365\365\377\205\205" "\205\377\215\214\215\377\301\301\301\377\300\301\300\377\223\222\223\377" "^^^\377\263\264\263\377\275\276\275\377\275\276\275\377\302\302\302\377\310" "\307\310\377FGF\377\251\247\251\377\364\363\364\377\372\371\372\377\314\314" "\314\377MNM\377\6\6)\377\0\0\177\377\0\0b\377\16\16\16\377=>=\377121\377" "***\377\273\274\273\377\275\276\275\377\227\230\227\377\0\0""5\377\3\3""3" "\377\216\216\216\377\275\276\275\377\275\276\275\377\263\264\263\377\13\25" "&\377\0D\262\377\0\0\277\377\0\2n\377\0\0\11\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\1\377\0\0""4\377\0<\277\377\0N\273\377\0\0\245\377233\377\255" "\253\255\377\265\266\265\377\271\272\271\377\265\266\265\377\265\266\265" "\377\276\276\276\377\316\314\316\377\303\303\303\377\325\323\325\377\272" "\272\272\377WYW\377SRS\377\273\270\273\377\322\321\322\377\363\363\363\377" "\362\362\362\377\360\360\360\377nnn\377\230\227\230\377\304\304\304\377\303" "\304\303\377\225\224\225\377\7\7\7\377hhh\377\267\270\267\377\275\276\275" "\377\301\301\301\377\307\307\307\377SSS\377676\377\347\346\347\377\361\360" "\361\377\324\324\324\377\275\275\275\377HGH\377&&-\377*)/\377ghg\377\204" "\205\204\377HIH\377\31\31\31\377\260\260\260\377\277\300\277\377\233\234" "\233\377\0\0M\377\0\10\261\377\206\206\206\377\301\302\301\377\301\302\301" "\377\276\277\276\377\37*:\377\0\\\234\377\0\6\21\377\0\0\4\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377232\377\255\253\255\377\275\276\275\377\275\276\275\377\275\276\275" "\377\275\276\275\377\301\302\301\377\321\320\321\377\332\330\332\377\311" "\311\311\377\275\276\275\377\265\265\265\377kkk\377\21\21\21\377232\377\277" "\300\277\377\275\276\275\377\261\262\261\377+++\377\276\277\276\377\320\316" "\320\377\316\315\316\377\275\276\275\377\20\20\20\377\0\0\0\377[\\[\377\264" "\265\264\377\275\276\275\377\307\307\307\377\230\230\230\377\0\0\0\377yy" "y\377\313\311\313\377\275\276\275\377\327\325\327\377\325\323\325\377\304" "\304\304\377\312\311\312\377\275\276\275\377\237\240\237\377\200\201\200" "\377\0\0L\377\215\215\221\377\310\310\310\377\253\254\253\377\0\2Y\377\0" "(\275\377\213\212\213\377\322\320\322\377\322\320\322\377\302\302\302\377" "opo\377\0\212\214\377\0\37\40\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\11\11\377\0\36\36\377\0\6\7\377\34\34\34" "\377\267\266\267\377\322\321\322\377\322\321\322\377\277\277\277\377\232" "\233\232\377\263\264\263\377\303\303\303\377\307\306\307\377{{{\377WX[\377" "[[`\377PPT\377\20\21\22\377]]]\377\311\310\311\377\310\310\310\377\234\234" "\234\377FFF\377\272\273\272\377\302\302\302\377\332\327\332\377\323\321\323" "\377ono\377\13\14R\377\10\10\37\377^^^\377\274\274\274\377\302\302\302\377" "\245\245\245\377\26\27\26\377\22\22\23\377^]`\377\206\207\206\377\306\305" "\306\377\300\301\300\377\301\301\301\377\266\265\266\377\257\260\257\377" "\253\254\253\377PPP\377\0\0K\377\211\211\214\377\301\301\301\377uuu\377\0" ";w\377\0\35e\377\200\200\200\377\306\306\306\377\302\300\302\377\320\317" "\320\377\377\0\217\221\377\0\240\243\377\0\275\304\377\0w\345\377\0$\311" "\377\0\0\245\377\31\31k\377\306\304\306\377\311\311\303\377\353\352y\377" "ff\32\377!!!\377333\377\10\10\10\377\31\31\37\377\31\31.\377YZY\377000\377" "\0Is\377\0$\263\377\10\10""1\377\31\31.\377ooo\377\236\237\236\377{|\200" "\377():\377\20\20\20\377\0\0]\377\24\24""3\377\31\31""6\377\24\24""5\377" "\13\13\34\377\0\0\0\377\0\0\0\377666\377\224\224\224\377WWW\377\0\0,\377" "\12\30M\377uxx\377\226\226\226\377\236\237\236\377\235\236\235\377<<<\377" "\2\2\2\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0!!" "\377\0_`\377\0\0\0\377\0ln\377\0\235\237\377\0\226\227\377\0\0\4\377\0QY" "\377\0\244\262\377\0g\273\377\0\37\223\377\0\0K\377333\377\325\323\325\377" "\325\325\232\377\363\362Q\377\207\207\34\377[\\[\377kjj\377EE\22\377\0\0" "\35\377\0\0e\377\0\0\31\377\0\0""2\377\0P~\377\0\247\315\377\0$\363\377\0" "\10\225\377\0\0:\377\0\0\22\377\31\31\31\377\213\213\213\377KKK\377\0\0\0" "\377\0\0\15\377\0\0\211\377\0\0\233\377\0\0S\377\35\35\35\377\12\12\12\377" "\231\231\231\377\10\10\10\377\0\0\0\377\0\0&\377\0\0*\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\1\1\377\0\2\2\377\0\0\0\377\0\2\2\377\0\3" "\3\377\0\3\3\377\0\0\20\377\0\2\34\377\0\3&\377\0\2""5\377\0\1\3\377\"\"" "#\377\231\231\231\377\350\346\217\377\374\374\23\377\377\377\1\377\375\375" "W\377\374\374\374\377\372\372\367\377\221\221-\377\0\0\1\377\0\0\2\377\0" "\0""1\377\0\0b\377\0\13\272\377\0Y\315\377\0M\316\377\0\37\314\377\0\0\227" "\377\0\0\214\377\0\0\3\377\3\3\3\377\1\1\1\377\0\0\0\377FFF\377\2\2\4\377" "\0\0\3\377\0\0\2\377999\377\23\23\23\377\3\3\3\377\0\0\0\377\0\0\0\377\0" "\0\1\377\0\0K\377\0\0\3\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\7\377\0\0\13\377\0\0" "\17\377\0\0\25\377\0\0\0\377\34\35\34\377PPP\377cc\31\377ll\0\377\206\206" "\0\377\377\377%\377\377\377l\377\232\232j\377\23\23\23\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0G\377\0\0V\377\0\5V\377\0\15V\377\0\0\37\377" "\0\0\206\377\0\0Z\377\0\0""9\377\0\0\15\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\27\27\0\377\314" "\314\3\377\372\372\12\377\236\236\0\377\14\14\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0W\377\0\0\220\377\0\0]\377\0\0\24\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\15\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377FF\0\377" "\343\343\35\377\216\216k\377\25\25\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\17\377\0\0\27\377\0" "\0\1\377\0\0u\377\0\0\27\377\0\0\15\377\0\0\3\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\15" "\15\15\377\40\40\40\377!!!\377###\377\15\15\15\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\315\315" "3\377\240\240\7\377\4\4\4\377\0\0\0\377\0\0\0\377\0\0\2\377\5\5\363\377\6" "\6\371\377\6\6\371\377\6\6\371\377\6\6\371\377\0\0#\377\3\3\231\377\6\6\371" "\377\6\6\371\377\6\6\371\377\6\6\371\377\0\0\"\377\3\3\207\377\6\6\371\377" "\6\6\371\377\5\5\363\377\4\4\250\377\0\0\2\377\5\5\351\377\5\5\352\377\0" "\0\17\377\0\0\17\377\5\5\352\377\5\5\347\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\15" "\15\15\377###\377!!!\377\40\40\40\377:::\377(((\377\36\36\36\377!!!\377\26" "\26\26\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0``\377\314\341\322\377\226\226\30\377\\\\\0\377\0\0\0\377\0\0\0\377" "\0\0\12\377\5\5\365\377\1\1""2\377\6\6\371\377\1\1R\377\5\5\325\377\1\1""0" "\377\0\0\14\377\6\6\371\377\1\1E\377\3\3\202\377\5\5\335\377\0\0\33\377\0" "\0\16\377\6\6\371\377\1\1H\377\1\1I\377\6\6\371\377\0\0\37\377\2\2v\377\6" "\6\371\377\2\2]\377\2\2[\377\6\6\371\377\2\2u\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\26\26" "\26\377!!!\377\37\37\37\377(((\377:::\377\0\0\0\0aaa\377===\377###\377!!" "!\377\36\36\36\377\15\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0CC\377m|W\377\315\315\11\377@@\0\377\0\0\0\377\0\0\0\377\0\0\7\377" "\4\4\253\377\0\0\0\377\6\6\371\377\0\0'\377\3\3\222\377\0\0!\377\0\0\0\377" "\6\6\371\377\6\6\371\377\6\6\371\377\0\0'\377\0\0\0\377\0\0\0\377\6\6\371" "\377\6\6\371\377\6\6\371\377\3\3\245\377\0\0\0\377\2\2j\377\4\4\303\377\4" "\4\262\377\4\4\255\377\4\4\303\377\2\2i\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\15\15\15\377\36\36\36\377!!!\377" "###\377===\377aaa\377\0\0\0\0\0\0\0\0\0\0\0\0}}}\377SSS\377222\377\36\36" "\36\377!!!\377\36\36\36\377\15\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\257\257\0\377==\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\6\6\371\377\0\0'\377\0\0\0\377\0\0\0\377\0\0\0\377\6\6\371" "\377\1\1E\377\4\4\305\377\3\3\210\377\0\0\11\377\0\0\0\377\6\6\371\377\1" "\1R\377\5\5\354\377\3\3\216\377\0\0\0\377\2\2t\377\3\3\233\377\4\4\306\377" "\4\4\302\377\3\3\234\377\2\2s\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\15\15\15\377###\377\"\"\"\377\36\36\36\377222\377RRR\377}}}\377" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0ooo\377KKK\377///\377\36" "\36\36\377!!!\377\33\33\33\377\26\26\26\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\207\207\0\377" "\1\1\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\12\377\1\1""2\377" "\6\6\371\377\1\1R\377\0\0\22\377\0\0\0\377\0\0\15\377\6\6\371\377\1\1H\377" "\0\0'\377\6\6\371\377\0\0'\377\0\0\21\377\6\6\371\377\1\1:\377\2\2{\377\5" "\5\353\377\0\0\36\377\3\3\214\377\4\4\246\377\1\1D\377\1\1C\377\4\4\246\377" "\3\3\213\377\0\0\0\377\0\0\0\377\0\0\0\377\26\26\26\377\33\33\33\377!!!\377" "\36\36\36\377///\377JJJ\377ooo\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0mmm\377LLL\377333\377\"\"\"\377" "\37\37\37\377\"\"\"\377###\377\26\26\26\377\0\0\0\377\0\0\0\377\0\0\0\377" "\0\0\0\377\0\0\0\377\0\0\0\377\\\\\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\2\2\\\377\6\6\371\377\6\6\371\377\6\6\371\377\3\3\202" "\377\0\0\0\377\3\3\201\377\6\6\371\377\6\6\371\377\6\6\371\377\6\6\371\377" "\0\0!\377\3\3\205\377\6\6\371\377\4\4\275\377\0\0\14\377\5\5\342\377\4\4" "\272\377\5\5\351\377\5\5\370\377\0\0%\377\0\0&\377\6\6\371\377\5\5\352\377" "\26\26\26\377###\377\"\"\"\377\37\37\37\377!!!\377333\377LLL\377mmm\377\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0uuu\377WWW\377>>>\377+++\377\36\36" "\36\377\37\37\37\377\"\"\"\377\36\36\36\377\26\26\26\377\15\15\15\377\15" "\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0" "\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\15\15\15\377\15\15" "\15\377\26\26\26\377\36\36\36\377\"\"\"\377\37\37\37\377\36\36\36\377+++" "\377>>>\377WWW\377uuu\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0jjj\377RRR\377>>>\377---\377!!!\377\36\36" "\36\377\40\40\40\377\"\"\"\377\33\33\33\377###\377\26\26\26\377\15\15\15" "\377\15\15\15\377\15\15\15\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0" "\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0\0\377\0\0" "\0\377\0\0\0\377\0\0\0\377\0\0\0\377\15\15\15\377\15\15\15\377\26\26\26\377" "###\377\33\33\33\377\"\"\"\377\40\40\40\377\36\36\36\377!!!\377---\377>>" ">\377QQQ\377jjj\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0ooo\377ZZZ\377III\377;;;\377...\377%%%\377\36\36\36\377\36\36\36\377\37" "\37\37\377\40\40\40\377\"\"\"\377\"\"\"\377!!!\377\33\33\33\377\36\36\36" "\377###\377###\377###\377###\377###\377###\377\36\36\36\377\33\33\33\377" "!!!\377\"\"\"\377\"\"\"\377\40\40\40\377\37\37\37\377\36\36\36\377\36\36" "\36\377%%%\377...\377;;;\377III\377YYY\377nnn\377\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0rrr\377bbb\377UUU\377JJJ\377AAA\377:::\377222\377---\377" "(((\377$$$\377!!!\377\37\37\37\377\36\36\36\377\35\35\35\377\35\35\35\377" "\36\36\36\377\37\37\37\377!!!\377$$$\377(((\377---\377222\377999\377AAA\377" "JJJ\377UUU\377bbb\377rrr\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0xxx\377ooo\377hhh\377bbb\377]]]\377ZZZ\377WWW\377VVV\377VVV\377WWW\377" "ZZZ\377]]]\377bbb\377hhh\377ooo\377xxx\377\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", }; char *output_types[]={ "Autodetect" #ifdef __unix__ " (X11, SDL, Curses)" #elif defined(_WIN32) " (SDL, Console, ANSI)" #endif #ifdef __unix__ ,"Curses" ,"Curses on cp437 Device" ,"Curses using US-ASCII" #endif ,"ANSI" #if defined(__unix__) && !defined(NO_X) ,"X11" #endif #ifdef _WIN32 ,"Win32 Console" ,"Win32 Console Fullscreen" #endif #if defined(WITH_SDL) || defined(WITH_SDL_AUDIO) ,"SDL" ,"SDL Fullscreen" #endif ,NULL}; int output_map[]={ CIOLIB_MODE_AUTO #ifdef __unix__ ,CIOLIB_MODE_CURSES ,CIOLIB_MODE_CURSES_IBM ,CIOLIB_MODE_CURSES_ASCII #endif ,CIOLIB_MODE_ANSI #if defined(__unix__) && !defined(NO_X) ,CIOLIB_MODE_X #endif #ifdef _WIN32 ,CIOLIB_MODE_CONIO ,CIOLIB_MODE_CONIO_FULLSCREEN #endif #if defined(WITH_SDL) || defined(WITH_SDL_AUDIO) ,CIOLIB_MODE_SDL ,CIOLIB_MODE_SDL_FULLSCREEN #endif ,0}; char *output_descrs[]={ "Autodetect" ,"Curses" ,"Curses on cp437 Device" ,"Curses using US-ASCII" ,"ANSI" ,"X11" ,"Win32 Console" ,"Win32 Console Fullscreen" ,"SDL" ,"SDL Fullscreen" ,NULL}; char *output_enum[]={ "Autodetect" ,"Curses" ,"Curses437" ,"CursesAscii" ,"ANSI" ,"X11" ,"WinConsole" ,"WinConsoleFullscreen" ,"SDL" ,"SDLFullscreen" ,NULL}; BOOL check_exit(BOOL force) { if (force || (uifc.exit_flags & UIFC_XF_QUIT)) { if (settings.confirm_close) { if (!confirm("Are you sure you want to exit?",NULL)) return false; } quitting=TRUE; return TRUE; } return FALSE; } void parse_url(char *url, struct bbslist *bbs, int dflt_conn_type, int force_defaults) { char *p1, *p2, *p3; #define BBSLIST_SIZE ((MAX_OPTS+1)*sizeof(struct bbslist *)) struct bbslist **list; int listcount=0, i; bbs->id=-1; bbs->added=time(NULL); bbs->calls=0; bbs->type=USER_BBSLIST; if(force_defaults) { bbs->user[0]=0; bbs->password[0]=0; bbs->screen_mode=SCREEN_MODE_CURRENT; bbs->conn_type=dflt_conn_type; bbs->port=conn_ports[dflt_conn_type]; bbs->xfer_loglevel=LOG_INFO; bbs->telnet_loglevel=LOG_INFO; bbs->music=CTERM_MUSIC_BANSI; strcpy(bbs->font,"Codepage 437 English"); } p1=url; if(!strnicmp("rlogin://",url,9)) { bbs->conn_type=CONN_TYPE_RLOGIN; bbs->port=conn_ports[bbs->conn_type]; p1=url+9; } else if(!strnicmp("ssh://",url,6)) { bbs->conn_type=CONN_TYPE_SSH; bbs->port=conn_ports[bbs->conn_type]; p1=url+6; } else if(!strnicmp("telnet://",url,9)) { bbs->conn_type=CONN_TYPE_TELNET; bbs->port=conn_ports[bbs->conn_type]; p1=url+9; } else if(!strnicmp("raw://",url,6)) { bbs->conn_type=CONN_TYPE_TELNET; bbs->port=conn_ports[bbs->conn_type]; p1=url+6; } else if(!strnicmp("shell:",url,6)) { bbs->conn_type=CONN_TYPE_SHELL; bbs->port=conn_ports[bbs->conn_type]; p1=url+6; } else if(!strnicmp("ghost://",url,8)) { bbs->conn_type=CONN_TYPE_MBBS_GHOST; bbs->port=conn_ports[bbs->conn_type]; p1=url+8; } /* ToDo: RFC2806 */ p3=strchr(p1,'@'); if(p3!=NULL) { *p3=0; p2=strchr(p1,':'); if(p2!=NULL) { *p2=0; p2++; SAFECOPY(bbs->password,p2); } SAFECOPY(bbs->user,p1); p1=p3+1; } p2 = p1; if(*p1=='[') { p2=strchr(p1, ']'); if(p2 != NULL) { p1++; *p2=0; p2++; } else p2 = p1; } p3=strrchr(p1,'/'); if(p3!=NULL) { *p3=0; SAFECOPY(bbs->ghost_program,p3+1); } SAFECOPY(bbs->name,p1); p2=strrchr(p2,':'); if(p2!=NULL) { *p2=0; p2++; bbs->port=atoi(p2); } SAFECOPY(bbs->addr,p1); /* Find BBS listing in users phone book */ list = calloc(1, BBSLIST_SIZE); read_list(settings.list_path, &list[0], NULL, &listcount, USER_BBSLIST); for(i=0;iaddr,list[i]->addr)==0) && (bbs->port==list[i]->port) && (bbs->conn_type==list[i]->conn_type) && (bbs->user[0]==0 || (stricmp(bbs->name,list[i]->name)==0)) && (bbs->password[0]==0 || (stricmp(bbs->password,list[i]->password)==0))) { memcpy(bbs,list[i],sizeof(struct bbslist)); break; } } if(i==listcount) { for(i=0;iname,list[i]->name)==0) { memcpy(bbs,list[i],sizeof(struct bbslist)); break; } } } free_list(&list[0],listcount); free(list); } #if defined(__APPLE__) && defined(__MACH__) static char *get_new_OSX_filename(char *fn, int fnlen, int type, int shared) { FSRef ref; /* First, get the path */ switch(type) { case SYNCTERM_PATH_INI: case SYNCTERM_PATH_LIST: if(FSFindFolder(shared?kLocalDomain:kUserDomain, kPreferencesFolderType, kCreateFolder, &ref)!=noErr) return(NULL); if(FSRefMakePath(&ref, (unsigned char*)fn, fnlen)!=noErr) return(NULL); backslash(fn); strncat(fn, "SyncTERM", fnlen-strlen(fn)-1); backslash(fn); if(!isdir(fn)) { if(MKDIR(fn)) return(NULL); } break; case SYNCTERM_DEFAULT_TRANSFER_PATH: /* I'd love to use the "right" setting here, but don't know how */ if(FSFindFolder(shared?kLocalDomain:kUserDomain, kDownloadsFolderType, kCreateFolder, &ref)!=noErr) return(NULL); if(FSRefMakePath(&ref, (unsigned char*)fn, fnlen)!=noErr) return(NULL); backslash(fn); if(!isdir(fn)) { if(MKDIR(fn)) return(NULL); } return(fn); case SYNCTERM_PATH_CACHE: if(FSFindFolder(shared?kLocalDomain:kUserDomain, kCachedDataFolderType, kCreateFolder, &ref)!=noErr) return(NULL); if(FSRefMakePath(&ref, (unsigned char*)fn, fnlen)!=noErr) return(NULL); backslash(fn); return(fn); } switch(type) { case SYNCTERM_PATH_INI: strncat(fn, "SyncTERM.ini", fnlen-strlen(fn)-1); return(fn); case SYNCTERM_PATH_LIST: strncat(fn, "SyncTERM.lst", fnlen-strlen(fn)-1); return(fn); } return(NULL); } #endif char *get_syncterm_filename(char *fn, int fnlen, int type, int shared) { char oldlst[MAX_PATH+1]; memset(fn, 0, fnlen); #ifdef _WIN32 char *home; static dll_handle shell32=NULL; BOOL we_got_this=FALSE; static HRESULT(__stdcall *GKFP)(REFKNOWNFOLDERID rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath)=NULL; const char *shell32dll[]={"Shell32", NULL}; static dll_handle ole32=NULL; static int (__stdcall *CTMF)(LPVOID)=NULL; const char *ole32dll[]={"OLE32", NULL}; home=getenv("HOME"); if(home==NULL) home=getenv("USERPROFILE"); if(home==NULL) { strcpy(oldlst,"./syncterm.lst"); } else { SAFECOPY(oldlst, home); strcat(oldlst, "/syncterm.lst"); } if(shell32==NULL) { shell32=xp_dlopen(shell32dll, RTLD_LAZY, 6); } if(ole32==NULL) { ole32=xp_dlopen(ole32dll, RTLD_LAZY, 0); } if(shell32!=NULL && ole32 !=NULL) { if(GKFP==NULL) { GKFP=xp_dlsym(shell32, SHGetKnownFolderPath); } if(CTMF==NULL) { CTMF=xp_dlsym(ole32, CoTaskMemFree); } if(GKFP && CTMF) { PWSTR path; switch(type) { case SYNCTERM_PATH_INI: case SYNCTERM_PATH_LIST: if(shared) { if(GKFP(&FOLDERID_ProgramData, KF_FLAG_CREATE, NULL, &path)==S_OK) { we_got_this=TRUE; } } else { if(GKFP(&FOLDERID_RoamingAppData, KF_FLAG_CREATE, NULL, &path)==S_OK) { we_got_this=TRUE; } } break; case SYNCTERM_DEFAULT_TRANSFER_PATH: if(shared) { if(GKFP(&FOLDERID_PublicDownloads, KF_FLAG_CREATE, NULL, &path)==S_OK) { we_got_this=TRUE; } } else { if(GKFP(&FOLDERID_Downloads, KF_FLAG_CREATE, NULL, &path)==S_OK) { we_got_this=TRUE; } } break; case SYNCTERM_PATH_CACHE: if(GKFP(&FOLDERID_InternetCache, KF_FLAG_CREATE, NULL, &path)==S_OK) { we_got_this=TRUE; } break; } if(we_got_this) { // Convert unicode to string using snprintf() if (type == SYNCTERM_DEFAULT_TRANSFER_PATH || type == SYNCTERM_PATH_CACHE) { if(snprintf(fn, fnlen, "%S", path) >= fnlen) we_got_this=FALSE; } else { if(snprintf(fn, fnlen, "%S\\SyncTERM", path) >= fnlen) we_got_this=FALSE; } CTMF(path); } } } if(!we_got_this) { #ifdef CSIDL_FLAG_CREATE if(type==SYNCTERM_DEFAULT_TRANSFER_PATH) { switch(SHGetFolderPath(NULL, CSIDL_PERSONAL|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, fn)) { case E_FAIL: case E_INVALIDARG: getcwd(fn, fnlen); backslash(fn); break; default: backslash(fn); strcat(fn,"SyncTERM"); break; } if(!isdir(fn)) MKDIR(fn); return(fn); } switch(SHGetFolderPath(NULL, (shared?CSIDL_COMMON_APPDATA:CSIDL_APPDATA)|CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, fn)) { case E_FAIL: case E_INVALIDARG: strcpy(fn,"."); break; default: backslash(fn); strcat(fn,"SyncTERM"); break; } #else getcwd(fn, fnlen); backslash(fn); #endif } /* Create if it doesn't exist */ if(*fn && !isdir(fn)) { if(MKDIR(fn)) fn[0]=0; } switch(type) { case SYNCTERM_PATH_INI: backslash(fn); strncat(fn,"syncterm.ini",fnlen-strlen(fn)-1); break; case SYNCTERM_PATH_LIST: backslash(fn); strncat(fn,"syncterm.lst",fnlen-strlen(fn)-1); break; case SYNCTERM_PATH_CACHE: backslash(fn); strncat(fn,"SyncTERM",fnlen-strlen(fn)-1); backslash(fn); if(!isdir(fn)) { if(MKDIR(fn)) { fn[0]=0; break; } } strncat(fn,"cache",fnlen-strlen(fn)-1); backslash(fn); if(!isdir(fn)) { if(MKDIR(fn)) fn[0]=0; } break; } #else /* UNIX */ char *home=getenv("HOME"); if (!shared) { if((home==NULL || strlen(home) > MAX_PATH-32)) { /* $HOME just too damn big */ if(type==SYNCTERM_DEFAULT_TRANSFER_PATH || type==SYNCTERM_PATH_CACHE) { getcwd(fn, fnlen); backslash(fn); if(type==SYNCTERM_PATH_CACHE) { strcat(fn,"cache"); backslash(fn); } return(fn); } SAFECOPY(oldlst,"syncterm.lst"); strcpy(fn,"./"); } else { if(type==SYNCTERM_DEFAULT_TRANSFER_PATH) { strcpy(fn, home); backslash(fn); #if defined(__APPLE__) && defined(__MACH__) if(get_new_OSX_filename(oldlst, sizeof(oldlst), type, shared)!=NULL) strcpy(fn, oldlst); #endif if(!isdir(fn)) if(MKDIR(fn)) fn[0]=0; if(type==SYNCTERM_PATH_CACHE) { strcat(fn,"cache"); backslash(fn); } return(fn); } SAFECOPY(oldlst,home); backslash(oldlst); strcat(oldlst,"syncterm.lst"); sprintf(fn,"%.*s",fnlen,home); strncat(fn, "/.syncterm", fnlen-strlen(fn)-1); backslash(fn); if(type==SYNCTERM_PATH_CACHE) { if(!isdir(fn)) if(MKDIR(fn)) fn[0]=0; strcat(fn,"cache"); backslash(fn); return(fn); } } } else { #ifdef SYSTEM_LIST_DIR strcpy(fn,SYSTEM_LIST_DIR); backslash(fn); #else strcpy(fn,"/usr/local/etc/"); #endif } #if !(defined(__APPLE__) && defined(__MACH__)) /* Create if it doesn't exist */ if(!isdir(fn) && !shared) { if(MKDIR(fn)) fn[0]=0; } #endif switch(type) { case SYNCTERM_PATH_INI: strncat(fn,"syncterm.ini",fnlen-strlen(fn)-1); break; case SYNCTERM_PATH_LIST: strncat(fn,"syncterm.lst",fnlen-strlen(fn)-1); break; case SYNCTERM_PATH_CACHE: strncat(fn,"cache",fnlen-strlen(fn)-1); backslash(fn); #if !(defined(__APPLE__) && defined(__MACH__)) if(!isdir(fn)) { if(MKDIR(fn)) fn[0]=0; } #endif break; } #if defined(__APPLE__) && defined(__MACH__) strcpy(oldlst, fn); if(get_new_OSX_filename(fn, fnlen, type, shared)!=NULL) { if(fexist(oldlst)) { if(!isdir(oldlst)) { char *lastslash=strrchr(oldlst, '/'); rename(oldlst, fn); if(lastslash) { *(lastslash+1)='*'; *(lastslash+2)=0; if(!fexist(oldlst)) { *lastslash=0; rmdir(oldlst); } } } } } #endif /* OS X */ #endif /* !Win32 */ return(fn); } void load_settings(struct syncterm_settings *set) { FILE *inifile; char inipath[MAX_PATH+1]; int i=0; str_list_t sortby; char *order; get_syncterm_filename(inipath, sizeof(inipath), SYNCTERM_PATH_INI, FALSE); inifile=fopen(inipath,"r"); set->confirm_close=iniReadBool(inifile,"SyncTERM","ConfirmClose",FALSE); set->prompt_save=iniReadBool(inifile,"SyncTERM","PromptSave",TRUE); set->startup_mode=iniReadEnum(inifile,"SyncTERM","VideoMode",screen_modes_enum,SCREEN_MODE_CURRENT); set->startup_mode=iniReadEnum(inifile,"SyncTERM","ScreenMode",screen_modes_enum,set->startup_mode); set->output_mode=iniReadEnum(inifile,"SyncTERM","OutputMode",output_enum,CIOLIB_MODE_AUTO); set->backlines=iniReadInteger(inifile,"SyncTERM","ScrollBackLines",2000); set->xfer_success_keypress_timeout=iniReadInteger(inifile,"SyncTERM", "TransferSuccessKeypressTimeout", /* seconds: */0); set->xfer_failure_keypress_timeout=iniReadInteger(inifile,"SyncTERM", "TransferFailureKeypressTimeout", /* seconds: */60); set->custom_cols = iniReadInteger(inifile, "SyncTERM", "CustomCols", 80); set->custom_rows = iniReadInteger(inifile, "SyncTERM", "CustomRows", 25); set->custom_fontheight = iniReadInteger(inifile, "SyncTERM", "CustomFontHeight", 16); set->custom_aw = iniReadInteger(inifile, "SyncTERM", "CustomAspectWidth", 4); set->custom_ah = iniReadInteger(inifile, "SyncTERM", "CustomAspectHeight", 3); get_syncterm_filename(set->list_path, sizeof(set->list_path), SYNCTERM_PATH_LIST, FALSE); iniReadString(inifile, "SyncTERM", "ListPath", set->list_path, set->list_path); set->scaling_factor=iniReadInteger(inifile,"SyncTERM","ScalingFactor",0); set->window_width=iniReadInteger(inifile,"SyncTERM","WindowWidth",0); set->window_height=iniReadInteger(inifile,"SyncTERM","WindowHeight",0); set->blocky=iniReadBool(inifile,"SyncTERM","BlockyScaling",TRUE); // TODO: Add this to the UI somewhere. set->left_just=iniReadBool(inifile,"SyncTERM","LeftJustify",FALSE); /* Modem settings */ iniReadString(inifile, "SyncTERM", "ModemInit", "AT&F&C1&D2", set->mdm.init_string); iniReadString(inifile, "SyncTERM", "ModemDial", "ATDT", set->mdm.dial_string); iniReadString(inifile, "SyncTERM", "ModemDevice", DEFAULT_MODEM_DEV, set->mdm.device_name); set->mdm.com_rate=iniReadLongInt(inifile, "SyncTERM", "ModemComRate", 0); /* Sort order */ sortby=iniReadStringList(inifile, "SyncTERM", "SortOrder", ",", "5,1"); while((order=strListRemove(&sortby,0))!=NULL) { sortorder[i++]=atoi(order); free(order); } strListFree(&sortby); /* Shell TERM settings */ iniReadString(inifile, "SyncTERM", "TERM", "syncterm", set->TERM); if(inifile) fclose(inifile); } int main(int argc, char **argv) { struct bbslist *bbs=NULL; BOOL bbs_alloc=FALSE; struct text_info txtinfo; char str[MAX_PATH+1]; char drive[MAX_PATH+1]; char path[MAX_PATH+1]; char fname[MAX_PATH+1]; char ext[MAX_PATH+1]; /* Command-line parsing vars */ char url[MAX_PATH+1]; int i; int ciolib_mode; str_list_t inifile; FILE *listfile; char *inpath=NULL; int conn_type=CONN_TYPE_TELNET; int text_mode; BOOL override_conn=FALSE; int addr_family=PF_UNSPEC; char *last_bbs=NULL; char *p, *lp; int cvmode; int ww, wh, sf; int default_hidepopups=-1; int default_nostatus=-1; const char syncterm_termcap[]="\n# terminfo database entry for SyncTERM\n" "syncterm|SyncTERM,\n" // cwin maybe? Or just left/right and top/bottom margins? // smgtb=\\E[%i%p1%d;%p2%dr, // shift/ctrl/alt Fx as extra keys? // Booleans: " am,bce,da,ndscr,\n" // sam is a printer capability // Numeric: " it#8,colors#8,pairs#64,\n" // Strings: " acsc=}\\234|\\330{\\322+\\020\\,\\021l\\332m\\300k\\277j\\331u\\264t\\303v\\301w\\302q\\304x\\263n\\305`^Da\\260f\\370g\\361~\\371.^Y-^Xh\\261i^U0\\333y\\363z\\362,\n" " cbt=\\E[Z,bel=^G,cr=^M,csr=\\E[%i%p1%d;%p2%dr,tbc=\\E[3g,\n" " mgc=\\E[69h\\E[s\\e[69l,clear=\\E[2J,csr=\\E[%i%p1%d;%p2%dr,el1=\\E[1K,\n" " el=\\E[K,ed=\\E[J,hpa=\\E[%i%p1%dG,cup=\\E[%i%p1%d;%p2%dH,cud1=^J,home=\\E[H,\n" " civis=\\E[?25l,cub1=\\E[D,cnorm=\\E[?25h,cuf1=\\E[C,ll=\\E[255H,cuu1=\\E[A,\n" " cvvis=\\E[?25h,dch1=\\E[P,dl1=\\E[M,smam=\\E[?7h,blink=\\E[5m,bold=\\E[1m,\n" " ech=\\E[%p1%dX,rmam=\\E[7l,sgr0=\\E[m,is1=\\Ec,ich1=\\E[@,il1=\\E[L,kbs=^H,\n" " kcbt=\\E[Z,kdch1=\\177,kcud1=\\E[B,kend=\\E[K,kf1=\\E[11~,kf2=\\E[12~,\n" " kf3=\\E[13~,kf4=\\E[14~,kf5=\\E[15~,kf6=\\E[17~,kf7=\\E[18~,kf8=\\E[19~,\n" " kf9=\\E[20~,kf10=\\E[21~,kf11=\\E[23~,kf12=\\E[24~,kcub1=\\E[D,knp=\\E[U,\n" " kpp=\\E[V,kcuf1=\\E[C,kcuu1=\\E[A,nel=^M^J,dch=\\E[%p1%dP,dl=\\E[%p1%dM,\n" " cud=\\E[%p1%dB,ich=\\E[%p1%d@,indn=\\E[%p1%dS,il=\\E[%p1%dL,cub=\\E[%p1%dD,\n" " cuf=\\E[%p1%dC,rin=\\E[%p1%dT,cuu=\\E[%p1%dA,rep=%p1%c\\E[%p2%{1}%-%db,\n" " rs1=\\E[c,rc=\\E[u,sc=\\E[s,ind=\\E[S,ri=\\E[T,\n" " sgr=\\E[0%?%p1%p6%|%t;1%;%?%p4%|%t;5%;%?%p1%p3%|%t;7%;%?%p7%|%t;8%;m,\n" " smglp=\\E[69h\\E[%{1}%p1%+%d;0s\\E[69l,smgrp=\\E[69h\\E[0;%{1}%p1%+%ds\\E[69l,\n" " hts=\\E[H,ht=\t,setab=\\E[4%p1%dm,setaf=\\E[3%p1%dm,\n" " smglr=\\E[?69h\\E[%i%p1%d;%p2%ds\\E?69l,smso=\\E[0;1;7m,rmso=\\E[m,\n" "syncterm-bitmap|SyncTERM in Bitmap Mode,\n" " ccc,\n" " colors#256,pairs#65535,\n" " initc=\\E]4;%p1%d;rgb\\:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\\E\\\\,\n" " setab=\\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,\n" " setaf=\\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,\n" "syncterm-24|SyncTERM 80x25,\n" " lines#24,use=syncterm,\n" "syncterm-25|SyncTERM No Status Line,\n" " lines#25,use=syncterm,\n" "syncterm-27|SyncTERM 80x28 With Status,\n" " lines#27,use=syncterm,\n" "syncterm-28|SyncTERM 80x28 No Status Line,\n" " lines#28,use=syncterm,\n" "syncterm-42|SyncTERM 80x23,\n" " lines#42,use=syncterm,\n" "syncterm-43|SyncTERM 80x23 No Status Line,\n" " lines#43,use=syncterm,\n" "syncterm-49|SyncTERM 80x50,\n" " lines#49,use=syncterm,\n" "syncterm-50|SyncTERM 80x50 No Status Line,\n" " lines#50,use=syncterm,\n" "syncterm-59|SyncTERM 80x60,\n" " lines#59,use=syncterm,\n" "syncterm-60|SyncTERM 80x60 No Status Line,\n" " lines#60,use=syncterm,\n" "syncterm-w|SyncTERM Wide,\n" " cols#132,use=syncterm,\n" "syncterm-25-w|SyncTERM No Status Line,\n" " cols#132,lines#25,use=syncterm,\n" "syncterm-27-w|SyncTERM 132x28 With Status,\n" " cols#132,lines#27,use=syncterm,\n" "syncterm-28-w|SyncTERM 132x28 No Status Line,\n" " cols#132,lines#28,use=syncterm,\n" "syncterm-36-w|SyncTERM 132x37,\n" " cols#132,lines#36,use=syncterm,\n" "syncterm-37-w|SyncTERM 132x37 No Status Line,\n" " cols#132,lines#37,use=syncterm,\n" "syncterm-42-w|SyncTERM 132x23,\n" " cols#132,lines#42,use=syncterm,\n" "syncterm-43-w|SyncTERM 132x23 No Status Line,\n" " cols#132,lines#43,use=syncterm,\n" "syncterm-49-w|SyncTERM 132x50,\n" " cols#132,lines#49,use=syncterm,\n" "syncterm-50-w|SyncTERM 132x50 No Status Line,\n" " cols#132,lines#50,use=syncterm,\n" "syncterm-51-w|SyncTERM 132x52,\n" " cols#132,lines#51,use=syncterm,\n" "syncterm-52-w|SyncTERM 132x52 No Status Line,\n" " cols#132,lines#52,use=syncterm,\n" "syncterm-59-w|SyncTERM 132x60,\n" " cols#132,lines#59,use=syncterm,\n" "syncterm-60-w|SyncTERM 132x60 No Status Line,\n" " cols#132,lines#60,use=syncterm,\n" "syncterm-24-bitmap|SyncTERM 80x25,\n" " lines#24,use=syncterm-bitmap,\n" "syncterm-25-bitmap|SyncTERM No Status Line,\n" " lines#25,use=syncterm-bitmap,\n" "syncterm-27-bitmap|SyncTERM 80x28 With Status,\n" " lines#27,use=syncterm-bitmap,\n" "syncterm-28-bitmap|SyncTERM 80x28 No Status Line,\n" " lines#28,use=syncterm-bitmap,\n" "syncterm-42-bitmap|SyncTERM 80x23,\n" " lines#42,use=syncterm-bitmap,\n" "syncterm-43-bitmap|SyncTERM 80x23 No Status Line,\n" " lines#43,use=syncterm-bitmap,\n" "syncterm-49-bitmap|SyncTERM 80x50,\n" " lines#49,use=syncterm-bitmap,\n" "syncterm-50-bitmap|SyncTERM 80x50 No Status Line,\n" " lines#50,use=syncterm-bitmap,\n" "syncterm-59-bitmap|SyncTERM 80x60,\n" " lines#59,use=syncterm-bitmap,\n" "syncterm-60-bitmap|SyncTERM 80x60 No Status Line,\n" " lines#60,use=syncterm-bitmap,\n" "syncterm-w-bitmap|SyncTERM Wide,\n" " cols#132,use=syncterm-bitmap,\n" "syncterm-25-w-bitmap|SyncTERM No Status Line,\n" " cols#132,lines#25,use=syncterm-bitmap,\n" "syncterm-27-w-bitmap|SyncTERM 132x28 With Status,\n" " cols#132,lines#27,use=syncterm-bitmap,\n" "syncterm-28-w-bitmap|SyncTERM 132x28 No Status Line,\n" " cols#132,lines#28,use=syncterm-bitmap,\n" "syncterm-36-w-bitmap|SyncTERM 132x37,\n" " cols#132,lines#36,use=syncterm-bitmap,\n" "syncterm-37-w-bitmap|SyncTERM 132x37 No Status Line,\n" " cols#132,lines#37,use=syncterm-bitmap,\n" "syncterm-42-w-bitmap|SyncTERM 132x23,\n" " cols#132,lines#42,use=syncterm-bitmap,\n" "syncterm-43-w-bitmap|SyncTERM 132x23 No Status Line,\n" " cols#132,lines#43,use=syncterm-bitmap,\n" "syncterm-49-w-bitmap|SyncTERM 132x50,\n" " cols#132,lines#49,use=syncterm-bitmap,\n" "syncterm-50-w-bitmap|SyncTERM 132x50 No Status Line,\n" " cols#132,lines#50,use=syncterm-bitmap,\n" "syncterm-51-w-bitmap|SyncTERM 132x52,\n" " cols#132,lines#51,use=syncterm-bitmap,\n" "syncterm-52-w-bitmap|SyncTERM 132x52 No Status Line,\n" " cols#132,lines#52,use=syncterm-bitmap,\n" "syncterm-59-w-bitmap|SyncTERM 132x60,\n" " cols#132,lines#59,use=syncterm-bitmap,\n" "syncterm-60-w-bitmap|SyncTERM 132x60 No Status Line,\n" " cols#132,lines#60,use=syncterm-bitmap,\n"; SetThreadName("Main Thread"); if(argc==2 && strcmp(argv[1],"-T")==0) { write(STDOUT_FILENO, syncterm_termcap, strlen(syncterm_termcap)); return 0; } if(argc==2 && strcmp(argv[1],"-v")==0) { fprintf(stdout, "%s\n", syncterm_version); return 0; } #if !defined(WITHOUT_CRYPTLIB) /* Cryptlib initialization MUST be done before ciolib init */ if(!crypt_loaded) init_crypt(); atexit(exit_crypt); #endif /* UIFC initialization */ memset(&uifc,0,sizeof(uifc)); uifc.mode=UIFC_NOCTRL|UIFC_NHM; uifc.size=sizeof(uifc); uifc.esc_delay=25; url[0]=0; load_settings(&settings); cvmode = find_vmode(CIOLIB_MODE_CUSTOM); vparams[cvmode].cols = settings.custom_cols; vparams[cvmode].rows = settings.custom_rows; vparams[cvmode].charheight = settings.custom_fontheight; vparams[cvmode].aspect_width = settings.custom_aw; vparams[cvmode].aspect_height = settings.custom_ah; ciolib_initial_window_height = settings.window_height; ciolib_initial_window_width = settings.window_width; aspect_fix(&ciolib_initial_window_width, &ciolib_initial_window_height, settings.custom_aw, settings.custom_ah); ciolib_mode=settings.output_mode; if(settings.startup_mode != SCREEN_MODE_CURRENT) text_mode=screen_to_ciolib(settings.startup_mode); else text_mode=_ORIGMODE; for(i=1;iconn_type) bbs->port=conn_ports[conn_type]; bbs->conn_type=conn_type; } parse_url(url, bbs, conn_type, FALSE); strListFree(&inilines); } if(addr_family != ADDRESS_FAMILY_UNSPEC) bbs->address_family=addr_family; if(bbs->port==0) goto USAGE; } if(!winsock_startup()) return(1); load_font_files(); while((!quitting) && (bbs!=NULL || (bbs=show_bbslist(last_bbs, FALSE))!=NULL)) { if (default_hidepopups >= 0) bbs->hidepopups = default_hidepopups; if (default_nostatus >= 0) bbs->nostatus = default_nostatus; gettextinfo(&txtinfo); /* Current mode may have changed while in show_bbslist() */ FREE_AND_NULL(last_bbs); uifcbail(); if (bbs->screen_mode != SCREEN_MODE_CURRENT) fake_mode = screen_to_ciolib(bbs->screen_mode); textmode(screen_to_ciolib(bbs->screen_mode)); if (!bbs->hidepopups) init_uifc(TRUE, TRUE); load_font_files(); setfont(find_font_id(bbs->font),TRUE,1); if(conn_connect(bbs)) { load_font_files(); uifcbail(); textmode(txtinfo.currmode); fake_mode = -1; init_uifc(TRUE, TRUE); settitle("SyncTERM"); } else { /* ToDo: Update the entry with new lastconnected */ /* ToDo: Disallow duplicate entries */ bbs->connected=time(NULL); bbs->calls++; if(bbs->id != -1) { if(bbs->type==SYSTEM_BBSLIST) { bbs->type=USER_BBSLIST; add_bbs(settings.list_path, bbs); } if((listfile=fopen(settings.list_path,"r"))!=NULL) { inifile=iniReadFile(listfile); fclose(listfile); iniSetDateTime(&inifile,bbs->name,"LastConnected",TRUE,bbs->connected,&ini_style); iniSetInteger(&inifile,bbs->name,"TotalCalls",bbs->calls,&ini_style); if((listfile=fopen(settings.list_path,"w"))!=NULL) { iniWriteFile(listfile,inifile); fclose(listfile); } strListFree(&inifile); } } uifcbail(); sprintf(str,"SyncTERM - %s",bbs->name); settitle(str); term.nostatus=bbs->nostatus; if(drawwin()) { return(1); } if(log_fp==NULL && bbs->logfile[0]) log_fp=fopen(bbs->logfile,bbs->append_logfile ? "a" : "w"); if(log_fp!=NULL) { time_t now=time(NULL); fprintf(log_fp,"%.15s Log opened\n", ctime(&now)+4); } for(i=CONIO_FIRST_FREE_FONT; i<256; i++) { FREE_AND_NULL(conio_fontdata[i].eight_by_sixteen); FREE_AND_NULL(conio_fontdata[i].eight_by_fourteen); FREE_AND_NULL(conio_fontdata[i].eight_by_eight); FREE_AND_NULL(conio_fontdata[i].desc); } load_font_files(); if(doterm(bbs)) quitting=TRUE; fake_mode = -1; setvideoflags(0); if(log_fp!=NULL) { time_t now=time(NULL); fprintf(log_fp,"%.15s Log closed\n", ctime(&now)+4); fprintf(log_fp,"---------------\n"); fclose(log_fp); log_fp=NULL; } textmode(txtinfo.currmode); settitle("SyncTERM"); } if(quitting || url[0]) { if(bbs != NULL && bbs->id==-1) { if(!safe_mode) { if(settings.prompt_save) { char *YesNo[3]={"Yes","No",""}; /* Started from the command-line with a URL */ init_uifc(TRUE, TRUE); i=1; if (!bbs->hidepopups) { switch(uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,NULL,"Save this directory entry?",YesNo)) { case 0: /* Yes */ edit_list(NULL, bbs,settings.list_path,FALSE); add_bbs(settings.list_path,bbs); last_bbs=strdup(bbs->name); break; default: /* ESC/No */ break; } } } } } if (bbs_alloc) { bbs_alloc=FALSE; free(bbs); } bbs=NULL; break; } else last_bbs=strdup(bbs->name); if (bbs_alloc) { bbs_alloc=FALSE; free(bbs); } bbs=NULL; } for(i=CONIO_FIRST_FREE_FONT; i<256; i++) { FREE_AND_NULL(conio_fontdata[i].eight_by_sixteen); FREE_AND_NULL(conio_fontdata[i].eight_by_fourteen); FREE_AND_NULL(conio_fontdata[i].eight_by_eight); FREE_AND_NULL(conio_fontdata[i].desc); } if (bbs_alloc) free(bbs); if (last_bbs) free(last_bbs); // Save changed settings gettextinfo(&txtinfo); // Only save window info if we're in the startup mode... if (txtinfo.currmode == screen_to_ciolib(settings.startup_mode) || (settings.startup_mode == SCREEN_MODE_CURRENT && txtinfo.currmode == C80)) { ww = wh = sf = -1; get_window_info(&ww, &wh, NULL, NULL); sf = getscaling(); if((sf > 0 && sf != settings.scaling_factor) || (ww > 0 && ww != settings.window_width) || (wh > 0 && wh != settings.window_height)) { char inipath[MAX_PATH+1]; FILE *inifile; str_list_t inicontents; get_syncterm_filename(inipath, sizeof(inipath), SYNCTERM_PATH_INI, FALSE); if((inifile=fopen(inipath,"r"))!=NULL) { inicontents=iniReadFile(inifile); fclose(inifile); } else { inicontents=strListInit(); } if (sf > 0 && sf != settings.scaling_factor) iniSetInteger(&inicontents,"SyncTERM","ScalingFactor",sf,&ini_style); if (ww > 0 && ww != settings.window_width) iniSetInteger(&inicontents,"SyncTERM","WindowWidth",ww,&ini_style); if (wh > 0 && wh != settings.window_height) iniSetInteger(&inicontents,"SyncTERM","WindowHeight",wh,&ini_style); if((inifile=fopen(inipath,"w"))!=NULL) { iniWriteFile(inifile,inicontents); fclose(inifile); } } } uifcbail(); #ifdef _WINSOCKAPI_ if(WSAInitialized && WSACleanup()!=0) fprintf(stderr,"!WSACleanup ERROR %d",ERROR_VALUE); #endif return(0); USAGE: if (bbs_alloc) free(bbs); uifcbail(); clrscr(); gettextinfo(&txtinfo); p=lp=usage; textattr(LIGHTGRAY); gettextinfo(&txtinfo); i=0; for(lp=usage; *lp; p=strchr(lp, '\n')) { if(p==NULL) p=strchr(lp, 0)-1; cprintf("%.*s", p-lp+1, lp); lp = p+1; i++; if(i >= txtinfo.screenheight-1) { textattr(WHITE); cputs(""); switch(getch()) { case 0: case 0xe0: getch(); } textattr(LIGHTGRAY); gotoxy(1, txtinfo.screenheight); delline(); i=0; } } textattr(WHITE); cputs(""); switch(getch()) { case 0: case 0xe0: getch(); } textattr(LIGHTGRAY); return(0); } int screen_to_ciolib(int screen) { struct text_info ti; switch(screen) { case SCREEN_MODE_CURRENT: gettextinfo(&ti); return(ti.currmode); case SCREEN_MODE_80X25: return(C80); case SCREEN_MODE_LCD80X25: return(LCD80X25); case SCREEN_MODE_80X28: return(C80X28); case SCREEN_MODE_80X30: return(C80X30); case SCREEN_MODE_80X43: return(C80X43); case SCREEN_MODE_80X50: return(C80X50); case SCREEN_MODE_80X60: return(C80X60); case SCREEN_MODE_132X37: return ST132X37_16_9; case SCREEN_MODE_132x52: return ST132X52_5_4; case SCREEN_MODE_132X25: return(VESA_132X25); case SCREEN_MODE_132X28: return(VESA_132X28); case SCREEN_MODE_132X30: return(VESA_132X30); case SCREEN_MODE_132X34: return(VESA_132X34); case SCREEN_MODE_132X43: return(VESA_132X43); case SCREEN_MODE_132X50: return(VESA_132X50); case SCREEN_MODE_132X60: return(VESA_132X60); case SCREEN_MODE_C64: return(C64_40X25); case SCREEN_MODE_C128_40: return(C128_40X25); case SCREEN_MODE_C128_80: return(C128_80X25); case SCREEN_MODE_ATARI: return(ATARI_40X24); case SCREEN_MODE_ATARI_XEP80: return(ATARI_80X25); case SCREEN_MODE_CUSTOM: return(CIOLIB_MODE_CUSTOM); case SCREEN_MODE_EGA_80X25: return(EGA80X25); case SCREEN_MODE_VGA_80X25: return(VGA80X25); } gettextinfo(&ti); return(ti.currmode); } int ciolib_to_screen(int ciolib) { switch(ciolib) { case C80 : return(SCREEN_MODE_80X25); case LCD80X25: return(SCREEN_MODE_LCD80X25); case C80X28 : return(SCREEN_MODE_80X28); case C80X30: return(SCREEN_MODE_80X30); case C80X43 : return(SCREEN_MODE_80X43); case C80X50 : return(SCREEN_MODE_80X50); case C80X60 : return(SCREEN_MODE_80X60); case ST132X37_16_9: return(SCREEN_MODE_132X37); case ST132X52_5_4: return(SCREEN_MODE_132x52); case VESA_132X25 : return(SCREEN_MODE_132X25); case VESA_132X28 : return(SCREEN_MODE_132X28); case VESA_132X30 : return(SCREEN_MODE_132X30); case VESA_132X34 : return(SCREEN_MODE_132X34); case VESA_132X43 : return(SCREEN_MODE_132X43); case VESA_132X50 : return(SCREEN_MODE_132X50); case VESA_132X60 : return(SCREEN_MODE_132X60); case C64_40X25 : return(SCREEN_MODE_C64); case C128_40X25 : return(SCREEN_MODE_C128_40); case C128_80X25 : return(SCREEN_MODE_C128_80); case ATARI_40X24 : return(SCREEN_MODE_ATARI); case ATARI_80X25: return(SCREEN_MODE_ATARI_XEP80); case CIOLIB_MODE_CUSTOM: return(SCREEN_MODE_CUSTOM); case EGA80X25: return(SCREEN_MODE_EGA_80X25); } return(SCREEN_MODE_CURRENT); }