#include "server_config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
#include "gam_error.h"
#include "gam_excludes.h"
typedef struct _gam_exclude gam_exclude;
typedef gam_exclude* gam_exclude_ptr;
struct _gam_exclude {
const char *pattern;
GPatternSpec *comp;
int exclude; /* 0 == notify, 1 == poll */
};
static int initialized = 0;
static GList *excludes = NULL;
static char *static_excludes[] = {
#ifdef HAVE_LINUX
"/media/*",
"/mnt/*",
"/dev/*",
"/proc/*",
#endif
NULL
};
/**
* gam_exclude_add:
* @pattern: the pattern to exclude
* @exclude: 1 to exclude, 0 to include
*
* Add an exclude pattern
*
* Returns -1 in case of error, and 0 otherwise
*/
int
gam_exclude_add(const char *pattern, int exclude) {
GPatternSpec *comp;
gam_exclude_ptr ptr;
comp = g_pattern_spec_new((const gchar *) pattern);
if (comp == NULL)
return(-1);
ptr = (gam_exclude_ptr) malloc(sizeof(gam_exclude));
if (ptr == NULL) {
g_pattern_spec_free(comp);
return(-1);
}
ptr->pattern = g_strdup(pattern);
ptr->comp = comp;
ptr->exclude = exclude;
excludes = g_list_append(excludes, ptr);
GAM_DEBUG(DEBUG_INFO, "added %s,%d to excludes\n", pattern, exclude);
return(0);
}
/**
* gam_exclude_check_all:
* @filename: the filename to check
*
* Check a filename against the exclude patterns
* The first matching pattern counts, whether positive or negative
*
* Returns 1 if a match is found and 0 otherwise.
*/
static int
gam_exclude_check_all(const char *filename) {
GList *cur;
gam_exclude_ptr ptr;
unsigned int len;
if ((filename == NULL) || (excludes == NULL))
return(0);
cur = excludes;
len = strlen(filename);
while (cur != NULL) {
ptr = cur->data;
if ((ptr != NULL) && (ptr->comp != NULL) &&
(g_pattern_match(ptr->comp, len, filename, NULL))) {
return(ptr->exclude);
}
cur = g_list_next(cur);
}
return(0);
}
/************************************************************************
* *
* Files to exclude from kernel watching due to dnotify limitations *
* *
************************************************************************/
/**
* gam_exclude_init:
*
* Initialize the excluding check mechanism
*
* Return 0 in case of success and -1 in case of failure.
*/
int
gam_exclude_init(void) {
unsigned int i;
if (initialized)
return(-1);
for (i = 0;i < (sizeof(static_excludes)/sizeof(static_excludes[0]));i++) {
if (static_excludes[i] != NULL)
gam_exclude_add(static_excludes[i], 1);
}
initialized = 1;
return(0);
}
/**
* gam_exclude_check:
* @filename: the absolute file path
*
* Check if the file should be monitored using the kernel dnotify
* mechanism or not.
*
* Returns TRUE if the file should not be monitored by dnotify, and FALSE
* otherwise.
*/
gboolean
gam_exclude_check(const char *filename) {
if (gam_exclude_check_all(filename))
return(TRUE);
return(FALSE);
}
void gam_exclude_debug (void)
{
GList *l;
GAM_DEBUG (DEBUG_INFO, "Dumping exclude list\n");
for (l = excludes;l;l = l->next)
{
gam_exclude_ptr exclude = l->data;
GAM_DEBUG (DEBUG_INFO, "Exclude: use %s on %s\n", exclude->exclude == 0 ? "KERNEL" : "POLL", exclude->pattern);
}
}
syntax highlighted by Code2HTML, v. 0.9.1