|
Packit |
90a5c9 |
/* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
Packit |
90a5c9 |
* contributor license agreements. See the NOTICE file distributed with
|
|
Packit |
90a5c9 |
* this work for additional information regarding copyright ownership.
|
|
Packit |
90a5c9 |
* The ASF licenses this file to You under the Apache License, Version 2.0
|
|
Packit |
90a5c9 |
* (the "License"); you may not use this file except in compliance with
|
|
Packit |
90a5c9 |
* the License. You may obtain a copy of the License at
|
|
Packit |
90a5c9 |
*
|
|
Packit |
90a5c9 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
90a5c9 |
*
|
|
Packit |
90a5c9 |
* Unless required by applicable law or agreed to in writing, software
|
|
Packit |
90a5c9 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
90a5c9 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
90a5c9 |
* See the License for the specific language governing permissions and
|
|
Packit |
90a5c9 |
* limitations under the License.
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
#include <ctype.h>
|
|
Packit |
90a5c9 |
#include <dirent.h>
|
|
Packit |
90a5c9 |
#include <stdio.h>
|
|
Packit |
90a5c9 |
#include <string.h>
|
|
Packit |
90a5c9 |
#include <time.h>
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* Compare a string to a mask
|
|
Packit |
90a5c9 |
* Mask characters:
|
|
Packit |
90a5c9 |
* @ - uppercase letter
|
|
Packit |
90a5c9 |
* # - lowercase letter
|
|
Packit |
90a5c9 |
* & - hex digit
|
|
Packit |
90a5c9 |
* # - digit
|
|
Packit |
90a5c9 |
* * - swallow remaining characters
|
|
Packit |
90a5c9 |
* <x> - exact match for any other character
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
static int checkmask(const char *data, const char *mask)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
int i, ch, d;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
for (i = 0; mask[i] != '\0' && mask[i] != '*'; i++) {
|
|
Packit |
90a5c9 |
ch = mask[i];
|
|
Packit |
90a5c9 |
d = data[i];
|
|
Packit |
90a5c9 |
if (ch == '@') {
|
|
Packit |
90a5c9 |
if (!isupper(d))
|
|
Packit |
90a5c9 |
return 0;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else if (ch == '$') {
|
|
Packit |
90a5c9 |
if (!islower(d))
|
|
Packit |
90a5c9 |
return 0;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else if (ch == '#') {
|
|
Packit |
90a5c9 |
if (!isdigit(d))
|
|
Packit |
90a5c9 |
return 0;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else if (ch == '&') {
|
|
Packit |
90a5c9 |
if (!isxdigit(d))
|
|
Packit |
90a5c9 |
return 0;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else if (ch != d)
|
|
Packit |
90a5c9 |
return 0;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (mask[i] == '*')
|
|
Packit |
90a5c9 |
return 1;
|
|
Packit |
90a5c9 |
else
|
|
Packit |
90a5c9 |
return (data[i] == '\0');
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
/*
|
|
Packit |
90a5c9 |
* Converts 8 hex digits to a time integer
|
|
Packit |
90a5c9 |
*/
|
|
Packit |
90a5c9 |
static int hex2sec(const char *x)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
int i, ch;
|
|
Packit |
90a5c9 |
unsigned int j;
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
for (i = 0, j = 0; i < 8; i++) {
|
|
Packit |
90a5c9 |
ch = x[i];
|
|
Packit |
90a5c9 |
j <<= 4;
|
|
Packit |
90a5c9 |
if (isdigit(ch))
|
|
Packit |
90a5c9 |
j |= ch - '0';
|
|
Packit |
90a5c9 |
else if (isupper(ch))
|
|
Packit |
90a5c9 |
j |= ch - ('A' - 10);
|
|
Packit |
90a5c9 |
else
|
|
Packit |
90a5c9 |
j |= ch - ('a' - 10);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
if (j == 0xffffffff)
|
|
Packit |
90a5c9 |
return -1; /* so that it works with 8-byte ints */
|
|
Packit |
90a5c9 |
else
|
|
Packit |
90a5c9 |
return j;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
int main(int argc, char **argv)
|
|
Packit |
90a5c9 |
{
|
|
Packit |
90a5c9 |
int i, ver;
|
|
Packit |
90a5c9 |
DIR *d;
|
|
Packit |
90a5c9 |
struct dirent *e;
|
|
Packit |
90a5c9 |
const char *s;
|
|
Packit |
90a5c9 |
FILE *fp;
|
|
Packit |
90a5c9 |
char path[FILENAME_MAX + 1];
|
|
Packit |
90a5c9 |
char line[1035];
|
|
Packit |
90a5c9 |
time_t date, lmod, expire;
|
|
Packit |
90a5c9 |
unsigned int len;
|
|
Packit |
90a5c9 |
struct tm ts;
|
|
Packit |
90a5c9 |
char sdate[30], slmod[30], sexpire[30];
|
|
Packit |
90a5c9 |
const char time_format[] = "%e %b %Y %R";
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (argc != 2) {
|
|
Packit |
90a5c9 |
printf("Usage: cls directory\n");
|
|
Packit |
90a5c9 |
exit(0);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
d = opendir(argv[1]);
|
|
Packit |
90a5c9 |
if (d == NULL) {
|
|
Packit |
90a5c9 |
perror("opendir");
|
|
Packit |
90a5c9 |
exit(1);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
for (;;) {
|
|
Packit |
90a5c9 |
e = readdir(d);
|
|
Packit |
90a5c9 |
if (e == NULL)
|
|
Packit |
90a5c9 |
break;
|
|
Packit |
90a5c9 |
s = e->d_name;
|
|
Packit |
90a5c9 |
if (s[0] == '.' || s[0] == '#')
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
sprintf(path, "%s/%s", argv[1], s);
|
|
Packit |
90a5c9 |
fp = fopen(path, "r");
|
|
Packit |
90a5c9 |
if (fp == NULL) {
|
|
Packit |
90a5c9 |
perror("fopen");
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
if (fgets(line, 1034, fp) == NULL) {
|
|
Packit |
90a5c9 |
perror("fgets");
|
|
Packit |
90a5c9 |
fclose(fp);
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
if (!checkmask(line, "&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&\n")) {
|
|
Packit |
90a5c9 |
fprintf(stderr, "Bad cache file\n");
|
|
Packit |
90a5c9 |
fclose(fp);
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
date = hex2sec(line);
|
|
Packit |
90a5c9 |
lmod = hex2sec(line + 9);
|
|
Packit |
90a5c9 |
expire = hex2sec(line + 18);
|
|
Packit |
90a5c9 |
ver = hex2sec(line + 27);
|
|
Packit |
90a5c9 |
len = hex2sec(line + 35);
|
|
Packit |
90a5c9 |
if (fgets(line, 1034, fp) == NULL) {
|
|
Packit |
90a5c9 |
perror("fgets");
|
|
Packit |
90a5c9 |
fclose(fp);
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
fclose(fp);
|
|
Packit |
90a5c9 |
i = strlen(line);
|
|
Packit |
90a5c9 |
if (strncmp(line, "X-URL: ", 7) != 0 || line[i - 1] != '\n') {
|
|
Packit |
90a5c9 |
fprintf(stderr, "Bad cache file\n");
|
|
Packit |
90a5c9 |
continue;
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
line[i - 1] = '\0';
|
|
Packit |
90a5c9 |
if (date != -1) {
|
|
Packit |
90a5c9 |
ts = *gmtime(&date);
|
|
Packit |
90a5c9 |
strftime(sdate, 30, time_format, &ts);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else
|
|
Packit |
90a5c9 |
strcpy(sdate, "-");
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (lmod != -1) {
|
|
Packit |
90a5c9 |
ts = *gmtime(&lmod;;
|
|
Packit |
90a5c9 |
strftime(slmod, 30, time_format, &ts);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else
|
|
Packit |
90a5c9 |
strcpy(slmod, "-");
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
if (expire != -1) {
|
|
Packit |
90a5c9 |
ts = *gmtime(&expire);
|
|
Packit |
90a5c9 |
strftime(sexpire, 30, time_format, &ts);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
else
|
|
Packit |
90a5c9 |
strcpy(sexpire, "-");
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
printf("%s: %d; %s %s %s\n", line + 7, ver, sdate, slmod, sexpire);
|
|
Packit |
90a5c9 |
}
|
|
Packit |
90a5c9 |
|
|
Packit |
90a5c9 |
closedir(d);
|
|
Packit |
90a5c9 |
return 0;
|
|
Packit |
90a5c9 |
}
|