libamxp  1.4.0
Patterns C Implementation
Directory Utilities

Typedefs

typedef int(* amxp_dir_match_fn_t) (const char *name, void *priv)
 Matching file/directory callback function signature. More...
 

Functions

int amxp_dir_make (const char *path, const mode_t mode)
 Creates sub-directories. More...
 
int amxp_dir_owned_make (const char *path, const mode_t mode, uid_t uid, gid_t gid)
 Creates sub-directories and changes ownership. More...
 
int amxp_dir_scan (const char *path, const char *filter, bool recursive, amxp_dir_match_fn_t fn, void *priv)
 Scans a directory and calls a callback function for each matching entry found. More...
 
bool amxp_dir_is_empty (const char *path)
 Checks if a directory is empty. More...
 
bool amxp_dir_is_directory (const char *path)
 Checks if a path is a directory. More...
 

Detailed Description

File system directory utilities and helper functions

Typedef Documentation

◆ amxp_dir_match_fn_t

typedef int(* amxp_dir_match_fn_t) (const char *name, void *priv)

Matching file/directory callback function signature.

The amxp_dir_scan function will call the callback function for each matching file or directory found.

Parameters
namefull path of the matching file or directory
priva pointer to some data, provided to amxp_dir_scan
Returns
When the callback function returns a non-zero value, the scan of the directory stops.

Definition at line 96 of file amxp_dir.h.

Function Documentation

◆ amxp_dir_is_directory()

bool amxp_dir_is_directory ( const char *  path)

Checks if a path is a directory.

Parameters
pathrelative or absolute path to a file or directory
Returns
true when the path is a directory.

Definition at line 257 of file amxp_dir.c.

257  {
258  bool retval = false;
259  struct stat sb;
260  when_str_empty(path, exit);
261 
262  when_false(stat(path, &sb) == 0, exit);
263  when_false((sb.st_mode & S_IFMT) == S_IFDIR, exit);
264 
265  retval = true;
266 
267 exit:
268  return retval;
269 }
static amxc_string_t path

◆ amxp_dir_is_empty()

bool amxp_dir_is_empty ( const char *  path)

Checks if a directory is empty.

A directory is considered empty when it doesn't contain any file or sub-directory.

if the given path doesn't exist or is not a directory this function will return true.

Parameters
pathrelative or absolute path to a directory that needs to be scanned
Returns
true when the path is an empty directory, doesn't exist or isn't a directory.

Definition at line 243 of file amxp_dir.c.

243  {
244  bool retval = true;
245  when_str_empty(path, exit);
246 
247  when_false(amxp_dir_is_directory(path), exit);
248 
249  if(amxp_dir_scan(path, NULL, false, amxp_dir_check_is_empty, NULL)) {
250  retval = false;
251  }
252 
253 exit:
254  return retval;
255 }
static int amxp_dir_check_is_empty(UNUSED const char *name, UNUSED void *priv)
Definition: amxp_dir.c:107
int amxp_dir_scan(const char *path, const char *filter, bool recursive, amxp_dir_match_fn_t fn, void *priv)
Scans a directory and calls a callback function for each matching entry found.
Definition: amxp_dir.c:216
bool amxp_dir_is_directory(const char *path)
Checks if a path is a directory.
Definition: amxp_dir.c:257

◆ amxp_dir_make()

int amxp_dir_make ( const char *  path,
const mode_t  mode 
)

Creates sub-directories.

This function will create all sub-directories, if not existing yet.

If the path provided contains intermediate sub-directories that don't exist, they will be created.

Parameters
pathrelative or absolute path to sub-directories that needs to be created
modethe argument mode specifies the permissions to use
Returns
0 when all directories has been created, otherwise an error occurred

Definition at line 212 of file amxp_dir.c.

212  {
213  return amxp_dir_owned_make(path, mode, 0, 0);
214 }
int amxp_dir_owned_make(const char *path, const mode_t mode, uid_t uid, gid_t gid)
Creates sub-directories and changes ownership.
Definition: amxp_dir.c:156

◆ amxp_dir_owned_make()

int amxp_dir_owned_make ( const char *  path,
const mode_t  mode,
uid_t  uid,
gid_t  gid 
)

Creates sub-directories and changes ownership.

This function will create all sub-directories, if not existing yet.

When a (sub)directory is created and the given user id and group id are not 0, ownership is changed and set to the given user id and group id.

Parameters
pathrelative or absolute path to sub-directories that needs to be created
modethe argument mode specifies the permissions to use
uida user id
gida group id
Returns
0 when all directories has been created, otherwise an error occurred

Definition at line 156 of file amxp_dir.c.

156  {
157  int retval = -1;
158  char* dir = NULL;
159  char* current = NULL;
160  struct stat sb;
161 
162  when_str_empty(path, exit);
163 
164  if(stat(path, &sb) == 0) {
165  retval = 0;
166  goto exit;
167  }
168 
169  dir = strdup(path);
170  when_null(dir, exit);
171  /* 'dir' does not exist. Create it, from left to right. */
172  current = strchr(dir, '/');
173 
174  while(current != NULL && *current != 0) {
175  *current = '\0';
176 
177  if(dir[0] == 0) {
178  *current = '/';
179  current = strchr(current + 1, '/');
180  continue;
181  }
182 
183  if(stat(dir, &sb) == 0) {
184  *current = '/';
185  current = strchr(current + 1, '/');
186  continue;
187  }
188 
189  retval = mkdir(dir, mode);
190  when_failed(retval, exit);
191  if((uid != 0) || (gid != 0)) {
192  retval = chown(dir, uid, gid);
193  when_failed(retval, exit);
194  }
195  *current = '/';
196  current = strchr(current + 1, '/');
197  }
198 
199  if(stat(dir, &sb) != 0) {
200  retval = mkdir(dir, mode);
201  when_failed(retval, exit);
202  if((uid != 0) || (gid != 0)) {
203  retval = chown(dir, uid, gid);
204  }
205  }
206 
207 exit:
208  free(dir);
209  return retval;
210 }
static struct timeval current
Definition: amxp_timer.c:66

◆ amxp_dir_scan()

int amxp_dir_scan ( const char *  path,
const char *  filter,
bool  recursive,
amxp_dir_match_fn_t  fn,
void *  priv 
)

Scans a directory and calls a callback function for each matching entry found.

When no filter is provided, all found entries are considered a match.

The filter works on the directory entry data. The fields that can be used are:

  • d_name
  • d_type
  • d_ino

When the argument recursive is set to true, the scan will enter all found directories and scan these as well.

Filter examples:

  • "d_type == DT_REG" - all regular files are matching
  • "d_type == DT_LNK" - all symbolic links are matching
  • "d_type == DT_REG && d_name matches '.*\\.so'" - all regular files with extention so are matching
Parameters
pathrelative or absolute path to a directory that needs to be scanned
filter(optional) an expression that can be used to filter to directory entries
recursivewhen set to true all found sub-directories will be scanned as well.
fncallback function which is called for each matching entry
privsome private data, will be passed to the callback function
Returns
0 when scan was successful, otherwise an error occurred

Definition at line 216 of file amxp_dir.c.

220  {
221  int retval = -1;
222  amxp_expr_t* expr = NULL;
223  char* real_path = NULL;
224 
225  when_str_empty(path, exit);
226 
227  real_path = realpath(path, NULL);
228  when_null(real_path, exit);
229 
230  if((filter != NULL) && (*filter != 0)) {
231  when_failed(amxp_expr_new(&expr, filter), exit);
232  }
233 
234  retval = amxp_dir_scan_impl(real_path, expr, recursive, fn, priv);
235 
236 exit:
237  free(real_path);
238  amxp_expr_delete(&expr);
239  return retval;
240 
241 }
static int amxp_dir_scan_impl(const char *path, amxp_expr_t *expr, bool recursive, amxp_dir_match_fn_t fn, void *priv)
Definition: amxp_dir.c:111
amxp_expr_status_t amxp_expr_new(amxp_expr_t **expr, const char *expression)
Allocates and initializes an expression.
void amxp_expr_delete(amxp_expr_t **expr)
Deletes a previously allocated expression structure.