Changeset 355e2ad for irc_commands.c


Ignore:
Timestamp:
2015-10-01T01:01:48Z (9 years ago)
Author:
dequis <dx@…>
Branches:
master
Children:
3cbf71d
Parents:
d797fb4
git-author:
dequis <dx@…> (18-08-15 05:53:17)
git-committer:
dequis <dx@…> (01-10-15 01:01:48)
Message:

Move CAP commands to irc_cap.c; use enum for flags

File:
1 edited

Legend:

Unmodified
Added
Removed
  • irc_commands.c

    rd797fb4 r355e2ad  
    2828#include "help.h"
    2929#include "ipc.h"
    30 
    31 typedef guint32 cap_flag;     /* 32 bits ought to be enough for anybody */
    32 
    33 typedef struct _cap_info {
    34         char *name;
    35         cap_flag flag;
    36 } cap_info_t;
    37 
    38 #define CAP_FOO (1 << 0)
    39 #define CAP_BAR (1 << 1)
    40 
    41 static const cap_info_t supported_caps[] = {
    42         {"foo", CAP_FOO},
    43         {"bar", CAP_BAR},
    44         {NULL},
    45 };
    46 
    47 static cap_flag cap_flag_from_string(char *cap_name) {
    48         int i;
    49 
    50         if (!cap_name && !cap_name[0]) {
    51                 return 0;
    52         }
    53 
    54         if (cap_name[0] == '-') {
    55                 cap_name++;
    56         }
    57 
    58         for (i = 0; supported_caps[i].name; i++) {
    59                 if (strcmp(supported_caps[i].name, cap_name) == 0) {
    60                         return supported_caps[i].flag;
    61                 }
    62         }
    63         return 0;
    64 }
    65 
    66 static gboolean irc_cmd_cap_req(irc_t *irc, char *caps)
    67 {
    68         int i;
    69         char *lower = NULL;
    70         char **split = NULL;
    71         cap_flag new_caps = irc->caps;
    72 
    73         if (!caps || !caps[0]) {
    74                 return FALSE;
    75         }
    76 
    77         lower = g_ascii_strdown(caps, -1);
    78         split = g_strsplit(lower, " ", -1);
    79         g_free(lower);
    80 
    81         for (i = 0; split[i]; i++) {
    82                 gboolean remove;
    83                 cap_flag flag;
    84 
    85                 if (!split[i][0]) {
    86                         continue;   /* skip empty items (consecutive spaces) */
    87                 }
    88 
    89                 remove = (split[i][0] == '-');
    90                 flag = cap_flag_from_string(split[i]);
    91                
    92                 if (!flag || (remove && !(irc->caps & flag))) {
    93                         /* unsupported cap, or removing something that isn't there */
    94                         g_strfreev(split);
    95                         return FALSE;
    96                 }
    97 
    98                 if (remove) {
    99                         new_caps &= ~flag;
    100                 } else {
    101                         new_caps |= flag;
    102                 }
    103         }
    104 
    105         /* if we got here, set the new caps and ack */
    106         irc->caps = new_caps;
    107 
    108         g_strfreev(split);
    109         return TRUE;
    110 }
    111 
    112 /* version can be "302" or NULL, but we don't need cap-3.2 for anything yet */
    113 static void irc_cmd_cap_ls(irc_t *irc, char *version) {
    114         int i;
    115         GString *str = g_string_sized_new(256);
    116 
    117         for (i = 0; supported_caps[i].name; i++) {
    118                 if (i != 0) {
    119                         g_string_append_c(str, ' ');
    120                 }
    121                 g_string_append(str, supported_caps[i].name);
    122         }
    123 
    124         irc_send_cap(irc, "LS", str->str);
    125 
    126         g_string_free(str, TRUE);
    127 }
    128 
    129 /* this one looks suspiciously similar to cap ls,
    130  * but cap-3.2 will make them very different */
    131 static void irc_cmd_cap_list(irc_t *irc) {
    132         int i;
    133         gboolean first = TRUE;
    134         GString *str = g_string_sized_new(256);
    135 
    136         for (i = 0; supported_caps[i].name; i++) {
    137                 if (irc->caps & supported_caps[i].flag) {
    138                         if (!first) {
    139                                 g_string_append_c(str, ' ');
    140                         }
    141                         first = FALSE;
    142 
    143                         g_string_append(str, supported_caps[i].name);
    144                 }
    145         }
    146 
    147         irc_send_cap(irc, "LIST", str->str);
    148 
    149         g_string_free(str, TRUE);
    150 }
    151 
    152 static void irc_cmd_cap(irc_t *irc, char **cmd)
    153 {
    154         if (!(irc->status & USTATUS_LOGGED_IN)) {
    155                 /* Put registration on hold until CAP END */
    156                 irc->status |= USTATUS_CAP_PENDING;
    157         }
    158 
    159         if (g_strcasecmp(cmd[1], "LS") == 0) {
    160                 irc_cmd_cap_ls(irc, cmd[2]);
    161 
    162         } else if (g_strcasecmp(cmd[1], "LIST") == 0) {
    163                 irc_cmd_cap_list(irc);
    164 
    165         } else if (g_strcasecmp(cmd[1], "REQ") == 0) {
    166                 gboolean ack = irc_cmd_cap_req(irc, cmd[2]);
    167 
    168                 irc_send_cap(irc, ack ? "ACK" : "NAK", cmd[2] ? : "");
    169 
    170         } else if (g_strcasecmp(cmd[1], "END") == 0) {
    171                 irc->status &= ~USTATUS_CAP_PENDING;
    172                 irc_check_login(irc);
    173 
    174         } else {
    175                 irc_send_num(irc, 410, "%s :Invalid CAP command", cmd[1]);
    176         }
    177 
    178 }
    17930
    18031static void irc_cmd_pass(irc_t *irc, char **cmd)
Note: See TracChangeset for help on using the changeset viewer.