summaryrefslogtreecommitdiffstats
path: root/test/cls.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 02:04:06 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-07 02:04:06 +0000
commit5dff2d61cc1c27747ee398e04d8e02843aabb1f8 (patch)
treea67c336b406c8227bac912beb74a1ad3cdc55100 /test/cls.c
parentInitial commit. (diff)
downloadapache2-5dff2d61cc1c27747ee398e04d8e02843aabb1f8.tar.xz
apache2-5dff2d61cc1c27747ee398e04d8e02843aabb1f8.zip
Adding upstream version 2.4.38.upstream/2.4.38upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r--test/cls.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/test/cls.c b/test/cls.c
new file mode 100644
index 0000000..1ee6ac7
--- /dev/null
+++ b/test/cls.c
@@ -0,0 +1,182 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <ctype.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+
+/*
+ * Compare a string to a mask
+ * Mask characters:
+ * @ - uppercase letter
+ * # - lowercase letter
+ * & - hex digit
+ * # - digit
+ * * - swallow remaining characters
+ * <x> - exact match for any other character
+ */
+static int checkmask(const char *data, const char *mask)
+{
+ int i, ch, d;
+
+ for (i = 0; mask[i] != '\0' && mask[i] != '*'; i++) {
+ ch = mask[i];
+ d = data[i];
+ if (ch == '@') {
+ if (!isupper(d))
+ return 0;
+ }
+ else if (ch == '$') {
+ if (!islower(d))
+ return 0;
+ }
+ else if (ch == '#') {
+ if (!isdigit(d))
+ return 0;
+ }
+ else if (ch == '&') {
+ if (!isxdigit(d))
+ return 0;
+ }
+ else if (ch != d)
+ return 0;
+ }
+
+ if (mask[i] == '*')
+ return 1;
+ else
+ return (data[i] == '\0');
+}
+
+/*
+ * Converts 8 hex digits to a time integer
+ */
+static int hex2sec(const char *x)
+{
+ int i, ch;
+ unsigned int j;
+
+ for (i = 0, j = 0; i < 8; i++) {
+ ch = x[i];
+ j <<= 4;
+ if (isdigit(ch))
+ j |= ch - '0';
+ else if (isupper(ch))
+ j |= ch - ('A' - 10);
+ else
+ j |= ch - ('a' - 10);
+ }
+ if (j == 0xffffffff)
+ return -1; /* so that it works with 8-byte ints */
+ else
+ return j;
+}
+
+int main(int argc, char **argv)
+{
+ int i, ver;
+ DIR *d;
+ struct dirent *e;
+ const char *s;
+ FILE *fp;
+ char path[FILENAME_MAX + 1];
+ char line[1035];
+ time_t date, lmod, expire;
+ unsigned int len;
+ struct tm ts;
+ char sdate[30], slmod[30], sexpire[30];
+ const char time_format[] = "%e %b %Y %R";
+
+ if (argc != 2) {
+ printf("Usage: cls directory\n");
+ exit(0);
+ }
+
+ d = opendir(argv[1]);
+ if (d == NULL) {
+ perror("opendir");
+ exit(1);
+ }
+
+ for (;;) {
+ e = readdir(d);
+ if (e == NULL)
+ break;
+ s = e->d_name;
+ if (s[0] == '.' || s[0] == '#')
+ continue;
+ sprintf(path, "%s/%s", argv[1], s);
+ fp = fopen(path, "r");
+ if (fp == NULL) {
+ perror("fopen");
+ continue;
+ }
+ if (fgets(line, 1034, fp) == NULL) {
+ perror("fgets");
+ fclose(fp);
+ continue;
+ }
+ if (!checkmask(line, "&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&\n")) {
+ fprintf(stderr, "Bad cache file\n");
+ fclose(fp);
+ continue;
+ }
+ date = hex2sec(line);
+ lmod = hex2sec(line + 9);
+ expire = hex2sec(line + 18);
+ ver = hex2sec(line + 27);
+ len = hex2sec(line + 35);
+ if (fgets(line, 1034, fp) == NULL) {
+ perror("fgets");
+ fclose(fp);
+ continue;
+ }
+ fclose(fp);
+ i = strlen(line);
+ if (strncmp(line, "X-URL: ", 7) != 0 || line[i - 1] != '\n') {
+ fprintf(stderr, "Bad cache file\n");
+ continue;
+ }
+ line[i - 1] = '\0';
+ if (date != -1) {
+ ts = *gmtime(&date);
+ strftime(sdate, 30, time_format, &ts);
+ }
+ else
+ strcpy(sdate, "-");
+
+ if (lmod != -1) {
+ ts = *gmtime(&lmod);
+ strftime(slmod, 30, time_format, &ts);
+ }
+ else
+ strcpy(slmod, "-");
+
+ if (expire != -1) {
+ ts = *gmtime(&expire);
+ strftime(sexpire, 30, time_format, &ts);
+ }
+ else
+ strcpy(sexpire, "-");
+
+ printf("%s: %d; %s %s %s\n", line + 7, ver, sdate, slmod, sexpire);
+ }
+
+ closedir(d);
+ return 0;
+}