htcacheclean.c revision 1018201f5223624476334c6e23aead02db7c4040
1e83c8de3aa48b316b28057d53995272baf1260cwrowe/* Licensed to the Apache Software Foundation (ASF) under one or more
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * contributor license agreements. See the NOTICE file distributed with
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * this work for additional information regarding copyright ownership.
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * The ASF licenses this file to You under the Apache License, Version 2.0
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * (the "License"); you may not use this file except in compliance with
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * the License. You may obtain a copy of the License at
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * Unless required by applicable law or agreed to in writing, software
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * distributed under the License is distributed on an "AS IS" BASIS,
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * See the License for the specific language governing permissions and
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * limitations under the License.
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * htcacheclean.c: simple program for cleaning of
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * the disk cache of the Apache HTTP server
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * Contributed by Andreas Steinmetz <ast domdv.de>
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * 8 Oct 2004
1e83c8de3aa48b316b28057d53995272baf1260cwrowe/* define the following for debugging */
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * Note: on Linux delays <= 2ms are busy waits without
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * scheduling, so never use a delay <= 2ms below
94b262d3639149df0b02642a9daa6db8bff58577wrowe#define DELETE_NICE 10 /* be nice after this amount of delete ops */
94b262d3639149df0b02642a9daa6db8bff58577wrowe#define STAT_ATTEMPTS 10 /* maximum stat attempts for a file */
1e83c8de3aa48b316b28057d53995272baf1260cwrowe#define DIRINFO (APR_FINFO_MTIME|APR_FINFO_SIZE|APR_FINFO_TYPE|APR_FINFO_LINK)
1e83c8de3aa48b316b28057d53995272baf1260cwrowetypedef struct _direntry {
1e83c8de3aa48b316b28057d53995272baf1260cwrowe int type; /* type of file/fileset: TEMP, HEADER, DATA, HEADERDATA */
1e83c8de3aa48b316b28057d53995272baf1260cwrowe apr_time_t htime; /* headers file modification time */
1e83c8de3aa48b316b28057d53995272baf1260cwrowetypedef struct _entry {
1e83c8de3aa48b316b28057d53995272baf1260cwrowe apr_time_t response_time; /* cache entry time of last response to client */
1e83c8de3aa48b316b28057d53995272baf1260cwrowe apr_time_t htime; /* headers file modification time */
94b262d3639149df0b02642a9daa6db8bff58577wrowestatic int delcount; /* file deletion count for nice mode */
94b262d3639149df0b02642a9daa6db8bff58577wrowestatic int interrupted; /* flag: true if SIGINT or SIGTERM occurred */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic int realclean; /* flag: true means user said apache is not running */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic int verbose; /* flag: true means print statistics */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic int benice; /* flag: true means nice mode is activated */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic int dryrun; /* flag: true means dry run, don't actually delete
1e83c8de3aa48b316b28057d53995272baf1260cwrowe anything */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic int deldirs; /* flag: true means directories should be deleted */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic int baselen; /* string length of the path to the proxy directory */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic apr_time_t now; /* start time of this processing run */
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic apr_off_t unsolicited; /* file size summary for deleted unsolicited
1e83c8de3aa48b316b28057d53995272baf1260cwrowestatic APR_RING_ENTRY(_entry) root; /* ENTRY ring anchor */
1e83c8de3aa48b316b28057d53995272baf1260cwrowe/* short program name as called */
1e83c8de3aa48b316b28057d53995272baf1260cwrowe * fake delete for debug purposes
#ifdef DEBUG
static int called = 0;
if (!called) {
return APR_ENOMEM;
if (!verbose) {
if (unsolicited) {
char *nextpath;
apr_pool_t *p;
if (dryrun) {
apr_pool_destroy(p);
if (benice) {
delcount = 0;
char *nextpath;
apr_pool_t *p;
if (dryrun) {
apr_pool_destroy(p);
if (benice) {
delcount = 0;
apr_pool_t *p;
apr_hash_t *h;
apr_hash_index_t *i;
DIRENTRY *d, *t, *n;
ENTRY *e;
h = apr_hash_make(p);
skip = 0;
if (interrupted) {
if (!base++) {
if (!ext) {
if (interrupted) {
void *hvalue;
d = hvalue;
switch(d->type) {
case HEADERDATA:
case HEADER:
case DATA:
case TEMP:
if (interrupted) {
apr_pool_destroy(p);
if (benice) {
if (interrupted) {
sum = 0;
entries = 0;
entries++;
entries--;
if (!interrupted) {
if (interrupted) {
entries--;
if (!interrupted) {
if (interrupted) {
oldest = e;
entries--;
if (!interrupted) {
if (error) {
apr_getopt_t *o;
char opt;
const char *arg;
interrupted = 0;
repeat = 0;
isdaemon = 0;
dryrun = 0;
limit_found = 0;
max = 0;
verbose = 0;
realclean = 0;
benice = 0;
deldirs = 0;
intelligent = 0;
if (argc) {
switch (opt) {
if (intelligent) {
if (dryrun) {
if (benice) {
if (deldirs) {
if (verbose) {
if (realclean) {
if (isdaemon) {
if (limit_found) {
char *end;
if (proxypath) {
if (!proxypath) {
if (max <= 0) {
#ifndef DEBUG
if (isdaemon) {
delcount = 0;
unsolicited = 0;
dowork = 0;
switch (intelligent) {
if (isdaemon) {
delay = 0;