mirror of https://github.com/leahneukirchen/mblaze
various code that may end up as a mail client
commit
30f0686fb2
@ -0,0 +1,373 @@
|
||||
// memmem
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
|
||||
// WSP = SP / HTAB
|
||||
#define iswsp(c) (((c) == ' ' || (c) == '\t'))
|
||||
|
||||
#define bufsiz 4096
|
||||
|
||||
static long
|
||||
parse_posint(char **s, size_t minn, size_t maxn)
|
||||
{
|
||||
long n;
|
||||
char *end;
|
||||
|
||||
errno = 0;
|
||||
n = strtol(*s, &end, 10);
|
||||
if (errno) {
|
||||
// perror("strtol");
|
||||
return -1;
|
||||
}
|
||||
if (n < (long)minn || n > (long)maxn) {
|
||||
// fprintf(stderr, "number outside %zd <= n < %zd\n", minn, maxn);
|
||||
return -1;
|
||||
}
|
||||
*s = end;
|
||||
return n;
|
||||
}
|
||||
|
||||
time_t
|
||||
parse_date(char *s) {
|
||||
struct tm tm;
|
||||
int c;
|
||||
|
||||
#if 0
|
||||
#define i4(m) (s[0] && (s[0]|0x20) == m[0] && \
|
||||
s[1] && (s[1]|0x20) == m[1] && \
|
||||
s[2] && (s[2]|0x20) == m[2] && \
|
||||
s[3] && (s[3]|0x20) == m[3] && (s = s+4) )
|
||||
|
||||
#define i3(m) (s[0] && (s[0]|0x20) == m[0] && \
|
||||
s[1] && (s[1]|0x20) == m[1] && \
|
||||
s[2] && (s[2]|0x20) == m[2] && (s = s+3) )
|
||||
#endif
|
||||
|
||||
#define i4(m) (((uint32_t) m[0]<<24 | m[1]<<16 | m[2]<<8 | m[3]) == \
|
||||
((uint32_t) s[0]<<24 | s[1]<<16 | s[2]<<8 | s[3] | 0x20202020) \
|
||||
&& (s += 4))
|
||||
|
||||
#define i3(m) (((uint32_t) m[0]<<24 | m[1]<<16 | m[2]<<8) == \
|
||||
((uint32_t) s[0]<<24 | s[1]<<16 | s[2]<<8 | 0x20202000) \
|
||||
&& (s += 3))
|
||||
|
||||
while (iswsp(*s))
|
||||
s++;
|
||||
if (i4("mon,") || i4("tue,") || i4("wed,") || i4("thu,") ||
|
||||
i4("fri,") || i4("sat,") || i4("sun,"))
|
||||
while (iswsp(*s))
|
||||
s++;
|
||||
|
||||
if ((c = parse_posint(&s, 1, 31)) < 0) goto fail;
|
||||
tm.tm_mday = c;
|
||||
|
||||
while (iswsp(*s))
|
||||
s++;
|
||||
|
||||
if (i3("jan")) tm.tm_mon = 0;
|
||||
else if (i3("feb")) tm.tm_mon = 1;
|
||||
else if (i3("mar")) tm.tm_mon = 2;
|
||||
else if (i3("apr")) tm.tm_mon = 3;
|
||||
else if (i3("may")) tm.tm_mon = 4;
|
||||
else if (i3("jul")) tm.tm_mon = 5;
|
||||
else if (i3("jun")) tm.tm_mon = 6;
|
||||
else if (i3("aug")) tm.tm_mon = 7;
|
||||
else if (i3("sep")) tm.tm_mon = 8;
|
||||
else if (i3("oct")) tm.tm_mon = 9;
|
||||
else if (i3("nov")) tm.tm_mon = 10;
|
||||
else if (i3("dec")) tm.tm_mon = 11;
|
||||
else goto fail;
|
||||
|
||||
while (iswsp(*s))
|
||||
s++;
|
||||
|
||||
if ((c = parse_posint(&s, 1000, 9999)) > 0) {
|
||||
tm.tm_year = c - 1900;
|
||||
} else if ((c = parse_posint(&s, 0, 49)) > 0) {
|
||||
tm.tm_year = c + 100;
|
||||
} else if ((c = parse_posint(&s, 50, 99)) > 0) {
|
||||
tm.tm_year = c;
|
||||
} else goto fail;
|
||||
|
||||
while (iswsp(*s))
|
||||
s++;
|
||||
|
||||
if ((c = parse_posint(&s, 0, 24)) < 0) goto fail;
|
||||
tm.tm_hour = c;
|
||||
if (*s++ != ':') goto fail;
|
||||
if ((c = parse_posint(&s, 0, 59)) < 0) goto fail;
|
||||
tm.tm_min = c;
|
||||
if (*s++ == ':') {
|
||||
if ((c = parse_posint(&s, 0, 61)) < 0) goto fail;
|
||||
tm.tm_sec = c;
|
||||
}
|
||||
|
||||
while (iswsp(*s))
|
||||
s++;
|
||||
|
||||
if (*s == '+' || *s == '-') {
|
||||
int neg = (*s == '-');
|
||||
s++;
|
||||
if ((c = parse_posint(&s, 0, 10000)) < 0) goto fail;
|
||||
if (neg) {
|
||||
tm.tm_hour += c / 100;
|
||||
tm.tm_min += c % 100;
|
||||
} else {
|
||||
tm.tm_hour -= c / 100;
|
||||
tm.tm_min -= c % 100;
|
||||
}
|
||||
}
|
||||
|
||||
tm.tm_isdst = -1;
|
||||
|
||||
time_t r = mktime(&tm);
|
||||
return r;
|
||||
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *
|
||||
parse_addr(char *s, char **dispo, char **addro)
|
||||
{
|
||||
static char disp[1024];
|
||||
static char addr[1024];
|
||||
// char *disp = disp+sizeof disp;
|
||||
// char *addr = addr+sizeof addr;
|
||||
char *c, *e;
|
||||
|
||||
printf("RAW : |%s|\n", s);
|
||||
|
||||
while (iswsp(*s))
|
||||
s++;
|
||||
|
||||
c = disp;
|
||||
e = disp + sizeof disp;
|
||||
|
||||
*disp = 0;
|
||||
*addr = 0;
|
||||
|
||||
while (*s) {
|
||||
if (*s == '<') {
|
||||
char *c = addr;
|
||||
char *e = addr + sizeof addr;
|
||||
|
||||
s++;
|
||||
while (*s && c < e && *s != '>')
|
||||
*c++ = *s++;
|
||||
if (*s == '>')
|
||||
s++;
|
||||
*c = 0;
|
||||
} else if (*s == '"') {
|
||||
s++;
|
||||
while (*s && c < e && *s != '"')
|
||||
*c++ = *s++;
|
||||
if (*s == '"')
|
||||
s++;
|
||||
} else if (*s == '(') {
|
||||
s++;
|
||||
|
||||
if (!*addr) { // assume: user@host (name)
|
||||
*c-- = 0;
|
||||
while (c > disp && iswsp(*c))
|
||||
*c-- = 0;
|
||||
strcpy(addr, disp);
|
||||
c = disp;
|
||||
*c = 0;
|
||||
}
|
||||
|
||||
while (*s && c < e && *s != ')')
|
||||
*c++ = *s++;
|
||||
if (*s == ')')
|
||||
s++;
|
||||
} else if (*s == ',') {
|
||||
s++;
|
||||
break;
|
||||
} else {
|
||||
*c++ = *s++;
|
||||
}
|
||||
}
|
||||
|
||||
*c-- = 0;
|
||||
// strip trailing ws
|
||||
while (c > disp && iswsp(*c))
|
||||
*c-- = 0;
|
||||
|
||||
if (*disp && !*addr && strchr(disp, '@')) {
|
||||
// just mail address was given
|
||||
strcpy(addr, disp);
|
||||
*disp = 0;
|
||||
}
|
||||
|
||||
printf("DISP :: |%s|\n", disp);
|
||||
printf("ADDR :: |%s|\n", addr);
|
||||
|
||||
if (dispo) *dispo = disp;
|
||||
if (addro) *addro = addr;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void
|
||||
blaze822(char *file)
|
||||
{
|
||||
int fd;
|
||||
ssize_t rd;
|
||||
char *buf;
|
||||
ssize_t bufalloc;
|
||||
ssize_t used;
|
||||
char *end;
|
||||
|
||||
fd = open(file, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
return;
|
||||
}
|
||||
|
||||
buf = malloc(3);
|
||||
buf[0] = '\n';
|
||||
buf[1] = '\n';
|
||||
buf[2] = '\n';
|
||||
bufalloc = 3;
|
||||
used = 3;
|
||||
|
||||
while (1) {
|
||||
bufalloc += bufsiz;
|
||||
buf = realloc(buf, bufalloc);
|
||||
|
||||
rd = read(fd, buf+used, bufalloc-used);
|
||||
if (rd == 0) {
|
||||
end = buf+used;
|
||||
break;
|
||||
}
|
||||
if (rd < 0)
|
||||
exit(-1);
|
||||
|
||||
if ((end = memmem(buf-1+used, rd+1, "\n\n", 2)) ||
|
||||
(end = memmem(buf-3+used, rd+3, "\r\n\r\n", 4))) {
|
||||
used += rd;
|
||||
break;
|
||||
}
|
||||
|
||||
used += rd;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
end++;
|
||||
*end = 0; // dereferencing *end is safe
|
||||
|
||||
char *s;
|
||||
for (s = buf; s < end; s++) {
|
||||
if (*s == 0) // sanitize nul bytes in headers
|
||||
*s = ' ';
|
||||
|
||||
if (*s == '\r') {
|
||||
if (*(s+1) == '\n') {
|
||||
*s++ = '\n';
|
||||
} else {
|
||||
*s = ' ';
|
||||
}
|
||||
}
|
||||
|
||||
if (iswsp(*s)) {
|
||||
// change prior \n to spaces
|
||||
int j;
|
||||
for (j = 1; s - j >= buf && *(s-j) == '\n'; j++)
|
||||
*(s-j) = ' ';
|
||||
}
|
||||
|
||||
if (*s == '\n') {
|
||||
s++;
|
||||
if (iswsp(*s)) {
|
||||
*(s-1) = ' ';
|
||||
} else {
|
||||
*(s-1) = 0;
|
||||
if (*(s-2) == '\n') // ex-crlf
|
||||
*(s-2) = 0;
|
||||
while (s < end && *s != ':') {
|
||||
*s = tolower(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf[0] = 0;
|
||||
|
||||
/*
|
||||
for (s = buf; s < end; ) {
|
||||
printf("%s\n", s);
|
||||
s += strlen(s) + 1;
|
||||
}
|
||||
*/
|
||||
char *v;
|
||||
if ((v = memmem(buf, end-buf, "\0from:", 6))) {
|
||||
printf("FROM : %s\n", v+6);
|
||||
parse_addr(v+6, 0, 0);
|
||||
}
|
||||
if ((v = memmem(buf, end-buf, "\0to:", 4))) {
|
||||
printf("TO : %s\n", v+4);
|
||||
char *a = v+4;
|
||||
char *disp, *addr;
|
||||
do {
|
||||
a = parse_addr(a, &disp, &addr);
|
||||
printf("DISP: |%s| ADDR: |%s|\n", disp, addr);
|
||||
} while (*a);
|
||||
}
|
||||
if ((v = memmem(buf, end-buf, "\0date:", 6))) {
|
||||
printf("DATE : %s\n", v+6);
|
||||
time_t t = parse_date(v+6);
|
||||
if (t != -1)
|
||||
printf("DATE :: %s", ctime(&t));
|
||||
else
|
||||
fprintf(stderr, "invalid date: %s\n", v+6);
|
||||
}
|
||||
if ((v = memmem(buf, end-buf, "\0subject:", 9))) {
|
||||
printf("SUBJECT : %s\n", v+9);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
|
||||
printf("used: %d %d\n", used, end-buf);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
char *s;
|
||||
|
||||
char *line = 0;
|
||||
size_t linelen = 0;
|
||||
int read;
|
||||
|
||||
int i = 0;
|
||||
|
||||
if (argc == 1 || (argc == 2 && strcmp(argv[1], "-") == 0)) {
|
||||
while ((read = getdelim(&line, &linelen, '\n', stdin)) != -1) {
|
||||
if (line[read-1] == '\n') line[read-1] = 0;
|
||||
fprintf(stderr, "%s\n", line);
|
||||
blaze822(line);
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < argc; i++) {
|
||||
fprintf(stderr, "%s\n", argv[i]);
|
||||
blaze822(argv[i]);
|
||||
}
|
||||
i--;
|
||||
}
|
||||
|
||||
printf("%d mails scanned\n", i);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,97 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <dirent.h> /* Defines DT_* constants */
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
#define handle_error(msg) \
|
||||
do { perror(msg); exit(EXIT_FAILURE); } while (0)
|
||||
|
||||
struct linux_dirent64 {
|
||||
ino64_t d_ino; /* 64-bit inode number */
|
||||
off64_t d_off; /* 64-bit offset to next structure */
|
||||
unsigned short d_reclen; /* Size of this dirent */
|
||||
unsigned char d_type; /* File type */
|
||||
char d_name[]; /* Filename (null-terminated) */
|
||||
};
|
||||
|
||||
|
||||
#define BUF_SIZE 1024000
|
||||
|
||||
void flagsort(char *s) {
|
||||
int i, j;
|
||||
if (!s[0])
|
||||
return;
|
||||
// adapted insertion sort from http://stackoverflow.com/a/2789530
|
||||
for (i = 1; s[i]; i++) {
|
||||
char t = s[i];
|
||||
for (j = i; j >= 1 && t < s[j-1]; j--)
|
||||
s[j] = s[j-1];
|
||||
s[j] = t;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int fd, nread;
|
||||
char buf[BUF_SIZE];
|
||||
struct linux_dirent64 *d;
|
||||
int bpos;
|
||||
char d_type;
|
||||
|
||||
fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
|
||||
if (fd == -1)
|
||||
handle_error("open");
|
||||
|
||||
while (1) {
|
||||
nread = syscall(SYS_getdents64, fd, buf, BUF_SIZE);
|
||||
if (nread == -1)
|
||||
handle_error("getdents64");
|
||||
|
||||
if (nread == 0)
|
||||
break;
|
||||
|
||||
printf("--------------- nread=%d ---------------\n", nread);
|
||||
printf("inode# file type d_reclen d_off d_name\n");
|
||||
for (bpos = 0; bpos < nread;) {
|
||||
d = (struct linux_dirent64 *) (buf + bpos);
|
||||
if (d->d_type != DT_REG)
|
||||
goto next;
|
||||
if (d->d_name[0] == '.')
|
||||
goto next;
|
||||
char *flags = strstr(d->d_name, ":2,");
|
||||
if (!flags)
|
||||
goto next;
|
||||
// if (strncmp(d->d_name, "1467836925_0.1439.juno,U=87588,FMD5=7e33429f656f1", strlen("1467836925_0.1439.juno,U=87588,FMD5=7e33429f656f1")-1))
|
||||
// goto next;
|
||||
// printf("%s\n", d->d_name);
|
||||
flagsort(flags+3);
|
||||
printf("%s\n", d->d_name);
|
||||
// if (!strchr(flags, 'S'))
|
||||
// printf("%s\n", d->d_name);
|
||||
|
||||
// goto next;
|
||||
|
||||
/*
|
||||
printf("%-10s ", (d_type == DT_REG) ? "regular" :
|
||||
(d_type == DT_DIR) ? "directory" :
|
||||
(d_type == DT_FIFO) ? "FIFO" :
|
||||
(d_type == DT_SOCK) ? "socket" :
|
||||
(d_type == DT_LNK) ? "symlink" :
|
||||
(d_type == DT_BLK) ? "block dev" :
|
||||
(d_type == DT_CHR) ? "char dev" : "???");
|
||||
printf("%4d %10lld %s\n", d->d_reclen,
|
||||
(long long) d->d_off, d->d_name);
|
||||
*/
|
||||
next:
|
||||
bpos += d->d_reclen;
|
||||
}
|
||||
}
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
unsigned int j;
|
||||
char *f, *e;
|
||||
|
||||
int8_t flagmod[255] = { 0 };
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (*argv[i] == '+') {
|
||||
f = argv[i] + 1;
|
||||
while (*f)
|
||||
flagmod[(int)*f++]++;
|
||||
continue;
|
||||
} else if (*argv[i] == '-') {
|
||||
f = argv[i] + 1;
|
||||
while (*f)
|
||||
flagmod[(int)*f++]--;
|
||||
continue;
|
||||
}
|
||||
|
||||
int8_t flags[255] = { 0 };
|
||||
char flagstr[255];
|
||||
f = e = strstr(argv[i], ":2,");
|
||||
|
||||
if (!f)
|
||||
continue;
|
||||
f += 3;
|
||||
while (*f)
|
||||
flags[(int)*f++] = 1;
|
||||
|
||||
*e = 0;
|
||||
f = flagstr;
|
||||
for (j = 0; j < sizeof flags; j++)
|
||||
if (flags[j] + flagmod[j])
|
||||
*f++ = j;
|
||||
*f = 0;
|
||||
|
||||
printf("%s:2,%s\n", argv[i], flagstr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,368 @@
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#undef getc
|
||||
#define getc getc_unlocked
|
||||
|
||||
#ifndef __GLIBC__
|
||||
#include "/home/chris/src/musl/src/internal/stdio_impl.h"
|
||||
#endif
|
||||
|
||||
FILE *input;
|
||||
|
||||
enum {
|
||||
EOL = -2,
|
||||
EOH = -3
|
||||
};
|
||||
|
||||
|
||||
// WSP = SP / HTAB
|
||||
#define iswsp(c) (((c) == ' ' || (c) == '\t'))
|
||||
|
||||
// CRLF is \n, LF is \n, just CR is ' ',
|
||||
// end of file is EOF, end of line is EOL, end of header is EOH,
|
||||
// CRLFCR is EOH, CRLFCRLF is EOH, CRCR is EOH
|
||||
int
|
||||
mgetch()
|
||||
{
|
||||
int c, d;
|
||||
|
||||
switch(c = getc(input)) {
|
||||
case EOF:
|
||||
return EOF;
|
||||
case '\r':
|
||||
d = getc(input);
|
||||
if (d != '\n') {
|
||||
// stray CR
|
||||
ungetc(d, input);
|
||||
return ' ';
|
||||
}
|
||||
/* fallthru */
|
||||
case '\n':
|
||||
d = getc(input);
|
||||
if (d == '\r') {
|
||||
d = getc(input);
|
||||
if (d != '\n' && d != '\r')
|
||||
return d;
|
||||
}
|
||||
if (d == '\n' || d == '\r') {
|
||||
return EOH;
|
||||
} else if (iswsp(d)) {
|
||||
// line continuation
|
||||
return ' ';
|
||||
} else {
|
||||
// end of line
|
||||
ungetc(d, input);
|
||||
return EOL;
|
||||
}
|
||||
default:
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
strip(char *t)
|
||||
{
|
||||
char *b, *e;
|
||||
for (b = t; *b && iswsp(*b); b++);
|
||||
for (e = b; *e && !iswsp(*e); e++);
|
||||
*e = 0;
|
||||
return b;
|
||||
}
|
||||
|
||||
void skipws() {
|
||||
int c;
|
||||
do {
|
||||
c = getc(input);
|
||||
} while (c != EOF && iswsp(c));
|
||||
ungetc(c, input);
|
||||
}
|
||||
|
||||
char *
|
||||
parse_header()
|
||||
{
|
||||
static char hdr[1024];
|
||||
static const char *hdrend = hdr + sizeof hdr;
|
||||
int c;
|
||||
|
||||
char *s = hdr;
|
||||
*s = 0;
|
||||
while ((c = mgetch()) > 0 && s < hdrend) {
|
||||
if (c < 0)
|
||||
return 0;
|
||||
if (c == ':') {
|
||||
*s = 0;
|
||||
skipws();
|
||||
return strip(hdr);
|
||||
}
|
||||
*s++ = tolower(c);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *
|
||||
parse_value()
|
||||
{
|
||||
static char value[1024];
|
||||
static const char *valend = value + sizeof value;
|
||||
|
||||
int c;
|
||||
char *s = value;
|
||||
|
||||
*s = 0;
|
||||
|
||||
while ((c = mgetch()) != EOF && s < valend) {
|
||||
if (c == EOH) {
|
||||
ungetc('\n', input);
|
||||
return value;
|
||||
}
|
||||
if (c == EOL) {
|
||||
*s = 0;
|
||||
return value;
|
||||
}
|
||||
*s++ = c;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
int
|
||||
parse_tok(char **t)
|
||||
{
|
||||
static char tok[16];
|
||||
static const char *tokend = tok + sizeof tok;
|
||||
|
||||
int c;
|
||||
|
||||
char *s = tok;
|
||||
*s = 0;
|
||||
*t = 0;
|
||||
|
||||
c = mgetch();
|
||||
while (iswsp(c))
|
||||
c = mgetch();
|
||||
while (c > 0 && s < tokend) {
|
||||
// printf("%c/%d ", c, c);
|
||||
if (iswsp(c)) {
|
||||
skipws();
|
||||
*s = 0;
|
||||
*t = tok;
|
||||
break;
|
||||
}
|
||||
else
|
||||
*s++ = c;
|
||||
c = mgetch();
|
||||
}
|
||||
if (c == EOL) {
|
||||
*s = 0;
|
||||
*t = tok;
|
||||
}
|
||||
if (t)
|
||||
*t = strip(tok);
|
||||
|
||||
// printf("TOK |%s|", tok);
|
||||
if (c < 0)
|
||||
return c;
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static long
|
||||
parse_posint(char *s, size_t minn, size_t maxn)
|
||||
{
|
||||
long n;
|
||||
char *end;
|
||||
|
||||
errno = 0;
|
||||
n = strtol(s, &end, 10);
|
||||
if (errno || *end || n < (long)minn || n > (long)maxn)
|
||||
return -1;
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
parse_date(time_t *r)
|
||||
{
|
||||
char *t;
|
||||
int c;
|
||||
|
||||
struct tm tm;
|
||||
|
||||
if ((c = parse_tok(&t)) < 0) goto fail;
|
||||
if (strlen(t) == 4 && t[3] == ',') // ignore day of week
|
||||
if ((c = parse_tok(&t)) < 0) goto fail;
|
||||
|
||||
if ((c = parse_posint(t, 1, 31)) < 0) goto fail;
|
||||
tm.tm_mday = c;
|
||||
|
||||
if ((c = parse_tok(&t)) < 0) goto fail;
|
||||
// convert to switch
|
||||
if (strcmp("Jan", t) == 0) tm.tm_mon = 0;
|
||||
else if (strcmp("Feb", t) == 0) tm.tm_mon = 1;
|
||||
else if (strcmp("Mar", t) == 0) tm.tm_mon = 2;
|
||||
else if (strcmp("Apr", t) == 0) tm.tm_mon = 3;
|
||||
else if (strcmp("May", t) == 0) tm.tm_mon = 4;
|
||||
else if (strcmp("Jun", t) == 0) tm.tm_mon = 5;
|
||||
else if (strcmp("Jul", t) == 0) tm.tm_mon = 6;
|
||||
else if (strcmp("Aug", t) == 0) tm.tm_mon = 7;
|
||||
else if (strcmp("Sep", t) == 0) tm.tm_mon = 8;
|
||||
else if (strcmp("Oct", t) == 0) tm.tm_mon = 9;
|
||||
else if (strcmp("Nov", t) == 0) tm.tm_mon = 10;
|
||||
else if (strcmp("Dec", t) == 0) tm.tm_mon = 11;
|
||||
else goto fail;
|
||||
|
||||
if ((c = parse_tok(&t)) < 0) goto fail;
|
||||
if ((c = parse_posint(t, 1000, 9999)) > 0) {
|
||||
tm.tm_year = c - 1900;
|
||||
} else if ((c = parse_posint(t, 0, 49)) > 0) {
|
||||
tm.tm_year = c + 100;
|
||||
} else if ((c = parse_posint(t, 50, 99)) > 0) {
|
||||
tm.tm_year = c;
|
||||
} else goto fail;
|
||||
|
||||
if ((c = parse_tok(&t)) < 0)
|
||||
if (!t) goto fail;
|
||||
if (strlen(t) == 8 && t[2] == ':' && t[5] == ':') {
|
||||
t[2] = t[5] = 0;
|
||||
if ((c = parse_posint(t, 0, 24)) < 0) goto fail;
|
||||
tm.tm_hour = c;
|
||||
if ((c = parse_posint(t+3, 0, 59)) < 0) goto fail;
|
||||
tm.tm_min = c;
|
||||
if ((c = parse_posint(t+6, 0, 61)) < 0) goto fail;
|
||||
tm.tm_sec = c;
|
||||
} else if (strlen(t) == 5 && t[2] == ':') {
|
||||
t[2] = 0;
|
||||
if ((c = parse_posint(t, 0, 24)) < 0) goto fail;
|
||||
tm.tm_hour = c;
|
||||
if ((c = parse_posint(t+3, 0, 59)) < 0) goto fail;
|
||||
tm.tm_min = c;
|
||||
tm.tm_sec = 0;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// if ((c = parse_tok(&t)) > 0) goto fail; // expect EOL, EOH, EOF
|
||||
c = parse_tok(&t);
|
||||
if (t && strlen(t) == 5 && (t[0] == '+' || t[0] == '-')) {
|
||||
if ((c = parse_posint(t+1, 0, 10000)) < 0) goto fail;
|
||||
if (t[0] == '+') {
|
||||
tm.tm_hour -= c / 100;
|
||||
tm.tm_min -= c % 100;
|
||||
} else {
|
||||
tm.tm_hour += c / 100;
|
||||
tm.tm_min += c % 100;
|
||||
}
|
||||
}
|
||||
// TODO: parse obs-zone?
|
||||
|
||||
tm.tm_isdst = -1;
|
||||
|
||||
*r = timegm(&tm);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
*r = -1;
|
||||
/* slurp rest of line and leave it */
|
||||
while ((c = mgetch()) > 0)
|
||||
;
|
||||
return c;
|
||||
}
|
||||
|
||||
int decode_rfc2047 (char *str, char *dst, size_t dstlen);
|
||||
|
||||
|
||||
int catmain() {
|
||||
int c;
|
||||
|
||||
input = stdin;
|
||||
while ((c = mgetch())) {
|
||||
if (c > 0)
|
||||
putchar(c);
|
||||
else
|
||||
printf("[%d]\n", c);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tmain() {
|
||||
char *s;
|
||||
|
||||
input = stdin;
|
||||
while ((s = parse_header())) {
|
||||
if (strcmp(s, "date") == 0) {
|
||||
time_t t;
|
||||
if (parse_date(&t) >= 0)
|
||||
printf("%s :: (%ld) %s", s, t, ctime(&t));
|
||||
else
|
||||
printf("date : OOPS\n");
|
||||
} else if (strcmp(s, "subject") == 0) {
|
||||
char *v = parse_value();
|
||||
char buf[2048];
|
||||
decode_rfc2047(v, buf, sizeof buf);
|
||||
printf("%s : %s\n", s, v);
|
||||
printf("%s :: %s\n", s, buf);
|
||||
} else {
|
||||
char *v = parse_value();
|
||||
printf("%s : %s\n", s, v);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
char *s;
|
||||
|
||||
char *line = 0;
|
||||
size_t linelen = 0;
|
||||
int read;
|
||||
|
||||
int i = 0;
|
||||
|
||||
static char buf[50000]; /* buf must survive until stdout is closed */
|
||||
|
||||
while ((read = getdelim(&line, &linelen, '\n', stdin)) != -1) {
|
||||
if (line[read-1] == '\n') line[read-1] = 0;
|
||||
|
||||
printf("%s\n", line);
|
||||
|
||||
FILE *f = fopen(line, "r");
|
||||
if (!f) {
|
||||
perror("fopen");
|
||||
continue;
|
||||
}
|
||||
setvbuf ( f , buf , _IOFBF , sizeof(buf) );
|
||||
i++;
|
||||
|
||||
input = f;
|
||||
while ((s = parse_header())) {
|
||||
if (strcmp(s, "date") == 0) {
|
||||
time_t t;
|
||||
if (parse_date(&t) >= 0)
|
||||
printf("%s :: (%ld) %s", s, t, ctime(&t));
|
||||
else
|
||||
printf("date : OOPS\n");
|
||||
} else if (strcmp(s, "subject") == 0 ||
|
||||
strcmp(s, "from") == 0 ||
|
||||
strcmp(s, "to") == 0) {
|
||||
char *v = parse_value();
|
||||
char buf[2048];
|
||||
if (decode_rfc2047(v, buf, sizeof buf))
|
||||
printf("%s :: %s\n", s, buf);
|
||||
else
|
||||
printf("%s : %s\n", s, v);
|
||||
} else
|
||||
parse_value(); // and ignore it
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
printf("%d mails scanned\n", i);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int fd;
|
||||
struct stat st;
|
||||
|
||||
fd = open("map", O_RDONLY);
|
||||
if (!fd)
|
||||
exit(101);
|
||||
|
||||
fstat(fd, &st);
|
||||
char *map = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||
if (!map)
|
||||
exit(102);
|
||||
|
||||
char *s = strstr(map, argv[1]);
|
||||
if (!argv[1][0] || !s) {
|
||||
// default to first line
|
||||
s = map;
|
||||
} else {
|
||||
while (*s && *s != '\n')
|
||||
s++;
|
||||
s++;
|
||||
}
|
||||
char *t = s;
|
||||
while (*t && *t != '\n')
|
||||
t++;
|
||||
if (!*t)
|
||||
exit(1);
|
||||
t++;
|
||||
write(1, s, t-s);
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue