You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bforce/source/bforce/outb_bsy.c

425 lines
10 KiB
C

/*
* binkleyforce -- unix FTN mailer project
*
* Copyright (c) 1998-2000 Alexander Belkin, 2:5020/1398.11
*
* 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.
*
* $Id$
*/
#include "includes.h"
#include "confread.h"
#include "logger.h"
#include "util.h"
#include "outbound.h"
typedef struct bsylist {
s_faddr addr;
char *name_4d;
char *name_domain;
char *name_amiga;
struct bsylist *next;
#ifdef BFORCE_USE_CSY
bool is_csy;
#endif
} s_bsylist;
s_bsylist *bsylist = NULL;
static int out_bsy_convert_csy_to_bsy(s_bsylist *ptrl);
/* ========================================================================= */
/* PRIVATE part */
/* ========================================================================= */
static int out_bsy_file_check(const char *name, const char *ext)
{
char lockname[BFORCE_MAX_PATH+1];
ASSERT(name != NULL && ext != NULL);
strnxcpy(lockname, name, sizeof(lockname));
strnxcat(lockname, ext, sizeof(lockname));
return plock_check(lockname);
}
static int out_bsy_file_create(const char *name, const char *ext)
{
char lockname[BFORCE_MAX_PATH+1];
ASSERT(name != NULL && ext != NULL);
strnxcpy(lockname, name, sizeof(lockname));
strnxcat(lockname, ext, sizeof(lockname));
return plock_create(lockname);
}
static int out_bsy_file_link(const char *oldname, const char *oldext,
const char *newname, const char *newext)
{
char old_lockname[BFORCE_MAX_PATH+1];
char new_lockname[BFORCE_MAX_PATH+1];
ASSERT(oldname != NULL && oldext != NULL);
ASSERT(newname != NULL && newext != NULL);
strnxcpy(old_lockname, oldname, sizeof(old_lockname));
strnxcat(old_lockname, oldext, sizeof(old_lockname));
strnxcpy(new_lockname, newname, sizeof(new_lockname));
strnxcat(new_lockname, newext, sizeof(new_lockname));
return plock_link(new_lockname, old_lockname);
}
static int out_bsy_file_unlink(const char *name, const char *ext)
{
char lockname[BFORCE_MAX_PATH+1];
ASSERT(name != NULL && ext != NULL);
strnxcpy(lockname, name, sizeof(lockname));
strnxcat(lockname, ext, sizeof(lockname));
return plock_remove(lockname);
}
/* ========================================================================= */
/* PUBLIC part */
/* ========================================================================= */
int out_bsy_check(s_faddr addr)
{
bool isfailed = FALSE;
char *name_4d = NULL;
char *name_domain = NULL;
char *name_amiga = NULL;
name_4d = out_getname_4d(addr);
name_domain = out_getname_domain(addr);
name_amiga = out_getname_amiga(addr);
DEB((D_OUTBOUND, "out_bsy_check: name_4d = \"%s\"", name_4d));
DEB((D_OUTBOUND, "out_bsy_check: name_domain = \"%s\"", name_domain));
DEB((D_OUTBOUND, "out_bsy_check: name_amiga = \"%s\"", name_amiga));
/* Check for BSY files in all outbounds */
if( (name_4d && out_bsy_file_check(name_4d, ".bsy") == PLOCK_EXIST)
|| (name_domain && out_bsy_file_check(name_domain, ".bsy") == PLOCK_EXIST)
|| (name_amiga && out_bsy_file_check(name_amiga, ".bsy") == PLOCK_EXIST) )
isfailed = TRUE;
#ifdef BFORCE_USE_CSY
if( !isfailed )
{
/* Check for CSY files in all outbounds */
if( (name_4d && out_bsy_file_check(name_4d, ".csy") == PLOCK_EXIST)
|| (name_domain && out_bsy_file_check(name_domain, ".csy") == PLOCK_EXIST)
|| (name_amiga && out_bsy_file_check(name_amiga, ".csy") == PLOCK_EXIST) )
isfailed = TRUE;
}
#endif
if( name_4d )
free(name_4d);
if( name_domain )
free(name_domain);
if( name_amiga )
free(name_amiga);
return isfailed ? -1 : 0;
}
#ifdef BFORCE_USE_CSY
int out_bsy_lock(s_faddr addr, bool csy_locks)
#else
int out_bsy_lock(s_faddr addr)
#endif
{
char *name_4d = NULL;
char *name_domain = NULL;
char *name_amiga = NULL;
bool locked_4d = FALSE;
bool locked_domain = FALSE;
bool locked_amiga = FALSE;
s_bsylist bsytmp, **bsylst;
bool isfailed = FALSE;
#ifdef DEBUG
char abuf[BF_MAXADDRSTR+1];
#endif
#ifdef BFORCE_USE_CSY
const char *lockext = csy_locks ? ".csy" : ".bsy";
#else
const char *lockext = ".bsy";
#endif
DEB((D_OUTBOUND, "out_bsy_lock: lock address %s",
ftn_addrstr(abuf, addr)));
/*
* Check, may be we've allready locked this address.
*/
for( bsylst = &bsylist; *bsylst; bsylst = &(*bsylst)->next )
{
if( !ftn_addrcomp((*bsylst)->addr, addr) )
{
DEB((D_OUTBOUND, "out_bsy_lock: address is allready locked"));
#ifdef BFORCE_USE_CSY
if( (*bsylst)->is_csy && !csy_locks )
return out_bsy_convert_csy_to_bsy(*bsylst);
#else
return 0;
#endif
}
}
name_4d = out_getname_4d(addr);
name_domain = out_getname_domain(addr);
name_amiga = out_getname_amiga(addr);
DEB((D_OUTBOUND, "out_bsy_lock: name_4d = \"%s\"", name_4d));
DEB((D_OUTBOUND, "out_bsy_lock: name_domain = \"%s\"", name_domain));
DEB((D_OUTBOUND, "out_bsy_lock: name_amiga = \"%s\"", name_amiga));
/* Check for BSY files in all outbounds */
if( (name_4d && out_bsy_file_check(name_4d, ".bsy") == PLOCK_EXIST)
|| (name_domain && out_bsy_file_check(name_domain, ".bsy") == PLOCK_EXIST)
|| (name_amiga && out_bsy_file_check(name_amiga, ".bsy") == PLOCK_EXIST) )
isfailed = TRUE;
#ifdef BFORCE_USE_CSY
if( !isfailed )
{
/* Check for CSY files in all outbounds */
if( (name_4d && out_bsy_file_check(name_4d, ".csy") == PLOCK_EXIST)
|| (name_domain && out_bsy_file_check(name_domain, ".csy") == PLOCK_EXIST)
|| (name_amiga && out_bsy_file_check(name_amiga, ".csy") == PLOCK_EXIST) )
isfailed = TRUE;
}
#endif
DEB((D_OUTBOUND, "out_bsy_lock: lock check result: %s",
isfailed ? "Locked" : "Not locked"));
/* Create ?SY file in 4D outbound */
if( !isfailed && name_4d )
{
switch( out_bsy_file_create(name_4d, lockext) ) {
case PLOCK_OK: locked_4d = TRUE; break;
case PLOCK_EXIST: isfailed = TRUE; break;
case PLOCK_ERROR: locked_4d = FALSE; break;
}
}
/* Create ?SY file in domain outbound */
if( !isfailed && name_domain )
{
switch( out_bsy_file_create(name_domain, lockext) ) {
case PLOCK_OK: locked_domain = TRUE; break;
case PLOCK_EXIST: isfailed = TRUE; break;
case PLOCK_ERROR: locked_domain = FALSE; break;
}
}
/* Create ?SY file in "AmigaDos" outbound */
if( !isfailed && name_amiga )
{
switch( out_bsy_file_create(name_amiga, lockext) ) {
case PLOCK_OK: locked_amiga = TRUE; break;
case PLOCK_EXIST: isfailed = TRUE; break;
case PLOCK_ERROR: locked_amiga = FALSE; break;
}
}
#ifdef BFORCE_USE_CSY
if( !isfailed )
{
/* Check for BSY files in all outbounds */
if( (name_4d && out_bsy_file_check(name_4d, ".bsy") == PLOCK_EXIST)
|| (name_domain && out_bsy_file_check(name_domain, ".bsy") == PLOCK_EXIST)
|| (name_amiga && out_bsy_file_check(name_amiga, ".bsy") == PLOCK_EXIST) )
isfailed = TRUE;
}
#endif
DEB((D_OUTBOUND, "out_bsy_lock: lock create result: %s",
isfailed ? "Failed" : "Successful"));
/* Somebody else create BSY before us?! */
if( isfailed )
{
if( locked_4d )
out_bsy_file_unlink(name_4d, lockext);
if( locked_domain )
out_bsy_file_unlink(name_domain, lockext);
if( locked_amiga )
out_bsy_file_unlink(name_amiga, lockext);
if( name_4d )
free(name_4d);
if( name_domain )
free(name_domain);
if( name_amiga )
free(name_amiga);
return -1;
}
/*
* Successful locking. Add new entry to the ``bsylist''.
*/
memset(&bsytmp, '\0', sizeof(s_bsylist));
bsytmp.addr = addr;
#ifdef BFORCE_USE_CSY
bsytmp.is_csy = csy_locks;
#endif
if( locked_4d )
bsytmp.name_4d = name_4d;
if( locked_domain )
bsytmp.name_domain = name_domain;
if( locked_amiga )
bsytmp.name_amiga = name_amiga;
for( bsylst = &bsylist; *bsylst; bsylst = &(*bsylst)->next )
{
/* EMPTY LOOP */
}
(*bsylst) = (s_bsylist*)xmalloc(sizeof(s_bsylist));
**bsylst = bsytmp;
return 0;
}
int out_bsy_unlockall(void)
{
s_bsylist *ptrl, *next;
#ifdef DEBUG
char abuf[BFORCE_MAX_ADDRSTR+1];
#endif
for( ptrl = bsylist; ptrl; ptrl = next )
{
#ifdef BFORCE_USE_CSY
const char *lockext = ptrl->is_csy ? ".csy" : ".bsy";
#else
const char *lockext = ".bsy";
#endif
next = ptrl->next;
DEB((D_OUTBOUND, "out_bsy_unlockall: unlock address %s",
ftn_addrstr(abuf, ptrl->addr)));
if( ptrl->name_4d )
{
out_bsy_file_unlink(ptrl->name_4d, lockext);
free(ptrl->name_4d);
}
if( ptrl->name_domain )
{
out_bsy_file_unlink(ptrl->name_domain, lockext);
free(ptrl->name_domain);
}
if( ptrl->name_amiga )
{
out_bsy_file_unlink(ptrl->name_amiga, lockext);
free(ptrl->name_amiga);
}
free(ptrl);
}
bsylist = NULL;
return 0;
}
#ifdef BFORCE_USE_CSY
static int out_bsy_convert_csy_to_bsy(s_bsylist *ptrl)
{
bool locked_4d = FALSE;
bool locked_domain = FALSE;
bool locked_amiga = FALSE;
bool isfailed = FALSE;
#ifdef DEBUG
char abuf[BF_MAXADDRSTR+1];
#endif
DEB((D_OUTBOUND, "out_bsy_convert_csy_to_bsy: process address %s",
ftn_addrstr(abuf, ptrl->addr)));
if( !ptrl->is_csy )
{
DEB((D_OUTBOUND, "out_bsy_convert_csy_to_bsy: skip (no csy locks)"));
return 0;
}
#define LINK_CSY_TO_BSY(lockname) \
out_bsy_file_link(lockname, ".csy", lockname, ".bsy")
/* Create BSY file in 4D outbound */
if( !isfailed && ptrl->name_4d )
{
switch( LINK_CSY_TO_BSY(ptrl->name_4d) ) {
case PLOCK_OK: locked_4d = TRUE; break;
case PLOCK_EXIST: isfailed = TRUE; break;
case PLOCK_ERROR: locked_4d = FALSE; break;
}
}
/* Create BSY file in domain outbound */
if( !isfailed && ptrl->name_domain )
{
switch( LINK_CSY_TO_BSY(ptrl->name_domain) ) {
case PLOCK_OK: locked_domain = TRUE; break;
case PLOCK_EXIST: isfailed = TRUE; break;
case PLOCK_ERROR: locked_domain = FALSE; break;
}
}
/* Create BSY file in "AmigaDos" outbound */
if( !isfailed && ptrl->name_amiga )
{
switch( LINK_CSY_TO_BSY(ptrl->name_amiga) ) {
case PLOCK_OK: locked_amiga = TRUE; break;
case PLOCK_EXIST: isfailed = TRUE; break;
case PLOCK_ERROR: locked_amiga = FALSE; break;
}
}
DEB((D_OUTBOUND, "out_csy_to_bsy: lock create result: %s",
isfailed ? "Failed" : "Successful"));
/* Somebody else create BSY before us?! */
if( isfailed )
{
if( locked_4d )
out_bsy_file_unlink(ptrl->name_4d, ".bsy");
if( locked_domain )
out_bsy_file_unlink(ptrl->name_domain, ".bsy");
if( locked_amiga )
out_bsy_file_unlink(ptrl->name_amiga, ".bsy");
/* Leave ``.csy'' files untouched! */
return 1;
}
ptrl->is_csy = FALSE;
return 0;
}
#endif /* BFORCE_USE_CSY */