1: #ifndef lint 2: static char sccsid[] = "@(#)db_dump.c 4.3 (Berkeley) 5/30/86"; 3: #endif 4: 5: /* 6: * Copyright (c) 1986 Regents of the University of California 7: * All Rights Reserved 8: */ 9: 10: #include <sys/types.h> 11: #include <sys/time.h> 12: #include <netinet/in.h> 13: #include <netdb.h> 14: #include <stdio.h> 15: #include <syslog.h> 16: #include <arpa/nameser.h> 17: #include "ns.h" 18: #include "db.h" 19: 20: extern char *p_type(), *p_class(); 21: 22: #ifdef DUMPFILE 23: char *dumpfile = DUMPFILE; 24: #else 25: char *dumpfile = "/usr/tmp/named_dump.db"; 26: #endif 27: 28: /* 29: * Dump current data base in a format similar to RFC 883. 30: */ 31: 32: doadump() 33: { 34: FILE *fp; 35: 36: #ifdef DEBUG 37: if (debug >= 3) 38: fprintf(ddt,"doadump()\n"); 39: #endif 40: 41: if ((fp = fopen(dumpfile, "w")) == NULL) 42: return; 43: fprintf(fp, "$ORIGIN .\n"); 44: if (hashtab != NULL) 45: db_dump(hashtab, fp); 46: (void) fclose(fp); 47: } 48: 49: db_dump(htp, fp) 50: struct hashbuf *htp; 51: FILE *fp; 52: { 53: register struct databuf *dp; 54: register struct namebuf *np; 55: struct namebuf **npp, **nppend; 56: char dname[MAXDNAME]; 57: long n; 58: u_long addr; 59: u_short i; 60: int j; 61: char *cp; 62: char *proto; 63: extern char *inet_ntoa(), *p_protocal(), *p_service(); 64: 65: 66: npp = htp->h_tab; 67: nppend = npp + htp->h_size; 68: while (npp < nppend) { 69: for (np = *npp++; np != NULL; np = np->n_next) { 70: if (np->n_data == NULL) 71: continue; 72: fprintf(fp, "%s\t", np->n_dname); 73: if (strlen(np->n_dname) < 8) 74: (void) putc('\t', fp); 75: for (dp = np->n_data; dp != NULL; dp = dp->d_next) { 76: if (dp != np->n_data) 77: fprintf(fp, "\t\t"); 78: if (dp->d_zone == 0) { 79: if (gettimeofday(&tt, (struct timezone *)0) < 0) 80: syslog(LOG_ERR, "gettimeofday: %m"); 81: if ((n = dp->d_ttl - tt.tv_sec) >= 0) 82: fprintf(fp, "%d\t", n); 83: } else if (dp->d_ttl > zones[dp->d_zone].z_minimum) 84: fprintf(fp, "%d\t", dp->d_ttl); 85: fprintf(fp, "%s\t%s\t", p_class(dp->d_class), 86: p_type(dp->d_type)); 87: cp = dp->d_data; 88: /* 89: * Print type specific data 90: */ 91: switch (dp->d_type) { 92: case T_A: 93: switch (dp->d_class) { 94: case C_IN: 95: n = htonl(getlong(cp)); 96: fprintf(fp, "%s\n", 97: inet_ntoa(*(struct in_addr *)&n)); 98: break; 99: } 100: break; 101: case T_CNAME: 102: case T_MB: 103: case T_MG: 104: case T_MR: 105: case T_NS: 106: case T_PTR: 107: if (cp[0] == '\0') 108: fprintf(fp, ".\n"); 109: else 110: fprintf(fp, "%s.\n", cp); 111: break; 112: 113: case T_HINFO: 114: if (n = *cp++) { 115: fprintf(fp, "%.*s", n, cp); 116: cp += n; 117: } else 118: fprintf(fp, "\"\""); 119: if (n = *cp++) 120: fprintf(fp, " %.*s", n, cp); 121: else 122: fprintf(fp, "\"\""); 123: (void) putc('\n', fp); 124: break; 125: 126: case T_SOA: 127: fprintf(fp, "%s", cp); 128: cp += strlen(cp) + 1; 129: fprintf(fp, " %s\n", cp); 130: cp += strlen(cp) + 1; 131: fprintf(fp, "\t\t%d", getlong(cp)); 132: cp += sizeof(u_long); 133: fprintf(fp, " %d", getlong(cp)); 134: cp += sizeof(u_long); 135: fprintf(fp, " %d", getlong(cp)); 136: cp += sizeof(u_long); 137: fprintf(fp, " %d", getlong(cp)); 138: cp += sizeof(u_long); 139: fprintf(fp, " %d\n", getlong(cp)); 140: break; 141: 142: case T_MX: 143: fprintf(fp,"%d", getshort(cp)); 144: cp += sizeof(u_short); 145: fprintf(fp," %s\n", cp); 146: break; 147: 148: 149: case T_UINFO: 150: fprintf(fp, "%s\n", cp); 151: break; 152: 153: case T_UID: 154: case T_GID: 155: if (dp->d_size == sizeof(u_long)) { 156: fprintf(fp, "%d\n", getlong(cp)); 157: cp += sizeof(u_long); 158: } 159: break; 160: 161: case T_WKS: 162: addr = htonl(getlong(cp)); 163: fprintf(fp,"%s ", 164: inet_ntoa(*(struct in_addr *)&addr)); 165: cp += sizeof(u_long); 166: proto = p_protocal(*cp); /* protocal */ 167: cp += sizeof(char); 168: fprintf(fp, "%s ", proto); 169: i = 0; 170: while(cp < dp->d_data + dp->d_size) { 171: j = *cp++; 172: do { 173: if(j & 0200) 174: fprintf(fp," %s", 175: p_service(i, proto)); 176: j <<= 1; 177: } while(++i & 07); 178: } 179: fprintf(fp,"\n"); 180: break; 181: 182: default: 183: fprintf(fp, "???\n", cp); 184: } 185: } 186: } 187: } 188: npp = htp->h_tab; 189: nppend = npp + htp->h_size; 190: while (npp < nppend) { 191: for (np = *npp++; np != NULL; np = np->n_next) { 192: if (np->n_hash == NULL) 193: continue; 194: getname(np, dname, sizeof(dname)); 195: fprintf(fp, "$ORIGIN %s.\n", dname); 196: db_dump(np->n_hash, fp); 197: } 198: } 199: } 200: 201: /* These next two routines will be moveing to res_debug.c */ 202: /* They are currently here for ease of distributing the WKS record fix */ 203: char * 204: p_protocal(num) 205: int num; 206: { 207: struct protoent *pp; 208: pp = getprotobynumber(num); 209: if(pp == 0) 210: return("???"); 211: return(pp->p_name); 212: } 213: 214: char * 215: p_service(port, proto) 216: u_short port; 217: char *proto; 218: { 219: struct servent *ss; 220: ss = getservbyport((int)htons(port), proto); 221: if(ss == 0) 222: return("???"); 223: return(ss->s_name); 224: }