#include #include #include #include #include #include "common.h" #include "debug.h" #include "string.h" #include "filepath.h" #include "rule.h" #include "filedirrule.h" #include "regexrule.h" enum { DEBUG_REGEXRULE = false, DEBUG_FILEREGEXRULE = false, DEBUG_DIRREGEXRULE = false }; typedef struct RegexRule { Rule; Reprog *regex; } RegexRule; Rule *regexrule_new(char *regex, char *root, RuleOperations *ops) { RegexRule *result; char buf[RULE_MAXNAMELEN]; assert_valid(root); assert_valid(ops); result = (RegexRule *)emalloc_fs(sizeof(*result)); result->ops = ops; result->root = estrdup_fs(root); snprint(buf, sizeof(buf), "regex<%s>", regex); result->name = estrdup_fs(buf); result->regex = regcomp(regex); return result; } static void regexrule_free(Rule *rule) { RegexRule *self = (RegexRule *)rule; free(self->name); self->name = nil; free(self->regex); self->regex = nil; free(self); } static bool regexrule_matches(RegexRule *self, char *path) { NOISE(DEBUG_REGEXRULE, "regexrule_matches checking against: %s", path); return regexec(self->regex, path, nil, 0) == 1; } static bool regexrule_contains(Rule *rule, char *path, int, ulong) { RegexRule *self = (RegexRule *)rule; return regexrule_matches(self, path); } bool regexrule_issatisfy(Rule *rule, char *path, Dir *) { RegexRule *self = (RegexRule *)rule; return regexrule_matches(self, path); } static RuleOperations regexops = { .free = regexrule_free, .issatisfy = regexrule_issatisfy, .contains = regexrule_contains }; Rule *regexrule_parse(char *rule, char *setting, char *path) { assert_valid(rule); assert_valid(setting); assert_valid(path); if(strcmp(rule, "regex") != 0) { return nil; } INFO(DEBUG_REGEXRULE, "parsed regex rule with path: %s regex: %s", path, setting); return regexrule_new(setting, path, ®exops); } typedef struct FileDirRegexRule { FileDirRule; Reprog *regex; } FileDirRegexRule; Rule *filedirregexrule_new(char *regex, char *root, RuleOperations *ops, FileDirRuleOperations *fdops, char *name) { FileDirRegexRule *result; char buf[RULE_MAXNAMELEN]; assert_valid(root); assert_valid(ops); assert_valid(fdops); result = (FileDirRegexRule *)emalloc_fs(sizeof(*result)); result->ops = ops; result->root = estrdup_fs(root); snprint(buf, sizeof(buf), "%s<%s>", name, regex); result->name = estrdup_fs(buf); result->fdops = fdops; result->regex = regcomp(regex); return result; } static void filedirregexrule_free(Rule *rule) { FileDirRegexRule *self = (FileDirRegexRule *)rule; free(self->name); self->name = nil; free(self->regex); self->regex = nil; free(self); } static bool filedirregexrule_contains(Rule *rule, char *name) { bool result; FileDirRegexRule *self = (FileDirRegexRule *)rule; result = regexec(self->regex, name, nil, 0) == 1; NOISE(DEBUG_REGEXRULE, "filedirregexrule_contains checking against: %s result: %d", name, result); return result; } static bool fileregexrule_contains(FileDirRule *rule, char *name); static RuleOperations fileregexops = { .free = filedirregexrule_free, .issatisfy = filedirrule_file_issatisfy, .contains = filedirrule_contains }; static FileDirRuleOperations fileregexfdops = { .contains_file = fileregexrule_contains, .contains_dir = filedirrule_contains_true }; static bool fileregexrule_contains(FileDirRule *rule, char *name) { char *filename; filename = string_after_last(name, '/'); if(filename == nil) { filename = name; } return filedirregexrule_contains(rule, filename); } Rule *fileregexrule_parse(char *rule, char *setting, char *path) { assert_valid(rule); assert_valid(setting); assert_valid(path); if(strcmp(rule, "fregex") != 0) { return nil; } INFO(DEBUG_FILEREGEXRULE, "parsed fregex rule with path: %s regex: %s", path, setting); return filedirregexrule_new(setting, path, &fileregexops, &fileregexfdops, "fregex"); } static bool dirregexrule_contains(FileDirRule *rule, char *name); static RuleOperations dirregexops = { .free = filedirregexrule_free, .issatisfy = filedirrule_dir_issatisfy, .contains = filedirrule_contains }; static FileDirRuleOperations dirregexfdops = { .contains_file = filedirrule_contains_false, .contains_dir = dirregexrule_contains }; static bool dirregexrule_contains(FileDirRule *rule, char *name) { bool result; String *dirname; dirname = s_copy(name); filepath_remove_last(dirname); result = filedirregexrule_contains(rule, s_to_c(dirname)); s_free(dirname); return result; } Rule *dirregexrule_parse(char *rule, char *setting, char *path) { assert_valid(rule); assert_valid(setting); assert_valid(path); if(strcmp(rule, "dregex") != 0) { return nil; } INFO(DEBUG_DIRREGEXRULE, "parsed dregex rule with path: %s regex: %s", path, setting); return filedirregexrule_new(setting, path, &dirregexops, &dirregexfdops, "dregex"); }