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/mbcico/mbout.c
2007-09-02 11:17:31 +00:00

371 lines
9.6 KiB
C

/*****************************************************************************
*
* $Id$
* Purpose: MBSE BBS Outbound Manager
*
*****************************************************************************
* Copyright (C) 1997-2007
*
* 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.
*
* MBSE 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 MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*****************************************************************************/
#include "../config.h"
#include "../lib/mbselib.h"
#include "../lib/nodelist.h"
#include "../lib/users.h"
#include "../lib/mbsedb.h"
#include "outstat.h"
#include "nlinfo.h"
extern int most_debug;
extern int do_quiet; /* Suppress screen output */
int do_attach = FALSE; /* Send file attaches */
int do_node = FALSE; /* Query the nodelist */
int do_poll = FALSE; /* Poll a node */
int do_req = FALSE; /* Request files from a node */
int do_stat = FALSE; /* Show outbound status */
int do_stop = FALSE; /* Stop polling a node */
int do_reset = FALSE; /* Reset node's try counter */
extern pid_t e_pid; /* Pid of child */
extern int show_log; /* Show logging */
time_t t_start; /* Start time */
time_t t_end; /* End time */
void ProgName(void);
void ProgName()
{
if (do_quiet)
return;
mbse_colour(WHITE, BLACK);
printf("\nMBOUT: MBSE BBS %s Outbound Manager\n", VERSION);
mbse_colour(YELLOW, BLACK);
printf(" %s\n", COPYRIGHT);
}
void die(int);
void die(int onsig)
{
deinitnl();
/*
* First check if a child is running, if so, kill it.
*/
if (e_pid) {
if ((kill(e_pid, SIGTERM)) == 0)
Syslog('+', "SIGTERM to pid %d succeeded", e_pid);
else {
if ((kill(e_pid, SIGKILL)) == 0)
Syslog('+', "SIGKILL to pid %d succeded", e_pid);
else
WriteError("$Failed to kill pid %d", e_pid);
}
/*
* In case the child had the tty in raw mode...
*/
execute_pth((char *)"stty", (char *)"sane", (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
}
signal(onsig, SIG_IGN);
if (show_log)
do_quiet = FALSE;
if (!do_quiet)
mbse_colour(CYAN, BLACK);
if (onsig) {
if (onsig <= NSIG)
WriteError("Terminated on signal %d (%s)", onsig, SigName[onsig]);
else
WriteError("Terminated with error %d", onsig);
}
t_end = time(NULL);
Syslog(' ', "MBOUT finished in %s", t_elapsed(t_start, t_end));
if (!do_quiet) {
mbse_colour(LIGHTGRAY, BLACK);
printf("\n");
}
ExitClient(onsig);
}
void Help(void);
void Help()
{
do_quiet = FALSE;
ProgName();
mbse_colour(LIGHTCYAN, BLACK);
printf("\nUsage: mbout [command] <params> <options>\n\n");
mbse_colour(LIGHTBLUE, BLACK);
printf(" Commands are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" a att <node> <flavor> <file> Attach a file to a node\n");
printf(" n node <node> Show nodelist information\n");
printf(" p poll <node> [node..node] Poll node(s) (always crash)\n");
printf(" req req <node> <file> [file..file] Request file(s) from node\n");
printf(" res reset <node> [node..node] Reset node(s) \"try\" counter\n");
printf(" sta stat Show outbound status\n");
printf(" sto stop <node> [node..node] Stop polling node(s)\n");
printf("\n");
printf(" <node> Should be in domain form, e.g. f16.n2801.z2.domain\n");
printf(" <flavor> Flavor's are: crash | immediate | normal | hold\n");
mbse_colour(LIGHTBLUE, BLACK);
printf("\n Options are:\n\n");
mbse_colour(CYAN, BLACK);
printf(" -quiet Quiet mode\n");
mbse_colour(LIGHTGRAY, BLACK);
die(MBERR_OK);
}
void Fatal(char *, int);
void Fatal(char *msg, int error)
{
show_log = TRUE;
if (!do_quiet) {
mbse_colour(LIGHTRED, BLACK);
printf("%s\n", msg);
}
WriteError(msg);
die(error);
}
int main(int argc, char *argv[])
{
char *cmd, flavor = 'x';
int i, j, rc = 0;
struct passwd *pw;
faddr *addr = NULL;
node *nlent;
FILE *fl;
most_debug = TRUE;
InitConfig();
InitNode();
InitFidonet();
mbse_TermInit(1, 80, 25);
t_start = time(NULL);
umask(002);
/*
* Catch all signals we can, and ignore the rest.
*/
for (i = 0; i < NSIG; i++) {
if ((i == SIGHUP) || (i == SIGINT) || (i == SIGBUS) || (i == SIGILL) || (i == SIGSEGV) || (i == SIGTERM) || (i == SIGIOT))
signal(i, (void (*))die);
else if ((i != SIGKILL) && (i != SIGSTOP))
signal(i, SIG_IGN);
}
if(argc < 2)
Help();
cmd = xstrcpy((char *)"Command line: mbout");
if (argc > 1) {
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[1]);
if (!strncasecmp(argv[1], "a", 1))
do_attach = TRUE;
if (!strncasecmp(argv[1], "n", 1))
do_node = TRUE;
if (!strncasecmp(argv[1], "p", 1))
do_poll = TRUE;
if (!strncasecmp(argv[1], "req", 3))
do_req = TRUE;
if (!strncasecmp(argv[1], "res", 3))
do_reset = TRUE;
if (!strncasecmp(argv[1], "sta", 3))
do_stat = TRUE;
if (!strncasecmp(argv[1], "sto", 3))
do_stop = TRUE;
}
for (i = 2; i < argc; i++) {
cmd = xstrcat(cmd, (char *)" ");
cmd = xstrcat(cmd, argv[i]);
if (!strncasecmp(argv[i], "-q", 2))
do_quiet = TRUE;
}
ProgName();
pw = getpwuid(getuid());
InitClient(pw->pw_name, (char *)"mbout", CFG.location, CFG.logfile, CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);
Syslog(' ', " ");
Syslog(' ', "MBOUT v%s", VERSION);
Syslog(' ', cmd);
free(cmd);
if (!do_quiet) {
mbse_colour(CYAN, BLACK);
printf("\n");
}
if (strcmp(pw->pw_name, "mbse"))
Fatal((char *)"You are not user 'mbse'", MBERR_COMMANDLINE);
if (do_stat) {
rc = outstat();
die(rc);
}
/*
* Get node number from commandline
*/
if (do_attach || do_node || do_poll || do_stop || do_req || do_reset) {
if (argc < 3)
Fatal((char *)"Not enough parameters", MBERR_COMMANDLINE);
}
if (do_attach || do_node || do_req || do_reset) {
if ((addr = parsefaddr(argv[2])) == NULL)
Fatal((char *)"Unrecognizable address", MBERR_COMMANDLINE);
}
if (do_node) {
rc = nlinfo(addr);
tidy_faddr(addr);
die(rc);
}
if (do_poll || do_stop) {
tidy_faddr(addr);
for (i = 3; i <= argc; i++) {
if (strncasecmp(argv[i-1], "-q", 2)) {
if ((addr = parsefaddr(argv[i-1])) == NULL)
Fatal((char *)"Unrecognizable address", MBERR_COMMANDLINE);
j = pollnode(addr, do_stop);
tidy_faddr(addr);
if (j)
rc = j;
}
}
die(rc);
}
if (do_reset) {
tidy_faddr(addr);
for (i = 3; i <= argc; i++) {
if (strncasecmp(argv[i-1], "-q", 2)) {
if ((addr = parsefaddr(argv[i-1])) == NULL)
Fatal((char *)"Unrecognizable address", MBERR_COMMANDLINE);
j = reset(addr);
tidy_faddr(addr);
if (j)
rc = j;
}
}
die(rc);
}
if (do_attach) {
if (argc < 5)
Fatal((char *)"Not enough parameters", MBERR_COMMANDLINE);
flavor = tolower(argv[3][0]);
switch (flavor) {
case 'n' : flavor = 'f'; break;
case 'i' : flavor = 'i'; break;
case 'c' : flavor = 'c'; break;
case 'h' : flavor = 'h'; break;
default : Fatal((char *)"Invalid flavor, must be: immediate, crash, normal or hold", MBERR_COMMANDLINE);
}
nlent = getnlent(addr);
if (nlent->addr.domain)
free(nlent->addr.domain);
nlent->addr.domain = NULL;
if (nlent->url)
free(nlent->url);
nlent->url = NULL;
if (nlent->pflag == NL_DUMMY)
Fatal((char *)"Node is not in nodelist", MBERR_NODE_NOT_IN_LIST);
if (nlent->pflag == NL_DOWN)
Fatal((char *)"Node has status Down", MBERR_NODE_MAY_NOT_CALL);
if (nlent->pflag == NL_HOLD)
Fatal((char *)"Node has status Hold", MBERR_NODE_MAY_NOT_CALL);
if (((nlent->can_pots && nlent->is_cm) == FALSE) && ((nlent->can_ip && nlent->is_icm) == FALSE) && (flavor == 'c'))
Fatal((char *)"Node is not CM, must use Immediate, Normal or Hold flavor", MBERR_NODE_MAY_NOT_CALL);
if (argv[4][0] == '-')
Fatal((char *)"Invalid filename given", MBERR_COMMANDLINE);
if (file_exist(argv[4], R_OK) != 0)
Fatal((char *)"File doesn't exist", MBERR_COMMANDLINE);
cmd = calloc(PATH_MAX, sizeof(char));
snprintf(cmd, PATH_MAX -1, "%s/%d.%d.%d.%d/.filelist", CFG.out_queue, addr->zone, addr->net, addr->node, addr->point);
mkdirs(cmd, 0750);
if ((fl = fopen(cmd, "a+")) == NULL) {
Fatal((char *)"File attach failed", MBERR_ATTACH_FAILED);
} else {
fprintf(fl, "%c LEAVE NOR %s\n", flavor, argv[4]);
Syslog('+', "File attach %s is successfull", argv[4]);
if (!do_quiet)
printf("File attach %s is successfull", argv[4]);
CreateSema((char *)"mailin");
tidy_faddr(addr);
fsync(fileno(fl));
fclose(fl);
free(cmd);
die(MBERR_OK);
}
free(cmd);
}
if (do_req) {
if (argc < 4)
Fatal((char *)"Not enough parameters", MBERR_COMMANDLINE);
for (i = 4; i <= argc; i++) {
if (strncasecmp(argv[i-1], "-q", 2)) {
rc = freq(addr, argv[i-1]);
if (rc)
break;
}
}
tidy_faddr(addr);
die(rc);
}
Help();
return MBERR_OK;
}