UFO: Alien Invasion
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
unix_files.cpp
Go to the documentation of this file.
1 
6 /*
7 Copyright (C) 2002-2020 UFO: Alien Invasion.
8 
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
13 
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17 
18 See the GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 
24 */
25 
26 #include <unistd.h>
27 #include <sys/time.h>
28 #include <stdlib.h>
29 #include <sys/stat.h>
30 #include <sys/types.h>
31 #include <pwd.h>
32 #include <dlfcn.h>
33 #include <fcntl.h>
34 #include <locale.h>
35 #include <signal.h>
36 #include <dirent.h>
37 
38 #include "../../common/common.h"
39 #include "../system.h"
40 
46 {
47  return getenv("HOME");
48 }
49 
50 void Sys_NormPath (char* path)
51 {
52 }
53 
54 static char findbase[MAX_OSPATH];
55 static char findpath[MAX_OSPATH];
56 static char findpattern[MAX_OSPATH];
57 static DIR* fdir;
58 
59 static bool CompareAttributes (const char* path, const char* name, unsigned musthave, unsigned canthave)
60 {
61  /* . and .. never match */
62  if (Q_streq(name, ".") || Q_streq(name, ".."))
63  return false;
64 
65  char fn[MAX_OSPATH];
66  Com_sprintf(fn, sizeof(fn), "%s/%s", path, name);
67  struct stat st;
68  if (stat(fn, &st) == -1) {
69  Com_Printf("CompareAttributes: Warning, stat failed: %s\n", name);
70  return false; /* shouldn't happen */
71  }
72 
73  if ((st.st_mode & S_IFDIR) && (canthave & SFF_SUBDIR))
74  return false;
75 
76  if ((musthave & SFF_SUBDIR) && !(st.st_mode & S_IFDIR))
77  return false;
78 
79  return true;
80 }
81 
87 char* Sys_FindFirst (const char* path, unsigned musthave, unsigned canhave)
88 {
89  if (fdir)
90  Sys_Error("Sys_BeginFind without close");
91 
92  Q_strncpyz(findbase, path, sizeof(findbase));
93 
94  char* p;
95  if ((p = strrchr(findbase, '/')) != nullptr) {
96  *p = 0;
97  Q_strncpyz(findpattern, p + 1, sizeof(findpattern));
98  } else
99  Q_strncpyz(findpattern, "*", sizeof(findpattern));
100 
101  if (Q_streq(findpattern, "*.*"))
102  Q_strncpyz(findpattern, "*", sizeof(findpattern));
103 
104  if ((fdir = opendir(findbase)) == nullptr)
105  return nullptr;
106 
107  const struct dirent* d;
108  while ((d = readdir(fdir)) != nullptr) {
109  if (!*findpattern || Com_Filter(findpattern, d->d_name)) {
110  if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
111  Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, d->d_name);
112  return findpath;
113  }
114  }
115  }
116  return nullptr;
117 }
118 
125 char* Sys_FindNext (unsigned musthave, unsigned canhave)
126 {
127  if (fdir == nullptr)
128  return nullptr;
129 
130  const struct dirent* d;
131  while ((d = readdir(fdir)) != nullptr) {
132  if (!*findpattern || Com_Filter(findpattern, d->d_name)) {
133  if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
134  Com_sprintf(findpath, sizeof(findpath), "%s/%s", findbase, d->d_name);
135  return findpath;
136  }
137  }
138  }
139  return nullptr;
140 }
141 
142 void Sys_FindClose (void)
143 {
144  if (fdir != nullptr)
145  closedir(fdir);
146  fdir = nullptr;
147 }
148 
149 #define MAX_FOUND_FILES 0x1000
150 
151 void Sys_ListFilteredFiles (const char* basedir, const char* subdirs, const char* filter, linkedList_t** list)
152 {
153  char search[MAX_OSPATH];
154 
155  if (subdirs[0] != '\0') {
156  Com_sprintf(search, sizeof(search), "%s/%s", basedir, subdirs);
157  } else {
158  Com_sprintf(search, sizeof(search), "%s", basedir);
159  }
160 
161  DIR* directory;
162  if ((directory = opendir(search)) == nullptr)
163  return;
164 
165  char filename[MAX_OSPATH];
166  const struct dirent* d;
167  struct stat st;
168 
169  while ((d = readdir(directory)) != nullptr) {
170  Com_sprintf(filename, sizeof(filename), "%s/%s", search, d->d_name);
171  if (stat(filename, &st) == -1)
172  continue;
173 
174  if (st.st_mode & S_IFDIR) {
175  char newsubdirs[MAX_OSPATH];
176  if (Q_strcasecmp(d->d_name, ".") && Q_strcasecmp(d->d_name, "..")) {
177  if (subdirs[0] != '\0') {
178  Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s/%s", subdirs, d->d_name);
179  } else {
180  Com_sprintf(newsubdirs, sizeof(newsubdirs), "%s", d->d_name);
181  }
182  Sys_ListFilteredFiles(basedir, newsubdirs, filter, list);
183  }
184  }
185  Com_sprintf(filename, sizeof(filename), "%s/%s", subdirs, d->d_name);
186  if (!Com_Filter(filter, filename))
187  continue;
188  LIST_AddString(list, filename);
189  }
190 
191  closedir(directory);
192 }
193 
197 char* Sys_Cwd (void)
198 {
199  static char cwd[MAX_OSPATH];
200 
201  if (getcwd(cwd, sizeof(cwd) - 1) == nullptr)
202  return nullptr;
203  cwd[MAX_OSPATH - 1] = 0;
204 
205  return cwd;
206 }
207 
208 void Sys_Mkdir (const char* thePath)
209 {
210  if (mkdir(thePath, 0777) != -1)
211  return;
212 
213  if (errno != EEXIST)
214  Com_Printf("\"mkdir %s\" failed, reason: \"%s\".", thePath, strerror(errno));
215 }
216 
217 void Sys_Mkfifo (const char* ospath, qFILE* f)
218 {
219  struct stat buf;
220 
221  /* if file already exists AND is a pipefile, remove it */
222  if (!stat(ospath, &buf) && S_ISFIFO(buf.st_mode))
223  FS_RemoveFile(ospath);
224 
225  const int result = mkfifo(ospath, 0600);
226  if (result != 0)
227  return;
228 
229  FILE* fifo = Sys_Fopen(ospath, "w+");
230  if (fifo) {
231  const int fn = fileno(fifo);
232  fcntl(fn, F_SETFL, O_NONBLOCK);
233  f->f = fifo;
234  } else {
235  Com_Printf("WARNING: Could not create fifo pipe at %s.\n", ospath);
236  f->f = nullptr;
237  }
238 }
239 
240 FILE* Sys_Fopen (const char* filename, const char* mode)
241 {
242  return fopen(filename, mode);
243 }
244 
245 int Sys_Remove (const char* filename)
246 {
247  return remove(filename);
248 }
249 
250 int Sys_Rename (const char* oldname, const char* newname)
251 {
252  return rename(oldname, newname);
253 }
254 
255 int Sys_Access (const char* filename, int mode)
256 {
257  return access(filename, mode);
258 }
FILE * Sys_Fopen(const char *filename, const char *mode)
Definition: unix_files.cpp:240
void Sys_Error(const char *error,...)
Definition: g_main.cpp:421
void Sys_ListFilteredFiles(const char *basedir, const char *subdirs, const char *filter, linkedList_t **list)
Definition: unix_files.cpp:151
char * Sys_FindNext(unsigned musthave, unsigned canhave)
Returns the next file of the already opened directory (Sys_FindFirst) that matches our search mask...
Definition: unix_files.cpp:125
int Sys_Access(const char *filename, int mode)
Definition: unix_files.cpp:255
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition: shared.cpp:494
const char * filename
Definition: ioapi.h:41
#define FILE
Definition: test_webapi.cpp:30
void FS_RemoveFile(const char *osPath)
Definition: files.cpp:1690
static DIR * fdir
Definition: unix_files.cpp:57
#define MAX_OSPATH
Definition: filesys.h:44
void Com_Printf(const char *const fmt,...)
Definition: common.cpp:386
static char findbase[MAX_OSPATH]
Definition: unix_files.cpp:54
#define SFF_SUBDIR
Definition: filesys.h:126
int Sys_Rename(const char *oldname, const char *newname)
Definition: unix_files.cpp:250
static char findpath[MAX_OSPATH]
Definition: unix_files.cpp:55
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition: shared.cpp:457
void LIST_AddString(linkedList_t **listDest, const char *data)
Adds an string to a new or to an already existing linked list. The string is copied here...
Definition: list.cpp:139
int Com_Filter(const char *pattern, const char *text)
Match the pattern PATTERN against the string TEXT;.
Definition: shared.cpp:145
void Sys_Mkdir(const char *thePath)
Definition: unix_files.cpp:208
void Sys_FindClose(void)
Definition: unix_files.cpp:142
char * Sys_FindFirst(const char *path, unsigned musthave, unsigned canhave)
Opens the directory and returns the first file that matches our searchrules.
Definition: unix_files.cpp:87
static char findpattern[MAX_OSPATH]
Definition: unix_files.cpp:56
#define Q_strcasecmp(a, b)
Definition: shared.h:131
char * Sys_GetHomeDirectory(void)
Returns the home environment variable (which hold the path of the user's homedir) ...
Definition: unix_files.cpp:45
QGL_EXTERN GLfloat f
Definition: r_gl.h:114
int Sys_Remove(const char *filename)
Definition: unix_files.cpp:245
void Sys_Mkfifo(const char *ospath, qFILE *f)
Definition: unix_files.cpp:217
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition: r_gl.h:110
const char int mode
Definition: ioapi.h:41
static bool CompareAttributes(const char *path, const char *name, unsigned musthave, unsigned canthave)
Definition: unix_files.cpp:59
void Sys_NormPath(char *path)
Definition: unix_files.cpp:50
#define Q_streq(a, b)
Definition: shared.h:136
char * Sys_Cwd(void)
Definition: unix_files.cpp:197
FILE * f
Definition: filesys.h:56