]> granicus.if.org Git - apache/blob - test/cls.c
mod_proxy: Fix ProxyRemoteMatch directive.
[apache] / test / cls.c
1 /* Copyright 1999-2004 The Apache Software Foundation
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <ctype.h>
17 #include <dirent.h>
18 #include <stdio.h>
19 #include <string.h>
20 #include <time.h>
21
22 /*
23  * Compare a string to a mask
24  * Mask characters:
25  *   @ - uppercase letter
26  *   # - lowercase letter
27  *   & - hex digit
28  *   # - digit
29  *   * - swallow remaining characters 
30  *  <x> - exact match for any other character
31  */
32 static int checkmask(const char *data, const char *mask)
33 {
34     int i, ch, d;
35
36     for (i = 0; mask[i] != '\0' && mask[i] != '*'; i++) {
37         ch = mask[i];
38         d = data[i];
39         if (ch == '@') {
40             if (!isupper(d))
41                 return 0;
42         }
43         else if (ch == '$') {
44             if (!islower(d))
45                 return 0;
46         }
47         else if (ch == '#') {
48             if (!isdigit(d))
49                 return 0;
50         }
51         else if (ch == '&') {
52             if (!isxdigit(d))
53                 return 0;
54         }
55         else if (ch != d)
56             return 0;
57     }
58
59     if (mask[i] == '*')
60         return 1;
61     else
62         return (data[i] == '\0');
63 }
64
65 /*
66  * Converts 8 hex digits to a time integer
67  */
68 static int hex2sec(const char *x)
69 {
70     int i, ch;
71     unsigned int j;
72
73     for (i = 0, j = 0; i < 8; i++) {
74         ch = x[i];
75         j <<= 4;
76         if (isdigit(ch))
77             j |= ch - '0';
78         else if (isupper(ch))
79             j |= ch - ('A' - 10);
80         else
81             j |= ch - ('a' - 10);
82     }
83     if (j == 0xffffffff)
84         return -1;              /* so that it works with 8-byte ints */
85     else
86         return j;
87 }
88
89 int main(int argc, char **argv)
90 {
91     int i, ver;
92     DIR *d;
93     struct dirent *e;
94     const char *s;
95     FILE *fp;
96     char path[FILENAME_MAX + 1];
97     char line[1035];
98     time_t date, lmod, expire;
99     unsigned int len;
100     struct tm ts;
101     char sdate[30], slmod[30], sexpire[30];
102     const char time_format[] = "%e %b %Y %R";
103
104     if (argc != 2) {
105         printf("Usage: cls directory\n");
106         exit(0);
107     }
108
109     d = opendir(argv[1]);
110     if (d == NULL) {
111         perror("opendir");
112         exit(1);
113     }
114
115     for (;;) {
116         e = readdir(d);
117         if (e == NULL)
118             break;
119         s = e->d_name;
120         if (s[0] == '.' || s[0] == '#')
121             continue;
122         sprintf(path, "%s/%s", argv[1], s);
123         fp = fopen(path, "r");
124         if (fp == NULL) {
125             perror("fopen");
126             continue;
127         }
128         if (fgets(line, 1034, fp) == NULL) {
129             perror("fgets");
130             fclose(fp);
131             continue;
132         }
133         if (!checkmask(line, "&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&\n")) {
134             fprintf(stderr, "Bad cache file\n");
135             fclose(fp);
136             continue;
137         }
138         date = hex2sec(line);
139         lmod = hex2sec(line + 9);
140         expire = hex2sec(line + 18);
141         ver = hex2sec(line + 27);
142         len = hex2sec(line + 35);
143         if (fgets(line, 1034, fp) == NULL) {
144             perror("fgets");
145             fclose(fp);
146             continue;
147         }
148         fclose(fp);
149         i = strlen(line);
150         if (strncmp(line, "X-URL: ", 7) != 0 || line[i - 1] != '\n') {
151             fprintf(stderr, "Bad cache file\n");
152             continue;
153         }
154         line[i - 1] = '\0';
155         if (date != -1) {
156             ts = *gmtime(&date);
157             strftime(sdate, 30, time_format, &ts);
158         }
159         else
160             strcpy(sdate, "-");
161
162         if (lmod != -1) {
163             ts = *gmtime(&lmod);
164             strftime(slmod, 30, time_format, &ts);
165         }
166         else
167             strcpy(slmod, "-");
168
169         if (expire != -1) {
170             ts = *gmtime(&expire);
171             strftime(sexpire, 30, time_format, &ts);
172         }
173         else
174             strcpy(sexpire, "-");
175
176         printf("%s: %d; %s  %s  %s\n", line + 7, ver, sdate, slmod, sexpire);
177     }
178
179     closedir(d);
180     return 0;
181 }