Thread: [srvx-commits] CVS: services/src modcmd.c,1.32,1.33 modcmd.help,1.6,1.7
Brought to you by:
entrope
|
From: Entrope <en...@us...> - 2002-10-26 22:51:44
|
Update of /cvsroot/srvx/services/src
In directory usw-pr-cvs1:/tmp/cvs-serv2412/src
Modified Files:
modcmd.c modcmd.help
Log Message:
implement and document a "showcommands" command (see featreq #572558)
Index: modcmd.c
===================================================================
RCS file: /cvsroot/srvx/services/src/modcmd.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -C2 -r1.32 -r1.33
*** modcmd.c 11 Oct 2002 03:11:57 -0000 1.32
--- modcmd.c 26 Oct 2002 22:51:40 -0000 1.33
***************
*** 27,32 ****
#define MCMSG_BARE_FLAG "Flag %.*s must be preceeded by a + or -."
#define MCMSG_UNKNOWN_FLAG "Unknown module flag %.*s."
! #define MCMSG_BAD_OPSERV_LEVEL "Invalid OpServ access level %s."
! #define MCMSG_BAD_CHANSERV_LEVEL "Invalid ChanServ access level %s."
#define MCMSG_UNKNOWN_COMMAND "Unknown command name %s (as template for %s in service %s)."
#define MCMSG_BAD_WEIGHT "Invalid command weight %s."
--- 27,32 ----
#define MCMSG_BARE_FLAG "Flag %.*s must be preceeded by a + or -."
#define MCMSG_UNKNOWN_FLAG "Unknown module flag %.*s."
! #define MCMSG_BAD_OPSERV_LEVEL "Invalid $O access level %s."
! #define MCMSG_BAD_CHANSERV_LEVEL "Invalid $C access level %s."
#define MCMSG_UNKNOWN_COMMAND "Unknown command name %s (as template for %s in service %s)."
#define MCMSG_BAD_WEIGHT "Invalid command weight %s."
***************
*** 450,454 ****
*/
static int
! svccmd_can_invoke_real(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, int server_qualified, int debit) {
unsigned int uData_checked = 0;
struct userData *uData = NULL;
--- 450,454 ----
*/
static int
! svccmd_can_invoke_real(struct userNode *user, struct userNode *bot, struct svccmd *cmd, struct chanNode *channel, char server_qualified, char debit, char noisy) {
unsigned int uData_checked = 0;
struct userData *uData = NULL;
***************
*** 456,517 ****
if (cmd->flags & MODCMD_DISABLED) {
! send_message(user, bot, MSG_COMMAND_DISABLED, cmd->name);
return 0;
}
if ((cmd->flags & MODCMD_REQUIRE_QUALIFIED) && !server_qualified) {
! send_message(user, bot, MCMSG_MUST_QUALIFY, bot->nick, cmd->name, bot->nick);
return 0;
}
if ((cmd->flags & MODCMD_REQUIRE_AUTHED) && !user->handle_info) {
! send_message(user, bot, MSG_AUTHENTICATE);
return 0;
}
! if ((cmd->flags & MODCMD_REQUIRE_CHANNEL) && !channel) {
! send_message(user, bot, MSG_INVALID_CHANNEL);
! return 0;
! }
! if (cmd->flags & MODCMD_REQUIRE_REGCHAN) {
! if (!channel) {
! /* XXX: could maybe figure out better way to handle this case */
! send_message(user, bot, MSG_INVALID_CHANNEL);
return 0;
! } else {
! if (!channel->channel_info) {
! send_message(user, bot, MCMSG_CHAN_NOT_REGISTERED, channel->name);
return 0;
}
}
! }
! if (cmd->flags & MODCMD_REQUIRE_CHANUSER) {
! if (!uData_checked) uData = _GetChannelUser(channel->channel_info, user->handle_info, 1, 0), uData_checked = 1;
! if (!uData) {
! send_message(user, bot, MCMSG_NO_CHANNEL_ACCESS, channel->name);
! return 0;
! } else if (uData->access < cmd->min_channel_access) {
! send_message(user, bot, MCMSG_LOW_CHANNEL_ACCESS, channel->name);
! return 0;
}
! }
! if (cmd->flags & MODCMD_REQUIRE_JOINABLE) {
! if (!uData_checked) uData = _GetChannelUser(channel->channel_info, user->handle_info, 1, 0), uData_checked = 1;
! if ((channel->modes & (MODE_INVITEONLY|MODE_KEY))
! && (!channel->channel_info || !uData)
! && !IsService(user)
! && !GetUserMode(channel, user)) {
! send_message(user, bot, MCMSG_REQUIRES_JOINABLE, channel->name);
! return 0;
}
! }
! if ((cmd->flags & MODCMD_TOY) && channel) {
! char opt = channel->channel_info ? channel->channel_info->options[optToys] : 'n';
! switch (opt) {
! case 'd':
! send_message(user, bot, MCMSG_TOYS_DISABLED, channel->name);
! return 0;
! case 'n':
! rflags |= ACTION_NOCHANNEL;
! break;
! case 'p':
! break;
}
}
--- 456,517 ----
if (cmd->flags & MODCMD_DISABLED) {
! if (noisy) send_message(user, bot, MSG_COMMAND_DISABLED, cmd->name);
return 0;
}
if ((cmd->flags & MODCMD_REQUIRE_QUALIFIED) && !server_qualified) {
! if (noisy) send_message(user, bot, MCMSG_MUST_QUALIFY, bot->nick, cmd->name, bot->nick);
return 0;
}
if ((cmd->flags & MODCMD_REQUIRE_AUTHED) && !user->handle_info) {
! if (noisy) send_message(user, bot, MSG_AUTHENTICATE);
return 0;
}
! if (channel || noisy) {
! if ((cmd->flags & MODCMD_REQUIRE_CHANNEL) && !channel) {
! if (noisy) send_message(user, bot, MSG_INVALID_CHANNEL);
return 0;
! }
! if (cmd->flags & MODCMD_REQUIRE_REGCHAN) {
! if (!channel) {
! /* XXX: could maybe figure out better way to handle this case */
! if (noisy) send_message(user, bot, MSG_INVALID_CHANNEL);
! return 0;
! } else if (!channel->channel_info) {
! if (noisy) send_message(user, bot, MCMSG_CHAN_NOT_REGISTERED, channel->name);
return 0;
}
}
! if (cmd->flags & MODCMD_REQUIRE_CHANUSER) {
! if (!uData_checked) uData = _GetChannelUser(channel->channel_info, user->handle_info, 1, 0), uData_checked = 1;
! if (!uData) {
! if (noisy) send_message(user, bot, MCMSG_NO_CHANNEL_ACCESS, channel->name);
! return 0;
! } else if (uData->access < cmd->min_channel_access) {
! if (noisy) send_message(user, bot, MCMSG_LOW_CHANNEL_ACCESS, channel->name);
! return 0;
! }
}
! if (cmd->flags & MODCMD_REQUIRE_JOINABLE) {
! if (!uData_checked) uData = _GetChannelUser(channel->channel_info, user->handle_info, 1, 0), uData_checked = 1;
! if ((channel->modes & (MODE_INVITEONLY|MODE_KEY))
! && (!channel->channel_info || !uData)
! && !IsService(user)
! && !GetUserMode(channel, user)) {
! if (noisy) send_message(user, bot, MCMSG_REQUIRES_JOINABLE, channel->name);
! return 0;
! }
}
! if ((cmd->flags & MODCMD_TOY) && channel) {
! char opt = channel->channel_info ? channel->channel_info->options[optToys] : 'n';
! switch (opt) {
! case 'd':
! if (noisy) send_message(user, bot, MCMSG_TOYS_DISABLED, channel->name);
! return 0;
! case 'n':
! rflags |= ACTION_NOCHANNEL;
! break;
! case 'p':
! break;
! }
}
}
***************
*** 522,539 ****
/* allow it */
} else {
! send_message(user, bot, MSG_COMMAND_PRIVILEGED, cmd->name);
return 0;
}
}
if ((cmd->flags & MODCMD_REQUIRE_HELPING) && !HANDLE_FLAGGED(user->handle_info, HELPING)) {
! send_message(user, bot, MCMSG_MUST_BE_HELPING);
return 0;
}
if (cmd->min_opserv_level > 0) {
! if (!oper_has_access(user, bot, cmd->min_opserv_level, 0)) return 0;
}
if (cmd->req_account_flags || cmd->deny_account_flags) {
if (!user->handle_info) {
! send_message(user, bot, MSG_AUTHENTICATE);
return 0;
}
--- 522,539 ----
/* allow it */
} else {
! if (noisy) send_message(user, bot, MSG_COMMAND_PRIVILEGED, cmd->name);
return 0;
}
}
if ((cmd->flags & MODCMD_REQUIRE_HELPING) && !HANDLE_FLAGGED(user->handle_info, HELPING)) {
! if (noisy) send_message(user, bot, MCMSG_MUST_BE_HELPING);
return 0;
}
if (cmd->min_opserv_level > 0) {
! if (!oper_has_access(user, bot, cmd->min_opserv_level, !noisy)) return 0;
}
if (cmd->req_account_flags || cmd->deny_account_flags) {
if (!user->handle_info) {
! if (noisy) send_message(user, bot, MSG_AUTHENTICATE);
return 0;
}
***************
*** 541,550 ****
if ((cmd->req_account_flags & ~user->handle_info->flags)
|| (cmd->deny_account_flags & user->handle_info->flags)) {
! send_message(user, bot, MSG_COMMAND_PRIVILEGED, cmd->name);
return 0;
}
}
if (debit && !policer_conforms(user->command_policer, now, cmd->weight)) {
! send_message(user, bot, MSG_COMMAND_FLOOD);
return 0;
}
--- 541,550 ----
if ((cmd->req_account_flags & ~user->handle_info->flags)
|| (cmd->deny_account_flags & user->handle_info->flags)) {
! if (noisy) send_message(user, bot, MSG_COMMAND_PRIVILEGED, cmd->name);
return 0;
}
}
if (debit && !policer_conforms(user->command_policer, now, cmd->weight)) {
! if (noisy) send_message(user, bot, MSG_COMMAND_FLOOD);
return 0;
}
***************
*** 552,555 ****
--- 552,556 ----
/* If it's an override, return a special value. */
if ((cmd->flags & MODCMD_REQUIRE_CHANUSER)
+ && noisy
&& (uData->access > ulOwner)
&& (!(uData = _GetChannelUser(channel->channel_info, user->handle_info, 0, 0))
***************
*** 565,569 ****
struct svccmd collapsed;
svccmd_collapse(cmd, &collapsed, 0);
! return svccmd_can_invoke_real(user, bot, &collapsed, channel, server_qualified, 0);
}
--- 566,570 ----
struct svccmd collapsed;
svccmd_collapse(cmd, &collapsed, 0);
! return svccmd_can_invoke_real(user, bot, &collapsed, channel, server_qualified, 0, 1);
}
***************
*** 684,688 ****
channel = NULL;
}
! perms = svccmd_can_invoke_real(user, service->bot, &cmd, channel, server_qualified, 1);
if (!perms) return 0;
if (argc < cmd.command->min_argc) {
--- 685,689 ----
channel = NULL;
}
! perms = svccmd_can_invoke_real(user, service->bot, &cmd, channel, server_qualified, 1, 1);
if (!perms) return 0;
if (argc < cmd.command->min_argc) {
***************
*** 1455,1458 ****
--- 1456,1537 ----
}
+ static MODCMD_FUNC(cmd_showcommands) {
+ struct svccmd_list commands;
+ struct svccmd collapsed;
+ struct helpfile_table tbl;
+ struct svccmd *svccmd;
+ dict_iterator_t it;
+ unsigned int ii, ignore_flags = 0;
+ unsigned int max_opserv_level = 1000;
+ enum userLevel max_chanserv_level = ulOwner;
+ char show_opserv_level = 0, show_channel_access = 0;
+
+ /* Check to see what the max access they want to see is. */
+ for (ii=1; ii<argc; ++ii) {
+ if (isdigit(argv[ii][0])) {
+ max_opserv_level = atoi(argv[ii]);
+ } else {
+ max_chanserv_level = user_level_from_name(argv[ii]);
+ if ((max_chanserv_level == ulNone) && irccasecmp(argv[ii], "none")) {
+ reply(MCMSG_BAD_CHANSERV_LEVEL, argv[ii]);
+ return 0;
+ }
+ }
+ }
+
+ /* Find the matching commands. */
+ svccmd_list_init(&commands);
+ if (cmd->parent->privileged) ignore_flags = MODCMD_REQUIRE_OPER;
+ for (it = dict_first(cmd->parent->commands); it; it = iter_next(it)) {
+ svccmd = iter_data(it);
+ if (strchr(svccmd->name, ' ')) continue;
+ svccmd_collapse(svccmd, &collapsed, 0);
+ if (!svccmd_can_invoke_real(user, cmd->parent->bot, &collapsed, channel, 1, 0, 0)) continue;
+ if (collapsed.min_opserv_level > max_opserv_level) continue;
+ if (collapsed.min_channel_access > max_chanserv_level) continue;
+ if (collapsed.min_opserv_level > 0) show_opserv_level = 1;
+ if (collapsed.min_channel_access > ulNone) show_channel_access = 1;
+ if (collapsed.flags & (MODCMD_REQUIRE_STAFF|MODCMD_REQUIRE_HELPING) & ~ignore_flags) show_channel_access = 1;
+ svccmd_list_append(&commands, svccmd);
+ }
+
+ /* Build the table. */
+ tbl.length = commands.used + 1;
+ tbl.width = 1 + show_opserv_level + show_channel_access;
+ tbl.flags = TABLE_REPEAT_ROWS;
+ tbl.contents = calloc(tbl.length, sizeof(tbl.contents[0]));
+ tbl.contents[0] = calloc(tbl.width, sizeof(tbl.contents[0][0]));
+ tbl.contents[0][0] = "Command";
+ if (show_opserv_level && show_channel_access) {
+ tbl.contents[0][1] = "OpServ Access";
+ tbl.contents[0][2] = "ChanServ Access";
+ } else if (show_opserv_level || show_channel_access) {
+ tbl.contents[0][1] = "Access";
+ }
+ for (ii=0; ii<commands.used; ++ii) {
+ svccmd = commands.list[ii];
+ tbl.contents[ii+1] = calloc(tbl.width, sizeof(tbl.contents[0][0]));
+ tbl.contents[ii+1][0] = svccmd->name;
+ svccmd_collapse(svccmd, &collapsed, 0);
+ if (show_opserv_level) tbl.contents[ii+1][1] = strtab(collapsed.min_opserv_level);
+ if (show_channel_access) {
+ const char *access;
+ if (collapsed.flags & MODCMD_REQUIRE_HELPING) access = "helping";
+ else if (collapsed.flags & MODCMD_REQUIRE_STAFF) {
+ switch (collapsed.flags & MODCMD_REQUIRE_STAFF) {
+ case MODCMD_REQUIRE_OPER: access = "oper"; break;
+ case MODCMD_REQUIRE_OPER | MODCMD_REQUIRE_NETWORK_HELPER:
+ case MODCMD_REQUIRE_NETWORK_HELPER: access = "net.helper"; break;
+ default: access = "staff"; break;
+ }
+ } else access = user_level_from_level(collapsed.min_channel_access);
+ tbl.contents[ii+1][1+show_opserv_level] = access;
+ }
+ }
+ svccmd_list_clean(&commands);
+ table_send(cmd->parent->bot, user->nick, 0, 0, tbl);
+ return 0;
+ }
+
void
modcmd_nick_change(struct userNode *user, const char *new_nick) {
***************
*** 1563,1566 ****
--- 1642,1646 ----
modcmd_register(modcmd_module, "stats modules", cmd_stats_modules, 1, 0, "access", "0", NULL);
modcmd_register(modcmd_module, "stats services", cmd_stats_services, 1, 0, "access", "0", NULL);
+ modcmd_register(modcmd_module, "showcommands", cmd_showcommands, 1, 0, NULL);
}
Index: modcmd.help
===================================================================
RCS file: /cvsroot/srvx/services/src/modcmd.help,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** modcmd.help 24 Sep 2002 19:21:01 -0000 1.6
--- modcmd.help 26 Oct 2002 22:51:41 -0000 1.7
***************
*** 63,64 ****
--- 63,67 ----
"When a bot nick is given, shows commands bound to that service.",
"$uSee Also:$u stats modules, command, modcmd, bind, unbind");
+ "showcommands" ("/msg $S SHOWCOMMANDS [opserv-access] [channel-access]",
+ "Shows commands which you can execute (with their required access levels). If you give a numeric $O access level or text $C access name, it further restricts output to only show commands which can be executed by users with that access.",
+ "$uSee Also:$u command");
|