You need to sign in or sign up before continuing.
Newer
Older
/* Synchronet "@code" functions */
/****************************************************************************
* @format.tab-size 4 (Plain Text/Source Code File Header) *
* @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
* *
* Copyright Rob Swindell - http://www.synchro.net/copyright.html *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License *
* as published by the Free Software Foundation; either version 2 *
* of the License, or (at your option) any later version. *
* See the GNU General Public License for more details: gpl.txt or *
* http://www.fsf.org/copyleft/gpl.html *
* *
* For Synchronet coding style and modification guidelines, see *
* http://www.synchro.net/source.html *
* *
* Note: If this box doesn't appear square, then you need to fix your tabs. *
****************************************************************************/
#include "sbbs.h"
#include "cmdshell.h"
#include "utf8.h"
#include "unicode.h"
#include "cp437defs.h"
#include "ver.h"
#include "petdefs.h"
#include "filedat.h"
#if defined(_WINSOCKAPI_)
extern WSADATA WSAData;
#define SOCKLIB_DESC WSAData.szDescription
#else
#define SOCKLIB_DESC NULL
#endif
struct atcode_format {

rswindell
committed
enum {
none,
left,
right,
center
} align = none;
bool zero_padded = false;
bool truncated = true;
bool doubled = false;
bool thousep = false; // thousands-separated
bool uppercase = false;
bool width_specified = false;
char* parse(char* sp) {
char* p;
disp_len = strlen(sp) + 2;
if ((p = strchr(sp, '|')) != NULL) {
if (strchr(p, 'T') != NULL)
if (strchr(p, 'U') != NULL)
if (strchr(p, 'L') != NULL)
else if (strchr(p, 'R') != NULL)
else if (strchr(p, 'C') != NULL)
else if (strchr(p, 'W') != NULL)
else if (strchr(p, 'Z') != NULL)
zero_padded = true;
else if (strchr(p, '>') != NULL)
truncated = false;
}
else if (strchr(sp, ':') != NULL)
else if ((p = strstr(sp, "-L")) != NULL)
else if ((p = strstr(sp, "-R")) != NULL)
else if ((p = strstr(sp, "-C")) != NULL)
else if ((p = strstr(sp, "-W")) != NULL) /* wide */
doubled = true;
else if ((p = strstr(sp, "-Z")) != NULL)
zero_padded = true;
else if ((p = strstr(sp, "-T")) != NULL)
thousep = true;
else if ((p = strstr(sp, "-U")) != NULL)
uppercase = true;
else if ((p = strstr(sp, "->")) != NULL) /* wrap */
lp++; // skip the '|' or '-'
while (*lp == '>' || IS_ALPHA(*lp))
width_specified = true;
while (*lp && !IS_DIGIT(*lp))
if (*lp && IS_DIGIT(*lp)) {
disp_len = atoi(lp);
width_specified = true;
}
}
return p;
}
};
/****************************************************************************/
/* Returns 0 if invalid @ code. Returns length of @ code if valid. */
/****************************************************************************/
int sbbs_t::show_atcode(const char *instr, JSObject* obj)
{
char str[128], str2[128], *tp, *sp, *p;
int len;
atcode_format fmt;
int pmode = 0;
const char * cp;
return 0;
SAFECOPY(str, instr);
tp = strchr(str + 1, '@');
if (!tp) /* no terminating @ */
sp = strchr(str + 1, ' ');
if (sp && sp < tp) /* space before terminating @ */
len = (tp - str) + 1;
(*tp) = 0;
sp = (str + 1);
if (*sp == '~' && *(sp + 1)) { // Mouse hot-spot (hungry)
tp = sp;
else {
*tp = 0;
tp++;
}
c_unescape_str(tp);
add_hotspot(tp, /* hungry: */ true, column, column + strlen(sp) - 1, row);

rswindell
committed
bputs(sp);
return len;
}
if (*sp == '`' && *(sp + 1)) { // Mouse hot-spot (strict)

rswindell
committed
sp++;
tp = strchr(sp + 1, '`');

rswindell
committed
tp = sp;
else {
*tp = 0;
tp++;
}
c_unescape_str(tp);
add_hotspot(tp, /* hungry: */ false, column, column + strlen(sp) - 1, row);
// @!x@ for Ctrl-A x equivalent(s) */
if (*sp == '!') {
for (p = sp + 1; *p != '\0' && *p != '@'; p++)
ctrl_a(*p);
return len;
}
p = fmt.parse(sp);
cp = atcode(sp, str2, sizeof(str2), &pmode, fmt.align == fmt.center, obj);
char separated[128];
cp = separate_thousands(cp, separated, sizeof(separated), ',');
SAFECOPY(upper, cp);
strupr(upper);
cp = upper;
}
if (p == NULL || fmt.truncated == false || (fmt.width_specified == false && fmt.align == fmt.none))
fmt.disp_len = strlen(cp);
if (fmt.uppercase && fmt.align == fmt.none)
fmt.align = fmt.left;

rswindell
committed
if (fmt.truncated && strchr(cp, '\n') == NULL) {
if (column + fmt.disp_len > cols - 1) {
if (column >= cols - 1)
fmt.disp_len = 0;
fmt.disp_len = (cols - 1) - column;
if (pmode & P_UTF8) {
if (term_supports(UTF8))
fmt.disp_len += strlen(cp) - utf8_str_total_width(cp, unicode_zerowidth);
else
fmt.disp_len += strlen(cp) - utf8_str_count_width(cp, /* min: */ 1, /* max: */ 2, unicode_zerowidth);
}
if (fmt.align == fmt.left)
bprintf(pmode, "%-*.*s", fmt.disp_len, fmt.disp_len, cp);
else if (fmt.align == fmt.right)
bprintf(pmode, "%*.*s", fmt.disp_len, fmt.disp_len, cp);
else if (fmt.align == fmt.center) {
if (vlen < fmt.disp_len) {
int left = (fmt.disp_len - vlen) / 2;
bprintf(pmode, "%*s%-*s", left, "", fmt.disp_len - left, cp);
bprintf(pmode, "%.*s", fmt.disp_len, cp);
} else if (fmt.doubled) {
} else if (fmt.zero_padded) {
int vlen = strlen(cp);
if (vlen < fmt.disp_len)
bprintf(pmode, "%-.*s%s", (int)(fmt.disp_len - strlen(cp)), "0000000000", cp);
else
bprintf(pmode, "%.*s", fmt.disp_len, cp);
bprintf(pmode, "%.*s", fmt.disp_len, cp);
static const char* getpath(scfg_t* cfg, const char* path)
{
for (int i = 0; i < cfg->total_dirs; i++) {
if (stricmp(cfg->dir[i]->code, path) == 0)
return cfg->dir[i]->path;
}
return path;
}
const char* sbbs_t::formatted_atcode(const char* sp, char* str, size_t maxlen)
{
char tmp[128];
char buf[256];
atcode_format fmt;
SAFECOPY(tmp, sp);
char* p = fmt.parse(tmp);
const char* cp = atcode(tmp, buf, sizeof buf);
if (cp == nullptr)
return nullptr;
char separated[128];
if (fmt.thousep)
cp = separate_thousands(cp, separated, sizeof(separated), ',');
char upper[128];
if (fmt.uppercase) {
SAFECOPY(upper, cp);
strupr(upper);
cp = upper;
}
if (p == NULL || fmt.truncated == false || (fmt.width_specified == false && fmt.align == fmt.none))
fmt.disp_len = strlen(cp);
if (fmt.align == fmt.left)
snprintf(str, maxlen, "%-*.*s", fmt.disp_len, fmt.disp_len, cp);
else if (fmt.align == fmt.right)
snprintf(str, maxlen, "%*.*s", fmt.disp_len, fmt.disp_len, cp);
else if (fmt.align == fmt.center) {
int vlen = strlen(cp);
if (vlen < fmt.disp_len) {
int left = (fmt.disp_len - vlen) / 2;
snprintf(str, maxlen, "%*s%-*s", left, "", fmt.disp_len - left, cp);
} else
snprintf(str, maxlen, "%.*s", fmt.disp_len, cp);
// } else if(fmt.doubled) { // Unsupported in this context
// wide(cp);
} else if (fmt.zero_padded) {
int vlen = strlen(cp);
if (vlen < fmt.disp_len)
snprintf(str, maxlen, "%-.*s%s", (int)(fmt.disp_len - strlen(cp)), "0000000000", cp);
else
snprintf(str, maxlen, "%.*s", fmt.disp_len, cp);
} else
snprintf(str, maxlen, "%.*s", fmt.disp_len, cp);
return str;
}

Rob Swindell
committed
const char* sbbs_t::atcode(const char* sp, char* str, size_t maxlen, int* pmode, bool centered, JSObject* obj)
char tmp[128];
char* tp = NULL;
int i;
uint ugrp;
uint usub;
long l;
stats_t stats;
node_t node;
struct tm tm;
str[0] = 0;
if (strcmp(sp, "SHOW") == 0) {
console &= ~CON_ECHO_OFF;
return nulstr;
}
if (strncmp(sp, "SHOW:", 5) == 0) {
uchar* ar = arstr(NULL, sp + 5, &cfg, NULL);
if (ar != NULL) {
if (!chk_ar(ar, &useron, &client))
console |= CON_ECHO_OFF;
else
console &= ~CON_ECHO_OFF;
free(ar);
}
return nulstr;
}
if (strcmp(sp, "HOT") == 0) { // Auto-mouse hot-spot attribute
if (strncmp(sp, "HOT:", 4) == 0) { // Auto-mouse hot-spot attribute
if (stricmp(sp, "hungry") == 0) {

rswindell
committed
hungry_hotspots = true;
hot_attr = curatr;
}
else if (stricmp(sp, "strict") == 0) {

rswindell
committed
hungry_hotspots = false;
hot_attr = curatr;
}
else if (stricmp(sp, "off") == 0)
hot_attr = strtoattr(sp, /* endptr: */ NULL);

rswindell
committed
return nulstr;
}
if (strcmp(sp, "CLEAR_HOT") == 0) {
clear_hotspots();
return nulstr;
}

rswindell
committed
if (strncmp(sp, "MNE:", 4) == 0) { // Mnemonic attribute control
sp += 4;
mneattr_low = strtoattr(sp, &tp);
mneattr_high = mneattr_low ^ HIGH;
if (tp != NULL && *tp != '\0')
mneattr_high = strtoattr(tp + 1, &tp);
if (tp != NULL && *tp != '\0')
mneattr_cmd = strtoattr(tp + 1, NULL);
return nulstr;
}
if (strncmp(sp, "RAINBOW:", 8) == 0) {
memset(rainbow, 0, sizeof rainbow);
parse_attr_str_list(rainbow, LEN_RAINBOW, sp + 8);
return nulstr;
}
if (strncmp(sp, "U+", 2) == 0) { // UNICODE
enum unicode_codepoint codepoint = (enum unicode_codepoint)strtoul(sp + 2, &tp, 16);
if (tp == NULL || *tp == 0)
outchar(codepoint, unicode_to_cp437(codepoint));
else {
char fallback = (char)strtoul(tp + 1, NULL, 16);
outchar(codepoint, fallback);
else if (*tp == '!') {
char ch = unicode_to_cp437(codepoint);
fallback = ch;
outchar(codepoint, fallback);
}
else
return NULL; // Invalid @-code
}
return nulstr;
}
if (strcmp(sp, "CHECKMARK") == 0) {
outchar(UNICODE_CHECK_MARK, CP437_CHECK_MARK);
return nulstr;
}
if (strcmp(sp, "ELLIPSIS") == 0) {
outchar(UNICODE_HORIZONTAL_ELLIPSIS, "...");
return nulstr;
}
if (strcmp(sp, "COPY") == 0) {
outchar(UNICODE_COPYRIGHT_SIGN, "(C)");
return nulstr;
}
if (strcmp(sp, "SOUNDCOPY") == 0) {
outchar(UNICODE_SOUND_RECORDING_COPYRIGHT, "(P)");
return nulstr;
}
if (strcmp(sp, "REGISTERED") == 0) {
outchar(UNICODE_REGISTERED_SIGN, "(R)");
return nulstr;
}
if (strcmp(sp, "TRADEMARK") == 0) {
outchar(UNICODE_TRADE_MARK_SIGN, "(TM)");
return nulstr;
}
if (strcmp(sp, "DEGREE_C") == 0) {
if (strcmp(sp, "DEGREE_F") == 0) {
if (strncmp(sp, "WIDE:", 5) == 0) {
if (!strcmp(sp, "VER"))
if (!strcmp(sp, "REV")) {
safe_snprintf(str, maxlen, "%c", REVISION);
if (!strcmp(sp, "FULL_VER")) {
safe_snprintf(str, maxlen, "%s%c%s", VERSION, REVISION, beta_version);

rswindell
committed
#if defined(_DEBUG)
strcat(str, " Debug");

rswindell
committed
#endif

rswindell
committed
}
if (!strcmp(sp, "VER_NOTICE"))
return VERSION_NOTICE;

rswindell
committed
if (!strcmp(sp, "OS_VER"))
return os_version(str, maxlen);
if (strcmp(sp, "OS_CPU") == 0)
return os_cpuarch(str, maxlen);

rswindell
committed
#ifdef JAVASCRIPT
if (!strcmp(sp, "JS_VER"))
return (char *)JS_GetImplementationVersion();

rswindell
committed
#endif
if (!strcmp(sp, "PLATFORM"))
return PLATFORM_DESC;

rswindell
committed
if (!strcmp(sp, "COPYRIGHT"))
return COPYRIGHT_NOTICE;

rswindell
committed
if (!strcmp(sp, "COMPILER")) {
char compiler[32];
DESCRIBE_COMPILER(compiler);
strncpy(str, compiler, maxlen);

rswindell
committed
}
if (strcmp(sp, "GIT_HASH") == 0)
return git_hash;
if (strcmp(sp, "GIT_BRANCH") == 0)
return git_branch;
if (strcmp(sp, "GIT_DATE") == 0)
if (strcmp(sp, "BUILD_DATE") == 0)
if (strcmp(sp, "BUILD_TIME") == 0)
if (!strcmp(sp, "UPTIME")) {
extern volatile time_t uptime;
now = time(NULL);
if (uptime != 0 && now >= uptime)
up = now - uptime;
char days[64] = "";
if ((up / (24 * 60 * 60)) >= 2) {
snprintf(days, sizeof days, "%u days ", (uint)(up / (24L * 60L * 60L)));
up %= (24 * 60 * 60);
safe_snprintf(str, maxlen, "%s%u:%02u"
, days
, (uint)(up / (60L * 60L))
, (uint)((up / 60L) % 60L)
);
if (!strcmp(sp, "SERVED")) {
safe_snprintf(str, maxlen, "%u", served);
if (!strcmp(sp, "SOCKET_LIB"))
return socklib_version(str, maxlen, SOCKLIB_DESC);

rswindell
committed
if (!strcmp(sp, "MSG_LIB")) {
safe_snprintf(str, maxlen, "SMBLIB %s", smb_lib_ver());

rswindell
committed
if (!strcmp(sp, "BBS") || !strcmp(sp, "BOARDNAME"))
if (!strcmp(sp, "BAUD") || !strcmp(sp, "BPS")) {
safe_snprintf(str, maxlen, "%u", cur_output_rate ? cur_output_rate : cur_rate);
if (!strcmp(sp, "CPS")) {
safe_snprintf(str, maxlen, "%u", cur_cps);
if (!strcmp(sp, "COLS")) {
safe_snprintf(str, maxlen, "%u", cols);
if (!strcmp(sp, "ROWS")) {
safe_snprintf(str, maxlen, "%u", rows);
if (strcmp(sp, "TERM") == 0)
return term_type();
if (strcmp(sp, "CHARSET") == 0)
return term_charset();
if (!strcmp(sp, "CONN"))
if (!strcmp(sp, "SYSOP"))
if (strcmp(sp, "SYSAVAIL") == 0)
return text[sysop_available(&cfg) ? LiSysopAvailable : LiSysopNotAvailable];
if (strcmp(sp, "SYSAVAILYN") == 0)
return text[sysop_available(&cfg) ? Yes : No];
if (!strcmp(sp, "LOCATION"))
return cfg.sys_location;
if (strcmp(sp, "NODE") == 0 || strcmp(sp, "NN") == 0) {
safe_snprintf(str, maxlen, "%u", cfg.node_num);
if (strcmp(sp, "TNODES") == 0 || strcmp(sp, "TNODE") == 0 || strcmp(sp, "TN") == 0) {
safe_snprintf(str, maxlen, "%u", cfg.sys_nodes);
if (strcmp(sp, "ANODES") == 0 || strcmp(sp, "ANODE") == 0 || strcmp(sp, "AN") == 0) {
safe_snprintf(str, maxlen, "%u", count_nodes(/* self: */ true));
return str;
}
if (strcmp(sp, "ONODES") == 0 || strcmp(sp, "ONODE") == 0 || strcmp(sp, "ON") == 0) {
safe_snprintf(str, maxlen, "%u", count_nodes(/* self: */ false));
return str;
}
if (strcmp(sp, "PWDAYS") == 0) {
if (cfg.sys_pwdays) {
safe_snprintf(str, maxlen, "%u", cfg.sys_pwdays);
return str;
}
return text[Unlimited];
}
if (strcmp(sp, "AUTODEL") == 0) {
if (cfg.sys_autodel) {
safe_snprintf(str, maxlen, "%u", cfg.sys_autodel);
return str;
}
return text[Unlimited];
}
if (strcmp(sp, "PAGER") == 0)
return (thisnode.misc & NODE_POFF) ? text[Off] : text[On];
if (strcmp(sp, "ALERTS") == 0)
return (thisnode.misc & NODE_AOFF) ? text[Off] : text[On];
if (strcmp(sp, "SPLITP") == 0)
return (useron.chat & CHAT_SPLITP) ? text[On] : text[Off];
if (!strcmp(sp, "INETADDR"))
return cfg.sys_inetaddr;
if (!strcmp(sp, "HOSTNAME"))
return server_host_name();
if (!strcmp(sp, "FIDOADDR")) {
if (cfg.total_faddrs)
return smb_faddrtoa(&cfg.faddr[0], str);
return nulstr;
if (!strcmp(sp, "EMAILADDR"))
return usermailaddr(&cfg, str
, (cfg.inetmail_misc & NMAIL_ALIAS) || (useron.rest & FLAG('O')) ? useron.alias : useron.name);
if (strcmp(sp, "NETMAIL") == 0)
return useron.netmail;
if (strcmp(sp, "TERMTYPE") == 0)

Rob Swindell
committed
return term_type(&useron, term_supports(), str, maxlen);
if (strcmp(sp, "TERMROWS") == 0)

Rob Swindell
committed
return term_rows(&useron, str, maxlen);
if (strcmp(sp, "TERMCOLS") == 0)

Rob Swindell
committed
return term_cols(&useron, str, maxlen);
if (strcmp(sp, "AUTOTERM") == 0)

Rob Swindell
committed
return (useron.misc & AUTOTERM) ? text[On] : text[Off];
if (strcmp(sp, "ANSI") == 0)

Rob Swindell
committed
return (useron.misc & ANSI) ? text[On] : text[Off];
if (strcmp(sp, "ASCII") == 0)

Rob Swindell
committed
return (useron.misc & NO_EXASCII) ? text[On] : text[Off];
if (strcmp(sp, "COLOR") == 0)

Rob Swindell
committed
return (useron.misc & COLOR) ? text[On] : text[Off];
if (strcmp(sp, "ICE") == 0)

Rob Swindell
committed
return (useron.misc & ICE_COLOR) ? text[On] : text[Off];
if (strcmp(sp, "RIP") == 0)

Rob Swindell
committed
return (useron.misc & RIP) ? text[On] : text[Off];
if (strcmp(sp, "PETSCII") == 0)

Rob Swindell
committed
return (useron.misc & PETSCII) ? text[On] : text[Off];
if (strcmp(sp, "PETGRFX") == 0) {
if (term_supports(PETSCII))
outcom(PETSCII_UPPERGRFX);
return nulstr;
}
if (strcmp(sp, "SWAPDEL") == 0)

Rob Swindell
committed
return (useron.misc & SWAP_DELETE) ? text[On] : text[Off];
if (strcmp(sp, "UTF8") == 0)

Rob Swindell
committed
return (useron.misc & UTF8) ? text[On] : text[Off];
if (strcmp(sp, "MOUSE") == 0)

Rob Swindell
committed
return (useron.misc & MOUSE) ? text[On] : text[Off];
if (strcmp(sp, "UPAUSE") == 0)

Rob Swindell
committed
return (useron.misc & UPAUSE) ? text[On] : text[Off];
if (strcmp(sp, "SPIN") == 0)

Rob Swindell
committed
return (useron.misc & SPIN) ? text[On] : text[Off];
if (strcmp(sp, "PAUSESPIN") == 0)

Rob Swindell
committed
return (useron.misc & NOPAUSESPIN) ? text[Off] : text[On];
if (strcmp(sp, "EXPERT") == 0)

Rob Swindell
committed
return (useron.misc & EXPERT) ? text[On] : text[Off];
if (strcmp(sp, "HOTKEYS") == 0)
return (useron.misc & COLDKEYS) ? text[Off] : text[On];

Rob Swindell
committed
if (strcmp(sp, "MSGCLS") == 0)

Rob Swindell
committed
return (useron.misc & CLRSCRN) ? text[On] : text[Off];
if (strcmp(sp, "FWD") == 0)
return (useron.misc & NETMAIL) ? text[On] : text[Off];
if (strcmp(sp, "REMSUBS") == 0)

Rob Swindell
committed
return (useron.misc & CURSUB) ? text[On] : text[Off];
if (strcmp(sp, "FILEDESC") == 0)

Rob Swindell
committed
return (useron.misc & EXTDESC) ? text[On] : text[Off];
if (strcmp(sp, "FILEFLAG") == 0)

Rob Swindell
committed
return (useron.misc & BATCHFLAG) ? text[On] : text[Off];
if (strcmp(sp, "AUTOHANG") == 0)

Rob Swindell
committed
return (useron.misc & AUTOHANG) ? text[On] : text[Off];
if (strcmp(sp, "AUTOLOGON") == 0)

Rob Swindell
committed
return (useron.misc & AUTOLOGON) ? text[On] : text[Off];
if (strcmp(sp, "QUIET") == 0)

Rob Swindell
committed
return (useron.misc & QUIET) ? text[On] : text[Off];
if (strcmp(sp, "ASKNSCAN") == 0)

Rob Swindell
committed
return (useron.misc & ASK_NSCAN) ? text[On] : text[Off];
if (strcmp(sp, "ASKSSCAN") == 0)

Rob Swindell
committed
return (useron.misc & ASK_SSCAN) ? text[On] : text[Off];
if (strcmp(sp, "ANFSCAN") == 0)

Rob Swindell
committed
return (useron.misc & ANFSCAN) ? text[On] : text[Off];
if (strcmp(sp, "EDITOR") == 0)

Rob Swindell
committed
return (useron.xedit < 1 || useron.xedit >= cfg.total_xedits) ? text[None] : cfg.xedit[useron.xedit - 1]->name;
if (strcmp(sp, "SHELL") == 0)

Rob Swindell
committed
return cfg.shell[useron.shell]->name;
if (strcmp(sp, "TMP") == 0)
return useron.tmpext;
if (strcmp(sp, "PROT") == 0) {
safe_snprintf(str, maxlen, "%c", useron.prot);
return str;
}
if (strcmp(sp, "PROTNAME") == 0)

Rob Swindell
committed
return protname(useron.prot);
if (strcmp(sp, "SEX") == 0) {
safe_snprintf(str, maxlen, "%c", useron.sex);
return str;
}
if (strcmp(sp, "GENDERS") == 0) {
if (!strcmp(sp, "QWKID"))
if (!strcmp(sp, "TIME") || !strcmp(sp, "SYSTIME") || !strcmp(sp, "TIME_UTC")) {
now = time(NULL);
memset(&tm, 0, sizeof(tm));
if (strcmp(sp, "TIME_UTC") == 0)
gmtime_r(&now, &tm);
else
localtime_r(&now, &tm);
if (cfg.sys_misc & SM_MILITARY)
safe_snprintf(str, maxlen, "%02d:%02d:%02d"
, tm.tm_hour, tm.tm_min, tm.tm_sec);
else
safe_snprintf(str, maxlen, "%02d:%02d %s"
, tm.tm_hour == 0 ? 12
: tm.tm_hour > 12 ? tm.tm_hour - 12
: tm.tm_hour, tm.tm_min, tm.tm_hour > 11 ? "pm":"am");
if (!strcmp(sp, "TIMEZONE"))
return smb_zonestr(sys_timezone(&cfg), str);
if (!strcmp(sp, "DATE") || !strcmp(sp, "SYSDATE") || !strcmp(sp, "DATE_UTC")) {
if (strcmp(sp, "DATE_UTC") == 0)
now -= xpTimeZone_local() * 60;
return datestr(now);
if (strncmp(sp, "DATE:", 5) == 0 || strncmp(sp, "TIME:", 5) == 0) {

Rob Swindell
committed
SAFECOPY(tmp, sp + 5);
c_unescape_str(tmp);
now = time(NULL);
memset(&tm, 0, sizeof(tm));
localtime_r(&now, &tm);

Rob Swindell
committed
strftime(str, maxlen, tmp, &tm);
return str;
}
if (strncmp(sp, "UTC:", 4) == 0) {
SAFECOPY(tmp, sp + 4);
c_unescape_str(tmp);
now = time(NULL);
memset(&tm, 0, sizeof(tm));
gmtime_r(&now, &tm);
strftime(str, maxlen, tmp, &tm);
return str;
}
if (!strcmp(sp, "DATETIME"))
return timestr(time(NULL));
if (!strcmp(sp, "DATETIME_UTC"))
return timestr(time(NULL) - (xpTimeZone_local() * 60));
if (!strcmp(sp, "DATETIMEZONE")) {
safe_snprintf(str, maxlen, "%s %s", timestr(time(NULL)), smb_zonestr(sys_timezone(&cfg), zone));
if (strcmp(sp, "DATEFMT") == 0) {
return date_format(&cfg, str, maxlen);
if (strcmp(sp, "BDATEFMT") == 0 || strcmp(sp, "BIRTHFMT") == 0) {
return birthdate_format(&cfg, str, maxlen);
if (strcmp(sp, "GENDERS") == 0)
return cfg.new_genders;
if (!strcmp(sp, "TMSG")) {
l = 0;
for (i = 0; i < cfg.total_subs; i++)
l += getposts(&cfg, i); /* l=total posts */
safe_snprintf(str, maxlen, "%lu", l);
if (!strcmp(sp, "TUSER")) {
safe_snprintf(str, maxlen, "%u", total_users(&cfg));
if (!strcmp(sp, "TFILE")) {
l = 0;
for (i = 0; i < cfg.total_dirs; i++)
l += getfiles(&cfg, i);
safe_snprintf(str, maxlen, "%lu", l);
if (strncmp(sp, "FILES:", 6) == 0) { // Number of files in specified directory
const char* path = getpath(&cfg, sp + 6);
safe_snprintf(str, maxlen, "%u", getfilecount(path));
if (strcmp(sp, "FILES") == 0) { // Number of files in current directory
safe_snprintf(str, maxlen, "%u", getfiles(&cfg, usrdir[curlib][curdir[curlib]]));
if (strncmp(sp, "FILESIZE:", 9) == 0) {
const char* path = getpath(&cfg, sp + 9);
byte_estimate_to_str(getfilesizetotal(path), str, maxlen, /* unit: */ 1, /* precision: */ 1);
if (strcmp(sp, "FILESIZE") == 0) {
byte_estimate_to_str(getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path)
, str, maxlen, /* unit: */ 1, /* precision: */ 1);
if (strncmp(sp, "FILEBYTES:", 10) == 0) { // Number of bytes in current file directory
const char* path = getpath(&cfg, sp + 10);
safe_snprintf(str, maxlen, "%" PRIu64, getfilesizetotal(path));
return str;
}
if (strcmp(sp, "FILEBYTES") == 0) { // Number of bytes in current file directory
, getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path));
if (strncmp(sp, "FILEKB:", 7) == 0) { // Number of kibibytes in current file directory
const char* path = getpath(&cfg, sp + 7);
safe_snprintf(str, maxlen, "%1.1f", getfilesizetotal(path) / 1024.0);
return str;
}
if (strcmp(sp, "FILEKB") == 0) { // Number of kibibytes in current file directory
, getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path) / 1024.0);
if (strncmp(sp, "FILEMB:", 7) == 0) { // Number of mebibytes in current file directory
const char* path = getpath(&cfg, sp + 7);
safe_snprintf(str, maxlen, "%1.1f", getfilesizetotal(path) / (1024.0 * 1024.0));
return str;
}
if (strcmp(sp, "FILEMB") == 0) { // Number of mebibytes in current file directory
, getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path) / (1024.0 * 1024.0));
if (strncmp(sp, "FILEGB:", 7) == 0) { // Number of gibibytes in current file directory
const char* path = getpath(&cfg, sp + 7);
safe_snprintf(str, maxlen, "%1.1f", getfilesizetotal(path) / (1024.0 * 1024.0 * 1024.0));
return str;
}
if (strcmp(sp, "FILEGB") == 0) { // Number of gibibytes in current file directory
, getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path) / (1024.0 * 1024.0 * 1024.0));
if (!strcmp(sp, "TCALLS") || !strcmp(sp, "NUMCALLS")) {
getstats(&cfg, 0, &stats);
safe_snprintf(str, maxlen, "%u", stats.logons);
if (!strcmp(sp, "PREVON") || !strcmp(sp, "LASTCALLERNODE")
|| !strcmp(sp, "LASTCALLERSYSTEM"))
if (!strcmp(sp, "CLS") || !strcmp(sp, "CLEAR")) {
if (strcmp(sp, "GETDIM") == 0) {

Rob Swindell
committed
getdimensions();

Rob Swindell
committed
return nulstr;
}
if (strcmp(sp, "GETKEY") == 0) {
if (strcmp(sp, "CONTINUE") == 0) {
if (ch == no_key() || ch == quit_key())
sys_status |= SS_ABORT;
if (strncmp(sp, "WAIT:", 5) == 0) {
if (!strcmp(sp, "PAUSE") || !strcmp(sp, "MORE")) {
if (!strcmp(sp, "RESETPAUSE")) {
lncntr = 0;
if (!strcmp(sp, "NOPAUSE") || !strcmp(sp, "POFF")) {
sys_status ^= SS_PAUSEOFF;
if (!strcmp(sp, "PON") || !strcmp(sp, "AUTOMORE")) {
sys_status ^= SS_PAUSEON;
if (strncmp(sp, "FILL:", 5) == 0) {

Rob Swindell
committed
SAFECOPY(tmp, sp + 5);
int margin = centered ? column : 1;
if (margin < 1)
margin = 1;

Rob Swindell
committed
c_unescape_str(tmp);
while (*tmp && online && column < cols - margin)

Rob Swindell
committed
bputs(tmp, P_TRUNCATE);
if (strncmp(sp, "POS:", 4) == 0) { // PCBoard (nn is 1 based)
if (i >= 1) // Convert to 0-based
for (l = i - column; l > 0; l--)
outchar(' ');
return nulstr;
}
if (strncmp(sp, "DELAY:", 6) == 0) { // PCBoard
mswait(atoi(sp + 6) * 100);
return nulstr;
}
if (strcmp(sp, "YESCHAR") == 0) { // PCBoard
safe_snprintf(str, maxlen, "%c", yes_key());
if (strcmp(sp, "NOCHAR") == 0) { // PCBoard
safe_snprintf(str, maxlen, "%c", no_key());
if (strcmp(sp, "QUITCHAR") == 0) {
safe_snprintf(str, maxlen, "%c", quit_key());