00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <unistd.h>
00027 #include <sys/time.h>
00028 #include <stdlib.h>
00029 #include <sys/stat.h>
00030 #include <sys/types.h>
00031 #include <pwd.h>
00032 #include <dlfcn.h>
00033 #include <fcntl.h>
00034 #include <locale.h>
00035 #include <signal.h>
00036 #include <dirent.h>
00037
00038 #include "../../common/common.h"
00039 #include "../system.h"
00040
00041 #ifdef HAVE_EXECINFO_H
00042 #include <execinfo.h>
00043 #define MAX_BACKTRACE_SYMBOLS 50
00044 #endif
00045
00046 const char *Sys_GetCurrentUser (void)
00047 {
00048 static char s_userName[MAX_VAR];
00049 struct passwd *p;
00050
00051 if ((p = getpwuid(getuid())) == NULL)
00052 s_userName[0] = '\0';
00053 else {
00054 strncpy(s_userName, p->pw_name, sizeof(s_userName));
00055 s_userName[sizeof(s_userName) - 1] = '\0';
00056 }
00057 return s_userName;
00058 }
00059
00063 char *Sys_Cwd (void)
00064 {
00065 static char cwd[MAX_OSPATH];
00066
00067 if (getcwd(cwd, sizeof(cwd) - 1) == NULL)
00068 return NULL;
00069 cwd[MAX_OSPATH - 1] = 0;
00070
00071 return cwd;
00072 }
00073
00079 void Sys_Error (const char *error, ...)
00080 {
00081 va_list argptr;
00082 char string[1024];
00083
00084 Sys_Backtrace();
00085
00086 #ifdef COMPILE_UFO
00087 Sys_ConsoleShutdown();
00088 #endif
00089
00090
00091 fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
00092
00093 #ifdef COMPILE_MAP
00094 Mem_Shutdown();
00095 #endif
00096
00097 va_start(argptr,error);
00098 Q_vsnprintf(string, sizeof(string), error, argptr);
00099 va_end(argptr);
00100
00101 fprintf(stderr, "Error: %s\n", string);
00102
00103 exit(1);
00104 }
00105
00110 void Sys_Quit (void)
00111 {
00112 #ifdef COMPILE_UFO
00113 CL_Shutdown();
00114 Qcommon_Shutdown();
00115 Sys_ConsoleShutdown();
00116 #elif COMPILE_MAP
00117 Mem_Shutdown();
00118 #endif
00119
00120 fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) & ~FNDELAY);
00121 exit(0);
00122 }
00123
00124 void Sys_Sleep (int milliseconds)
00125 {
00126 #if 0
00127 struct timespec sleep, remaining;
00128 sleep.tv_sec = (long) milliseconds / 1000;
00129 sleep.tv_nsec = 1000000 * (milliseconds - (long) milliseconds);
00130 while (nanosleep(&sleep, &remaining) < 0 && errno == EINTR)
00131
00132
00133 sleep = remaining;
00134 #endif
00135 if (milliseconds < 1)
00136 milliseconds = 1;
00137 usleep(milliseconds * 1000);
00138 }
00139
00140 #ifdef COMPILE_UFO
00141 const char *Sys_SetLocale (const char *localeID)
00142 {
00143 const char *locale;
00144
00145 # ifndef __sun
00146 unsetenv("LANGUAGE");
00147 # endif
00148 # ifdef __APPLE__
00149 if (localeID[0] != '\0') {
00150 if (Sys_Setenv("LANGUAGE", localeID) != 0)
00151 Com_Printf("...setenv for LANGUAGE failed: %s\n", localeID);
00152 if (Sys_Setenv("LC_ALL", localeID) != 0)
00153 Com_Printf("...setenv for LC_ALL failed: %s\n", localeID);
00154 }
00155 # endif
00156
00157
00158 setlocale(LC_ALL, "C");
00159 locale = setlocale(LC_MESSAGES, localeID);
00160 if (!locale) {
00161 Com_DPrintf(DEBUG_CLIENT, "...could not set to language: %s\n", localeID);
00162 locale = setlocale(LC_MESSAGES, "");
00163 if (!locale) {
00164 Com_DPrintf(DEBUG_CLIENT, "...could not set to system language\n");
00165 }
00166 return NULL;
00167 } else {
00168 Com_Printf("...using language: %s\n", locale);
00169 }
00170
00171 return locale;
00172 }
00173
00174 const char *Sys_GetLocale (void)
00175 {
00176
00177 const char *currentLocale = setlocale(LC_MESSAGES, NULL);
00178 if (currentLocale != NULL && currentLocale[0] != '\0')
00179 return currentLocale;
00180 else
00181 return "C";
00182 }
00183 #endif
00184
00188 int Sys_Setenv (const char *name, const char *value)
00189 {
00190 if (value && value[0] != '\0')
00191 return setenv(name, value, 1);
00192 else
00193 return unsetenv(name);
00194 }
00195
00200 char *Sys_GetHomeDirectory (void)
00201 {
00202 return getenv("HOME");
00203 }
00204
00205 void Sys_NormPath (char* path)
00206 {
00207 }
00208
00209 static char findbase[MAX_OSPATH];
00210 static char findpath[MAX_OSPATH];
00211 static char findpattern[MAX_OSPATH];
00212 static DIR *fdir;
00213
00214 static qboolean CompareAttributes (const char *path, const char *name, unsigned musthave, unsigned canthave)
00215 {
00216 struct stat st;
00217 char fn[MAX_OSPATH];
00218
00219
00220 if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
00221 return qfalse;
00222
00223 Com_sprintf(fn, sizeof(fn), "%s/%s", path, name);
00224 if (stat(fn, &st) == -1) {
00225 Com_Printf("CompareAttributes: Warning, stat failed: %s\n", name);
00226 return qfalse;
00227 }
00228
00229 if ((st.st_mode & S_IFDIR) && (canthave & SFF_SUBDIR))
00230 return qfalse;
00231
00232 if ((musthave & SFF_SUBDIR) && !(st.st_mode & S_IFDIR))
00233 return qfalse;
00234
00235 return qtrue;
00236 }
00237
00243 char *Sys_FindFirst (const char *path, unsigned musthave, unsigned canhave)
00244 {
00245 struct dirent *d;
00246 char *p;
00247
00248 if (fdir)
00249 Sys_Error("Sys_BeginFind without close");
00250
00251 Q_strncpyz(findbase, path, sizeof(findbase));
00252
00253 if ((p = strrchr(findbase, '/')) != NULL) {
00254 *p = 0;
00255 Q_strncpyz(findpattern, p + 1, sizeof(findpattern));
00256 } else
00257 Q_strncpyz(findpattern, "*", sizeof(findpattern));
00258
00259 if (strcmp(findpattern, "*.*") == 0)
00260 Q_strncpyz(findpattern, "*", sizeof(findpattern));
00261
00262 if ((fdir = opendir(findbase)) == NULL)
00263 return NULL;
00264
00265 while ((d = readdir(fdir)) != NULL) {
00266 if (!*findpattern || Com_Filter(findpattern, d->d_name)) {
00267 if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
00268 Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, d->d_name);
00269 return findpath;
00270 }
00271 }
00272 }
00273 return NULL;
00274 }
00275
00282 char *Sys_FindNext (unsigned musthave, unsigned canhave)
00283 {
00284 struct dirent *d;
00285
00286 if (fdir == NULL)
00287 return NULL;
00288 while ((d = readdir(fdir)) != NULL) {
00289 if (!*findpattern || Com_Filter(findpattern, d->d_name)) {
00290 if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
00291 Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, d->d_name);
00292 return findpath;
00293 }
00294 }
00295 }
00296 return NULL;
00297 }
00298
00299 void Sys_FindClose (void)
00300 {
00301 if (fdir != NULL)
00302 closedir(fdir);
00303 fdir = NULL;
00304 }
00305
00306 #define MAX_FOUND_FILES 0x1000
00307
00308 void Sys_ListFilteredFiles (const char *basedir, const char *subdirs, const char *filter, linkedList_t **list)
00309 {
00310 char search[MAX_OSPATH], newsubdirs[MAX_OSPATH];
00311 char filename[MAX_OSPATH];
00312 DIR *fdir;
00313 struct dirent *d;
00314 struct stat st;
00315
00316 if (subdirs[0] != '\0') {
00317 Com_sprintf(search, sizeof(search), "%s/%s", basedir, subdirs);
00318 } else {
00319 Com_sprintf(search, sizeof(search), "%s", basedir);
00320 }
00321
00322 if ((fdir = opendir(search)) == NULL)
00323 return;
00324
00325 while ((d = readdir(fdir)) != NULL) {
00326 Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name);
00327 if (stat(filename, &st) == -1)
00328 continue;
00329
00330 if (st.st_mode & S_IFDIR) {
00331 if (Q_strcasecmp(d->d_name, ".") && Q_strcasecmp(d->d_name, "..")) {
00332 if (subdirs[0] != '\0') {
00333 Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s/%s", subdirs, d->d_name);
00334 } else {
00335 Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", d->d_name);
00336 }
00337 Sys_ListFilteredFiles(basedir, newsubdirs, filter, list);
00338 }
00339 }
00340 Com_sprintf(filename, sizeof(filename), "%s/%s", subdirs, d->d_name);
00341 if (!Com_Filter(filter, filename))
00342 continue;
00343 LIST_AddString(list, filename);
00344 }
00345
00346 closedir(fdir);
00347 }
00348
00349 #ifdef COMPILE_UFO
00350 void Sys_SetAffinityAndPriority (void)
00351 {
00352 if (sys_affinity->modified) {
00353 sys_affinity->modified = qfalse;
00354 }
00355
00356 if (sys_priority->modified) {
00357 sys_priority->modified = qfalse;
00358 }
00359 }
00360 #endif
00361
00362 int Sys_Milliseconds (void)
00363 {
00364 struct timeval tp;
00365 struct timezone tzp;
00366 static int secbase = 0;
00367
00368 gettimeofday(&tp, &tzp);
00369
00370 if (!secbase) {
00371 secbase = tp.tv_sec;
00372 return tp.tv_usec / 1000;
00373 }
00374
00375 return (tp.tv_sec - secbase) * 1000 + tp.tv_usec / 1000;
00376 }
00377
00378 void Sys_Mkdir (const char *thePath)
00379 {
00380 if (mkdir(thePath, 0777) != -1)
00381 return;
00382
00383 if (errno != EEXIST)
00384 Com_Printf("\"mkdir %s\" failed, reason: \"%s\".", thePath, strerror(errno));
00385 }
00386
00390 void Sys_Backtrace (void)
00391 {
00392 #ifdef HAVE_EXECINFO_H
00393 void *symbols[MAX_BACKTRACE_SYMBOLS];
00394 const int i = backtrace(symbols, MAX_BACKTRACE_SYMBOLS);
00395 backtrace_symbols_fd(symbols, i, STDERR_FILENO);
00396 #endif
00397 }
00398
00399 #if USE_SIGNALS
00400
00403 static void Sys_Signal (int s)
00404 {
00405 switch (s) {
00406 case SIGHUP:
00407 case SIGINT:
00408 case SIGQUIT:
00409 case SIGTERM:
00410 Com_Printf("Received signal %d, quitting..\n", s);
00411 Sys_Quit();
00412 break;
00413 default:
00414 Sys_Backtrace();
00415 Sys_Error("Received signal %d.\n", s);
00416 break;
00417 }
00418 }
00419 #endif
00420
00421 void Sys_InitSignals (void)
00422 {
00423 #if USE_SIGNALS
00424 signal(SIGHUP, Sys_Signal);
00425 signal(SIGINT, Sys_Signal);
00426 signal(SIGQUIT, Sys_Signal);
00427 signal(SIGILL, Sys_Signal);
00428 signal(SIGABRT, Sys_Signal);
00429 signal(SIGFPE, Sys_Signal);
00430 signal(SIGSEGV, Sys_Signal);
00431 signal(SIGTERM, Sys_Signal);
00432 #endif
00433 }