EXPORTED void sync_log_init(void) { const char *conf; int i; /* sync_log_init() may be called more than once */ if (channels) strarray_free(channels); conf = config_getstring(IMAPOPT_SYNC_LOG_CHANNELS); if (!conf) conf = "\"\""; channels = strarray_split(conf, " ", 0); /* * The sysadmin can specify "" in the value of sync_log_channels to * mean the default channel name - this will be useful for sysadmins * who want to start using a sync log channel for squatter but who * have been using the default sync log channel for sync_client. */ i = strarray_find(channels, "\"\"", 0); if (i >= 0) strarray_set(channels, i, NULL); strarray_free(unsuppressable); unsuppressable = NULL; conf = config_getstring(IMAPOPT_SYNC_LOG_UNSUPPRESSABLE_CHANNELS); if (conf) unsuppressable = strarray_split(conf, " ", 0); }
gboolean strarray_find_dest(char **array, const TEXT_DEST_REC *dest) { g_return_val_if_fail(array != NULL, FALSE); if (strarray_find(array, dest->target) != -1) return TRUE; if (dest->server_tag != NULL) { char *tagtarget = g_strdup_printf("%s/%s", dest->server_tag, dest->target); int ret = strarray_find(array, tagtarget); g_free(tagtarget); if (ret != -1) return TRUE; } return FALSE; }
static int sync_log_enabled(const char *channel) { if (!config_getswitch(IMAPOPT_SYNC_LOG)) return 0; /* entire mechanism is disabled */ if (!sync_log_suppressed) return 1; /* _suppress() wasn't called */ if (unsuppressable && strarray_find(unsuppressable, channel, 0) >= 0) return 1; /* channel is unsuppressable */ return 0; /* suppressed */ }
char *hilight_match(const char *channel, const char *nickmask, int level, const char *str) { GSList *tmp; const char *color; char number[MAX_INT_STRLEN]; int len, best_match, colornum; g_return_val_if_fail(str != NULL, NULL); color = NULL; best_match = 0; for (tmp = hilights; tmp != NULL; tmp = tmp->next) { HILIGHT_REC *rec = tmp->data; if ((level & (rec->level > 0 ? rec->level : DEFAULT_HILIGHT_LEVEL)) == 0) continue; if (!rec->nick && nickmask != NULL) continue; if (rec->channels != NULL && (channel == NULL || strarray_find(rec->channels, channel) == -1)) continue; if (rec->nickmask) { if (nickmask == NULL || !match_wildcards(rec->text, nickmask)) continue; } else if (rec->regexp) { if (!regexp_match(str, rec->text)) continue; } else if (rec->fullword) { if (stristr_full(str, rec->text) == NULL) continue; } else { if (stristr(str, rec->text) == NULL) continue; } len = strlen(rec->text); if (best_match < len) { best_match = len; color = rec->color; } } if (best_match == 0) return NULL; if (color == NULL) color = settings_get_str("hilight_color"); if (isalpha((int) *color)) { /* color was specified with it's name - try to convert it */ colornum = mirc_color_name(color); if (colornum <= 0) colornum = 16; ltoa(number, colornum); color = number; } return g_strconcat(isdigit(*color) ? "\003" : "", color, NULL); }
gboolean settings_set_choice(const char *key, const char *value) { SETTINGS_REC *rec; rec = settings_get_record(key); if (rec != NULL && strarray_find(rec->choices, value) < 0) return FALSE; settings_set_str(key, value); return TRUE; }
EXPORTED int is_system_user(const char *userid) { static strarray_t *admins = NULL; if (!admins) admins = strarray_split(config_getstring(IMAPOPT_ADMINS), NULL, STRARRAY_TRIM); if (!strcmp(userid, "anyone")) return 1; if (!strcmp(userid, "anonymous")) return 1; if (strarray_find(admins, userid, 0) >= 0) return 1; return 0; }
static LOG_REC *log_find_item(const char *item) { GSList *tmp; for (tmp = logs; tmp != NULL; tmp = tmp->next) { LOG_REC *rec = tmp->data; if (rec->items != NULL && strarray_find(rec->items, item) != -1) return rec; } return NULL; }
IGNORE_REC *ignore_find(const char *servertag, const char *mask, char **channels) { GSList *tmp; char **chan; int ignore_servertag; if (mask != NULL && *mask == '\0') mask = NULL; ignore_servertag = servertag != NULL && strcmp(servertag, "*") == 0; for (tmp = ignores; tmp != NULL; tmp = tmp->next) { IGNORE_REC *rec = tmp->data; if (!ignore_servertag) { if ((servertag == NULL && rec->servertag != NULL) || (servertag != NULL && rec->servertag == NULL)) continue; if (servertag != NULL && g_strcasecmp(servertag, rec->servertag) != 0) continue; } if ((rec->mask == NULL && mask != NULL) || (rec->mask != NULL && mask == NULL)) continue; if (rec->mask != NULL && g_strcasecmp(rec->mask, mask) != 0) continue; if ((channels == NULL && rec->channels == NULL)) return rec; /* no channels - ok */ if (channels != NULL && strcmp(*channels, "*") == 0) return rec; /* ignore channels */ if (channels == NULL || rec->channels == NULL) continue; /* other doesn't have channels */ if (strarray_length(channels) != strarray_length(rec->channels)) continue; /* different amount of channels */ /* check that channels match */ for (chan = channels; *chan != NULL; chan++) { if (strarray_find(rec->channels, *chan) == -1) break; } if (*chan == NULL) return rec; /* channels ok */ } return NULL; }
static void event_end_of_who(IRC_SERVER_REC *server, const char *data) { SERVER_QUERY_REC *rec; GSList *tmp, *next; char *params, *channel, **channels; int failed, multiple; g_return_if_fail(data != NULL); params = event_get_params(data, 2, NULL, &channel); multiple = strchr(channel, ',') != NULL; channels = g_strsplit(channel, ",", -1); failed = FALSE; rec = server->chanqueries; for (tmp = rec->current_queries; tmp != NULL; tmp = next) { IRC_CHANNEL_REC *chanrec = tmp->data; next = tmp->next; if (strarray_find(channels, chanrec->name) == -1) continue; if (chanrec->ownnick->host == NULL && multiple && !server->one_endofwho) { /* we should receive our own host for each channel. However, some servers really are stupid enough not to reply anything to /WHO requests.. */ failed = TRUE; } else { chanrec->wholist = TRUE; signal_emit("channel wholist", 1, chanrec); channel_got_query(chanrec, CHANNEL_QUERY_WHO); } } g_strfreev(channels); if (multiple) server->one_endofwho = TRUE; if (failed) { /* server didn't understand multiple WHO replies, send them again separately */ query_current_error(server); } g_free(params); }
int settings_get_choice(const char *key) { SETTINGS_REC *rec; CONFIG_NODE *node; char *str; int index; rec = settings_get(key, SETTING_TYPE_CHOICE); if (rec == NULL) return -1; node = iconfig_node_traverse("settings", FALSE); node = node == NULL ? NULL : iconfig_node_section(node, rec->module, -1); str = node == NULL ? rec->default_value.v_string : config_node_get_str(node, key, rec->default_value.v_string); if (str == NULL || (index = strarray_find(rec->choices, str)) < 0) return rec->default_value.v_int; return index; }
static HILIGHT_REC *hilight_find(const char *text, char **channels) { GSList *tmp; char **chan; g_return_val_if_fail(text != NULL, NULL); for (tmp = hilights; tmp != NULL; tmp = tmp->next) { HILIGHT_REC *rec = tmp->data; if (g_ascii_strcasecmp(rec->text, text) != 0) continue; if ((channels == NULL && rec->channels == NULL)) return rec; /* no channels - ok */ if (channels != NULL && strcmp(*channels, "*") == 0) return rec; /* ignore channels */ if (channels == NULL || rec->channels == NULL) continue; /* other doesn't have channels */ if (strarray_length(channels) != strarray_length(rec->channels)) continue; /* different amount of channels */ /* check that channels match */ for (chan = channels; *chan != NULL; chan++) { if (strarray_find(rec->channels, *chan) == -1) break; } if (*chan == NULL) return rec; /* channels ok */ } return NULL; }
IGNORE_REC *ignore_find_full(const char *servertag, const char *mask, const char *pattern, char **channels, const int flags) { GSList *tmp; char **chan; int ignore_servertag; if (mask != NULL && (*mask == '\0' || g_strcmp0(mask, "*") == 0)) mask = NULL; ignore_servertag = servertag != NULL && g_strcmp0(servertag, "*") == 0; for (tmp = ignores; tmp != NULL; tmp = tmp->next) { IGNORE_REC *rec = tmp->data; if (!ignore_servertag) { if ((servertag == NULL && rec->servertag != NULL) || (servertag != NULL && rec->servertag == NULL)) continue; if (servertag != NULL && g_ascii_strcasecmp(servertag, rec->servertag) != 0) continue; } if ((flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) == 0) continue; if (!(flags & IGNORE_FIND_NOACT) && (rec->level & MSGLEVEL_NO_ACT) != 0) continue; if ((rec->mask == NULL && mask != NULL) || (rec->mask != NULL && mask == NULL)) continue; if (rec->mask != NULL && g_ascii_strcasecmp(rec->mask, mask) != 0) continue; /* match the pattern too if requested */ if (flags & IGNORE_FIND_PATTERN) { if ((rec->pattern == NULL && pattern != NULL) || (rec->pattern != NULL && pattern == NULL)) continue; if (rec->pattern != NULL && g_ascii_strcasecmp(rec->pattern, pattern) != 0) continue; } if ((channels == NULL && rec->channels == NULL)) return rec; /* no channels - ok */ if (channels != NULL && g_strcmp0(*channels, "*") == 0) return rec; /* ignore channels */ if (channels == NULL || rec->channels == NULL) continue; /* other doesn't have channels */ if (g_strv_length(channels) != g_strv_length(rec->channels)) continue; /* different amount of channels */ /* check that channels match */ for (chan = channels; *chan != NULL; chan++) { if (strarray_find(rec->channels, *chan) == -1) break; } if (*chan == NULL) return rec; /* channels ok */ } return NULL; }
static int _parse_entry_params(struct vparse_state *state) { struct vparse_param **paramp = &state->entry->params; int multiparam = 0; int haseq = 0; int r; repeat: multiparam = 0; haseq = 0; MAKE(state->param, vparse_param); NOTESTART(); r = _parse_param_key(state, &haseq); if (r) return r; if (state->multiparam && strarray_find(state->multiparam, state->param->name, 0)) multiparam = 1; /* now get the value */ while (*state->p) { switch (*state->p) { case '\\': /* normal backslash quoting */ /* seen in the wild - \n split by line wrapping */ if (state->p[1] == '\r') INC(1); if (state->p[1] == '\n') { if (state->p[2] != ' ' && state->p[2] != '\t') return PE_PARAMVALUE_EOL; INC(2); } if (!state->p[1]) return PE_BACKQUOTE_EOF; if (state->p[1] == 'n' || state->p[1] == 'N') PUTC('\n'); else PUTC(state->p[1]); INC(2); break; case '^': /* special value quoting for doublequote (RFC 6868) */ /* seen in the wild - \n split by line wrapping */ if (state->p[1] == '\r') INC(1); if (state->p[1] == '\n') { if (state->p[2] != ' ' && state->p[2] != '\t') return PE_PARAMVALUE_EOL; INC(2); } if (state->p[1] == '\'') { PUTC('"'); INC(2); } else if (state->p[1] == 'n') { PUTC('\n'); INC(2); } else if (state->p[1] == '^') { PUTC('^'); INC(2); } else { PUTC('^'); INC(1); /* treat next char normally */ } break; case '"': INC(1); loop: r = _parse_param_quoted(state, multiparam); if (r == PE_QSTRING_COMMA) { char *name = strdup(state->param->name); state->param->value = buf_dup_cstring(&state->buf); *paramp = state->param; paramp = &state->param->next; MAKE(state->param, vparse_param); state->param->name = name; INC(1); goto loop; } if (r) return r; break; case ':': /* done - all parameters parsed */ if (haseq) state->param->value = buf_dup_cstring(&state->buf); *paramp = state->param; state->param = NULL; INC(1); return 0; case ';': /* another parameter to parse */ if (haseq) state->param->value = buf_dup_cstring(&state->buf); *paramp = state->param; paramp = &state->param->next; INC(1); goto repeat; case '\r': INC(1); break; /* just skip */ case '\n': if (state->p[1] != ' ' && state->p[1] != '\t') return PE_PARAMVALUE_EOL; INC(2); break; case ',': if (multiparam) { char *name = strdup(state->param->name); if (haseq) state->param->value = buf_dup_cstring(&state->buf); *paramp = state->param; paramp = &state->param->next; MAKE(state->param, vparse_param); state->param->name = name; INC(1); break; } /* or fall through, comma isn't special */ default: PUTC(*state->p); INC(1); break; } } return PE_PARAMVALUE_EOF; }
int ignore_check(IRC_SERVER_REC *server, const char *nick, const char *host, const char *channel, const char *text, int level) { GSList *tmp; int ok, mask_len, patt_len; int best_mask, best_patt, best_ignore; g_return_val_if_fail(server != NULL, 0); best_mask = 0; best_patt = 0; best_ignore = FALSE; for (tmp = ignores; tmp != NULL; tmp = tmp->next) { IGNORE_REC *rec = tmp->data; if ((level & (rec->level|rec->except_level)) == 0) continue; /* server */ if (rec->servertag != NULL && g_strcasecmp(server->tag, rec->servertag) != 0) continue; /* channel list */ if (rec->channels != NULL) { if (channel == NULL || !ischannel(*channel)) continue; if (strarray_find(rec->channels, channel) == -1) continue; } /* nick mask */ mask_len = 0; if (rec->mask != NULL) { if (nick == NULL) continue; mask_len = strlen(rec->mask); if (mask_len <= best_mask) continue; ok = ((host == NULL || *host == '\0')) ? match_wildcards(rec->mask, nick) : irc_mask_match_address(rec->mask, nick, host); if (!ok) { /* nick didn't match, but maybe this is a reply to nick? */ if (!rec->replies || channel == NULL || text == NULL || !ignore_check_replies(rec, server, channel, text)) continue; } } /* pattern */ patt_len = 0; if (rec->pattern != NULL) { if (!mask_len && !best_mask) { patt_len = strlen(rec->pattern); if (patt_len <= best_patt) continue; } ok = rec->regexp ? regexp_match(text, rec->pattern) : rec->fullword ? stristr_full(text, rec->pattern) != NULL : stristr(text, rec->pattern) != NULL; if (!ok) continue; } if (mask_len || best_mask) best_mask = mask_len; else if (patt_len) best_patt = patt_len; best_ignore = (rec->level & level) != 0; } return best_ignore; }