// --------------------------------------------------------------------------
// Citadel: DoSysop.CPP
//
// The root of the F6/.S menu.

#include "ctdl.h"
#pragma hdrstop

#include "config.h"
#include "infofile.h"
#include "filecmd.h"
#include "room.h"
#include "pathdat.h"
#include "log.h"
#include "auxtab.h"
#include "logedit.h"
#include "viewlog.h"
#include "msg.h"
#include "account.h"
#include "hall.h"
#include "group.h"
#include "roompriv.h"
#include "menus.h"
#include "cfgfiles.h"
#include "tallybuf.h"
#include "aplic.h"
#include "miscovl.h"


// --------------------------------------------------------------------------
// Contents
//
// doSysop()		Privileged Fn: menu breakdown
// do_SysopGroup()	handles doSysop() Group functions
// do_SysopHall()	handles the doSysop hall functions
// globalverify()	does global sweep to verify any un-verified

void net69_menu(void);

static void doSysFPDown(void);
static void ShowTables(void);
static void do_SysopEnter(void);
static void do_SysopHall();
static void do_SysopGroup();
#ifdef AUXMEM
static void ShowAuxmemUsage(auxTabList *List, const char *Name, int PageSlots);
#endif


// --------------------------------------------------------------------------
// doSysop() Privileged Fn: menu breakdown.

void doSysop(void)
	{
	label scrFile;
	Bool saveSysop;

	if (!read_sys_messages())
		{
		cPrintf(getmsg(59));
		return;
		}

	TI()MRO.Reverse = FALSE;

	saveSysop = TI()CurrentUser->IsSysop();
	TI()CurrentUser->SetSysop(TRUE);

	StatusLine.Update();

	while (!TI()ExitToMsdos)
		{
		amZap();

		SetDoWhat(SYSOPMENU);

		const int c = DoMenuPrompt(getsysmsg(1), NULL);

		SetDoWhat(DUNO);

		switch (toupper(c))
			{
			case '1':
				{
				SetDoWhat(SYSMAINT);

				char prompt[128];

				mPrintfCR(getsysmsg(2), HallData->GetEntry(1)->GetName(),
						cfg.Lhall_nym);

				sprintf(prompt, getsysmsg(196),
						HallData->GetEntry(1)->GetName(), cfg.Lhall_nym);

				if (getYesNo(prompt, 0))
					{
					for (int i = 0; i < cfg.maxrooms; i++)
						{
						if (i != DUMP && IsRoomInuse(i) &&
								!HallData->GetEntry(1)->IsRoomInHall(i))
							{
							mPrintfCR(pcts, GetRoomName(i));
							HallData->GetEntry(1)->SetRoomInHall(i, TRUE);
							}
						}

					HallData->Save();
					}

				break;
				}

			case '6':
				{
				mPrintf(getsysmsg(25));
				net69_menu();
				break;
				}

			case ESC:
			case 'A':
				{
				mPrintfCR(getmsg(653));
				}

			case 0:
				{
				// restore old mode
				TI()CurrentUser->SetSysop(saveSysop);
				StatusLine.Update();
				dump_sys_messages();
				return;
				}

			case 'C':
				{
				mPrintf(getsysmsg(3));
				cron_commands();
				break;
				}

			case 'D':
				{
				mPrintfCR(getsysmsg(5));
				changeDate();
				break;
				}

			case 'E':
				{
				mPrintf(getsysmsg(6));
				do_SysopEnter();
				break;
				}

			case 'F':
				{
				doAide(1, 'E');
				break;
				}

			case 'G':
				{
				mPrintf(getsysmsg(7), cfg.Ugroup_nym);
				do_SysopGroup();
				break;
				}

			case 'H':
				{
				mPrintf(getsysmsg(7), cfg.Uhall_nym);
				do_SysopHall();
				break;
				}

			case 'I':
				{
				SetDoWhat(SYSINFO);

				mPrintfCR(getsysmsg(9));
				ReIndexFileInfo();
				break;
				}

			case 'J':
				{
				mPrintf(getsysmsg(10));

				if (onConsole)
					{
					roomJournal();
					}
				else
					{
					CRCRmPrintfCR(getsysmsg(44));
					}
				break;
				}

			case 'K':
				{
				mPrintfCR(getsysmsg(11));
				killuser(NULL);
				break;
				}

			case 'L':
				{
				mPrintfCR(getsysmsg(12));
				sysopNew = TRUE;
				break;
				}

			case 'M':
				{
				mPrintfCR(getsysmsg(13));
				massdelete();
				break;
				}

			case 'N':
				{
				mPrintfCR(getsysmsg(14));
				globalverify();
				break;
				}

			case 'O':
				{
				SetDoWhat(SYSOFFHK);

				mPrintfCR(getsysmsg(4));

				if (onConsole)
					{
					offhook();
					}
				else
					{
					CRmPrintf(getsysmsg(44));
					}

				break;
				}

			case 'P':
				{
				mPrintfCR(getsysmsg(15));
				purgeuserlog();
				break;
				}

			case 'R':
				{
				SetDoWhat(SYSSCR);

				mPrintfCR(getsysmsg(16));
				getNormStr(getsysmsg(17), scrFile, LABELSIZE, ECHO);

				if (scrFile[0])
					{
					runScript(scrFile);
					}
				break;
				}

			case 'S':
				{
				mPrintfCR(getsysmsg(18));
				TI()CurrentUser->SetSysop(saveSysop);
				storeLog(); 	// in case we look at ourselves
				TI()CurrentUser->SetSysop(TRUE);
				showuser();
				break;
				}

			case 'U':
				{
				mPrintfCR(getsysmsg(19));
				TI()CurrentUser->SetSysop(saveSysop);
				userEdit();
				saveSysop = TI()CurrentUser->IsSysop();
				break;
				}

			case 'X':
				{
				SetDoWhat(SYSEXIT);

				mPrintfCR(getsysmsg(21));

				if (onConsole)
					{
					if (getYesNo(getmsg(57), 0))
						{
						// restore old mode
						TI()CurrentUser->SetSysop(saveSysop);
						TI()ExitToMsdos = TRUE;
						}
					}
				else
					{
					CRmPrintf(getsysmsg(44));
					}
				break;
				}

			case 'Z':
				{
				mPrintfCR(getsysmsg(22));
				killempties();
				break;
				}

			case '!':
				{
				SetDoWhat(SYSSHELL);

				mPrintfCR(getsysmsg(23));

				if (onConsole)
					{
					shellescape(FALSE);
					}
				else
					{
					CRmPrintf(getsysmsg(44));
					}
				break;
				}

			case '@':
				{
				SetDoWhat(SYSSHELL);

				mPrintfCR(getsysmsg(24));

				if (onConsole)
					{
					shellescape(TRUE);
					}
				else
					{
					CRmPrintf(getsysmsg(44));
					}
				break;
				}

#ifdef AUXMEM
			case '^':
				{
				SetDoWhat(SYSAUXDEB);

				TI()UserControl.SetOutFlag(OUTOK);

				mPrintfCR(getsysmsg(26));

				CRmPrintf(getsysmsg(27), usexms, xmshand, xmssize);
				CRmPrintf(getsysmsg(28), emsframe, emshand,
						emssize * (AUXPAGESIZE / 1024));
				CRmPrintf(getsysmsg(29), vrthand, vrtpags * (AUXPAGESIZE / 1024));

extern auxTabList *scrollBuf;
extern int LinesPerPage;

				ShowAuxmemUsage(mtList, getsysmsg(30), MSGTABPERPAGE);
				ShowAuxmemUsage(rtList, getsysmsg(36), ROOMTABPERPAGE);
				ShowAuxmemUsage(((talleyTaskInfo *) (TI()talleyInfo))->tbList,
						getsysmsg(47), TALLEYBUFPERPAGE);

				if (LinesPerPage)
					{
					ShowAuxmemUsage(scrollBuf, getsysmsg(183), LinesPerPage);
					}

extern auxTabList *freeBlock;
				ShowAuxmemUsage(freeBlock, getsysmsg(37), 1);

				if (xmserr)
					{
					int errcode = 0;

					switch (xmserr)
						{
						case 0x80: errcode = 91; break;
						case 0x81: errcode = 92; break;
						case 0x82: errcode = 93; break;
						case 0x8e: errcode = 94; break;
						case 0x8f: errcode = 95; break;
						case 0x90: errcode = 96; break;
						case 0x91: errcode = 97; break;
						case 0x92: errcode = 98; break;
						case 0x93: errcode = 99; break;
						case 0x94: errcode = 100; break;
						case 0xa0: errcode = 101; break;
						case 0xa1: errcode = 102; break;
						case 0xa2: errcode = 103; break;
						case 0xa3: errcode = 104; break;
						case 0xa4: errcode = 105; break;
						case 0xa5: errcode = 106; break;
						case 0xa6: errcode = 107; break;
						case 0xa7: errcode = 108; break;
						case 0xa8: errcode = 109; break;
						case 0xa9: errcode = 110; break;
						case 0xaa: errcode = 111; break;
						case 0xab: errcode = 112; break;
						case 0xac: errcode = 113; break;
						case 0xad: errcode = 114; break;
						case 0xb0: errcode = 115; break;
						case 0xb1: errcode = 116; break;
						case 0xb2: errcode = 269; break;
						}

					if (errcode)
						{
						CRmPrintf(getecmsg(167), getsysmsg(errcode), xmserr);
						}
					else
						{
						CRmPrintf(getsysmsg(222), xmserr);
						}
					}

				if (emserr)
					{
					if ((emserr >= 0x80) && (emserr <= 0xa4))
						{
						CRmPrintf(getsysmsg(267),
								getsysmsg(emserr - 0x80 + 117), emserr);
						}
					else
						{
						CRmPrintf(getsysmsg(270), emserr);
						}
					}

				doCR();
				break;
				}
#endif

			case '#':
				{
				SetDoWhat(SYSREADMSG);

				mPrintfCR(getsysmsg(39), cfg.Lmsg_nym);
				ClearMsgReadOptions(&TI()MRO);
				readbymsgno();
				break;
				}

			case '%':
				{
				SetDoWhat(SYSFPDOWN);

				mPrintf(getsysmsg(43));
				doSysFPDown();
				break;
				}

			case '>':
				{
				CreatePathDat();

				break;
				}

			case '+':
				{
				ShowTables();
				break;
				}

			// Get rid of this later
//			case '}':
//				{
//				for (i = 0; i < 200; i++)
//					{
//					char string[10];
//					itoa(i, string, 10);
//					autoroom(string);
//					}
//
//				break;
//				}

			case '?':
				{
				SetDoWhat(SYSMENU);

				oChar('?');
				showMenu(M_SYSOP);
				break;
				}

			default:
				{
				BadMenuSelection(c);
				break;
				}
			}
		}

	// restore old mode
	TI()CurrentUser->SetSysop(saveSysop);
	dump_sys_messages();
	}


// --------------------------------------------------------------------------
// do_SysopGroup(): Handles doSysop() Group functions.

static void do_SysopGroup()
	{
	char ich;

	SetDoWhat(SYSGRP);

	switch (toupper(ich = (char) iCharNE()))
		{
		case 'E':
		case 'R':
			{
			mPrintf(getmsg(197));
			renamegroup();
			break;
			}

		case 'G':
			{
			mPrintf(getsysmsg(46), cfg.Ugroup_nym);
			globalgroup(NULL, FALSE);
			break;
			}

		case 'K':
			{
			mPrintf(getmsg(339));
			killgroup(NULL);
			break;
			}

		case 'L':
			{
			mPrintf(getmsg(332), cfg.Lgroup_nym);
			listgroup();
			break;
			}

		case 'N':
			{
			mPrintf(getsysmsg(48));
			newgroup(NULL, NULL, FALSE, FALSE, FALSE);
			break;
			}

		case 'O':
			{
			mPrintf(getsysmsg(212));
			OperatorSpecificMembership();
			break;
			}

		case 'U':
			{
			mPrintfCR(getsysmsg(49));
			globaluser();
			break;
			}

		case '?':
			{
			oChar('?');
			showMenu(M_SYSGROUP);
			break;
			}

		case ESC:
			{
			break;
			}

		default:
			{
			BadMenuSelection(ich);
			break;
			}
		}
	}


// --------------------------------------------------------------------------
// do_SysopHall(): Handles the doSysop hall functions.

static void do_SysopHall()
	{
	char ich;

	SetDoWhat(SYSHALL);

	switch (toupper(ich = (char) iCharNE()))
		{
		case 'E':
		case 'R':
			{
			mPrintf(getmsg(197));
			renamehall();
			break;
			}

		case 'F':
			{
			mPrintf(getsysmsg(50));
			force();
			break;
			}

		case 'G':
			{
			mPrintf(getsysmsg(55));
			globalhall();
			break;
			}

		case 'K':
			{
			mPrintf(getmsg(339));
			killhall(NULL);
			break;
			}

		case 'L':
			{
			mPrintf(getmsg(332), cfg.Lhalls_nym);
			ListHalls(FALSE);
			break;
			}

		case 'N':
			{
			mPrintf(getsysmsg(48));
			newhall(NULL, NULL, TI()thisRoom);
			break;
			}

		case '+':
			{
			moveHall(1, TI()thisHall, TRUE);
			break;
			}

		case '-':
			{
			moveHall(-1, TI()thisHall, TRUE);
			break;
			}

		case '?':
			{
			oChar('?');
			showMenu(M_SYSHALL);
			break;
			}

		case ESC:
			{
			break;
			}

		default:
			{
			BadMenuSelection(ich);
			break;
			}
		}
	}


// --------------------------------------------------------------------------
// do_SysopEnter(): Handle .SE functions.

static void do_SysopEnter(void)
	{
	SetDoWhat(SYSENTER);

	if (read_cfg_messages())
		{
		Bool all = FALSE;
		const Bool oldAcct = cfg.accounting;

		const int ich = iCharNE();

		switch (toupper(ich))
			{
			case 'A':
				mPrintfCR(getsysmsg(63));
				all = TRUE;

			case 'C':
				{
				mPrintfCR(citfiles[C_CONFIG_CIT]);
				changedir(cfg.homepath);		// just in case

				readconfig(2);

				if (!oldAcct && cfg.accounting)
					{
					ReadGrpdataCit();

					TI()CurrentUserAccount = new UserAccountInfo;
					if (!TI()CurrentUserAccount)
						{
						crashout(getsysmsg(357));
						}

					TI()CurrentUserAccount->Negotiate(TI()CurrentUser);
					if (TI()CurrentUser->IsAccounting())
						{
						TI()CurrentUserAccount->GiveDailyIncrement();
						}
					}

				if (oldAcct && !cfg.accounting)
					{
					delete [] AccountingData;
					AccountingData = NULL;
					delete TI()CurrentUserAccount;
					TI()CurrentUserAccount = NULL;
					}

				if (!all)
					{
					break;
					}
				}

			case 'E':
				{
				mPrintfCR(citfiles[C_EXTERNAL_CIT]);
				ReadExternalCit();

				if (!all)
					{
					break;
					}
				}

			case 'G':
				{
				if (!(all && !cfg.accounting))
					{
					mPrintfCR(citfiles[C_GRPDATA_CIT]);

					if (cfg.accounting)
						{
						ReadGrpdataCit();
						}
					else
						{
						mPrintfCR(getsysmsg(64));
						}
					}

				if (!all)
					{
					break;
					}
				}

			case 'I':
				{
				mPrintfCR(citfiles[C_MCI_CIT]);
				ReadMCICit(TRUE);

				if (!all)
					{
					break;
					}
				}

			case 'M':
				{
				mPrintfCR(citfiles[C_MDMRESLT_CIT]);
				ReadMdmresltCit();

				if (!all)
					{
					break;
					}
				}

			case 'P':
				{
				mPrintfCR(citfiles[C_PROTOCOL_CIT]);
				ReadProtocolCit();

				if (!all)
					{
					break;
					}
				}

			case 'T':
				{
				mPrintfCR(citfiles[C_CRON_CIT]);
				Cron.ReadCronCit();
				break;
				}

			case '?':
				{
				oChar('?');
				showMenu(M_SYSENTER);
				break;
				}

			case ESC:
				{
				break;
				}

			default:
				{
				BadMenuSelection(ich);
				break;
				}
			}

		dump_cfg_messages();
		}
	else
		{
		mPrintf(getmsg(188), getsysmsg(272));
		}
	}


static void doSysFPDown(void)
	{
	char filePath[256], tmp[256], *filename;

	int ch = iCharNE();

	if (ch == '\n' || ch == '\r')
		{
		ch = TI()CurrentUser->GetDefaultProtocol();
		}

	const protocols *theProt = GetProtocolByKey(ch);

	if (theProt)
		{
		mPrintfCR(pcts, theProt->name);

		getString(getsysmsg(65), filePath, 63, FALSE, ECHO, ns);
		normalizeString(filePath);
		if (strchr(filePath, ' '))
			{
			mPrintfCR(getsysmsg(66));
			}
		else
			{
			if (filePath[0])
				{
				if (!strchr(filePath, '\\'))
					{
					CopyStringToBuffer(tmp, filePath, sizeof(tmp) - 1);
					sprintf(filePath, sbs, cfg.homepath, tmp);
					}

				CopyStringToBuffer(tmp, filePath, sizeof(tmp) - 1);
				*strrchr(tmp, '\\') = 0;
				if (!onConsole && inExternal(getmsg(1462), tmp))
					{
					securityViolation(tmp);
					return;
					}

				if (ambig(filePath) && !theProt->batch)
					{
					mPrintfCR(getsysmsg(67));
					}
				else
					{
					filename = strrchr(filePath, '\\') + 1;
					doTheDownload(filename, tmp, TRUE, theProt, FALSE);
					}
				}
			}
		}
	else
		{
		if (ch == '?')
			{
			oChar('?');
			upDownMnu('D', FALSE);
			}
		else
			{
			oChar(ch);
			mPrintf(sqst);
			if (!TI()CurrentUser->IsExpert())
				{
				upDownMnu('D', FALSE);
				}
			}
		}
	}

static void ShowTables(void)
	{
	SetDoWhat(SYSTAB);

	int ich;

	mPrintf(getsysmsg(273));

	switch (toupper(ich = iCharNE()))
		{
		case 'M':
			{
			label Newest;
			strcpy(Newest, ltoac(cfg.newest));

			mPrintfCR(getsysmsg(274));
			CRmPrintfCR(getsysmsg(164), ltoac(cfg.mtoldest), Newest);

			for (;;)
				{
				long msgno;
				char prompt[80];

				sprintf(prompt, getsysmsg(165), cfg.Lmsg_nym);
				msgno = getNumber(prompt, 0l, LONG_MAX, -1l, FALSE, NULL);

				if (!msgno || msgno == -1)
					{
					break;
					}

				if (((ulong) msgno < cfg.mtoldest) ||
						((ulong)msgno > cfg.newest))
					{
					CRmPrintfCR(getsysmsg(166));
					}
				else
					{
					m_slot slot = indexslot(msgno);

					if (slot != M_SLOT_ERROR)
						{
						CRmPrintfCR(getsysmsg(275), getFlags(slot)->IsMail() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(276), getFlags(slot)->IsReceived() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(277), getFlags(slot)->IsReply() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(278), getFlags(slot)->IsProblem() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(279), getFlags(slot)->IsMadevis() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(280), getFlags(slot)->IsLimited() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(281), getFlags(slot)->IsModerated() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(283), getFlags(slot)->IsCopy() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(284), getFlags(slot)->IsNet() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(285), getFlags(slot)->IsForwarded() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(286), getFlags(slot)->IsNetworked() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(287), getFlags(slot)->IsMassemail() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(288), getFlags(slot)->IsCensored() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(289), getFlags(slot)->IsLocal() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(290), getFlags(slot)->IsInuse() ?
								getmsg(896) : getmsg(895));

						mPrintfCR(getsysmsg(291), ltoac(getRoomNum(slot)));

						mPrintfCR(getsysmsg(292), ltoac(getLocation(slot)));

						mPrintfCR(getsysmsg(295), ltoac(getOriginID(slot)));

						if (getFlags(slot)->IsCopy())
							{
							mPrintfCR(getsysmsg(296), ltoac(getCopy(slot)));
							}
						else
							{
							mPrintfCR(getsysmsg(293), ltoac(getToHash(slot)));

							mPrintfCR(getsysmsg(294), ltoac(getAuthHash(slot)));
							}

						#if defined(WINCIT) || defined(AUXMEM)
							mPrintfCR(getsysmsg(323), ltoac(getPrevRoomMsg(slot)));
							mPrintfCR(getsysmsg(324), ltoac(getNextRoomMsg(slot)));
						#endif
						}
					else
						{
						mPrintfCR(getsysmsg(58));
						}
					}
				}

			break;
			}

		case 'R':
			{
			mPrintfCR(getsysmsg(297));

			for (;;)
				{
				r_slot RoomNumber;

				RoomNumber = (r_slot) getNumber(getsysmsg(298), 0l,
						cfg.maxrooms - 1, -1l, FALSE, NULL);

				if (RoomNumber < 0)
					{
					break;
					}

				CRmPrintfCR(getsysmsg(299), IsRoomInuse(RoomNumber) ?
						getmsg(896) : getmsg(895));

				if (IsRoomInuse(RoomNumber))
					{
					mPrintfCR(getsysmsg(300), IsRoomPermanent(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(301), IsRoomGroupOnly(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(302), IsRoomMultiGroup(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(303), IsRoomPrivGroup(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(304), IsRoomReadOnly(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(305), IsRoomModerated(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(306), IsRoomDownloadOnly(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(307), IsRoomUploadOnly(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(308), IsRoomShared(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(309), IsRoomDirectory(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(310), IsRoomHidden(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(311), IsRoomBIO(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(312), IsRoomSubject(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(313), IsRoomAnonymous(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(314), IsRoomArchive(RoomNumber) ?
							getmsg(896) : getmsg(895));

					mPrintfCR(getsysmsg(315), IsRoomApplication(RoomNumber) ?
							getmsg(896) : getmsg(895));

					if (IsRoomPrivGroup(RoomNumber))
						{
						mPrintfCR(getsysmsg(316),
								IsRoomGroupModerated(RoomNumber) ?
								getmsg(896) : getmsg(895));
						}

					mPrintfCR(getsysmsg(317), GetRoomName(RoomNumber));

					mPrintfCR(getsysmsg(318), GetRoomNetID(RoomNumber));

					if (IsRoomGroupOnly(RoomNumber))
						{
						if (IsRoomMultiGroup(RoomNumber))
							{
							mPrintf(getsysmsg(319), ns);
							ShowBooleanExpression(GetRoomGroupExpression(RoomNumber),
									ShowGroup);
							}
						else
							{
							mPrintf(getsysmsg(319),
									GroupData->GetEntry(GetRoomGroupNumber(
									RoomNumber))->GetName());
							}

						doCR();
						}

					if (IsRoomPrivGroup(RoomNumber))
						{
						mPrintfCR(getsysmsg(320),
									GroupData->GetEntry(GetRoomPrivNumber(
									RoomNumber))->GetName());
						}
					}
				}

			break;
			}

		case '?':
			{
			oChar('?');
			showMenu(M_SYSTABLE);
			break;
			}

		case ESC:
			{
			break;
			}

		default:
			{
			BadMenuSelection(ich);
			break;
			}
		}
	}

#ifdef AUXMEM
static void ShowAuxmemUsage(auxTabList *List, const char *Name, int PageSlots)
	{
	for (int j = 1; List; List = List->next, j++)
		{
		CRmPrintf(Name, j);
		if (List->whatMem == atHEAP) mPrintf(getsysmsg(31));
		if (List->whatMem == atXMS) mPrintf(getsysmsg(32));
		if (List->whatMem == atEMS) mPrintf(getsysmsg(33));
		if (List->whatMem == atVIRT) mPrintf(getsysmsg(34));
		mPrintf(getsysmsg(35), MkPtr(List->Where), List->first,
				List->first + PageSlots - 1);
		}
	}
#endif
