From 729a73e0194e2936b12cbb8f36a8ffd6e93d8d18 Mon Sep 17 00:00:00 2001 From: chatty Date: Thu, 7 Feb 2002 18:41:01 +0000 Subject: Initial revision --- README | 45 ++++++ TODO | 4 + include/config.h | 196 +++++++++++++++++++++++ include/history.h | 14 ++ include/inbound.h | 13 ++ include/plugin.h | 122 ++++++++++++++ include/text.h | 10 ++ include/xchat.h | 425 +++++++++++++++++++++++++++++++++++++++++++++++++ include/xchatc.h | 35 ++++ redhat/changelog | 10 ++ redhat/ivyd.init | 43 +++++ redhat/rules | 12 ++ src/Makefile | 27 ++++ src/ivy-xchat-plugin.c | 225 ++++++++++++++++++++++++++ 14 files changed, 1181 insertions(+) create mode 100644 README create mode 100644 TODO create mode 100644 include/config.h create mode 100644 include/history.h create mode 100644 include/inbound.h create mode 100644 include/plugin.h create mode 100644 include/text.h create mode 100644 include/xchat.h create mode 100644 include/xchatc.h create mode 100644 redhat/changelog create mode 100755 redhat/ivyd.init create mode 100644 redhat/rules create mode 100644 src/Makefile create mode 100644 src/ivy-xchat-plugin.c diff --git a/README b/README new file mode 100644 index 0000000..5d37d2e --- /dev/null +++ b/README @@ -0,0 +1,45 @@ +README for ivy-xchat-plugin + +This is a C plugin for xchat, which creates a bridge between the IRC channels +and an Ivy bus. To use it, you should : + - install a binary package or compile the sources + - either load explicitely the plugin from the appropriate xchat menu, or copy +or link it to your .xchat directory (which causes the plugin to be loaded when +xchat starts) + +There are a few issues that need to be solved: + +1. Where to install plugins? +I am not aware of any standard place to install plugins from rpm or deb packages. I +took the decision to put mine in /usr/lib/xchat/plugins, but I should check this with +the maintainers of xchat. + +2. Where to get headers? +To compile, plugins need a few C header files from xchat. I found them in the sources +of xchat 1.8.7 and copied them in the 'include' directory. But ideally, there would be a +xchat-devel package which installs the necessary header files to /usr/include. I should +check this with the maintainers. + +3. The plugin should quit properly. +The IvyStop function is currently not implemented in the Gtk implementation of Ivy, +which causes the plugin to stay as a zombie on the Ivy bus. I should discuss that with +FR.Colin. + +4. What events and what Ivy syntax? +The current version only sends major events from irc to ivy, in a very primitive syntax. +Some thoughts should be given to improving this. + +5. Ivy relaying should be improved. +The idea of relaying Ivy events to IRC channels is interesting, but +needs to be designed more carefully. Buffer overflow should be checked +for, binding deletion should be allowed, original messages (and not +only captures) should be printed, and my nickname (and not the empty +string) should appear in my window when a message is relayed from Ivy +to a channel. + +6. How to choose the bus? +Probably from a config file? From the xchat config file? + + +Stéphane Chatty +chatty@intuilab.com \ No newline at end of file diff --git a/TODO b/TODO new file mode 100644 index 0000000..4a7284d --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +Réessayer de régler le problème du nickname qui n'apparait pas, en +reprenant le serveur comme clé, mais en mettant les flags needserver. + + diff --git a/include/config.h b/include/config.h new file mode 100644 index 0000000..7b72993 --- /dev/null +++ b/include/config.h @@ -0,0 +1,196 @@ +/* config.h. Generated automatically by configure. */ +/* config.h.in. Generated automatically from configure.in by autoheader. */ + +/* Define if using alloca.c. */ +/* #undef C_ALLOCA */ + +/* Define to empty if the keyword does not work. */ +/* #undef const */ + +/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. + This function is required for alloca.c support on those systems. */ +/* #undef CRAY_STACKSEG_END */ + +/* Define if you have alloca, as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define if you have and it should be used (not on Ultrix). */ +#define HAVE_ALLOCA_H 1 + +/* Define if you have a working `mmap' system call. */ +#define HAVE_MMAP 1 + +/* Define as __inline if that's what the C compiler calls it. */ +/* #undef inline */ + +/* Define to `long' if doesn't define. */ +/* #undef off_t */ + +/* Define if you need to in order for stat and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to `unsigned' if doesn't define. */ +/* #undef size_t */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at run-time. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown + */ +/* #undef STACK_DIRECTION */ + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +#define USE_MMX 1 +#define OLD_PERL 1 +#define ENABLE_NLS 1 +/* #undef HAVE_CATGETS */ +#define HAVE_GETTEXT 1 +#define HAVE_LC_MESSAGES 1 +#define HAVE_STPCPY 1 +/* #undef USE_PYTHON */ +/* #undef USE_DEBUG */ +#define USE_GNOME 1 +#define USE_ZVT 1 +#define USE_PERL 1 +#define USE_PLUGIN 1 +/* #undef USE_GDK_PIXBUF */ +#define USE_XLIB 1 +/* #undef USE_PANEL */ +/* #undef USE_MYGLIB */ +#define USE_TRANS 1 +/* #undef USE_HEBREW */ +/* #undef USE_OPENSSL */ +/* #undef USE_IPV6 */ +/* #undef USE_JCODE */ +/* #undef SOCKS */ +#define PREFIX "/usr" +#define USING_LINUX 1 +/* #undef USING_FREEBSD */ + +/* Define if you have the __argz_count function. */ +#define HAVE___ARGZ_COUNT 1 + +/* Define if you have the __argz_next function. */ +#define HAVE___ARGZ_NEXT 1 + +/* Define if you have the __argz_stringify function. */ +#define HAVE___ARGZ_STRINGIFY 1 + +/* Define if you have the dcgettext function. */ +#define HAVE_DCGETTEXT 1 + +/* Define if you have the dlerror function. */ +#define HAVE_DLERROR 1 + +/* Define if you have the dlopen function. */ +#define HAVE_DLOPEN 1 + +/* Define if you have the eval_pv function. */ +/* #undef HAVE_EVAL_PV */ + +/* Define if you have the getaddrinfo function. */ +/* #undef HAVE_GETADDRINFO */ + +/* Define if you have the getcwd function. */ +#define HAVE_GETCWD 1 + +/* Define if you have the getpagesize function. */ +#define HAVE_GETPAGESIZE 1 + +/* Define if you have the munmap function. */ +#define HAVE_MUNMAP 1 + +/* Define if you have the putenv function. */ +#define HAVE_PUTENV 1 + +/* Define if you have the setenv function. */ +#define HAVE_SETENV 1 + +/* Define if you have the setlocale function. */ +#define HAVE_SETLOCALE 1 + +/* Define if you have the snprintf function. */ +#define HAVE_SNPRINTF 1 + +/* Define if you have the stpcpy function. */ +#define HAVE_STPCPY 1 + +/* Define if you have the strcasecmp function. */ +#define HAVE_STRCASECMP 1 + +/* Define if you have the strchr function. */ +#define HAVE_STRCHR 1 + +/* Define if you have the strdup function. */ +#define HAVE_STRDUP 1 + +/* Define if you have the vsnprintf function. */ +#define HAVE_VSNPRINTF 1 + +/* Define if you have the header file. */ +#define HAVE_ARGZ_H 1 + +/* Define if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define if you have the header file. */ +#define HAVE_LOCALE_H 1 + +/* Define if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define if you have the header file. */ +#define HAVE_NL_TYPES_H 1 + +/* Define if you have the header file. */ +/* #undef HAVE_OPENSSL_SSL_H */ + +/* Define if you have the header file. */ +/* #undef HAVE_SOCKS_H */ + +/* Define if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define if you have the db library (-ldb). */ +/* #undef HAVE_LIBDB */ + +/* Define if you have the dl library (-ldl). */ +/* #undef HAVE_LIBDL */ + +/* Define if you have the i library (-li). */ +/* #undef HAVE_LIBI */ + +/* Define if you have the nsl library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define if you have the pthread library (-lpthread). */ +/* #undef HAVE_LIBPTHREAD */ + +/* Define if you have the resolv library (-lresolv). */ +/* #undef HAVE_LIBRESOLV */ + +/* Define if you have the socket library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define if you have the util library (-lutil). */ +/* #undef HAVE_LIBUTIL */ + +/* Name of package */ +#define PACKAGE "xchat" + +/* Version number of package */ +#define VERSION "1.8.7" + diff --git a/include/history.h b/include/history.h new file mode 100644 index 0000000..b299b8f --- /dev/null +++ b/include/history.h @@ -0,0 +1,14 @@ + +#define HISTORY_SIZE 100 + +struct history +{ + char *lines[HISTORY_SIZE]; + int pos; + int realpos; +}; + +void history_add (struct history *his, char *text); +void history_free (struct history *his); +char *history_up (struct history *his); +char *history_down (struct history *his); diff --git a/include/inbound.h b/include/inbound.h new file mode 100644 index 0000000..bb67eca --- /dev/null +++ b/include/inbound.h @@ -0,0 +1,13 @@ +void channel_msg (struct server *serv, char *outbuf, char *chan, char *from, + char *text, char fromme); +void clear_channel (struct session *sess); +void set_topic(struct session *sess, char *topic); +void private_msg (struct server *serv, char *tbuf, char *from, char *ip, + char *text); +void channel_action (struct session *sess, char *tbuf, char *chan, char *from, + char *text, int fromme); +void user_new_nick (struct server *serv, char *nick, char *newnick, int quiet); +void set_server_name (struct server *serv, char *name); +void do_dns (struct session *sess, char *tbuf, char *nick, char *host); +void process_line (struct server *serv, char *buf); + diff --git a/include/plugin.h b/include/plugin.h new file mode 100644 index 0000000..e20ddb5 --- /dev/null +++ b/include/plugin.h @@ -0,0 +1,122 @@ + +#ifndef PLUGIN_H +#define PLUGIN_H + +#define MODULE_IFACE_VER 2 +#define XP_CALLBACK(x) ( (int (*) (void *, void *, void *, void *, void *, char) ) x ) + +enum +{ XP_USERCOMMAND = + 0, XP_PRIVMSG, XP_CHANACTION, XP_CHANMSG, XP_CHANGENICK, XP_JOIN, + XP_CHANSETKEY, XP_CHANSETLIMIT, XP_CHANHOP, XP_CHANOP, XP_CHANVOICE, + XP_CHANBAN, XP_CHANRMKEY, XP_CHANRMLIMIT, XP_CHANDEHOP, XP_CHANDEOP, + XP_CHANDEVOICE, XP_CHANUNBAN, XP_CHANEXEMPT, XP_CHANRMEXEMPT, + XP_CHANINVITE, XP_CHANRMINVITE, XP_INBOUND, XP_HIGHLIGHT, + XP_TE_JOIN, XP_TE_CHANACTION, XP_TE_HCHANACTION, XP_TE_CHANMSG, + XP_TE_HCHANMSG, XP_TE_PRIVMSG, XP_TE_CHANGENICK, + XP_TE_NEWTOPIC, XP_TE_TOPIC, XP_TE_KICK, XP_TE_PART, XP_TE_CHANDATE, + XP_TE_TOPICDATE, XP_TE_QUIT, XP_TE_PINGREP, XP_TE_NOTICE, XP_TE_UJOIN, + XP_TE_UCHANMSG, XP_TE_DPRIVMSG, XP_TE_UCHANGENICK, XP_TE_UKICK, + XP_TE_UPART, XP_TE_CTCPSND, XP_TE_CTCPGEN, XP_TE_CTCPGENC, + XP_TE_CHANSETKEY, XP_TE_CHANSETLIMIT, XP_TE_CHANHOP, XP_TE_CHANOP, + XP_TE_CHANVOICE, XP_TE_CHANBAN, XP_TE_CHANRMKEY, XP_TE_CHANRMLIMIT, + XP_TE_CHANDEHOP, XP_TE_CHANDEOP, XP_TE_CHANDEVOICE, XP_TE_CHANUNBAN, + XP_TE_CHANEXEMPT, XP_TE_CHANRMEXEMPT, XP_TE_CHANINVITE, + XP_TE_CHANRMINVITE, XP_TE_CHANMODEGEN, XP_TE_WHOIS1, XP_TE_WHOIS2, + XP_TE_WHOIS3, XP_TE_WHOIS4, XP_TE_WHOIS4T, XP_TE_WHOIS5, XP_TE_WHOIS6, + XP_TE_USERLIMIT, XP_TE_BANNED, XP_TE_INVITE, XP_TE_KEYWORD, + XP_TE_MOTDSKIP, XP_TE_SERVTEXT, XP_TE_INVITED, XP_TE_USERSONCHAN, + XP_TE_NICKCLASH, XP_TE_NICKFAIL, XP_TE_UKNHOST, XP_TE_CONNFAIL, + XP_TE_CONNECT, XP_TE_CONNECTED, XP_TE_SCONNECT, XP_TE_DISCON, + XP_TE_NODCC, XP_TE_DELNOTIFY, XP_TE_ADDNOTIFY, + XP_TE_CHANMODES, XP_TE_RAWMODES, XP_TE_KILL, XP_TE_DCCSTALL, + XP_TE_DCCTOUT, XP_TE_DCCCHATF, XP_TE_DCCFILEERR, XP_TE_DCCRECVERR, + XP_TE_DCCRECVCOMP, XP_TE_DCCCONFAIL, XP_TE_DCCCON, XP_TE_DCCSENDFAIL, + XP_TE_DCCSENDCOMP, XP_TE_DCCOFFER, XP_TE_DCCABORT, XP_TE_DCCIVAL, + XP_TE_DCCCHATREOFFER, XP_TE_DCCCHATOFFERING, + XP_TE_DCCCHATOFFER, XP_TE_DCCRESUMEREQUEST, XP_TE_DCCSENDOFFER, + XP_TE_DCCGENERICOFFER, XP_TE_NOTIFYONLINE, XP_TE_NOTIFYNUMBER, + XP_TE_NOTIFYEMPTY, XP_TE_NOCHILD, XP_TE_ALREADYPROCESS, + XP_TE_SERVERLOOKUP, XP_TE_SERVERCONNECTED, XP_TE_SERVERERROR, + XP_TE_SERVERGENMESSAGE, XP_TE_FOUNDIP, XP_TE_DCCRENAME, XP_TE_CTCPSEND, + XP_TE_MSGSEND, XP_TE_NOTICESEND, XP_TE_WALLOPS, + XP_TE_IGNOREHEADER, XP_TE_IGNORELIST, XP_TE_IGNOREFOOTER, + XP_TE_IGNOREADD, XP_TE_IGNOREREMOVE, XP_TE_RESOLVINGUSER, + XP_TE_IGNOREEMPTY, XP_TE_IGNORECHANGE, XP_TE_NOTIFYOFFLINE, + XP_TE_MALFORMED_FROM, XP_TE_MALFORMED_PACKET, XP_TE_PARTREASON, + XP_TE_UPARTREASON, XP_TE_NEWMAIL, XP_TE_MOTD, XP_TE_PINGTIMEOUT, + XP_TE_UINVITE, XP_TE_BANLIST, XP_TE_CHANLISTHEAD, XP_TE_NOTIFYHEAD, + XP_TE_DCCHEAD, + XP_IF_SEND, XP_IF_RECV, XP_TE_CHANNOTICE, + NUM_XP +}; + +#define EMIT_SIGNAL(s, a, b, c, d, e, f) (fire_signal(s, a, b, c, d, e, f)) +/* #define XP_CALLNEXT(s, a, b, c, d, e, f) if (s != NULL) return s(a, b, c, d, e, f); return 0; */ +/* #define XP_CALLNEXT_ANDSET(s, a, b, c, d, e, f) if (s != NULL) s(a, b, c, d, e, f); return 1; */ + +#define XP_CALLNEXT(s, a, b, c, d, e, f) return 0; +#define XP_CALLNEXT_ANDSET(s, a, b, c, d, e, f) return 1; + + +#ifdef USE_PLUGIN + +struct module +{ + void *handle; + char *name, *desc; + struct module *next, *last; +}; + +struct module_cmd_set +{ + struct module *mod; + struct commands *cmds; + struct module_cmd_set *next, *last; +}; + +#endif + +struct xp_signal +{ + int signal; + int (**naddr) (void *, void *, void *, void *, void *, char); + int (*callback) (void *, void *, void *, void *, void *, char); + /* These aren't used, but needed to keep compatibility --AGL */ + void *next, *last; + void *data; +#ifdef USE_PLUGIN + struct module *mod; +#else + void *padding; +#endif +}; + +struct pevt_stage1 +{ + int len; + char *data; + struct pevt_stage1 *next; +}; + +#ifndef PLUGIN_C +int fire_signal (int, void *, void *, void *, void *, void *, char); +#endif + +extern int current_signal; +extern void *signal_data; +extern GSList *sigroots[NUM_XP]; +extern struct module *modules; + +int module_command (char *cmd, struct session *sess, char *tbuf, + char *word[], char *word_eol[]); +int module_load (char *name, struct session *sess); +int module_list (struct session *sess, char *tbuf, char *word[], + char *word_eol[]); +int module_unload (char *name, struct session *sess); +void module_setup (void); +void signal_setup (void); +void unhook_signal (struct xp_signal *); +int hook_signal (struct xp_signal *); + +#endif /* PLUGIN_H */ diff --git a/include/text.h b/include/text.h new file mode 100644 index 0000000..b804dab --- /dev/null +++ b/include/text.h @@ -0,0 +1,10 @@ +void PrintText (session *sess, unsigned char *text); +void end_logging (int fd); +void setup_logging (session *sess); +void load_text_events (void); +void pevent_save (char *fn); +void printevent_setup (void); +int pevt_build_string (char *input, char **output, int *max_arg); +int text_event (int i); +int pevent_load (char *filename); +void pevent_make_pntevts (void); diff --git a/include/xchat.h b/include/xchat.h new file mode 100644 index 0000000..671117f --- /dev/null +++ b/include/xchat.h @@ -0,0 +1,425 @@ +#include "config.h" + +#ifdef USE_MYGLIB +#include "../fe-text/myglib.h" +#else +#include +#endif +#include /* need time_t */ + +#include "history.h" + +#ifndef HAVE_SNPRINTF +#define snprintf g_snprintf +#endif + +#ifdef USE_DEBUG +#define malloc(n) xchat_malloc(n, __FILE__, __LINE__) +#define realloc(n, m) xchat_realloc(n, m, __FILE__, __LINE__) +#define free(n) xchat_free(n, __FILE__, __LINE__) +#define strdup(n) xchat_strdup(n, __FILE__, __LINE__) +void *xchat_malloc (int size, char *file, int line); +void *xchat_strdup (char *str, char *file, int line); +void xchat_free (void *buf, char *file, int line); +void *xchat_realloc (char *old, int len, char *file, int line); +#endif + +#ifdef SOCKS +#ifdef __sgi +#include +#define INCLUDE_PROTOTYPES 1 +#endif +#include +#endif + +#ifdef USE_OPENSSL +#include /* SSL_() */ +#endif + +#ifdef __EMX__ /* for o/s 2 */ +#define OFLAGS O_BINARY +#define strcasecmp stricmp +#define strncasecmp strnicmp +#define PATH_MAX MAXPATHLEN +#define FILEPATH_LEN_MAX MAXPATHLEN +#else +#ifdef WIN32 +#define OFLAGS O_BINARY +#define sleep(t) _sleep(t*1000) +#include +#define F_OK 0 +#define X_OK 1 +#define W_OK 2 +#define R_OK 4 +#ifndef S_ISDIR +#define S_ISDIR(m) ((m) & _S_IFDIR) +#endif +#define NETWORK_PRIVATE +#else +#define OFLAGS 0 +#endif +#endif + +#define FONTNAMELEN 127 +#define PATHLEN 255 +#define NICKLEN 64 /* including the NULL, so 63 really */ +#define CHANLEN 202 +#define PDIWORDS 32 + +#define safe_strcpy(dest,src,len) strncpy(dest,src,len); \ + dest[len-1] = 0; + +#if defined(ENABLE_NLS) && !defined(_) +# include +# define _(x) gettext(x) +# ifdef gettext_noop +# define N_(String) gettext_noop (String) +# else +# define N_(String) (String) +# endif +#endif +#if !defined(_) +# define N_(String) (String) +# define _(x) (x) +#endif + +struct nbexec +{ + int myfd; + int childpid; + int tochannel; /* making this int keeps the struct 4-byte aligned */ + int iotag; + char *linebuf; + int buffill; + struct session *sess; +}; + +struct xchatprefs +{ + char nick1[64]; + char nick2[64]; + char nick3[64]; + char realname[127]; + char username[127]; + char nick_suffix[4]; /* Only ever holds a one-character string. */ + char awayreason[256]; + char quitreason[256]; + char partreason[256]; + char font_normal[FONTNAMELEN + 1]; + char dialog_font_normal[FONTNAMELEN + 1]; + char font_shell[FONTNAMELEN + 1]; + char doubleclickuser[256]; + char sounddir[PATHLEN + 1]; + char soundcmd[PATHLEN + 1]; + char background[PATHLEN + 1]; + char background_dialog[PATHLEN + 1]; + char dccdir[PATHLEN + 1]; + char bluestring[300]; + char dnsprogram[72]; + char hostname[127]; + char cmdchar[4]; + char trans_file[256]; + char logmask[256]; + char stamp_format[64]; + char timestamp_log_format[64]; + + char proxy_host[64]; + int proxy_port; + int proxy_type; /* 0=disabled, 1=wingate 2=socks4, 3=socks5, 4=http */ + + int first_dcc_send_port; + int last_dcc_send_port; + + int tint_red; + int tint_green; + int tint_blue; + + int dialog_tint_red; + int dialog_tint_green; + int dialog_tint_blue; + + int tabs_position; + int max_auto_indent; + int indent_pixels; + int dialog_indent_pixels; + int dcc_blocksize; + int max_lines; + int notify_timeout; + int dcctimeout; + int dccstalltimeout; + int mainwindow_left; + int mainwindow_top; + int mainwindow_width; + int mainwindow_height; + int dccpermissions; + int recon_delay; + int bantype; + int userlist_sort; + int nu_color; + unsigned long local_ip; + unsigned long dcc_ip; + char dcc_ip_str[16]; + + unsigned int mainwindow_save; + unsigned int perc_color; + unsigned int perc_ascii; + unsigned int hilightnick; + unsigned int use_trans; + unsigned int nopanel; + unsigned int autosave; + unsigned int autodialog; + unsigned int autosave_url; + unsigned int autoreconnect; + unsigned int autoreconnectonfail; + unsigned int invisible; + unsigned int servernotice; + unsigned int wallops; + unsigned int skipmotd; + unsigned int autorejoin; + unsigned int colorednicks; + unsigned int chanmodebuttons; + unsigned int userlistbuttons; + unsigned int userlist_icons; + unsigned int showhostname_in_userlist; + unsigned int nickcompletion; + unsigned int old_nickcompletion; + unsigned int tabchannels; + unsigned int paned_userlist; + unsigned int autodccchat; + unsigned int autodccsend; + unsigned int autoresume; + unsigned int autoopendccsendwindow; + unsigned int autoopendccrecvwindow; + unsigned int autoopendccchatwindow; + unsigned int transparent; + unsigned int tint; + unsigned int dialog_transparent; + unsigned int dialog_tint; + unsigned int dialog_width; + unsigned int dialog_height; + unsigned int stripcolor; + unsigned int timestamp; + unsigned int fastdccsend; + unsigned int dcc_send_fillspaces; + unsigned int dcc_remove; + unsigned int skipserverlist; + unsigned int filterbeep; + unsigned int beepmsg; + unsigned int beepchans; + unsigned int truncchans; + unsigned int privmsgtab; + unsigned int logging; + unsigned int timestamp_logs; + unsigned int newtabstofront; + unsigned int dccwithnick; + unsigned int hilitenotify; + unsigned int hidever; + unsigned int ip_from_server; + unsigned int panelize_hide; + unsigned int panel_vbox; + unsigned int raw_modes; + unsigned int show_away_once; + unsigned int show_away_message; + unsigned int auto_unmark_away; + unsigned int userhost; + unsigned int use_server_tab; + unsigned int notices_tabs; + unsigned int style_namelistgad; + unsigned int style_inputbox; + unsigned int windows_as_tabs; +#ifdef USE_JCODE + unsigned int kanji_conv; +#endif + unsigned int use_fontset; + unsigned int indent_nicks; + unsigned int show_separator; + unsigned int thin_separator; + unsigned int dialog_indent_nicks; + unsigned int dialog_show_separator; + unsigned int treeview; + unsigned int auto_indent; + unsigned int wordwrap; + unsigned int dialog_wordwrap; + unsigned int mail_check; + unsigned int throttle; + unsigned int fudgeservernotice; + unsigned int topicbar; + unsigned int hideuserlist; + unsigned int hidemenu; + unsigned int perlwarnings; + unsigned int lagometer; + unsigned int throttlemeter; + unsigned int hebrew; + unsigned int limitedtabhighlight; + unsigned int pingtimeout; + unsigned int show_invite_in_front_session; + unsigned int show_notify_in_front_session; + unsigned int whois_on_notifyonline; + unsigned int inputgad_superfocus; + unsigned int nickgad; + unsigned int channelbox; + unsigned int persist_chans; + + unsigned int ctcp_number_limit; /*flood */ + unsigned int ctcp_time_limit; /*seconds of floods */ + + unsigned int msg_number_limit; /*same deal */ + unsigned int msg_time_limit; +}; + +/* Session types */ +#define SESS_SERVER 1 +#define SESS_CHANNEL 2 +#define SESS_DIALOG 3 +#define SESS_SHELL 4 +#define SESS_NOTICES 5 +#define SESS_SNOTICES 6 + +struct session +{ + struct server *server; + GSList *userlist; + char channel[CHANLEN]; + char waitchannel[CHANLEN]; /* waiting to join this channel */ + char willjoinchannel[CHANLEN]; /* /join done for this channel */ + char channelkey[64]; /* XXX correct max length? */ + int limit; /* channel user limit */ + int logfd; + + char lastnick[NICKLEN]; /* last nick you /msg'ed */ + + struct history history; + + int ops; /* num. of ops in channel */ + int hops; /* num. of half-oped users */ + int voices; /* num. of voiced people */ + int total; /* num. of users in channel */ + + char *quitreason; + char *topic; + char *current_modes; /* free() me */ + + int mode_timeout_tag; + + struct session *lastlog_sess; + struct setup *setup; + struct nbexec *running_exec; + + struct session_gui *gui; /* initialized by fe_new_window */ + + int userlisthidden; + int type; + int is_tab:1; /* is this a tab or toplevel window? */ + int new_data:1; /* new data avail? (red tab) */ + int nick_said:1; /* your nick mentioned? (blue tab) */ + int ignore_date:1; + int ignore_mode:1; + int ignore_names:1; + int end_of_names:1; + int doing_who:1; /* /who sent on this channel */ + int highlight_tab:1; /* Highlight the channel tab (red-style) */ +}; + +typedef struct session session; + +struct server +{ + int port; + int sok; + int sok4; + int sok6; +#ifdef USE_OPENSSL + SSL *ssl; + int ssl_do_connect_tag; + int use_ssl:1; /* is server SSL capable? */ + int accept_invalid_cert:1; /* ignore result of server's cert. verify */ +#endif + int childread; + int childwrite; + int childpid; + int iotag; + int bartag; + int recondelay_tag; /* reconnect delay timeout */ + char hostname[128]; /* real ip number */ + char servername[128]; /* what the server says is its name */ + char password[86]; + char nick[NICKLEN]; + char linebuf[522]; /* RFC says 512 including \r\n */ + char *last_away_reason; + int pos; /* current position in linebuf */ + int nickcount; + + char *chantypes; /* for 005 numeric - free me */ + char *chanmodes; /* for 005 numeric - free me */ + char *nick_prefixes; /* e.g. "*@%+" */ + char *nick_modes; /* e.g. "aohv" */ + char *bad_nick_prefixes; /* for ircd that doesn't give the modes */ + int modes_per_line; /* 6 on undernet, 4 on efnet etc... */ + + char *eom_cmd; /* end-of-motd command, free it! */ + + GSList *outbound_queue; + int next_send; /* cptr->since in ircu */ + int sendq_len; /* queue size */ + + struct session *front_session; + + struct server_gui *gui; /* initialized by fe_new_server */ + + unsigned int ctcp_counter; /*flood */ + time_t ctcp_last_time; + + unsigned int msg_counter; /*counts the msg tab opened in a certain time */ + time_t msg_last_time; + + /*time_t connect_time;*/ /* when did it connect? */ + time_t lag_sent; + time_t ping_recv; /* when we last got a ping reply */ + time_t away_time; /* when we were marked away */ + + int motd_skipped:1; + int connected:1; + int connecting:1; + int no_login:1; + int skip_next_who:1; /* used for "get my ip from server" */ + int inside_whois:1; + int doing_who:1; /* /dns has been done */ + int end_of_motd:1; /* end of motd reached (logged in) */ + int sent_quit:1; /* sent a QUIT already? */ + int is_newtype:1; /* undernet and dalnet need /list >0,<10000 */ + int is_away:1; + int reconnect_away:1; /* whether to reconnect in is_away state */ + int dont_use_proxy:1; /* to proxy or not to proxy */ + int supports_watch:1; /* supports the WATCH command */ + int bad_prefix:1; /* gave us a bad PREFIX= 005 number */ +}; + +typedef struct server server; + +typedef int (*cmd_callback) (struct session * sess, char *tbuf, char *word[], + char *word_eol[]); + +struct commands +{ + char *name; + cmd_callback callback; + char needserver; + char needchannel; + char *help; +}; + +struct away_msg +{ + struct server *server; + char nick[NICKLEN]; + char *message; +}; + +/* not just for popups, but used for usercommands, ctcp replies, + userlist buttons etc */ + +struct popup +{ + char *cmd; + char *name; +}; diff --git a/include/xchatc.h b/include/xchatc.h new file mode 100644 index 0000000..84215a2 --- /dev/null +++ b/include/xchatc.h @@ -0,0 +1,35 @@ +extern struct xchatprefs prefs; + +extern int auto_connect; +extern int xchat_is_quitting; + +extern session *menu_sess; +extern session *current_tab; + +extern GSList *popup_list; +extern GSList *button_list; +extern GSList *dlgbutton_list; +extern GSList *command_list; +extern GSList *ctcp_list; +extern GSList *replace_list; +extern GSList *sess_list; +extern GSList *serv_list; +extern GSList *dcc_list; +extern GSList *ignore_list; +extern GSList *usermenu_list; +extern GSList *urlhandler_list; + +int tcp_send_len (server *serv, char *buf, int len); +int tcp_send (server *serv, char *buf); +session * find_session_from_channel (char *chan, server *serv); +session * find_dialog (server *serv, char *nick); +session * new_ircwindow (server *serv, char *name, int type); +void set_server_defaults (server *serv); +struct away_msg *find_away_message (struct server *serv, char *nick); +void save_away_message (server *serv, char *nick, char *msg); +int is_server (server * serv); +int is_session (session * sess); +void lag_check (void); +void kill_session_callback (session * killsess); +void xchat_exit (void); +void xchat_exec (char *cmd); diff --git a/redhat/changelog b/redhat/changelog new file mode 100644 index 0000000..1058aeb --- /dev/null +++ b/redhat/changelog @@ -0,0 +1,10 @@ +$Version = "0.1"; +$Release = 1; + +$ChangeLog = ' + + * Thu Feb 7 2002 Stéphane Chatty +- Generation of version 0.1-1 +- First release + +'; diff --git a/redhat/ivyd.init b/redhat/ivyd.init new file mode 100755 index 0000000..b9d9a52 --- /dev/null +++ b/redhat/ivyd.init @@ -0,0 +1,43 @@ +#!/bin/sh +# +# irbox: Starts the in.ivyd super-daemon for the ivyd Ivy relay +# +# Version: @(#) /etc/rc.d/init.d/irbox.init 1.1 +# +# chkconfig: 345 13 87 +# description: This is a daemon that works as a port server for ivyd, \ +# a relay to Ivy for short-lived applications +# processname: in.ivyd +# config: + +# Source function library. +. /etc/rc.d/init.d/functions + +# See how we were called. +case "$1" in + start) + echo -n "Ivy daemon port server... " + daemon in.ivyd -boot + echo + touch /var/lock/subsys/ivyd + ;; + stop) + echo -n "Shutting down Ivy daemon port server " + killproc in.ivyd + rm -f /var/lock/subsys/ivyd + echo + ;; + status) + status in.ivyd + ;; + restart) + $0 stop + $0 start + ;; + *) + echo "*** Usage: ivyd {start|stop|status|restart}" + exit 1 +esac + +exit 0 + diff --git a/redhat/rules b/redhat/rules new file mode 100644 index 0000000..f6a88ae --- /dev/null +++ b/redhat/rules @@ -0,0 +1,12 @@ +$Summary = "ivy-xchat-plugin, an xchat plugin that relays events to an Ivy bus"; +$Name = "ivy-xchat-plugin"; +$Copyright = "LGPL"; +$Vendor = "IntuiLab"; +$Distribution = "Ivy"; +$Group = "System Environment/Daemons"; +$Url = "http://www.tls.cena.fr/products/ivy"; +$BuildArchitectures = "i386"; +$Requires = "ivy-c, xchat"; +$Description = "ivy-xchat-plugin is a plugin for XChat. It relays events to an Ivy bus"; + + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..1b3ae1b --- /dev/null +++ b/src/Makefile @@ -0,0 +1,27 @@ +# +# ivy-xchat-plugin, an xchat plugin that relays events to an Ivy bus +# +# Copyright (C) 2002 +# IntuiLab +# +# Makefile +# +# Author(s): Stephane Chatty +# +# $Id$ +# +# Distributed under the LGPL license +# +LIB = $(PREFIX)/usr/lib/xchat/plugins + +LDFLAGS = -L/usr/X11R6/lib -ggdb +CFLAGS = -Wall +CC = gcc + +ivy-xchat-plugin.so: ivy-xchat-plugin.c + $(CC) $(LDFLAGS) $(CFLAGS) -I../include -DSKIPCONFIG -shared -Wl,-soname,ivy-xchat-plugin.so -o $@ $< -lc -lgtkivy `gtk-config --cflags` + + +install: + test -d $(LIB) || mkdir -p $(LIB) + install -m 755 ivy-xchat-plugin.so $(LIB); diff --git a/src/ivy-xchat-plugin.c b/src/ivy-xchat-plugin.c new file mode 100644 index 0000000..ba67c5d --- /dev/null +++ b/src/ivy-xchat-plugin.c @@ -0,0 +1,225 @@ +/* + * ivy-xchat-plugin, an xchat plugin that relays events to and from an Ivy bus + * + * Copyright (C) 2002 + * IntuiLab + * + * only file + * + * Author: Stephane Chatty + * + * $Id$ + * + * Distributed under the LGPL license + * + */ + + +#define USE_PLUGIN +#include +#include +#include +#include +#include "xchat.h" +#include "xchatc.h" +#include "plugin.h" +#include "text.h" +#include "inbound.h" + +extern struct module *module_find (char *name); +extern void module_add_cmds (struct module_cmd_set *xc_cmds); + +/* a bunch of global variables */ +static char *module_name = "ivy-xchat-plugin"; +static char *module_desc = "This plugin relays basic events from a channel to an Ivy bus."; +static int dorelay = 1; + +/* the commands defined by the module */ + +static struct module_cmd_set cmd_set; + +static int cmd_on (struct session *sess, char *tbuf, char *word[], char *word_eol[]); +static int cmd_off (struct session *sess, char *tbuf, char *word[], char *word_eol[]); +static int cmd_bind (struct session *sess, char *tbuf, char *word[], char *word_eol[]); + +static struct commands cmds[] = { + /* name, callback, needserver, needchannel, help */ + {"IvyOn", cmd_on, 0, 0, "/ivyon"}, + {"IvyOff", cmd_off, 0, 0, "/ivyoff"}, + {"IvyRelay", cmd_bind, 0, 0, "/ivyrelay regexp"}, + {"IvyBind", cmd_bind, 0, 0, "/ivybind regexp"}, + {0, 0, 0, 0, 0} +}; + +/* the event subscriptions and their gear, calbacks, etc */ + +struct xp_signal chanmsg_sig; +int (*chanmsg_next) (void *, void *, void *, void *, void *, char); + + +static int +chanmsg (struct server *serv, char* chan, char *from, char *text, char *d, char fromme) +{ + if (dorelay) + IvySendMsg ("IRC [%s] <%s> %s", chan, from, text); + + XP_CALLNEXT (chanmsg_next, serv, chan, from, text, d, fromme); +} + +/* the Ivy callbacks and their help function */ + +static void +IvyBuildMessage (char* p, IvyClientPtr app, int argc, char *argv[]) +{ + int i; + + p += sprintf (p, "%s sent", IvyGetApplicationName (app)); + + /* should limit size of what I add to buf! */ + for (i = 0; i < argc; i++) + p += sprintf (p, " '%s'", argv[i]); + sprintf (p, "\n"); +} + +static void +IvyBindCallback (IvyClientPtr app, void *user_data, int argc, char **argv) +{ + struct session *sess = (struct session*) user_data; + char buf [512]; + + /* forget it if there's no session to print to */ + if (!sess) + return; + + /* print the message */ + IvyBuildMessage (buf, app, argc, argv); + PrintText (sess, buf); +} + +static void +IvyRelayCallback (IvyClientPtr app, void *user_data, int argc, char **argv) +{ + struct session *sess = (struct session*) user_data; + char buf1 [512]; + char buf2 [512]; + + /* forget it if there's no session to print to */ + if (!sess) + return; + + /* relay the message to channel, and print it */ + IvyBuildMessage (buf1, app, argc, argv); + sprintf (buf2, "PRIVMSG %s :%s\r\n", sess->channel, buf1); + tcp_send (sess->server, buf2); + EMIT_SIGNAL (XP_TE_UCHANMSG, sess, sess->server->nick, buf1, "moi", 0, 0); +} + + +/* the commands */ + +static int +cmd_on (struct session *sess, char *tbuf, char *word[], char *word_eol[]) +{ + if (dorelay == 0) { + PrintText (sess, "Relaying to Ivy is on!\n"); + dorelay = 1; + } else { + PrintText (sess, "Relaying to Ivy was already on\n"); + } + return 0; +} + +static int +cmd_off (struct session *sess, char *tbuf, char *word[], char *word_eol[]) +{ + if (dorelay == 1) { + PrintText (sess, "Relaying to Ivy is off!\n"); + dorelay = 0; + } else { + PrintText (sess, "Relaying to Ivy was already off\n"); + } + return 0; +} + +static int +cmd_bind (struct session *sess, char *tbuf, char *word[], char *word_eol[]) +{ + char buf[512]; + char* p; + MsgCallback cb; + const char* action; + + /* determine which command was used, then skip it */ + p = strstr (word[1], "ivyrelay"); + cb = p ? IvyRelayCallback : IvyBindCallback; + action = p ? "Relaying" : "Binding"; + p = p ? p+8 : word[1]+7; + + /* skip white space and detect empty regexps */ + while (*p == ' ') + ++p; + if (*p == '\0') { + PrintText (sess, "Usage : /ivybind or /ivyrelay \n"); + return 0; + } + + /* bind and provide confirmation */ + IvyBindMsg (cb, sess, p); + sprintf (buf, "%s Ivy regexp %s\n", action, p); + PrintText (sess, buf); + + return 0; +} + + + +/* and finally the module init and cleanup functions */ + +int +module_init (int ver, struct module *mod, struct session *sess) +{ + /** first let's do our connection work as an xchat plugin **/ + + /* version check */ + if (ver != MODULE_IFACE_VER) + return 1; + + /* check whether we are already loaded */ + if (module_find (module_name) != 0) { + PrintText (sess, "Module ivy-xchat-plugin already loaded\n"); + return 1; + } + + /* make an announcement and register our name and description */ + PrintText (sess, "Loaded module ivy-xchat-plugin\n"); + mod->name = module_name; + mod->desc = module_desc; + + /* register our commands */ + cmd_set.mod = mod; + cmd_set.cmds = cmds; + module_add_cmds (&cmd_set); + + + /* and now register our event subscriptions */ + + chanmsg_sig.signal = XP_CHANMSG; + chanmsg_sig.callback = XP_CALLBACK (chanmsg); + chanmsg_sig.naddr = &chanmsg_next; + chanmsg_sig.mod = mod; + hook_signal (&chanmsg_sig); + + /** then let's connect to Ivy **/ + IvyGtkChannelInit (); + IvyInit ("ivy-xchat-plugin", 0, 0, 0, 0, 0); + IvyStart (0); + return 0; +} + +void +module_cleanup (struct module *mod, struct session *sess) +{ + PrintText (sess, "Unloading ivy-xchat-plugin module.\n"); + IvyStop (); +} + -- cgit v1.1