Download | Plain Text | No Line Numbers
- /* prettycache.c
- diet -Os gcc -s -o prettycache prettycache.c -Wall -W -lowfat
- http://riemann.fmi.uni-sofia.bg/
-
- or in ./djbdns-1.05/ with:
- ./compile prettycache.c
- ./load prettycache buffer.a byte.a libtai.a unix.a
- */
-
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <errno.h>
- #include "tai.h"
- #include "buffer.h"
- #include "uint32.h"
- #include "uint16.h"
- #include "fmt.h"
-
- #define outs(x) buffer_puts(buffer_1,x)
- #define out(x,y) buffer_put(buffer_1,x,y)
- int outu(uint32 u) {char tmp[12]; return out(tmp,fmt_ulong(tmp,u));}
-
- static uint32 pos;
- static int flagdot, flagupper, flagtai, flagflat, flagalive;
- struct tai now;
- char hex[16] = "0123456789abcdef";
-
- void die(int n, const char *s1, const char *s2, const char *s3) {
- buffer_flush(buffer_1);
- if (s1) buffer_puts(buffer_2, s1);
- if (s2) buffer_puts(buffer_2, s2);
- if (s3) buffer_puts(buffer_2, s3);
- buffer_puts(buffer_2, "\n");
- buffer_flush(buffer_2);
- _exit(n);
- }
-
- void bad_input() {
- char tmp[12];
- tmp[fmt_ulong(tmp, pos)]=0;
- die(111,"\n\ntruncated input near to ", tmp, " position");
- }
-
- void u_octal(unsigned char ch) {
- char buf[4];
- buf[3] = '0' + (ch & 7); ch >>= 3;
- buf[2] = '0' + (ch & 7); ch >>= 3;
- buf[1] = '0' + (ch & 7);
- buf[0] = '\\';
- out(buf,4);
- }
-
- int dns_dtodot(const char *d, uint32 len) {
- char ch, ch2;
- int total=0;
-
- if (!len) return 0;
- if (!*d) { outs("."); return 1; }
-
- for (;len;) {
- ch = *d++;
- total++;
- len--;
- while (len && ch--) {
- ch2 = *d++;
- total++;
- len--;
- if (!flagupper)
- if ((ch2 >= 'A') && (ch2 <= 'Z'))
- ch2 += 32;
- if (((ch2 >= 'a') && (ch2 <= 'z')) ||
- ((ch2 >= '0') && (ch2 <= '9')) || (ch2 == '-') || (ch2 == '_') ||
- ((ch2 >= 'A') && (ch2 <= 'Z'))) {
- out(&ch2,1);
- }
- else
- u_octal((unsigned char)ch2);
- }
- if (len && !*d) { if (flagdot) out(".",1); return ++total; }
- out(".",1);
- }
- return -1;
- }
-
- void u_misc(char *s, uint32 len) {
- char *a=s, *end=a+len;
- while(a<end) {
- out(hex + ((a[0] >> 4) & 15), 1);
- out(hex + ((a[0]) & 15), 1);
- ++a;
- }
- }
-
- void u_a(char *s, uint32 len) {
- char *a=s, *end=a+len;
- while(a+4<=end) {
- int i=0;
- for(i=0; i<4; i++) {
- outu((uint32)(unsigned char)a[i]);
- if (i<3) outs(".");
- }
- a += 4;
- if (a+4 <= end) outs(" ");
- }
- }
-
- void u_hex(unsigned char *p) {
- char x[4];
- int i;
- x[0]=hex[p[0] >> 4];
- x[1]=hex[p[0] & 15];
- x[2]=hex[p[1] >> 4];
- x[3]=hex[p[1] & 15];
- for (i=0; i<3 && x[i]=='0';) i++;
- out(x+i, 4-i);
- }
-
- void u_ip6(unsigned char *ip) {
- int k, p0,len0, p1,len1, compr;
-
- for (k=0, p0=0,len0=0, p1=0, compr=0; k<16; k+=2) {
- if (ip[k]==0 && ip[k+1]==0) {
- if (!compr) {
- compr=1;
- p1=k;
- }
- if (k==14) { k=16; goto last; }
- } else if (compr) {
- last:
- if ((len1 = k-p1) > len0) {
- len0=len1;
- p0=p1;
- }
- compr=0;
- }
- }
-
- for (k=0; k<16; k+=2) {
- if (p0 == k && len0) {
- out("::", 1 + !p0);
- k += len0-2;
- continue;
- }
- u_hex(ip + k);
- if (k<14) outs(":");
- }
- }
-
- void u_aaaa(char *s, uint32 len) {
- char *end = s + len;
- while (s+18 <= end) {
- if (flagflat) u_misc(s+2,16);
- else u_ip6((unsigned char*)s+2);
- s += 18;
- if (s+18 <= end) outs(" ");
- }
- }
-
- void u_txt(char *a, uint32 len) {
- unsigned int txtlen,i;
- txtlen=0;
- for (i = 2;i < len;++i) {
- char ch = a[i];
- if (!txtlen)
- txtlen = (unsigned char) ch;
- else {
- --txtlen;
- if (ch < 32 || ch > 126) u_octal((unsigned char)ch);
- else out(&ch,1);
- }
- }
- if (txtlen) bad_input();
- }
-
- void u_name(char *s, uint32 len) {
- char *a=s, *end=a+len;
- unsigned long r;
- while(a<end) {
- if ((r = dns_dtodot(a,end-a))<=0) bad_input();
- a += r;
- if (a<end) outs(" ");
- }
- }
-
- void u_mx(char *s, uint32 len) {
- char *a=s, *end=a+len;
- unsigned long r;
- uint16 u;
- while(a+3<end) {
- uint16_unpack_big(a, &u);
- outu(u);
- outs(" ");
- if ((r=dns_dtodot(a+2, end-(a+2)))<=0) bad_input();
- a += r+2;
- if (a+3<end) outs(" ");
- }
- }
-
- int u_time(char *tai) {
- struct tai expire;
-
- tai_unpack(tai, &expire);
- if (expire.x <= now.x) {
- if (flagalive) return 1;
- } else
-
- if (flagtai) {
- outs("@");
- u_misc(tai,8);
- outs("00000000");
- } else {
- char sp[] = " ";
- if (len<6) out(sp, 6-len);
- }
- outs(" ");
- return 0;
- }
-
- int main(int argc, char **argv) {
- uint32 len;
- uint32 keylen;
- uint32 datalen;
- uint32 out;
- char *p, buf[8];
- const char *type, *sep=" ";
- int fd;
- void (*uu)(char*, uint32);
-
- while (argc>1 && argv[1][0] == '-') {
- for (p=argv[1]+1; *p; p++)
- switch (*p) {
- case 'A': flagalive=1; break;
- case 'u': flagupper=1; break;
- case 'd': flagdot=1; break;
- case 't': flagtai=1; break;
- case 'f': flagflat=1; break;
- case 'T': sep="\t"; break;
- default: goto usage;
- }
- argc--; argv++;
- }
-
- if (argc<2) {usage: die(1,"usage: prettycache [-AdftTu] data",0,0);}
-
- if ((fd=open(argv[1],O_RDONLY)) == -1)
- die(21, argv[1], ": open ", "error");
- if ((len=lseek(fd,0,SEEK_END)) == (uint32)-1)
- die(21, argv[1], ": lseek ", "error");
- if ((p=mmap(0,len,PROT_READ,MAP_SHARED,fd,0))==MAP_FAILED)
- die(21, "mmap ", "error", 0);
- close(fd);
-
- tai_now(&now);
- pos = 0;
-
- while (pos+16 <= len) {
- char *a,*b;
- uint16 u;
-
- uint32_unpack(p + pos, &keylen);
- uint32_unpack(p + pos + 4, &datalen);
-
- out = 16 + keylen + datalen;
- if (pos + out > len) bad_input();
- if (keylen < 3 || keylen > 1024) bad_input();
- if (datalen > 1000000) bad_input();
-
- if (u_time(p + pos + 8)) goto next;
- a = p + pos + 16;
- b = a + keylen;
- uint16_unpack_big(a, &u);
- uu=u_misc;
-
- switch (u) {
- case 1: uu=u_a; type="a"; break;
- case 2: uu=u_name; type="ns"; break;
- case 5: uu=u_name; type="cname"; break;
- case 12: uu=u_name; type="ptr"; break;
- case 15: uu=u_mx; type="mx"; break;
- case 16: uu=u_txt; type="txt"; break;
- case 28: uu=u_aaaa; type="aaaa"; break;
- case 33: type="srv"; break;
- case 252: type="servfail"; break;
- case 255: type="nxdomain"; break;
- default: buf[fmt_ulong(buf,u)]=0; type=buf; break;
- }
-
- outs(type); outs(sep);
- u_name(a+2, keylen-2); outs(sep);
- uu(b,datalen); outs("\n");
- next:
- pos += out;
- }
-
- buffer_flush(buffer_1);
- munmap(p,len);
- return 0;
- }
-