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