This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
deb-mbse/mbtask/taskcomm.c

733 lines
16 KiB
C
Raw Normal View History

2001-08-17 05:46:24 +00:00
/*****************************************************************************
*
* $Id$
2001-08-17 05:46:24 +00:00
* Purpose ...............: MBSE BBS Daemon
*
*****************************************************************************
* Copyright (C) 1997-2006
2001-08-17 05:46:24 +00:00
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS 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, or (at your option) any
* later version.
*
* MB BBS 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 MB BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************/
2002-06-30 13:20:57 +00:00
#include "../config.h"
2004-02-21 17:22:00 +00:00
#include "../lib/mbselib.h"
2001-08-17 05:46:24 +00:00
#include "taskstat.h"
#include "taskregs.h"
#include "taskdisk.h"
#include "taskinfo.h"
#include "taskutil.h"
2003-03-24 19:44:38 +00:00
#include "taskchat.h"
2001-08-17 05:46:24 +00:00
#include "taskcomm.h"
extern int oserr; /* Copy of Unix error */
extern int sock; /* Server socket */
extern struct sockaddr_un from; /* From socket address */
extern int fromlen; /* From address length */
extern int logtrans; /* Log transactions */
extern int T_Shutdown; /* Program shutdown */
2005-09-01 19:58:35 +00:00
extern int ibc_run; /* Chatserver running */
int cmd_run = FALSE;/* cmd running */
2001-08-17 05:46:24 +00:00
/************************************************************************
*
* Logging procedures.
*/
int userlog(char *);
int userlog(char *param)
{
char *prname, *prpid, *grade, *msg;
static char lfn[PATH_MAX], token[14];
int rc;
lfn[0] = '\0';
strcpy(token, strtok(param, ","));
strcpy(token, strtok(NULL, ","));
snprintf(lfn, PATH_MAX, "%s/log/%s", getenv("MBSE_ROOT"), token);
prname = strtok(NULL, ",");
prpid = strtok(NULL, ",");
grade = strtok(NULL, ",");
msg = xstrcpy(cldecode(strtok(NULL, ";")));
rc = ulog(lfn, grade, prname, prpid, msg);
free(msg);
return rc;
2001-08-17 05:46:24 +00:00
}
/*
* Process command received from the client.
*/
char *exe_cmd(char *);
char *exe_cmd(char *in)
{
static char obuf[SS_BUFSIZE];
static char ibuf[SS_BUFSIZE];
static char cmd[4];
static char token[SS_BUFSIZE];
static char ebuf[19];
static char *cnt, var1[16];
int result;
char *buf;
strcpy(ibuf, in);
strncpy(cmd, ibuf, 4);
token[0] = '\0';
strcpy(ebuf, "200:1,Syntax error;");
/*
* Split the commandline after the colon so we can give the
* options directly to the actual functions. Also set a default
* and most used answer.
*/
strcpy(token, &ibuf[5]);
strcpy(obuf, "100:0;");
/*
* The A(counting) commands.
*
* AINI:5,pid,tty,user,program,city;
* 100:1,linenr;
* 200:1,Syntax Error;
*/
if (strncmp(cmd, "AINI", 4) == 0) {
if ((result = reg_newcon(token)) != -1) {
2005-08-29 21:03:28 +00:00
snprintf(obuf, SS_BUFSIZE, "100:1,%d;", result);
return obuf;
} else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
* ACLO:1,pid;
* 107:0;
* 200:1,Syntax Error;
*/
if (strncmp(cmd ,"ACLO", 4) == 0) {
if (reg_closecon(token) == 0) {
strcpy(obuf, "107:0;");
return obuf;
} else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
* ADOI:2,pid,doing;
* 100:0;
* 200:1,Syntax Error;
*/
if (strncmp(cmd, "ADOI", 4) == 0) {
if (reg_doing(token) == 0)
return obuf;
else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
* ATCP:1,pid;
* 100:0;
* 200:1,Syntax Error;
*/
if (strncmp(cmd, "ATCP", 4) == 0) {
if (reg_ip(token) == 0)
return obuf;
else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
* ATTY:2,pid,tty;
* 100:0;
* 200:1,Syntax Error;
*/
if (strncmp(cmd, "ATTY", 4) == 0) {
if (reg_tty(token) == 0)
return obuf;
else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
* ALOG:5,file,program,pid,grade,text;
* 100:0;
* 201:1,errno;
*/
if (strncmp(cmd, "ALOG", 4) == 0) {
if (userlog(token) != 0)
2005-08-29 21:03:28 +00:00
snprintf(obuf, SS_BUFSIZE, "201:1,%d;", oserr);
return obuf;
}
/*
* AUSR:3,pid,user,city;
* 100:0;
* 200:1,Syntax Error;
*/
if (strncmp(cmd, "AUSR", 4) == 0) {
if (reg_user(token) == 0)
return obuf;
else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
* ADIS:2,pid,flag; (set Do Not Disturb).
* 100:0;
* 200:1,Syntax Error;
*/
if (strncmp(cmd, "ADIS", 4) == 0) {
if (reg_silent(token) == 0)
return obuf;
else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
* ATIM:2,pid,seconds;
* 100:0;
* 200:1,Syntax Error;
*/
if (strncmp(cmd, "ATIM", 4) == 0) {
if (reg_timer(TRUE, token) == 0)
return obuf;
else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
* ADEF:1,pid;
* 100:0;
*/
if (strncmp(cmd, "ADEF", 4) == 0) {
if (reg_timer(FALSE, token) == 0)
return obuf;
else {
stat_inc_serr();
return ebuf;
2001-08-17 05:46:24 +00:00
}
}
/*
2003-03-24 19:44:38 +00:00
* Check for personal message
*
2003-03-24 19:44:38 +00:00
* CIPM:1,pid; (Is personal message present)
* 100:2,fromname,message;
* 100:0;
*/
if (strncmp(cmd, "CIPM", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
reg_ipm_r(token, buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
}
/*
2003-03-24 19:44:38 +00:00
* CSPM:3,fromuser,touser,text; (Send personal message).
* 100:1,n; n: 1=donotdisturb 2=buffer full 3=error
* 100:0;
*/
if (strncmp(cmd, "CSPM", 4) == 0) {
2003-03-20 22:43:40 +00:00
if ((result = reg_spm(token)))
2005-08-29 21:03:28 +00:00
snprintf(obuf, SS_BUFSIZE, "100:1,%d;", result);
2003-03-20 22:43:40 +00:00
return obuf;
}
/*
2003-04-02 21:36:47 +00:00
* CSYS:2,pid,1; Sysop available for chat (from mbmon)
* CSYS:2,pid,0; Sysop goes away (from mbmon)
* 100:0; Allways Ok.
*/
if (strncmp(cmd, "CSYS", 4) == 0) {
reg_sysop(token);
return obuf;
}
2003-03-20 22:43:40 +00:00
/*
* CPAG:2,pid,reason; Page sysop for a chat
* 100:1,n; 1=busy, 2=sysop not available, 3=error
* 100:0; Ok
*/
if (strncmp(cmd, "CPAG", 4) == 0) {
2005-09-01 19:58:35 +00:00
if (ibc_run) {
if ((result = reg_page(token))) {
snprintf(obuf, SS_BUFSIZE, "100:1,%d;", result);
}
} else {
snprintf(obuf, SS_BUFSIZE, "100:1,3;");
2003-03-20 22:43:40 +00:00
}
2005-09-01 19:58:35 +00:00
Syslog('+', "%s", obuf);
2003-03-20 22:43:40 +00:00
return obuf;
}
/*
* CCAN:1,pid; Cancel sysop page
* 100:0; Always Ok
*/
if (strncmp(cmd, "CCAN", 4) == 0) {
reg_cancel(token);
return obuf;
}
2003-03-24 19:44:38 +00:00
/*
* Check for sysop page (from mbmon)
*
* CCKP:0;
* 100:3,pid,1,reason; Page is active
* 100:3,pid,0,reason; Page is canceled, but user still online
* 100:0; No page active
*/
2003-03-20 22:43:40 +00:00
if (strncmp(cmd, "CCKP", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
reg_checkpage_r(token, buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
2003-03-20 22:43:40 +00:00
}
2003-04-02 21:36:47 +00:00
/*
* Check for sysop in chatmode for forced sysop chat
*
* CISC:1,pid;
* 100:1,1; Yes (and drop into chatmode)
* 100:1,0; No
*/
if (strncmp(cmd, "CISC", 4) == 0) {
return chat_checksysop(token);
}
2003-03-24 19:44:38 +00:00
/*
* Connect to chatserver
*
2005-04-20 16:59:32 +00:00
* CCON:4,pid,username,unixname,n; Connect to chatserver with username, n=1 user is the sysop
2003-04-02 21:36:47 +00:00
* 100:1,error; If error
* 100:0; Ok
2003-03-24 19:44:38 +00:00
*/
if (strncmp(cmd, "CCON", 4) == 0) {
2005-09-01 19:58:35 +00:00
if (ibc_run)
return chat_connect(token);
else
return ebuf;
2003-03-24 19:44:38 +00:00
}
/*
* Close chat session
*
* CCLO:1,pid; Leave chatserver
* 100:1,error; Error
* 100:0; Ok
*/
if (strncmp(cmd, "CCLO", 4) == 0) {
return chat_close(token);
}
/*
* Put message on server
*
* CPUT:2,pid,message; Put message on server
2003-04-02 21:36:47 +00:00
* 100:2,0,error; Error, not fatal and continue chat
* 100:2,1,error; Error, fatal and disconnect
2003-03-24 19:44:38 +00:00
* 100:0; Ok
*/
if (strncmp(cmd, "CPUT", 4) == 0) {
return chat_put(token);
}
/*
* Get message from server
*
* CGET:1,pid; Get message from server
2003-04-02 21:36:47 +00:00
* 100:2,0,message; If message present
* 100:2,1,error; Error and disconnect
2003-03-24 19:44:38 +00:00
* 100:0; No message
*/
if (strncmp(cmd, "CGET", 4) == 0) {
return chat_get(token);
}
2004-03-20 13:26:34 +00:00
/*
* The D(isk) commands.
*/
/*
* DRES:0; Reset and reread disk tables.
* 100:0; Always Ok.
*/
if (strncmp(cmd, "DRES", 4) == 0) {
return disk_reset();
}
/*
2004-03-20 19:25:57 +00:00
* DSPC:1,n; Check free space in MBytes
2004-03-21 12:55:45 +00:00
* 100:2,0,n; No, n = lowest size in MBytes
* 100:2,1,n; Yes, n = lowest size in MBytes
2004-03-20 13:26:34 +00:00
* 100:1,2; Unknown
* 100:1,3; Error
*/
if (strncmp(cmd, "DSPC", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
disk_check_r(token, buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
2004-03-20 13:26:34 +00:00
}
/*
* DGFS:0; Get filesystem status.
* 100:n,data1,..,data10;
*/
if (strncmp(cmd, "DGFS", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
disk_getfs_r(buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
2004-03-20 13:26:34 +00:00
}
2003-03-24 19:44:38 +00:00
/*
* The G(lobal) commands.
*
* GNOP:1,pid;
* 100:0;
*/
if (strncmp(cmd ,"GNOP", 4) == 0) {
reg_nop(token);
return obuf;
}
/*
* GPNG:n,data;
* 100:n,data;
*/
if (strncmp(cmd, "GPNG", 4) == 0) {
2005-08-29 21:03:28 +00:00
snprintf(obuf, SS_BUFSIZE, "100:%s", token);
return obuf;
}
/*
* GVER:0;
* 100:1,Version ...;
*/
if (strncmp(cmd, "GVER", 4) == 0) {
2005-08-29 21:03:28 +00:00
snprintf(obuf, SS_BUFSIZE, "100:1,Version %s;", VERSION);
return obuf;
}
/*
* GSTA:0;
* 100:19,start,laststart,daily,startups,clients,tot_clients,tot_peak,tot_syntax,tot_comerr,
* today_clients,today_peak,today_syntax,today_comerr,!BBSopen,ZMH,internet,Processing,Load,sequence;
* 201:1,16;
*/
if (strncmp(cmd, "GSTA", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
stat_status_r(buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
}
/*
* GMON:1,n; n=1 First time
* 100:7,pid,tty,user,program,city,isdoing,starttime;
* 100:0;
*/
if (strncmp(cmd, "GMON", 4) == 0) {
cnt = strtok(token, ",");
strcpy(var1, strtok(NULL, ";"));
buf = calloc(SS_BUFSIZE, sizeof(char));
get_reginfo_r(atoi(var1), buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
}
/*
2004-03-20 13:26:34 +00:00
* GDST:0; Obsolete!
* 100:n,data1,..,data10;
*/
if (strncmp(cmd, "GDST", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
disk_getfs_r(buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
}
/*
* GSYS:0;
* 100:7,calls,pots_calls,isdn_calls,network_calls,local_calls,startdate,last_caller;
* 201:1,16;
*/
if (strncmp(cmd, "GSYS", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
get_sysinfo_r(buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
}
/*
* GLCC:0;
* 100:1,n;
*/
if (strncmp(cmd, "GLCC", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
get_lastcallercount_r(buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
}
/*
* GLCR:1,recno;
* 100:9,user,location,level,device,time,mins,calls,speed,actions;
* 201:1,16;
*/
if (strncmp(cmd, "GLCR", 4) == 0) {
cnt = strtok(token, ",");
strcpy(var1, strtok(NULL, ";"));
buf = calloc(SS_BUFSIZE, sizeof(char));
get_lastcallerrec_r(atoi(var1), buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* The (S)tatus commands.
*
* SBBS:0;
* 100:2,n,status message;
*/
if (strncmp(cmd, "SBBS", 4) == 0) {
switch(stat_bbs_stat()) {
2005-08-29 21:03:28 +00:00
case 0: snprintf(obuf, SS_BUFSIZE, "100:2,0,The system is open for use;");
2003-03-20 22:43:40 +00:00
break;
2005-08-29 21:03:28 +00:00
case 1: snprintf(obuf, SS_BUFSIZE, "100:2,1,The system is closed right now!;");
2003-03-20 22:43:40 +00:00
break;
2005-08-29 21:03:28 +00:00
case 2: snprintf(obuf, SS_BUFSIZE, "100:2,2,The system is closed for Zone Mail Hour!;");
2003-03-20 22:43:40 +00:00
break;
2001-08-17 05:46:24 +00:00
}
2003-03-20 22:43:40 +00:00
return obuf;
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* SOPE:0;
* 100:0;
*/
if (strncmp(cmd, "SOPE", 4) == 0) {
stat_set_open(1);
return obuf;
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* SCLO:0;
2003-03-20 22:43:40 +00:00
* 100:0;
*/
if (strncmp(cmd, "SCLO", 4) == 0) {
stat_set_open(0);
return obuf;
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* SFRE:0;
* 100:1,Running utilities: n Active users: n;
* 100:0;
* 201:1,16;
*/
if (strncmp(cmd, "SFRE", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
reg_fre_r(buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
2003-03-20 22:43:40 +00:00
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* SSEQ:0;
* 100:1,number;
* 200:1,16;
*/
if (strncmp(cmd, "SSEQ", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
getseq_r(buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
2003-03-20 22:43:40 +00:00
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* SEST:1,semafore; Get status of semafore
* 100:1,n; 1 = set, 0 = not set
* 200:1,16;
*/
if (strncmp(cmd, "SEST", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
sem_status_r(token, buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
2003-03-20 22:43:40 +00:00
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* SECR:1,semafore; Set semafore
* 100:0;
* 200:1,16;
*/
if (strncmp(cmd, "SECR", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
sem_create_r(token, buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
2003-03-20 22:43:40 +00:00
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* SERM:1,semafore; Remove semafore
* 100:0;
* 200:1,16;
*/
if (strncmp(cmd, "SERM", 4) == 0) {
buf = calloc(SS_BUFSIZE, sizeof(char));
sem_remove_r(token, buf);
snprintf(obuf, SS_BUFSIZE, "%s", buf);
free(buf);
return obuf;
2003-03-20 22:43:40 +00:00
}
2001-08-17 05:46:24 +00:00
2003-03-20 22:43:40 +00:00
/*
* If we got this far, there must be an error.
*/
stat_inc_serr();
2003-04-02 21:36:47 +00:00
Syslog('!', "Comm systax error: \"%s:%s\"", cmd, printable(token, 0));
2003-03-20 22:43:40 +00:00
return ebuf;
2001-08-17 05:46:24 +00:00
}
void do_cmd(char *);
2001-08-17 05:46:24 +00:00
void do_cmd(char *cmd)
{
2003-03-20 22:43:40 +00:00
char buf[SS_BUFSIZE];
int slen, tries = 0;
if (logtrans)
Syslog('-', "< %s", cmd);
2005-08-29 21:03:28 +00:00
snprintf(buf, SS_BUFSIZE, "%s", exe_cmd(cmd));
2003-03-20 22:43:40 +00:00
if (logtrans)
Syslog('-', "> %s", buf);
for (;;) {
2003-07-06 11:49:01 +00:00
slen = sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&from, fromlen);
2003-03-20 22:43:40 +00:00
if (slen == -1)
Syslog('?', "$do_cmd(): sendto error %d %s", tries, from.sun_path);
else if (slen != strlen(buf))
Syslog('?', "do_cmd(): send %d of %d bytes, try=%d", slen, strlen(buf), tries);
else
return;
tries++;
if (tries == 3)
return;
sleep(1);
}
2001-08-17 05:46:24 +00:00
}
/*
* Thread that reads the command socket for new commands.
*/
void *cmd_thread(void)
{
int rlen, rc;
struct pollfd pfd;
static char buf[2048];
2003-12-24 12:00:00 +00:00
Syslog('+', "Starting cmd thread");
cmd_run = TRUE;
while (! T_Shutdown) {
/*
* Poll UNIX Datagram socket until the defined timeout of one second.
* This means we listen of a MBSE BBS client program has something
* to tell.
*/
pfd.fd = sock;
pfd.events = POLLIN;
pfd.revents = 0;
rc = poll(&pfd, 1, 1000);
if (rc == -1) {
/*
* Poll can be interrupted by a finished child so that's not a real error.
*/
2003-12-24 12:00:00 +00:00
if (errno != EINTR) {
Syslog('?', "$poll() rc=%d sock=%d, events=%04x", rc, sock, pfd.revents);
2003-12-24 12:00:00 +00:00
}
} else if (rc) {
if (pfd.revents & POLLIN) {
/*
* Process the clients request
*/
memset(&buf, 0, sizeof(buf));
fromlen = sizeof(from);
rlen = recvfrom(sock, buf, sizeof(buf) -1, 0, (struct sockaddr *)&from, &fromlen);
if (rlen == -1) {
Syslog('?', "$recvfrom()");
} else {
do_cmd(buf);
}
} else {
Syslog('-', "Return poll rc=%d, events=%04x", rc, pfd.revents);
}
}
}
cmd_run = FALSE;
Syslog('+', "Cmd thread stopped");
pthread_exit(NULL);
}