00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "opensync.h"
00022 #include "opensync_internals.h"
00023
00031
00032 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00033 OSyncFilter *_osync_filter_add_ids(OSyncGroup *group, long long int sourcememberid, long long int destmemberid, const char *sourceobjtype, const char *destobjtype, const char *detectobjtype, OSyncFilterAction action, const char *function_name)
00034 {
00035 OSyncFilter *filter = osync_filter_new();
00036 filter->group = group;
00037 filter->sourcememberid = sourcememberid;
00038 filter->destmemberid = destmemberid;
00039 filter->sourceobjtype = g_strdup(sourceobjtype);
00040 filter->destobjtype = g_strdup(destobjtype);
00041 filter->detectobjtype = g_strdup(detectobjtype);
00042 filter->action = action;
00043
00044 if (function_name) {
00045 osync_filter_update_hook(filter, group, function_name);
00046 }
00047
00048 osync_filter_register(group, filter);
00049 return filter;
00050 }
00051
00052 void osync_filter_update_hook(OSyncFilter *filter, OSyncGroup *group, const char *function_name)
00053 {
00054 g_assert(filter);
00055 g_assert(group);
00056 g_assert(function_name);
00057
00058 OSyncFilterFunction hook = NULL;
00059 GList *f;
00060 for (f = group->conv_env->filter_functions; f; f = f->next) {
00061 OSyncCustomFilter *custom = f->data;
00062 if (!strcmp(custom->name, function_name))
00063 hook = custom->hook;
00064 }
00065 if (!hook) {
00066 osync_trace(TRACE_ERROR, "Unable to add custom filter, hook not found!");
00067 return;
00068 }
00069 filter->hook = hook;
00070 filter->function_name = g_strdup(function_name);
00071 }
00072
00073
00074 GList *_osync_filter_find(OSyncMember *member)
00075 {
00076 GList *f = NULL;
00077 GList *ret = NULL;
00078 for (f = member->group->filters; f; f = f->next) {
00079 OSyncFilter *filter = f->data;
00080 if (!filter->destmemberid || filter->destmemberid == member->id)
00081 ret = g_list_append(ret, filter);
00082 }
00083 return ret;
00084 }
00085
00086 OSyncFilterAction osync_filter_invoke(OSyncFilter *filter, OSyncChange *change, OSyncMember *destmember)
00087 {
00088 g_assert(filter);
00089 g_assert(change);
00090 osync_debug("OSFLT", 3, "Starting to invoke filter for change %s", change->uid);
00091 if (filter->sourcememberid && change->sourcemember && filter->sourcememberid != change->sourcemember->id)
00092 return OSYNC_FILTER_IGNORE;
00093 if (filter->destmemberid && filter->destmemberid != destmember->id)
00094 return OSYNC_FILTER_IGNORE;
00095 if (filter->sourceobjtype && strcmp(filter->sourceobjtype, change->sourceobjtype))
00096 return OSYNC_FILTER_IGNORE;
00097 if (filter->destobjtype && change->destobjtype && strcmp(filter->destobjtype, change->destobjtype))
00098 return OSYNC_FILTER_IGNORE;
00099 if (filter->detectobjtype) {
00100 OSyncError *error = NULL;
00101 OSyncObjType *objtype = osync_change_detect_objtype_full(osync_member_get_format_env(destmember), change, &error);
00102 if (!objtype) {
00103 osync_error_free(&error);
00104 return OSYNC_FILTER_IGNORE;
00105 }
00106 if (strcmp(filter->detectobjtype, objtype->name))
00107 return OSYNC_FILTER_IGNORE;
00108 }
00109
00110 osync_debug("OSFLT", 3, "Change %s passed the filter!", change->uid);
00111
00112 if (!filter->hook)
00113 return filter->action;
00114
00115
00116 return filter->hook(change, filter->config);
00117 }
00118
00119 osync_bool osync_filter_change_allowed(OSyncMember *destmember, OSyncChange *change)
00120 {
00121 osync_trace(TRACE_ENTRY, "osync_filter_change_allowed(%p, %p)", destmember, change);
00122 GList *filters = _osync_filter_find(destmember);
00123 GList *f = NULL;
00124 int ret = TRUE;
00125 osync_debug("OSFLT", 3, "Checking if change %s is allowed for member %lli. Filters to invoke: %i", change->uid, destmember->id, g_list_length(filters));
00126 for (f = filters; f; f = f->next) {
00127 OSyncFilter *filter = f->data;
00128 OSyncFilterAction action = osync_filter_invoke(filter, change, destmember);
00129 if (action == OSYNC_FILTER_ALLOW)
00130 ret = TRUE;
00131 if (action == OSYNC_FILTER_DENY)
00132 ret = FALSE;
00133 }
00134 g_list_free(filters);
00135 osync_trace(TRACE_EXIT, "osync_filter_change_allowed: %s", ret ? "TRUE" : "FALSE");
00136 return ret;
00137 }
00138
00139 const char *osync_filter_get_sourceobjtype(OSyncFilter *filter)
00140 {
00141 return filter->sourceobjtype;
00142 }
00143
00144 const char *osync_filter_get_destobjtype(OSyncFilter *filter)
00145 {
00146 return filter->destobjtype;
00147 }
00148
00149 const char *osync_filter_get_detectobjtype(OSyncFilter *filter)
00150 {
00151 return filter->detectobjtype;
00152 }
00153
00154 OSyncFilterAction osync_filter_get_action(OSyncFilter *filter)
00155 {
00156 return filter->action;
00157 }
00158
00159 OSyncMember *osync_filter_get_sourcemember(OSyncFilter *filter)
00160 {
00161 return osync_member_from_id(filter->group, filter->sourcememberid);
00162 }
00163
00164 OSyncMember *osync_filter_get_destmember(OSyncFilter *filter)
00165 {
00166 return osync_member_from_id(filter->group, filter->destmemberid);
00167 }
00168 #endif
00169
00179
00185 void osync_filter_register(OSyncGroup *group, OSyncFilter *filter)
00186 {
00187 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, group, filter);
00188 g_assert(group);
00189 group->filters = g_list_append(group->filters, filter);
00190 osync_trace(TRACE_EXIT, "%s", __func__);
00191 }
00192
00197 OSyncFilter *osync_filter_new(void)
00198 {
00199 osync_trace(TRACE_ENTRY, "%s(void)", __func__);
00200 OSyncFilter *filter = g_malloc0(sizeof(OSyncFilter));
00201 g_assert(filter);
00202 osync_trace(TRACE_EXIT, "%s: %p", __func__, filter);
00203 return filter;
00204 }
00205
00210 void osync_filter_free(OSyncFilter *filter)
00211 {
00212 osync_trace(TRACE_ENTRY, "%s(%p)", __func__, filter);
00213 g_assert(filter);
00214 if (filter->sourceobjtype)
00215 g_free(filter->sourceobjtype);
00216 if (filter->destobjtype)
00217 g_free(filter->destobjtype);
00218 if (filter->detectobjtype)
00219 g_free(filter->detectobjtype);
00220
00221 g_free(filter);
00222 osync_trace(TRACE_EXIT, "%s", __func__);
00223 }
00224
00236 OSyncFilter *osync_filter_add(OSyncGroup *group, OSyncMember *sourcemember, OSyncMember *destmember, const char *sourceobjtype, const char *destobjtype, const char *detectobjtype, OSyncFilterAction action)
00237 {
00238 osync_trace(TRACE_ENTRY, "%s(%p, %p:%lli, %p:%lli, %s, %s, %s, %i)", __func__, group, \
00239 sourcemember, sourcemember ? sourcemember->id : 0, \
00240 destmember, destmember ? destmember->id : 0, \
00241 sourceobjtype, destobjtype, detectobjtype, action);
00242
00243 long long int sourcememberid = 0;
00244 long long int destmemberid = 0;
00245 if (sourcemember)
00246 sourcememberid = sourcemember->id;
00247 if (destmember)
00248 destmemberid = destmember->id;
00249
00250 OSyncFilter *filter = _osync_filter_add_ids(group, sourcememberid, destmemberid, sourceobjtype, destobjtype, detectobjtype, action, NULL);
00251 osync_trace(TRACE_EXIT, "%s: %p", __func__, filter);
00252 return filter;
00253 }
00254
00260 void osync_filter_remove(OSyncGroup *group, OSyncFilter *filter)
00261 {
00262 osync_trace(TRACE_ENTRY, "%s(%p, %p)", __func__, group, filter);
00263 g_assert(group);
00264 group->filters = g_list_remove(group->filters, filter);
00265 osync_trace(TRACE_EXIT, "%s", __func__);
00266 }
00267
00280 OSyncFilter *osync_filter_add_custom(OSyncGroup *group, OSyncMember *sourcemember, OSyncMember *destmember, const char *sourceobjtype, const char *destobjtype, const char *detectobjtype, const char *function_name)
00281 {
00282 osync_trace(TRACE_ENTRY, "%s(%p, %p:%lli, %p:%lli, %s, %s, %s, %s)", __func__, group, \
00283 sourcemember, sourcemember ? sourcemember->id : 0, \
00284 destmember, destmember ? destmember->id : 0, \
00285 sourceobjtype, destobjtype, detectobjtype, function_name);
00286 long long int sourcememberid = 0;
00287 long long int destmemberid = 0;
00288 if (sourcemember)
00289 sourcememberid = sourcemember->id;
00290 if (destmember)
00291 destmemberid = destmember->id;
00292
00293 OSyncFilter *filter = _osync_filter_add_ids(group, sourcememberid, destmemberid, sourceobjtype, destobjtype, detectobjtype, OSYNC_FILTER_IGNORE, function_name);
00294 osync_trace(TRACE_EXIT, "%s: %p", __func__, filter);
00295 return filter;
00296 }
00297
00305 void osync_filter_set_config(OSyncFilter *filter, const char *config)
00306 {
00307 osync_trace(TRACE_ENTRY, "%s(%p, %s)", __func__, filter, config);
00308 g_assert(filter);
00309 if (filter->config)
00310 g_free(filter->config);
00311 filter->config = g_strdup(config);
00312 osync_trace(TRACE_EXIT, "%s", __func__);
00313 }
00314
00320 const char *osync_filter_get_config(OSyncFilter *filter)
00321 {
00322 osync_trace(TRACE_ENTRY, "%s(%p)", __func__, filter);
00323 g_assert(filter);
00324 osync_trace(TRACE_EXIT, "%s: %s", __func__, filter->config);
00325 return filter->config;
00326 }
00327