X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/b37021a45e15eef2e937aa11f185b48cf766d772..b2c208be091670e3c5259eba77187bae6ac6eece:/modules/m_services.c?ds=inline diff --git a/modules/m_services.c b/modules/m_services.c index 5108f58a..dd99fbec 100644 --- a/modules/m_services.c +++ b/modules/m_services.c @@ -31,7 +31,6 @@ #include "stdinc.h" -#include "tools.h" #include "send.h" #include "channel.h" #include "client.h" @@ -39,7 +38,6 @@ #include "config.h" #include "ircd.h" #include "numeric.h" -#include "memory.h" #include "s_conf.h" #include "s_newconf.h" #include "s_serv.h" @@ -47,10 +45,15 @@ #include "msg.h" #include "parse.h" #include "modules.h" -#include "sprintf_irc.h" #include "whowas.h" #include "monitor.h" +static int _modinit(void); +static void _moddeinit(void); + +static void mark_services(void); +static void unmark_services(void); + static int me_su(struct Client *, struct Client *, int, const char **); static int me_login(struct Client *, struct Client *, int, const char **); static int me_rsfnc(struct Client *, struct Client *, int, const char **); @@ -59,6 +62,8 @@ static int me_nickdelay(struct Client *, struct Client *, int, const char **); static void h_svc_server_introduced(hook_data_client *); static void h_svc_whois(hook_data_client *); static void h_svc_stats(hook_data_int *); +static void h_svc_conf_read_start(void *); +static void h_svc_conf_read_end(void *); struct Message su_msgtab = { "SU", 0, 0, 0, MFLG_SLOW, @@ -85,10 +90,24 @@ mapi_hfn_list_av1 services_hfnlist[] = { { "doing_whois", (hookfn) h_svc_whois }, { "doing_whois_global", (hookfn) h_svc_whois }, { "server_introduced", (hookfn) h_svc_server_introduced }, + { "conf_read_start", (hookfn) h_svc_conf_read_start }, + { "conf_read_end", (hookfn) h_svc_conf_read_end }, { NULL, NULL } }; -DECLARE_MODULE_AV1(services, NULL, NULL, services_clist, NULL, services_hfnlist, "$Revision: 1907 $"); +DECLARE_MODULE_AV1(services, _modinit, _moddeinit, services_clist, NULL, services_hfnlist, "$Revision: 1907 $"); + +static int +_modinit(void) +{ + mark_services(); +} + +static void +_moddeinit(void) +{ + unmark_services(); +} static int me_su(struct Client *client_p, struct Client *source_p, @@ -97,7 +116,11 @@ me_su(struct Client *client_p, struct Client *source_p, struct Client *target_p; if(!(source_p->flags & FLAGS_SERVICE)) + { + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Non-service server %s attempting to execute services-only command SU", source_p->name); return 0; + } if((target_p = find_client(parv[1])) == NULL) return 0; @@ -108,7 +131,11 @@ me_su(struct Client *client_p, struct Client *source_p, if(EmptyString(parv[2])) target_p->user->suser[0] = '\0'; else - strlcpy(target_p->user->suser, parv[2], sizeof(target_p->user->suser)); + rb_strlcpy(target_p->user->suser, parv[2], sizeof(target_p->user->suser)); + + sendto_common_channels_local_butone(target_p, CLICAP_ACCOUNT_NOTIFY, ":%s!%s@%s ACCOUNT %s", + target_p->name, target_p->username, target_p->host, + EmptyString(target_p->user->suser) ? "*" : target_p->user->suser); invalidate_bancache_user(target_p); @@ -122,7 +149,7 @@ me_login(struct Client *client_p, struct Client *source_p, if(!IsPerson(source_p)) return 0; - strlcpy(source_p->user->suser, parv[1], sizeof(source_p->user->suser)); + rb_strlcpy(source_p->user->suser, parv[1], sizeof(source_p->user->suser)); return 0; } @@ -154,9 +181,14 @@ me_rsfnc(struct Client *client_p, struct Client *source_p, struct Client *target_p; struct Client *exist_p; time_t newts, curts; + char note[NICKLEN + 10]; if(!(source_p->flags & FLAGS_SERVICE)) + { + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Non-service server %s attempting to execute services-only command RSFNC", source_p->name); return 0; + } if((target_p = find_person(parv[1])) == NULL) return 0; @@ -185,7 +217,7 @@ me_rsfnc(struct Client *client_p, struct Client *source_p, * safety --anfl */ if(target_p == exist_p) - return 0; + goto doit; if(MyClient(exist_p)) sendto_one(exist_p, ":%s KILL %s :(Nickname regained by services)", @@ -194,19 +226,25 @@ me_rsfnc(struct Client *client_p, struct Client *source_p, exist_p->flags |= FLAGS_KILLED; /* Do not send kills to servers for unknowns -- jilles */ if(IsClient(exist_p)) + { kill_client_serv_butone(NULL, exist_p, "%s (Nickname regained by services)", me.name); + sendto_realops_snomask(SNO_SKILL, L_ALL, + "Nick collision due to services forced nick change on %s", + parv[2]); + } - snprintf(buf, sizeof(buf), "Killed (%s (Nickname regained by services))", + rb_snprintf(buf, sizeof(buf), "Killed (%s (Nickname regained by services))", me.name); exit_client(NULL, exist_p, &me, buf); } +doit: newts = atol(parv[3]); /* timestamp is older than 15mins, ignore it */ - if(newts < (CurrentTime - 900)) - newts = CurrentTime - 900; + if(newts < (rb_current_time() - 900)) + newts = rb_current_time() - 900; target_p->tsinfo = newts; @@ -219,31 +257,29 @@ me_rsfnc(struct Client *client_p, struct Client *source_p, target_p->name, parv[2], target_p->username, target_p->host); - sendto_common_channels_local(target_p, ":%s!%s@%s NICK :%s", + sendto_common_channels_local(target_p, NOCAPS, ":%s!%s@%s NICK :%s", target_p->name, target_p->username, target_p->host, parv[2]); add_history(target_p, 1); sendto_server(NULL, NULL, CAP_TS6, NOCAPS, ":%s NICK %s :%ld", use_id(target_p), parv[2], (long) target_p->tsinfo); - sendto_server(NULL, NULL, NOCAPS, CAP_TS6, ":%s NICK %s :%ld", - target_p->name, parv[2], (long) target_p->tsinfo); del_from_client_hash(target_p->name, target_p); - strcpy(target_p->name, parv[2]); + rb_strlcpy(target_p->name, parv[2], NICKLEN); add_to_client_hash(target_p->name, target_p); monitor_signon(target_p); del_all_accepts(target_p); - comm_note(target_p->localClient->fd, "Nick: %s", target_p->name); + rb_snprintf(note, NICKLEN + 10, "Nick: %s", target_p->name); + rb_note(target_p->localClient->F, note); return 0; } /* ** me_nickdelay -** parv[0] = sender prefix ** parv[1] = duration in seconds (0 to remove) ** parv[2] = nick */ @@ -254,7 +290,11 @@ me_nickdelay(struct Client *client_p, struct Client *source_p, int parc, const c struct nd_entry *nd; if(!(source_p->flags & FLAGS_SERVICE)) + { + sendto_realops_snomask(SNO_GENERAL, L_ALL, + "Non-service server %s attempting to execute services-only command NICKDELAY", source_p->name); return 0; + } duration = atoi(parv[1]); if (duration <= 0) @@ -270,7 +310,7 @@ me_nickdelay(struct Client *client_p, struct Client *source_p, int parc, const c add_nd_entry(parv[2]); nd = irc_dictionary_retrieve(nd_dict, parv[2]); if (nd != NULL) - nd->expire = CurrentTime + duration; + nd->expire = rb_current_time() + duration; } return 0; @@ -279,9 +319,9 @@ me_nickdelay(struct Client *client_p, struct Client *source_p, int parc, const c static void h_svc_server_introduced(hook_data_client *hdata) { - dlink_node *ptr; + rb_dlink_node *ptr; - DLINK_FOREACH(ptr, service_list.head) + RB_DLINK_FOREACH(ptr, service_list.head) { if(!irccmp((const char *) ptr->data, hdata->target->name)) { @@ -306,9 +346,8 @@ h_svc_whois(hook_data_client *data) if(*p == '\0') p = data->target->user->suser; - sendto_one(data->client, form_str(RPL_WHOISLOGGEDIN), - get_id(&me, data->client), - get_id(data->client, data->client), + sendto_one_numeric(data->client, RPL_WHOISLOGGEDIN, + form_str(RPL_WHOISLOGGEDIN), data->target->name, p); } } @@ -317,15 +356,56 @@ static void h_svc_stats(hook_data_int *data) { char statchar = (char) data->arg2; - dlink_node *ptr; + rb_dlink_node *ptr; if (statchar == 'U' && IsOper(data->client)) { - DLINK_FOREACH(ptr, service_list.head) + RB_DLINK_FOREACH(ptr, service_list.head) { sendto_one_numeric(data->client, RPL_STATSULINE, form_str(RPL_STATSULINE), - ptr->data, "*", "*", "s"); + (const char *)ptr->data, "*", "*", "s"); } } } + +static void +h_svc_conf_read_start(void *dummy) +{ + unmark_services(); +} + +static void +unmark_services(void) +{ + struct Client *target_p; + rb_dlink_node *ptr; + + RB_DLINK_FOREACH(ptr, global_serv_list.head) + { + target_p = ptr->data; + + target_p->flags &= ~FLAGS_SERVICE; + } +} + +static void +h_svc_conf_read_end(void *dummy) +{ + mark_services(); +} + +static void +mark_services(void) +{ + struct Client *target_p; + rb_dlink_node *ptr; + + RB_DLINK_FOREACH(ptr, service_list.head) + { + target_p = find_server(NULL, (const char *)ptr->data); + + if (target_p) + target_p->flags |= FLAGS_SERVICE; + } +}