|
Atrinik Client 2.5
|
00001 /************************************************************************ 00002 * Atrinik, a Multiplayer Online Role Playing Game * 00003 * * 00004 * Copyright (C) 2009-2011 Alex Tokar and Atrinik Development Team * 00005 * * 00006 * Fork from Daimonin (Massive Multiplayer Online Role Playing Game) * 00007 * and Crossfire (Multiplayer game for X-windows). * 00008 * * 00009 * This program is free software; you can redistribute it and/or modify * 00010 * it under the terms of the GNU General Public License as published by * 00011 * the Free Software Foundation; either version 2 of the License, or * 00012 * (at your option) any later version. * 00013 * * 00014 * This program is distributed in the hope that it will be useful, * 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00017 * GNU General Public License for more details. * 00018 * * 00019 * You should have received a copy of the GNU General Public License * 00020 * along with this program; if not, write to the Free Software * 00021 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 00022 * * 00023 * The author can be reached at admin@atrinik.org * 00024 ************************************************************************/ 00025 00030 #include <global.h> 00031 00036 static size_t file_updates_requested = 0; 00037 00041 static void file_updates_request(char *filename) 00042 { 00043 SockList sl; 00044 unsigned char buf[HUGE_BUF]; 00045 00046 sl.buf = buf; 00047 sl.len = 0; 00048 SockList_AddString(&sl, "upf "); 00049 SockList_AddString(&sl, filename); 00050 send_socklist(sl); 00051 00052 file_updates_requested++; 00053 } 00054 00060 void cmd_request_update(unsigned char *data, int len) 00061 { 00062 char filename[MAX_BUF], c; 00063 size_t pos = 0, i = 0; 00064 unsigned long ucomp_len; 00065 unsigned char *dest; 00066 FILE *fp; 00067 00068 filename[0] = '\0'; 00069 file_updates_requested--; 00070 00071 while ((c = (char) (data[pos++]))) 00072 { 00073 filename[i++] = c; 00074 } 00075 00076 filename[i] = '\0'; 00077 len -= i; 00078 ucomp_len = GetInt_String(data + pos); 00079 pos += 4; 00080 len -= 4; 00081 00082 /* Uncompress it. */ 00083 dest = malloc(ucomp_len); 00084 uncompress((Bytef *) dest, (uLongf *) &ucomp_len, (const Bytef *) data + pos, (uLong) len); 00085 data = dest; 00086 len = ucomp_len; 00087 00088 fp = fopen_wrapper(filename, "wb"); 00089 00090 if (!fp) 00091 { 00092 LOG(llevBug, "Could not open file '%s' for writing.\n", filename); 00093 free(dest); 00094 return; 00095 } 00096 00097 /* Update the file. */ 00098 fwrite(data, 1, len, fp); 00099 fclose(fp); 00100 free(dest); 00101 LOG(llevInfo, "Updated file '%s'.\n", filename); 00102 } 00103 00107 int file_updates_finished() 00108 { 00109 return file_updates_requested == 0; 00110 } 00111 00114 void file_updates_parse() 00115 { 00116 FILE *fp; 00117 char buf[HUGE_BUF]; 00118 00119 /* Is the feature disabled? */ 00120 if (setting_get_int(OPT_CAT_CLIENT, OPT_DISABLE_FILE_UPDATES)) 00121 { 00122 return; 00123 } 00124 00125 fp = server_file_open(SERVER_FILE_UPDATES); 00126 00127 if (!fp) 00128 { 00129 return; 00130 } 00131 00132 while (fgets(buf, sizeof(buf) - 1, fp)) 00133 { 00134 char filename[MAX_BUF], crc_buf[MAX_BUF], *contents; 00135 uint64 size; 00136 size_t st_size, numread; 00137 FILE *fp2; 00138 unsigned long crc; 00139 struct stat sb; 00140 00141 if (sscanf(buf, "%s %"FMT64U" %s", filename, &size, crc_buf) != 3) 00142 { 00143 continue; 00144 } 00145 00146 fp2 = fopen_wrapper(filename, "rb"); 00147 00148 /* No such file? Then we'll want to update this. */ 00149 if (!fp2) 00150 { 00151 file_updates_request(filename); 00152 continue; 00153 } 00154 00155 fstat(fileno(fp2), &sb); 00156 st_size = sb.st_size; 00157 contents = malloc(st_size); 00158 numread = fread(contents, 1, st_size, fp2); 00159 fclose(fp2); 00160 00161 /* Get the CRC32... */ 00162 crc = crc32(1L, (const unsigned char FAR *) contents, numread); 00163 free(contents); 00164 00165 /* If the checksum or the size doesn't match, we'll want to update it. */ 00166 if (crc != strtoul(crc_buf, NULL, 16) || st_size != (size_t) size) 00167 { 00168 file_updates_request(filename); 00169 } 00170 } 00171 00172 fclose(fp); 00173 }
1.7.4