|
|
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 m
Length: 6666 (0x1a0a)
Types: TextFile
Names: »msg-clean.c«
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
└─⟦dc59850a2⟧ »EurOpenD22/pp5.0/pp-5.tar.Z«
└─⟦e5a54fb17⟧
└─⟦this⟧ »pp-5.0/Chans/msg-clean/msg-clean.c«
/* msg_clean.c: message cleanout channel */
# ifndef lint
static char Rcsid[] = "@(#)$Header: /cs/research/pp/hubris/pp-beta/Chans/msg-clean/RCS/msg-clean.c,v 5.0 90/09/20 15:49:07 pp Exp Locker: pp $";
# endif
/*
* $Header: /cs/research/pp/hubris/pp-beta/Chans/msg-clean/RCS/msg-clean.c,v 5.0 90/09/20 15:49:07 pp Exp Locker: pp $
*
* $Log: msg-clean.c,v $
* Revision 5.0 90/09/20 15:49:07 pp
* rcsforce : 5.0 public release
*
*/
#include "util.h"
#include "head.h"
#include "qmgr.h"
#include "q.h"
#include "prm.h"
#include <isode/usr.dirent.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/file.h>
extern char *mquedir;
extern char *quedfldir;
extern char *chndfldir;
extern CHAN *ch_nm2struct();
extern void getfpath(), rd_end(), sys_init(), err_abrt();
/* CHANGE LATER */
CHAN *mychan;
char currentdir[MAXPATHLEN];
char fullname[MAXPATHLEN];
static struct type_Qmgr_DeliveryStatus *process ();
static int initialise ();
static int security_check ();
static struct type_Qmgr_DeliveryStatus *new_DeliveryStatus();
static void dirinit ();
int error;
/* \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
*/
/* channel initialise routine */
static int initialise (arg)
struct type_Qmgr_Channel *arg;
{
char *name;
name = qb2str(arg);
if ((mychan = ch_nm2struct(name)) == NULLCHAN) {
PP_OPER(NULLCP,
("Channel '%s' not known",name));
if (name != NULL) free(name);
return NOTOK;
}
/* check if a cleanout channel */
if (name != NULL) free(name);
return OK;
}
/* \f
*/
/* routine called to do clean out */
static struct type_Qmgr_DeliveryStatus *process (arg)
struct type_Qmgr_ProcMsg *arg;
{
char *this_msg = NULL,
addrfile[FILNSIZE],
msgfile[FILNSIZE];
struct stat statbuf;
extern char *quedfldir;
extern char *aquedir;
extern char *mquedir;
delivery_init(arg->users);
delivery_setall(int_Qmgr_status_messageFailure);
if (security_check(arg) != TRUE)
return deliverystate;
/* ok-you asked for it-remove message */
this_msg = qb2str (arg->qid);
PP_LOG(LLOG_NOTICE,
("Cleaning out msg %s", this_msg));
(void) sprintf(addrfile, "%s/%s",aquedir,this_msg);
(void) sprintf(msgfile, "%s/%s",mquedir, this_msg);
currentdir[0] = '\0';
error = FALSE;
rec_rmdir(msgfile);
if (error == FALSE && stat(addrfile, &statbuf) == OK) {
unlink(addrfile);
}
if (this_msg != NULL) free(this_msg);
/* create return values */
if (error == FALSE)
delivery_setall(int_Qmgr_status_success);
return deliverystate;
}
int printFiles(entry)
struct dirent *entry;
{
PP_TRACE(("'%s' still in directory",entry->d_name));
return 0;
}
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"));
error = TRUE;
}
PP_TRACE(("Removed '%s'", fullname));
return 0;
}
}
/* recursive rmdir */
rec_rmdir(dir)
char *dir;
{
struct dirent **namelist, **ix;
int noOfSubdirs, i;
char *temp;
struct stat statbuf;
if (currentdir[0] == '\0')
strcpy(currentdir,dir);
else
(void) sprintf(currentdir,"%s/%s",currentdir,dir);
if (stat(currentdir,&statbuf) != OK)
/* does not exist */
return;
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"));
_scandir(currentdir, &namelist, printFiles, NULLCP);
error = TRUE;
} else
PP_TRACE(("Removed directory '%s'", currentdir));
/* knock of one level of directories */
if ((temp = (char *) rindex(currentdir, '/')) != NULL) {
while (*temp == '/')
*temp -- = '\0';
}
if (namelist) free((char *) namelist);
}
/* \f
*/
/* routine to check if allowed to remove this message */
static int security_check (msg)
struct type_Qmgr_ProcMsg *msg;
{
char *msg_file = NULL, *msg_chan = NULL;
struct prm_vars prm;
Q_struct que;
ADDR *sender = NULL;
ADDR *recips = NULL;
int rcount,
result;
ADDR *ix = NULL;
char real_aquedir[FILNSIZE],
msgname[FILNSIZE];
struct stat statbuf;
extern char *quedfldir,
*aquedir;
prm_init (&prm);
q_init (&que);
result = TRUE;
msg_file = qb2str (msg->qid);
msg_chan = qb2str (msg->channel);
if ((mychan == NULLCHAN) || (strcmp(msg_chan,mychan->ch_name) != 0)) {
PP_LOG(LLOG_EXCEPTIONS,
("Wrong channel name '%s'",msg_chan));
result = FALSE;
}
getfpath (quedfldir, aquedir, real_aquedir);
getfpath (real_aquedir, msg_file, msgname);
if (stat(msgname, &statbuf) != OK) {
/* does not exist so effectively removed */
if (msg_file != NULL) free(msg_file);
if (msg_chan != NULL) free(msg_chan);
return TRUE;
}
if ((result == TRUE)
&& (rp_isbad(rd_msg(msg_file,&prm,&que,&sender,&recips,&rcount)))) {
PP_LOG(LLOG_EXCEPTIONS,
("Can't read message '%s'",msg_file));
result = FALSE;
}
/* unlock file */
rd_end();
if (result == TRUE) {
/* now check message is valid for removing */
/* first the senders (if you can have more than one) */
ix = que.Oaddress;
while ((ix != NULL) && (ix->ad_status == AD_STAT_DONE))
ix = ix->ad_next;
if (ix != NULL) {
PP_LOG(LLOG_EXCEPTIONS,
("bad sender status for '%s'", msg_file));
result = FALSE;
}
}
/* now the recips */
if (result == TRUE) {
ix = que.Raddress;
while ((ix != NULL) && (ix->ad_status == AD_STAT_DONE))
ix = ix->ad_next;
if (ix != NULL) {
PP_LOG(LLOG_EXCEPTIONS,
("recipient %d status not DONE: '%s'",
ix->ad_no,msg_file));
result = FALSE;
}
}
/* free all storage used */
if (msg_file != NULL) free(msg_file);
if (msg_chan != NULL) free(msg_chan);
q_free (&que);
return result;
}