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_fsqueue.c

256 lines
6.1 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"
int out_filetype(const char *fname)
{
const char *p_nam;
const char *p_ext;
int i;
/*
* Get only file name, w/o dir part
*/
if( (p_nam = strrchr(fname, DIRSEPCHR)) )
p_nam++;
else
p_nam = fname;
/*
* Get file name extension
*/
if( (p_ext = strrchr(p_nam, '.')) == NULL )
return TYPE_UNKNOWN;
for( i = 0; outtab[i].ext; i++ )
if( strcasemask(p_ext, outtab[i].ext) == 0 )
return outtab[i].type;
for( i = 0; exttab[i].ext; i++ )
if( strcasemask(p_ext, exttab[i].ext) == 0 )
return exttab[i].type;
return TYPE_UNKNOWN;
}
/* ------------------------------------------------------------------------- */
/* Read FLO file line by line and call handler proc for each file in FLO */
/* ------------------------------------------------------------------------- */
static int out_readflo(s_filelist **fslist, const char *floname,
int flavor, bool aso, int flodsc)
{
s_FLO *FLO;
s_filelist **tmpl;
struct stat st;
int type;
DEB((D_OUTBOUND, "out_readflo: opening flo file \"%s\"", floname));
if( (FLO = flo_open(floname, "r")) == NULL )
{
logerr("can't open flo \"%s\"", floname);
return -1;
}
for( tmpl = fslist; *tmpl; tmpl = &(*tmpl)->next );
while( flo_next(FLO) == 0 )
{
if( stat(FLO->att_path, &st) == 0 )
{
type = out_filetype(FLO->att_path);
type |= TYPE_FROMFLO;
type |= aso ? TYPE_ASONAME : 0;
(*tmpl) = (s_filelist*)xmalloc(sizeof(s_filelist));
memset(*tmpl, '\0', sizeof(s_filelist));
(*tmpl)->fname = (char *)xstrcpy(FLO->att_path);
(*tmpl)->size = st.st_size;
(*tmpl)->type = type;
(*tmpl)->flavor = flavor;
(*tmpl)->action = FLO->att_action;
(*tmpl)->status = STATUS_WILLSEND;
(*tmpl)->flodsc = flodsc;
tmpl = &(*tmpl)->next;
}
else
logerr("can't stat file \"%s\" from flo \"%s\"",
FLO->att_path, floname);
}
flo_close(FLO);
return 0;
}
/*
* Add new entry to the flo files table, return it's index number
*/
static int out_addfloentry(s_fsqueue *q, const char *floname, int flavor)
{
q->flotab = (s_flofile*)xrealloc(q->flotab, sizeof(s_flofile)*(q->flonum+1));
memset(&q->flotab[q->flonum], '\0', sizeof(s_flofile));
q->flotab[q->flonum].fname = xstrcpy(floname);
q->flotab[q->flonum].flavor = flavor;
q->flonum++;
return q->flonum-1;
}
/* ------------------------------------------------------------------------- */
/* Handle each file $fi found in outbound. Usually it called by outbound */
/* scanner.. Pointer to result information will be stored at dst */
/* ------------------------------------------------------------------------- */
int out_handle_fsqueue(s_outbound_callback_data *callback)
{
s_fsqueue *queue;
int type;
int flavor;
int action;
ASSERT(callback);
ASSERT(callback->path);
ASSERT(callback->dest);
queue = (s_fsqueue*)callback->dest;
DEB((D_OUTBOUND, "out_handle_fsqueue: process file \"%s\"",
callback->path));
if( callback->type != OUTB_TYPE_FBOX )
{
int i;
const char *p_ext = strrchr(callback->path, '.');
if( !p_ext )
return -1;
for( i = 0; outtab[i].ext && strcasecmp(p_ext, outtab[i].ext); i++ );
if( !outtab[i].ext )
return -1;
type = outtab[i].type;
flavor = outtab[i].flavor;
action = outtab[i].action;
}
else
{
type = out_filetype(callback->path) | TYPE_FILEBOX;
if( callback->flavor != -1 )
flavor = callback->flavor;
else
flavor = FLAVOR_HOLD;
action = ACTION_UNLINK;
}
if( (type & TYPE_NETMAIL) == TYPE_NETMAIL
|| (type & TYPE_REQUEST) == TYPE_REQUEST
|| (type & TYPE_FILEBOX) == TYPE_FILEBOX )
{
struct stat st;
if( stat(callback->path, &st) == 0 )
{
s_filelist **tmpl;
for( tmpl = &queue->fslist; *tmpl; tmpl = &(*tmpl)->next );
(*tmpl) = (s_filelist*)xmalloc(sizeof(s_filelist));
memset(*tmpl, '\0', sizeof(s_filelist));
(*tmpl)->fname = xstrcpy(callback->path);
(*tmpl)->size = st.st_size;
(*tmpl)->type = type |
(callback->type == OUTB_TYPE_ASO ? TYPE_ASONAME : 0);
(*tmpl)->flavor = flavor;
(*tmpl)->action = action;
(*tmpl)->status = STATUS_WILLSEND;
(*tmpl)->flodsc = -1;
}
else
logerr("can't stat file \"%s\"", callback->path);
}
else if( (type & TYPE_FLOFILE) == TYPE_FLOFILE )
{
out_readflo(&queue->fslist, callback->path,
flavor, (callback->type == OUTB_TYPE_ASO),
out_addfloentry(queue, callback->path, flavor));
}
return 0;
}
void deinit_filelist(s_filelist *filelist)
{
struct filelist *ptrl, *next;
for( ptrl = filelist; ptrl; ptrl = next )
{
next = ptrl->next;
if( ptrl->fname ) free(ptrl->fname);
free(ptrl);
}
}
void deinit_fsqueue(s_fsqueue *q)
{
int i;
if( q->fslist )
deinit_filelist(q->fslist);
if( q->flotab )
{
for( i = 0; i < q->flonum; i++ )
if( q->flotab[i].fname ) free(q->flotab[i].fname);
free(q->flotab);
}
memset(q, '\0', sizeof(s_fsqueue));
}
#ifdef DEBUG
void log_filelist(const s_filelist *filelist)
{
const s_filelist *ptrl;
DEB((D_OUTBOUND, "log_filelist: BEGIN"));
for( ptrl = filelist; ptrl; ptrl = ptrl->next )
{
DEB((D_OUTBOUND, "log_filelist: \tfile \"%s\", %ld byte(s), flodsc = %d, status: \"%s\"",
ptrl->fname, (long)ptrl->size, ptrl->flodsc,
ptrl->status == STATUS_WILLSEND ? "WILLSEND" :
ptrl->status == STATUS_SKIP ? "SKIP" :
ptrl->status == STATUS_SKIP ? "SENDING" :
ptrl->status == STATUS_SENT ? "SENT" : "?"));
}
DEB((D_OUTBOUND, "log_filelist: END"));
}
void log_fsqueue(const s_fsqueue *q)
{
int i;
DEB((D_OUTBOUND, "log_queue_long: BEGIN"));
log_filelist(q->fslist);
for( i = 0; i < q->flonum; i++ )
DEB((D_OUTBOUND, "log_queue_long: FLO file \"%s\"", q->flotab[i].fname));
DEB((D_OUTBOUND, "log_queue_long: END"));
}
#endif