|
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 00032 static FILE *logstream = NULL; 00033 00036 static const char *const loglevel_names[] = 00037 { 00038 "[Error] ", 00039 "[Bug] ", 00040 "[Debug] ", 00041 "[Info] " 00042 }; 00043 00049 void LOG(LogLevel logLevel, char *format, ...) 00050 { 00051 va_list ap; 00052 char buf[HUGE_BUF * 4]; 00053 00054 if (!logstream) 00055 { 00056 logstream = fopen_wrapper(LOG_FILE, "w"); 00057 } 00058 00059 va_start(ap, format); 00060 vsnprintf(buf, sizeof(buf), format, ap); 00061 va_end(ap); 00062 00063 fputs(loglevel_names[logLevel], stdout); 00064 fputs(buf, stdout); 00065 00066 if (logstream) 00067 { 00068 fputs(loglevel_names[logLevel], logstream); 00069 fputs(buf, logstream); 00070 fflush(logstream); 00071 } 00072 00073 if (logLevel == llevError) 00074 { 00075 LOG(llevInfo, "\nFatal error encountered. Exiting...\n"); 00076 system_end(); 00077 abort(); 00078 exit(-1); 00079 } 00080 } 00081 00084 void system_start() 00085 { 00086 SDL_Surface *icon; 00087 00088 icon = IMG_Load_wrapper(DIRECTORY_BITMAPS"/"CLIENT_ICON_NAME); 00089 00090 if (icon) 00091 { 00092 SDL_WM_SetIcon(icon, 0); 00093 SDL_FreeSurface(icon); 00094 } 00095 00096 SDL_WM_SetCaption(PACKAGE_NAME, PACKAGE_NAME); 00097 00098 logstream = fopen_wrapper(LOG_FILE, "w"); 00099 } 00100 00103 void system_end() 00104 { 00105 popup_destroy_visible(); 00106 list_remove_all(); 00107 script_killall(); 00108 save_interface_file(); 00109 kill_widgets(); 00110 curl_deinit(); 00111 socket_deinitialize(); 00112 sound_deinit(); 00113 free_bitmaps(); 00114 text_deinit(); 00115 free_help_files(); 00116 effects_deinit(); 00117 settings_deinit(); 00118 keybind_deinit(); 00119 SDL_Quit(); 00120 } 00121 00127 char *get_word_from_string(char *str, int *pos) 00128 { 00129 static char buf[HUGE_BUF]; 00130 int i = 0; 00131 00132 buf[0] = '\0'; 00133 00134 while (*(str + (*pos)) != '\0' && (!isalnum(*(str + (*pos))) && !isalpha(*(str + (*pos))))) 00135 { 00136 (*pos)++; 00137 } 00138 00139 /* Nothing left */ 00140 if (*(str + (*pos)) == '\0') 00141 { 00142 return NULL; 00143 } 00144 00145 /* Copy until end of string or whitespace */ 00146 while (*(str + (*pos)) != '\0' && (isalnum(*(str + (*pos))) || isalpha(*(str + (*pos))))) 00147 { 00148 buf[i++] = *(str + (*pos)++); 00149 } 00150 00151 buf[i] = '\0'; 00152 00153 return buf; 00154 } 00155 00162 static int mkdir_recurse(const char *path) 00163 { 00164 char *copy, *p; 00165 00166 p = copy = strdup(path); 00167 00168 do 00169 { 00170 p = strchr(p + 1, '/'); 00171 00172 if (p) 00173 { 00174 *p = '\0'; 00175 } 00176 00177 if (access(copy, F_OK) == -1) 00178 { 00179 if (mkdir(copy, 0755) == -1) 00180 { 00181 free(copy); 00182 return -1; 00183 } 00184 } 00185 00186 if (p) 00187 { 00188 *p = '/'; 00189 } 00190 } 00191 while (p); 00192 00193 free(copy); 00194 00195 return 0; 00196 } 00197 00202 void copy_file(const char *filename, const char *filename_out) 00203 { 00204 FILE *fp, *fp_out; 00205 char buf[HUGE_BUF], *stmp; 00206 00207 fp = fopen(filename, "r"); 00208 00209 if (!fp) 00210 { 00211 LOG(llevBug, "copy_file(): Failed to open '%s' for reading.\n", filename); 00212 return; 00213 } 00214 00215 stmp = strrchr(filename_out, '/'); 00216 00217 if (stmp) 00218 { 00219 char ctmp; 00220 00221 ctmp = stmp[0]; 00222 stmp[0] = '\0'; 00223 mkdir_recurse(filename_out); 00224 stmp[0] = ctmp; 00225 } 00226 00227 fp_out = fopen(filename_out, "w"); 00228 00229 if (!fp_out) 00230 { 00231 LOG(llevBug, "copy_file(): Failed to open '%s' for writing.\n", filename_out); 00232 fclose(fp); 00233 return; 00234 } 00235 00236 while (fgets(buf, sizeof(buf), fp)) 00237 { 00238 fputs(buf, fp_out); 00239 } 00240 00241 fclose(fp); 00242 fclose(fp_out); 00243 } 00244 00251 void copy_if_exists(const char *from, const char *to, const char *src, const char *dst) 00252 { 00253 char src_path[HUGE_BUF], dst_path[HUGE_BUF]; 00254 00255 snprintf(src_path, sizeof(src_path), "%s/%s", from, src); 00256 snprintf(dst_path, sizeof(dst_path), "%s/%s", to, dst); 00257 00258 if (access(src_path, R_OK) == 0) 00259 { 00260 copy_rec(src_path, dst_path); 00261 } 00262 } 00263 00269 void rmrf(const char *path) 00270 { 00271 DIR *dir; 00272 struct dirent *currentfile; 00273 char buf[HUGE_BUF]; 00274 struct stat st; 00275 00276 dir = opendir(path); 00277 00278 if (!dir) 00279 { 00280 return; 00281 } 00282 00283 while ((currentfile = readdir(dir))) 00284 { 00285 if (!strcmp(currentfile->d_name, ".") || !strcmp(currentfile->d_name, "..")) 00286 { 00287 continue; 00288 } 00289 00290 snprintf(buf, sizeof(buf), "%s/%s", path, currentfile->d_name); 00291 00292 if (stat(buf, &st) != 0) 00293 { 00294 continue; 00295 } 00296 00297 if (S_ISDIR(st.st_mode)) 00298 { 00299 rmrf(buf); 00300 } 00301 else if (S_ISREG(st.st_mode)) 00302 { 00303 unlink(buf); 00304 } 00305 } 00306 00307 closedir(dir); 00308 rmdir(path); 00309 } 00310 00315 void copy_rec(const char *src, const char *dst) 00316 { 00317 struct stat st; 00318 00319 /* Does it exist? */ 00320 if (stat(src, &st) != 0) 00321 { 00322 return; 00323 } 00324 00325 /* Copy directory contents. */ 00326 if (S_ISDIR(st.st_mode)) 00327 { 00328 DIR *dir; 00329 struct dirent *currentfile; 00330 char dir_src[HUGE_BUF], dir_dst[HUGE_BUF]; 00331 00332 dir = opendir(src); 00333 00334 if (!dir) 00335 { 00336 return; 00337 } 00338 00339 /* Try to make the new directory. */ 00340 if (access(dst, R_OK) != 0) 00341 { 00342 mkdir(dst, 0755); 00343 } 00344 00345 while ((currentfile = readdir(dir))) 00346 { 00347 if (currentfile->d_name[0] == '.') 00348 { 00349 continue; 00350 } 00351 00352 snprintf(dir_src, sizeof(dir_src), "%s/%s", src, currentfile->d_name); 00353 snprintf(dir_dst, sizeof(dir_dst), "%s/%s", dst, currentfile->d_name); 00354 copy_rec(dir_src, dir_dst); 00355 } 00356 00357 closedir(dir); 00358 } 00359 /* Copy file. */ 00360 else 00361 { 00362 copy_file(src, dst); 00363 } 00364 } 00365 00369 const char *get_config_dir() 00370 { 00371 const char *desc; 00372 00373 #ifdef LINUX 00374 desc = getenv("HOME"); 00375 #else 00376 desc = getenv("APPDATA"); 00377 #endif 00378 00379 /* Failed to find an usable destination, so store it in the 00380 * current directory. */ 00381 if (!desc || !*desc) 00382 { 00383 desc = "."; 00384 } 00385 00386 return desc; 00387 } 00388 00394 void get_data_dir_file(char *buf, size_t len, const char *fname) 00395 { 00396 /* Try the current directory first. */ 00397 snprintf(buf, len, "./%s", fname); 00398 00399 #ifdef INSTALL_SUBDIR_SHARE 00400 /* Not found, try the share directory since it was defined... */ 00401 if (access(buf, R_OK)) 00402 { 00403 char *prefix; 00404 00405 /* Get the prefix. */ 00406 prefix = br_find_prefix("./"); 00407 /* Construct the path. */ 00408 snprintf(buf, len, "%s/"INSTALL_SUBDIR_SHARE"/%s", prefix, fname); 00409 free(prefix); 00410 } 00411 #endif 00412 } 00413 00420 char *file_path(const char *fname, const char *mode) 00421 { 00422 static char tmp[HUGE_BUF]; 00423 char *stmp, ctmp, version[MAX_BUF]; 00424 00425 snprintf(tmp, sizeof(tmp), "%s/.atrinik/%s/%s", get_config_dir(), package_get_version_partial(version, sizeof(version)), fname); 00426 00427 if (strchr(mode, 'w')) 00428 { 00429 if ((stmp = strrchr(tmp, '/'))) 00430 { 00431 ctmp = stmp[0]; 00432 stmp[0] = '\0'; 00433 mkdir_recurse(tmp); 00434 stmp[0] = ctmp; 00435 } 00436 } 00437 else if (strchr(mode, '+') || strchr(mode, 'a')) 00438 { 00439 if (access(tmp, W_OK)) 00440 { 00441 char otmp[HUGE_BUF]; 00442 00443 get_data_dir_file(otmp, sizeof(otmp), fname); 00444 00445 if ((stmp = strrchr(tmp, '/'))) 00446 { 00447 ctmp = stmp[0]; 00448 stmp[0] = '\0'; 00449 mkdir_recurse(tmp); 00450 stmp[0] = ctmp; 00451 } 00452 00453 copy_file(otmp, tmp); 00454 } 00455 } 00456 else 00457 { 00458 if (access(tmp, R_OK)) 00459 { 00460 get_data_dir_file(tmp, sizeof(tmp), fname); 00461 } 00462 } 00463 00464 return tmp; 00465 } 00466 00482 FILE *fopen_wrapper(const char *fname, const char *mode) 00483 { 00484 return fopen(file_path(fname, mode), mode); 00485 } 00486 00491 SDL_Surface *IMG_Load_wrapper(const char *file) 00492 { 00493 return IMG_Load(file_path(file, "r")); 00494 } 00495 00501 TTF_Font *TTF_OpenFont_wrapper(const char *file, int ptsize) 00502 { 00503 return TTF_OpenFont(file_path(file, "r"), ptsize); 00504 }
1.7.4