DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦e5a0bd899⟧ TextFile

    Length: 6666 (0x1a0a)
    Types: TextFile
    Names: »msg-clean.c«

Derivation

└─⟦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« 

TextFile

/* 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;
}