|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T t
Length: 7427 (0x1d03)
Types: TextFile
Names: »trash-channel.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Chans/trashman/trash-channel.c«
/* trash_channel.c: message trash collection channel */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/trashman/RCS/trash-channel.c,v 5.0 90/09/20 15:55:03 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Chans/trashman/RCS/trash-channel.c,v 5.0 90/09/20 15:55:03 pp Exp Locker: pp $
*
* $Log: trash-channel.c,v $
* Revision 5.0 90/09/20 15:55:03 pp
* rcsforce : 5.0 public release
*
*/
#include <sys/param.h>
#include "head.h"
#include "qmgr.h"
#include "q.h"
#include "prm.h"
#include <sys/stat.h>
#include <sys/file.h>
#include <isode/usr.dirent.h>
extern char *mquedir;
extern char *aquedir;
extern char *tquedir;
extern char *quedfldir;
extern char *chndfldir;
extern CHAN *ch_nm2struct();
extern void rd_end(), sys_init(), err_abrt();
extern time_t time();
/* CHANGE LATER */
char *cmdname = "xtake_out_the_trash";
CHAN *mychan;
static struct type_Qmgr_DeliveryStatus *process ();
static int initialise ();
static void dirinit ();
/* \f
*/
/* main routine */
main (argc, argv)
int argc;
char **argv;
{
sys_init(argv[0]);
dirinit ();
#ifdef PP_DEBUG
if (argc>1 && (strcmp(argv[1],"debug") == 0))
debug_channel_control(argc,argv,initialise,process,NULLIFP);
else
#endif
channel_control (argc, argv, initialise, process, NULLIFP);
}
/* \f
*/
/* routine to move to correct place in file system */
static void dirinit ()
{
if (chdir (quedfldir) < 0)
err_abrt (RP_LIO, " Unable to change directory to '%s'",
quedfldir);
}
/* \f
*/
/* routine to initialise channel */
/* also does all the work */
char fullname[MAXPATHLEN];
char currentdir[MAXPATHLEN];
time_t interval,
current;
#define DEFAULT_INTERVAL (60*60*24*3) /* 3 days for normal files */
#define TMP_INTERVAL (60*60*24) /* 1 day for temp files */
int hasMsg(entry)
struct dirent *entry;
{
struct stat statbuf;
if ((strcmp(entry->d_name,".") == 0)
|| (strcmp(entry->d_name, "..") == 0))
return 0;
/* fullname */
(void) sprintf(fullname, "%s/%s", mquedir, entry->d_name);
if (stat(fullname, &statbuf) != OK)
PP_OPER(NULLCP,
("Addr file '%s' does not have a msg directory",
entry->d_name));
else if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
PP_OPER(NULLCP,
("Msg entry for '%s' is not a directory",
entry->d_name));
return 0;
}
int isDir(entry)
struct dirent *entry;
{
struct stat statbuf;
if ((strcmp(entry->d_name,".") == 0)
|| (strcmp(entry->d_name,"..") == 0))
return 0;
/* fullname */
(void) sprintf(fullname, "%s/%s", mquedir,entry->d_name);
if ((stat(fullname,&statbuf) == OK)
&& ((statbuf.st_mode & S_IFMT) == S_IFDIR))
/* directory */
return 1;
else
/* ignore */
return 0;
}
int isOld (entry)
struct dirent *entry;
{
struct stat statbuf;
if (strcmp (entry->d_name, ".") == 0 ||
strcmp (entry->d_name, "..") == 0)
return 0;
(void) sprintf (fullname, "%s/%s", tquedir, entry->d_name);
if (stat (fullname, &statbuf) == NOTOK)
return 0;
if (current - statbuf.st_mtime > TMP_INTERVAL) {
PP_NOTICE (("Removing temp message %s", entry->d_name));
currentdir[0] = 0;
if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
rec_rmdir (fullname);
else
if (unlink (fullname) == NOTOK)
PP_SLOG (LLOG_EXCEPTIONS, fullname,
("Can't unlink file"));
}
return 0;
}
static int initialise (arg)
struct type_Qmgr_Channel *arg;
{
char *name;
int num,
i;
struct dirent **namelist, **ix;
name = qb2str(arg);
if ((mychan = ch_nm2struct(name)) == NULLCHAN) {
PP_OPER(NULLCP,
("Channel '%s' not known",name));
if (name != NULL) free(name);
return NOTOK;
}
if (name != NULL) free(name);
interval = DEFAULT_INTERVAL;
(void) time(¤t);
num = _scandir(mquedir, &namelist, isDir, NULLIFP);
i = 0;
ix = namelist;
while ((i++ < num) && (*ix != 0)) {
if (check_addrfile((*ix)->d_name)!= OK)
/* addr file does not exist or has not been touched for a while */
/* try trash collection */
trashcollect((*ix)->d_name);
ix++;
}
free((char *)namelist);
/* now check for addr files with no msg directories */
num = _scandir(aquedir, &namelist, hasMsg, NULLIFP);
/* now check the tmp directory for junk */
num = _scandir (tquedir, &namelist, isOld, NULLIFP);
return OK;
}
int check_addrfile(name)
char *name;
{
struct stat statbuf;
struct prm_vars prm;
Q_struct que;
ADDR *sender = NULL;
ADDR *recips = NULL;
int rcount;
ADDR *ix = NULL;
bzero ((char *)&prm, sizeof(prm));
bzero ((char *)&que, sizeof(que));
(void) sprintf(fullname, "%s/%s", aquedir,name);
if (stat(fullname,&statbuf) != OK)
/* no addr file so try trash */
return NOTOK;
else {
if ((current - statbuf.st_mtime) > interval) {
/* check to see if all recipients are done */
if (rp_isbad(rd_msg(name,&prm,&que,&sender,&recips,&rcount))) {
PP_LOG(LLOG_EXCEPTIONS,
("rd_msg failure: '%s'", name));
/* don't delete */
return OK;
}
rd_end();
ix = que.Oaddress;
while ((ix != NULL) && (ix->ad_status == AD_STAT_DONE))
ix = ix->ad_next;
if (ix != NULL)
/* don't trash as some work needs to be done */
return OK;
/* now the recips */
ix = que.Raddress;
while ((ix != NULL) && (ix->ad_status == AD_STAT_DONE))
ix = ix->ad_next;
if (ix != NULL)
/* don't trash as some work needs to be done */
return OK;
return NOTOK;
}
}
return OK;
}
trashcollect(name)
char *name;
{
struct stat statbuf;
(void) sprintf(fullname, "%s/%s", mquedir,name);
if (stat(fullname,&statbuf) == OK) {
if ((current - statbuf.st_mtime) > interval) {
PP_NOTICE (("trash removing '%s'", name));
currentdir[0] = '\0';
rec_rmdir(fullname);
/* now remove addr file if there */
sprintf(fullname,"%s/%s", aquedir, name);
if (stat(fullname,&statbuf) == OK)
unlink(fullname);
}
}
}
int rmFiles(entry)
struct dirent *entry;
{
struct stat statbuf;
if ((strcmp(entry->d_name,".") == 0)
|| (strcmp(entry->d_name,"..") == 0))
return 0;
/* full name */
(void) sprintf(fullname,"%s/%s",currentdir,entry->d_name);
if ((stat(fullname,&statbuf) == OK)
&& ((statbuf.st_mode & S_IFMT) == S_IFDIR))
return 1;
else {
if (unlink(fullname) == NOTOK)
PP_SLOG(LLOG_EXCEPTIONS,fullname,("can't remove file"));
return 0;
}
}
/* recursive rmdir */
rec_rmdir(dir)
char *dir;
{
struct dirent **namelist, **ix;
int noOfSubdirs, i;
char *temp;
if (currentdir[0] == '\0')
strcpy(currentdir,dir);
else
(void) sprintf(currentdir,"%s/%s",currentdir,dir);
noOfSubdirs = _scandir(currentdir,&namelist, rmFiles, NULLIFP);
i = 0;
ix = namelist;
while ((i++ < noOfSubdirs) && (*ix != NULL)) {
rec_rmdir((*ix)->d_name);
ix++;
}
if (rmdir(currentdir) == NOTOK)
PP_SLOG(LLOG_EXCEPTIONS,currentdir,
("unable to remove directory"));
/* knock of one level of directories */
if ((temp = (char *) rindex(currentdir, '/')) != NULL)
*temp = '\0';
free((char *) namelist);
}
/* \f
*/
/* all work done in initialise */
/* process is just a dummy routine */
static struct type_Qmgr_DeliveryStatus *process (arg)
struct type_Qmgr_ProcMsg *arg;
{
delivery_init(arg->users);
delivery_setall(int_Qmgr_status_success);
return deliverystate;
}