static void gs_cmd_leave(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; if (!parv[0]) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "LEAVE"); command_fail(si, fault_needmoreparams, _("Syntax: LEAVE <!groupname>")); return; } if (!(mg = mygroup_find(parv[0]))) { command_fail(si, fault_alreadyexists, _("Group \2%s\2 does not exist."), parv[0]); return; } if (!groupacs_sourceinfo_has_flag(mg, si, 0)) { command_fail(si, fault_nosuch_target, _("You are not a member of group \2%s\2."), parv[0]); return; } groupacs_delete(mg, entity(si->smu)); command_success_nodata(si, _("You are not longer a member of group \2%s\2."), entity(mg)->name); }
static void gs_cmd_set_public(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; if (!parv[0] || !parv[1]) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "PUBLIC"); command_fail(si, fault_needmoreparams, _("Syntax: PUBLIC <!group> <ON|OFF>")); return; } if ((mg = mygroup_find(parv[0])) == NULL) { command_fail(si, fault_nosuch_target, _("The group \2%s\2 does not exist."), parv[0]); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_FOUNDER)) { command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED); return; } if (!strcasecmp(parv[1], "ON")) { if (mg->flags & MG_PUBLIC) { command_fail(si, fault_nochange, _("\2%s\2 is already public."), entity(mg)->name); return; } mg->flags |= MG_PUBLIC; logcommand(si, CMDLOG_SET, "PUBLIC:ON: \2%s\2", entity(mg)->name); command_success_nodata(si, _("\2%s\2 is now public."), entity(mg)->name); } else if (!strcasecmp(parv[1], "OFF")) { if (!(mg->flags & MG_PUBLIC)) { command_fail(si, fault_nochange, _("\2%s\2 is not public already."), entity(mg)->name); return; } mg->flags &= ~MG_PUBLIC; logcommand(si, CMDLOG_SET, "PUBLIC:OFF: \2%s\2", entity(mg)->name); command_success_nodata(si, _("\2%s\2 is no longer public."), entity(mg)->name); } else { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "PUBLIC"); command_fail(si, fault_badparams, _("Syntax: PUBLIC <!group> <ON|OFF>")); } }
/* SET GROUPNAME <name> */ static void gs_cmd_set_groupname(sourceinfo_t *si, int parc, char *parv[]) { char *oldname, *newname; mygroup_t *mg; if (parc != 2) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "GROUPNAME"); command_fail(si, fault_needmoreparams, _("Syntax: SET GROUPNAME <oldname> <newname>")); return; } oldname = parv[0]; newname = parv[1]; if (*oldname != '!' || *newname != '!') { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "GROUPNAME"); command_fail(si, fault_badparams, _("Syntax: SET GROUPNAME <oldname> <newname>")); return; } mg = mygroup_find(oldname); if (mg == NULL) { command_fail(si, fault_nosuch_target, _("The group \2%s\2 does not exist."), oldname); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_FOUNDER)) { command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED); return; } if (strcmp(entity(mg)->name, newname) == 0) { command_fail(si, fault_nochange, _("The group name is already set to \2%s\2."), newname); return; } if (mygroup_find(newname) != NULL) { command_fail(si, fault_nochange, _("The group \2%s\2 already exists."), newname); return; } mygroup_rename(mg, newname); logcommand(si, CMDLOG_REGISTER, "SET:GROUPNAME: \2%s\2 to \2%s\2", oldname, newname); command_success_nodata(si, _("The group \2%s\2 has been renamed to \2%s\2."), oldname, newname); }
static void gs_cmd_set_joinflags(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; char *joinflags = parv[1]; unsigned int flags = 0; if (!(mg = mygroup_find(parv[0]))) { command_fail(si, fault_nosuch_target, _("Group \2%s\2 does not exist."), parv[0]); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_SET)) { command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED); return; } if (!joinflags || !strcasecmp("OFF", joinflags) || !strcasecmp("NONE", joinflags)) { /* not in a namespace to allow more natural use of SET PROPERTY. * they may be able to introduce spaces, though. c'est la vie. */ if (metadata_find(mg, "joinflags")) { metadata_delete(mg, "joinflags"); logcommand(si, CMDLOG_SET, "SET:JOINFLAGS:NONE: \2%s\2", entity(mg)->name); command_success_nodata(si, _("The group-specific join flags for \2%s\2 have been cleared."), parv[0]); return; } command_fail(si, fault_nochange, _("Join flags for \2%s\2 were not set."), parv[0]); return; } if (!strncasecmp(joinflags, "-", 1)) { command_fail(si, fault_badparams, _("You can't set join flags to be removed.")); return; } flags = gs_flags_parser(joinflags, 0, flags); /* we'll overwrite any existing metadata */ metadata_add(mg, "joinflags", number_to_string(flags)); logcommand(si, CMDLOG_SET, "SET:JOINFLAGS: \2%s\2 \2%s\2", entity(mg)->name, joinflags); command_success_nodata(si, _("The join flags of \2%s\2 have been set to \2%s\2."), parv[0], joinflags); }
static void gs_cmd_set_email(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; char *mail = parv[1]; if (!(mg = mygroup_find(parv[0]))) { command_fail(si, fault_nosuch_target, _("Group \2%s\2 does not exist."), parv[0]); return; } if (si->smu == NULL) { command_fail(si, fault_noprivs, _("You are not logged in.")); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_SET)) { command_fail(si, fault_noprivs, _("You are not authorized to execute this command.")); return; } if (!mail || !strcasecmp(mail, "NONE") || !strcasecmp(mail, "OFF")) { if (metadata_find(mg, "email")) { metadata_delete(mg, "email"); command_success_nodata(si, _("The e-mail address for group \2%s\2 was deleted."), entity(mg)->name); logcommand(si, CMDLOG_SET, "SET:EMAIL:NONE: \2%s\2", entity(mg)->name); return; } command_fail(si, fault_nochange, _("The e-mail address for group \2%s\2 was not set."), entity(mg)->name); return; } if (!validemail(mail)) { command_fail(si, fault_badparams, _("\2%s\2 is not a valid e-mail address."), mail); return; } /* we'll overwrite any existing metadata */ metadata_add(mg, "email", mail); logcommand(si, CMDLOG_SET, "SET:EMAIL: \2%s\2 \2%s\2", entity(mg)->name, mail); command_success_nodata(si, _("The e-mail address for group \2%s\2 has been set to \2%s\2."), parv[0], mail); }
static void gs_cmd_invite(struct sourceinfo *si, int parc, char *parv[]) { struct mygroup *mg; struct myuser *mu; struct groupacs *ga; char *group = parv[0]; char *user = parv[1]; char buf[BUFSIZE]; struct service *svs; if (!group || !user) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "INVITE"); command_fail(si, fault_needmoreparams, _("Syntax: INVITE <!group> <user>")); return; } if ((mg = mygroup_find(group)) == NULL) { command_fail(si, fault_nosuch_target, _("The group \2%s\2 does not exist."), group); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_INVITE)) { command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED); return; } if ((mu = myuser_find_ext(user)) == NULL) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not a registered account."), user); return; } if ((ga = groupacs_find(mg, entity(mu), 0, false)) != NULL) { command_fail(si, fault_badparams, _("\2%s\2 is already a member of \2%s\2."), user, group); return; } if (metadata_find(mu, "private:groupinvite")) { command_fail(si, fault_badparams, _("\2%s\2 can not be invited to a group currently because they already \ have another invitation pending."), user); return; }
static void gs_cmd_set_channel(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; char *chan = parv[1]; if (!(mg = mygroup_find(parv[0]))) { command_fail(si, fault_nosuch_target, _("Group \2%s\2 does not exist."), parv[0]); return; } if (si->smu == NULL) { command_fail(si, fault_noprivs, _("You are not logged in.")); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_SET)) { command_fail(si, fault_noprivs, _("You are not authorized to execute this command.")); return; } if (!chan || !strcasecmp("OFF", chan) || !strcasecmp("NONE", chan)) { /* not in a namespace to allow more natural use of SET PROPERTY. * they may be able to introduce spaces, though. c'est la vie. */ if (metadata_find(mg, "channel")) { metadata_delete(mg, "channel"); logcommand(si, CMDLOG_SET, "SET:CHANNEL:NONE: \2%s\2", entity(mg)->name); command_success_nodata(si, _("The official channel for \2%s\2 has been cleared."), parv[0]); return; } command_fail(si, fault_nochange, _("A official channel for \2%s\2 was not set."), parv[0]); return; } /* we'll overwrite any existing metadata */ metadata_add(mg, "channel", chan); logcommand(si, CMDLOG_SET, "SET:CHANNEL: \2%s\2 \2%s\2", entity(mg)->name, chan); command_success_nodata(si, _("The official channel of \2%s\2 has been set to \2%s\2."), parv[0], chan); }
static void gs_cmd_info(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; struct tm tm; char buf[BUFSIZE], strfbuf[BUFSIZE]; metadata_t *md; if (!parv[0]) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "INFO"); command_fail(si, fault_needmoreparams, _("Syntax: INFO <!groupname>")); return; } if (!(mg = mygroup_find(parv[0]))) { command_fail(si, fault_alreadyexists, _("Group \2%s\2 does not exist."), parv[0]); return; } tm = *localtime(&mg->regtime); strftime(strfbuf, sizeof strfbuf, TIME_FORMAT, &tm); command_success_nodata(si, _("Information for \2%s\2:"), parv[0]); command_success_nodata(si, _("Registered : %s (%s ago)"), strfbuf, time_ago(mg->regtime)); if (config_options.show_entity_id || has_priv(si, PRIV_GROUP_AUSPEX)) command_success_nodata(si, _("Entity ID : %s"), entity(mg)->id); if (mg->flags & MG_PUBLIC || (si->smu != NULL && groupacs_sourceinfo_has_flag(mg, si, 0) && !groupacs_sourceinfo_has_flag(mg, si, GA_BAN)) || has_priv(si, PRIV_GROUP_AUSPEX)) command_success_nodata(si, _("Founder : %s"), mygroup_founder_names(mg)); if ((md = metadata_find(mg, "description"))) command_success_nodata(si, _("Description : %s"), md->value); if ((md = metadata_find(mg, "channel"))) command_success_nodata(si, _("Channel : %s"), md->value); if ((md = metadata_find(mg, "url"))) command_success_nodata(si, _("URL : %s"), md->value); if ((md = metadata_find(mg, "email"))) command_success_nodata(si, _("Email : %s"), md->value); *buf = '\0'; if (mg->flags & MG_REGNOLIMIT) mowgli_strlcat(buf, "REGNOLIMIT", BUFSIZE); if (mg->flags & MG_ACSNOLIMIT) { if (*buf) mowgli_strlcat(buf, " ", BUFSIZE); mowgli_strlcat(buf, "ACSNOLIMIT", BUFSIZE); } if (mg->flags & MG_OPEN) { if (*buf) mowgli_strlcat(buf, " ", BUFSIZE); mowgli_strlcat(buf, "OPEN", BUFSIZE); } if (mg->flags & MG_PUBLIC) { if (*buf) mowgli_strlcat(buf, " ", BUFSIZE); mowgli_strlcat(buf, "PUBLIC", BUFSIZE); } if (*buf) command_success_nodata(si, _("Flags : %s"), buf); command_success_nodata(si, _("\2*** End of Info ***\2")); logcommand(si, CMDLOG_GET, "INFO: \2%s\2", parv[0]); }
static void gs_cmd_drop(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; char *name = parv[0]; char *key = parv[1]; char fullcmd[512]; char key0[80], key1[80]; if (!name) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "DROP"); command_fail(si, fault_needmoreparams, _("Syntax: DROP <!group>")); return; } if (*name != '!') { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "DROP"); command_fail(si, fault_badparams, _("Syntax: DROP <!group>")); return; } if (!(mg = mygroup_find(name))) { command_fail(si, fault_nosuch_target, _("Group \2%s\2 does not exist."), name); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_FOUNDER)) { command_fail(si, fault_noprivs, _("You are not authorized to execute this command.")); return; } if (si->su != NULL) { if (!key) { create_challenge(si, entity(mg)->name, 0, key0); snprintf(fullcmd, sizeof fullcmd, "/%s%s DROP %s %s", (ircd->uses_rcommand == false) ? "msg " : "", si->service->disp, entity(mg)->name, key0); command_success_nodata(si, _("To avoid accidental use of this command, this operation has to be confirmed. Please confirm by replying with \2%s\2"), fullcmd); return; } /* accept current and previous key */ create_challenge(si, entity(mg)->name, 0, key0); create_challenge(si, entity(mg)->name, 1, key1); if (strcmp(key, key0) && strcmp(key, key1)) { command_fail(si, fault_badparams, _("Invalid key for %s."), "DROP"); return; } } logcommand(si, CMDLOG_REGISTER, "DROP: \2%s\2", entity(mg)->name); remove_group_chanacs(mg); object_unref(mg); command_success_nodata(si, _("The group \2%s\2 has been dropped."), name); return; }
static void gs_cmd_join(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; groupacs_t *ga; metadata_t *md, *md2; unsigned int flags = 0; bool invited = false; groupinvite_t *gi; if (!parv[0]) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "JOIN"); command_fail(si, fault_needmoreparams, _("Syntax: JOIN <!groupname>")); return; } if (!(mg = mygroup_find(parv[0]))) { command_fail(si, fault_alreadyexists, _("Group \2%s\2 does not exist."), parv[0]); return; } if ((gi = groupinvite_find(mg, entity(si->smu))) != NULL) { invited = true; } else { /* Legacy code - Search old invite and delete it */ if ((md2 = metadata_find(si->smu, "private:groupinvite"))) { if (!strcasecmp(md2->value, parv[0])) { invited = true; metadata_delete(si->smu, "private:groupinvite"); } } } if (groupacs_sourceinfo_has_flag(mg, si, 0)) { command_fail(si, fault_nochange, _("You are already a member of group \2%s\2."), parv[0]); return; } if (!(mg->flags & MG_OPEN) && !invited) { command_fail(si, fault_noprivs, _("Group \2%s\2 is not open to anyone joining."), parv[0]); return; } if (groupacs_sourceinfo_has_flag(mg, si, GA_BAN)) { command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED); return; } if (MOWGLI_LIST_LENGTH(&mg->acs) > gs_config->maxgroupacs && (!(mg->flags & MG_ACSNOLIMIT)) && !invited) { command_fail(si, fault_toomany, _("Group \2%s\2 access list is full."), entity(mg)->name); return; } if ((md = metadata_find(mg, "joinflags"))) flags = atoi(md->value); else flags = gs_flags_parser(gs_config->join_flags, 0, flags); ga = groupacs_add(mg, entity(si->smu), flags); if (invited) groupinvite_delete(mg, entity(si->smu)); command_success_nodata(si, _("You are now a member of \2%s\2."), entity(mg)->name); }
static void gs_cmd_invite(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; myuser_t *mu; groupacs_t *ga; char *group = parv[0]; char *user = parv[1]; char buf[BUFSIZE], description[256]; service_t *svs; if (!group || !user) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "INVITE"); command_fail(si, fault_needmoreparams, _("Syntax: INVITE <!group> <user>")); return; } if ((mg = mygroup_find(group)) == NULL) { command_fail(si, fault_nosuch_target, _("The group \2%s\2 does not exist."), group); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_INVITE)) { command_fail(si, fault_noprivs, _("You are not authorized to perform this operation.")); return; } if ((mu = myuser_find_ext(user)) == NULL) { command_fail(si, fault_nosuch_target, _("\2%s\2 is not a registered account."), user); return; } if ((ga = groupacs_find(mg, entity(mu), 0, false)) != NULL) { command_fail(si, fault_badparams, _("\2%s\2 is already a member of: \2%s\2"), entity(mu)->name, entity(mg)->name); return; } if (metadata_find(mu, "private:groupinvite")) { command_fail(si, fault_badparams, _("\2%s\2 may not be invited to a group and already has another invitation pending."), entity(mu)->name); return; } if (MU_NEVERGROUP & mu->flags) { command_fail(si, fault_noprivs, _("\2%s\2 does not wish to belong to any groups."), entity(mu)->name); return; } metadata_add(mu, "private:groupinvite", entity(mg)->name); if ((svs = service_find("memoserv")) != NULL) { snprintf(buf, BUFSIZE, "%s [auto memo] You have been invited to the group: %s", entity(mu)->name, entity(mg)->name); command_exec_split(svs, si, "SEND", buf, svs->commands); } else { myuser_notice(si->service->nick, mu, "You have been invited to the group: %s", entity(mg)->name); } logcommand(si, CMDLOG_SET, "INVITE: \2%s\2 \2%s\2", entity(mg)->name, entity(mu)->name); command_success_nodata(si, _("\2%s\2 has been invited to \2%s\2"), entity(mu)->name, entity(mg)->name); snprintf(description, sizeof description, "Invited \2%s\2 to join.", entity(mu)->name); notify_group_misc_change(si, mg, description); }
static void gs_cmd_set_open(sourceinfo_t *si, int parc, char *parv[]) { mygroup_t *mg; if (!parv[0] || !parv[1]) { command_fail(si, fault_needmoreparams, STR_INSUFFICIENT_PARAMS, "OPEN"); command_fail(si, fault_needmoreparams, _("Syntax: OPEN <!group> <ON|OFF>")); return; } if ((mg = mygroup_find(parv[0])) == NULL) { command_fail(si, fault_nosuch_target, _("The group \2%s\2 does not exist."), parv[0]); return; } if (!groupacs_sourceinfo_has_flag(mg, si, GA_FOUNDER)) { command_fail(si, fault_noprivs, STR_NOT_AUTHORIZED); return; } if (!strcasecmp(parv[1], "ON")) { if (!gs_config->enable_open_groups) { command_fail(si, fault_nochange, _("Setting groups as open has been administratively disabled.")); return; } if (mg->flags & MG_OPEN) { command_fail(si, fault_nochange, _("\2%s\2 is already open to anyone joining."), entity(mg)->name); return; } mg->flags |= MG_OPEN; logcommand(si, CMDLOG_SET, "OPEN:ON: \2%s\2", entity(mg)->name); command_success_nodata(si, _("\2%s\2 is now open to anyone joining."), entity(mg)->name); } else if (!strcasecmp(parv[1], "OFF")) { if (!(mg->flags & MG_OPEN)) { command_fail(si, fault_nochange, _("\2%s\2 is already not open to anyone joining."), entity(mg)->name); return; } mg->flags &= ~MG_OPEN; logcommand(si, CMDLOG_SET, "OPEN:OFF: \2%s\2", entity(mg)->name); command_success_nodata(si, _("\2%s\2 is no longer open to anyone joining."), entity(mg)->name); } else { command_fail(si, fault_badparams, STR_INVALID_PARAMS, "OPEN"); command_fail(si, fault_badparams, _("Syntax: OPEN <!group> <ON|OFF>")); } }