📄 db_dump.c
字号:
case T_NS: cp = (u_char *)dp->d_data; if (cp[0] == '\0') fprintf(fp, ".\t"); else fprintf(fp, "%s.", cp); break; case T_HINFO: if (n = *cp++) { fprintf(fp, "\"%.*s\"", (int)n, cp); cp += n; } else fprintf(fp, "\"\""); if (n = *cp++) fprintf(fp, " \"%.*s\"", (int)n, cp); else fprintf(fp, " \"\""); break; case T_SOA: fprintf(fp, "%s.", cp); cp += strlen((char *)cp) + 1; fprintf(fp, " %s. (\n", cp); cp += strlen((char *)cp) + 1; GETLONG(n, cp); fprintf(fp, "\t\t%lu", n); GETLONG(n, cp); fprintf(fp, " %lu", n); GETLONG(n, cp); fprintf(fp, " %lu", n); GETLONG(n, cp); fprintf(fp, " %lu", n); GETLONG(n, cp); fprintf(fp, " %lu )", n); break; case T_MX: case T_AFSDB: GETSHORT(n, cp); fprintf(fp,"%lu", n); fprintf(fp," %s.", cp); break; case T_TXT: end = (u_char *)dp->d_data + dp->d_size; (void) putc('"', fp); while (cp < end) { if (n = *cp++) { for (j = n ; j > 0 && cp < end ; j--) if (*cp == '\n') { (void) putc('\\', fp); (void) putc(*cp++, fp); } else (void) putc(*cp++, fp); } } (void) fputs("\"", fp); break; case T_UINFO: fprintf(fp, "\"%s\"", cp); break; case T_UID: case T_GID: if (dp->d_size == sizeof(u_int32_t)) { GETLONG(n, cp); } else { n = -2; /* XXX - hack */ } fprintf(fp, "%u", n); break; case T_WKS: GETLONG(addr, cp); addr = htonl(addr); fprintf(fp, "%s ", inet_ntoa(*(struct in_addr *)&addr)); proto = protocolname(*cp); cp += sizeof(char); fprintf(fp, "%s ", proto); i = 0; while(cp < (u_char *)dp->d_data + dp->d_size) { j = *cp++; do { if (j & 0200) fprintf(fp, " %s", servicename(i, proto)); j <<= 1; } while (++i & 07); } break; case T_MINFO: case T_RP: fprintf(fp, "%s.", cp); cp += strlen((char *)cp) + 1; fprintf(fp, " %s.", cp); break;#ifdef ALLOW_T_UNSPEC case T_UNSPEC: /* Dump binary data out in an ASCII-encoded format */ { /* Allocate more than enough space: * actually need 5/4 size + 20 or so */ int TmpSize = 2 * dp->d_size + 30; char *TmpBuf = (char *) malloc(TmpSize); if (TmpBuf == NULL) { dprintf(1, (ddt, "Dump T_UNSPEC: bad malloc\n" ) ); syslog(LOG_ERR, "Dump T_UNSPEC: malloc: %m"); *TmpBuf = "BAD_MALLOC"; } if (btoa(cp, dp->d_size, TmpBuf, TmpSize) == CONV_OVERFLOW) { dprintf(1, (ddt, "Dump T_UNSPEC: Output buffer overflow\n" ) ); syslog(LOG_ERR, "Dump T_UNSPEC: Output buffer overflow\n"); TmpBuf = "OVERFLOW"; } fprintf(fp, "%s", TmpBuf); } break;#endif /* ALLOW_T_UNSPEC */ default: fprintf(fp, "%s?d_type=%d?", sep, dp->d_type); sep = " "; }#ifdef CRED if (dp->d_cred != DB_C_AUTH) { fprintf(fp, "%sCr=%s", sep, MkCredStr(dp->d_cred)); sep = " "; }#endifeoln: putc('\n', fp); } } } if (ferror(fp)) return(NODBFILE); npp = htp->h_tab; nppend = npp + htp->h_size; while (npp < nppend) { for (np = *npp++; np != NULL; np = np->n_next) { if (np->n_hash == NULL) continue; getname(np, dname, sizeof(dname)); if (db_dump(np->n_hash, fp, zone, dname) == NODBFILE) return(NODBFILE); } } return(OK);}#ifdef CREDchar *MkCredStr(cred) int cred;{ static char badness[20]; switch (cred) { case DB_C_AUTH: return "auth"; case DB_C_ANSWER: return "answer"; case DB_C_ADDITIONAL: return "addtnl"; case DB_C_CACHE: return "cache"; default: sprintf(badness, "?%d?", cred); return badness; } /*NOTREACHED*/}#endif#ifdef ALLOW_T_UNSPEC/* * Subroutines to convert between 8 bit binary bytes and printable ASCII. * Computes the number of bytes, and three kinds of simple checksums. * Incoming bytes are collected into 32-bit words, then printed in base 85: * exp(85,5) > exp(2,32) * The ASCII characters used are between '!' and 'u'; * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data. * * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for * the atob/btoa programs, released with the compress program, in mod.sources. * Modified by Mike Schwartz 8/19/86 for use in BIND. *//* Make sure global variable names are unique */#define Ceor T_UNSPEC_Ceor#define Csum T_UNSPEC_Csum#define Crot T_UNSPEC_Crot#define word T_UNSPEC_word#define bcount T_UNSPEC_bcountstatic int32_t Ceor, Csum, Crot, word, bcount;#define EN(c) ((int) ((c) + '!'))#define DE(c) ((c) - '!')#define AddToBuf(bufp, c) **bufp = c; (*bufp)++;#define times85(x) ((((((x<<2)+x)<<2)+x)<<2)+x)/* Decode ASCII-encoded byte c into binary representation and * place into *bufp, advancing bufp */static intbyte_atob(c, bufp) register c; char **bufp;{ if (c == 'z') { if (bcount != 0) return(CONV_BADFMT); else { putbyte(0, bufp); putbyte(0, bufp); putbyte(0, bufp); putbyte(0, bufp); } } else if ((c >= '!') && (c < ('!' + 85))) { if (bcount == 0) { word = DE(c); ++bcount; } else if (bcount < 4) { word = times85(word); word += DE(c); ++bcount; } else { word = times85(word) + DE(c); putbyte((int)((word >> 24) & 255), bufp); putbyte((int)((word >> 16) & 255), bufp); putbyte((int)((word >> 8) & 255), bufp); putbyte((int)(word & 255), bufp); word = 0; bcount = 0; } } else return(CONV_BADFMT); return(CONV_SUCCESS);}/* Compute checksum info and place c into *bufp, advancing bufp */static voidputbyte(c, bufp) register c; char **bufp;{ Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; AddToBuf(bufp, c);}/* Read the ASCII-encoded data from inbuf, of length inbuflen, and convert it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes; outbuflen must be divisible by 4. (Note: this is because outbuf is filled in 4 bytes at a time. If the actual data doesn't end on an even 4-byte boundary, there will be no problem...it will be padded with 0 bytes, and numbytes will indicate the correct number of bytes. The main point is that since the buffer is filled in 4 bytes at a time, even if there is not a full 4 bytes of data at the end, there has to be room to 0-pad the data, so the buffer must be of size divisible by 4). Place the number of output bytes in numbytes, and return a failure/success status */intatob(inbuf, inbuflen, outbuf, outbuflen, numbytes) char *inbuf; int inbuflen; char *outbuf; int outbuflen; int *numbytes;{ int inc, nb; int32_t oeor, osum, orot; char *inp, *outp = outbuf, *endoutp = &outbuf[outbuflen]; if ( (outbuflen % 4) != 0) return(CONV_BADBUFLEN); Ceor = Csum = Crot = word = bcount = 0; for (inp = inbuf, inc = 0; inc < inbuflen; inp++, inc++) { if (outp > endoutp) return(CONV_OVERFLOW); if (*inp == 'x') { inp +=2; break; } else { if (byte_atob(*inp, &outp) == CONV_BADFMT) return(CONV_BADFMT); } } /* Get byte count and checksum information from end of buffer */ if(sscanf(inp, "%ld %lx %lx %lx", numbytes, &oeor, &osum, &orot) != 4) return(CONV_BADFMT); if ((oeor != Ceor) || (osum != Csum) || (orot != Crot)) return(CONV_BADCKSUM); return(CONV_SUCCESS);}/* Encode binary byte c into ASCII representation and place into *bufp, advancing bufp */static voidbyte_btoa(c, bufp) register c; char **bufp;{ Ceor ^= c; Csum += c; Csum += 1; if ((Crot & 0x80000000)) { Crot <<= 1; Crot += 1; } else { Crot <<= 1; } Crot += c; word <<= 8; word |= c; if (bcount == 3) { if (word == 0) { AddToBuf(bufp, 'z'); } else { register int tmp = 0; register int32_t tmpword = word; if (tmpword < 0) { /* Because some don't support unsigned long */ tmp = 32; tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32); } if (tmpword < 0) { tmp = 64; tmpword -= (int32_t)(85 * 85 * 85 * 85 * 32); } AddToBuf(bufp, EN((tmpword / (int32_t)(85 * 85 * 85 * 85)) + tmp)); tmpword %= (int32_t)(85 * 85 * 85 * 85); AddToBuf(bufp, EN(tmpword / (85 * 85 * 85))); tmpword %= (85 * 85 * 85); AddToBuf(bufp, EN(tmpword / (85 * 85))); tmpword %= (85 * 85); AddToBuf(bufp, EN(tmpword / 85)); tmpword %= 85; AddToBuf(bufp, EN(tmpword)); } bcount = 0; } else { bcount += 1; }}/* * Encode the binary data from inbuf, of length inbuflen, into a * null-terminated ASCII representation in outbuf, not to exceed outbuflen * bytes. Return success/failure status */static intbtoa(inbuf, inbuflen, outbuf, outbuflen) char *inbuf; int inbuflen; char *outbuf; int outbuflen;{ int32_t inc, nb; int32_t oeor, osum, orot; char *inp, *outp = outbuf, *endoutp = &outbuf[outbuflen -1]; Ceor = Csum = Crot = word = bcount = 0; for (inp = inbuf, inc = 0; inc < inbuflen; inp++, inc++) { byte_btoa((unsigned char) (*inp), &outp); if (outp >= endoutp) return(CONV_OVERFLOW); } while (bcount != 0) { byte_btoa(0, &outp); if (outp >= endoutp) return(CONV_OVERFLOW); } /* Put byte count and checksum information at end of buffer, delimited by 'x' */ (void) sprintf(outp, "x %ld %lx %lx %lx", inbuflen, Ceor, Csum, Crot); if (&outp[strlen(outp) - 1] >= endoutp) return(CONV_OVERFLOW); else return(CONV_SUCCESS);}#endif /* ALLOW_T_UNSPEC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -