home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / yagirc-0.51.tar.gz / yagirc-0.51.tar / yagirc-0.51 / events-numeric.c < prev    next >
C/C++ Source or Header  |  1998-05-09  |  12KB  |  466 lines

  1. /*
  2.  
  3.  events-numeric.c : Functions to handle (numeric) IRC server replies
  4.  
  5.     Copyright (C) 1998 Timo Sirainen
  6.  
  7.     This program is free software; you can redistribute it and/or modify
  8.     it under the terms of the GNU General Public License as published by
  9.     the Free Software Foundation; either version 2 of the License, or
  10.     (at your option) any later version.
  11.  
  12.     This program is distributed in the hope that it will be useful,
  13.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.     GNU General Public License for more details.
  16.  
  17.     You should have received a copy of the GNU General Public License
  18.     along with this program; if not, write to the Free Software
  19.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. */
  21.  
  22. #include <stdio.h>
  23. #include <stdarg.h>
  24. #include <string.h>
  25. #include <sys/time.h>
  26.  
  27. #include <glib.h>
  28.  
  29. #include "os.h"
  30. #include "irc.h"
  31. #include "txt.h"
  32. #include "gui.h"
  33. #include "ctcp.h"
  34. #include "events.h"
  35. #include "script.h"
  36.  
  37. static char tmpstr[600];
  38.  
  39. static CHAN_REC *names_chan; /* /NAMES */
  40. static GList *ison_users, *ison_tempusers; /* /ISON */
  41.  
  42. /* Initialize events */
  43. void events_init(void)
  44. {
  45.     names_chan = NULL;
  46.     ison_users = NULL;
  47.     ison_tempusers = NULL;
  48. }
  49.  
  50. void events_deinit(void)
  51. {
  52.     GList *tmp;
  53.  
  54.     for (tmp = g_list_first(ison_users); tmp != NULL; tmp = tmp->next)
  55.         g_free(tmp->data);
  56.     g_list_free(ison_users);
  57. }
  58.  
  59. /* Get next parameter */
  60. char *event_get_param(char **data)
  61. {
  62.     char *pos;
  63.  
  64.     g_return_val_if_fail(data != NULL, NULL);
  65.     g_return_val_if_fail(*data != NULL, NULL);
  66.  
  67.     if (**data == ':')
  68.     {
  69.         pos = *data;
  70.         *data += strlen(*data);
  71.         return pos+1; /* easy. :) */
  72.     }
  73.  
  74.     pos = *data;
  75.     while (**data != '\0' && **data != ' ') (*data)++;
  76.     if (**data == ' ') *(*data)++ = '\0';
  77.  
  78.     return pos;
  79. }
  80.  
  81. /* Get next count parameters from data */
  82. char *event_get_params(char *data, int count, ...)
  83. {
  84.     char **str, *tmp;
  85.  
  86.     va_list args;
  87.     va_start(args, count);
  88.  
  89.     while (count-- > 0)
  90.     {
  91.         str = (char **) va_arg(args, char **);
  92.         tmp = event_get_param(&data);
  93.         if (str != NULL) *str = tmp;
  94.     }
  95.     va_end(args);
  96.  
  97.     return data;
  98. }
  99.  
  100. void eirc_welcome(char *data)
  101. {
  102.     /* first welcome message found - we're connected now! */
  103.     eserver->connected = 1;
  104.     return;
  105. }
  106.  
  107. void eirc_connected(char *data)
  108. {
  109.     /* last welcome message found - commands can be sent to server now. */
  110. #ifdef USE_SCRIPT
  111.     char *tmp;
  112.  
  113.     tmp = (char *) g_malloc(strlen(eserver->name)+20);
  114.     sprintf(tmp, "%d %s", eserver->handle, eserver->name);
  115.     script_event(eserver, esendnick, esendaddr, "CONNECTED", tmp);
  116.     g_free(tmp);
  117. #endif
  118.     gui_connected(eserver, 1);
  119. }
  120.  
  121. void eirc_nick_in_use(char *data)
  122. {
  123.     char *nick;
  124.  
  125.     if (eserver->connected)
  126.         return; /* Already connected, no need to handle this anymore. */
  127.  
  128.     /* nick already in use - need to change it .. */
  129.     nick = eserver->nick;
  130.     if (strlen(nick) < 9)
  131.         strcpy(nick+strlen(nick), "_");
  132.     else
  133.     {
  134.         int n;
  135.  
  136.         /* keep adding numbers to end of nick */
  137.         for (n = 8; n > 0; n--)
  138.         {
  139.             if (nick[n] < '0' || nick[n] > '9')
  140.             {
  141.                 nick[n] = '1';
  142.                 break;
  143.             }
  144.             else
  145.             {
  146.                 if (nick[n] < '9')
  147.                 {
  148.                     nick[n]++;
  149.                     break;
  150.                 }
  151.                 else
  152.                     nick[n] = '0';
  153.             }
  154.         }
  155.     }
  156.  
  157.     eserver->connected = 1;
  158.     sprintf(tmpstr, "NICK %s", nick);
  159.     irc_send_cmd(eserver, tmpstr);
  160.  
  161.     eserver->connected = 0;
  162. }
  163.  
  164. void eirc_names_list(char *data)
  165. {
  166.     char *type, *channel, *names, *ptr;
  167.  
  168.     g_return_if_fail(data != NULL);
  169.  
  170.     /* type = '=' = public, '*' = private, '@' = secret */
  171.     event_get_params(data, 4, NULL, &type, &channel, &names);
  172.  
  173.     drawtext(edefwin, TXT_TYPE_SERVER_TEXT, IRCTXT_NAMES, channel, names);
  174.  
  175.     if (names_chan == NULL)
  176.     {
  177.         names_chan = channel_joined(eserver, channel);
  178.         if (names_chan == NULL) return;
  179.         if (names_chan->nicks != NULL)
  180.         {
  181.             GList *tmp;
  182.  
  183.             for (tmp = g_list_first(names_chan->nicks); tmp != NULL; tmp = tmp->next)
  184.                 g_free(tmp->data);
  185.             g_list_free(names_chan->nicks);
  186.         }
  187.         names_chan->nicks = NULL;
  188.     }
  189.  
  190.     while (*names != '\0')
  191.     {
  192.         while (*names == ' ') names++;
  193.         ptr = names;
  194.         while (*names != '\0' && *names != ' ') names++;
  195.         if (*names != '\0') *names++ = '\0';
  196.  
  197.         names_chan->nicks = g_list_insert_sorted(names_chan->nicks, g_strdup(ptr), (GCompareFunc) irc_nicks_compare);
  198.     }
  199. }
  200.  
  201. void eirc_end_of_names(char *data)
  202. {
  203.     char *chan;
  204.  
  205.     event_get_params(data, 2, NULL, &chan);
  206.     drawtext(edefwin, TXT_TYPE_SERVER_TEXT, IRCTXT_ENDOFNAMES, chan);
  207.     if (names_chan != NULL) gui_nicklist_redraw(names_chan->window);
  208.     names_chan = NULL;
  209. }
  210.  
  211. void eirc_topic(char *data)
  212. {
  213.     CHAN_REC *chan;
  214.     char *channame, *topic;
  215.  
  216.     g_return_if_fail(data != NULL);
  217.  
  218.     event_get_params(data, 3, NULL, &channame, &topic);
  219.     chan = channel_joined(eserver, channame);
  220.     if (channame == NULL) return;
  221.  
  222.     if (chan->topic != NULL) g_free(chan->topic);
  223.     chan->topic = *topic == '\0' ? NULL : g_strdup(topic);
  224.  
  225.     if (chan->topic != NULL)
  226.         drawtext(chan->window, TXT_TYPE_SERVER_TEXT, IRCTXT_TOPIC, chan->name, chan->topic);
  227.     gui_change_topic(chan);
  228. }
  229.  
  230. void eirc_topic_info(char *data)
  231. {
  232.     CHAN_REC *chan;
  233.     time_t t;
  234.     struct tm *tim;
  235.     char timestr[100], *channame, *topicby, *topictime;
  236.  
  237.     g_return_if_fail(data != NULL);
  238.  
  239.     event_get_params(data, 4, NULL, &channame, &topicby, &topictime);
  240.  
  241.     chan = channel_joined(eserver, channame);
  242.     if (chan == NULL) return;
  243.  
  244.     if (sscanf(topictime, "%lu", &t) != 1) t = 0; /* topic set date */
  245.     tim = localtime(&t);
  246.     strcpy(timestr, asctime(tim));
  247.     if (timestr[strlen(timestr)-1] == '\n') timestr[strlen(timestr)-1] = '\0';
  248.  
  249.     drawtext(chan->window, TXT_TYPE_SERVER_TEXT, IRCTXT_TOPIC_INFO, topicby, timestr);
  250. }
  251.  
  252. void eirc_who(char *data)
  253. {
  254.     char *nick, *channel, *user, *host, *status, *realname;
  255.  
  256.     g_return_if_fail(data != NULL);
  257.  
  258.     event_get_params(data, 8, NULL, &channel, &user, &host, NULL, &nick, &status, &realname);
  259.     /* skip hop count */
  260.     while (*realname != '\0' && *realname != ' ') realname++;
  261.     while (*realname == ' ') realname++;
  262.  
  263.     sprintf(tmpstr, "%-10s %%_%-9s %-3s%%_ %s@%s (%%!%s%%!)\n", channel, nick, status, user, host, realname);
  264.     drawtext(edefwin, TXT_TYPE_SERVER_TEXT, tmpstr);
  265. }
  266.  
  267. void eirc_ban_list(char *data)
  268. {
  269.     char *chan, *ban, *setby, *tims;
  270.     long secs, tim;
  271.     CHAN_REC *ch;
  272.  
  273.     g_return_if_fail(data != NULL);
  274.  
  275.     event_get_params(data, 5, NULL, &chan, &ban, &setby, &tims);
  276.     ch = channel_joined(eserver, chan);
  277.  
  278.     if (sscanf(tims, "%lu", &tim) != 1) tim = 0;
  279.     secs = time(NULL)-tim;
  280.     drawtext(ch != NULL ? ch->window : edefwin, TXT_TYPE_SERVER_TEXT, IRCTXT_BANLIST,
  281.              chan, ban, setby, secs);
  282. }
  283.  
  284. void eirc_end_of_banlist(char *data)
  285. {
  286.     g_return_if_fail(data != NULL);
  287. }
  288.  
  289. void eirc_ison(char *data)
  290. {
  291.     char *online;
  292.     GList *tmp, *next;
  293.  
  294.     g_return_if_fail(data != NULL);
  295.  
  296.     event_get_params(data, 2, NULL, &online);
  297.  
  298.     if (eserver->ison_reqs <= 0)
  299.     {
  300.         /* user wrote /ISON.. */
  301.         if (eserver->ison_reqs < 0) eserver->ison_reqs++;
  302.         drawtext(curwin, TXT_TYPE_SERVER_TEXT, IRCTXT_ONLINE, online);
  303.         return;
  304.     }
  305.  
  306.     /* we're trying to find out who of the notify list members are in IRC */
  307.     while (online != NULL && *online != '\0')
  308.     {
  309.         char *ptr;
  310.  
  311.         ptr = strchr(online, ' ');
  312.         if (ptr != NULL) *ptr++ = '\0';
  313.         ison_tempusers = g_list_append(ison_tempusers, g_strdup(online));
  314.         online = ptr;
  315.     }
  316.  
  317.     if (--eserver->ison_reqs == 0)
  318.     {
  319.         /* all /ISON requests got - scan through notify list to check who's
  320.            came and who's left */
  321.  
  322.         /* first check who's came to irc */
  323.         for (tmp = g_list_first(ison_tempusers); tmp != NULL; tmp = tmp->next)
  324.         {
  325.             GList *on;
  326.  
  327.             for (on = g_list_first(ison_users); on != NULL; on = on->next)
  328.             {
  329.                 if (strcasecmp((char *) tmp->data, (char *) on->data) == 0)
  330.                     break;
  331.             }
  332.             if (on == NULL)
  333.             {
  334.                 /* not found from list, user's just joined to irc */
  335.                 gui_notify_join(tmp->data);
  336.                 ison_users = g_list_append(ison_users, g_strdup(tmp->data));
  337.             }
  338.         }
  339.  
  340.         /* and then check who's left irc */
  341.         for (tmp = g_list_first(ison_users); tmp != NULL; tmp = next)
  342.         {
  343.             GList *on;
  344.  
  345.             next = tmp->next;
  346.             for (on = g_list_first(ison_tempusers); on != NULL; on = on->next)
  347.             {
  348.                 if (strcasecmp((char *) tmp->data, (char *) on->data) == 0)
  349.                     break;
  350.             }
  351.             if (on == NULL)
  352.             {
  353.                 /* not found from list, user's left irc */
  354.                 gui_notify_part(tmp->data);
  355.                 g_free(tmp->data);
  356.                 ison_users = g_list_remove_link(ison_users, tmp);
  357.             }
  358.         }
  359.  
  360.         /* free memory used by temp list */
  361.         for (tmp = g_list_first(ison_tempusers); tmp != NULL; tmp = tmp->next)
  362.             g_free(tmp->data);
  363.         g_list_free(ison_tempusers); ison_tempusers = NULL;
  364.     }
  365. }
  366.  
  367. static void cannot_join(char *channel, char *reason)
  368. {
  369.     CHAN_REC *chan;
  370.  
  371.     g_return_if_fail(channel != NULL);
  372.  
  373.     chan = channel_joined(eserver, channel);
  374.     drawtext(edefwin, TXT_TYPE_SERVER_TEXT, IRCTXT_CANNOT_JOIN, channel, reason);
  375.  
  376.     if (chan == NULL) return;
  377.  
  378.     if (chan == chan->window->curchan)
  379.         irc_select_new_channel(chan->window);
  380.  
  381.     gui_channel_part(chan, NULL);
  382.     irc_chan_free(chan);
  383. }
  384.  
  385. void eirc_nick_unavailable(char *data)
  386. {
  387.     g_return_if_fail(data != NULL);
  388.  
  389.     /* skip target list.. */
  390.     while (*data != ' ') data++;
  391.     data++;
  392.  
  393.     if (*data == '#' || *data == '&')
  394.     {
  395.         /* channel is unavailable. */
  396.         char *channel;
  397.  
  398.         channel = event_get_param(&data);
  399.         cannot_join(data, _("Channel is temporarily unavailable"));
  400.         return;
  401.     }
  402.  
  403.     /* nick is unavailable.. */
  404.     eirc_nick_in_use(data);
  405. }
  406.  
  407. void eirc_too_many_channels(char *data)
  408. {
  409.     char *channel;
  410.  
  411.     g_return_if_fail(data != NULL);
  412.  
  413.     event_get_params(data, 2, NULL, &channel);
  414.     cannot_join(channel, _("You have joined too many channels"));
  415. }
  416.  
  417. void eirc_channel_is_full(char *data)
  418. {
  419.     char *channel;
  420.  
  421.     g_return_if_fail(data != NULL);
  422.  
  423.     event_get_params(data, 2, NULL, &channel);
  424.     cannot_join(channel, _("Channel is full"));
  425. }
  426.  
  427. void eirc_invite_only(char *data)
  428. {
  429.     char *channel;
  430.  
  431.     g_return_if_fail(data != NULL);
  432.  
  433.     event_get_params(data, 2, NULL, &channel);
  434.     cannot_join(channel, _("You must be invited"));
  435. }
  436.  
  437. void eirc_banned(char *data)
  438. {
  439.     char *channel;
  440.  
  441.     g_return_if_fail(data != NULL);
  442.  
  443.     event_get_params(data, 2, NULL, &channel);
  444.     cannot_join(channel, _("You are banned"));
  445. }
  446.  
  447. void eirc_bad_channel_key(char *data)
  448. {
  449.     char *channel;
  450.  
  451.     g_return_if_fail(data != NULL);
  452.  
  453.     event_get_params(data, 2, NULL, &channel);
  454.     cannot_join(channel, _("Bad channel key"));
  455. }
  456.  
  457. void eirc_bad_channel_mask(char *data)
  458. {
  459.     char *channel;
  460.  
  461.     g_return_if_fail(data != NULL);
  462.  
  463.     event_get_params(data, 2, NULL, &channel);
  464.     cannot_join(channel, _("Bad channel mask"));
  465. }
  466.