1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3
4#ifndef BASE_FS_H
5#define BASE_FS_H
6
7#include "types.h"
8
9#include <cstddef> // size_t
10#include <ctime> // time_t
11
12/**
13 * Utilities for accessing the file system.
14 *
15 * @defgroup Filesystem Filesystem
16 */
17
18/**
19 * Creates a directory.
20 *
21 * @ingroup Filesystem
22 *
23 * @param path Directory to create.
24 *
25 * @return `0` on success. Negative value on failure.
26 *
27 * @remark Does not create several directories if needed. "a/b/c" will
28 * result in a failure if b or a does not exist.
29 *
30 * @remark The strings are treated as null-terminated strings.
31 */
32int fs_makedir(const char *path);
33
34/**
35 * Recursively creates parent directories for a file or directory.
36 *
37 * @ingroup Filesystem
38 *
39 * @param path File or directory for which to create parent directories.
40 *
41 * @return `0` on success. Negative value on failure.
42 *
43 * @remark The strings are treated as null-terminated strings.
44 */
45int fs_makedir_rec_for(const char *path);
46
47/**
48 * Removes a directory.
49 *
50 * @ingroup Filesystem
51 *
52 * @param path Directory to remove.
53 *
54 * @return `0` on success. Negative value on failure.
55 *
56 * @remark Cannot remove a non-empty directory.
57 *
58 * @remark The strings are treated as null-terminated strings.
59 */
60int fs_removedir(const char *path);
61
62/**
63 * Lists the files and folders in a directory.
64 *
65 * @ingroup Filesystem
66 *
67 * @param dir Directory to list.
68 * @param cb Callback function to call for each entry.
69 * @param type Type of the directory.
70 * @param user Pointer to give to the callback.
71 *
72 * @remark The strings are treated as null-terminated strings.
73 */
74void fs_listdir(const char *dir, FS_LISTDIR_CALLBACK cb, int type, void *user);
75
76/**
77 * Lists the files and folders in a directory and gets additional file information.
78 *
79 * @ingroup Filesystem
80 *
81 * @param dir Directory to list.
82 * @param cb Callback function to call for each entry.
83 * @param type Type of the directory.
84 * @param user Pointer to give to the callback.
85 *
86 * @remark The strings are treated as null-terminated strings.
87 */
88void fs_listdir_fileinfo(const char *dir, FS_LISTDIR_CALLBACK_FILEINFO cb, int type, void *user);
89
90/**
91 * Changes the current working directory.
92 *
93 * @ingroup Filesystem
94 *
95 * @param path New working directory path.
96 *
97 * @return `0` on success. `1` on failure.
98 *
99 * @remark The strings are treated as null-terminated strings.
100 */
101int fs_chdir(const char *path);
102
103/**
104 * Gets the current working directory.
105 *
106 * @ingroup Filesystem
107 *
108 * @param buffer Buffer that will receive the current working directory.
109 * @param buffer_size Size of the buffer.
110 *
111 * @return Pointer to the buffer on success, `nullptr` on failure.
112 *
113 * @remark The strings are treated as null-terminated strings.
114 */
115char *fs_getcwd(char *buffer, int buffer_size);
116
117/**
118 * Fetches per user configuration directory.
119 *
120 * @ingroup Filesystem
121 *
122 * @param appname Name of the application.
123 * @param path Buffer that will receive the storage path.
124 * @param max Size of the buffer.
125 *
126 * @return `0` on success. Negative value on failure.
127 *
128 * @remark Returns ~/.appname on UNIX based systems.
129 * @remark Returns ~/Library/Applications Support/appname on macOS.
130 * @remark Returns %APPDATA%/Appname on Windows based systems.
131 *
132 * @remark The strings are treated as null-terminated strings.
133 */
134int fs_storage_path(const char *appname, char *path, int max);
135
136/**
137 * Gets the absolute path to the executable.
138 *
139 * @ingroup Filesystem
140 *
141 * @param buffer Buffer that will receive the path of the executable.
142 * @param buffer_size Size of the buffer.
143 *
144 * @return `0` on success. Negative value on failure.
145 *
146 * @remark The executable name is included in the result.
147 *
148 * @remark The strings are treated as null-terminated strings.
149 */
150int fs_executable_path(char *buffer, int buffer_size);
151
152/**
153 * Checks if a file exists.
154 *
155 * @ingroup Filesystem
156 *
157 * @param path The path to check.
158 *
159 * @return `1` if a file with the given path exists.
160 * @return `0` on failure or if the file does not exist.
161 *
162 * @remark The strings are treated as null-terminated strings.
163 */
164int fs_is_file(const char *path);
165
166/**
167 * Checks if a folder exists.
168 *
169 * @ingroup Filesystem
170 *
171 * @param path The path to check.
172 *
173 * @return `1` if a folder with the given path exists.
174 * @return `0` on failure or if the folder does not exist.
175 *
176 * @remark The strings are treated as null-terminated strings.
177 */
178int fs_is_dir(const char *path);
179
180/**
181 * Checks whether a given path is relative or absolute.
182 *
183 * @ingroup Filesystem
184 *
185 * @param path Path to check.
186 *
187 * @return `1` if relative, `0` if absolute.
188 *
189 * @remark The strings are treated as null-terminated strings.
190 */
191int fs_is_relative_path(const char *path);
192
193/**
194 * Gets the name of a file or folder specified by a path,
195 * i.e. the last segment of the path.
196 *
197 * @ingroup Filesystem
198 *
199 * @param path Path from which to retrieve the filename.
200 *
201 * @return Filename of the path.
202 *
203 * @remark Supports forward and backward slashes as path segment separator.
204 * @remark No distinction between files and folders is being made.
205 * @remark The strings are treated as null-terminated strings.
206 */
207const char *fs_filename(const char *path);
208
209/**
210 * Splits a filename into name (without extension) and file extension.
211 *
212 * @ingroup Filesystem
213 *
214 * @param filename The filename to split.
215 * @param name Buffer that will receive the name without extension, may be nullptr.
216 * @param name_size Size of the name buffer (ignored if name is nullptr).
217 * @param extension Buffer that will receive the extension, may be nullptr.
218 * @param extension_size Size of the extension buffer (ignored if extension is nullptr).
219 *
220 * @remark Does NOT handle forward and backward slashes.
221 * @remark No distinction between files and folders is being made.
222 * @remark The strings are treated as null-terminated strings.
223 */
224void fs_split_file_extension(const char *filename, char *name, size_t name_size, char *extension = nullptr, size_t extension_size = 0);
225
226/**
227 * Get the parent directory of a directory.
228 *
229 * @ingroup Filesystem
230 *
231 * @param path Path of the directory. The parent will be store in this buffer as well.
232 *
233 * @return `0` on success. `1` on failure.
234 *
235 * @remark The strings are treated as null-terminated strings.
236 */
237int fs_parent_dir(char *path);
238
239/**
240 * Normalizes the given path: replaces backslashes with regular slashes
241 * and removes trailing slashes.
242 *
243 * @ingroup Filesystem
244 *
245 * @param path Path to normalize.
246 *
247 * @remark The strings are treated as null-terminated strings.
248 */
249void fs_normalize_path(char *path);
250
251/**
252 * Deletes a file.
253 *
254 * @ingroup Filesystem
255 *
256 * @param filename Path of the file to delete.
257 *
258 * @return `0` on success. `1` on failure.
259 *
260 * @remark The strings are treated as null-terminated strings.
261 * @remark Returns an error if the path specifies a directory name.
262 */
263int fs_remove(const char *filename);
264
265/**
266 * Renames the file or directory. If the paths differ the file will be moved.
267 *
268 * @ingroup Filesystem
269 *
270 * @param oldname The current path of a file or directory.
271 * @param newname The new path for the file or directory.
272 *
273 * @return `0` on success. `1` on failure.
274 *
275 * @remark The strings are treated as null-terminated strings.
276 */
277int fs_rename(const char *oldname, const char *newname);
278
279/**
280 * Gets the creation and the last modification date of a file or directory.
281 *
282 * @ingroup Filesystem
283 *
284 * @param name Path of a file or directory.
285 * @param created Pointer where the creation time will be stored.
286 * @param modified Pointer where the modification time will be stored.
287 *
288 * @return `0` on success. non-zero on failure.
289 *
290 * @remark The strings are treated as null-terminated strings.
291 * @remark Returned time is in seconds since UNIX Epoch.
292 */
293int fs_file_time(const char *name, time_t *created, time_t *modified);
294
295#endif
296