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