Blame test/cls.c

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
}