xfer.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,802 行 · 第 1/3 页
C
1,802 行
continue; } if (dn_expand(buf, buf + 512, nmp, name2, sizeof(name2)) == -1) goto badsoa; if (strcasecmp((char *)name, (char *)name2) != 0) {#ifdef DEBUG if (debug > 1) (void)fprintf(ddt, "extraneous SOA for %s\n", name2);#endif DEBUG continue; } tmp -= sizeof(u_short); if (soa_zinfo(&zp_finish, tmp, eom) == -1) goto badsoa;#ifdef DEBUG if (debug > 1) (void)fprintf(ddt, "SOA, serial %d\n", zp_finish.z_serial);#endif DEBUG if (serial != zp_finish.z_serial) { soacnt = 0; got_soa = 0; minimum_ttl = 0; strcpy(prev_origin, zp->z_origin); prev_dname[0] = 0;#ifdef DEBUG if (debug) (void)fprintf(ddt, "serial changed, restart\n");#endif DEBUG /* * Flush buffer, truncate file * and seek to beginning to restart. */ fflush(dbfp); if (ftruncate(fileno(dbfp), 0) != 0) { if (!quiet) syslog(LOG_ERR, "ftruncate %s: %m\n", tmpname); return(XFER_FAIL); } fseek(dbfp, 0L, 0); } else break; } } (void) close(s); if (error == 0) { (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); return XFER_SUCCESS; }#ifdef DEBUG if (debug >= 2) (void)fprintf(ddt,"error receiving zone transfer\n");#endif } else { (void) close(s);#ifdef DEBUG if (debug) (void)fprintf(ddt, "zone up-to-date, serial %d\n", zp_start.z_serial);#endif DEBUG return XFER_UPTODATE; } } (void) sigvec(SIGALRM, &osv, (struct sigvec *)0); if (error) return XFER_TIMEOUT; return XFER_FAIL;}/* * Set flag saying to read was interrupted * used for a read timer */void read_alarm(){ extern int read_interrupted; read_interrupted = 1;} writemsg(rfd, msg, msglen) int rfd; u_char *msg; int msglen;{ struct iovec iov[2]; u_short len = htons((u_short)msglen); iov[0].iov_base = (caddr_t)&len; iov[0].iov_len = sizeof(len); iov[1].iov_base = (caddr_t)msg; iov[1].iov_len = msglen; if (writev(rfd, iov, 2) != sizeof(len) + msglen) {#ifdef DEBUG if (debug) (void)fprintf(ddt,"write failed %d\n", errno);#endif return (-1); } return (0);}soa_zinfo(zp, cp, eom) register struct zoneinfo *zp; register u_char *cp; u_char *eom;{ register int n;#ifdef AUTHEN u_char *ocp; ocp = cp;#endif AUTHEN if (eom - cp < 3 * sizeof(u_short)) return (-1);#ifdef ULTRIXFUNC cp += sizeof(u_short); GETSHORT(zp->z_class, cp); cp += sizeof(u_short);#else ULTRIXFUNC cp += 3 * sizeof(u_short);#endif ULTRIXFUNC if (eom - cp < sizeof(u_long)) return (-1); cp += sizeof(u_long); if ((n = dn_skipname(cp, eom)) == -1) return (-1); cp += n; if ((n = dn_skipname(cp, eom)) == -1) return (-1); cp += n; if (eom - cp < 5 * sizeof(u_long)) return (-1); GETLONG(zp->z_serial, cp); GETLONG(zp->z_refresh, cp); gettime(&tt); zp->z_time = tt.tv_sec + zp->z_refresh; GETLONG(zp->z_retry, cp); GETLONG(zp->z_expire, cp); GETLONG(zp->z_minimum, cp);#ifdef AUTHEN return(cp - ocp);#endif AUTHEN}gettime(ttp)struct timeval *ttp;{ if (gettimeofday(ttp, (struct timezone *)0) < 0) syslog(LOG_ERR, "gettimeofday failed: %m");}/* * Parse the message, determine if it should be printed, and if so, print it * in .db file form. * Does minimal error checking on the message content. */print_output(msg, msglen, rrp) u_char *msg; int msglen; u_char *rrp;{ register u_char *cp; register HEADER *hp = (HEADER *) msg; u_long addr, ttl; int n, i, j, tab, result, class, type, dlen, n1; u_char *cp1, data[BUFSIZ]; u_char buf[MAXDATA], *tmpdata, *tmpbuf; u_char *temp_ptr; /* used to get ttl for RR */ char *cdata, *origin, *proto, dname[MAXDNAME]; extern char *inet_ntoa(), *protocolname(), *servicename(); cp = rrp; /* * Read the name of RR */ if ((n = dn_expand(msg, msg + msglen, cp, (u_char *) dname, sizeof(dname))) < 0) { hp->rcode = FORMERR; return (-1); } /* * Read the type, class, ttl, and dlen (length of data) */ cp += n; GETSHORT(type, cp); GETSHORT(class, cp); GETLONG(ttl, cp); GETSHORT(dlen, cp); origin = index(dname, '.'); if (origin == NULL) origin = ""; else origin++; /* move past the '.' */#ifdef DEBUG if (debug > 2) (void) fprintf(ddt, "print_output: dname %s type %d class %d ttl %d\n", dname, type, class, ttl);#endif /* * Convert the resource record data into the internal database * format. Set cp1 to be pointer to data. Set n to length of * data. Set cp past the data. */ switch (type) { case T_A: case T_WKS: case T_HINFO: case T_UINFO: case T_TXT: case T_UID: case T_GID: cp1 = cp; n = dlen; cp += n; break; case T_CNAME: case T_MB: case T_MG: case T_MR: case T_NS: case T_PTR: if ((n = dn_expand(msg, msg + msglen, cp, data, sizeof(data))) < 0) { hp->rcode = FORMERR; return (-1); } cp += n; cp1 = data; n = strlen((char *) data) + 1; break; case T_MINFO: case T_SOA: if ((n = dn_expand(msg, msg + msglen, cp, data, sizeof(data))) < 0) { hp->rcode = FORMERR; return (-1); } cp += n; cp1 = data + (n = strlen((char *) data) + 1); n1 = sizeof(data) - n; if (type == T_SOA) n1 -= 5 * sizeof(u_long); if ((n = dn_expand(msg, msg + msglen, cp, cp1, n1)) < 0) { hp->rcode = FORMERR; return (-1); } cp += n; cp1 += strlen((char *) cp1) + 1; if (type == T_SOA) { temp_ptr = cp + 4 * sizeof(u_long); GETLONG(minimum_ttl, temp_ptr); bcopy((char *) cp, (char *) cp1, n = 5 * sizeof(u_long)); cp += n; cp1 += n; } n = cp1 - data; cp1 = data; break; case T_MX: /* grab preference */ bcopy((char *) cp, (char *) data, sizeof(u_short)); cp1 = data + sizeof(u_short); cp += sizeof(u_short); /* get name */ if ((n = dn_expand(msg, msg + msglen, cp, cp1, sizeof(data) - sizeof(u_short))) < 0) return (-1); cp += n; /* compute end of data */ cp1 += strlen((char *) cp1) + 1; /* compute size of data */ n = cp1 - data; cp1 = data; break; default:#ifdef DEBUG if (debug >= 3) (void) fprintf(ddt, "unknown type %d\n", type);#endif return ((cp - rrp) + dlen); } if (n > MAXDATA) {#ifdef DEBUG if (debug) (void) fprintf(ddt, "update type %d: %d bytes is too much data\n", type, n);#endif hp->rcode = NOCHANGE; /* XXX - FORMERR ??? */ return (-1); } /* * cdata is a pointer to the data. */ cdata = (char *) cp1; result = cp - rrp; /* * Only print one SOA per db file */ if (type == T_SOA) { if (got_soa) return result; else got_soa++; } /* * If the origin has changed, print the new origin */ if (strcasecmp(prev_origin, origin)) { (void) strcpy(prev_origin, origin); (void) fprintf(dbfp, "$ORIGIN %s.\n", origin); } tab = 0; if (strcasecmp(prev_dname, dname)) { /* * set the prev_dname to be the current dname, then cut off all * characters of dname after (and including) the first '.' */ char *cutp = index(dname, '.'); (void) strcpy(prev_dname, dname); if (cutp) *cutp = NULL; if (dname[0] == 0) { if (origin[0] == 0) (void) fprintf(dbfp, ".\t"); else (void) fprintf(dbfp, ".%s.\t", origin); /* ??? */ } else (void) fprintf(dbfp, "%s\t", dname); if (strlen(dname) < 8) tab = 1; } else { (void) putc('\t', dbfp); tab = 1; } if (ttl != 0 && ttl != minimum_ttl) (void) fprintf(dbfp, "%d\t", (int) ttl); else if (tab) (void) putc('\t', dbfp); (void) fprintf(dbfp, "%s\t%s\t", p_class(class), p_type(type)); /* * Set cp back to the data. */ cp = (u_char *) cdata; /* * Print type specific data */ switch (type) { case T_A: switch (class) { case C_IN: case C_HS: GETLONG(n, cp); n = htonl(n); (void) fprintf(dbfp, "%s", inet_ntoa(*(struct in_addr *) & n)); break; } (void) fprintf(dbfp, "\n"); break; case T_CNAME: case T_MB: case T_MG: case T_MR: case T_PTR: if (cp[0] == '\0') (void) fprintf(dbfp, ".\n"); else (void) fprintf(dbfp, "%s.\n", cp); break; case T_NS: cp = (u_char *) cdata; if (cp[0] == '\0') (void) fprintf(dbfp, ".\t"); else (void) fprintf(dbfp, "%s.", cp); (void) fprintf(dbfp, "\n"); break; case T_HINFO: if (n = *cp++) { (void) fprintf(dbfp, "\"%.*s\"", (int) n, cp); cp += n; } else (void) fprintf(dbfp, "\"\""); if (n = *cp++) (void) fprintf(dbfp, " \"%.*s\"", (int) n, cp); else (void) fprintf(dbfp, "\"\""); (void) putc('\n', dbfp); break; case T_SOA: (void) fprintf(dbfp, "%s.", cp); cp += strlen((char *) cp) + 1; (void) fprintf(dbfp, " %s. (\n", cp); cp += strlen((char *) cp) + 1; GETLONG(n, cp); (void) fprintf(dbfp, "\t\t%lu", n); GETLONG(n, cp); (void) fprintf(dbfp, " %lu", n); GETLONG(n, cp); (void) fprintf(dbfp, " %lu", n); GETLONG(n, cp); (void) fprintf(dbfp, " %lu", n); GETLONG(n, cp); (void) fprintf(dbfp, " %lu )\n", n); break; case T_MX: GETSHORT(n, cp); (void) fprintf(dbfp, "%lu", n); (void) fprintf(dbfp, " %s.\n", cp); break; case T_UINFO: case T_TXT: cp1 = cp; (void) putc('"', dbfp); while (cp1 < cp + dlen) { if (n = (unsigned char) *cp1++) { for (j = n ; j > 0 ; j--) { if (*cp1 == '\n') (void) putc('\\', dbfp); (void) putc(*cp1++, dbfp); } } } (void) fputs("\"\n", dbfp); break; case T_UID: case T_GID: if (n == sizeof(u_long)) { GETLONG(n, cp); (void) fprintf(dbfp, "%lu\n", n); } break; case T_WKS: GETLONG(addr, cp); addr = htonl(addr); (void) fprintf(dbfp, "%s ", inet_ntoa(*(struct in_addr *) & addr)); proto = protocolname(*cp); cp += sizeof(char); (void) fprintf(dbfp, "%s ", proto); i = 0; while (cp < (u_char *) cdata + n) { j = *cp++; do { if (j & 0200) (void) fprintf(dbfp, " %s", servicename(i, proto)); j <<= 1; } while (++i & 07); } (void) fprintf(dbfp, "\n"); break; case T_MINFO: (void) fprintf(dbfp, "%s.", cp); cp += strlen((char *) cp) + 1; (void) fprintf(dbfp, " %s.\n", cp); break; default: (void) fprintf(dbfp, "???\n"); } if (ferror(dbfp)) { syslog(LOG_ERR, "%s: %m", tmpname); exit(XFER_FAIL); } return result;}/* * Make a copy of a string and return a pointer to it. */char *savestr(str) char *str;{ char *cp; cp = malloc((unsigned)strlen(str) + 1); if (cp == NULL) { syslog(LOG_ERR, "savestr: %m"); exit(XFER_FAIL); } (void) strcpy(cp, str); return (cp);}#define YES 1#define NO 0mkstemp(as) char *as;{ int fd; return (_gettemp(as, &fd) ? fd : -1);}char *mktemp(as) char *as;{ return(_gettemp(as, (int *)NULL) ? as : (char *)NULL);}static_gettemp(as, doopen) char *as; register int *doopen;{ extern int errno; register char *start, *trv; struct stat sbuf; u_int pid; pid = getpid(); /* extra X's get set to 0's */ for (trv = as; *trv; ++trv); while (*--trv == 'X') { *trv = (pid % 10) + '0'; pid /= 10; } /* * check for write permission on target directory; if you have * six X's and you can't write the directory, this will run for * a *very* long time. */ for (start = ++trv; trv > as && *trv != '/'; --trv); if (*trv == '/') { *trv = '\0'; if (stat(as, &sbuf) || !(sbuf.st_mode & S_IFDIR)) return(NO); *trv = '/'; } else if (stat(".", &sbuf) == -1) return(NO); for (;;) { if (doopen) { if ((*doopen = open(as, O_CREAT|O_EXCL|O_RDWR, 0600)) >= 0) return(YES); if (errno != EEXIST) return(NO); } else if (stat(as, &sbuf)) return(errno == ENOENT ? YES : NO); /* tricky little algorithm for backward compatibility */ for (trv = start;;) { if (!*trv) return(NO); if (*trv == 'z') *trv++ = 'a'; else { if (isdigit(*trv)) *trv = 'a'; else ++*trv; break; } } } /*NOTREACHED*/}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?