static XS (XS_Xchat_send_modes) { AV *p_targets = NULL; int modes_per_line = 0; char sign; char mode; int i = 0; const char **targets; int target_count = 0; SV **elem; dXSARGS; if (items < 3 || items > 4) { xchat_print (ph, "Usage: Xchat::send_modes( targets, sign, mode, modes_per_line)" ); } else { if (SvROK (ST (0))) { p_targets = (AV*) SvRV (ST (0)); target_count = av_len (p_targets) + 1; targets = malloc (target_count * sizeof (char *)); for (i = 0; i < target_count; i++ ) { elem = av_fetch (p_targets, i, 0); if (elem != NULL) { targets[i] = SvPV_nolen (*elem); } else { targets[i] = ""; } } } else{ targets = malloc (sizeof (char *)); targets[0] = SvPV_nolen (ST (0)); target_count = 1; } if (target_count == 0) { XSRETURN_EMPTY; } sign = (SvPV_nolen (ST (1)))[0]; mode = (SvPV_nolen (ST (2)))[0]; if (items == 4 ) { modes_per_line = (int) SvIV (ST (3)); } xchat_send_modes (ph, targets, target_count, modes_per_line, sign, mode); free (targets); } }
/* * lua: xchat.send_modes(targets, sign, mode [, modes_per_line]) * desc: Sends a number of channel mode changes to the current channel. * For example, you can Op a whole group of people in one go. It may * send multiple MODE lines if the request doesn't fit on one. Pass 0 * for modes_per_line to use the current server's maximum possible. * This function should only be called while in a channel context. * ret: none * args: * * targets (table): list of names * * sign (string): mode sign, i.e. "+" or "-", only the first char of * this is used (currently unchecked if it's really "+" or "-") * * mode (string): mode char, i.e. "o" for opping, only the first * char of this is used (currently unchecked, what char) * * modes_per_line (number): [optional] number of modes per line */ static int lxc_send_modes(lua_State *L) { int i = 1; const char *name, *mode, *sign; const char *targets[4096]; int num = 0; /* modes per line */ if (!lua_istable(L, 1)) { luaL_error(L, "xchat.send_modes(): first argument is not a table: %s", lua_typename(L, lua_type(L, 1))); return 0; } while (1) { lua_pushnumber(L, i); /* push index on stack */ lua_gettable(L, 1); /* and get the element @ index */ if (lua_isnil(L, -1)) { /* end of table */ lua_pop(L, 1); break; } if (lua_type(L, -1) != LUA_TSTRING) { /* oops, something wrong */ luaL_error(L, "lua: xchat.send_modes(): table element #%d not a string: %s", i, lua_typename(L, lua_type(L, -1))); lua_pop(L, 1); return 0; } name = lua_tostring(L, -1); if (name == NULL) { /* this should not happen, but... */ lua_pop(L, 1); break; } targets[i-1] = name; lua_pop(L, 1); /* take index from stack */ ++i; } sign = luaL_checkstring(L, 2); if (sign[0] == '\0' || sign[1] != '\0') { luaL_error(L, "argument #2 (mode sign) does not have length 1"); return 0; } if ((sign[0] != '+') && (sign[0] != '-')) { luaL_error(L, "argument #2 (mode sign) is not '+' or '-'"); return 0; } mode = luaL_checkstring(L, 3); if (mode[0] == '\0' || mode[1] != '\0') { luaL_error(L, "argument #3 (mode char) does not have length 1"); return 0; } if (!isalpha((int)mode[0]) || !isascii((int)mode[0])) { luaL_error(L, "argument #3 is not a valid mode character"); return 0; } if (lua_gettop(L) == 4) num = luaL_checknumber(L, 4); xchat_send_modes(ph, targets, i-1, num, sign[0], mode[0]); return 0; }