/* 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" #if defined(_WINSOCKAPI_) extern WSADATA WSAData; #define SOCKLIB_DESC WSAData.szDescription #else #define SOCKLIB_DESC NULL #endif struct atcode_format { int disp_len; 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) thousep = true; if(strchr(p, 'U') != NULL) uppercase = true; if(strchr(p, 'L') != NULL) align = left; else if(strchr(p, 'R') != NULL) align = right; else if(strchr(p, 'C') != NULL) align = center; else if(strchr(p, 'W') != NULL) doubled = true; else if(strchr(p, 'Z') != NULL) zero_padded = true; else if(strchr(p, '>') != NULL) truncated = false; } else if(strchr(sp, ':') != NULL) p = NULL; else if((p=strstr(sp,"-L"))!=NULL) align = left; else if((p=strstr(sp,"-R"))!=NULL) align = right; else if((p=strstr(sp,"-C"))!=NULL) align = center; 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 */ truncated = false; if(p!=NULL) { char* lp = p; lp++; // skip the '|' or '-' while(*lp == '>'|| IS_ALPHA(*lp)) lp++; if(*lp) width_specified = true; while(*lp && !IS_DIGIT(*lp)) lp++; if(*lp && IS_DIGIT(*lp)) { disp_len=atoi(lp); width_specified = true; } *p=0; } 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; if(*instr != '@') return 0; SAFECOPY(str,instr); tp=strchr(str+1,'@'); if(!tp) /* no terminating @ */ return(0); sp=strchr(str+1,' '); if(sp && sp<tp) /* space before terminating @ */ return(0); len=(tp-str)+1; (*tp)=0; sp=(str+1); if(*sp == '~' && *(sp + 1)) { // Mouse hot-spot (hungry) sp++; tp = strchr(sp + 1, '~'); if(tp == NULL) tp = sp; else { *tp = 0; tp++; } c_unescape_str(tp); add_hotspot(tp, /* hungry: */true, column, column + strlen(sp) - 1, row); bputs(sp); return len; } if(*sp == '`' && *(sp + 1)) { // Mouse hot-spot (strict) sp++; tp = strchr(sp + 1, '`'); if(tp == NULL) tp = sp; else { *tp = 0; tp++; } c_unescape_str(tp); add_hotspot(tp, /* hungry: */false, column, column + strlen(sp) - 1, row); bputs(sp); return len; } // @!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); if(cp==NULL) return(0); 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.uppercase && fmt.align == fmt.none) fmt.align = fmt.left; if(fmt.truncated && strchr(cp, '\n') == NULL) { if(column + fmt.disp_len > cols - 1) { if(column >= cols - 1) fmt.disp_len = 0; else 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) { int vlen = strlen(cp); if(vlen < fmt.disp_len) { int left = (fmt.disp_len - vlen) / 2; bprintf(pmode, "%*s%-*s", left, "", fmt.disp_len - left, cp); } else bprintf(pmode, "%.*s", fmt.disp_len, cp); } else if(fmt.doubled) { wide(cp); } 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); } else bprintf(pmode, "%.*s", fmt.disp_len, cp); return(len); } 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; } 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 hot_attr = curatr; return nulstr; } if(strncmp(sp, "HOT:", 4) == 0) { // Auto-mouse hot-spot attribute sp += 4; if(stricmp(sp, "hungry") == 0) { hungry_hotspots = true; hot_attr = curatr; } else if(stricmp(sp, "strict") == 0) { hungry_hotspots = false; hot_attr = curatr; } else if(stricmp(sp, "off") == 0) hot_attr = 0; else hot_attr = strtoattr(sp, /* endptr: */NULL); return nulstr; } if(strcmp(sp, "CLEAR_HOT") == 0) { clear_hotspots(); return nulstr; } 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 if(*tp == ':') outchar(codepoint, tp + 1); else { char fallback = (char)strtoul(tp + 1, NULL, 16); if(*tp == ',') outchar(codepoint, fallback); else if(*tp == '!') { char ch = unicode_to_cp437(codepoint); if(ch != 0) 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) { outchar(UNICODE_DEGREE_CELSIUS, "\xF8""C"); return nulstr; } if(strcmp(sp, "DEGREE_F") == 0) { outchar(UNICODE_DEGREE_FAHRENHEIT, "\xF8""F"); return nulstr; } if(strncmp(sp, "WIDE:", 5) == 0) { wide(sp + 5); return(nulstr); } if(!strcmp(sp,"VER")) return(VERSION); if(!strcmp(sp,"REV")) { safe_snprintf(str,maxlen,"%c",REVISION); return(str); } if(!strcmp(sp,"FULL_VER")) { safe_snprintf(str,maxlen,"%s%c%s",VERSION,REVISION,beta_version); truncsp(str); #if defined(_DEBUG) strcat(str," Debug"); #endif return(str); } if(!strcmp(sp,"VER_NOTICE")) return(VERSION_NOTICE); if(!strcmp(sp,"OS_VER")) return(os_version(str, maxlen)); if(strcmp(sp,"OS_CPU") == 0) return(os_cpuarch(str, maxlen)); #ifdef JAVASCRIPT if(!strcmp(sp,"JS_VER")) return((char *)JS_GetImplementationVersion()); #endif if(!strcmp(sp,"PLATFORM")) return(PLATFORM_DESC); if(!strcmp(sp,"COPYRIGHT")) return(COPYRIGHT_NOTICE); if(!strcmp(sp,"COMPILER")) { char compiler[32]; DESCRIBE_COMPILER(compiler); strncpy(str, compiler, maxlen); return(str); } if(strcmp(sp, "GIT_HASH") == 0) return git_hash; if(strcmp(sp, "GIT_BRANCH") == 0) return git_branch; if(strcmp(sp, "GIT_DATE") == 0) return git_date; if(strcmp(sp, "BUILD_DATE") == 0) return __DATE__; if(strcmp(sp, "BUILD_TIME") == 0) return __TIME__; if(!strcmp(sp,"UPTIME")) { extern volatile time_t uptime; time_t up=0; now = time(NULL); if (uptime != 0 && now >= uptime) up = now-uptime; char days[64]=""; if((up/(24*60*60))>=2) { sprintf(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) ); return(str); } if(!strcmp(sp,"SERVED")) { extern volatile uint served; safe_snprintf(str,maxlen,"%u",served); return(str); } if(!strcmp(sp,"SOCKET_LIB")) return(socklib_version(str,SOCKLIB_DESC)); if(!strcmp(sp,"MSG_LIB")) { safe_snprintf(str,maxlen,"SMBLIB %s",smb_lib_ver()); return(str); } if(!strcmp(sp,"BBS") || !strcmp(sp,"BOARDNAME")) return(cfg.sys_name); if(!strcmp(sp,"BAUD") || !strcmp(sp,"BPS")) { safe_snprintf(str,maxlen,"%u",cur_output_rate ? cur_output_rate : cur_rate); return(str); } if(!strcmp(sp,"CPS")) { safe_snprintf(str,maxlen,"%u",cur_cps); return(str); } if(!strcmp(sp,"COLS")) { safe_snprintf(str,maxlen,"%u",cols); return(str); } if(!strcmp(sp,"ROWS")) { safe_snprintf(str,maxlen,"%u",rows); return(str); } if(strcmp(sp,"TERM") == 0) return term_type(); if(strcmp(sp,"CHARSET") == 0) return term_charset(); if(!strcmp(sp,"CONN")) return(connection); if(!strcmp(sp,"SYSOP")) return(cfg.sys_op); 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); return(str); } if(strcmp(sp, "TNODES") == 0 || strcmp(sp, "TNODE") == 0 || strcmp(sp, "TN") == 0) { safe_snprintf(str,maxlen,"%u",cfg.sys_nodes); return(str); } 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) return term_type(&useron, term_supports(), str, maxlen); if(strcmp(sp, "TERMROWS") == 0) return term_rows(&useron, str, maxlen); if(strcmp(sp, "TERMCOLS") == 0) return term_cols(&useron, str, maxlen); if(strcmp(sp, "AUTOTERM") == 0) return (useron.misc & AUTOTERM) ? text[On] : text[Off]; if(strcmp(sp, "ANSI") == 0) return (useron.misc & ANSI) ? text[On] : text[Off]; if(strcmp(sp, "ASCII") == 0) return (useron.misc & NO_EXASCII) ? text[On] : text[Off]; if(strcmp(sp, "COLOR") == 0) return (useron.misc & COLOR) ? text[On] : text[Off]; if(strcmp(sp, "ICE") == 0) return (useron.misc & ICE_COLOR) ? text[On] : text[Off]; if(strcmp(sp, "RIP") == 0) return (useron.misc & RIP) ? text[On] : text[Off]; if(strcmp(sp, "PETSCII") == 0) 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) return (useron.misc & SWAP_DELETE) ? text[On] : text[Off]; if(strcmp(sp, "UTF8") == 0) return (useron.misc & UTF8) ? text[On] : text[Off]; if(strcmp(sp, "MOUSE") == 0) return (useron.misc & MOUSE) ? text[On] : text[Off]; if(strcmp(sp, "UPAUSE") == 0) return (useron.misc & UPAUSE) ? text[On] : text[Off]; if(strcmp(sp, "SPIN") == 0) return (useron.misc & SPIN) ? text[On] : text[Off]; if(strcmp(sp, "PAUSESPIN") == 0) return (useron.misc & NOPAUSESPIN) ? text[Off] : text[On]; if(strcmp(sp, "EXPERT") == 0) return (useron.misc & EXPERT) ? text[On] : text[Off]; if(strcmp(sp, "HOTKEYS") == 0) return (useron.misc & COLDKEYS) ? text[Off] : text[On]; if(strcmp(sp, "MSGCLS") == 0) 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) return (useron.misc & CURSUB) ? text[On] : text[Off]; if(strcmp(sp, "FILEDESC") == 0) return (useron.misc & EXTDESC) ? text[On] : text[Off]; if(strcmp(sp, "FILEFLAG") == 0) return (useron.misc & BATCHFLAG) ? text[On] : text[Off]; if(strcmp(sp, "AUTOHANG") == 0) return (useron.misc & AUTOHANG) ? text[On] : text[Off]; if(strcmp(sp, "AUTOLOGON") == 0) return (useron.misc & AUTOLOGON) ? text[On] : text[Off]; if(strcmp(sp, "QUIET") == 0) return (useron.misc & QUIET) ? text[On] : text[Off]; if(strcmp(sp, "ASKNSCAN") == 0) return (useron.misc & ASK_NSCAN) ? text[On] : text[Off]; if(strcmp(sp, "ASKSSCAN") == 0) return (useron.misc & ASK_SSCAN) ? text[On] : text[Off]; if(strcmp(sp, "ANFSCAN") == 0) return (useron.misc & ANFSCAN) ? text[On] : text[Off]; if(strcmp(sp, "EDITOR") == 0) return (useron.xedit < 1 || useron.xedit >= cfg.total_xedits) ? text[None] : cfg.xedit[useron.xedit - 1]->name; if(strcmp(sp, "SHELL") == 0) 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) return protname(useron.prot); if(strcmp(sp, "SEX") == 0) { safe_snprintf(str, maxlen, "%c", useron.sex); return str; } if(strcmp(sp, "GENDERS") == 0) { return cfg.new_genders; } if(!strcmp(sp,"QWKID")) return(cfg.sys_id); if(!strcmp(sp,"TIME") || !strcmp(sp,"SYSTIME")) { now=time(NULL); memset(&tm,0,sizeof(tm)); 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"); return(str); } if(!strcmp(sp,"TIMEZONE")) return(smb_zonestr(sys_timezone(&cfg),str)); if(!strcmp(sp,"DATE") || !strcmp(sp,"SYSDATE")) { return datestr(time(NULL)); } if(strncmp(sp, "DATE:", 5) == 0 || strncmp(sp, "TIME:", 5) == 0) { SAFECOPY(tmp, sp + 5); c_unescape_str(tmp); now = time(NULL); memset(&tm, 0, sizeof(tm)); localtime_r(&now, &tm); strftime(str, maxlen, tmp, &tm); return str; } if(!strcmp(sp,"DATETIME")) return(timestr(time(NULL))); if(!strcmp(sp,"DATETIMEZONE")) { char zone[32]; safe_snprintf(str, maxlen, "%s %s", timestr(time(NULL)), smb_zonestr(sys_timezone(&cfg),zone)); return str; } 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); return(str); } if(!strcmp(sp,"TUSER")) { safe_snprintf(str,maxlen,"%u",total_users(&cfg)); return(str); } if(!strcmp(sp,"TFILE")) { l=0; for(i=0;i<cfg.total_dirs;i++) l+=getfiles(&cfg,i); safe_snprintf(str,maxlen,"%lu",l); return(str); } 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)); return str; } if(strcmp(sp, "FILES") == 0) { // Number of files in current directory safe_snprintf(str, maxlen, "%u", getfiles(&cfg, usrdir[curlib][curdir[curlib]])); return str; } 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); return str; } if(strcmp(sp, "FILESIZE") == 0) { byte_estimate_to_str(getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path) ,str, maxlen, /* unit: */1, /* precision: */1); return str; } 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 safe_snprintf(str, maxlen, "%" PRIu64 ,getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path)); return str; } 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 safe_snprintf(str, maxlen, "%1.1f" ,getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path) / 1024.0); return str; } 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 safe_snprintf(str, maxlen, "%1.1f" ,getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path) / (1024.0 * 1024.0)); return str; } 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 safe_snprintf(str, maxlen, "%1.1f" ,getfilesizetotal(cfg.dir[usrdir[curlib][curdir[curlib]]]->path) / (1024.0 * 1024.0 * 1024.0)); return str; } if(!strcmp(sp,"TCALLS") || !strcmp(sp,"NUMCALLS")) { getstats(&cfg,0,&stats); safe_snprintf(str,maxlen,"%u", stats.logons); return(str); } if(!strcmp(sp,"PREVON") || !strcmp(sp,"LASTCALLERNODE") || !strcmp(sp,"LASTCALLERSYSTEM")) return(lastuseron); if(!strcmp(sp,"CLS") || !strcmp(sp,"CLEAR")) { CLS; return(nulstr); } if(strcmp(sp, "GETDIM") == 0) { getdimensions(); return nulstr; } if(strcmp(sp, "GETKEY") == 0) { getkey(); return(nulstr); } if(strcmp(sp, "CONTINUE") == 0) { char ch = getkey(K_UPPER); if(ch == no_key() || ch == quit_key()) sys_status|=SS_ABORT; return(nulstr); } if(strncmp(sp, "WAIT:", 5) == 0) { inkey(K_NONE, atoi(sp + 5) * 100); return(nulstr); } if(!strcmp(sp,"PAUSE") || !strcmp(sp,"MORE")) { pause(); return(nulstr); } if(!strcmp(sp,"RESETPAUSE")) { lncntr=0; return(nulstr); } if(!strcmp(sp,"NOPAUSE") || !strcmp(sp,"POFF")) { sys_status^=SS_PAUSEOFF; return(nulstr); } if(!strcmp(sp,"PON") || !strcmp(sp,"AUTOMORE")) { sys_status^=SS_PAUSEON; return(nulstr); } if(strncmp(sp, "FILL:", 5) == 0) { SAFECOPY(tmp, sp + 5); int margin = centered ? column : 1; if(margin < 1) margin = 1; c_unescape_str(tmp); while(*tmp && online && column < cols - margin) bputs(tmp, P_TRUNCATE); return nulstr; } if(strncmp(sp, "POS:", 4) == 0) { // PCBoard (nn is 1 based) i = atoi(sp + 4); if(i >= 1) // Convert to 0-based i--; 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()); return str; } if(strcmp(sp, "NOCHAR") == 0) { // PCBoard safe_snprintf(str, maxlen, "%c", no_key()); return str; } if(strcmp(sp, "QUITCHAR") == 0) { safe_snprintf(str, maxlen, "%c", quit_key()); return str; } if(strncmp(sp, "BPS:", 4) == 0) { set_output_rate((enum output_rate)atoi(sp + 4)); return nulstr; } if(strncmp(sp, "TEXT:", 5) == 0) { i = atoi(sp + 5); if(i >= 1 && i <= TOTAL_TEXT) return text[i - 1]; else return get_text(sp + 5); } /* NOSTOP */ /* STOP */ if(!strcmp(sp,"BELL") || !strcmp(sp,"BEEP")) return("\a"); if(!strcmp(sp,"EVENT")) { if(event_time==0) return("<none>"); return(timestr(event_time)); } /* LASTCALL */ if(strcmp(sp, "NODE_USER") == 0) return thisnode.misc&NODE_ANON ? text[UNKNOWN_USER] : useron.alias; if(!strncmp(sp,"NODE",4) && IS_DIGIT(sp[4])) { i=atoi(sp+4); if(i && i<=cfg.sys_nodes) { getnodedat(i, &node); printnodedat(i,&node); } return(nulstr); } if(!strcmp(sp,"WHO")) { whos_online(true); return(nulstr); } /* User Codes */ if(!strcmp(sp,"USER") || !strcmp(sp,"ALIAS") || !strcmp(sp,"NAME")) return(useron.alias); if(!strcmp(sp,"FIRST")) { safe_snprintf(str,maxlen,"%s",useron.alias); tp=strchr(str,' '); if(tp) *tp=0; return(str); } if(!strcmp(sp,"USERNUM")) { safe_snprintf(str,maxlen,"%u",useron.number); return(str); } if(!strcmp(sp,"PHONE") || !strcmp(sp,"HOMEPHONE") || !strcmp(sp,"DATAPHONE") || !strcmp(sp,"DATA")) return(useron.phone); if(!strcmp(sp,"ADDR1")) return(useron.address); if(!strcmp(sp,"FROM")) return(useron.location); if(!strcmp(sp,"CITY")) { safe_snprintf(str,maxlen,"%s",useron.location); char* p=strchr(str,','); if(p) { *p=0; return(str); } return(nulstr); } if(!strcmp(sp,"STATE")) { char* p=strchr(useron.location,','); if(p) { p++; if(*p==' ') p++; return(p); } return(nulstr); } if(!strcmp(sp,"CPU")) return(useron.comp); if(!strcmp(sp,"HOST")) return(client_name); if(!strcmp(sp,"BDATE")) return getbirthdstr(&cfg, useron.birth, str, maxlen); if(strcmp(sp, "BIRTH") == 0) return format_birthdate(&cfg, useron.birth, str, maxlen); if(strncmp(sp, "BDATE:", 6) == 0 || strncmp(sp, "BIRTH:", 6) == 0) { SAFECOPY(tmp, sp + 6); c_unescape_str(tmp); memset(&tm,0,sizeof(tm)); tm.tm_year = getbirthyear(useron.birth) - 1900; tm.tm_mon = getbirthmonth(&cfg, useron.birth) - 1; tm.tm_mday = getbirthday(&cfg, useron.birth); mktime(&tm); strftime(str, maxlen, tmp, &tm); return str; } if(!strcmp(sp,"AGE")) { safe_snprintf(str,maxlen,"%u",getage(&cfg,useron.birth)); return(str); } if(!strcmp(sp,"CALLS") || !strcmp(sp,"NUMTIMESON")) { safe_snprintf(str,maxlen,"%u",useron.logons); return(str); } if(strcmp(sp, "PWAGE") == 0) { time_t age = time(NULL) - useron.pwmod; safe_snprintf(str, maxlen, "%d", (uint)(age/(24*60*60))); return str; } if(strcmp(sp, "PWDATE") == 0 || strcmp(sp, "MEMO") == 0) return datestr(useron.pwmod); if(strncmp(sp, "PWDATE:", 7) == 0) { SAFECOPY(tmp, sp + 7); c_unescape_str(tmp); memset(&tm, 0, sizeof(tm)); time_t date = useron.pwmod; localtime_r(&date, &tm); strftime(str, maxlen, tmp, &tm); return str; } if(!strcmp(sp,"SEC") || !strcmp(sp,"SECURITY")) { safe_snprintf(str,maxlen,"%u",useron.level); return(str); } if(!strcmp(sp,"SINCE")) return datestr(useron.firston); if(strncmp(sp, "SINCE:", 6) == 0) { SAFECOPY(tmp, sp + 6); c_unescape_str(tmp); memset(&tm, 0, sizeof(tm)); time_t date = useron.firston; localtime_r(&date, &tm); strftime(str, maxlen, tmp, &tm); return str; } if(!strcmp(sp,"TIMEON") || !strcmp(sp,"TIMEUSED")) { now=time(NULL); safe_snprintf(str,maxlen,"%u",(uint)(now-logontime)/60); return(str); } if(!strcmp(sp,"TUSED")) { /* Synchronet only */ now=time(NULL); return(sectostr((uint)(now-logontime),str)+1); } if(!strcmp(sp,"TLEFT")) { /* Synchronet only */ gettimeleft(); return(sectostr(timeleft,str)+1); } if(!strcmp(sp,"TPERD")) /* Synchronet only */ return(sectostr(cfg.level_timeperday[useron.level],str)+4); if(!strcmp(sp,"TPERC")) /* Synchronet only */ return(sectostr(cfg.level_timepercall[useron.level],str)+4); if(strcmp(sp, "MPERC") == 0 || strcmp(sp, "TIMELIMIT") == 0) { safe_snprintf(str,maxlen,"%u",cfg.level_timepercall[useron.level]); return(str); } if(strcmp(sp, "MPERD") == 0) { safe_snprintf(str,maxlen,"%u",cfg.level_timeperday[useron.level]); return str; } if(strcmp(sp, "MAXCALLS") == 0) { safe_snprintf(str,maxlen,"%u",cfg.level_callsperday[useron.level]); return str; } if(strcmp(sp, "MAXPOSTS") == 0) { safe_snprintf(str,maxlen,"%u",cfg.level_postsperday[useron.level]); return str; } if(strcmp(sp, "MAXMAILS") == 0) { safe_snprintf(str,maxlen,"%u",cfg.level_emailperday[useron.level]); return str; } if(strcmp(sp, "MAXLINES") == 0) { safe_snprintf(str,maxlen,"%u",cfg.level_linespermsg[useron.level]); return str; } if(!strcmp(sp,"MINLEFT") || !strcmp(sp,"LEFT") || !strcmp(sp,"TIMELEFT")) { gettimeleft(); safe_snprintf(str,maxlen,"%u",timeleft/60); return(str); } if(!strcmp(sp,"LASTON")) return(timestr(useron.laston)); if(!strcmp(sp,"LASTDATEON")) return datestr(useron.laston); if(strncmp(sp, "LASTON:", 7) == 0) { SAFECOPY(tmp, sp + 7); c_unescape_str(tmp); memset(&tm, 0, sizeof(tm)); time_t date = useron.laston; localtime_r(&date, &tm); strftime(str, maxlen, tmp, &tm); return str; } if(!strcmp(sp,"LASTTIMEON")) { memset(&tm,0,sizeof(tm)); localtime32(&useron.laston,&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"); return(str); } if(!strcmp(sp,"FIRSTON")) return(timestr(useron.firston)); if(!strcmp(sp,"FIRSTDATEON")) return datestr(useron.firston); if(strncmp(sp, "FIRSTON:", 8) == 0) { SAFECOPY(tmp, sp + 8); c_unescape_str(tmp); memset(&tm, 0, sizeof(tm)); time_t date = useron.firston; localtime_r(&date, &tm); strftime(str, maxlen, tmp, &tm); return str; } if(!strcmp(sp,"FIRSTTIMEON")) { memset(&tm,0,sizeof(tm)); localtime32(&useron.firston,&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"); return(str); } if(strcmp(sp, "EMAILS") == 0) { safe_snprintf(str, maxlen, "%u", useron.emails); return str; } if(strcmp(sp, "FBACKS") == 0) { safe_snprintf(str, maxlen, "%u", useron.fbacks); return str; } if(strcmp(sp, "ETODAY") == 0) { safe_snprintf(str, maxlen, "%u", useron.etoday); return str; } if(strcmp(sp, "PTODAY") == 0) { safe_snprintf(str, maxlen, "%u", useron.ptoday); return str; } if(strcmp(sp, "LTODAY") == 0) { safe_snprintf(str, maxlen, "%u", useron.ltoday); return str; } if(strcmp(sp, "MTODAY") == 0) { safe_snprintf(str, maxlen, "%u", useron.ttoday); return str; } if(strcmp(sp, "MTOTAL") == 0) { safe_snprintf(str, maxlen, "%u", useron.timeon); return str; } if(strcmp(sp, "TTODAY") == 0) return sectostr(useron.ttoday, str) + 3; if(strcmp(sp, "TTOTAL") == 0) return sectostr(useron.timeon, str) + 3; if(strcmp(sp, "TLAST") == 0) { safe_snprintf(str, maxlen, "%u", useron.tlast); return str; } if(strcmp(sp, "MEXTRA") == 0) { safe_snprintf(str, maxlen, "%u", useron.textra); return str; } if(strcmp(sp, "TEXTRA") == 0) return sectostr(useron.textra, str) + 3; if(strcmp(sp, "MBANKED") == 0) { safe_snprintf(str, maxlen, "%" PRIu32, useron.min); return str; } if(strcmp(sp, "TBANKED") == 0) return sectostr(useron.min, str) + 3; if(!strcmp(sp,"MSGLEFT") || !strcmp(sp,"MSGSLEFT")) { safe_snprintf(str,maxlen,"%u",useron.posts); return(str); } if(!strcmp(sp,"MSGREAD")) { safe_snprintf(str,maxlen,"%u",posts_read); return(str); } if(!strcmp(sp,"FREESPACE")) { safe_snprintf(str,maxlen,"%" PRIu64,getfreediskspace(cfg.temp_dir,0)); return(str); } if(!strcmp(sp,"FREESPACEK")) { safe_snprintf(str,maxlen,"%" PRIu64,getfreediskspace(cfg.temp_dir,1024)); return(str); } if(strcmp(sp,"FREESPACEM") == 0) { safe_snprintf(str,maxlen,"%" PRIu64,getfreediskspace(cfg.temp_dir, 1024 * 1024)); return(str); } if(strcmp(sp,"FREESPACEG") == 0) { safe_snprintf(str,maxlen,"%" PRIu64,getfreediskspace(cfg.temp_dir, 1024 * 1024 * 1024)); return(str); } if(strcmp(sp,"FREESPACET") == 0) { safe_snprintf(str,maxlen,"%" PRIu64,getfreediskspace(cfg.temp_dir, 1024 * 1024 * 1024) / 1024); return(str); } if(!strcmp(sp,"UPBYTES")) { safe_snprintf(str,maxlen,"%" PRIu64,useron.ulb); return(str); } if(!strcmp(sp,"UPK")) { safe_snprintf(str,maxlen,"%" PRIu64,useron.ulb/1024L); return(str); } if(!strcmp(sp,"UPS") || !strcmp(sp,"UPFILES")) { safe_snprintf(str,maxlen,"%u",useron.uls); return(str); } if(!strcmp(sp,"DLBYTES")) { safe_snprintf(str,maxlen,"%" PRIu64,useron.dlb); return(str); } if(!strcmp(sp,"DOWNK")) { safe_snprintf(str,maxlen,"%" PRIu64,useron.dlb/1024L); return(str); } if(!strcmp(sp,"DOWNS") || !strcmp(sp,"DLFILES")) { safe_snprintf(str,maxlen,"%u",useron.dls); return(str); } if(strcmp(sp, "PCR") == 0) { float f = 0; if(useron.posts) f = (float)useron.logons / useron.posts; safe_snprintf(str, maxlen, "%u", f ? (uint)(100 / f) : 0); return str; } if(strcmp(sp, "UDR") == 0) { float f = 0; if(useron.ulb) f = (float)useron.dlb / useron.ulb; safe_snprintf(str, maxlen, "%u", f ? (uint)(100 / f) : 0); return str; } if(strcmp(sp, "UDFR") == 0) { float f = 0; if(useron.uls) f = (float)useron.dls / useron.uls; safe_snprintf(str, maxlen, "%u", f ? (uint)(100 / f) : 0); return str; } if(!strcmp(sp,"LASTNEW")) return datestr(ns_time); if(strncmp(sp, "LASTNEW:", 8) == 0) { SAFECOPY(tmp, sp + 8); c_unescape_str(tmp); memset(&tm, 0, sizeof(tm)); time_t date = ns_time; localtime_r(&date, &tm); strftime(str, maxlen, tmp, &tm); return str; } if(!strcmp(sp,"NEWFILETIME")) return(timestr(ns_time)); /* MAXDL */ if(!strcmp(sp,"MAXDK") || !strcmp(sp,"DLKLIMIT") || !strcmp(sp,"KBLIMIT")) { safe_snprintf(str,maxlen,"%" PRIu64,cfg.level_freecdtperday[useron.level]/1024L); return(str); } if(!strcmp(sp,"DAYBYTES")) { /* amt of free cdts used today */ safe_snprintf(str,maxlen,"%" PRIu64,cfg.level_freecdtperday[useron.level]-useron.freecdt); return(str); } if(!strcmp(sp,"BYTELIMIT")) { safe_snprintf(str,maxlen,"%" PRIu64, cfg.level_freecdtperday[useron.level]); return(str); } if(!strcmp(sp,"KBLEFT")) { safe_snprintf(str,maxlen,"%" PRIu64,user_available_credits(&useron)/1024UL); return(str); } if(!strcmp(sp,"BYTESLEFT")) { safe_snprintf(str,maxlen,"%" PRIu64,user_available_credits(&useron)); return(str); } if(strcmp(sp, "CREDITS") == 0) { safe_snprintf(str, maxlen, "%" PRIu64, useron.cdt); return str; } if(strcmp(sp, "FREECDT") == 0) { safe_snprintf(str, maxlen, "%" PRIu64, useron.freecdt); return str; } if(!strcmp(sp,"CONF")) { safe_snprintf(str,maxlen,"%s %s" ,usrgrps ? cfg.grp[usrgrp[curgrp]]->sname :nulstr ,usrgrps ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->sname : nulstr); return(str); } if(!strcmp(sp,"CONFNUM")) { safe_snprintf(str,maxlen,"%u %u",curgrp+1,cursub[curgrp]+1); return(str); } if(!strcmp(sp,"NUMDIR")) { safe_snprintf(str,maxlen,"%u %u",usrlibs ? curlib+1 : 0,usrlibs ? curdir[curlib]+1 : 0); return(str); } if(!strcmp(sp,"EXDATE") || !strcmp(sp,"EXPDATE")) return datestr(useron.expire); if(strncmp(sp, "EXPDATE:", 8) == 0) { if(!useron.expire) return nulstr; SAFECOPY(tmp, sp + 8); c_unescape_str(tmp); memset(&tm, 0, sizeof(tm)); time_t date = useron.expire; localtime_r(&date, &tm); strftime(str, maxlen, tmp, &tm); return str; } if(!strcmp(sp,"EXPDAYS")) { now=time(NULL); l=(uint)(useron.expire-now); if(l<0) l=0; safe_snprintf(str,maxlen,"%lu",l/(1440L*60L)); return(str); } if(strcmp(sp, "NOTE") == 0 || strcmp(sp, "MEMO1") == 0) return useron.note; if(strcmp(sp,"REALNAME") == 0 || !strcmp(sp,"MEMO2") || !strcmp(sp,"COMPANY")) return(useron.name); if(!strcmp(sp,"ZIP")) return(useron.zipcode); if(!strcmp(sp,"HANGUP")) { hangup(); return(nulstr); } /* Synchronet Specific */ if(!strncmp(sp,"SETSTR:",7)) { strcpy(main_csi.str,sp+7); return(nulstr); } if(strcmp(sp,"STR") == 0) { return main_csi.str; } if(strncmp(sp, "STRVAR:", 7) == 0) { uint32_t crc = crc32(sp + 7, 0); if(main_csi.str_var && main_csi.str_var_name) { for(i=0;i<main_csi.str_vars;i++) if(main_csi.str_var_name[i] == crc) return main_csi.str_var[i]; } return nulstr; } if(strncmp(sp, "JS:", 3) == 0) { jsval val; if(JS_GetProperty(js_cx, obj == NULL ? js_glob : obj, sp + 3, &val)) JSVALUE_TO_STRBUF(js_cx, val, str, maxlen, NULL); return str; } if(!strncmp(sp,"EXEC:",5)) { exec_bin(sp+5,&main_csi); return(nulstr); } if(!strncmp(sp,"EXEC_XTRN:",10)) { for(i=0;i<cfg.total_xtrns;i++) if(!stricmp(cfg.xtrn[i]->code,sp+10)) break; if(i<cfg.total_xtrns) exec_xtrn(i); return(nulstr); } if(!strncmp(sp,"MENU:",5)) { menu(sp+5); return(nulstr); } if(!strncmp(sp,"CONDMENU:",9)) { menu(sp+9, P_NOERROR); return(nulstr); } if(!strncmp(sp,"TYPE:",5)) { printfile(cmdstr(sp+5,nulstr,nulstr,str),0); return(nulstr); } if(!strncmp(sp,"INCLUDE:",8)) { printfile(cmdstr(sp+8,nulstr,nulstr,str),P_NOCRLF|P_SAVEATR); return(nulstr); } if(!strcmp(sp,"QUESTION")) return(question); if(!strcmp(sp,"HANDLE")) return(useron.handle); if(strcmp(sp, "LASTIP") == 0) return useron.ipaddr; if(!strcmp(sp,"CID") || !strcmp(sp,"IP")) return(cid); if(!strcmp(sp,"LOCAL-IP")) return(local_addr); if(!strcmp(sp,"CRLF")) return("\r\n"); if(!strcmp(sp,"PUSHXY")) { ansi_save(); return(nulstr); } if(!strcmp(sp,"POPXY")) { ansi_restore(); return(nulstr); } if(!strcmp(sp,"HOME")) { cursor_home(); return(nulstr); } if(!strcmp(sp,"CLRLINE")) { clearline(); return(nulstr); } if(!strcmp(sp,"CLR2EOL") || !strcmp(sp,"CLREOL")) { cleartoeol(); return(nulstr); } if(!strcmp(sp,"CLR2EOS")) { cleartoeos(); return(nulstr); } if(!strncmp(sp,"UP:",3)) { cursor_up(atoi(sp+3)); return(str); } if(!strncmp(sp,"DOWN:",5)) { cursor_down(atoi(sp+5)); return(str); } if(!strncmp(sp,"LEFT:",5)) { cursor_left(atoi(sp+5)); return(str); } if(!strncmp(sp,"RIGHT:",6)) { cursor_right(atoi(sp+6)); return(str); } if(!strncmp(sp,"GOTOXY:",7)) { const char* cp=strchr(sp,','); if(cp!=NULL) { cp++; cursor_xy(atoi(sp+7),atoi(cp)); } return(nulstr); } if(!strcmp(sp,"GRP")) { if(SMB_IS_OPEN(&smb)) { if(smb.subnum==INVALID_SUB) return("Local"); if(is_valid_subnum(smb.subnum)) return(cfg.grp[cfg.sub[smb.subnum]->grp]->sname); } return(usrgrps ? cfg.grp[usrgrp[curgrp]]->sname : nulstr); } if(!strcmp(sp,"GRPL")) { if(SMB_IS_OPEN(&smb)) { if(smb.subnum==INVALID_SUB) return("Local"); if(is_valid_subnum(smb.subnum)) return(cfg.grp[cfg.sub[smb.subnum]->grp]->lname); } return(usrgrps ? cfg.grp[usrgrp[curgrp]]->lname : nulstr); } if(!strcmp(sp,"GN")) { if(SMB_IS_OPEN(&smb)) ugrp=getusrgrp(smb.subnum); else ugrp=usrgrps ? curgrp+1 : 0; safe_snprintf(str,maxlen,"%u",ugrp); return(str); } if(!strcmp(sp,"GL")) { if(SMB_IS_OPEN(&smb)) ugrp=getusrgrp(smb.subnum); else ugrp=usrgrps ? curgrp+1 : 0; safe_snprintf(str,maxlen,"%-4u",ugrp); return(str); } if(!strcmp(sp,"GR")) { if(SMB_IS_OPEN(&smb)) ugrp=getusrgrp(smb.subnum); else ugrp=usrgrps ? curgrp+1 : 0; safe_snprintf(str,maxlen,"%4u",ugrp); return(str); } if(!strcmp(sp,"SUB")) { if(SMB_IS_OPEN(&smb)) { if(smb.subnum==INVALID_SUB) return("Mail"); else if(is_valid_subnum(smb.subnum)) return(cfg.sub[smb.subnum]->sname); } return(usrgrps ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->sname : nulstr); } if(!strcmp(sp,"SUBL")) { if(SMB_IS_OPEN(&smb)) { if(smb.subnum==INVALID_SUB) return("Mail"); else if(is_valid_subnum(smb.subnum)) return(cfg.sub[smb.subnum]->lname); } return(usrgrps ? cfg.sub[usrsub[curgrp][cursub[curgrp]]]->lname : nulstr); } if(!strcmp(sp,"SN")) { if(SMB_IS_OPEN(&smb)) usub=getusrsub(smb.subnum); else usub=usrgrps ? cursub[curgrp]+1 : 0; safe_snprintf(str,maxlen,"%u",usub); return(str); } if(!strcmp(sp,"SL")) { if(SMB_IS_OPEN(&smb)) usub=getusrsub(smb.subnum); else usub=usrgrps ? cursub[curgrp]+1 : 0; safe_snprintf(str,maxlen,"%-4u",usub); return(str); } if(!strcmp(sp,"SR")) { if(SMB_IS_OPEN(&smb)) usub=getusrsub(smb.subnum); else usub=usrgrps ? cursub[curgrp]+1 : 0; safe_snprintf(str,maxlen,"%4u",usub); return(str); } if(!strcmp(sp,"LIB")) return(usrlibs ? cfg.lib[usrlib[curlib]]->sname : nulstr); if(!strcmp(sp,"LIBL")) return(usrlibs ? cfg.lib[usrlib[curlib]]->lname : nulstr); if(!strcmp(sp,"LN")) { safe_snprintf(str,maxlen,"%u",usrlibs ? curlib+1 : 0); return(str); } if(!strcmp(sp,"LL")) { safe_snprintf(str,maxlen,"%-4u",usrlibs ? curlib+1 : 0); return(str); } if(!strcmp(sp,"LR")) { safe_snprintf(str,maxlen,"%4u",usrlibs ? curlib+1 : 0); return(str); } if(!strcmp(sp,"DIR")) return(usrlibs ? cfg.dir[usrdir[curlib][curdir[curlib]]]->sname :nulstr); if(!strcmp(sp,"DIRL")) return(usrlibs ? cfg.dir[usrdir[curlib][curdir[curlib]]]->lname : nulstr); if(!strcmp(sp,"DN")) { safe_snprintf(str,maxlen,"%u",usrlibs ? curdir[curlib]+1 : 0); return(str); } if(!strcmp(sp,"DL")) { safe_snprintf(str,maxlen,"%-4u",usrlibs ? curdir[curlib]+1 : 0); return(str); } if(!strcmp(sp,"DR")) { safe_snprintf(str,maxlen,"%4u",usrlibs ? curdir[curlib]+1 : 0); return(str); } if(!strcmp(sp,"NOACCESS")) { if(noaccess_str==text[NoAccessTime]) safe_snprintf(str,maxlen,noaccess_str,noaccess_val/60,noaccess_val%60); else if(noaccess_str==text[NoAccessDay]) safe_snprintf(str,maxlen,noaccess_str,wday[noaccess_val]); else safe_snprintf(str,maxlen,noaccess_str,noaccess_val); return(str); } if(!strcmp(sp,"LAST")) { tp=strrchr(useron.alias,' '); if(tp) tp++; else tp=useron.alias; return(tp); } if(!strcmp(sp,"REAL") || !strcmp(sp,"FIRSTREAL")) { safe_snprintf(str,maxlen,"%s",useron.name); tp=strchr(str,' '); if(tp) *tp=0; return(str); } if(!strcmp(sp,"LASTREAL")) { tp=strrchr(useron.name,' '); if(tp) tp++; else tp=useron.name; return(tp); } if(!strcmp(sp,"MAILR")) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number, /* Sent: */FALSE, /* attr: */MSG_READ)); return(str); } if(!strcmp(sp,"MAILU")) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number, /* Sent: */FALSE, /* attr: */~MSG_READ)); return(str); } if(!strcmp(sp,"MAILW")) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number, /* Sent: */FALSE, /* attr: */0)); return(str); } if(!strcmp(sp,"MAILP")) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number,/* Sent: */TRUE, /* attr: */0)); return(str); } if(!strcmp(sp,"SPAMW")) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,useron.number, /* Sent: */FALSE, /* attr: */MSG_SPAM)); return(str); } if(!strncmp(sp,"MAILR:",6) || !strncmp(sp,"MAILR#",6)) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6), /* Sent: */FALSE, /* attr: */MSG_READ)); return(str); } if(!strncmp(sp,"MAILU:",6) || !strncmp(sp,"MAILU#",6)) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6), /* Sent: */FALSE, /* attr: */~MSG_READ)); return(str); } if(!strncmp(sp,"MAILW:",6) || !strncmp(sp,"MAILW#",6)) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6), /* Sent: */FALSE, /* attr: */0)); return(str); } if(!strncmp(sp,"MAILP:",6) || !strncmp(sp,"MAILP#",6)) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6), /* Sent: */TRUE, /* attr: */0)); return(str); } if(!strncmp(sp,"SPAMW:",6) || !strncmp(sp,"SPAMW#",6)) { safe_snprintf(str,maxlen,"%u",getmail(&cfg,atoi(sp+6), /* Sent: */FALSE, /* attr: */MSG_SPAM)); return(str); } if(!strcmp(sp,"MSGREPLY")) { safe_snprintf(str,maxlen,"%c",cfg.sys_misc&SM_RA_EMU ? 'R' : 'A'); return(str); } if(!strcmp(sp,"MSGREREAD")) { safe_snprintf(str,maxlen,"%c",cfg.sys_misc&SM_RA_EMU ? 'A' : 'R'); return(str); } if(!strncmp(sp,"STATS.",6)) { getstats(&cfg,0,&stats); sp+=6; if(!strcmp(sp,"LOGONS")) safe_snprintf(str,maxlen,"%u", stats.logons); else if(!strcmp(sp,"LTODAY")) safe_snprintf(str,maxlen,"%u", stats.ltoday); else if(!strcmp(sp,"TIMEON")) safe_snprintf(str,maxlen,"%u", stats.timeon); else if(!strcmp(sp,"TTODAY")) safe_snprintf(str,maxlen,"%u", stats.ttoday); else if(!strcmp(sp,"ULS")) safe_snprintf(str,maxlen,"%u", stats.uls); else if(!strcmp(sp,"ULB")) safe_snprintf(str,maxlen,"%" PRIu64, stats.ulb); else if(!strcmp(sp,"DLS")) safe_snprintf(str,maxlen,"%u", stats.dls); else if(!strcmp(sp,"DLB")) safe_snprintf(str,maxlen,"%" PRIu64, stats.dlb); else if(!strcmp(sp,"PTODAY")) safe_snprintf(str,maxlen,"%u", stats.ptoday); else if(!strcmp(sp,"ETODAY")) safe_snprintf(str,maxlen,"%u", stats.etoday); else if(!strcmp(sp,"FTODAY")) safe_snprintf(str,maxlen,"%u", stats.ftoday); else if(!strcmp(sp,"NUSERS")) safe_snprintf(str,maxlen,"%u",stats.nusers); return(str); } /* Message header codes */ if(!strcmp(sp,"MSG_TO") && current_msg != nullptr) { if(pmode != NULL) *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); if(current_msg->to_ext!=NULL) safe_snprintf(str, maxlen, "%s #%s", current_msg_to == nullptr ? current_msg->to : current_msg_to, current_msg->to_ext); else if(current_msg->to_net.addr != NULL) { char tmp[128]; safe_snprintf(str,maxlen,"%s (%s)", current_msg_to == nullptr ? current_msg->to : current_msg_to ,smb_netaddrstr(¤t_msg->to_net,tmp)); } else return current_msg_to == nullptr ? current_msg->to : current_msg_to; return(str); } if(!strcmp(sp,"MSG_TO_NAME") && current_msg != nullptr) { if(pmode != NULL) *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); return current_msg_to == nullptr ? current_msg->to : current_msg_to; } if(!strcmp(sp,"MSG_TO_FIRST") && current_msg != nullptr) { if(pmode != NULL) *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); safe_snprintf(str, maxlen, "%s", current_msg_to == nullptr ? current_msg->to : current_msg_to); if((tp = strchr(str, ' ')) != NULL) *tp = '\0'; return str; } if(!strcmp(sp,"MSG_TO_EXT") && current_msg!=NULL) { if(current_msg->to_ext==NULL) return(nulstr); return(current_msg->to_ext); } if(!strcmp(sp,"MSG_TO_NET") && current_msg!=NULL) { if(current_msg->to_net.addr == NULL) return nulstr; return(smb_netaddrstr(¤t_msg->to_net,str)); } if(!strcmp(sp,"MSG_TO_NETTYPE") && current_msg!=NULL) { if(current_msg->to_net.type==NET_NONE) return nulstr; return(smb_nettype((enum smb_net_type)current_msg->to_net.type)); } if(!strcmp(sp,"MSG_CC") && current_msg!=NULL) return(current_msg->cc_list == NULL ? nulstr : current_msg->cc_list); if(!strcmp(sp,"MSG_FROM") && current_msg != nullptr) { if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) return(text[Anonymous]); if(pmode != NULL) *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); if(current_msg->from_ext!=NULL) safe_snprintf(str,maxlen,"%s #%s", current_msg_from == nullptr ? current_msg->from : current_msg_from, current_msg->from_ext); else if(current_msg->from_net.addr != NULL) { safe_snprintf(str,maxlen,"%s (%s)", current_msg_from == nullptr ? current_msg->from : current_msg_from ,smb_netaddrstr(¤t_msg->from_net,tmp)); } else return current_msg_from == nullptr ? current_msg->from : current_msg_from; return(str); } if(!strcmp(sp,"MSG_FROM_NAME") && current_msg != nullptr) { if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) return(text[Anonymous]); if(pmode != NULL) *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); return current_msg_from == nullptr ? current_msg->from : current_msg_from; } if(!strcmp(sp,"MSG_FROM_FIRST") && current_msg != nullptr) { if(current_msg->hdr.attr&MSG_ANONYMOUS && !SYSOP) safe_snprintf(str, maxlen, "%s", text[Anonymous]); else safe_snprintf(str, maxlen, "%s", current_msg_from == nullptr ? current_msg->from : current_msg_from); if((tp = strchr(str, ' ')) != NULL) *tp = '\0'; return str; } if(!strcmp(sp,"MSG_FROM_EXT") && current_msg!=NULL) { if(!(current_msg->hdr.attr&MSG_ANONYMOUS) || SYSOP) if(current_msg->from_ext!=NULL) return(current_msg->from_ext); return(nulstr); } if(!strcmp(sp,"MSG_FROM_NET") && current_msg!=NULL) { if(current_msg->from_net.addr!=NULL && (!(current_msg->hdr.attr&MSG_ANONYMOUS) || SYSOP)) return(smb_netaddrstr(¤t_msg->from_net,str)); return(nulstr); } if(!strcmp(sp,"MSG_FROM_NETTYPE") && current_msg!=NULL) { if(current_msg->from_net.type==NET_NONE) return nulstr; return(smb_nettype((enum smb_net_type)current_msg->from_net.type)); } if(!strcmp(sp,"MSG_SUBJECT") && current_msg != nullptr) { if(pmode != NULL) *pmode |= (current_msg->hdr.auxattr & MSG_HFIELDS_UTF8); return current_msg_subj == nullptr ? current_msg->subj : current_msg_subj; } if(!strcmp(sp,"MSG_SUMMARY") && current_msg!=NULL) return(current_msg->summary==NULL ? nulstr : current_msg->summary); if(!strcmp(sp,"MSG_TAGS") && current_msg!=NULL) return(current_msg->tags==NULL ? nulstr : current_msg->tags); if(!strcmp(sp,"MSG_DATE") && current_msg!=NULL) return(timestr(current_msg->hdr.when_written.time)); if(!strcmp(sp,"MSG_IMP_DATE") && current_msg!=NULL) return(timestr(current_msg->hdr.when_imported.time)); if(!strcmp(sp,"MSG_AGE") && current_msg!=NULL) return age_of_posted_item(str, maxlen , current_msg->hdr.when_written.time - (smb_tzutc(current_msg->hdr.when_written.zone) * 60)); if(!strcmp(sp,"MSG_TIMEZONE") && current_msg!=NULL) return(smb_zonestr(current_msg->hdr.when_written.zone,NULL)); if(!strcmp(sp,"MSG_IMP_TIMEZONE") && current_msg!=NULL) return(smb_zonestr(current_msg->hdr.when_imported.zone,NULL)); if(!strcmp(sp,"MSG_ATTR") && current_msg!=NULL) { uint16_t attr = current_msg->hdr.attr; uint16_t poll = attr&MSG_POLL_VOTE_MASK; uint32_t auxattr = current_msg->hdr.auxattr; /* Synchronized with show_msgattr(): */ safe_snprintf(str,maxlen,"%s%s%s%s%s%s%s%s%s%s%s%s%s%s" ,attr&MSG_PRIVATE ? "Private " :nulstr ,attr&MSG_SPAM ? "SPAM " :nulstr ,attr&MSG_READ ? "Read " :nulstr ,attr&MSG_DELETE ? "Deleted " :nulstr ,attr&MSG_KILLREAD ? "Kill " :nulstr ,attr&MSG_ANONYMOUS ? "Anonymous " :nulstr ,attr&MSG_LOCKED ? "Locked " :nulstr ,attr&MSG_PERMANENT ? "Permanent " :nulstr ,attr&MSG_MODERATED ? "Moderated " :nulstr ,attr&MSG_VALIDATED ? "Validated " :nulstr ,attr&MSG_REPLIED ? "Replied " :nulstr ,attr&MSG_NOREPLY ? "NoReply " :nulstr ,poll == MSG_POLL ? "Poll " :nulstr ,poll == MSG_POLL && auxattr&POLL_CLOSED ? "(Closed) " :nulstr ); return(str); } if(!strcmp(sp,"MSG_AUXATTR") && current_msg!=NULL) { safe_snprintf(str,maxlen,"%s%s%s%s%s%s%s" ,current_msg->hdr.auxattr&MSG_FILEREQUEST ? "FileRequest " :nulstr ,current_msg->hdr.auxattr&MSG_FILEATTACH ? "FileAttach " :nulstr ,current_msg->hdr.auxattr&MSG_MIMEATTACH ? "MimeAttach " :nulstr ,current_msg->hdr.auxattr&MSG_KILLFILE ? "KillFile " :nulstr ,current_msg->hdr.auxattr&MSG_RECEIPTREQ ? "ReceiptReq " :nulstr ,current_msg->hdr.auxattr&MSG_CONFIRMREQ ? "ConfirmReq " :nulstr ,current_msg->hdr.auxattr&MSG_NODISP ? "DontDisplay " :nulstr ); return(str); } if(!strcmp(sp,"MSG_NETATTR") && current_msg!=NULL) { safe_snprintf(str,maxlen,"%s%s%s%s%s%s%s%s" ,current_msg->hdr.netattr&NETMSG_LOCAL ? "Local " :nulstr ,current_msg->hdr.netattr&NETMSG_INTRANSIT ? "InTransit " :nulstr ,current_msg->hdr.netattr&NETMSG_SENT ? "Sent " :nulstr ,current_msg->hdr.netattr&NETMSG_KILLSENT ? "KillSent " :nulstr ,current_msg->hdr.netattr&NETMSG_HOLD ? "Hold " :nulstr ,current_msg->hdr.netattr&NETMSG_CRASH ? "Crash " :nulstr ,current_msg->hdr.netattr&NETMSG_IMMEDIATE ? "Immediate " :nulstr ,current_msg->hdr.netattr&NETMSG_DIRECT ? "Direct " :nulstr ); return(str); } if(!strcmp(sp,"MSG_ID") && current_msg!=NULL) return(current_msg->id==NULL ? nulstr : current_msg->id); if(!strcmp(sp,"MSG_REPLY_ID") && current_msg!=NULL) return(current_msg->reply_id==NULL ? nulstr : current_msg->reply_id); if(!strcmp(sp,"MSG_NUM") && current_msg!=NULL) { safe_snprintf(str,maxlen,"%lu", (ulong)current_msg->hdr.number); return(str); } if(!strcmp(sp,"MSG_SCORE") && current_msg!=NULL) { safe_snprintf(str, maxlen, "%ld", (long)current_msg->upvotes - (long)current_msg->downvotes); return(str); } if(!strcmp(sp,"MSG_UPVOTES") && current_msg!=NULL) { safe_snprintf(str, maxlen, "%lu", (ulong)current_msg->upvotes); return(str); } if(!strcmp(sp,"MSG_DOWNVOTES") && current_msg!=NULL) { safe_snprintf(str, maxlen, "%lu", (ulong)current_msg->downvotes); return(str); } if(!strcmp(sp,"MSG_TOTAL_VOTES") && current_msg!=NULL) { safe_snprintf(str, maxlen, "%lu", (ulong)current_msg->total_votes); return(str); } if(!strcmp(sp,"MSG_VOTED")) return (current_msg != NULL && current_msg->user_voted) ? text[PollAnswerChecked] : nulstr; if(!strcmp(sp,"MSG_UPVOTED")) return (current_msg != NULL && current_msg->user_voted == 1) ? text[PollAnswerChecked] : nulstr; if(!strcmp(sp,"MSG_DOWNVOTED")) return (current_msg != NULL && current_msg->user_voted == 2) ? text[PollAnswerChecked] : nulstr; if(strcmp(sp, "MSG_THREAD_ID") == 0 && current_msg != NULL) { safe_snprintf(str, maxlen, "%lu", (ulong)current_msg->hdr.thread_id); return str; } if(strcmp(sp, "MSG_THREAD_BACK") == 0 && current_msg != NULL) { safe_snprintf(str, maxlen, "%lu", (ulong)current_msg->hdr.thread_back); return str; } if(strcmp(sp, "MSG_THREAD_NEXT") == 0 && current_msg != NULL) { safe_snprintf(str, maxlen, "%lu", (ulong)current_msg->hdr.thread_next); return str; } if(strcmp(sp, "MSG_THREAD_FIRST") == 0 && current_msg != NULL) { safe_snprintf(str, maxlen, "%lu", (ulong)current_msg->hdr.thread_first); return str; } if(!strcmp(sp,"SMB_AREA")) { if(is_valid_subnum(smb.subnum)) safe_snprintf(str,maxlen,"%s %s" ,cfg.grp[cfg.sub[smb.subnum]->grp]->sname ,cfg.sub[smb.subnum]->sname); else strncpy(str, "Email", maxlen); return(str); } if(!strcmp(sp,"SMB_AREA_DESC")) { if(is_valid_subnum(smb.subnum)) safe_snprintf(str,maxlen,"%s %s" ,cfg.grp[cfg.sub[smb.subnum]->grp]->lname ,cfg.sub[smb.subnum]->lname); else strncpy(str, "Personal Email", maxlen); return(str); } if(!strcmp(sp,"SMB_GROUP")) { if(is_valid_subnum(smb.subnum)) return(cfg.grp[cfg.sub[smb.subnum]->grp]->sname); return(nulstr); } if(!strcmp(sp,"SMB_GROUP_DESC")) { if(is_valid_subnum(smb.subnum)) return(cfg.grp[cfg.sub[smb.subnum]->grp]->lname); return(nulstr); } if(!strcmp(sp,"SMB_GROUP_NUM")) { if(is_valid_subnum(smb.subnum)) safe_snprintf(str,maxlen,"%u",getusrgrp(smb.subnum)); return(str); } if(!strcmp(sp,"SMB_SUB")) { if(smb.subnum==INVALID_SUB) return("Mail"); else if(is_valid_subnum(smb.subnum)) return(cfg.sub[smb.subnum]->sname); return(nulstr); } if(!strcmp(sp,"SMB_SUB_DESC")) { if(smb.subnum==INVALID_SUB) return("Mail"); else if(is_valid_subnum(smb.subnum)) return(cfg.sub[smb.subnum]->lname); return(nulstr); } if(!strcmp(sp,"SMB_SUB_CODE")) { if(smb.subnum==INVALID_SUB) return("MAIL"); else if(is_valid_subnum(smb.subnum)) return(cfg.sub[smb.subnum]->code); return(nulstr); } if(!strcmp(sp,"SMB_SUB_NUM")) { if(is_valid_subnum(smb.subnum)) safe_snprintf(str,maxlen,"%u",getusrsub(smb.subnum)); return(str); } if(!strcmp(sp,"SMB_MSGS")) { safe_snprintf(str,maxlen,"%lu", (ulong)smb.msgs); return(str); } if(!strcmp(sp,"SMB_CURMSG")) { safe_snprintf(str,maxlen,"%lu", (ulong)(smb.curmsg+1)); return(str); } if(!strcmp(sp,"SMB_LAST_MSG")) { safe_snprintf(str,maxlen,"%lu", (ulong)smb.status.last_msg); return(str); } if(!strcmp(sp,"SMB_MAX_MSGS")) { safe_snprintf(str,maxlen,"%lu", (ulong)smb.status.max_msgs); return(str); } if(!strcmp(sp,"SMB_MAX_CRCS")) { safe_snprintf(str,maxlen,"%lu", (ulong)smb.status.max_crcs); return(str); } if(!strcmp(sp,"SMB_MAX_AGE")) { safe_snprintf(str,maxlen,"%hu",smb.status.max_age); return(str); } if(!strcmp(sp,"SMB_TOTAL_MSGS")) { safe_snprintf(str,maxlen,"%lu", (ulong)smb.status.total_msgs); return(str); } /* Currently viewed file */ if(current_file != NULL) { if(is_valid_dirnum(current_file->dir)) { if(strcmp(sp, "FILE_AREA") == 0) { safe_snprintf(str, maxlen, "%s %s" ,cfg.lib[cfg.dir[current_file->dir]->lib]->sname ,cfg.dir[current_file->dir]->sname); return str; } if(strcmp(sp, "FILE_AREA_DESC") == 0) { safe_snprintf(str, maxlen, "%s %s" ,cfg.lib[cfg.dir[current_file->dir]->lib]->lname ,cfg.dir[current_file->dir]->lname); return str; } if(strcmp(sp, "FILE_LIB") == 0) return cfg.lib[cfg.dir[current_file->dir]->lib]->sname; if(strcmp(sp, "FILE_LIB_DESC") == 0) return cfg.lib[cfg.dir[current_file->dir]->lib]->lname; if(strcmp(sp, "FILE_LIB_NUM") == 0) { safe_snprintf(str, maxlen, "%u", getusrlib(current_file->dir)); return str; } if(strcmp(sp, "FILE_DIR") == 0) return cfg.dir[current_file->dir]->sname; if(strcmp(sp, "FILE_DIR_DESC") == 0) return cfg.dir[current_file->dir]->lname; if(strcmp(sp, "FILE_DIR_CODE") == 0) return cfg.dir[current_file->dir]->code; if(strcmp(sp, "FILE_DIR_NUM") == 0) { safe_snprintf(str, maxlen, "%u", getusrdir(current_file->dir)); return str; } } if(strcmp(sp, "FILE_NAME") == 0) return current_file->name; if(strcmp(sp, "FILE_DESC") == 0) return current_file->desc; if(strcmp(sp, "FILE_TAGS") == 0) return current_file->tags; if(strcmp(sp, "FILE_UPLOADER") == 0) return current_file->from; if(strcmp(sp, "FILE_SIZE") == 0) { safe_snprintf(str, maxlen, "%ld", (long)current_file->size); return str; } if(strcmp(sp, "FILE_CREDITS") == 0) { safe_snprintf(str, maxlen, "%" PRIu64, current_file->cost); return str; } if(strcmp(sp, "FILE_TIME") == 0) return timestr(current_file->time); if(strcmp(sp, "FILE_TIME_ULED") == 0) return timestr(current_file->hdr.when_imported.time); if(strcmp(sp, "FILE_TIME_DLED") == 0) return timestr(current_file->hdr.last_downloaded); if(strcmp(sp, "FILE_DATE") == 0) return datestr(current_file->time); if(strcmp(sp, "FILE_DATE_ULED") == 0) return datestr(current_file->hdr.when_imported.time); if(strcmp(sp, "FILE_DATE_DLED") == 0) return datestr(current_file->hdr.last_downloaded); if(strcmp(sp, "FILE_TIMES_DLED") == 0) { safe_snprintf(str, maxlen, "%lu", (ulong)current_file->hdr.times_downloaded); return str; } } return get_text(sp); } char* sbbs_t::expand_atcodes(const char* src, char* buf, size_t size, const smbmsg_t* msg) { char* dst = buf; char* end = dst + (size - 1); const smbmsg_t* saved_msg{current_msg}; if (msg != NULL) current_msg = msg; while (*src != '\0' && dst < end) { if (*src == '@') { char str[32]; SAFECOPY(str, src + 1); char* at = strchr(str, '@'); const char* sp = strchr(str, ' '); if (at != NULL && (sp == NULL || sp > at)) { char tmp[128]; *at = '\0'; src += strlen(str) + 2; const char* p = formatted_atcode(str, tmp, sizeof tmp); if(p != NULL) dst += strlcpy(dst, p, end - dst); continue; } } *(dst++) = *(src++); } if(dst > end) dst = end; *dst = '\0'; current_msg = saved_msg; return buf; }