//--------------------------------------------------------- void CData_Source_PgSQL::Update_Sources(const wxTreeItemId &Root) { Freeze(); //----------------------------------------------------- wxTreeItemIdValue Cookie; wxTreeItemId Item = GetFirstChild(Root, Cookie); while( Item.IsOk() ) { Update_Source(Item); Item = GetNextChild(Item, Cookie); } //----------------------------------------------------- CSG_Table Connections; RUN_MODULE(DB_PGSQL_Get_Connections, false, SET_PARAMETER("CONNECTIONS", &Connections)); // CGet_Connections for(int i=0; i<Connections.Get_Count(); i++) { if( !Find_Source(Connections[i].asString(0)) ) { Update_Source(Connections[i].asString(0)); } } //----------------------------------------------------- SortChildren(Root); Expand (Root); Thaw(); }
//--------------------------------------------------------- void CData_Source_PgSQL::Source_Open(const wxTreeItemId &Item) { CData_Source_PgSQL_Data *pData = Item.IsOk() ? (CData_Source_PgSQL_Data *)GetItemData(Item) : NULL; if( pData == NULL ) return; if( pData->Get_Type() == TYPE_ROOT || pData->Get_Type() == TYPE_SERVER ) { CSG_Module *pModule = SG_Get_Module_Library_Manager().Get_Module("db_pgsql", DB_PGSQL_Get_Connection); // CGet_Connection if( pModule && pModule->On_Before_Execution() ) { if( pData->Get_Type() == TYPE_SERVER ) { pModule->Set_Parameter("PG_HOST", pData->Get_Host()); pModule->Set_Parameter("PG_PORT", pData->Get_Port()); } if( DLG_Parameters(pModule->Get_Parameters()) ) { pModule->Execute(); } } } else if( pData->is_Connected() ) { Update_Source(Item); } else if( !Source_Open(pData, true) ) { DLG_Message_Show_Error(_TL("Could not connect to data source."), _TL("Connect to PostgreSQL")); } }
//--------------------------------------------------------- void CData_Source_PgSQL::Update_Item(const wxTreeItemId &Item) { CData_Source_PgSQL_Data *pData = Item.IsOk() ? (CData_Source_PgSQL_Data *)GetItemData(Item) : NULL; if( pData == NULL ) return; switch( pData->Get_Type() ) { case TYPE_ROOT: Update_Sources(); break; case TYPE_SERVER: Update_Sources(Item); break; case TYPE_SOURCE: Update_Source (Item); break; } }
//--------------------------------------------------------- CData_Source_PgSQL::CData_Source_PgSQL(wxWindow *pParent) : wxTreeCtrl(pParent, ID_WND_DATA_SOURCE_DATABASE) { AssignImageList(new wxImageList(IMG_SIZE_TREECTRL, IMG_SIZE_TREECTRL, true, 0)); IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_DB_SOURCES ); // IMG_ROOT IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_DB_SOURCES ); // IMG_SERVER IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_DB_SOURCE_OFF ); // IMG_SRC_CLOSED IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_DB_SOURCE_ON ); // IMG_SRC_OPENED IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_DB_TABLE ); // IMG_TABLE IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_SHAPES_POINT ); // IMG_POINT IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_SHAPES_POINTS ); // IMG_POINTS IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_SHAPES_LINE ); // IMG_LINE IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_SHAPES_POLYGON); // IMG_POLYGON IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_GRID_MANAGER ); // IMG_GRIDS IMG_ADD_TO_TREECTRL(ID_IMG_WKSP_GRID ); // IMG_GRID AddRoot(_TL("PostgreSQL Sources"), IMG_ROOT, IMG_ROOT, new CData_Source_PgSQL_Data(TYPE_ROOT)); //----------------------------------------------------- SG_UI_Msg_Lock(true); wxString Server; for(int i=0; CONFIG_Read(CFG_PGSQL_DIR, wxString::Format(CFG_PGSQL_SRC, i), Server); i++) { wxString User, Password; if( Server.Find("|") > 0 ) { User = Server.AfterFirst ('|').BeforeFirst('|'); Password = Server.AfterLast ('|'); Server = Server.BeforeFirst('|'); } CData_Source_PgSQL_Data *pData = new CData_Source_PgSQL_Data(TYPE_SOURCE, &Server, &Server, &User, &Password); Update_Source(AppendItem(Get_Server_Item(Server, true), pData->Get_DBName().c_str(), IMG_SRC_CLOSED, IMG_SRC_CLOSED, pData)); } Update_Sources(); SG_UI_Msg_Lock(false); }
//--------------------------------------------------------- void CData_Source_PgSQL::Update_Source(const wxString &Server) { if( Server.IsEmpty() ) { Update_Sources(); return; } wxTreeItemId Item = Find_Source(Server); if( !Item.IsOk() && PGSQL_is_Connected(&Server) ) { CData_Source_PgSQL_Data *pData = new CData_Source_PgSQL_Data(TYPE_SOURCE, &Server, &Server); Item = AppendItem(Get_Server_Item(Server, true), pData->Get_DBName().c_str(), IMG_SRC_OPENED, IMG_SRC_OPENED, pData); } Update_Source(Item); }
int SB_Source_Add(const char* name, const char* address, sb_source_type_t type) { source_data *s; char addr[512]; int pos; if (strlen(name) <= 0 || strlen(address) <= 0) return -1; // create new source s = Create_Source(); s->type = type; strlcpy (s->name, name, sizeof (s->name)); strlcpy (addr, address, sizeof (addr)); if (s->type == type_file) { strlcpy (s->address.filename, address, sizeof (s->address.filename)); } else if (s->type == type_url) { strlcpy(s->address.url, address, sizeof(s->address.url)); } else { if (!strchr(addr, ':')) { strlcat (addr, ":27000", sizeof (addr)); } if (!NET_StringToAdr(addr, &(s->address.address))) { return -1; } } pos = sourcesn++; sources[pos] = s; Mark_Source(sources[pos]); Update_Source(sources[pos]); SB_Sources_Dump(); return pos; }
void Reload_Sources(void) { int i; vfsfile_t *f; char ln[2048]; source_data *s; SB_ServerList_Lock(); for (i=0; i < sourcesn; i++) Delete_Source(sources[i]); sourcesn = 0; // create dummy unbound source sources[0] = Create_Source(); sources[0]->type = type_dummy; strlcpy (sources[0]->name, "Unbound", sizeof (sources[0]->name)); sources[0]->servers = (server_data **) Q_malloc(MAX_UNBOUND*sizeof(server_data *)); sources[0]->serversn = 0; sources[0]->servers_allocated = MAX_UNBOUND; sourcesn = 1; f = FS_OpenVFS(SOURCES_LIST_FILENAME, "rb", FS_ANY); if (!f) { //Com_Printf ("sources file not found: %s\n", SOURCES_PATH); SB_ServerList_Unlock(); return; } s = Create_Source(); while (VFS_GETS(f, ln, sizeof(ln))) { char line[2048]; char *p, *q; if (sscanf(ln, "%[ -~ ]s", line) != 1) { continue; } p = next_nonspace(line); if (*p == '/') continue; // comment q = next_space(p); if (!strncmp(p, "master", q-p)) { s->type = type_master; } else if (!strncmp(p, "file", q-p)) { s->type = type_file; } else if (!strncmp(p, "url", q-p)) { s->type = type_url; } else { continue; } p = next_nonspace(q); q = (*p == '\"') ? next_quote(++p) : next_space(p); if (q-p <= 0) continue; strlcpy (s->name, p, min(q-p+1, MAX_SOURCE_NAME+1)); p = next_nonspace(q+1); q = next_space(p); *q = 0; if (q-p <= 0) continue; if (s->type == type_file) strlcpy (s->address.filename, p, sizeof (s->address.filename)); else if (s->type == type_url) strlcpy (s->address.url, p, sizeof (s->address.url)); else if (!NET_StringToAdr(p, &(s->address.address))) continue; sources[sourcesn] = Create_Source(); i = sources[sourcesn]->unique; memcpy(sources[sourcesn], s, sizeof(source_data)); sources[sourcesn]->unique = i; sourcesn++; } Delete_Source(s); VFS_CLOSE(f); //Com_Printf("Read %d sources for Server Browser\n", sourcesn); // update all file sources for (i=0; i < sourcesn; i++) if (sources[i]->type == type_file) Update_Source(sources[i]); else if (sources[i]->type == type_master || sources[i]->type == type_url) Precache_Source(sources[i]); rebuild_servers_list = 1; resort_sources = 1; SB_ServerList_Unlock(); }
DWORD WINAPI Update_Multiple_Sources_Proc(void * lpParameter) { // get servers from master server SYSTEMTIME lt; char request[] = {'c', '\n', '\0'}; socket_t newsocket; struct sockaddr_storage server; int ret = 0, i, sourcenum; unsigned char answer[10000]; fd_set fd; struct timeval tv; int total_masters = 0; int updated = 0; int d1, d2; GetLocalTime(<); d1 = lt.wSecond + 60*(lt.wMinute + 60*(lt.wHour + 24*(lt.wDay))); // update file sources - this should be a flash for (sourcenum = 0; sourcenum < psourcesn; sourcenum++) if (psources[sourcenum]->checked) { if (psources[sourcenum]->type == type_file) Update_Source(psources[sourcenum]); if (psources[sourcenum]->type == type_url) Update_Source(psources[sourcenum]); // todo cache this too else if (psources[sourcenum]->type == type_master) { source_data *s = psources[sourcenum]; if (s->last_update.wYear != 0 && !source_full_update) { d2 = s->last_update.wSecond + 60*(s->last_update.wMinute + 60*(s->last_update.wHour + 24*(s->last_update.wDay))); if (d1 > d2 && d1 < d2 + sb_sourcevalidity.value*60) continue; } total_masters++; } } // update master sources newsocket = UDP_OpenSocket(PORT_ANY); for (sourcenum = 0; sourcenum < psourcesn && !abort_ping; sourcenum++) { server_data *servers[MAX_SERVERS]; int serversn = 0; int trynum = 0; source_data *s = psources[sourcenum]; double timeout; if (psources[sourcenum]->type != type_master || !psources[sourcenum]->checked) continue; if (s->last_update.wYear != 0 && !source_full_update) { d2 = s->last_update.wSecond + 60*(s->last_update.wMinute + 60*(s->last_update.wHour + 24*(s->last_update.wDay))); if (d1 > d2 && d1 < d2 + sb_sourcevalidity.value*60) continue; } // send trynum queries to master server for (trynum=0; trynum < sb_masterretries.value; trynum++) { NetadrToSockadr (&(s->address.address), &server); ret = sendto (newsocket, request, sizeof(request), 0, (struct sockaddr *)&server, sizeof(server) ); } if (ret <= 0) continue; timeout = Sys_DoubleTime() + (sb_mastertimeout.value / 1000.0); while (Sys_DoubleTime() < timeout) { struct sockaddr_storage hostaddr; netadr_t from; //fd.fd_count = 1; //fd.fd_array[0] = newsocket; FD_ZERO(&fd); FD_SET(newsocket, &fd); tv.tv_sec = 0; tv.tv_usec = 1000 * sb_mastertimeout.value; ret = select(newsocket+1, &fd, NULL, NULL, &tv); // get answer i = sizeof(hostaddr); if (ret > 0) ret = recvfrom (newsocket, (char *) answer, 10000, 0, (struct sockaddr *)&hostaddr, (socklen_t *)&i); if (ret > 0 && ret < 10000) { SockadrToNetadr (&hostaddr, &from); if (from.ip[0] == s->address.address.ip[0] && from.ip[1] == s->address.address.ip[1] && from.ip[2] == s->address.address.ip[2] && from.ip[3] == s->address.address.ip[3] && from.port == s->address.address.port) { answer[ret] = 0; if (memcmp(answer, "\xff\xff\xff\xff\x64\x0a", 6)) { continue; } // create servers avoiding duplicates for (i=6; i+5 < ret; i+=6) { char buf[32]; server_data* server; qbool exists = false; int j; snprintf(buf, sizeof (buf), "%u.%u.%u.%u:%u", (int)answer[i+0], (int)answer[i+1], (int)answer[i+2], (int)answer[i+3], 256 * (int)answer[i+4] + (int)answer[i+5]); server = Create_Server(buf); for (j=0; j<serversn; j++) { if (NET_CompareAdr(servers[j]->address, server->address)) { exists = true; break; } } if (!exists) servers[serversn++] = server; else Delete_Server(server); } } } } // copy all servers to source list if (serversn > 0) { updated++; SB_ServerList_Lock(); Reset_Source(s); s->servers = (server_data **) Q_malloc(serversn * sizeof(server_data *)); for (i=0; i < serversn; i++) s->servers[i] = servers[i]; s->serversn = serversn; s->servers_allocated = serversn; if (s->checked) rebuild_servers_list = 1; GetLocalTime(&(s->last_update)); SB_ServerList_Unlock(); if (sb_mastercache.value) DumpSource(s); } ping_pos = updated / (double)total_masters; } closesocket(newsocket); // Not having this here leads to crash almost always when some // other action with servers list happens right after this function. // Even 1 ms delay was enough during the tests, previously 500 ms was used. //Sys_MSleep(100); updating_sources = 0; sb_queuedtriggers |= SB_TRIGGER_SOURCESUPDATED; return 0; }