]> jfr.im git - irc/thales.git/blame - guile-libircclient/src/init.c
Moved libircclient library as just package example
[irc/thales.git] / guile-libircclient / src / init.c
CommitLineData
f1b54f23
DB
1#include "definitions.h"
2#include <assert.h>
3#include <ctype.h>
4static irc_callbacks_t irc_callbacks;
5static SCM irc_error_symbol;
6static scm_t_bits scm_t_irc_session_tag;
7
8void
9scm_throw_from_irc_session (irc_session_t * session)
10{
11 int errno = irc_errno (session);
12 const char *errmsg = irc_strerror (errno);
13 SCM scm_errmsg = scm_from_locale_string (errmsg);
14 scm_throw (irc_error_symbol, scm_list_1 (scm_errmsg));
15}
16
17irc_session_t*
18scm_to_irc_session(SCM scm_session)
19{
20 scm_assert_smob_type (scm_t_irc_session_tag, scm_session);
21 struct scm_t_irc_session *scm_t_session = SCM_SMOB_DATA(scm_session);
22 assert(scm_t_session);
23 return scm_t_session->session;
24}
25
26char*
27guarded_scm_to_ascii_string (SCM string_or_false)
28{
29 if (scm_is_false (string_or_false))
30 return NULL;
31
32 char *str = scm_to_locale_string (string_or_false);
33 scm_dynwind_free (str);
34 return str;
35}
36
37static inline SCM
38scm_from_string_array (const char **args, unsigned int count)
39{
40 SCM result = SCM_EOL;
41 for (unsigned int index = 0; index != count; ++index)
42 {
43 SCM current_parameter = scm_from_locale_string (args[index]);
44 SCM current_parameter_list = scm_list_1 (current_parameter);
45
46 result = scm_append (scm_list_2 (current_parameter_list, result));
47 }
48 return scm_reverse(result);
49}
50
51static void
52generic_event_handler (irc_session_t * sesion, const char *event,
53 const char *origin, const char **params,
54 unsigned int count)
55{
56 struct scm_t_irc_session *scm_irc_session = irc_get_ctx (sesion);
57 SCM scm_params = scm_from_string_array (params, count);
58
59 scm_call_4 (scm_irc_session->event_dispatcher, scm_irc_session->closure,
60 scm_from_locale_string (event), scm_from_locale_string (origin),
61 scm_params);
62}
63
64SCM_DEFINE (scm_create_irc_session,
65 "irc-create-session", 3, 0, 0,
66 (SCM closure, SCM event_dispatcher, SCM numeric_dispatcher),
67 "Create irc session with callback functions specified by alist. This is"
68 "low-level api you should not use directly in user-level scheme code.")
69{
70 struct scm_t_irc_session *scm_irc_session;
71 irc_session_t *irc_session = irc_create_session (&irc_callbacks);
72 scm_irc_session =
73 scm_gc_malloc (sizeof (struct scm_t_irc_session), "irc-session");
74 irc_set_ctx (irc_session, scm_irc_session);
75
76 scm_irc_session->closure = closure;
77 scm_irc_session->event_dispatcher = event_dispatcher;
78 scm_irc_session->numeric_dispatcher = numeric_dispatcher;
79 scm_irc_session->session = irc_session;
80
81 return scm_new_smob (scm_t_irc_session_tag, (scm_t_bits) scm_irc_session);
82}
83
84SCM_DEFINE (scm_irc_connect, "irc-connect", 8, 0, 0,
85 (SCM scm_session, SCM scm_server, SCM scm_port,
86 SCM scm_nick, SCM scm_server_pass, SCM scm_username,
87 SCM scm_realname, SCM scm_use_ipv6_p),
88 "This function prepares and initiates a connection to the IRC"
89 "server. The connection is done asynchronously (see"
90 "event_connect), so the success return value means that"
91 "connection was initiated successfully.")
92{
93 irc_session_t *session = scm_to_irc_session(scm_session);
94 scm_dynwind_begin (0);
95 char *server = guarded_scm_to_ascii_string (scm_server);
96 char *nick = guarded_scm_to_ascii_string (scm_nick);
97 char *server_pass = guarded_scm_to_ascii_string (scm_server_pass);
98 char *username = guarded_scm_to_ascii_string (scm_username);
99 char *realname = guarded_scm_to_ascii_string (scm_realname);
100 unsigned short int port = scm_to_uint16 (scm_port);
101 int (*connect_fn) (irc_session_t *, const char *, unsigned short,
102 const char *, const char *, const char *, const char *)
103 = scm_to_bool (scm_use_ipv6_p) ? irc_connect6 : irc_connect;
104 int error =
105 (*connect_fn) (session, server, port, server_pass,
106 nick, username, realname);
107 if (error)
108 scm_throw_from_irc_session (session);
109
110 scm_dynwind_end ();
111 scm_remember_upto_here_1 (scm_session);
112 return SCM_UNSPECIFIED;
113}
114
115SCM_DEFINE (scm_irc_run, "irc-run", 1, 0, 0,
116 (SCM scm_session),
117 "This function goes into the loop, processing the IRC events, and"
118 "calling appropriate callbacks. This function will not return until"
119 "the server connection is terminated – either by server, or by calling"
120 "irc_cmd_quit. This function should be used, if you don’t need"
121 "asynchronous request processing (i.e. your bot just reacts on the"
122 "events, and doesn’t generate it asynchronously). Even in last case,"
123 "you still can call irc_run, and start the asynchronous thread in"
124 "event_connect handler.")
125{
126 scm_assert_smob_type (scm_t_irc_session_tag, scm_session);
127 struct scm_t_irc_session *c_scm_session = SCM_SMOB_DATA (scm_session);
128 irc_run (c_scm_session->session);
129 /*
130 * Error is not checked due bug in underlying library.
131 */
132 scm_remember_upto_here_1 (scm_session);
133 return SCM_UNSPECIFIED;
134}
135
136static SCM
137scm_mark_irc_session (SCM s)
138{
139 struct scm_t_irc_session *scm_session = SCM_SMOB_DATA(s);
140
141 scm_gc_mark (scm_session->event_dispatcher);
142 scm_gc_mark (scm_session->numeric_dispatcher);
143 return scm_session->closure;
144}
145
146static size_t
147scm_free_irc_session (SCM s)
148{
149 struct scm_t_irc_session *scm_session = SCM_SMOB_DATA(s);
150 if (scm_session->session)
151 {
152 irc_disconnect(scm_session->session);
153 irc_destroy_session (scm_session->session);
154 }
155 scm_session->session = NULL;
156 return 0;
157}
158
159SCM_DEFINE (scm_irc_disconnect, "irc-disconnect", 1, 0, 0,
160 (SCM s), "Rude disconnect.")
161{
162 irc_session_t *session = scm_to_irc_session(s);
163 irc_disconnect(session);
164 return SCM_UNSPECIFIED;
165}
166
167
168static inline void
169setup_generic_event_handler (irc_callbacks_t * cb)
170{
171 cb->event_connect
172 = cb->event_nick
173 = cb->event_quit
174 = cb->event_join
175 = cb->event_part
176 = cb->event_mode
177 = cb->event_umode
178 = cb->event_topic
179 = cb->event_kick
180 = cb->event_channel
181 = cb->event_privmsg
182 = cb->event_notice
183 = cb->event_channel_notice
184 = cb->event_invite = generic_event_handler;
185}
186
187#include "cmd.c"
188#include "misc.c"
189void
190scm_init_im_irc ()
191{
192 irc_error_symbol = scm_from_locale_symbol ("irc-error");
193 setup_generic_event_handler (&irc_callbacks);
194 scm_t_irc_session_tag =
195 scm_make_smob_type ("irc-session", sizeof (struct scm_t_irc_session));
196 scm_set_smob_mark (scm_t_irc_session_tag, scm_mark_irc_session);
197 scm_set_smob_free (scm_t_irc_session_tag, scm_free_irc_session);
198
199#ifndef SCM_MAGIC_SNARFER
200#include "init.x"
201#endif
202}