This is cls.c in view mode; [Download] [Up]
#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;
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.