00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef lint
00021 static const char rcsid[] = "$Id: scriptcmds.c,v 1.47 2005-06-09 02:56:44 stdarg Exp $";
00022 #endif
00023
00024 #include "server.h"
00025
00026
00027 extern int cycle_delay;
00028 extern current_server_t current_server;
00029
00030
00031 extern char *global_output_string;
00032
00033
00034 extern char *global_input_string;
00035
00036
00037 static int script_isbotnick(char *nick)
00038 {
00039 return match_my_nick(nick);
00040 }
00041
00042 static int script_irccmp(char *nick1, char *nick2)
00043 {
00044 return (current_server.strcmp)(nick1, nick2);
00045 }
00046
00047 static int script_server_list(script_var_t *retval)
00048 {
00049 server_t *s;
00050
00051 retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
00052 retval->len = 0;
00053
00054 for (s = server_list; s; s = s->next) {
00055 script_list_append(retval, script_list(3, script_string(s->host, -1), script_string(s->pass, -1), script_int(s->port)));
00056 }
00057 return(0);
00058 }
00059
00060 static int name_to_priority(const char *queue, const char *next)
00061 {
00062 int prio;
00063
00064
00065 if (!next) queue = NULL;
00066 else if (!queue) {
00067
00068
00069 if (!strcasecmp(next, "next")) queue = NULL;
00070 else {
00071 queue = next;
00072 next = NULL;
00073 }
00074 }
00075 else if (!strcasecmp(queue, "next")) {
00076
00077 const char *temp = next;
00078 next = queue;
00079 queue = temp;
00080 }
00081
00082
00083 if (!queue) prio = SERVER_NORMAL;
00084 else if (!strcasecmp(queue, "noqueue")) prio = SERVER_NOQUEUE;
00085 else if (!strcasecmp(queue, "slow")) prio = SERVER_SLOW;
00086 else if (!strcasecmp(queue, "quick")) prio = SERVER_QUICK;
00087 else prio = SERVER_NORMAL;
00088
00089 if (next) prio |= SERVER_NEXT;
00090
00091 return(prio);
00092 }
00093
00094 static int script_putserv(char *queue, char *next, char *text)
00095 {
00096 int prio;
00097
00098 prio = name_to_priority(queue, next);
00099 printserv(prio, "%s\r\n", text);
00100
00101 return(0);
00102 }
00103
00104 static int script_jump(int nargs, int num)
00105 {
00106 if (nargs) server_set_next(num);
00107
00108 cycle_delay = server_config.cycle_delay;
00109 kill_server("changing servers");
00110
00111 return(0);
00112 }
00113
00114 static int script_dcc_send_info(int idx, char *what)
00115 {
00116 int field, value;
00117
00118 if (!strcasecmp(what, "bytes_left"))
00119 field = DCC_SEND_LEFT;
00120 else if (!strcasecmp(what, "bytes_sent"))
00121 field = DCC_SEND_SENT;
00122 else if (!strcasecmp(what, "total_cps"))
00123 field = DCC_SEND_CPS_TOTAL;
00124 else if (!strcasecmp(what, "snapshot_cps"))
00125 field = DCC_SEND_CPS_SNAPSHOT;
00126 else if (!strcasecmp(what, "acks"))
00127 field = DCC_SEND_ACKS;
00128 else if (!strcasecmp(what, "bytes_acked"))
00129 field = DCC_SEND_BYTES_ACKED;
00130 else if (!strcasecmp(what, "resumed_at"))
00131 field = DCC_SEND_RESUMED_AT;
00132 else if (!strcasecmp(what, "request_time"))
00133 field = DCC_SEND_REQUEST_TIME;
00134 else if (!strcasecmp(what, "connect_time"))
00135 field = DCC_SEND_CONNECT_TIME;
00136 else
00137 return(-1);
00138
00139 if (dcc_send_info(idx, field, &value) < 0)
00140 return(-1);
00141
00142 return(value);
00143 }
00144
00145 static int script_channel_list(script_var_t *retval)
00146 {
00147 channel_t *chan;
00148
00149 retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
00150 retval->len = 0;
00151
00152 for (chan = channel_head; chan; chan = chan->next) {
00153 script_list_append(retval, script_string(chan->name, -1));
00154 }
00155 return(0);
00156 }
00157
00158 static int script_channel_members(script_var_t *retval, char *chan_name)
00159 {
00160 channel_t *chan;
00161 channel_member_t *m;
00162
00163 retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
00164 retval->len = 0;
00165
00166 chan = channel_probe(chan_name, 0);
00167 if (!chan) return(-1);
00168
00169 for (m = chan->member_head; m; m = m->next) {
00170 script_list_append(retval, script_string(m->nick, -1));
00171 }
00172
00173 return(0);
00174 }
00175
00176 static int script_channel_topic(script_var_t *retval, char *chan_name)
00177 {
00178 channel_t *chan;
00179
00180 retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
00181 retval->len = 0;
00182
00183 chan = channel_probe(chan_name, 0);
00184 if (!chan) return(-1);
00185
00186 script_list_append(retval, script_string(chan->topic, -1));
00187 script_list_append(retval, script_string(chan->topic_nick, -1));
00188 script_list_append(retval, script_int(chan->topic_time));
00189 return(0);
00190 }
00191
00192 static int script_channel_mask_list(script_var_t *retval, char *chan_name, char *type)
00193 {
00194 channel_t *chan;
00195 channel_mask_t *m;
00196 channel_mask_list_t *l;
00197
00198 retval->type = SCRIPT_ARRAY | SCRIPT_FREE | SCRIPT_VAR;
00199 retval->len = 0;
00200
00201 chan = channel_probe(chan_name, 0);
00202 if (!chan) return(-1);
00203
00204 l = channel_get_mask_list(chan, type[0]);
00205 if (!l) return(-1);
00206
00207 for (m = l->head; m; m = m->next) {
00208 script_list_append(retval,
00209 script_list(3,
00210 script_string(m->mask, -1),
00211 script_string(m->set_by, -1),
00212 script_int(m->time)
00213 )
00214 );
00215 }
00216 return(0);
00217 }
00218
00219 static char *script_channel_mode(char *chan, char *nick)
00220 {
00221 char *buf;
00222
00223 buf = malloc(64);
00224 channel_mode(chan, nick, buf);
00225 return(buf);
00226 }
00227
00228 static const char *script_channel_mode_arg(char *chan, char *mode)
00229 {
00230 const char *value = NULL;
00231
00232 channel_mode_arg(chan, *mode, &value);
00233 return(value);
00234 }
00235
00236 static char *script_channel_key(char *chan_name)
00237 {
00238 channel_t *chan;
00239
00240 chan = channel_probe(chan_name, 0);
00241 if (chan) return(chan->key);
00242 return(NULL);
00243 }
00244
00245 static int script_channel_limit(char *chan_name)
00246 {
00247 channel_t *chan;
00248
00249 chan = channel_probe(chan_name, 0);
00250 if (chan) return(chan->limit);
00251 return(-1);
00252 }
00253
00254 static char *script_schan_get(char *chan_name, char *setting)
00255 {
00256 channel_t *chan = channel_probe(chan_name, 0);
00257 char *value;
00258
00259 if (!chan) return(NULL);
00260 channel_get(chan, &value, setting, 0, NULL);
00261 return(value);
00262 }
00263
00264 static int script_schan_set(char *chan_name, char *setting, char *value)
00265 {
00266 channel_t *chan = channel_probe(chan_name, 1);
00267
00268 if (!chan) return(-1);
00269 return channel_set(chan, value, setting, 0, NULL);
00270 }
00271
00272
00273
00274 static int script_queue_len(char *qname, char *next)
00275 {
00276 int prio;
00277 queue_t *queue;
00278
00279
00280 prio = name_to_priority(qname, next);
00281 queue = queue_get_by_priority(prio);
00282
00283 return(queue->len);
00284 }
00285
00286 static void get_queue_entry(char *qname, char *next, int num, queue_t **queue_ptr, queue_entry_t **queue_entry_ptr)
00287 {
00288 int prio;
00289 queue_t *queue;
00290 queue_entry_t *q;
00291
00292
00293 prio = name_to_priority(qname, next);
00294 queue = queue_get_by_priority(prio);
00295
00296
00297 if (num >= 0 && num < queue->len/2) {
00298 for (q = queue->queue_head; q && num > 0; q = q->next) {
00299 num--;
00300 }
00301 }
00302 else if (num >= queue->len/2 && num < queue->len) {
00303 num -= (queue->len/2);
00304 for (q = queue->queue_tail; q && num > 0; q = q->prev) {
00305 num--;
00306 }
00307 }
00308 else q = NULL;
00309
00310 if (queue_ptr) *queue_ptr = queue;
00311 if (queue_entry_ptr) *queue_entry_ptr = q;
00312 }
00313
00314 static char *script_queue_get(char *qname, char *next, int num)
00315 {
00316 queue_entry_t *q;
00317 char buf[1024];
00318 int remaining;
00319
00320 get_queue_entry(qname, next, num, NULL, &q);
00321 if (!q) return(NULL);
00322
00323 remaining = sizeof(buf);
00324 queue_entry_to_text(q, buf, &remaining);
00325 if (remaining < sizeof(buf)) buf[sizeof(buf)-remaining-1] = 0;
00326 else buf[0] = 0;
00327
00328 return strdup(buf);
00329 }
00330
00331 static int script_queue_set(char *qname, char *next, int num, char *msg)
00332 {
00333 queue_entry_t *q;
00334
00335 get_queue_entry(qname, next, num, NULL, &q);
00336 if (!q) return(-1);
00337
00338 queue_entry_from_text(q, msg);
00339 return(0);
00340 }
00341
00342 static int script_queue_insert(char *qname, char *next, int num, char *msg)
00343 {
00344 queue_t *queue;
00345 queue_entry_t *q, *newq;
00346
00347 get_queue_entry(qname, next, num, &queue, &q);
00348 newq = queue_new(msg);
00349 if (!q) queue_append(queue, newq);
00350 else {
00351 queue->len++;
00352 newq->next = q;
00353 newq->prev = q->prev;
00354 if (q->prev) q->prev->next = newq;
00355 else queue->queue_head = newq;
00356 q->prev = q;
00357 }
00358
00359 return(0);
00360 }
00361
00362
00363 static int script_supports(const char *name)
00364 {
00365 const char *value;
00366
00367 if (!server_support(name, &value)) {
00368
00369 return(1);
00370 }
00371 return(0);
00372 }
00373
00374 static const char *script_support_val(const char *name)
00375 {
00376 const char *value;
00377 server_support(name, &value);
00378 return value;
00379 }
00380
00381 static script_linked_var_t server_script_vars[] = {
00382 {"", "servidx", ¤t_server.idx, SCRIPT_INTEGER | SCRIPT_READONLY, NULL},
00383 {"", "server", &server_list_index, SCRIPT_INTEGER | SCRIPT_READONLY, NULL},
00384 {"", "botnick", ¤t_server.nick, SCRIPT_STRING | SCRIPT_READONLY, NULL},
00385 {"", "myip", ¤t_server.myip, SCRIPT_STRING, NULL},
00386 {"", "mylongip", ¤t_server.mylongip, SCRIPT_UNSIGNED, NULL},
00387 {"", "server_input_string", &global_input_string, SCRIPT_STRING, NULL},
00388 {"", "server_output_string", &global_output_string, SCRIPT_STRING, NULL},
00389 {0}
00390 };
00391
00392 static script_command_t server_script_cmds[] = {
00393
00394 {"", "irccmp", script_irccmp, NULL, 2, "ss", "str1 str2", SCRIPT_INTEGER, 0},
00395 {"", "get_uhost", uhost_cache_lookup, NULL, 1, "s", "nick", SCRIPT_STRING, 0},
00396
00397
00398 {"", "nick_add", nick_add, NULL, 1, "s", "nick", SCRIPT_INTEGER, 0},
00399 {"", "nick_del", nick_del, NULL, 1, "i", "nick-num", SCRIPT_INTEGER, 0},
00400 {"", "nick_clear", nick_clear, NULL, 0, "", "", SCRIPT_INTEGER, 0},
00401 {"", "nick_find", nick_find, NULL, 0, "s", "nick", SCRIPT_INTEGER, 0},
00402 {"", "isbotnick", script_isbotnick, NULL, 1, "s", "nick", SCRIPT_INTEGER, 0},
00403
00404
00405 {"", "jump", script_jump, NULL, 0, "i", "num", SCRIPT_INTEGER, SCRIPT_VAR_ARGS | SCRIPT_PASS_COUNT},
00406 {"", "server_list", script_server_list, NULL, 0, "", "", 0, SCRIPT_PASS_RETVAL},
00407 {"", "server_add", server_add, NULL, 1, "sis", "host ?port? ?pass?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
00408 {"", "server_del", server_del, NULL, 1, "i", "server-num", SCRIPT_INTEGER, 0},
00409 {"", "server_clear", server_clear, NULL, 0, "", "", SCRIPT_INTEGER, 0},
00410 {"", "server_find", server_find, NULL, 1, "sis", "host ?port? ?pass?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
00411
00412
00413 {"", "server_supports", script_supports, NULL, 1, "s", "name", SCRIPT_INTEGER, 0},
00414 {"", "server_support_val", script_support_val, NULL, 1, "s", "name", SCRIPT_STRING, 0},
00415
00416
00417 {"", "dcc_chat", dcc_start_chat, NULL, 1, "si", "nick ?timeout?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
00418 {"", "dcc_send", dcc_start_send, NULL, 2, "ssi", "nick filename ?timeout?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
00419 {"", "dcc_send_info", script_dcc_send_info, NULL, 2, "is", "idx stat", SCRIPT_INTEGER, 0},
00420 {"", "dcc_accept_send", dcc_accept_send, NULL, 7, "sssiisii", "nick localfile remotefile size resume ip port ?timeout?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
00421
00422
00423 {"", "channel_list", script_channel_list, NULL, 0, "", "", 0, SCRIPT_PASS_RETVAL},
00424 {"", "channel_members", script_channel_members, NULL, 1, "s", "channel", 0, SCRIPT_PASS_RETVAL},
00425 {"", "channel_topic", script_channel_topic, NULL, 1, "s", "channel", 0, SCRIPT_PASS_RETVAL},
00426 {"", "channel_mask_list", script_channel_mask_list, NULL, 2, "ss", "channel type", 0, SCRIPT_PASS_RETVAL},
00427 {"", "channel_mode", script_channel_mode, NULL, 1, "ss", "channel ?nick?", SCRIPT_STRING|SCRIPT_FREE, SCRIPT_VAR_ARGS},
00428 {"", "channel_mode_arg", script_channel_mode_arg, NULL, 2, "ss", "channel mode", SCRIPT_STRING, 0},
00429 {"", "channel_key", script_channel_key, NULL, 1, "s", "channel", SCRIPT_STRING, 0},
00430 {"", "channel_limit", script_channel_limit, NULL, 1, "s", "channel", SCRIPT_INTEGER, 0},
00431
00432
00433 {"", "channel_get", script_schan_get, NULL, 2, "ss", "channel setting", SCRIPT_STRING, 0},
00434 {"", "channel_set", script_schan_set, NULL, 3, "sss", "channel setting value", SCRIPT_INTEGER, 0},
00435
00436
00437 {"", "server_fake_input", server_parse_input, NULL, 1, "s", "text", SCRIPT_INTEGER, 0},
00438 {"", "putserv", script_putserv, NULL, 1, "sss", "?queue? ?next? text", SCRIPT_INTEGER, SCRIPT_VAR_ARGS | SCRIPT_VAR_FRONT},
00439
00440
00441 {"", "server_queue_len", script_queue_len, NULL, 1, "ssi", "queue ?next?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
00442 {"", "server_queue_get", script_queue_get, NULL, 1, "ssi", "?queue? ?next? msgnum", SCRIPT_STRING|SCRIPT_FREE, SCRIPT_VAR_ARGS|SCRIPT_VAR_FRONT},
00443 {"", "server_queue_set", script_queue_set, NULL, 2, "ssis", "?queue? ?next? msgnum msg", SCRIPT_INTEGER, SCRIPT_VAR_ARGS|SCRIPT_VAR_FRONT},
00444 {"", "server_queue_insert", script_queue_insert, NULL, 2, "ssis", "?queue? ?next? msgnum msg", SCRIPT_INTEGER, SCRIPT_VAR_ARGS|SCRIPT_VAR_FRONT},
00445
00446 {0}
00447 };
00448
00449 int server_script_init()
00450 {
00451 script_create_commands(server_script_cmds);
00452 script_link_vars(server_script_vars);
00453 return(0);
00454 }
00455
00456 int server_script_destroy()
00457 {
00458 script_delete_commands(server_script_cmds);
00459 script_unlink_vars(server_script_vars);
00460 return(0);
00461 }