/* funext.c - Functions that rely on external call-outs */ /* $Id: funext.c,v 1.21 2003/02/24 18:05:23 rmg Exp $ */ #include "copyright.h" #include "autoconf.h" #include "config.h" #include "alloc.h" /* required by mudconf */ #include "flags.h" /* required by mudconf */ #include "htab.h" /* required by mudconf */ #include "mudconf.h" /* required by code */ #include "db.h" /* required by externs */ #include "externs.h" /* required by code */ #include "functions.h" /* required by code */ #include "powers.h" /* required by code */ #include "command.h" /* required by code */ #include "db_sql.h" /* required by code */ extern void FDECL(make_ulist, (dbref, char *, char **)); extern void FDECL(make_portlist, (dbref, dbref, char *, char **)); extern int FDECL(fetch_idle, (dbref, int)); extern int FDECL(fetch_connect, (dbref, int)); extern char * FDECL(get_doing, (dbref, int)); extern void FDECL(make_sessioninfo, (dbref, dbref, int, char *, char **)); extern dbref FDECL(get_programmer, (dbref)); extern void FDECL(cf_display, (dbref, char *, char *, char **)); extern void FDECL(help_helper, (dbref, int, int, char *, char *, char **)); extern INLINE int FDECL(safe_chr_real_fn, (char, char *, char **, int)); #define Find_Connection(x,s,t,p) \ p = t = NOTHING; \ if (is_integer(s)) { \ p = atoi(s); \ } else { \ t = lookup_player(x, s, 1); \ if (Good_obj(t) && Can_Hide(t) && Hidden(t) && \ !See_Hidden(x)) \ t = NOTHING; \ } /* --------------------------------------------------------------------------- * config: Display a MUSH config parameter. */ FUNCTION(fun_config) { cf_display(player, fargs[0], buff, bufc); } /* --------------------------------------------------------------------------- * fun_lwho: Return list of connected users. */ FUNCTION(fun_lwho) { make_ulist(player, buff, bufc); } /* --------------------------------------------------------------------------- * fun_ports: Returns a list of ports for a user. */ FUNCTION(fun_ports) { dbref target; if (!Wizard(player)) { return; } target = lookup_player(player, fargs[0], 1); if (!Good_obj(target) || !Connected(target)) { return; } make_portlist(player, target, buff, bufc); } /* --------------------------------------------------------------------------- * fun_doing: Returns a user's doing. */ FUNCTION(fun_doing) { dbref target; int port; char *str; Find_Connection(player, fargs[0], target, port); if ((port < 0) && (target == NOTHING)) { return; } str = get_doing(target, port); if (str) { safe_str(str, buff, bufc); } } /* --------------------------------------------------------------------------- * handle_conninfo: return seconds idle or connected (IDLE, CONN). */ FUNCTION(handle_conninfo) { dbref target; int port; Find_Connection(player, fargs[0], target, port); if ((port < 0) && (target == NOTHING)) { safe_known_str((char *) "-1", 2, buff, bufc); return; } safe_ltos(buff, bufc, Is_Func(CONNINFO_IDLE) ? fetch_idle(target, port) : fetch_connect(target, port)); } /* --------------------------------------------------------------------------- * fun_session: Return session info about a port. */ FUNCTION(fun_session) { dbref target; int port; Find_Connection(player, fargs[0], target, port); if ((port < 0) && (target == NOTHING)) { safe_str((char *) "-1 -1 -1", buff, bufc); return; } make_sessioninfo(player, target, port, buff, bufc); } /* --------------------------------------------------------------------------- * fun_programmer: Returns the dbref or #1- of an object in a @program. */ FUNCTION(fun_programmer) { dbref target; target = lookup_player(player, fargs[0], 1); if (!Good_obj(target) || !Connected(target) || !Examinable(player, target)) { safe_nothing(buff, bufc); return; } safe_dbref(buff, bufc, get_programmer(target)); } /*--------------------------------------------------------------------------- * fun_helptext: Read an entry from a helpfile. */ FUNCTION(fun_helptext) { CMDENT *cmdp; char *p; if (!fargs[0] || !*fargs[0]) { safe_str((char *) "#-1 NOT FOUND", buff, bufc); return; } for (p = fargs[0]; *p; p++) *p = tolower(*p); cmdp = (CMDENT *) hashfind(fargs[0], &mudstate.command_htab); if (!cmdp || (cmdp->info.handler != do_help)) { safe_str((char *) "#-1 NOT FOUND", buff, bufc); return; } if (!Check_Cmd_Access(player, cmdp, cargs, ncargs)) { safe_noperm(buff, bufc); return; } help_helper(player, (cmdp->extra & ~HELP_RAWHELP), (cmdp->extra & HELP_RAWHELP) ? 0 : 1, fargs[1], buff, bufc); } /*--------------------------------------------------------------------------- * SQL stuff. */ FUNCTION(fun_sql) { Delim row_delim, field_delim; /* Special -- the last two arguments are output delimiters */ VaChk_Range(1, 3); VaChk_Sep(&row_delim, 2, DELIM_STRING|DELIM_NULL|DELIM_CRLF); if (nfargs < 3) { Delim_Copy(&field_delim, &row_delim); } else { VaChk_Sep(&field_delim, 3, DELIM_STRING|DELIM_NULL|DELIM_CRLF); } sql_query(player, fargs[0], buff, bufc, &row_delim, &field_delim); } /*--------------------------------------------------------------------------- * Pueblo HTML-related functions. */ #ifdef PUEBLO_SUPPORT FUNCTION(fun_html_escape) { html_escape(fargs[0], buff, bufc); } FUNCTION(fun_html_unescape) { const char *msg_orig; int ret = 0; for (msg_orig = fargs[0]; msg_orig && *msg_orig && !ret; msg_orig++) { switch (*msg_orig) { case '&': if (!strncmp(msg_orig, """, 6)) { ret = safe_chr_fn('\"', buff, bufc); msg_orig += 5; } else if (!strncmp(msg_orig, "<", 4)) { ret = safe_chr_fn('<', buff, bufc); msg_orig += 3; } else if (!strncmp(msg_orig, ">", 4)) { ret = safe_chr_fn('>', buff, bufc); msg_orig += 3; } else if (!strncmp(msg_orig, "&", 5)) { ret = safe_chr_fn('&', buff, bufc); msg_orig += 4; } else { ret = safe_chr_fn('&', buff, bufc); } break; default: ret = safe_chr_fn(*msg_orig, buff, bufc); break; } } } FUNCTION(fun_url_escape) { /* These are the characters which are converted to %<hex> */ char *escaped_chars = "<>#%{}|\\^~[]';/?:@=&\"+"; const char *msg_orig; int ret = 0; char tbuf[10]; for (msg_orig = fargs[0]; msg_orig && *msg_orig && !ret; msg_orig++) { if (strchr(escaped_chars, *msg_orig)) { sprintf(tbuf, "%%%2x", *msg_orig); ret = safe_str_fn(tbuf, buff, bufc); } else if (*msg_orig == ' ') { ret = safe_chr_fn('+', buff, bufc); } else { ret = safe_chr_fn(*msg_orig, buff, bufc); } } } FUNCTION(fun_url_unescape) { const char *msg_orig; int ret = 0; unsigned int tempchar; char tempstr[10]; for (msg_orig = fargs[0]; msg_orig && *msg_orig && !ret;) { switch (*msg_orig) { case '+': ret = safe_chr_fn(' ', buff, bufc); msg_orig++; break; case '%': strncpy(tempstr, msg_orig + 1, 2); tempstr[2] = '\0'; if ((sscanf(tempstr, "%x", &tempchar) == 1) && (tempchar > 0x1F) && (tempchar < 0x7F)) { ret = safe_chr_fn((char)tempchar, buff, bufc); } if (*msg_orig) msg_orig++; /* Skip the '%' */ if (*msg_orig) /* Skip the 1st hex character. */ msg_orig++; if (*msg_orig) /* Skip the 2nd hex character. */ msg_orig++; break; default: ret = safe_chr_fn(*msg_orig, buff, bufc); msg_orig++; break; } } return; } #endif /* PUEBLO_SUPPORT */