OpenSync
0.22
|
00001 /* 00002 * libopensync - A synchronization framework 00003 * Copyright (C) 2004-2005 Armin Bauer <armin.bauer@opensync.org> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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 //We passed the filter. Now we can return the action 00112 if (!filter->hook) 00113 return filter->action; 00114 00115 //What exactly do we need to pass to the hook? 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