ekg2
|
00001 /* $Id$ */ 00002 00003 /* 00004 * (C) Copyright 2003 Wojtek Kaniewski <wojtekka@irc.pl> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License Version 2 as 00008 * published by the Free Software Foundation. 00009 * 00010 * This program 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 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00018 */ 00019 00020 #ifndef __EKG_PLUGINS_H 00021 #define __EKG_PLUGINS_H 00022 00023 #include <sys/types.h> 00024 #include <stdarg.h> 00025 00026 #include "dynstuff.h" 00027 #include "sessions.h" 00028 00029 #ifdef __cplusplus 00030 extern "C" { 00031 #endif 00032 00033 #define EKG_ABI_VER 4921 00034 00035 #define EXPORT __attribute__ ((visibility("default"))) 00036 00037 typedef enum { 00038 PLUGIN_ANY = 0, 00039 PLUGIN_GENERIC, 00040 PLUGIN_PROTOCOL, 00041 PLUGIN_UI, 00042 PLUGIN_LOG, 00043 PLUGIN_SCRIPTING, 00044 PLUGIN_AUDIO, 00045 PLUGIN_CODEC, 00046 PLUGIN_CRYPT 00047 } plugin_class_t; 00048 00049 typedef int (*plugin_destroy_func_t)(void); 00050 typedef int (*plugin_theme_init_func_t)(void); 00051 typedef void (plugin_notify_func_t)(session_t *, const char *); 00052 00053 #define PLUGIN_VAR_ADD(name, type, value, secret, notify) { name, value, secret, type, notify } 00054 #define PLUGIN_VAR_END() { NULL, NULL, 0, -1, NULL } 00055 extern int plugin_abi_version(int plugin_abi_ver, const char * plugin_name); 00056 #define PLUGIN_CHECK_VER(name) { if (!plugin_abi_version(EKG_ABI_VER, name)) return -1; } 00057 00058 typedef struct { 00059 char *key; /* name */ 00060 char *value; /* value */ 00061 int secret; /* should it be hidden ? */ 00062 int type; /* type */ 00063 plugin_notify_func_t *notify; /* notify */ 00064 } plugins_params_t; 00065 00066 struct protocol_plugin_priv { 00067 const char **protocols; /* NULL-terminated list of supported protocols, replacing GET_PLUGIN_PROTOCOLS */ 00068 const status_t *statuses; /* EKG_STATUS_NULL-terminated list of supported statuses */ 00069 }; 00070 00071 typedef struct plugin { 00072 struct plugin *next; 00073 00074 char *name; 00075 int prio; 00076 plugin_class_t pclass; 00077 plugin_destroy_func_t destroy; 00078 /* lt_dlhandle */ void *dl; 00079 plugins_params_t *params; 00080 plugin_theme_init_func_t theme_init; 00081 00082 const void *priv; 00083 } plugin_t; 00084 00085 /* Note about plugin_t.statuses: 00086 * we currently put every supported status there, including unsettable by user, 00087 * we assume that user cannot set states <= EKG_STATUS_NA 00088 * [XXX] 00089 */ 00090 00091 #ifndef EKG2_WIN32_NOFUNCTION 00092 00093 int plugin_load(const char *name, int prio, int quiet); 00094 int plugin_unload(plugin_t *); 00095 int plugin_register(plugin_t *, int prio); 00096 int plugin_unregister(plugin_t *); 00097 plugin_t *plugin_find(const char *name); 00098 plugin_t *plugin_find_uid(const char *uid); 00099 int have_plugin_of_class(plugin_class_t pclass); 00100 int plugin_var_add(plugin_t *pl, const char *name, int type, const char *value, int secret, plugin_notify_func_t *notify); 00101 int plugin_var_find(plugin_t *pl, const char *name); 00102 00103 void plugins_unlink(plugin_t *pl); 00104 #endif 00105 00106 #ifdef USINGANANTIQUECOMPILER 00107 #define PLUGIN_DEFINE(x, y, z)\ 00108 static int x##_plugin_destroy(); \ 00109 \ 00110 plugin_t x##_plugin = { \ 00111 NULL, \ 00112 #x, \ 00113 0, \ 00114 y, \ 00115 x##_plugin_destroy, \ 00116 NULL, NULL, \ 00117 z \ 00118 } 00119 #else 00120 #define PLUGIN_DEFINE(x, y, z)\ 00121 static int x##_plugin_destroy(); \ 00122 \ 00123 plugin_t x##_plugin = { \ 00124 .name = #x, \ 00125 .pclass = y, \ 00126 .destroy = x##_plugin_destroy, \ 00127 .theme_init = z \ 00128 } 00129 #endif /* USINGANANTIQUECOMPILER */ 00130 00131 #define QUERY(x) int x(void *data, va_list ap) 00132 typedef QUERY(query_handler_func_t); 00133 00134 typedef struct queryx { 00135 struct queryx *next; 00136 00137 int id; 00138 plugin_t *plugin; 00139 void *data; 00140 query_handler_func_t *handler; 00141 int count; 00142 } query_t; 00143 00144 #ifndef EKG2_WIN32_NOFUNCTION 00145 00146 query_t *query_connect(plugin_t *plugin, const char *name, query_handler_func_t *handler, void *data); 00147 query_t *query_connect_id(plugin_t *plugin, const int id, query_handler_func_t *handler, void *data); 00148 int query_free(query_t *q); 00149 void query_external_free(); 00150 00151 int query_emit_id(plugin_t *, const int, ...); 00152 int query_emit(plugin_t *, const char *, ...); 00153 void queries_reconnect(); 00154 00155 const char *query_name(const int id); 00156 const struct query_def *query_struct(const int id); 00157 00158 #endif 00159 00160 typedef enum { 00161 WATCH_NONE = 0, 00162 WATCH_WRITE = 1, 00163 WATCH_READ = 2, 00164 WATCH_READ_LINE = 4, 00165 WATCH_WRITE_LINE = 8, 00166 } watch_type_t; 00167 00168 #define WATCHER(x) int x(int type, int fd, watch_type_t watch, void *data) 00169 #define WATCHER_LINE(x) int x(int type, int fd, const char *watch, void *data) 00170 #define WATCHER_SESSION(x) int x(int type, int fd, watch_type_t watch, session_t *s) 00171 #define WATCHER_SESSION_LINE(x) int x(int type, int fd, const char *watch, session_t *s) 00172 00173 typedef WATCHER(watcher_handler_func_t); 00174 /* typedef WATCHER_LINE(watcher_handler_line_func_t); */ 00175 typedef WATCHER_SESSION(watcher_session_handler_func_t); 00176 00177 typedef struct watch { 00178 int fd; /* obserwowany deskryptor */ 00179 watch_type_t type; /* co sprawdzamy */ 00180 plugin_t *plugin; /* wtyczka obsługująca deskryptor */ 00181 void *handler; /* funkcja wywoływana jeśli są dane itp. */ 00182 void *data; /* dane przekazywane powyższym funkcjom. */ 00183 string_t buf; /* bufor na linię */ 00184 time_t timeout; /* timeout */ 00185 time_t started; /* kiedy zaczęto obserwować */ 00186 int removed; /* wywołano już watch_remove() */ 00187 00188 int transfer_limit; /* XXX, requested by GiM to limit data transmitted to ircd server... currently only to send all data 00189 done by serveral calls of watch_write() in one packet... by setting it to -1 and than changing it back to 0 00190 if we really want to send packet in that function we ought to do by calling watch_handle_write() 00191 [PLEASE NOTE, THAT YOU CANNOT DO watch_write().. cause it will check if there is somethink in write buffor... 00192 and if it is, it won't call watch_handle_write()] 00193 or it will be 00194 executed in next ekg_loop() loop. 00195 */ 00196 int is_session; /* if set, this watch belongs to session specified in data */ 00197 } watch_t; 00198 00199 #ifndef EKG2_WIN32_NOFUNCTION 00200 00201 #ifdef __GNU__ 00202 int watch_write(watch_t *w, const char *format, ...) __attribute__ ((format (printf, 2, 3))); 00203 #else 00204 int watch_write(watch_t *w, const char *format, ...); 00205 #endif 00206 int watch_write_data(watch_t *w, const char *buf, int len); 00207 00208 watch_t *watch_find(plugin_t *plugin, int fd, watch_type_t type); 00209 void watch_free(watch_t *w); 00210 00211 typedef void *watch_handler_func_t; 00212 00213 int watch_timeout_set(watch_t *w, time_t timeout); 00214 00215 watch_t *watch_add(plugin_t *plugin, int fd, watch_type_t type, watcher_handler_func_t *handler, void *data); 00216 #define watch_add_line(p, fd, type, handler, data) watch_add(p, fd, type, (watcher_handler_func_t *) (handler), data) 00217 watch_t *watch_add_session(session_t *session, int fd, watch_type_t type, watcher_session_handler_func_t *handler); 00218 #define watch_add_session_line(s, fd, type, handler) watch_add_session(s, fd, type, (watcher_session_handler_func_t *) (handler)) 00219 00220 int watch_remove(plugin_t *plugin, int fd, watch_type_t type); 00221 00222 void watch_handle(watch_t *w); 00223 void watch_handle_line(watch_t *w); 00224 int watch_handle_write(watch_t *w); 00225 int ekg2_dlinit(); 00226 00227 #endif 00228 00229 #ifndef EKG2_WIN32_NOFUNCTION 00230 extern plugin_t *plugins; 00231 extern list_t watches; 00232 extern query_t *queries[]; 00233 #endif 00234 00235 #ifdef __cplusplus 00236 } 00237 #endif 00238 00239 #endif /* __EKG_PLUGINS_H */ 00240 00241 /* 00242 * Local Variables: 00243 * mode: c 00244 * c-file-style: "k&r" 00245 * c-basic-offset: 8 00246 * indent-tabs-mode: t 00247 * End: 00248 */