X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=support%2Fhtcacheclean.c;h=43d5117dd2f021916e592b32c50fe0e9d468f428;hb=55f3e480134c1b9d79285e3976132eda08ea787a;hp=e2d73caf64464eca6e957e5dd54ccbf1e3129e23;hpb=4fdaeae371cbd93cbe6746eeeb0386e2ed38fc04;p=apache diff --git a/support/htcacheclean.c b/support/htcacheclean.c index e2d73caf64..43d5117dd2 100644 --- a/support/htcacheclean.c +++ b/support/htcacheclean.c @@ -342,7 +342,7 @@ static int process_dir(char *path, apr_pool_t *pool) } } - /* this may look strange but apr_stat() may return errno which + /* this may look strange but apr_stat() may return an error which * is system dependent and there may be transient failures, * so just blindly retry for a short while */ @@ -474,9 +474,7 @@ static int process_dir(char *path, apr_pool_t *pool) e->dtime = d->dtime; e->hsize = d->hsize; e->dsize = d->dsize; - e->basename = apr_palloc(pool, - strlen(d->basename) + 1); - strcpy(e->basename, d->basename); + e->basename = apr_pstrdup(pool, d->basename); break; } else { @@ -491,6 +489,7 @@ static int process_dir(char *path, apr_pool_t *pool) apr_file_remove(apr_pstrcat(p, path, "/", d->basename, CACHE_DATA_SUFFIX, NULL), p); + break; } } else { @@ -534,14 +533,16 @@ static int process_dir(char *path, apr_pool_t *pool) len = sizeof(expires); - apr_file_read_full(fd, &expires, len, &len); + if (apr_file_read_full(fd, &expires, len, + &len) == APR_SUCCESS) { - apr_file_close(fd); + apr_file_close(fd); - if (expires < current) { - delete_entry(path, d->basename, p); + if (expires < current) { + delete_entry(path, d->basename, p); + } + break; } - break; } } apr_file_close(fd); @@ -700,12 +701,15 @@ static void purge(char *path, apr_pool_t *pool, apr_off_t max) * usage info */ #define NL APR_EOL_STR -static void usage(void) +static void usage(const char *error) { + if (error) { + apr_file_printf(errfile, "%s error: %s\n", shortname, error); + } apr_file_printf(errfile, "%s -- program for cleaning the disk cache." NL - "Usage: %s [-Dvtrn] -pPATH -lLIMIT" NL - " %s [-nti] -dINTERVAL -pPATH -lLIMIT" NL + "Usage: %s [-Dvtrn] -pPATH -lLIMIT [-PPIDFILE]" NL + " %s [-nti] -dINTERVAL -pPATH -lLIMIT [-PPIDFILE]" NL NL "Options:" NL " -d Daemonize and repeat cache cleaning every INTERVAL minutes." NL @@ -731,6 +735,8 @@ static void usage(void) NL " -p Specify PATH as the root directory of the disk cache." NL NL + " -P Specify PIDFILE as the file to write the pid to." NL + NL " -l Specify LIMIT as the total disk cache size limit. Attach 'K'" NL " or 'M' to the number for specifying KBytes or MBytes." NL NL @@ -746,6 +752,12 @@ static void usage(void) } #undef NL +static void usage_repeated_arg(apr_pool_t *pool, char option) { + usage(apr_psprintf(pool, + "The option '%c' cannot be specified more than once", + option)); +} + /* * main */ @@ -760,7 +772,8 @@ int main(int argc, const char * const argv[]) int retries, isdaemon, limit_found, intelligent, dowork; char opt; const char *arg; - char *proxypath, *path; + char *proxypath, *path, *pidfile; + char errmsg[1024]; interrupted = 0; repeat = 0; @@ -775,6 +788,7 @@ int main(int argc, const char * const argv[]) intelligent = 0; previous = 0; /* avoid compiler warning */ proxypath = NULL; + pidfile = NULL; if (apr_app_initialize(&argc, &argv, NULL) != APR_SUCCESS) { return 1; @@ -796,53 +810,53 @@ int main(int argc, const char * const argv[]) apr_getopt_init(&o, pool, argc, argv); while (1) { - status = apr_getopt(o, "iDnvrtd:l:L:p:", &opt, &arg); + status = apr_getopt(o, "iDnvrtd:l:L:p:P:", &opt, &arg); if (status == APR_EOF) { break; } else if (status != APR_SUCCESS) { - usage(); + usage(NULL); } else { switch (opt) { case 'i': if (intelligent) { - usage(); + usage_repeated_arg(pool, opt); } intelligent = 1; break; case 'D': if (dryrun) { - usage(); + usage_repeated_arg(pool, opt); } dryrun = 1; break; case 'n': if (benice) { - usage(); + usage_repeated_arg(pool, opt); } benice = 1; break; case 't': if (deldirs) { - usage(); + usage_repeated_arg(pool, opt); } deldirs = 1; break; case 'v': if (verbose) { - usage(); + usage_repeated_arg(pool, opt); } verbose = 1; break; case 'r': if (realclean) { - usage(); + usage_repeated_arg(pool, opt); } realclean = 1; deldirs = 1; @@ -850,7 +864,7 @@ int main(int argc, const char * const argv[]) case 'd': if (isdaemon) { - usage(); + usage_repeated_arg(pool, opt); } isdaemon = 1; repeat = apr_atoi64(arg); @@ -860,7 +874,7 @@ int main(int argc, const char * const argv[]) case 'l': if (limit_found) { - usage(); + usage_repeated_arg(pool, opt); } limit_found = 1; @@ -885,44 +899,65 @@ int main(int argc, const char * const argv[]) } } if (rv != APR_SUCCESS) { - apr_file_printf(errfile, "Invalid limit: %s" - APR_EOL_STR APR_EOL_STR, arg); - usage(); + usage(apr_psprintf(pool, "Invalid limit: %s" + APR_EOL_STR APR_EOL_STR, arg)); } } while(0); break; case 'p': if (proxypath) { - usage(); + usage_repeated_arg(pool, opt); } proxypath = apr_pstrdup(pool, arg); - if (apr_filepath_set(proxypath, pool) != APR_SUCCESS) { - usage(); + if ((status = apr_filepath_set(proxypath, pool)) != APR_SUCCESS) { + usage(apr_psprintf(pool, "Could not set filepath to '%s': %s", + proxypath, apr_strerror(status, errmsg, sizeof errmsg))); + } + break; + + case 'P': + if (pidfile) { + usage_repeated_arg(pool, opt); } + pidfile = apr_pstrdup(pool, arg); break; + } /* switch */ } /* else */ } /* while */ + if (argc <= 1) { + usage(NULL); + } + if (o->ind != argc) { - usage(); + usage("Additional parameters specified on the command line, aborting"); + } + + if (isdaemon && repeat <= 0) { + usage("Option -d must be greater than zero"); } - if (isdaemon && (repeat <= 0 || verbose || realclean || dryrun)) { - usage(); + if (isdaemon && (verbose || realclean || dryrun)) { + usage("Option -d cannot be used with -v, -r or -D"); } if (!isdaemon && intelligent) { - usage(); + usage("Option -i cannot be used without -d"); } - if (!proxypath || max <= 0) { - usage(); + if (!proxypath) { + usage("Option -p must be specified"); + } + + if (max <= 0) { + usage("Option -l must be greater than zero"); } if (apr_filepath_get(&path, 0, pool) != APR_SUCCESS) { - usage(); + usage(apr_psprintf(pool, "Could not get the filepath: %s", + apr_strerror(status, errmsg, sizeof errmsg))); } baselen = strlen(path); @@ -933,6 +968,21 @@ int main(int argc, const char * const argv[]) } #endif + if (pidfile) { + apr_file_t *file; + pid_t mypid = getpid(); + if (APR_SUCCESS == (status = apr_file_open(&file, pidfile, APR_WRITE + | APR_CREATE | APR_TRUNCATE | APR_DELONCLOSE, + APR_UREAD | APR_UWRITE | APR_GREAD, pool))) { + apr_file_printf(file, "%" APR_PID_T_FMT APR_EOL_STR, mypid); + } + else if (!isdaemon) { + apr_file_printf(errfile, + "Could not write the pid file '%s': %s" APR_EOL_STR, + pidfile, apr_strerror(status, errmsg, sizeof errmsg)); + } + } + do { apr_pool_create(&instance, pool);