UFO: Alien Invasion
Loading...
Searching...
No Matches
unix_files.cpp
Go to the documentation of this file.
1
5
6/*
7Copyright (C) 2002-2025 UFO: Alien Invasion.
8
9This program is free software; you can redistribute it and/or
10modify it under the terms of the GNU General Public License
11as published by the Free Software Foundation; either version 2
12of the License, or (at your option) any later version.
13
14This program is distributed in the hope that it will be useful,
15but WITHOUT ANY WARRANTY; without even the implied warranty of
16MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
17
18See the GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software
22Foundation, 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
50void Sys_NormPath (char* path)
51{
52}
53
54static char findbase[MAX_OSPATH];
55static char findpath[MAX_OSPATH];
57static DIR* fdir;
58
59static 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
87char* 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
125char* 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
142void Sys_FindClose (void)
143{
144 if (fdir != nullptr)
145 closedir(fdir);
146 fdir = nullptr;
147}
148
149#define MAX_FOUND_FILES 0x1000
150
151void 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;
189 }
190
191 closedir(directory);
192}
193
197char* 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
208void 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
217void 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
240FILE* Sys_Fopen (const char* filename, const char* mode)
241{
242 return fopen(filename, mode);
243}
244
245int Sys_Remove (const char* filename)
246{
247 return remove(filename);
248}
249
250int Sys_Rename (const char* oldname, const char* newname)
251{
252 return rename(oldname, newname);
253}
254
255int Sys_Access (const char* filename, int mode)
256{
257 return access(filename, mode);
258}
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
definitions common between client and server, but not game lib
void FS_RemoveFile(const char *osPath)
Definition files.cpp:1692
#define MAX_OSPATH
Definition filesys.h:44
#define SFF_SUBDIR
Definition filesys.h:126
void Sys_Error(const char *error,...)
Definition g_main.cpp:421
const char * filename
Definition ioapi.h:41
voidpf void * buf
Definition ioapi.h:42
const char int mode
Definition ioapi.h:41
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
QGL_EXTERN GLfloat f
Definition r_gl.h:114
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
Definition r_gl.h:110
#define Q_strcasecmp(a, b)
Definition shared.h:131
#define Q_streq(a, b)
Definition shared.h:136
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
Definition shared.cpp:457
int Com_Filter(const char *pattern, const char *text)
Match the pattern PATTERN against the string TEXT;.
Definition shared.cpp:145
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
Definition shared.cpp:494
System specific stuff.
#define FILE
char * Sys_Cwd(void)
static char findbase[MAX_OSPATH]
char * Sys_FindFirst(const char *path, unsigned musthave, unsigned canhave)
Opens the directory and returns the first file that matches our searchrules.
void Sys_NormPath(char *path)
FILE * Sys_Fopen(const char *filename, const char *mode)
static char findpath[MAX_OSPATH]
int Sys_Remove(const char *filename)
int Sys_Rename(const char *oldname, const char *newname)
char * Sys_GetHomeDirectory(void)
Returns the home environment variable (which hold the path of the user's homedir).
void Sys_ListFilteredFiles(const char *basedir, const char *subdirs, const char *filter, linkedList_t **list)
static bool CompareAttributes(const char *path, const char *name, unsigned musthave, unsigned canthave)
void Sys_Mkfifo(const char *ospath, qFILE *f)
static char findpattern[MAX_OSPATH]
void Sys_Mkdir(const char *thePath)
static DIR * fdir
void Sys_FindClose(void)
char * Sys_FindNext(unsigned musthave, unsigned canhave)
Returns the next file of the already opened directory (Sys_FindFirst) that matches our search mask.
int Sys_Access(const char *filename, int mode)