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