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.
425 lines
10 KiB
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 */
|
|
|