linbpq/MailCommands.c

697 lines
15 KiB
C
Raw Permalink Normal View History

2022-08-28 09:35:46 +01:00
/*
Copyright 2001-2018 John Wiseman G8BPQ
This file is part of LinBPQ/BPQ32.
LinBPQ/BPQ32 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 3 of the License, or
(at your option) any later version.
LinBPQ/BPQ32 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with LinBPQ/BPQ32. If not, see http://www.gnu.org/licenses
*/
#include "bpqmail.h"
int APIENTRY ChangeSessionIdletime(int Stream, int idletime);
struct MsgInfo * GetMsgFromNumber(int msgno);
BOOL ForwardMessagetoFile(struct MsgInfo * Msg, FILE * Handle);
struct UserInfo * FindBBS(char * Name);
int ListMessagestoForward(CIRCUIT * conn, struct UserInfo * user);
static char seps[] = " \t\r";
VOID DoAuthCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int AuthInt = 0;
if (!(user->flags & F_SYSOP))
{
nodeprintf(conn, "AUTH can only be used by SYSOPs\r");
SendPrompt(conn, user);
return;
}
if (Arg1)
AuthInt = atoi(Arg1);
else
{
nodeprintf(conn, "AUTH Code missing\r");
SendPrompt(conn, user);
return;
}
if (user->Temp->LastAuthCode == AuthInt)
{
nodeprintf(conn, "AUTH Code already used\r");
SendPrompt(conn, user);
return;
}
if (Arg1 && CheckOneTimePassword(Arg1, user->pass))
{
conn->sysop = TRUE;
nodeprintf(conn, "Ok\r");
user->Temp->LastAuthCode = atoi(Arg1);
}
else
nodeprintf(conn, "AUTH Failed\r");
SendPrompt(conn, user);
return;
}
VOID DoEditUserCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
char Line[200] = "User Flags:";
struct UserInfo * EUser = user;
if (conn->sysop == 0)
{
nodeprintf(conn, "Edit User needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1 == 0 || _stricmp(Arg1, "HELP") == 0)
{
nodeprintf(conn, "EDITUSER CALLSIGN to Display\r");
nodeprintf(conn, "EDITUSER CALLSIGN FLAG1 FLAG2 ... to set, -FLAG1 -FLAG2 ... to clear\r");
nodeprintf(conn, "EDITUSER: Flags are: EXC(luded) EXP(ert) SYSOP BBS PMS EMAIL HOLD RMS(Express User) APRS(Mail For)\r");
SendPrompt(conn, user);
return;
}
EUser = LookupCall(Arg1);
if (EUser == 0)
{
nodeprintf(conn, "User %s not found\r", Arg1);
SendPrompt(conn, user);
return;
}
Arg1 = strtok_s(NULL, seps, &Context);
if (Arg1 == NULL)
goto UDisplay;
// A set of flags to change +Flag or -Flag
while(Arg1 && strlen(Arg1) > 2)
{
_strupr(Arg1);
if (strstr(Arg1, "EXC"))
if (Arg1[0] != '-') EUser->flags |= F_Excluded; else EUser->flags &= ~F_Excluded;
if (strstr(Arg1, "EXP"))
if (Arg1[0] != '-') EUser->flags |= F_Expert; else EUser->flags &= ~F_Expert;
if (strstr(Arg1, "SYS"))
if (Arg1[0] != '-') EUser->flags |= F_SYSOP; else EUser->flags &= ~F_SYSOP;
if (strstr(Arg1, "BBS"))
if (Arg1[0] != '-') EUser->flags |= F_BBS; else EUser->flags &= ~F_BBS;
if (strstr(Arg1, "PMS"))
if (Arg1[0] != '-') EUser->flags |= F_PMS; else EUser->flags &= ~F_PMS;
if (strstr(Arg1, "EMAIL"))
if (Arg1[0] != '-') EUser->flags |= F_EMAIL; else EUser->flags &= ~F_EMAIL;
if (strstr(Arg1, "HOLD"))
if (Arg1[0] != '-') EUser->flags |= F_HOLDMAIL; else EUser->flags &= ~F_HOLDMAIL;
if (strstr(Arg1, "RMS"))
if (Arg1[0] != '-') EUser->flags |= F_Temp_B2_BBS; else EUser->flags &= ~F_Temp_B2_BBS;
if (strstr(Arg1, "APRS"))
if (Arg1[0] != '-') EUser->flags |= F_APRSMFOR; else EUser->flags &= ~F_APRSMFOR;
Arg1 = strtok_s(NULL, seps, &Context);
}
SaveUserDatabase();
// Drop through to display
UDisplay:
if (EUser->flags & F_Excluded)
strcat(Line, " EXC");
if (EUser->flags & F_Expert)
strcat(Line, " EXP");
if (EUser->flags & F_SYSOP)
strcat(Line, " SYSOP");
if (EUser->flags & F_BBS)
strcat(Line, " BBS");
if (EUser->flags & F_PMS)
strcat(Line, " PMS");
if (EUser->flags & F_EMAIL)
strcat(Line, " EMAIL");
if (EUser->flags & F_HOLDMAIL)
strcat(Line, " HOLD");
if (EUser->flags & F_Temp_B2_BBS)
strcat(Line, " RMS");
if (EUser->flags & F_APRSMFOR)
strcat(Line, " APRS");
strcat(Line, "\r");
nodeprintf(conn, Line);
SendPrompt(conn, user);
return;
}
VOID DoShowRMSCmd(CIRCUIT * conn, struct UserInfo * inuser, char * Arg1, char * Context)
{
int i, s;
char FWLine[10000] = "";
struct UserInfo * user;
char RMSCall[20];
if (conn->sysop == 0)
{
nodeprintf(conn, "Command needs SYSOP status\r");
SendPrompt(conn, inuser);
return;
}
for (i = 0; i <= NumberofUsers; i++)
{
user = UserRecPtr[i];
if (user->flags & F_POLLRMS)
{
if (user->RMSSSIDBits == 0) user->RMSSSIDBits = 1;
for (s = 0; s < 16; s++)
{
if (user->RMSSSIDBits & (1 << s))
{
strcat(FWLine, " ");
if (s)
{
sprintf(RMSCall, "%s-%d", user->Call, s);
strcat(FWLine, RMSCall);
}
else
strcat(FWLine, user->Call);
}
}
}
}
strcat(FWLine, "\r");
nodeprintf(conn, FWLine);
}
VOID DoPollRMSCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
char RMSLine[200];
char RMSCall[10];
struct UserInfo * RMSUser = user;
int s;
Loop:
if (Arg1)
{
// Update
if (_stricmp(Arg1, "Enable") == 0)
{
RMSUser->flags |= F_POLLRMS;
Arg1 = strtok_s(NULL, seps, &Context);
goto Display;
}
else if (_stricmp(Arg1, "Disable") == 0)
{
RMSUser->flags &= ~F_POLLRMS;
Arg1 = strtok_s(NULL, seps, &Context);
goto Display;
}
else if (strlen(Arg1) > 2)
{
// Callsign - if SYSOP, following commands apply to selected user
if (conn->sysop == 0)
{
nodeprintf(conn, "Changing RMS Poll params for another user needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
RMSUser = LookupCall(Arg1);
if (RMSUser == NULL)
{
nodeprintf(conn, "User %s not found\r", Arg1);
SendPrompt(conn, user);
return;
}
Arg1 = strtok_s(NULL, seps, &Context);
if (Arg1 == NULL)
goto Display;
if (_stricmp(Arg1, "Enable") == 0 || _stricmp(Arg1, "Disable") == 0 || (strlen(Arg1) < 3))
goto Loop;
goto Display;
}
// A list of SSID's to poll
RMSUser->RMSSSIDBits = 0;
while(Arg1 && strlen(Arg1) < 3)
{
s = atoi(Arg1);
if (s < 16)
RMSUser->RMSSSIDBits |= (1 << (s));
Arg1 = strtok_s(NULL, seps, &Context);
}
}
// Drop through to display
Display:
strcpy(RMSLine, "Polling for calls");
if (RMSUser->flags & F_POLLRMS)
{
if (RMSUser->RMSSSIDBits == 0) RMSUser->RMSSSIDBits = 1;
{
for (s = 0; s < 16; s++)
{
if (RMSUser->RMSSSIDBits & (1 << s))
{
strcat(RMSLine, " ");
if (s)
{
sprintf(RMSCall, "%s-%d", RMSUser->Call, s);
strcat(RMSLine, RMSCall);
}
else
strcat(RMSLine, RMSUser->Call);
}
}
}
strcat(RMSLine, "\r");
nodeprintf(conn, RMSLine);
}
else
nodeprintf(conn, "RMS Polling for %s disabled\r", RMSUser->Call);
if (Arg1)
goto Loop;
SaveUserDatabase();
SendPrompt(conn, user);
}
VOID DoSetIdleTime(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int IdleTime;
if (Arg1)
IdleTime = atoi(Arg1);
else
{
nodeprintf(conn, "Format is IDLETIME nnn\r");
SendPrompt(conn, user);
return;
}
if (IdleTime < 60 || IdleTime > 900)
{
nodeprintf(conn, "Time out of range (60 to 900 seconds)\r");
SendPrompt(conn, user);
return;
}
if (conn->BPQStream >= 0)
ChangeSessionIdletime(conn->BPQStream, IdleTime);
else
{
nodeprintf(conn, "Can't set Idle Time on Console)\r");
SendPrompt(conn, user);
return;
}
nodeprintf(conn, "Idle Tine set to %d\r", IdleTime);
SendPrompt(conn, user);
return;
}
VOID DoSetMsgNo(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int newNumber;
if (conn->sysop == 0)
{
nodeprintf(conn, "Command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1)
newNumber = atoi(Arg1);
else
{
nodeprintf(conn, "New Number not specified\r");
SendPrompt(conn, user);
return;
}
if (newNumber < LatestMsg)
{
nodeprintf(conn, "New Number less tham current (%d)\r", LatestMsg);
SendPrompt(conn, user);
return;
}
if (newNumber > (MaxMsgno - 1000))
{
nodeprintf(conn, "New Number too close to Max Message Number\r");
SendPrompt(conn, user);
return;
}
nodeprintf(conn, "Next message number was %d, now %d\r", LatestMsg, newNumber);
SendPrompt(conn, user);
LatestMsg = newNumber;
SaveMessageDatabase();
}
VOID DoExportCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int msgno;
char * FN;
FILE * Handle = NULL;
struct MsgInfo * Msg;
if (conn->sysop == 0)
{
nodeprintf(conn, "EXPORT command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1 == 0 || _stricmp(Arg1, "HELP") == 0)
{
nodeprintf(conn, "EXPORT nnn FILENAME - Export Message nnn to file FILENAME\r");
SendPrompt(conn, user);
return;
}
msgno = atoi(Arg1);
FN = strtok_s(NULL, " \r", &Context);
if (FN == NULL)
{
nodeprintf(conn, "Missong Filename");
SendPrompt(conn, user);
return;
}
Msg = GetMsgFromNumber(msgno);
if (Msg == NULL)
{
nodeprintf(conn, "Message %d not found\r", msgno);
SendPrompt(conn, user);
return;
}
conn->BBSFlags |= BBS;
Handle = fopen(FN, "ab");
if (Handle == NULL)
{
nodeprintf(conn, "File %s could not be opened\r", FN);
SendPrompt(conn, user);
return;
}
// SetFilePointer(Handle, 0, 0, FILE_END);
ForwardMessagetoFile(Msg, Handle);
fclose(Handle);
nodeprintf(conn, "%Message %d Exported\r", msgno);
SendPrompt(conn, user);
return;
}
VOID DoImportCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
int count;
if (conn->sysop == 0)
{
nodeprintf(conn, "IMPORT command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1 == 0 || _stricmp(Arg1, "HELP") == 0)
{
nodeprintf(conn, "IMPORT FILENAME - Import Messages from file FILENAME\r");
SendPrompt(conn, user);
return;
}
conn->BBSFlags |= BBS;
count = ImportMessages(conn, Arg1, TRUE);
conn->BBSFlags &= ~BBS;
conn->Flags = 0;
nodeprintf(conn, "%d Messages Processed\r", count);
SendPrompt(conn, user);
return;
}
VOID DoFwdCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
char Line[200];
struct UserInfo * FwdBBS;
struct BBSForwardingInfo * ForwardingInfo;
if (conn->sysop == 0)
{
nodeprintf(conn, "FWD command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
if (Arg1 == 0 || _stricmp(Arg1, "HELP") == 0)
{
nodeprintf(conn, "FWD BBSCALL - Display settings\r");
nodeprintf(conn, "FWD BBSCALL interval - Set forwarding interval\r");
nodeprintf(conn, "FWD BBSCALL REV interval - Set reverse forwarding interval\r");
nodeprintf(conn, "FWD BBSCALL +- Flags (Flags are EN(able) RE(verse Poll) SE(Send Immediately)\r");
nodeprintf(conn, "FWD BBSCALL NOW - Start a forwarding cycle now\r");
nodeprintf(conn, "FWD QUEUE - List BBS's with queued messages\r");
nodeprintf(conn, "FWD NOW can specify a Connect Script to use, overriding the configured script.\r");
nodeprintf(conn, "Elements are separated by | chars. eg FWD RMS NOW ATT 7|C GM8BPQ-10\r");
SendPrompt(conn, user);
return;
}
if (_stricmp(Arg1, "QUEUE") == 0)
{
struct UserInfo * xuser;
int Msgs;
if (Context && Context[0])
{
// a bbs name - list all messages queued to it
strlop(Context, '\r');
xuser = FindBBS(_strupr(Context));
if (xuser)
{
ListMessagestoForward(conn, xuser);
SendPrompt(conn, user);
return;
}
}
for (xuser = BBSChain; xuser; xuser = xuser->BBSNext)
{
Msgs = CountMessagestoForward(xuser);
if (Msgs)
nodeprintf(conn, "%s %d Msgs\r", xuser->Call, Msgs);
}
SendPrompt(conn, user);
return;
}
FwdBBS = LookupCall(Arg1);
if (FwdBBS == 0 || (FwdBBS->flags & F_BBS) == 0)
{
nodeprintf(conn, "BBS %s not found\r", Arg1);
SendPrompt(conn, user);
return;
}
ForwardingInfo = FwdBBS->ForwardingInfo;
Arg1 = strtok_s(NULL, seps, &Context);
if (Arg1 == NULL)
goto FDisplay;
if (_stricmp(Arg1, "NOW") == 0)
{
char ** Value = NULL;
if (ForwardingInfo->Forwarding)
{
BBSputs(conn, "Already Connected\r");
SendPrompt(conn, user);
return;
}
while (Context[0] == ' ')
Context++;
if (Context)
strlop(Context, 13);
if (Context && Context[0])
{
// Temp Connect Script to use
char * ptr1;
char * MultiString = NULL;
const char * ptr;
int Count = 0;
Value = zalloc(sizeof(void *)); // always NULL entry on end even if no values
Value[0] = NULL;
ptr = Context;
while (ptr && strlen(ptr))
{
ptr1 = strchr(ptr, '|');
if (ptr1)
*(ptr1++) = 0;
Value = realloc(Value, (Count+2) * sizeof(void *));
Value[Count++] = _strdup(ptr);
ptr = ptr1;
}
Value[Count] = NULL;
}
StartForwarding(FwdBBS->BBSNumber, Value);
if (ForwardingInfo->Forwarding)
nodeprintf(conn, "Forwarding Started\r");
else
nodeprintf(conn, "Start Forwarding failed\r");
SendPrompt(conn, user);
return;
}
if (_stricmp(Arg1, "REV") == 0)
{
Arg1 = strtok_s(NULL, seps, &Context);
ForwardingInfo->RevFwdInterval = atoi(Arg1);
}
else
{
while(Arg1)
{
_strupr(Arg1);
if (isdigits(Arg1))
ForwardingInfo->FwdInterval = atoi(Arg1);
else if (strstr(Arg1, "EN"))
if (Arg1[0] == '-') ForwardingInfo->Enabled = FALSE; else ForwardingInfo->Enabled = TRUE;
else if (strstr(Arg1, "RE"))
if (Arg1[0] == '-') ForwardingInfo->ReverseFlag = FALSE; else ForwardingInfo->ReverseFlag = TRUE;
else if (strstr(Arg1, "SE"))
if (Arg1[0] == '-') ForwardingInfo->SendNew = FALSE; else ForwardingInfo->SendNew = TRUE;
Arg1 = strtok_s(NULL, seps, &Context);
}
}
SaveConfig(ConfigName);
GetConfig(ConfigName);
FDisplay:
sprintf(Line, "%s Fwd Interval %d Rev Interval %d Fwd %s, Reverse Poll %s, Send Immediately %s\r",
FwdBBS->Call, ForwardingInfo->FwdInterval, ForwardingInfo->RevFwdInterval,
(ForwardingInfo->Enabled)? "Enabled" : "Disabled", (ForwardingInfo->ReverseFlag) ? "Enabled": "Disabled",
(ForwardingInfo->SendNew) ? "Enabled": "Disabled");
nodeprintf(conn, Line);
SendPrompt(conn, user);
return;
}
void DoHousekeepingCmd(CIRCUIT * conn, struct UserInfo * user, char * Arg1, char * Context)
{
if (conn->sysop == 0)
{
nodeprintf(conn, "DOHOUSEKEEPING command needs SYSOP status\r");
SendPrompt(conn, user);
return;
}
DoHouseKeeping(FALSE);
nodeprintf(conn, "Ok\r", Arg1);
SendPrompt(conn, user);
}