static int server_process(int sockfd) { t_list * serverlist_head; t_elem * curr; t_server * server; struct sockaddr_in cliaddr; t_psock_fd_set rfds; struct timeval tv; time_t last; FILE * outfile; psock_t_socklen len; t_trackpacket packet; if (!(serverlist_head = list_create())) { eventlog(eventlog_level_error,__FUNCTION__,"could not create server list"); return -1; } /* the main loop */ last = time(NULL) - prefs.update; for (;;) { /* time to dump our list to disk and call the process command */ /* (I'm making the assumption that this won't take very long.) */ if (last+(signed)prefs.update<time(NULL)) { last = time(NULL); if (!(outfile = fopen(prefs.outfile,"w"))) { eventlog(eventlog_level_error,__FUNCTION__,"unable to open file \"%s\" for writing (fopen: %s)",prefs.outfile,pstrerror(errno)); continue; } LIST_TRAVERSE(serverlist_head,curr) { server = elem_get_data(curr); if (server->updated+(signed)prefs.expire<last) { list_remove_elem(serverlist_head,&curr); xfree(server); } else { if (prefs.XML_mode == 1) { fprintf(outfile,"<server>\n\t<address>%s</address>\n",inet_ntoa(server->address)); fprintf(outfile,"\t<port>%hu</port>\n",bn_short_nget(server->info.port)); fprintf(outfile,"\t<location>%s</location>\n",server->info.server_location); fprintf(outfile,"\t<software>%s</software>\n",server->info.software); fprintf(outfile,"\t<version>%s</version>\n",server->info.version); fprintf(outfile,"\t<users>%lu</users>\n",bn_int_nget(server->info.users)); fprintf(outfile,"\t<channels>%lu</channels>\n",bn_int_nget(server->info.channels)); fprintf(outfile,"\t<games>%lu</games>\n",bn_int_nget(server->info.games)); fprintf(outfile,"\t<description>%s</description>\n",server->info.server_desc); fprintf(outfile,"\t<platform>%s</platform>\n",server->info.platform); fprintf(outfile,"\t<url>%s</url>\n",server->info.server_url); fprintf(outfile,"\t<contact_name>%s</contact_name>\n",server->info.contact_name); fprintf(outfile,"\t<contact_email>%s</contact_email>\n",server->info.contact_email); fprintf(outfile,"\t<uptime>%lu</uptime>\n",bn_int_nget(server->info.uptime)); fprintf(outfile,"\t<total_games>%lu</total_games>\n",bn_int_nget(server->info.total_games)); fprintf(outfile,"\t<logins>%lu</logins>\n",bn_int_nget(server->info.total_logins)); fprintf(outfile,"</server>\n"); } else { fprintf(outfile,"%s\n##\n",inet_ntoa(server->address)); fprintf(outfile,"%hu\n##\n",bn_short_nget(server->info.port)); fprintf(outfile,"%s\n##\n",server->info.server_location); fprintf(outfile,"%s\n##\n",server->info.software); fprintf(outfile,"%s\n##\n",server->info.version); fprintf(outfile,"%lu\n##\n",bn_int_nget(server->info.users)); fprintf(outfile,"%lu\n##\n",bn_int_nget(server->info.channels)); fprintf(outfile,"%lu\n##\n",bn_int_nget(server->info.games)); fprintf(outfile,"%s\n##\n",server->info.server_desc); fprintf(outfile,"%s\n##\n",server->info.platform); fprintf(outfile,"%s\n##\n",server->info.server_url); fprintf(outfile,"%s\n##\n",server->info.contact_name); fprintf(outfile,"%s\n##\n",server->info.contact_email); fprintf(outfile,"%lu\n##\n",bn_int_nget(server->info.uptime)); fprintf(outfile,"%lu\n##\n",bn_int_nget(server->info.total_games)); fprintf(outfile,"%lu\n##\n",bn_int_nget(server->info.total_logins)); fprintf(outfile,"###\n"); } } } if (fclose(outfile)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not close output file \"%s\" after writing (fclose: %s)",prefs.outfile,pstrerror(errno)); if (prefs.process[0]!='\0') system(prefs.process); }
/* size of the _complete_ packet, not the amount currently received or sent */ extern unsigned int packet_get_size(t_packet const * packet) { unsigned int size; if (!packet) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet"); return 0; } switch (packet->pclass) { case packet_class_init: size = sizeof(t_client_initconn); break; case packet_class_bnet: size = (unsigned int)bn_short_get(packet->u.bnet.h.size); break; case packet_class_file: size = (unsigned int)bn_short_get(packet->u.file.h.size); break; case packet_class_udp: size = packet->len; break; case packet_class_raw: size = packet->len; break; case packet_class_d2game: size = packet->len; /* FIXME: does header not contain the size? */ break; case packet_class_d2gs: size = (unsigned int)bn_short_get(packet->u.d2cs_d2gs.h.size); break; case packet_class_d2cs_bnetd: size = (unsigned int)bn_short_get(packet->u.d2cs_bnetd.h.size); break; case packet_class_d2cs: size = (unsigned int)bn_short_get(packet->u.d2cs_client.h.size); break; case packet_class_w3route: size = (unsigned int)bn_short_get(packet->u.w3route.h.size); break; case packet_class_wolgameres: /* PELISH: We check and return size explicitly in this case, because we need to check MAX_WOL_GAMERES_PACKET_SIZE */ { size = (unsigned int)bn_short_nget(packet->u.wolgameres.h.size); if (size == 0) /* RNGD sends size on rngd_size */ size = (unsigned int)bn_short_nget(packet->u.wolgameres.h.rngd_size); // if (size>MAX_WOL_GAMERES_PACKET_SIZE) { /* PELISH: Fix for bug but also disable WOL gameres */ if (size>MAX_PACKET_SIZE) { // eventlog(eventlog_level_error,__FUNCTION__,"packet has bad size %u",size); return 0; } } return size; default: eventlog(eventlog_level_error,__FUNCTION__,"packet has invalid class %d",(int)packet->pclass); return 0; } if (size>MAX_PACKET_SIZE) { eventlog(eventlog_level_error,__FUNCTION__,"packet has bad size %u",size); return 0; } return size; }