RELEASEC.SAV0 RELEASEC.SAV;BACKUP/LOG/INTERCHANGE RELCDIR RELEASEC.SAV/SAVE/BLOCK=8192 ORCHARD @tvV5.3 _ETHEL::  _$1$DUA1: V5.3  :*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]AALLOC.C;8+,./@ 4U-B0123 KPWO5 6 7 +Qe&8`!e o9G@HJ/*< * Routine to call c memory allocation routines and abort if * they fail. * Bruce Orchard, August 5, 1988 *9 * If LOG is defined, all calls will be logged to stdout. */#include #include "domser.h" #ifdef LOGstatic int call_number;#endifchar *amalloc (nc) int nc;{ char *p; p = malloc (nc);- if (p == 0) signal_abort (DOMS$_OUTPMEM); #ifdef LOGR printf ("%6d malloc %08X %08X %5d\n", ++call_number, calling_pc (), p, nc);#endif return p;}char *acalloc (ns, ss) int ns, ss;{ char *p; p = calloc (ns, ss);- if (p == 0) signal_abort (DOMS$_OUTPMEM); #ifdef LOGU printf ("%6d calloc %08X %08X %5d\n", ++call_number, calling_pc (), p, ns*ss);#endif return p;}void afree (p) char *p;{ #ifdef LOGJ printf ("%6d free %08X %08X \n", ++call_number, calling_pc (), p);#endif free (p);} B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ADD_TCP_PREFIX.C;1+,"./@ 4"-B0123 KPWO56@Iؒ7Rؒ8pw o9G@HJ/* * Add TCP prefix to message" * Bruce Orchard, November 9, 1989 */void add_tcp_prefix ( unsigned char *m, int length) { *m++ = (length >> 8) & 0377; *m++ = (length) & 0377;} B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ADD_UDP_PREFIX.C;4+,./@ 4Y-B0123 KPWO56(ǒ7@peؒ8ڏ o9G@HJ/*- * Add UDP address prefix for CMU TCP package" * Bruce Orchard, October 18, 1989 */void add_udp_prefix ( unsigned char *m, int source_address, int source_port, int destination_address, int destination_port) {O *m++ = (source_address >> 24) & 0377; /* Source address in network order */) *m++ = (source_address >> 16) & 0377;( *m++ = (source_address >> 8) & 0377;# *m++ = (source_address) & 0377;Y *m++ = (destination_address >> 24) & 0377; /* Destination address in network order */. *m++ = (destination_address >> 16) & 0377;- *m++ = (destination_address >> 8) & 0377;( *m++ = (destination_address) & 0377;H *m++ = (source_port) & 0377; /* Source port in VAX order */% *m++ = (source_port >> 8) & 0377;R *m++ = (destination_port) & 0377; /* Destination port in VAX order */* *m++ = (destination_port >> 8) & 0377;} E*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ANALYZE_AUTHORITY.C;6+,%./@ 4ot-B0123 KPWO56t7@o-:8D o9G@HJ /*@ * Function to determine which RR's of a zone are authoritative. * Bruce Orchard, June 11, 1988 * * Return: * 0: RR list is improper * 1: RR list is proper */#include "domser.h"#include #include struct dn_ { struct dn_ *dn_next; char *dn_name;};#static int suffix (char *, char *);int analyze_authority (rr)E struct rr_ *rr; /* RR list (private memory) */B /* Should start with SOA */{ struct rr_ *cr; struct a_ *a;6 struct dn_ *dn_first=0, *dn_last=0, *dn, *dn_next; char *soa_name; long int soa_minimum; if (rr == 0) return 0;* if (rr -> rr_type != RR_SOA) return 0;$ soa_name = rr -> rr_name_string;: soa_minimum = ((struct rr_sa_ *) rr) -> rr_sa_minimum;: for (cr = rr; cr != 0; cr = cr -> rr_link . lp_next) {% if (cr -> rr_type == RR_NS) {A if (seqnc (soa_name, cr -> rr_name_string)) continue;2 dn = acalloc (1, sizeof (struct dn_)); if (dn_first == 0) { dn_first = dn; } else {( dn_last -> dn_next = dn; } dn_last = dn;1 dn -> dn_name = cr -> rr_name_string; } }: for (cr = rr; cr != 0; cr = cr -> rr_link . lp_next) {' a = cr -> rr_a_head . hp_first; if (a == 0) abort ();? if (a -> a_ttl < soa_minimum) a -> a_ttl = soa_minimum;j if (!suffix (soa_name, cr -> rr_name_string)) goto not_authority; /* Must be a glue RR */: for (dn = dn_first; dn != 0; dn = dn -> dn_next) {o if (suffix (dn -> dn_name, cr -> rr_name_string)) goto not_authority; /* Found an applicable NS */ } a -> a_authority = 1; continue; not_authority: a -> a_authority = 0; }0 for (dn = dn_first; dn != 0; dn = dn_next) { dn_next = dn -> dn_next; afree (dn); } return 1;}/*9 * Function to check if string a is a suffix of string b.4 * It is also true if string a is equal to string b. */static int suffix (a, b) char *a, *b;{ char *aa, *bb, ca, cb; aa = a; while (*aa++);K aa -= 2; /* aa -> last character of string */ bb = b; while (*bb++);K bb -= 2; /* bb -> last character of string */ while (1) { ca = *aa--; cb = *bb--;3 if (toupper (ca) != toupper (cb)) return 0; if (aa < a) return 1; if (bb < b) return 0; }}<*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ARITH64.H;26+,./@ 45-B0123 KPWO56@LU-7  M8 9G@HJtypedef int int32;struct int64 { long int l; long int h;};typedef struct int64 int64;int64 add646464 (int64, int64);int64 conv3264 (int32);int64 conv3264s (int32);int32 conv6432 (int64);int current_year ();int64 current_date ();int64 current_date_time ();int64 current_time ();int64 div646464 (int64, int64);int eq6464 (int64, int64);int ge6464 (int64, int64);int gt6464 (int64, int64);int le6464 (int64, int64);int lt6464 (int64, int64);int64 mul326464 (i~Q RELEASEC.SAVB<[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ARITH64.H;265nt32, int64);int64 mul646464 (int64, int64);int64 sub646464 (int64, int64);int64 vdate (int, int, int);(void mdate (int64, int *, int *, int *);5void mdatetime (int64, int *, int *, int *, int64 *);(void mtime (int64, int *, int *, int *);int day_of_week (int64);+int64 local_time_to_universal_time (int64);+int64 universal_time_to_local_time (int64);int64 summer_start (int);int64 summer_end (int);char *sdate (int64);?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ARITH64.MAR;100+,(."/@ 4`""-B0123 KPWO#5Y6 EB-7`.h8`x`9G@HJ .TITLE ARITH64;"; 64 bit arithmetic routines for C; Bruce Orchard, April 5, 1989;6; Note that all these routines are called by value and; return a value.;/; These routines treat all numbers as unsigned.;;D; Add a 64 bit integer and a 64 bit integer giving a 64 bit integer;& .PSECT ARITH64_CODE,EXE,PIC,NOWRT,SHR .ENTRY ADD646464,0RET=4A=8B=16; MOVL RET(AP),R1 ; R1 -> result area= ADDL3 A(AP),B(AP),(R1) ; Add low order wordsD MOVL A+4(AP),R0 ; High order word of A -> R0> ADWC B+4(AP),R0 ; High order sum -> R0? MOVL R0,4(R1) ; Return high order sum0 RET ; Return;6; Convert a signed 32 bit integer to a 64 bit integer; .ENTRY CONV3264S,0RET=4A=8W ASHQ #-32,A-4(AP),@RET(AP) ; Sign extend a whole word to do the conversion RET;9; Convert an unsigned 32 bit integer to a 64 bit integer; .ENTRY CONV3264,0RET=4A=88 MOVL A(AP),R0 ; Argument -> R0< CLRL R1 ; 0 -> R1, High word> MOVQ R0,@RET(AP) ; Return 64 bit number RET;/; Convert a 64 bit integer to a 32 bit integer; .ENTRY CONV6432,0D=4M MOVL D(AP),R0 ; Just throw away the high order word RET;G; Divide a 64 bit integer by a 64 bit integer giving a 64 bit quotient;K; The argorithm used is based on Algorithm D in Knuth, volume 2, page 237.F; Here the radix is 2**16. (Not 2**32--there is no unsigned divide.);= .ENTRY DIV646464,^MRET=42A=8 ; Dividend1B=16 ; Divisor2Q=-20 ; QuotientQN=-28P=-40NCT=-44NNCT=-48FRAME=48J SUBL #FRAME,SP ; Make room on stack for work areaE CLRL R2 ; Clear high word of dividend> MOVQ A(AP),R0 ; Dividend -> R2-R1-R0: MOVQ B(AP),R3 ; Divisor -> R3-R4B CLRQ Q(FP) ; Clear quotient work areaG BITL #^XFFFF0000,R4 ; Is high quarter of divisor 0?- BEQL D200 ; YesED101: BBS #31,R4,D102 ; Is high bit of divisor set?S ASHQ #1,R1,R1 ; No: Shift high 2 words of dividend leftL ASHL #-1,R1,R1 ; Shift middle word of dividend backN ASHQ #1,R0,R0 ; Shift low two words of dividend left< ASHQ #1,R3,R3 ; Shift divisor left= BRB D101 ; Go recheck high bitDD102: MOVL R4,R5 ; High word of divisor -> R5D ASHL #-16,R5,R5 ; Move 16 bit chunk to right= BICL #^XFFFF0000,R5 ; Undo sign extensionK MOVQ R1,R6 ; High 2 words of dividend -> R7-R6D ASHQ #-16,R6,R6 ; Put desired 2 chunks in R6G EDIV R5,R6,R8,R9 ; Quotient chunk estimate -> R8@D103: MOVL R8,Q(FP) ; Save quotient estimate MOVL R8,QN(FP) CLRL QN+4(FP)D JSB CHECKQ ; See if quotient is too big, BEQL D104 ; OK@ SUBL #1,R8 ; Too big: decrement it; BRB D103 ; Check the new try:D104: JMP D001 ; Go return resultQD200: BITL #^X0000FFFF,R4 ; Is the second chunk of divisor nonzero?- BNEQ D200A ; YesC JMP D300 ; No: Go check third chunk=D200A: CLRL R5 ; Clear shift counter@D201: BBS #15,R4,D202 ; Is divisor normalized?S ASHQ #1,R1,R1 ; No: Shift high 2 words of dividend leftL ASHL #-1,R1,R1 ; Shift middle word of dividend backN ASHQ #1,R0,R0 ; Shift low two words of dividend left< ASHQ #1,R3,R3 ; Shift divisor left; INCL R5 ; Count bit shifted= BRB D201 ; Go recheck high bit:D202: MOVL R5,NCT(FP) ; Save shift count MNEGL R5,NNCT(FP)D MOVL R4,R5 ; High word of divisor -> R5K MOVQ R1,R6 ; High 2 words of dividend -> R7-R6D ASHQ #-16,R6,R6 ; Put desired 2 chunks in R6G EDIV R5,R6,R8,R9 ; Quotient chunk estimate -> R8GD203: MOVW R8,Q+2(FP) ; Position quotient and save it CLRQ QN(FP) MOVW R8,QN+2(FP)D JSB CHECKQ ; See if quotient is too big, BEQL D204 ; OK@ DECL R8 ; Too big: decrement it; BRB D203 ; Check the new tryD204: CLRL R2 MOVQ A(AP),R0 ASHQ NCT(FP),R1,R1 ASHL NNCT(FP),R1,R1 ASHQ NCT(FP),R0,R0 MOVL R4,R5 MOVL R1,R6 CLRL R7 EDIV R5,R6,R8,R9D205: MOVW R8,Q(FP) MOVL R8,QN(FP) JSB CHECKQ BEQL D206 DECL R8 BRB D205D206: JMP D001ND300: BITL #^XFFFF0000,R3 ; Is the third chunk of the divisor 0? BNEQ D300A ; No- JMP D400 ; YesBD300A: CLRL R5 ; 0 -> R5, normalize count@D301: BBS #31,R3,D302 ; Is divisor normalized?S ASHQ #1,R1,R1 ; No: Shift high 2 words of dividend leftL ASHL #-1,R1,R1 ; Shift middle word of dividend backN ASHQ #1,R0,R0 ; Shift low two words of dividend left< ASHQ #1,R3,R3 ; Shift divisor left; INCL R5 ; Count bit shifted= BRB D301 ; Go recheck high bit>D302: MOVL R5,NCT(FP) ; Save normalize countJ MNEGL R5,NNCT(FP) ; Save negative of normalize countC MOVL R3,R5 ; Low word of divisor -> R5@ ASHL #-16,R5,R5 ; Shift dis RELEASEC.SAV(B?[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ARITH64.MAR;100`"fvisor to rightE BICL #^XFFFF0000,R5 ; Undo sign extend from shiftK MOVQ R1,R6 ; High 2 words of dividend -> R7-R6D ASHQ #-16,R6,R6 ; Put desired 2 chunks in R6G EDIV R5,R6,R8,R9 ; Quotient chunk estimate -> R8GD303: MOVW R8,Q+4(FP) ; Position quotient and save itA CLRQ QN(FP) ; Clear new quotient wordA MOVW R8,QN+4(FP) ; Save new quotient chunkD JSB CHECKQ ; See if quotient is too big, BEQL D304 ; OK@ DECL R8 ; Too big: decrement it; BRB D303 ; Check the new tryLD304: CLRL R2 ; Clear R2 for high part of dividendE MOVQ A(AP),R0 ; Remaining dividend -> R1-R0L ASHQ NCT(FP),R1,R1 ; Shift R2-R1 to match divisor shift4 ASHL NNCT(FP),R1,R1 ; Unshift R1L ASHQ NCT(FP),R0,R0 ; Shift R1-R0 to match divisor shiftC MOVL R3,R5 ; Low word of divisor -> R5Z ASHL #-16,R5,R5 ; Shift most significant chunk of divisor to rightE BICL #^XFFFF0000,R5 ; Undo sign extend from shiftG MOVL R1,R6 ; Second part of dividend -> R6I CLRL R7 ; Clear high word of EDIV divisorA EDIV R5,R6,R8,R9 ; Estimate quotient chunkb>D305: MOVW R8,Q+2(FP) ; Store quotient chunkA CLRQ QN(FP) ; Clear new quotient wordaB MOVL R8,QN+2(FP) ; Store new quotient chunkF JSB CHECKQ ; Multiply quotient by divisorB BEQL D306 ; Branch if quotient is OKN DECL R8 ; Quotient is too large: Decrement it= BRB D305 ; Go recheck quotientrLD306: CLRL R2 ; Clear R2 for high part of dividendE MOVQ A(AP),R0 ; Remaining dividend -> R1-R0 L ASHQ NCT(FP),R1,R1 ; Shift R2-R1 to match divisor shift4 ASHL NNCT(FP),R1,R1 ; Unshift R1L ASHQ NCT(FP),R0,R0 ; Shift R1-R0 to match divisor shiftC MOVL R3,R5 ; Low word of divisor -> R5hZ ASHL #-16,R5,R5 ; Shift most significant chunk of divisor to rightE BICL #^XFFFF0000,R5 ; Undo sign extend from shift F MOVQ R0,R6 ; Third part of dividend -> R6A ASHQ #-16,R6,R6 ; Shift dividend to right I CLRL R7 ; Clear high word of EDIV divisor A EDIV R5,R6,R8,R9 ; Estimate quotient chunk>D307: MOVW R8,Q(FP) ; Store quotient chunkA CLRQ QN(FP) ; Clear new quotient word B MOVL R8,QN(FP) ; Store new quotient chunkF JSB CHECKQ ; Multiply quotient by divisorB BEQL D001 ; Branch if quotient is OKN DECL R8 ; Quotient is too large: Decrement it= BRB D307 ; Go recheck quotient ; ; Return quotient;29D001: MOVQ Q(FP),@RET(AP) ; Return quotient40 RET ; Return;A@; The high order 48 bit of the divisor are 0: The estimates are; now guaranteed to be right. ;aGD400: ASHL #-16,R1,R4 ; First chunk of dividend -> R4e? BICL #^XFFFF0000,R4 ; Clear high half of R4 D CLRL R5 ; Clear high word for divideO EDIV R3,R4,R6,R7 ; Quotient chunk -> R6, remainder -> R7I ASHL #16,R6,R9 ; First quotient chunk -> high R8 G BICL #^XFFFF0000,R1 ; Clear first chunk of dividend < ASHL #16,R7,R7 ; Position remainderQ BISL R7,R1 ; Combine remainder with rest of dividendQS MOVL R1,R4 ; First and second chunks of dividend -> R41D CLRL R5 ; Clear high word for divideO EDIV R3,R4,R6,R7 ; Quotient chunk -> R6, remainder -> R7i; BISL R6,R9 ; Combine quotients = MOVL R7,R1 ; Move remainder back5S ASHQ #-16,R0,R4 ; Second and third chunks of dividend -> R4rD CLRL R5 ; Clear high word for divideO EDIV R3,R4,R6,R7 ; Quotient chunk -> R6, remainder -> R7kD ASHL #16,R6,R8 ; Third quotient chunk -> R8G BICL #^XFFFF0000,R0 ; Clear third chunk of dividend < ASHL #16,R7,R7 ; Position remainderB BISL R7,R0 ; Put third remainder backE CLRL R1 ; Clear high word of dividend O EDIV R3,R0,R6,R7 ; Quotient chunk -> R6, remainder -> R7r: BISL R6,R8 ; Combine quotient9 MOVQ R8,@RET(AP) ; Return quotient 0 RET ; Return; $; Check quotient and update dividend;2CHECKQ: CLRL R11 " EMUL B(AP),QN(FP),#0,R9 TSTL B(AP), BGEQ CK1  ADDL QN(FP),R10CK1: TSTL QN(FP) BGEQ CK2i ADDL B(AP),R10dCK2: MOVQ R9,P(FP) MOVL R11,P+8(FP) $ EMUL B+4(AP),QN(FP),#0,R9 TSTL B+4(AP)  BGEQ CK3  ADDL QN(FP),R10CK3: TSTL QN(FP) BGEQ CK4i ADDL B+4(AP),R105CK4: ADDL R9,P+4(FP) ADWC R10,P+8(FP) $ EMUL B(AP),QN+4(FP),#0,R9 TSTL B(AP)L BGEQ CK5  ADDL QN+4(FP),R10CK5: TSTL QN+4(FP) BGEQ CK6  ADDL B(AP),R10rCK6: ADDL R9,P+4(FP) ADWC R10,P+8(FP)  TSTL P+8(FP)e BGTRU CK9  CMPL P+4(FP),A+4(AP)  BGTRU CK9i BLSSU CK8  CMPL P(FP),A(AP)t BGTRU CK9>CK8: SUBL P(FP),A(AP)F SBWC P+4(FP),A+4(AP)nC MOVL #0,R10 ; Quotient is OK: Return 00 RSB ; ReturnJCK9: MOVL #1,R10 ; Quotient is too large: Return 10 RSB ; Return; @; Compare 2 64 bit intgers. Return 1 if equal or 0 if unequal.;  .ENTRY EQ6464,0X=4QY=12+ CMPL X+4(AP),Y+4(AP) ; Compare high words  BNEQ EQ.N ; Unequal& CMPL X(AP),Y(AP) ; Compare low words BNEQ EQ.N ; Unequal MOVL #1,R0 ; Equal: Return 1 RET ; Return$EQ.N: CLRL R0 ; Unequal: Return 0 RET ; Return; Q; Compare 2 64 bit intgers. Return 1 if first >= second or 0 if first < second. ;  .ENTRY GE6464,0X=4 Y=12+ CMPL X+4(AP),Y+4(AP) ; Compare high wordss BGTRU GE.Y ; Greateri BLSSU GE.N ; Less& CMPL X(AP),Y(AP) ; Compare low words BGTRU GE.Y ; GreaterL BEQLU GE.Y ; Equal 2GE.N: MOVL #0,R0 ; Less than or equal: Return 0 RET ; Return'GE.Y: MOVL #1,R0 ; Greater: Return 1Q RET ; Return; Q; Compare 2 64 bit intgers. Return 1 if first > second or 0 if first <= second. ;  .ENTRY GT6464,0X=4 Y=12+ CMPL X+4(AP),Y+4(AP) ; CMf RELEASEC.SAV(B?[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ARITH64.MAR;100`" ompare high words  BGTRU GT.Y ; Greaterd BLSSU GT.N ; Less& CMPL X(AP),Y(AP) ; Compare low words BGTRU GT.Y ; Greater 2GT.N: MOVL #0,R0 ; Less than or equal: Return 0 RET ; Return'GT.Y: MOVL #1,R0 ; Greater: Return 1g RET ; Return; Q; Compare 2 64 bit intgers. Return 1 if first <= second or 0 if first > second. ;  .ENTRY LE6464,0X=4rY=12+ CMPL X+4(AP),Y+4(AP) ; Compare high words  BGTRU LE.N ; Greater> BLSSU LE.Y ; Less& CMPL X(AP),Y(AP) ; Compare low words BLSSU LE.Y ; Less BEQLU LE.Y ; Equal 2LE.N: MOVL #0,R0 ; Less than or equal: Return 0 RET ; Return'LE.Y: MOVL #1,R0 ; Greater: Return 1 RET ; Return; Q; Compare 2 64 bit intgers. Return 1 if first < second or 0 if first >= second. ;  .ENTRY LT6464,0X=4mY=12+ CMPL X+4(AP),Y+4(AP) ; Compare high words  BGTRU LT.N ; Greatera BLSSU LT.Y ; Less& CMPL X(AP),Y(AP) ; Compare low words BLSSU LT.Y ; Less2LT.N: MOVL #0,R0 ; Less than or equal: Return 0 RET ; Return'LT.Y: MOVL #1,R0 ; Greater: Return 1o RET ; Return; I; Multiply a 32 bit integer and a 64 bit integer giving a 64 bit product ; .ENTRY MUL326464,^MRET=4 A=8 C=12D EMUL A(AP),C(AP),#0,R0 ; A * low half of C -> R1-R0` EMUL A(AP),C+4(AP),R1,R1 ; A * high half of C + high half of last result -> R2-R1D TSTL C(AP) ; Is low word of C negative?, BGEQ 20$ ; NoN ADDL A(AP),R1 ; Yes: Cancel sign extension EMUL did720$: MOVQ R0,@RET(AP) ; Return result 0 RET ; Return; 1; Multiply a 64 bit integer and a 64 bit integerc;k .ENTRY MUL646464,^MRET=4FA=80B=16 MOVL RET(AP),R2# EMUL A(AP),B(AP),#0,(R2) MULL3 A+4(AP),B(AP),R0 MULL3 A(AP),B+4(AP),R1 ADDL R1,R0l TSTL A(AP)i BGEQ 10$  ADDL B(AP),R010$: TSTL B(AP)n BGEQ 20$8 ADDL A(AP),R020$: ADDL R0,4(R2) RETF; J; Subtract a 64 bit integer from a 64 bit integer giving a 64 bit integer;  .ENTRY SUB646464,0RET=4 1A=8 ; Minuend 4B=16 ; Subtrahend; MOVL RET(AP),R1 ; R1 -> result area B SUBL3 B(AP),A(AP),(R1) ; Subtract low order wordsD MOVL A+4(AP),R0 ; High order word of A -> R0E SBWC B+4(AP),R0 ; High order difference -> R00F MOVL R0,4(R1) ; Return high order difference0 RET ; Return .END ; Unshift R1L ASHQ NCT(FP),R0,R0 ; Shift R1-R0 to match divisor shiftC MOVL R3,R5 ; Low word of divisor -> R5hZ ASHL #-16,R5,R5 ; Shift most significant chunk9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ATIME.C;6+,*./@ 4\$-B0123 KPWO56l7 eؒ8 o9G@HJ/*= * Function to convert a time in seconds since Jan 1, 1980 to * a printable date/time string. *! * Bruce Orchard, October 3, 1989 */#include #include char *atime (t) long int t;{ static int first=1; static int64 BASE, LSECOND; int64 lt; if (first) { first = 0; BASE = vdate (1, 1, 80); LSECOND = conv3264 (10000000); }\ lt = universal_time_to_local_time (add646464 (mul646464 (conv3264 (t), LSECOND), BASE)); return sdate (lt);}@*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]BUILD_ALL.COM;16+,. /@ 4U -B0123KPWO 56`7?d8;r9G@HJ )$ here_file = f$environment ("procedure")U$ here_directory = f$parse (here_file,,,"device") + f$parse (here_file,,,"directory")!$ define domsdir 'here_directory'$ define hdir 'here_directory'$$ define arith64dir 'here_directory'!$ define cmuhdir 'here_directory'$ lib/log/create domser.olb$ CC AALLOC.C /OBJ$ lib/log/insert domser AALLOC$ CC ADD_TCP_PREFIX.C /OBJ&$ lib/log/insert domser ADD_TCP_PREFIX$ CC ADD_UDP_PREFIX.C /OBJ&$ lib/log/insert domser ADD_UDP_PREFIX$ CC ANALYZE_AUTHORITY.C /OBJ)$ lib/log/insert domser ANALYZE_AUTHORITY$ MACRO ARITH64.MAR /OBJ$ lib/log/insert domser ARITH64$ CC ATIME.C /OBJ$ lib/log/insert domser ATIME$ CC CHECK.C /OBJ$ CC CHECK_DATA.C /OBJ"$ lib/log/insert domser CHECK_DATA$ CC CLEAN_EXPIRED.C /OBJ%$ lib/log/insert domser CLEAN_EXPIRED$ CC CLI_GET_VALUE.C /OBJ%$ lib/log/insert domser CLI_GET_VALUE$ CC CLI_NEGATED.C /OBJ#$ lib/log/insert domser CLI_NEGATED$ CC CLI_PRESENT.C /OBJ#$ lib/log/insert domser CLI_PRESENT$ CC CREATE_PROCESS.C /OBJ&$ lib/log/insert domser CREATE_PROCESS$ CC CURRENT_TIME.C /OBJ$$ lib/log/insert domser CURRENT_TIME$ CC DAY_OF_WEEK.C /OBJ#$ lib/log/insert domser DAY_OF_WEEK$ CC DELAY.C /OBJ$ lib/log/insert domser DELAY$ CC DELAYMS.C /OBJ$ lib/log/insert domser DELAYMS$ CC DELETE.C /OBJ$ lib/log/insert domser DELETE$ CC DELETE_ZONE.C /OBJ#$ lib/log/insert domser DELETE_ZONE$ MESSAGE DOMSER_MSG.MSG /OBJ"$ lib/log/insert domser DOMSER_MSG$ CC DO_QUERY.C /OBJ $ lib/log/insert domser DO_QUERY$ CC EXAMINE.C /OBJ$ CC EXIT_REQUESTED.C /OBJ&$ lib/log/insert domser EXIT_REQUESTED$ CC FIND_LOCK_NAME.C /OBJ&$ lib/log/insert domser FIND_LOCK_NAME$ CC GETJPI_ME_INT.C /OBJ%$ lib/log/insert domser GETJPI_ME_INT$ CC GLOBAL.C /OBJ$ lib/log/insert domser GLOBAL$ CC LEXIC.C /OBJ$ lib/log/insert domser LEXIC$ CC LIST_MANAGE.C /OBJ#$ lib/log/insert domser LIST_MANAGE$ CC LOCK.C /OBJ$ lib/log/insert domser LOCK$ CC LOOKUP.C /OBJ%$ SET COMMAND LOOKUP_COMMAND.CLD /OBJ$ MESSAGE LOOKUP_MSG.MSG /OBJ$ CC LOOK_UP_PROTOCOL.C /OBJ($ lib/log/insert domser LOOK_UP_PROTOCOL$ CC LOOK_UP_SERVER.C /OBJ&$ lib/log/insert domser LOOK_UP_SERVER$ CC MCOM.C /OBJ$ lib/log/insert domser MCOM$ CC MDATE.C /OBJ$ lib/log/insert domser MDATE$ MESSAGE NETERROR.MSG /OBJ $ lib/log/insert domser NETERROR$ CC NETWORK_ERROR_CHECK.C /OBJ+$ lib/log/insert domser NETWORK_ERROR_CHECK$ CC OP_MESSAGE.C /OBJ"$ lib/log/insert domser OP_MESSAGE$ CC PACK_MESSAGE.C /OBJ$$ lib/log/insert domser PACK_MESSAGE$ CC PARSE_MESSAGE.C /OBJ%$ lib/log/insert domser PARSE_MESSAGE$ CC PASS_ON_QUERY.C /OBJ%$ lib/log/insert domser PASS_ON_QUERY$ CC PERIODIC_UPDATE.C /OBJ$ CC PREFERRED_ADDRESS.C /OBJ)$ lib/log/insert domser PREFERRED_ADDRESS$ CC PRINT.C /OBJ$ CC PRINT_MESSAGE.C /OBJ%$ lib/log/insert domser PRINT_MESSAGE$ CC PROCESS_QUERY.C /OBJ%$ lib/log/insert domser PROCESS_QUERY$ CC PUT_1_MESSAGE.C /OBJ%$ lib/log/insert domser PUT_1_MESSa RELEASEC.SAVB@[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]BUILD_ALL.COM;16U AGE$ CC READ_RR.C /OBJ$ lib/log/insert domser READ_RR$ CC RECEIVE.C /OBJ$ lib/log/insert domser RECEIVE$ CC RRNAME.C /OBJ$ lib/log/insert domser RRNAME$ CC SDATE.C /OBJ$ lib/log/insert domser SDATE$ CC SEND.C /OBJ$ lib/log/insert domser SEND$ CC SEQ.C /OBJ$ lib/log/insert domser SEQ$ CC SEQNC.C /OBJ$ lib/log/insert domser SEQNC$ CC SERVE_TCP.C /OBJ$ CC SERVE_UDP.C /OBJ$ CC SERVE_UDP_FORKED.C /OBJ$ CC SET_PROGRAM_TYPE.C /OBJ($ lib/log/insert domser SET_PROGRAM_TYPE$ CC SIGNAL_ABORT.C /OBJ$$ lib/log/insert domser SIGNAL_ABORT$ CC START.C /OBJ$ CC STOP.C /OBJ$ CC STORE_STRING.C /OBJ$$ lib/log/insert domser STORE_STRING$ CC S_ALLOC.C /OBJ$ lib/log/insert domser S_ALLOC$ CC S_DEALLOC.C /OBJ!$ lib/log/insert domser S_DEALLOC$ CC TIME_STAMP.C /OBJ"$ lib/log/insert domser TIME_STAMP$ MACRO TRANSFER.MAR /OBJ $ lib/log/insert domser TRANSFER$ CC TRANSLATE_LOGICAL.C /OBJ)$ lib/log/insert domser TRANSLATE_LOGICAL$ CC UNIVERSAL_TIME.C /OBJ&$ lib/log/insert domser UNIVERSAL_TIME$ CC UPDATE_PRIMARY.C /OBJ$ CC UPDATE_RR.C /OBJ!$ lib/log/insert domser UPDATE_RR$ CC UPDATE_ZONE_RR.C /OBJ&$ lib/log/insert domser UPDATE_ZONE_RR$ CC VDATE.C /OBJ$ lib/log/insert domser VDATE$ CC ZERO.C /OBJ$ lib/log/insert domser ZERO$ CC ZONE_TRANSFER_IN.C /OBJ($ lib/log/insert domser ZONE_TRANSFER_IN$ CC ZONE_TRANSFER_OUT.C /OBJ)$ lib/log/insert domser ZONE_TRANSFER_OUT$$ link DOMSSHR.OPT/OPT/SHARE=DOMSSHR"$ set protect=world:re DOMSSHR.EXE$ link CHECK.OPT/OPT $ set protect=world:re CHECK.EXE$ link EXAMINE.OPT/OPT"$ set protect=world:re EXAMINE.EXE$ link LOOKUP.OPT/OPT!$ set protect=world:re LOOKUP.EXE$ link PERIODIC_UPDATE.OPT/OPT*$ set protect=world:re PERIODIC_UPDATE.EXE$ link PRINT.OPT/OPT $ set protect=world:re PRINT.EXE$ link SERVE_TCP.OPT/OPT$$ set protect=world:re SERVE_TCP.EXE$ link SERVE_UDP.OPT/OPT$$ set protect=world:re SERVE_UDP.EXE$ link SERVE_UDP_FORKED.OPT/OPT+$ set protect=world:re SERVE_UDP_FORKED.EXE$ link START.OPT/OPT $ set protect=world:re START.EXE$ link STOP.OPT/OPT$ set protect=world:re STOP.EXE$ link UPDATE_PRIMARY.OPT/OPT)$ set protect=world:re UPDATE_PRIMARY.EXE@*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CALLING_PC.MAR;2+,+./@ 46 -B0123 KPWO56 m%7%89G@HJ .TITLE CALLING_PC4; C function to return the PC of the calling routine"; Bruce Orchard, February 15, 1990;) .PSECT CALLING_PC_CODE,EXE,PIC,NOWRT,SHR .ENTRY CALLING_PC,06 MOVL 12(FP),R0 ; R0 -> frame of caller of CALLING_PC" MOVL 16(R0),R0 ; Stored PC -> R0 RET .END9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CHECK.C;1+,?O./@ 4[h-B0123 KPWO56lGNAޒ7`Aޒ8 o9G@HJ/*& * Program to check domain server data# * Bruce Orchard, November 16, 1989 */#include "domser.h"#include main (argc, argv) int argc; char *argv[];{ int status; map_mcom (); status = check_data ();[ printf (status ? "Domain data passes all checks\n" : "Domain data fails some check\n");};*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CHECK.OPT;2+,F./@ 4  -B0123KPWO56.pAޒ7BM08q9G@HJ domsdir:check domsshr/share?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CHECK_DATA.C;23+,U./@ 4-B0123 KPWO56ݒ7+a8V" o9G@HJ /*$ * Function to check the shared data# * Bruce Orchard, November 16, 1989 */#include "domser.h"#include #include #static void check_pointer (char *);%static void check_lock (struct l_ *);2static void check_name (struct n_ *, struct n_ *);6static void check_rr_list (struct n_ *, struct hp_ *);static void check_zone ();static void check_forward ();static int write_count;static jmp_buf get_out;static int error_count;int check_data () { struct b_ *bb, *be; error_count = 0; if (setjmp (get_out) != 0) { return 0; } write_count = 0;G if (((struct b_ *) mcom_base) -> b_size != size_word (struct f_)) {: printf ("First word of shared memory is wrong\n"); return 0; }W for (bb = mcom_base; (int *) bb < f -> f_top; bb = (int *) bb + bb -> b_size + 2) {# be = bb + bb -> b_size + 1;+ if (be -> b_size != bb -> b_size) {A printf ("Block size mismatch: %08x %08x\n", bb, be); return 0; } }% check_lock (& f -> f_alloc_lock);! check_lock (& f -> f_n_lock);! check_lock (& f -> f_z_lock);" check_lock (& f -> f_fw_lock);" check_lock (& f -> f_kc_lock);" check_lock (& f -> f_pa_lock);" check_lock (& f -> f_ru_lock);E check_name (abspointer (f -> f_n_head . hp_first, struct n_), 0); check_zone (); check_forward (); if (write_count > 0) {1 printf ("%d write locks\n", write_count); return 0; } return error_count == 0;}static void check_lock (l)_ struct l_ *l; /* Pointer to lock to check (shared memory, absolute) */{ if (l -> l_nwrite) { write_count++; l -> l_nwrite = 0; }}/*) * Check for write locks in the name tree */static void check_name (_ struct n_ *n, /* Pointer to name to check (shared memory, absolute) */] struct n_ *np ) /* Pointer to parent name (shared memory, absolute) */{ struct n_ *nd, *nb; struct rp_ *rp; struct h_ *h; int i;T if (!((np == 0 && n -> n_up == 0) || abspointer (n -> n_up, struct n_) == np)) {E printf ("%08X: n_up mismatch\n", relpointer (n, struct n_)); longjmp (get_out, 1); } check_pointer (n); check_lock (& n -> n_lock); rp = n -> n_rr; if (rp != 0) {) rp = abspointer (rp, struct rp_);. check_rr_list (n, & rp - s. RELEASEC.SAVUB?[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CHECK_DATA.C;23" > rr_ad_head);. check_rr_list (n, & rp -> rr_cn_head);. check_rr_list (n, & rp -> rr_hi_head);. check_rr_list (n, & rp -> rr_ks_head);. check_rr_list (n, & rp -> rr_mb_head);. check_rr_list (n, & rp -> rr_mg_head);. check_rr_list (n, & rp -> rr_mi_head);. check_rr_list (n, & rp -> rr_mr_head);. check_rr_list (n, & rp -> rr_mx_head);. check_rr_list (n, & rp -> rr_ns_head);. check_rr_list (n, & rp -> rr_pt_head);. check_rr_list (n, & rp -> rr_sa_head);. check_rr_list (n, & rp -> rr_tx_head); } h = n -> n_h; if (h != 0) {& h = abspointer (h, struct h_);1 for (i = 0; i < NAME_HASH_DIVISOR; i++) { nb = 0;Z for (nd = h -> h_nhead [i] . hp_first; nd != 0; nd = nd -> n_link . lp_next) {0 nd = abspointer (nd, struct n_);| if (!((nb == 0 && nd -> n_link . lp_prev == 0) || (abspointer (nd -> n_link . lp_prev, struct n_) == nb))) {^ printf ("%08X: n_link . lp_prev mismatch\n", relpointer (nd, struct n_));) longjmp (get_out, 1); }# check_name (nd, n); nb = nd; } if (!((nb == 0 && h -> h_nhead [i] . hp_last == 0) || (abspointer (h -> h_nhead [i] . hp_last, struct n_) == nb))) {Z printf ("%08X: h_nhead . lp_last mismatch\n", relpointer (n, struct n_));% longjmp (get_out, 1); } } }}:static void check_rr_list (struct n_ *n, struct hp_ *hp) { struct rr_ *rr, *rrb; struct a_ *a, *ab; rrb = 0;F for (rr = hp -> hp_first; rr != 0; rr = rr -> rr_link . lp_next) { check_pointer (rr);) rr = abspointer (rr, struct rr_);y if (!((rrb == 0 && rr -> rr_link . lp_prev == 0) || (abspointer (rr -> rr_link . lp_prev, struct rr_) == rrb))) {X printf ("%08X: rr_link . lp_prev mismatch\n", relpointer (rr, struct rr_));! longjmp (get_out, 1); }> if (abspointer (rr -> rr_name_node, struct n_) != n) {S printf ("%08X: rr_name_node mismatch\n", relpointer (rr, struct rr_));! longjmp (get_out, 1); } switch (rr -> rr_type) { case RR_CNAME:: if (((struct rr_cn_ *) rr) -> rr_cn_name_node == 0) {K printf ("%08X: rr_cn_name_node is zero\n", relpointer (rr, struct rr_)); error_count++; } break; case RR_MB:< if (((struct rr_mb_ *) rr) -> rr_mb_server_node == 0) {M printf ("%08X: rr_mb_server_node is zero\n", relpointer (rr, struct rr_)); error_count++; } break; case RR_MG:= if (((struct rr_mg_ *) rr) -> rr_mg_mailbox_node == 0) {N printf ("%08X: rr_mg_mailbox_node is zero\n", relpointer (rr, struct rr_)); error_count++; } break; case RR_MINFO:> if (((struct rr_mi_ *) rr) -> rr_mi_rmailbox_node == 0) {O printf ("%08X: rr_mi_rmailbox_node is zero\n", relpointer (rr, struct rr_)); error_count++; }> if (((struct rr_mi_ *) rr) -> rr_mi_emailbox_node == 0) {O printf ("%08X: rr_mi_emailbox_node is zero\n", relpointer (rr, struct rr_)); error_count++; } break; case RR_MR:= if (((struct rr_mr_ *) rr) -> rr_mr_mailbox_node == 0) {N printf ("%08X: rr_mr_mailbox_node is zero\n", relpointer (rr, struct rr_)); error_count++; } break; case RR_MX:< if (((struct rr_mx_ *) rr) -> rr_mx_server_node == 0) {M printf ("%08X: rr_mx_server_node is zero\n", relpointer (rr, struct rr_)); error_count++; } break; case RR_NS:< if (((struct rr_ns_ *) rr) -> rr_ns_server_node == 0) {M printf ("%08X: rr_ns_server_node is zero\n", relpointer (rr, struct rr_)); error_count++; } break; case RR_PTR:: if (((struct rr_pt_ *) rr) -> rr_pt_name_node == 0) {M printf ("%08X: rr_pt_server_node is zero\n", relpointer (rr, struct rr_)); error_count++; } break; } ab = 0;Q for (a = rr -> rr_a_head . hp_first; a != 0; a = a -> a_link . lp_next) {* a = abspointer (a, struct a_);v if (!((ab == 0 && a -> a_link . lp_prev == 0) || (abspointer (a -> a_link . lp_prev, struct a_) == ab))) {Z printf ("%08X: a _link . lp_prev mismatch\n", relpointer (a, struct a_));% longjmp (get_out, 1); }; if (abspointer (a -> a_rr, struct rr_) != rr) {M printf ("%08X: a_rr mismatch\n", relpointer (a, struct a_));% longjmp (get_out, 1); } ab = a; } rrb = rr; }a if (!((rrb == 0 && hp -> hp_last == 0) || (abspointer (hp -> hp_last, struct rr_) == rrb))) {o printf ("%08X %08X: rr . lp_last mismatch\n", relpointer (n, struct n_), relpointer (hp, struct hp_)); longjmp (get_out, 1); }}/*) * Check for write locks in the zone list */static void check_zone (){ struct z_ *z; struct a_ *a, *ab;K for (z = f -> f_z_head . hp_first; z != 0; z = z -> z_link . lp_next) {& z = abspointer (z, struct z_);% check_lock (& z -> z_a_lock);E if (z -> z_type == Z_PRIMARY || z -> z_type == Z_SECONDARY) { ab = 0;T for (a = z -> z_a_head . hp_first; a != 0; a = a -> a_zlink . lp_next) {. a = abspointer (a, struct a_);| if (!((ab == 0 && a -> a_zlink . lp_prev == 0) || (abspointer (a -> a_zlink . lp_prev, struct a_) == ab))) {n printf ("%08X: a_zlink . lp_prev mismatch (ab = %08x)\n", relpointer (a, struct a_), ab);) longjmp (get_out, 1);o }t? if (abspointer (a -> a_zone, struct z_) != z) {uS printf ("%08X: a_zone mismatch\n", relpointer (a, struct a_));c) longjmp (get_out, 1);w }i ab = a;j } }t }c}t/*! * Check the forward servers list  */*static void check_forward () { struct fw_ *fw, *fwb;) fwb = 0;R for (fw = f -> f_fw_head . hp_first; fw != 0; fw = fw -> fw_link . lp_next) { check_pointer (fw);) fw = abspointer (fw, struct fw_); y if (!((fwb == 0 && fw -> fw_link . lp_prev == 0) || (abspointer (fw -> fw_link . lp_prev, struct fw_) == fwb))) { j printf ("%08X: fw_link . lp_prev mismatch (fwb = %08X)\n", relpointer (fw, struct fw_), fwb);! longjmp (get_out, 1);% }, fwb = fw; } } %static void check_pointer (char *p) {_ if (((int) p & 3) != 0) { 4 printf ("%08X: Pointer not to int boundary\n", p); longjmp (get_out, 1); }(} f_fw_lock);" check_lock (& f -> f_kc_lock);" check_lock (& f -> f_pa_lock);" check_lock (& f -> f_ru_lock);E check_name (abspointer (f -> f_n_head . hp_first, struct n_), 0); check_zone (); check_forward (); if (write_count > 0) {1 printf ("%d write locks\n", write_count)A*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CLEAN_EXPIRED.C;7+,_*./@ 4h -B0123 KPWO5 6@;7o8`@ o9G@HJ5 RELEASEC.SAV_*BA[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CLEAN_EXPIRED.C;7h/*% * Function to clean out expired data * Bruce Orchard, June 30, 1988 */#include "domser.h"#include static t_timestamp start_time;Astatic void clean1 (struct n_ *, struct n_ *, int *, int *, int);8static void check_rr (struct hp_ *, struct n_ *, int *);"static int all_null (struct h_ *);"void clean_expired (do_server_age) int do_server_age;{ struct n_ *root; int lock_state; start_time = time_stamp();< root = abspointer (f -> f_n_head . hp_first, struct n_); read_lock (& f -> f_n_lock); lock_state = 0;4 clean1 (root, 0, &lock_state, 0, do_server_age);" read_unlock (& f -> f_n_lock); do_dereference_name ();}Fstatic void clean1 (n, np, p_lock_state, pp_lock_state, do_server_age) struct n_ *n; struct n_ *np; int *p_lock_state; int *pp_lock_state; int do_server_age;{% int lock_state, i, hv, new_score; struct h_ *h; struct n_ *nd, *ndn; struct rp_ *rp; struct hp_ *hp; struct s_ *ss; char *s; read_lock (& n -> n_lock); *p_lock_state = 1; h = n -> n_h; if (h != 0) {& h = abspointer (h, struct h_);1 for (i = 0; i < NAME_HASH_DIVISOR; i++) {F for (nd = h -> h_nhead[i] . hp_first; nd != 0; nd = ndn) {0 nd = abspointer (nd, struct n_);- ndn = nd -> n_link . lp_next; lock_state = 0;I clean1 (nd, n, &lock_state, p_lock_state, do_server_age); } } } rp = n -> n_rr; if (rp != 0) {) rp = abspointer (rp, struct rp_);7 check_rr (& rp -> rr_ad_head, n, p_lock_state);7 check_rr (& rp -> rr_cn_head, n, p_lock_state);7 check_rr (& rp -> rr_hi_head, n, p_lock_state);7 check_rr (& rp -> rr_ks_head, n, p_lock_state);7 check_rr (& rp -> rr_mb_head, n, p_lock_state);7 check_rr (& rp -> rr_mg_head, n, p_lock_state);7 check_rr (& rp -> rr_mi_head, n, p_lock_state);7 check_rr (& rp -> rr_mr_head, n, p_lock_state);7 check_rr (& rp -> rr_mx_head, n, p_lock_state);7 check_rr (& rp -> rr_ns_head, n, p_lock_state);7 check_rr (& rp -> rr_pt_head, n, p_lock_state);7 check_rr (& rp -> rr_sa_head, n, p_lock_state);7 check_rr (& rp -> rr_tx_head, n, p_lock_state); }) if (do_server_age && n -> n_s != 0) {! if (*p_lock_state == 1) {( read_unlock (& n -> n_lock);' write_lock (& n -> n_lock); *p_lock_state = 2; }. ss = abspointer (n -> n_s, struct s_);h new_score = (ss -> s_response_time - SERVER_SCORE_BASE) * SERVER_AGE_FACTOR + SERVER_SCORE_BASE;* ss -> s_response_time = new_score; } recheck_name: if (n -> n_rr == 0 &&M (n -> n_h == 0 || all_null (abspointer (n -> n_h, struct n_))) &&1 n -> n_server_reference_count == 0 && n -> n_s == 0 && n -> n_up != 0) {! if (*p_lock_state == 1) {( read_unlock (& n -> n_lock);' write_lock (& n -> n_lock); *p_lock_state = 2; goto recheck_name; }b n -> n_server_reference_count = 1; /* make sure name doesn't go away when we unlock it */! switch (*pp_lock_state) { case 0: abort (); case 1:$ switch (*p_lock_state) { case 0: abort (); case 1:, read_unlock (& n -> n_lock); break; case 2:- write_unlock (& n -> n_lock); break; }) read_unlock (& np -> n_lock);( write_lock (& np -> n_lock); *pp_lock_state = 2;' write_lock (& n -> n_lock); *p_lock_state = 2;, n -> n_server_reference_count--; goto recheck_name; case 2:$ switch (*p_lock_state) { case 0: abort (); case 1:, read_unlock (& n -> n_lock);+ write_lock (& n -> n_lock);" *p_lock_state = 2;0 n -> n_server_reference_count--;" goto recheck_name; case 2: break; } }( n -> n_server_reference_count--; h = n -> n_h; if (h != 0) {* h = abspointer (h, struct h_); s_dealloc (h); }. h = abspointer (np -> n_h, struct h_);+ s = abspointer (n -> n_name, char); hv = name_hash (s); hp = & h -> h_nhead[hv];( remove_s (hp, n, & n -> n_link);% write_unlock (& n -> n_lock); s_dealloc ((int *) s); s_dealloc (n); *p_lock_state = 0; } switch (*p_lock_state) { case 1:$ read_unlock (& n -> n_lock); break; case 2:% write_unlock (& n -> n_lock); break; } *p_lock_state = 0;}*static void check_rr (hp, n, p_lock_state) struct hp_ *hp; struct n_ *n; int *p_lock_state;{ struct rr_ *rr, *rrn; struct a_ *a, *an; start_over:2 for (rr = hp -> hp_first; rr != 0; rr = rrn) {) rr = abspointer (rr, struct rr_);& rrn = rr -> rr_link . lp_next;> for (a = rr -> rr_a_head . hp_first; a != 0; a = an) {* a = abspointer (a, struct a_);' an = a -> a_link . lp_next;: if (a -> a_source_type == A_SOURCE_RESPONSE &&1 start_time > a -> a_expire) {) if (*p_lock_state == 1) {0 read_unlock (& n -> n_lock);/ write_lock (& n -> n_lock);& *p_lock_state = 2;$ goto start_over; }? remove_s (& rr -> rr_a_head, a, & a -> a_link); s_dealloc (a); } }. if (rr -> rr_a_head . hp_first == 0) {% if (*p_lock_state == 1) {, read_unlock (& n -> n_lock);+ write_lock (& n -> n_lock);" *p_lock_state = 2; goto start_over; }( delete_rr_holding_name (rr); } }}static int all_null (h) struct h_ *h;{ int i;- for (i = 0; i < NAME_HASH_DIVISOR; i++) {6 if (h -> h_nhead[i] . hp_first != 0) return 0; } return 1;}A*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CLI_GET_VALUE.C;2+,G./@ 47F-B0123KPWO56>ӴI7טJ8*uo9G@HJ/*0 * Function to return a value of a CLI qualifier * * Bruce Orchard, May 1, 1989 */#include #include #include char *cli_get_value (char *s){ struct dsc$descriptor d, td;#define SL 150 char t[SL], *rs; int r; short len; d.dsc$w_length = strlen (s); d.dsc$a_pointer = s;" d.dsc$b_class = DSC$K_CLASS_S;" d.dsc$b_dtype = DSC$K_DTYPE_T; td.dsc$w_length = SL; td.dsc$a_pointer = t;# td.dsc$b_classBe RELEASEC.SAVGBA[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CLI_GET_VALUE.C;27* = DSC$K_CLASS_S;# td.dsc$b_dtype = DSC$K_DTYPE_T;& r = cli$get_value (&d, &td, &len);# if (r == CLI$_ABSENT) return 0;7 if (r == CLI$_COMMA || CLI$_CONCAT || SS$_NORMAL) { rs = malloc (len + 1); strncpy (rs, t, len); rs[len] = 0; return rs; } abort ();}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CLI_NEGATED.C;3+,OJ./@ 48-B0123KPWO56A 7U8:oX9G@HJ/*8 * Function to determine if a CLI qualifier is pnegated. *" * Bruce Orchard, December 6, 1989 */#include #include #include 5int cli_negated (char *s /* Qualifier to look for */){ struct dsc$descriptor d; int r; d.dsc$w_length = strlen (s); d.dsc$a_pointer = s;" d.dsc$b_class = DSC$K_CLASS_S;" d.dsc$b_dtype = DSC$K_DTYPE_T; r = cli$present (&d);1 return r == CLI$_NEGATED || r == CLI$_LOCNEG;}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CLI_PRESENT.C;2+,^./@ 4I-B0123KPWO56z=I7@ J8$uo9G@HJ/*7 * Function to determine if a CLI qualifier is persent. * * Bruce Orchard, May 1, 1989 */#include #include #include 5int cli_present (char *s /* Qualifier to look for */){ struct dsc$descriptor d; int r; d.dsc$w_length = strlen (s); d.dsc$a_pointer = s;" d.dsc$b_class = DSC$K_CLASS_S;" d.dsc$b_dtype = DSC$K_DTYPE_T; r = cli$present (&d);I return r == CLI$_PRESENT || r == CLI$_LOCPRES || r == CLI$_DEFAULTED;}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CMUNETERROR.H;1+,./@ 4O-B0123KPWO56 |7g*8`Wl9G@HJ/*++O********************************************************************************* TITLE: CMUNetError.H** VERSION: V1.0* * FACILITY:** CMU-Tek TCP/IP* * ABSTRACT:*A* C header file defining CMU-Tek TCP/IP error message constants** ENVIRONMENT:** VAX/VMS *%* AUTHOR: Art Stine, Clarkson U/ERC3* Copyright (c) 1990, Clarkson University*!* CREATION DATE: January, 1990** MODIFIED BY:*&* 1-001 A. Stine Clarkson U/ERC* Updated for V6.5 of CMU-TEKO********************************************************************************--*/Gglobalvalue NET$_IR, NET$_IFC, NET$_IPC, NET$_UCT, NET$_IFS, NET$_ILP, I NET$_NUC, NET$_CSE, NET$_NOPRV, NET$_CIP, NET$_CDE, NET$_CR, J NET$_FSU, NET$_UNN, NET$_VTF, NET$_CREF, NET$_CCAN, NET$_FIP, H NET$_BTS, NET$_IHI, NET$_BDI, NET$_EPD, NET$_URC, NET$_IGF, F NET$_UNA, NET$_UNU, NET$_CC, NET$_CTO, NET$_TWT, NET$_TE, O NET$_FTO, NET$_NYI, NET$_NOPN, NET$_NOINA, NET$_NOANA, NET$_NOADR, G NET$_GTHFUL, NET$_DAE, NET$_NMLTO, NET$_NSEXIT, NET$_NONS, C NET$_NSQFULL, NET$_DSDOWN, NET$_DSNODS, NET$_DSINCOMP, H NET$_DSNOADDR, NET$_DSNONAME, NET$_DSFMTERR, NET$_DSSRVERR, H NET$_DSNAMERR, NET$_DSNOTIMP, NET$_DSREFUSD, NET$_DSNONSRV, I NET$_DSUNKERR, NET$_DSREFEXC, NET$_GREENERR, NET$_GP_INVREQ, L NET$_GP_INVINF, NET$_GP_INVNAM, NET$_GP_INVADR, NET$_GP_INVMBX, L NET$_GP_INVCLS, NET$_GP_RSBUSY, NET$_GP_NONMSR, NET$_GP_NOHINF, L NET$_GP_NOTFND, NET$_GP_UNKMBX, NET$_GP_NOTIMP, NET$_GP_TOOBIG, % NET$_GP_NSDOWN, NET$_NRT; B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CREATE_PROCESS.C;4+,v./@ 4h.-B0123 KPWO56`ȝ믒73 Z83'p9G@HJ/* ) * Function to create a detached process.$ * Bruce Orchard, September 18, 1989 */#include #include #include #include #include dint create_process (char *process_name, char *image_name, int priority, int wsquota, int wsextent) { int status, suffix=0;( struct dsc$descriptor_s process_des;h struct dsc$descriptor_s image_des = {strlen (image_name), DSC$K_DTYPE_T, DSC$K_CLASS_S, image_name}; int privs[2] = {-1, -1};( char tname[30], quotalist[20], *qpt;! strcpy (tname, process_name); while (1) {) process_des.dsc$b_dtype = DSC$K_DTYPE_T;) process_des.dsc$b_class = DSC$K_CLASS_S;# process_des.dsc$a_pointer = tname;2 process_des.dsc$w_length = strlen (tname); qpt = quotalist; if (wsquota > 0) { *qpt++ = PQL$_WSQUOTA; *((int *)qpt)++ = wsquota; } if (wsextent > 0) { *qpt++ = PQL$_WSEXTENT; *((int *)qpt)++ = wsextent; } *qpt++ = PQL$_LISTEND;d status = sys$creprc (0, &image_des, 0, 0, 0, privs, quotalist, &process_des, priority, 0, 0,) PRC$M_DETACH | PRC$M_IMGDMP);" if (status != SS$_DUPLNAM) break;1 sprintf (tname, "%s%d", process_name, ++suffix); }2 if (status != SS$_NORMAL) lib$signal (status); return;}@*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]CURRENT_TIME.C;1+,./@ 4--B0123 KPWO56zIJ7Qz8jc9G@HJ/*- * Function to get current time in VMS format * Bruce Orchard, May 12, 1989 */#include "arith64.h"int64 current_time (){ int64 t; sys$gettim (&t); return t;}  RELEASEC.SAVB?[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DAY_OF_WEEK.C;34S?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DAY_OF_WEEK.C;3+,./@ 44-B0123 KPWO56Aɷ7@wz8@Ei9G@HJ/*4 * Function to compute day of week (0 = Sunday, ...)$ * Bruce Orchard, September 28, 1989 */#include static int first=1;'static int64 SECOND, MINUTE, HOUR, DAY;int day_of_week (int64 time) { int td; if (first) {% SECOND = conv3264 (10000000);( MINUTE = mul326464 (60, SECOND);& HOUR = mul326464 (60, MINUTE);# DAY = mul326464 (24, HOUR); first = 1; }* td = conv6432 (div646464 (time, DAY)); return (td+3) % 7;}9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DELAY.C;2+,./@ 4:*-B0123 KPWO5 6517@{8 b9G@HJ/*( * Function to delay a number of seconds$ * Bruce Orchard, September 15, 1989 */#include void delay (int seconds) {int64 cseconds;: cseconds = mul326464 (seconds, conv3264s (-10000000));$ sys$schdwk (0, 0, &cseconds, 0); sys$hiber ();};*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DELAYMS.C;2+,./@ 4AH-B0123 KPWO56U.Β7@{8`fc9G@HJ/*- * Function to delay a number of milliseconds" * Bruce Orchard, October 27, 1989 */#include !void delayms (int milliseconds) {int64 cmilliseconds;A cmilliseconds = mul326464 (milliseconds, conv3264s (-10000));) sys$schdwk (0, 0, &cmilliseconds, 0); sys$hiber ();};*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DELETE.C;10+,~6./@ 4n-B0123 KPWO5 6@727 XUL8 o9G@HJ/* * Delete routines * Bruce Orchard, June 14, 1988 */#include "domser.h"#include struct cn_ { struct cn_ *cn_next; struct n_ *cn_name_node;};static struct cn_ *cn_top = 0;/static void set_dereference_name (struct n_ *);/* * Delete an authority entry3 * Required lock: Authority list from zone (write) */&void delete_authority_holding_zone (a)a struct a_ *a; /* Pointer to authority entry (shared memory, absolute) */{ struct rr_ *rr; struct n_ *n;U remove_s (& (abspointer (a -> a_zone, struct z_) -> z_a_head), a,& a -> a_zlink);, rr = abspointer (a -> a_rr, struct rr_);3 n = abspointer (rr -> rr_name_node, struct n_); write_lock (& n -> n_lock);3 remove_s (& rr -> rr_a_head, a, & a -> a_link); s_dealloc (a);* if (rr -> rr_a_head . hp_first == 0) {$ delete_rr_holding_name (rr); } check_and_release_name (n); do_dereference_name ();}/* * Delete an RR entry$ * Required lock: Name node (write) */ void delete_rr_holding_name (rr)Z struct rr_ *rr; /* Pointer to RR entry (shared memory, absolute) */{ int type, i; struct hp_ *hp=0; struct n_ *n; struct rp_ *rp;3 n = abspointer (rr -> rr_name_node, struct n_);! if (n -> n_rr == 0) abort ();, rp = abspointer (n -> n_rr, struct rp_); type = rr -> rr_type; switch (type) { case RR_A: hp = & rp -> rr_ad_head; break; case RR_CNAME: hp = & rp -> rr_cn_head;a set_dereference_name (abspointer (((struct rr_cn_ *) rr) -> rr_cn_name_node, struct n_)); break; case RR_HINFO:S s_dealloc ((int *) abspointer (((struct rr_hi_ *) rr) -> rr_hi_cpu, char));R s_dealloc ((int *) abspointer (((struct rr_hi_ *) rr) -> rr_hi_os, char)); hp = & rp -> rr_hi_head; break; case RR_MB: hp = & rp -> rr_mb_head;c set_dereference_name (abspointer (((struct rr_mb_ *) rr) -> rr_mb_server_node, struct n_)); break; case RR_MG: hp = & rp -> rr_mg_head;d set_dereference_name (abspointer (((struct rr_mg_ *) rr) -> rr_mg_mailbox_node, struct n_)); break; case RR_MINFO: hp = & rp -> rr_mi_head;e set_dereference_name (abspointer (((struct rr_mi_ *) rr) -> rr_mi_rmailbox_node, struct n_));e set_dereference_name (abspointer (((struct rr_mi_ *) rr) -> rr_mi_emailbox_node, struct n_)); break; case RR_MR: hp = & rp -> rr_mr_head;d set_dereference_name (abspointer (((struct rr_mr_ *) rr) -> rr_mr_mailbox_node, struct n_)); break; case RR_MX: hp = & rp -> rr_mx_head;c set_dereference_name (abspointer (((struct rr_mx_ *) rr) -> rr_mx_server_node, struct n_)); break; case RR_NS: hp = & rp -> rr_ns_head;c set_dereference_name (abspointer (((struct rr_ns_ *) rr) -> rr_ns_server_node, struct n_)); break; case RR_PTR: hp = & rp -> rr_pt_head;a set_dereference_name (abspointer (((struct rr_pt_ *) rr) -> rr_pt_name_node, struct n_)); break; case RR_SOA: hp = & rp -> rr_sa_head;d set_dereference_name (abspointer (((struct rr_sa_ *) rr) -> rr_sa_primary_node, struct n_));h set_dereference_name (abspointer (((struct rr_sa_ *) rr) -> rr_sa_responsible_node, struct n_)); break; case RR_TXT:> for (i = 0; i < ((struct rr_tx_ *) rr) -> rr_tx_ntext; i++) {[ s_dealloc ((int *) abspointer (((struct rr_tx_ *) rr) -> rr_tx_text[i], char)); } hp = & rp -> rr_tx_head; break; case RR_WKS:V s_dealloc ((int *) abspointer (((struct rr_ks_ *) rr) -> rr_ks_server, char)); hp = & rp -> rr_ks_head; break; default: abort (); }' remove_s (hp, rr, & rr -> rr_link); s_dealloc (rr);+ if (rp -> rr_ad_head . hp_first == 0 &&+ rp -> rr_cn_head . hp_first == 0 &&+ rp -> rr_hi_head . hp_first == 0 &&+ rp -> rr_ks_head . hp_first == 0 &&+ rp -> rr_mx_head . hp_first == 0 &&+ rp -> rr_ns_head . hp_first == 0 &&+ rp -> rr_pt_head . hp_first == 0 &&+ rp -> rr_sa_head . hp_first == 0 &&+ rp -> rr_tx_head . hp_first == 0) { n -> n_rr = 0; s_dealloc (rp); }}/*> * Add name to list to decrement name node reference count and * delete node if no use left */$0 ü RELEASEC.SAV~6B;[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DELETE.C;10ng  static void set_dereference_name (n)n struct n_ *n; /* Pointer to name node to set_dereference (shared memory, absolute) */{ struct cn_ *cn;* cn = acalloc (1, sizeof (struct cn_)); cn -> cn_next = cn_top; cn_top = cn; cn -> cn_name_node = n;}/*& * Check if any use left for name node; * If no use, delete it. If remaining use, just unlock it. * Required lock: Name (write) */void check_and_release_name (n)\ struct n_ *n; /* Pointer to name entry (shared memory, absolute) */{ struct n_ *np; struct h_ *h; struct hp_ *hp; char *s; int hv, i; if (n -> n_rr == 0 && n -> n_h == 0 &&1 n -> n_server_reference_count == 0 && n -> n_s == 0 && n -> n_up != 0) {b n -> n_server_reference_count = 1; /* make sure name doesn't go away when we unlock it *// np = abspointer (n -> n_up, struct n_);% write_unlock (& n -> n_lock);$ write_lock (& np -> n_lock);# write_lock (& n -> n_lock);( n -> n_server_reference_count--; if (n -> n_rr == 0 && n -> n_h == 0 &&5 n -> n_server_reference_count == 0 && n -> n_s == 0) {2 h = abspointer (np -> n_h, struct h_);/ s = abspointer (n -> n_name, char); hv = name_hash (s);$ hp = & h -> h_nhead[hv];, remove_s (hp, n, & n -> n_link);) write_unlock (& n -> n_lock);" s_dealloc ((int *) s); s_dealloc (n);5 for (i = 0; i < NAME_HASH_DIVISOR; i++) {I if (h -> h_nhead[i] . hp_first != 0) goto something_left; } np -> n_h = 0; s_dealloc (h); something_left:( check_and_release_name (np);D } else { /* Another process snuck in */* write_unlock (& np -> n_lock);) write_unlock (& n -> n_lock); } } else {% write_unlock (& n -> n_lock); }}/* * Actually dereference names */void do_dereference_name (){ struct cn_ *cn; struct n_ *n; while (cn = cn_top) { cn_top = cn -> cn_next; n = cn -> cn_name_node;# write_lock (& n -> n_lock);) n -> n_server_reference_count --;# check_and_release_name (n); afree (cn); }}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DELETE_ZONE.C;2+,&./@ 4VX-B0123 KPWO567`eؒ8 ව o9G@HJ/*5 * Function to delete authorities arising from a zoneA * This will usually result in the associated RR's being deleted. * Bruce Orchard, June 17, 1988 */#include "domser.h"#include void delete_zone (z)V struct z_ *z; /* Zone to delete (shared memory, absolute) */{ struct a_ *a; write_lock (z -> z_a_lock);M for (a = z -> z_a_head . hp_first; a != 0; a = a -> a_zlink . lp_next) {( a = abspointer (a, struct a_);, delete_authority_holding_zone (a); }" write_unlock (z -> z_a_lock);}9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOC.WP;27+,,.@/@ 4@@-B0123 KPWOA56!m-\7qn-\8q.r9G@HJWPC. 2 JVTW#|x10 pitchzNxxx,+x  @;HP LaserJet Series II in room 551HLSEIIA0.PRSx  @,t023VE WCourier 10 pitchzNxxx,Ax  @;HP LaserJet Series II in room 551HLSEIIA0.PRSx  @,t02$B,#|x x  @;A 1 D !Domain Name Server1E$2 *"3 1, 4"E   X  PROGRAMS p(#H 2 X X` CHECK ` p(#H 2 X X` EXAMINE ` p(#H 2 X X` LOOKUP ` p(#H 3 X X` PERIODIC_UPDATE ` p(#H 5 X X` PRINT ` p(#H 5 X X` SERVE_TCP ` p(#H 6 X X` SERVE_UDP ` p(#H 6 X X` SERVE_UDP_FORKED ` p(#H 7 X X` START ` p(#H 7 X X` STOP ` p(#H 8 X X` UPDATE_PRIMARY ` p(#H 8 X  INITIALIZATION FILES p(#H 9 X X` Parameter file ` p(#H 9 X X` Protocols file ` p(#H 12 X X` Services file ` p(#H 12 X X` Resource records files ` p%(#H 12 X  SET UP p(#H 13 X  TROUBLESHOOTING p(#H 15   The domain name server programs implement the server described in RFC's 1034, and 1035. This document does not include introductory material about the domain name system. That material can be found in RFC 1033. The following resource record types are implemented: A, CNAME, HINFO, MB, MG, MINFO, MR, MX, NS, PTR, SOA, TXT, and WKS. Only internet class is implemented. Automatic refresh of zones in secondary servers is implemented. Inverse queries and completion queries are not implemented. It uses the CMU/Tektronix TCP/IP package for communication calls. The cache is implemented as a global section. The global section is created when the server is started and deleted when the server is stopped. The backing file for the global section is created when the server is started if necessary. It is not deleted when the server is stopped so the cache will usually survive stopping and starting the server. Since several processes can be accessing the cache at once, VMS locks are used to control access to individual records in the cache. If more than one node in a cluster is running the domain server, each node must have its own copy of the global section backing file. PROGRAMS  CHECK The check program verifies the integrity of the cache. If no errors are found, the message "Passes all checks" is displayed. Otherwise the first error found is displayed. CHECK should be invoked with a DCL command. DCL invocation: DOMAIN/CHECK options Options: /DEBUG_LEVEL=n` Xh#Sets the level of debugging output. The higher the number, the greater the output. Th RBG[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]@K\_U/Q0((:4216Y^ZTT$P e;I.q[j@-8&J]>/o 8[sXEt1T~v! g6A8lF}N%'NWY6yW?_:$#]hk\2h`t4E70vQ`0o5#I)ICl8vWEVu;?lAN%A.2a3UvdKx0 xMg- Daj=q@@H6)0+POBe}Bjj3pSAMx.x^WQJNqXUGfg6{0[^9XMh% h &WkĄ( ?':XYbL'ArI6qa ^iXf2@LNHZij^pLKL.wQS_J CSpsZ0g=o`u)jnA#+tgTKK[r)Mm*C~GC}8nORt/_KM`PA# <X4 fkyrQJUs)"V!zm-g5o|&I? ICNI%z5G[Fa:;#N\OD]bH>%)V^v?(>+ ?/)|02pA:e9cѤů1c'nj,M9z%<Q8 h4G- ki N`+,xzh?1 zt,$f|pLg$x^?9b.enR<+t13'.?J`I| K5\?1J\p51\IvBX rQd|}MNA K\x6B15t6:*p&^&oA+t- #L)zeM[U yj)XmN\J#,k5q=Sr,!L5n"*!E|2Y±QI,m""(P[?Gp^-9XJ[p8m%R,6YRfhwXM7:lF]j^3;;cY5ZO&/5ek kZs 1N9)U}M n^8+Kpr;14PA}7T>_18Py>f(= c3Oda\}uNH4C;OhT7  ((6Z^\bejl\6o9?CS"m'h OeH%1R1vy?!~>*T a`298V#g:~8ow5Dt%(gs$ieH4d-B=1*VVdw] lVdG\9qSzceFCKSP}wrhfygF 8S/y=j!%1S8okO`&M6{sX;; 2F%Jkd17(IGw$F\V O0EdZHv"5Kiqm&po U A*CAWh'$o)CgT`ikUJ2\1 +b*V I#Dy}BM>Gn= x 2;Wt9 TX]R 4aU ni^Gs:JW,U;QDcpM,Q"r zy\1'Y[z# sijfdRi]@ah"W4.:[fLc92Az<{tuddTJ#a\$J>7HLKI~cS ~F74rw630(~" ,o)>w;-@G(xf3&Qjzp%xMV @RCk~N>MSr zBg#FtUv6GORR}=o:\9f2 EI[uq !SybSstsIMMAA m2u6a,Fw{+&i.l?P Bf}D^A~0Rk a+OQ bOR]aCQ66lfio~\3$ Ft9f='XHA09rIi3bB\P ]jB>qwpOJg63Ma'REaVsSz`Y#.Gm+|%aD+([Z)Q.c8.PrR>[ 4wG&^,-" 4D#8I-A"T{Y {I6E/(m Eg4 n>p1l"cIK@*%=2`!I}0,qGF1EQFN y; ڹWPOc[U#f$q,H }}@'x{PEi&8Ey}PR[PN{68s4i,FYQt+d,5ag4sz#[OAlD>\^2#~Qrt"QOz%n `sj.\\AQd9 +U#{gBVCl8}0%F$s%[nG >ROe1OyitF+ )`DuU|r_ ~6ii44T!2DFsj2 fHsj.V#/.[WY?$^ g /{yK 4VL~JO;FiI,v/ { {: c|-.te&qCm ,F]-n,S*$G;D1SLobgQ|5wN,5:lisycWHz-?DO,FrDk!V =' ,*C2*#"K!+f(NKF?he]9Ojd'gƾmt]n?AQ#P9,@U !5}%}T,3G.xlL\.lc\@@9wuhu (u_0m fRHA'<9=N'oo /Y&V F{wXrO@\( sYpL/|%lnBMiYsBDRr LX1PpV(h$Qdip`R$Z??gA8fc7zfDo[XP(/eQp2kt~ZGkw> lE&6;'}kQ+|z!d>05w?V)>);a-j>+]_^J3l PJ_DsTIK*gr;?`?yz*b7?0;8,oH6uVKL"1#TO cOc# P`CJ$8Uz: x v>-:/&_N@MqWX>5(]HGJj4q(Yc, .Bmg&Cb?U "}? hv?XG`98&I= FwD1'[H!:J g2W cr?tLCG1EONV|13uX%HkWZZx` q`Rm=!MR:6Eu?DEB(,66N,{]1 Sbuu]-Oe^v3+\M#58X3 cm8,g?_gtU6{.>NXdRc$x31b;f08l%#sTZ0y J7"@FE,9[ :Efft&Q#@}ϑX?B`r@%2WٛXrj]1Kem'}'\7D%*..nz,+vYC++|Pb.} 6 sp&UTmVZ -^>2(#0CTFskz@;K){uh-mt~gC?~^(MyH2 oU_a)u /2#Vcw:Uh&sP\}Tb \p7IRa-IL4Pu5 O$P =;bq> x*Gyfr P[MU9E=|CIIKyG$R~iBqEO .IcnbLVP#mGGDw{n9VfQi jFZU`W1_nQ \5vfN[K=f>xJ' Qs"+Cz093-75;-$=]7\_ 'q:^/h{0pFm:WXfF&1_duz iR]Opas]Y#uR`tR6)Xn,Mn78})/ H>O.1c(x{\Xj}_v&A=+SM$*I= ir 1}{cfr8f.o@Li8 r 9q*it9|_NI_!" T"ml#=qd"J~sx|Uw]b`2Xd(Tiz5;?v\ j)r&oh39_CH G@MxTOSjw pgYT&|0 wM7z m^kDnkR-~Bh4%gp)geHSOwoGC*1b!u^@za-QK 7[patY*(d JJd֗,\GxTZ#A*P `c;My/aL\"S4:(C#@h"D(n'Ja4s?s8I8\RY^Jo:O GlV zLu+M); 6CiR,F_psn]T]QGU}X/HGU9%hT|" 0~UhQ[?ZAa7&e:3!#⛇Mדٓ#xYwv/PaH U)c-B8e o9Vy-:Mo;"4goPrpQGg6rwyP_dJ}Z(Ty}(+!#$vzD !YH(([urzd`RA>N@- mPX0OfcrVU6~ `yo=|\.LbJP^Txv?~(.!at:*{^}eJ!]>,io'lq =}Fp`K-dI[ײݬஐ鼕ՓA|U S'UmGjX+\`!Mq*i}6<'ۊ2V1FKd& sw Qk/NVMyeOgb0?q;*[aB3u"Hgmb)72?yRy-M!)(M+XO\m+1<)-u*4M v R;2R=5kLZ swn*RE/ p&`f.Vg!Ӛs4:0 ,%vu+;eeHnDn\pd`/n\gV1I.U0H, r"F}LZ[b7PH$geMt5v+0NQ%+4J+,6ww2pu_$O cx}\F~.GAE='F_G688~k<6%7mgloJ oX~tQXZ=^X 5fPuFE*)gn G.[MF,]M!OL #ĘeB:eKYDz'u+f/%9 >GRYGiK\>q*>,M)/3thDPOT%cn.Sk frQ{ 7.3nCW)fjnl_+nHbrg&7Q_ZXB8qbfdHYw4=%#+mZ@vXd<]\]&`  yAY@Y?'w6msP0C6a9![8n%}+Z[0zqn}~nxC \9lH9henNPAy1c|AsOR?% Y\̔ |5l=<֬ l-\ }y\B4KXX$18JlLVn)Q [7*C#&"fHoiy1ˑ$GQY P37 qiK)B {%4-`O7za\NQ~JhGvx# kv'8"'@^gg@?0l!9p1{qDH#4`t (' 0ޓGA];w3\~FI@e'a8]u"Yۭ3g7q#{N!Cl6J0,qm\yfL"VW${6LS\uR>,M .~~U3UC\>48[ /sGCc_9 rgpDfBh}`{4vGuk`eBG i0n8 7)%Wd y[i`GdLn@~G+9U}2h9 +7+Ek6Ziff6!'2fS(54VLeOFu+#Wdl};"=;(u`As.GT|kQX w\PktjeW]>F=y#95#K5\?/rCm a/mO1Vg21 m.Uz9uaTHqKJ9]X5x2K}LZP=<}g]"Cqu/,HGoEW/3(=k3qDY@~LS.;W=%y.0MJPPN5,<pcwi]lx@ !.wa+#n#osBYP,|xwYg@xijnTCd; ^kvKsa`r"yiQEh-L$V?h$AOhB''ofh/ (7@ hjh~)#FRvpt{-+a1+~SL+\.)5Kkcac((|mG,y5Syn!OBRM lYy&B:{qCTCf7NA`N*4yKIzNgY):)>@/eVaojt"(t,hR .'CkO=kiO=BopA YK=JAvb!D@ pHz.??|uyx,xUk\-2x(#nKpYa`_*\W Z(`A@^.MM.\^vx@&8+"H{ #qZ\_^.6cP=RLZ*bRu5*3FJ8^\ /"y!9P U:c6%s;Y%v#, 5J&y*(`}z HH8DRP3#w9alDty>(OcL->!r+lRM~iO#-.-;5F3 Zn#Q2 J aC it[E{(flX(p{B:Tm+?O{["o'ks1_t{pb[3s܋{|B^Pt 3nmRbTh0sfi I`Oh 8g|qtv?`m S|[Rswcf*-y:?:':/I0 l!(F'>*/ 5!,9=p^} .h|=5;?d%I/[s}z%Gi' U*D"7!?ze QRrs~:uBL#|hH 8e}XEP [iU#Z5fXETM/~cEI1&uMXhlYqcJY#Mweg"E6?^]R^eD\#X]]'tLUXSayK#6`Q~R=7>3I:l;|n/7+\-wK8h:td"&-7{y<,i!({a%n}#6fl}_R, e5g*y :3p&ndSf&({4s38i y+&9Ulc[8Asmi"1p` @+=rkIulDRXICT64, int64);int64 mul326464 (i ( RELEASEC.SAV,B9[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOC.WP;27@:$e source code must be consulted to interpret the debugging output.(#h  EXAMINE The examine program displays parts of the cache in hexadecimal and ASCII. It is used as a debugging tool. EXAMINE should be invoked with a DCL command. DCL invocation: DOMAIN/EXAMINE The invocation line should be followed with addresses to ' examine, one address per line, relative to the start of the cache, in hexadecimal. The 32 bytes starting at the address are displayed.  LOOKUP The lookup program is in interactive program to do queries requested by the user and print the result. It can be used to examine data stored in the servers and to debug servers. DCL invocation: DOMAIN/LOOKUP The invocation line should be followed with commands giving parameters to be set and names to be looked up. Commands: X SET options ...(# X ` The SET command sets options for the following LOOKUP commands. Options set with the SET command remain in effect until changed with another SET command. The following options are available:(# X X` /CLASS=class(#` X X`  The/CLASS option sets the class to be used for LOOKUP commands. The class can be either INTERNET, CHAOS, HESIOD, or ALL. The default is INTERNET.(#` X X` /FULL(#` X X` /NOFULL(#` X X`  The /FULL option turns on full output from LOOKUP commands. The /NOFULL option turns off full output. Partial output just includes the resource records returned by the server. Full output includes the query, the resource records returned by the server, and the time the server took to answer the query. The default is /NOFULL.(#` X X` /PORT=port(#` X X`  The /PORT option sets the TCP or UDP port number to be used by LOOKUP commands. /PORT defaults to 53, the standard port for domain service.(#` ` /PROTOCOL=protocol X X`  The /PROTOCOL option sets the protocol to be used by LOOKUP commands. The protocol can be either TCP or UDP. The default is UDP except for zone transfers, where the default is TCP. To request a zone transfer with UDP, which is not allowed by the specification, the /PROTOCOL option must be specified on the LOOKUP command.(#`  'Ԍ ` /RECURSION ` /NORECURSION X X`  The /RECURSION option sets the recursion requested bit in queries sent by the LOOKUP command. The /NORECURSION option clears it. The default is /RECURSION.(#` ` /RETRY=count X X`  The /RETRY option sets the number of times a UDP request will be retried. The default is 3 retries for a total of 4 tries.(#` X X` /SERVER=server(#` X X`  The /SERVER option sets the server to be used for LOOKUP commands. The server can be specified as either a domain name or an internet address in dotted decimal notation. There is no default for /SERVER.(#` X X` /SUFFIX=suffix(#` X X`  The /SUFFIX option sets a suffix to be applied to unqualified domain names (ones with no periods) by the LOOKUP command.(#` X X` /TIMEOUT=timeout(#` X X`  The /TIMEOUT option sets the length of time in seconds the LOOKUP command will wait for a response before doing a retry when using the UDP protocol. The default is 5 seconds.(#` X X` /TYPE=type(#` X X`  The /TYPE option sets the query type for LOOKUP commands. The following types are available: A (Internet address), ANY (any records the server happens to have), CNAME (canonical name), HINFO (host information), MAILA (mail agent, obsolete), MAILB (mailbox), MB (mailbox), MD (mail destination, obsolete), MF (mail forwarder, obsolete), MG (mail group), MINFO (mail information), MR (mailbox rename), MX (mail exchanger), NS (name server), NULL (undefined), PTR (pointer), TXT (text), WKS (well known server), ZONE_TRANSFER (zone transfer). The default is A (Internet address).(#` X EXIT(# X ` The EXIT command exits from LOOKUP and returns to DCL.(# X HELP topic(# X ` The HELP command displays help about the topic given.(# X LOOKUP target options...(# X ` The LOOKUP command does a query to the current server about the target given and displays the results. Options ' specified on the LOOKUP command apply only to that command and override options specified on previous SET commands. The same options as on the SET command can be used on the LOOKUP command.(# Examples: DOMAIN/LOOKUP SET /SUFFIX=WAISMAN.WISC.EDU SET /SERVER=DON SET /TYPE=A LOOKUP HARRY This sequence of commands will query DON.WAISMAN.WISC.EDU for the Internet address of HARRY.WAISMAN.WISC.EDU.  PERIODIC_UPDATE The periodic update program keeps zones for which this server is a secondary server current, keeps resource records on the keep current list current, and removes expired responses from the cache. It normally runs continuously, checking the cache for expired data every 5 minutes. PERIODIC_UPDATE can be run either by calling the CREPRC system service or with a DCL command. It does not require that DCL be in its address space. It is started by START when the server is started. PERIODIC_UPDATE requires SYSLCK privilege. DCL invocation: DOMAIN/PERIODIC options Options: /DEBUG_LEVEL=n` Xh#Sets the level of debugging output. The higher the number, the greater the output. The source code must be consulted to interpret the debugging output.(#h  PRINT The print program lists the cache. PRINT should be run with a DCL command. DCL invocation: DOMAIN/PRINT options Options: /LOCK XXh#Lock each record while it is being printed. If this option is selected, the process running print must have SYSLCK privilege.(#h 'Ԍ /NOLOCK XXh#(Default) Do not lock each record while it is being printed. This may result in inconsistent data being printed or even the program getting lost in the cache if a record in the cache is updated while PRINT is looking at it. The lock information about each record is printed.(#h /OUTPUT=file` Xh#Specifies the output file to receive the listing. The default extension for the file is .LIS. If the /OUTPUT qualifier is not specified, the listing is written to SYS$OUTPUT.(#h  SERVE_TCP SERVE_TCP accepts messages from the TCP domain server port, port 53, and answers them. A separate invocation of SERVE_TCP is run for each TCP connection. SERVE_TCP can be run either by calling the CREPRC system service or with a DCL command. It does not require that DCL be in its address space. It is started by IPACP when a connection request is received for port 53. SERVE_TCP requires PHY_IO and SYSLCK privilege. DCL invocation: DOMAIN/TCP options Options: /DEBUG_LEVEL=n` Xh#Sets the level of debugging output. The higher the number, the greater the output. The  RELEASEC.SAV,B9[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOC.WP;27@ source code must be consulted to interpret the debugging output.(#h   SERVE_UDP SERVE_UDP accepts messages from the UDP domain server port, port 53, and answers the messages than can be answered from resource records in the cache. For the messages that cannot be answered from the cache, it creates a process running SERVE_UDP_FORKED to answer them. SERVE_UDP can be run either by calling the CREPRC system service or with a DCL command. It does not require that DCL be in its address space. It is started by START when the server is started. SERVE_UDP requires PHY_IO and SYSLCK privilege. DCL invocation: DOMAIN/UDP options  'ԌOptions: /DEBUG_LEVEL=n` Xh#Sets the level of debugging output. The higher the number, the greater the output. The source code must be consulted to interpret the debugging output.(#h /FORK_REQUEST` Xh#(Default) Makes SERVE_UDP queue requests that cannot be answered from the cache for processing by SERVE_UDP_FORKED.(#h  /NOFORK_REQUEST h#Makes SERVE_UDP answer all requests. This option is used for debugging since a request requiring queries to other hosts can required several minutes and SERVE_UDP only processes one request at a time.(#h /RUN_PROGRAMS` Xh#(Default) Makes SERVE_UDP create a process to run SERVE_UDP_FORKED if a message is queued to be processed by SERVE_UDP_FORKED.(#h /NORUN_PROGRAMS h#Prevents SERVE_UDP from creating a process to run SERVE_UDP_FORKED. This option is used for debugging.(#h  SERVE_UDP_FORKED SERVE_UDP_FORKED answers queries queued to it by SERVE_UDP. SERVE_UDP_FORKED can be run either by calling the CREPRC system service or with a DCL command. It does not require that DCL be in its address space. It is started by SERVE_UDP when a query is received that cannot be answered from the cache. SERVE_UDP_FORKED requires SYSLCK privilege. DCL invocation: DOMAIN/FORK_SERVER options Options: /DEBUG_LEVEL=n` Xh#Sets the level of debugging output. The higher the number, the greater the output. The source code must be consulted to interpret the debugging output.(#h  START START initializes the domain server programs. It creates the global section for the cache if it does not exist, validates the contents of the cache, initializes the cache if it is invalid or the /INITIALIZE option is used, reads the initialization files, and starts the UDP server, the periodic update program, and, if necessary, the primary update program. Note that the initialization file is only read if the cache is initialized. It can be run as part of the system bootstrap procedure after the TCP/IP package has been initialized. The process in which it is run should have SYSGBL, SYSLCK, PHY_IO, and PRMGBL privileges. 'Ԍ DCL invocation: DOMAIN/START options Options: /DEBUG_LEVEL=n` Xh#Sets the level of debugging output. The higher the number, the greater the output. The source code must be consulted to interpret the debugging output.(#h /INITIALIZE` Xh#Unconditionally initialize the cache. This qualifier must be used if the cache is intact and an initialization file is changed. The primary update program will be started if START starts programs.(#h /NOINITIALIZE` Xh#(Default) Initialize the cache only if it does not exist or is corrupted. If the cache is intact, the primary update program will not be started and the initialization files will not be read.(#h /RUN_PROGRAMS` Xh#(Default) Create processes with the UDP server program, the periodic update program, and, if necessary, the primary update program.(#h /NORUN_PROGRAMS h#Do not create processes with the UDP server program, the periodic update program, and the primary update program. This option is used mainly to debug the programs START would normally start.(#h  STOP STOP stops the UDP server process and the periodic update process and removes the cache global section. STOP can be run either by calling the CREPRC system service or with a DCL command. It does not require that DCL be in its address space. It is started by START when the server is started and the cache is not intact and manually when the primary zone data is changed. STOP requires PRMGBL, SYSGBL, and SYSLCK privilege. DCL invocation: DOMAIN/STOP options Options: /DEBUG_LEVEL=n` Xh#Sets the level of debugging output. The higher the number, the greater the output. The source code must be consulted to interpret the debugging output.(#h  UPDATE_PRIMARY 'Ԍ UPDATE_PRIMARY reads the zone master files for the server and stores them in the cache. If an error is found in any file read, the cache is not changed. UPDATE_PRIMARY can be run either by calling the CREPRC system service or with a DCL command. It does not require that DCL be in its address space. It is started by START when the server is started and the cache is not intact and manually when the primary zone data is changed. UPDATE_PRIMARY requires SYSLCK privilege. DCL invocation: DOMAIN/PRIMARY options Options: /DEBUG_LEVEL=n` Xh#Sets the level of debugging output. The higher the number, the greater the output. The source code must be consulted to interpret the debugging output.(#h  INITIALIZATION FILES START reads several text files if it has to initialize the cache. These files must be prepared manually before START is run. In all the files, everything between a semicolon (;) and the end of the line is treated as a comment and ignored. In general, letter case does not matter, although it will be preserved in resource records. In the command and resource record descriptions, items shown in upper case are keywords which should be used as shown, although case does not matter. Items shown in angle brackets (< >) should be replaced with a value. Ellipsis (...) indicate that the last item on the line may be repeated as many times as needed. Parameter file The parameter file describes the zones the server will maintain, initialization data, nearby servers, and other information. It is read by START using the logical DOMAIN$SERVER_STARTUP. Cache command Format: X X` CACHE (#` X X`  Gives the size for the cache in bytes. A cache size of 512,000 bytes (1000 pages) will be used if the cache command is not used. All the data for zones the server holds as both a primary and secondary server is stored in the cache as well as responses that have not expired. If the server holds many or large zones, the cache size '  may have to be increased.(#` Workset command Format: X X` WORKSET (#` X X`  Gives the working set quota and extent for programs started by START. can be either PERIODIC_UPDATE, UDP_SERVER, or UPDATE_PRIMARY. The working set quota and extent are given in pages.(#` Primary command Format: X X` PRIMARY (#` X X` N RELEASEC.SAV,B9[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOC.WP;27@W& Indicates that the server will be a primary server for the zone named. The resource records for the zone are to be found in the file named.(#` Secondary command X Format:(# ` SECONDARY ... X X`  Indicates that the server will be a secondary server for the zone named. The resource records for the zone will be copied from one of the servers named.(#` Forwarder command X Format:(# ` FORWARDER ... X X`  Indicates that the server may forward queries to the servers named. In general, if FORWARDERONLY is not specified, the server prefers to send queries to authoritative servers rather than forwarder servers.(#` Forwarderonly command Format: X X` FORWARDERONLY(#` X X`  Indicates that the server should only query the forwarder servers that are listed in this file and not any servers it learns about in responses to queries.(#` Initial command  ' Ԍ Format: ` INITIAL X X`  Indicates that the server should read resource records from the file named to initialize the cache. These resource records will not be returned in response to any query but may be used by the server to find other servers. Therefore, only NS and A resource records are of any use in the initialization file. Since the resource records in the initialization file must be updated manually if any of the information on them changes, the fewer resource records the better. On the other hand, these resource records are used to initialize the server so the more options the server has to find data, the more likely it is to be able to find all the data it needs.(#` Keep current command Format: X X` KEEPCURRENT (#` X X`  Indicates that the server should read a list of resource records to be kept current from the file named. Each record in the file should consist of a domain name and a resource record type. The server will query other servers for the resource records listed often enough so that they never time out in the cache. Most sites will want the NS resource records of the root servers on their keep current list and perhaps other servers that are likely to be used. Note that it is not necessary to explicitly list A records for the servers along with the NS records for the domain since the A records are returned along with the NS records.(#` Preferred address command Format: ` PREFERREDADDRESS X X`  Indicates that the server should read a list of network preferences from the file named. Each record is in the form(#` X X`  (#` X X` where and are in internet address dotted decimal notation and is an integer. When the server needs to contact another server and that server has more than one internet address, the server checks the address preference list. It uses the address that has the lowest preference value among the preference records that match according to(#` X X`  & == (#`  ' ԌX X` X  & (# X X` This can be used to encode the network topology to minimize the number of hops a message takes.(#` Protocols file The protocols file contains a list of the protocol names and the corresponding protocol numbers. It is used by UPDATE_PRIMARY for the protocol names used on WKS resource records. It is found by the logical DOMAIN$SERVER_PROTOCOLS. Each record consists of a protocol name, whitespace, and the protocol number. Services file The services file contains a list of the service names and the corresponding port numbers. It is used by UPDATE_PRIMARY for the service names used on WKS resource records. It is found by the logical DOMAIN$SERVER_SERVICES. Each records consists of a service name, whitespace, the port number, a slash, and the protocol name. WKS resource records only cover ports 1255 so services at any other port numbers are ignored. Resource records files The zone master files and the initialization files are in the standard resource record format described in RFC 1135, sections 3 and 5. Here is a summary of the resource record formats in the files (fields in brackets ([ ]) are optional): Internet address resource record X [] [] [] A (# Canonical name resource record X [] [] [] CNAME (# Host information resource record X [] [] [] HINFO (# Mailbox resource record X [] [] [] MB (# Mailing list member resource record X [] [] [] MG (# Mailing list information record X [] [] [] MINFO (# ' Ԍ Mailbox rename resource record X [] [] [] MR (# Mail exchanger resource record X [] [] [] MX (# Name server resource record X [] [] [] NS (# Pointer resource record X [] [] [] PTR (# Start of authority resource record X [] [] [] SOA (# Text resource record X [] [] [] TXT ...(# Well known server resource record X [] [] [] WKS ...(# If the of a resource record is omitted, the first character of the line must be whitespace (blank or tab). The of the preceding resource record will be used. If the is omitted, from the SOA record is used. If the is omitted, internet is used (which is all that is allowed anyway). SET UP The domain server is distributed in 3 save sets. Save set A consists of the .EXE files and a .COM file to start the domain server, STARTUP.COM. Save set B consists of documents and some sample zone files. Save set C consists of the source modules. Save set C also includes the source for this document and the source for the LOOKUP help file in WordPerfect form. The first step in the installation is to restore save set A and to restore save sets B and C if desired. The file '  BUILD_ALL.COM in save set C can be used to compile all the modules if desired. The second step is to edit file STARTUP.COM if necessary. STARTUP.COM is intended to be executed during a system boot. The symbol DOMSDIR must be defined to be the directory containiE RELEASEC.SAV,B9[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOC.WP;27@5ng the .EXE files and the help library for LOOKUP. If the .EXE files are in the same directory as STARTUP.COM, the definition as distributed will work. The time zone symbols TZ$WINTER_ZONE and TZ$SUMMER_ZONE in STARTUP.COM can be corrected if desired, although all that matters to the domain server is the difference in the offsets between summer time and winter time. The syntax is hhmm:zzz where hhmm is the offset to universal time in hours and minutes (omit the for zones east of the prime meridian) and zzz is the zone name. The symbols giving the rules for starting and ending summer time, TZ$SUMMER_START and TZ$SUMMER_END, should be correct, although the only effect of them being wrong would be that a resource record expires an hour too early or an hour too late at the time change. The syntax is m:w:d:hhmm where m is the month number when the change takes place (1 is January, etc.), w is the occurrence of the day when the change takes place (1 for the first, etc., and L for the last), d is the day of the week when the change takes place (1 for Sunday, etc.), and hhmm is the time in local time when the change takes place. The third step is to create the server initialization files DOMAIN$SERVER_STARTUP and the files it references, particularly the zone master files. Save set B contains examples of these files that can be used is templates. RFC 1033 contains a description of how to build the master files. The fourth step is to edit the INTERNET.CONFIG file. A well known server line should be added for the TCP domain server, such as the following:  WKS:53:DOMSSV:TCP$DOMSSV:NETWRK:NETMBX,TMPMBX,PHY_IO,SYSLCK:4:5 KEEPALIVES can be turned on to catch a server failure on an incoming zone transfer and to catch a client failure on TCP queries. IPACP must be stopped and restarted to use the modified INTERNET.CONFIG. The last step is to execute the STARTUP.COM file which actually starts the server. This file must also be executed after every system boot. The file SHUTDOWN.COM stops the server. It can be used in the system shutdown file. It is not necessary to set up the server to just run LOOKUP.  ' All that is necessary is to define DOMSDIR as the directory containing DOMSER.CLD, LOOKUP.EXE and LOOKUP_HELP.HLB and do SET COMMAND DOMSDIR:DOMSER TROUBLESHOOTING 1. Using the LIST command in INSTALL, check that DOMSSHR, SERVE_TCP, and SERVE_UDP_FORKED are installed. These files are installed by the startup procedure. Check that the .EXE files are stored where the logicals say they are. (It is not essential that they be installed, but the start up procedure does install them.) 2. Using SHOW SYSTEM, check that processes named DOMS_UDP_SERVER and DOMS_PER_UPD are running. These processes are created by DOMAIN/START. They will not be started if there were errors in one of the set up files read by DOMAIN/START or if they were inaccessible, perhaps due to erroneous logicals. 3. Using NETSTAT, check that there is a server active for UDP port 53. Process DOMS_UDP_SERVER should have opened UDP port 53. 4. Using the LIST/GLOBAL command in INSTALL, check that global section DOMAIN_SERVER_MCOM has been defined. It should have the write attribute and be 1000 pages (or whatever you set with the CACHE parameter) long. It is defined by DOMAIN/START. The cache is stored in this global section. 5. Using DOMAIN/PRINT, examine the cache. Look for: X ` 1. The RR's in the initialization file. They should have authority INIT. They are stored by DOMAIN/START when it initializes the cache.(# X ` 2. The RR's in the zones for which the server is a primary server. They should have authority PRI. They are stored by DOMAIN/PRIMARY when it is run manually or when it is started by DOMAIN/START when the cache is initialized.(# X ` 3. The RR's in the zones for which the server is a secondary server. They should have authority SEC. They are stored by DOMS_PER_UPD when the cache is initialized or when they are updated by the primary server.(# X ` 4. The RR's on the keep current list. They should have authority RES. They are stored by DOMS_PER_UPD when the cache is initialized and whenever they are close to expiring. In particular, look for the root servers. They will be at the beginning of the listing since it is a preorder traversal of the tree.(# 6. Using DOMAIN/LOOKUP, send a UDP query to the server being installed. Using SET /FULL, enable full output so you see the status codes. If you get a correct response, the UDP server should be working. If you get a response with server failure status, it means that the server could not contact another server that appeared to hold necessary information. In particular, it may not ' have been able to contact the root servers. (If you are not connected to the Internet and so cannot contact the root servers, you can either live with the server failure status for an invalid name or fake a root server entry. Warning: If you fake a root server record, be sure it never escapes to the Internet, particularly if you later connect to the Internet.) 7. Using DOMAIN/LOOKUP send a TCP query to the server being installed. If UDP queries are answered and TCP queries are not, check the well known server declaration for port 53 in INTERNET.CONFIG. =*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSER.CLD;15+,-./@ 40r-B0123KPWO56@ 7=89G@HJDEFINE VERB DOMAIN QUALIFIER CHECK SYNTAX=CHECK$ QUALIFIER EXAMINE SYNTAX=EXAMINE" QUALIFIER LOOKUP SYNTAX=LOOKUP, QUALIFIER FORK_SERVER SYNTAX=FORK_SERVER& QUALIFIER PERIODIC SYNTAX=PERIODIC$ QUALIFIER PRIMARY SYNTAX=PRIMARY QUALIFIER PRINT SYNTAX=PRINT QUALIFIER START SYNTAX=START QUALIFIER STOP SYNTAX=STOP* QUALIFIER TCP_SERVER SYNTAX=TCP_SERVER* QUALIFIER UDP_SERVER SYNTAX=UDP_SERVERDEFINE SYNTAX CHECK IMAGE DOMSDIR:CHECK* QUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)DEFINE SYNTAX EXAMINE IMAGE DOMSDIR:EXAMINEDEFINE SYNTAX FORK_SERVER" IMAGE DOMSDIR:SERVE_UDP_FORKED* QUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)DEFINE SYNTAX LOOKUP IMAGE DOMSDIR:LOOKUP* QUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)DEFINE SYNTAX PRIMARY IMAGE DOMSDIR:UPDATE_PRIMARY* QUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)DEFINE SYNTAX PERIODIC! IMAGE DOMSDIR:PERIODIC_UPDATE* QUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)DEFINE SYNTAX PRINT IMAGE DOMSDIR:PRINT QUALIFIER LOCK0 QUALIFIER OUTPUT, VALUE(TYPE=$FILE,REQUIRED)DEFINE SYNTAX START IMAGE DOMSDIR:START QUALIFIER INITIALIZE* QUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)# QUALIFIER RUN_PROGRAMS, DEFAULTDEFINE SYNTAX STOP IMAGE DOMSDIR:STOP* QUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)DEFINE SYNTAX TCP_SERVER IMAGE DOMSDIR:SERVE_TCP* QUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)DEFINE SYNTAX UDP_SERVER IMAGE DOMSDIR:SERVE_UDP*  RELEASEC.SAV-B=[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSER.CLD;150 YQUALIFIER DEBUG_LEVEL, VALUE(REQUIRED)# QUALIFIER FORK_REQUEST, DEFAULT# QUALIFIER RUN_PROGRAMS, DEFAULT;*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSER.H;78+, .6/@ 4l65-B0123 KPWO75M6$7@ 8`9G@HJ/* * Domain server include file * Bruce Orchard' * Harris Vulcan version: June, 1988: * DEC VAX VMS (with CMU TCP/IP) version: October, 1989 *//* * File names */,#define STARTUP_FILE "DOMAIN$SERVER_STARTUP"/#define PROTOCOL_FILE "DOMAIN$SERVER_PROTOCOLS",#define SERVER_FILE "DOMAIN$SERVER_SERVICES"@#define MCOM_SECTION_FILE_NAME "DOMAIN$SERVER_MCOM_SECTION_FILE"/* * Program names */@#define UPDATE_PRIMARY_ZONE_IMAGE "DOMAIN$SERVER_UPDATE_PRIMARY"=#define PERIODIC_UPDATE_IMAGE "DOMAIN$SERVER_PERIODIC_UPDATE"3#define UDP_SERVER_IMAGE "DOMAIN$SERVER_UDP_SERVER":#define UDP_SERVER_FORKED_IMAGE "DOMAIN$SERVER_UDP_FORKED"3#define TCP_SERVER_IMAGE "DOMAIN$SERVER_TCP_SERVER"/* * Process names */2#define UPDATE_PRIMARY_ZONE_PROCESS "DOMS_UPD_PRI".#define PERIODIC_UPDATE_PROCESS "DOMS_PER_UPD",#define UDP_SERVER_PROCESS "DOMS_UDP_SERVER"1#define UDP_SERVER_FORKED_PROCESS "DOMS_UDP_FORK",#define TCP_SERVER_PROCESS "DOMS_TCP_SERVER"/*7 * Shared global section name and default size in bytes */.#define MCOM_SECTION_NAME "DOMAIN_SERVER_MCOM"#define MCOM_SIZE_BYTES 512000/* * Port number */#define DOMAIN_PORT 53/* * Update period */D#define UPDATE_PERIOD 300 /* Update period, seconds */Q#define TICKS_PER_SECOND 1 /* clock ticks per second (for $DELAY) *//*0 * Time to refresh RR's on the keep current list */#define REFRESH_TIME HOUR/* * Server aging parameters */$#define SERVER_AGE_PERIOD (6 * HOUR)#define SERVER_AGE_FACTOR .95S#define SERVER_SCORE_BASE 500 /* Assumed response time in milliseconds *//*+ * These routines only deal with one class: */#define CLASS_ALPHA "IN"#define CLASS_NUM 1#define CLASS_ALL 255/* * Priority */#define PRIORITY 4/*9 * Substitute character for . when it divides name levels * (Watch out--it's negative) */#define DOT 0201/* * Size in words */%#define size_word(s) (sizeof (s) / 3)/*, * Make a pointer relative to monitor common */>#define relpointer(p, t) ((t *) ((int) (p) - (int) mcom_base))/*, * Make a pointer to monitor common absolute */>#define abspointer(p, t) ((t *) ((int) (p) + (int) mcom_base))/* * Monitor common block pointer */extern noshare char *mcom_base;extern noshare int mcom_size;/* * Typedef's */$typedef long int t_internet_address;^typedef long int t_timestamp; /* Times are in seconds since Jan 1, 1980, 00:00:00 */#define SECOND 1#define MINUTE (SECOND*60)#define HOUR (MINUTE*60)#define DAY (HOUR*24)#define MONTH (DAY*30)/* * Maximums */U#define MAX_LEVEL 50 /* Maximum number of levels in domain name */M#define MAX_WKS 255 /* Maximum server number in WKS RR */L#define MAX_MESSAGE 2000 /* Maximum message length (bytes) */M#define MAX_PREFIX 100 /* Maximum outgoing message prefix */Q#define MAX_TXT_STRING 200 /* Maximum number of strings in TXT RR *//*2 * Message prefix lengths (CMU/TEK TCP/IP version) */#define UDP_PREFIX_LENGTH 12#define TCP_PREFIX_LENGTH 2/* * Memory block format: *
 *  *  *# * Header and trailer word format: */ struct b_ {< unsigned int b_alloc:1, /* Block allocated */7 b_last:1, /* Last block */Q b_pad:2, /* Padding to make dumps easier to read */? b_size:28; /* Block size (words) */};/* * Free list */ struct bf_ { struct bf_ *bf_next;};/* * List head pointer */ struct hp_ {K struct lp_ *hp_first; /* Pointer to first entry in list */J struct lp_ *hp_last; /* Pointer to next entry in list */};/* * Link pointer */ struct lp_ { struct lp_ *lp_next; struct lp_ *lp_prev;};/* * Lock */ struct l_ {J int l_nwrite; /* Number of writers (at most 1) */};/* * Resource record name */ union rn_ {] struct n_ *rn_name_node; /* Pointer to name structure (used in shared memory */g char *rn_name_string; /* Pointer to string with whole name (used in private memory) */J /* (Levels are separated by .'s) */d struct nl_ *rn_name_list; /* Pointer to name list structure (used in private memory) */};#define RN_NODE 1#define RN_STRING 2#define RN_LIST 3/* * First block of monitor common */ struct f_ {G struct l_ f_alloc_lock; /* Lock for memory allocation */C struct hp_ f_n_head; /* Name list head pointer */M struct l_ f_n_lock; /* Lock for level 0 name entry list */D struct hp_ f_z_head; /* Zone list head pointer */? struct l_ f_z_lock; /* Lock for zone list */O int f_n_bad_zone; /* Number of zones with unloaded data */H struct hp_ f_fw_head; /* Forwarder list head pointer */K struct l_ f_fw_lock; /* Lock for forwarder server list */R int f_fw_only; /* Nonzero => only use forwarder servers */K struct hp_ f_kc_head; /* Keep current list head pointer */G struct l_ f_kc_lock; /* Lock for keep current list */K struct hp_ f_pa_head; /* Preferred address head pointer */L struct l_ f_pa_lock; /* Lock for preferred address list */L struct hp_ f_ru_head; /* Recent UDP request head pointer */M struct l_ f_ru_lock; /* Lock for recent UDP request list */N t_timestamp f_last_server_age; /* Last time server scores were aged */H int f_aging_in_progress; /* Server aging is in progress */? struct l_ f_last_server_age_lock; /* Lock for last time */Q char f_exit_periodic_mailbox[16]; /* Mailbox to make periodic_update exit */N char f_exit_udp_server_mailbox[16]; /* Mailbox to maike udp_server exit */F struct hp_ f_fq_head; /* Head of forked query list */> struct l_ f_fq_lock; /* Forked query lock */#define NFREELIST 100> struct bf_ *f_free[NFREELIST]; /* Free memory lists */H int *f_top; /* First unused cell in memory */? int f_mcom_size_bytes; /* MCOM size in bytes */H int f_pri_wsquota; /* WSQUTOTA f RELEASEC.SAV B;[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSER.H;786l6(or PRIMARY_UPDATE */H int f_pri_wsextent; /* WSEXTENT for PRIMARY_UPDATE */I int f_per_wsquota; /* WSQUTOTA for PERIODIC_UPDATE */I int f_per_wsextent; /* WSEXTENT for PERIODIC_UPDATE */D int f_udp_wsquota; /* WSQUTOTA for UDP_SERVER */D int f_udp_wsextent; /* WSEXTENT for UDP_SERVER */};/* * Name (one level)' * (There is a name node for the root.) */ struct n_ {] struct lp_ n_link; /* Pointer to next name in hash chain at this level */H struct n_ *n_up; /* Pointer to parent name node */C char *n_name; /* One level of node name */A struct rp_ *n_rr; /* Pointer to RR vector */H struct h_ *n_h; /* Pointer to hash head vector */M struct hp_ n_ne_head; /* First authority for nonexistence */V struct l_ n_lock; /* Lock for everything hanging on name entry */T int n_server_reference_count; /* Reference count for this name as server */V struct s_ *n_s; /* Head pointer for server score information */};/* * Hash head vectorF * (This is really just an extension of the n_ structure, but, since? * the leaf nodes don't have one, splitting it saves memory.) */#define NAME_HASH_DIVISOR 7 struct h_ {* struct hp_ h_nhead[NAME_HASH_DIVISOR];};/* * RR type values */#define RR_A 1#define RR_NS 2#define RR_CNAME 5#define RR_SOA 6#define RR_MB 7*#define RR_MG 8v#define RR_MR 98#define RR_NULL 10#define RR_WKS 11v#define RR_PTR 129#define RR_HINFO 13 #define RR_MINFO 14 #define RR_MX 15#define RR_TXT 16/*! * Resource record pointer vectorO' * (Also an extension of n_ structure)R */I struct rp_ { struct hp_ rr_ad_head; struct hp_ rr_cn_head; struct hp_ rr_hi_head; struct hp_ rr_ks_head; struct hp_ rr_mb_head; struct hp_ rr_mg_head; struct hp_ rr_mi_head; struct hp_ rr_mr_head; struct hp_ rr_mx_head; struct hp_ rr_ns_head; struct hp_ rr_pt_head; struct hp_ rr_sa_head; struct hp_ rr_tx_head;};/* * RR entry prefix */o struct rr_ {Q struct lp_ rr_link; /* Pointers to next and previos entries */C9 union rn_ rr_name; /* Name pointer */R+#define rr_name_node rr_name . rn_name_node_/#define rr_name_string rr_name . rn_name_stringS+#define rr_name_list rr_name . rn_name_listn4 int rr_type; /* RR type */F struct hp_ rr_a_head; /* Pointer to authority list */};/* * Address RRA */Rstruct rr_ad_ {dA struct rr_ rr_ad_prefix; /* Links, RR name, etc. */ = t_internet_address rr_ad_address; /* Internet address */c};/* * Canonical name RR */struct rr_cn_ {o struct rr_ rr_cn_prefix; union rn_ rr_cn_name;R1#define rr_cn_name_node rr_cn_name . rn_name_node*5#define rr_cn_name_string rr_cn_name . rn_name_stringR1#define rr_cn_name_list rr_cn_name . rn_name_list };/* * Host info RRi */ struct rr_hi_ { struct rr_ rr_hi_prefix; char *rr_hi_cpu; char *rr_hi_os;L};/* * Mailbox RRU */struct rr_mb_ {  struct rr_ rr_mb_prefix; union rn_ rr_mb_server;*5#define rr_mb_server_node rr_mb_server . rn_name_node9#define rr_mb_server_string rr_mb_server . rn_name_string5#define rr_mb_server_list rr_mb_server . rn_name_liste};/* * Mail group RR */nstruct rr_mg_ {o struct rr_ rr_mg_prefix; union rn_ rr_mg_mailbox;7#define rr_mg_mailbox_node rr_mg_mailbox . rn_name_nodec;#define rr_mg_mailbox_string rr_mg_mailbox . rn_name_string(7#define rr_mg_mailbox_list rr_mg_mailbox . rn_name_liste};/* * Mailing list info RR_ */struct rr_mi_ {i struct rr_ rr_mi_prefix; union rn_ rr_mi_rmailbox;t9#define rr_mi_rmailbox_node rr_mi_rmailbox . rn_name_nodeT=#define rr_mi_rmailbox_string rr_mi_rmailbox . rn_name_stringO9#define rr_mi_rmailbox_list rr_mi_rmailbox . rn_name_list union rn_ rr_mi_emailbox; 9#define rr_mi_emailbox_node rr_mi_emailbox . rn_name_node =#define rr_mi_emailbox_string rr_mi_emailbox . rn_name_stringe9#define rr_mi_emailbox_list rr_mi_emailbox . rn_name_listr};/* * Mail rename RRf */Astruct rr_mr_ {  struct rr_ rr_mr_prefix; union rn_ rr_mr_mailbox;7#define rr_mr_mailbox_node rr_mr_mailbox . rn_name_node ;#define rr_mr_mailbox_string rr_mr_mailbox . rn_name_stringm7#define rr_mr_mailbox_list rr_mr_mailbox . rn_name_list };/* * Mail exchanger RR */struct rr_mx_ {F struct rr_ rr_mx_prefix; int rr_mx_preference;o union rn_ rr_mx_server;r5#define rr_mx_server_node rr_mx_server . rn_name_node*9#define rr_mx_server_string rr_mx_server . rn_name_string 5#define rr_mx_server_list rr_mx_server . rn_name_list/};/* * Name server RR  */ struct rr_ns_ {k struct rr_ rr_ns_prefix; union rn_ rr_ns_server;m5#define rr_ns_server_node rr_ns_server . rn_name_node 9#define rr_ns_server_string rr_ns_server . rn_name_stringi5#define rr_ns_server_list rr_ns_server . rn_name_list};/* * Pointer RR */struct rr_pt_ {  struct rr_ rr_pt_prefix; union rn_ rr_pt_name;t1#define rr_pt_name_node rr_pt_name . rn_name_node 5#define rr_pt_name_string rr_pt_name . rn_name_stringn1#define rr_pt_name_list rr_pt_name . rn_name_listn};/* * Start of authority RR */struct rr_sa_ {t struct rr_ rr_sa_prefix; union rn_ rr_sa_primary;7#define rr_sa_primary_node rr_sa_primary . rn_name_noden;#define rr_sa_primary_string rr_sa_primary . rn_name_string 7#define rr_sa_primary_list rr_sa_primary . rn_name_list union rn_ rr_sa_responsible;?#define rr_sa_responsible_node rr_sa_responsible . rn_name_noderC#define rr_sa_responsible_string rr_sa_responsible . rn_name_stringe?#define rr_sa_responsible_list rr_sa_responsible . rn_name_listo long int rr_sa_serial; long int rr_sa_refresh;f long int rr_sa_retry;S long int rr_sa_expire; long int rr_sa_minimum;i};/* * Text RR */ struct rr_tx_ {  struct rr_ rr_tx_prefix;C int rr_tx_ntext; /* Number of text strings *//J char *rr_tx_text[1]; /* Array of text string pointers */};/* * Well known server RR  */ustruct rr_ks_ {  struct rr_ rr_ks_prefix;% t_internet_address rr_ks_address;  int rr_ks_protocol;z int rr_ks_high_server; unsigned char *rr_ks_server;};/* * Authority information */u struct a_ {e^ struct lp_ a_link; /* Pointers to next and previous entries for this RR */: struct rr_ *a_rr; /* Pointer to RR */J int a_source_type; /* Type of source of information */L#define A_SOURCE_BOOT 1 /* Information came from boot file */S#define A_SOURCE_PRIMARY_ZONE 2 /* Information came from zone master file */ P#define A_SOURCE_SECONDARY_ZONE 3 /* Information came from zone transfer */Q#define A_SOURCE_RESPONSE 4 /* Information came from query response *//B struct z_ *a_zone; /* Pointer to zone entry */\ struct lp_ a_zlink; /* Pointers to next and previous authority of zone */C long int a_ttl; /* Time to live (seconds) */ W t_timestamp a_expire; /* Expiration time (only for query responses) */rl union rn_ a_source; /* Source of information (only for responseGC( RELEASEC.SAV B;[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSER.H;78;100l6hs--to track fishy data) */-#define a_source_node a_source . rn_name_nodek1#define a_source_string a_source . rn_name_string > t_timestamp a_time; /* Time data entered */I unsigned int a_authority:1; /* This record is authoritative */tK unsigned int a_present:1; /* This record is present in zone */ };/* * Zonei1 * (One entry for each zone we are authority for)y */ struct z_ { T struct lp_ z_link; /* Links to next and previous zone entries */6 union rn_ z_name; /* Zone name */)#define z_name_node z_name . rn_name_node_-#define z_name_string z_name . rn_name_stringI? unsigned long int z_serial; /* Zone serial number */f6 int z_type; /* Zone type */S#define Z_BOOT 1 /* Dummy zone--came from initializer file */EV#define Z_PRIMARY 2 /* We are primary server (have master file ) */^#define Z_SECONDARY 3 /* We are secondary server (don't have master file ) */M char *z_file; /* File containing zone master file */oD t_timestamp z_filewrite; /* Last write time of file */O t_timestamp z_try_time; /* Time for next try to get zone data */tC t_timestamp z_expire_time; /* Time zone data expires */dL long int z_refresh_seconds; /* Seconds to wait befoore refresh */I long int z_retry_seconds; /* Seconds to wait before retry */ J long int z_expire_seconds; /* Seconds to wait before expire */E struct hp_ z_server_head; /* Server list head pointer */ A struct hp_ z_a_head; /* RR list head pointer */sI struct l_ z_a_lock; /* Lock for zone authority list */ @ unsigned int z_good:1; /* Zone data is loaded */};/*% * Zone servers (for secondary zones)t */h struct zs_ { struct lp_ zs_link;D union rn_ zs_name;+#define zs_name_node zs_name . rn_name_node /#define zs_name_string zs_name . rn_name_stringd};/* * RR's to keep currentd: * (These RR's are always kept current. There is no point4 * in listing RR's here for which we have the zone.) */ struct kc_ { struct lp_ kc_link; union rn_ kc_name;+#define kc_name_node kc_name . rn_name_nodes/#define kc_name_string kc_name . rn_name_string_ int kc_rrtype;};/* * Server < * This structure is just used to keep score on the servers.? * (Actually, its most important effect is to blacklist serversi * that don't answer.) */h struct s_ {uT union rn_ s_name; /* Server name (whole name, including .'s) */)#define s_name_node s_name . rn_name_node;-#define s_name_string s_name . rn_name_string{M int s_nquery; /* Number of queries sent to server */sQ int s_nanswer; /* Number of queries answered by server */oN int s_response_time; /* Mean response time (milliseconds) */};/* * Forward serversE * (The server tries these servers before the authoritative servers.)  */t struct fw_ {M struct lp_ fw_link; /* Links to next and previous entry */8 union rn_ fw_name; /* Server name */+#define fw_name_node fw_name . rn_name_noded/#define fw_name_string fw_name . rn_name_string};/* * Temporary server list4 * These servers will be tried for the current query */ struct ts_ {U struct lp_ ts_link; /* Link to next temporary server list entry */e] struct n_ *ts_name; /* Pointer to server name (shared memory, absolute) */Re struct s_ *ts_s; /* Pointer to server score record (shared memory, absolute) */;b int ts_score; /* Server score (average response time in milliseconds)) */V#define DEFAULT_SCORE 1000 /* Score to use if we never used this server */ struct hp_ ts_address;L int ts_nparent; /* Number of parent levels of name */9 struct n_ *ts_parent[MAX_LEVEL]; /* Parent names */pQ int ts_tried; /* Nonzero => this server already tried */_R int ts_forwarder; /* Nonzero => added to list as forwarder */};/*& * Addresses for temporary server list */* struct tsa_ {s struct lp_ tsa_link;# t_internet_address tsa_address;;};/*# * Message header (internal format)_@ * (Since there will only be a few of these around at a time, itD * does not pay to pack the bits as is done in the external format.) */m struct mh_ {< int mh_id; /* Query ID number */6 int mh_qr; /* 0: Query */9 /* 1: Response */ ; int mh_opcode; /* Operation code */#define Q_QUERY 0#define Q_IQUERY 1#define Q_STATUS 2A int mh_aa; /* Authoritative answer */o> int mh_tc; /* Message truncated */> int mh_rd; /* Recursion desired */@ int mh_ra; /* Recursion available */A int mh_rcode; /* Response status code */n#define RCODE_NO_ERROR 0#define RCODE_FORMAT_ERROR 1#define RCODE_SERVER_FAILURE 2#define RCODE_NAME_ERROR 3#define RCODE_NOT_IMPLEMENTED 4 #define RCODE_REFUSED 5s> int mh_qdcount; /* Number of queries */C struct hp_ mh_query; /* Pointer to first query */nB int mh_ancount; /* Number of answer RR's */G struct hp_ mh_answer; /* Pointer to first answer RR */_G int mh_nscount; /* Number of name server RR's */L struct hp_ mh_nameserver; /* Pointer to first name server RR */F int mh_arcount; /* Number of additional RR's */K struct hp_ mh_additional; /* Pointer to first additional RR */e};#define SECTION_ANSWER 1#define SECTION_SERVER 2#define SECTION_ADDITIONAL 3/* * Query (internal format)m */ struct q_ {_? struct lp_ q_link; /* Link to next query */_J union rn_ q_name; /* Name that is subject of query */)#define q_name_node q_name . rn_name_nodee-#define q_name_string q_name . rn_name_stringa)#define q_name_list q_name . rn_name_list_? int q_name_source; /* Type of name entry */r7 int q_type; /* Query type */ #define Q_AXFR 252#define Q_MAILB 253_#define Q_ALL 255o8 int q_class; /* Query class */};/* * Forked query list5 * (UDP queries that could not be answered from cachex */i struct fq_ {? struct lp_ fq_link; /* Link to next query */h? t_internet_address fq_source_address; /* Source address */ 8 int fq_source_port; /* Source port */X t_internet_address fq_destination_address; /* Destination address (this server!) */B int fq_destination_port; /* Destination port (53) */4 char *fq_message; /* Message */C int fq_message_length; /* Message length (bytes) */dE struct ru_ *fq_ru; /* Recent UDP entry pointer */ };/*2 * Name list (used to build queries and responses) */e struct nl_ {L struct lp_ nl_name_link; /* Link to next level of this name */O struct lp_ nl_this_level_link; /* Link to another name at this level */oD struct hp_ nl_down_level_link; /* Link to next level down */H inF & RELEASEC.SAV B;[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSER.H;78;100l6,t nl_length; /* String length at this level */> int nl_offset; /* Offset in message */? char nl_string[1]; /* String (one level) */i};/* * RR type names */ struct rt_ {; int rt_type; /* RR type number */ 9 char *rt_name; /* RR type name */ };/* * Preferred addresses */o'#define DEFAULT_ADDRESS_PREFERENCE 1000o struct pa_ {Q struct lp_ pa_link; /* Link to next preferred address entry */n< t_internet_address pa_network; /* Network address */9 t_internet_address pa_mask; /* Network mask */ Q /* Matches if (address&mask) == network */rO int pa_preference; /* Preference value (lower is better) */ };/* * Recent UDP request list */ struct ru_ {N struct lp_ ru_link; /* Link to next recent request entry */Q t_internet_address ru_source_host; /* Source of request: Internet address */eE int ru_source_port; /* Source of request: Port */e7 int ru_query_id; /* Request ID */ B t_timestamp ru_time; /* Time request received */B int ru_in_process; /* Nonzero => in process */};/* * Locking rules:mI * 1. There can be one reader or any number of writers holding a lock. G * 2. The read lock and write lock are mutually exclusive. A holder D * of the read lock that wants the write lock must release theF * read lock before requesting the write lock. It will probablyH * want to make sure there were no changes after getting the write * lock.O * 3. To avoid deadlocks, the locks must be requested in this partial order:i * Zonet * Zone authority list * Keep currentz4 * Name node (higher node before lower node) * AllocatetD * 4. The lock for a parent node controls the access to the linksB * in the lists hanging from the parent. This means that toB * insert of delete something form a list, the parent of the# * list must be write locked. E * 5. There are no locking order restrictions within the name tree ( * if only read accesses are done.D * 6. If write accesses are to be done, all the nodes in the pathE * from the root to the node to be written must be locked. AlluC * should be read locked except the node to be written, whiche * should be write locked.F * 7. A name node cannot disappear while its server reference countI * is greater than 0 or there is an RR or name node or server scoresI * hanging from it. Note that server scores are never deallocated.i *//* * Returns from lexical routines */k#define LEX_EOF 1d#define LEX_EOL 2_#define LEX_NULL 3#define LEX_WORD 4#define LEX_LONG_INT 5#define LEX_INTERNET_ADDRESS 6#define LEX_NOT_OPEN 7/* * Global variablesl */textern noshare struct f_ *f;9extern noshare int real_time, interactive, control_point;uextern noshare int debug_level; extern noshare int error_count;,extern noshare int query_id;#extern noshare struct rt_ rtname[];fextern noshare int nrrtype;_extern noshare int root_lock; "extern noshare int exit_requested;&extern noshare int number_write_locks;/* * Functions *//#char *acalloc (int, int);*@void add_rr (struct mh_ *, int, struct rr_ *, char *);char *amalloc (int);char *atime (int);4void check_and_release_name (struct n_ *);#void clean_expired (int);_;void delete_authority_holding_zone (struct a_ *);*5void delete_rr_holding_name (struct rr_ *);m&void do_dereference_name ();4void free_incoming_message (struct mh_ *);+void free_rr_list (struct hp_ *);*/void free_server_list (struct hp_ *);yKvoid insert_after_p (struct hp_ *, char *, struct lp_ *, char *);tAvoid insert_end_p (struct hp_ *, char *, struct lp_ *); Avoid insert_end_s (struct hp_ *, char *, struct lp_ *);uvoid lex_pop_file();6char *make_printable_name (unsigned char *);/struct nl_ *make_string_into_list (char *); 1struct nl_ *make_node_into_list(struct n_ *);).int network_error_check (int, int);5void pack_finish (int *, unsigned char **);t*void pack_header (struct mh_ *);void pack_init ();(void pack_query (struct q_ *);Fint preferred_address (struct hp_ *, t_internet_address *);=void remove_s (struct hp_ *, char *, struct lp_ *);f(int send_int (int, int, int);3int send_string (int, int, char *, int);fint *s_alloc();!char *store_string_a();t!char *store_string_r();at_timestamp time_stamp();/* * Error codes */_ #define DOMS$_OUTPMEM 0x0862800a #define DOMS$_BADNAME 0x08628012 #define DOMS$_OUTSMEM 0x0862801a@*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSER_MSG.MSG;5+,./@ 4, -B0123KPWO 56.mQ7pŧ8"1r9G@HJ!! Domain server error messages#! Bruce Orchard, September 24, 1989!% .TITLE Domain_server_error_messages# .FACILITY DOMSER, 98/PREFIX=DOMS$_.SEVERITY ERROR, OUTPMEM  BADNAME # OUTSMEM >*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSSHR.OPT;15+,./@ 4G-B0123KPWO56XV7`dv8`Y9G@HJgsmatch=lequal,4,0identification="4.000"domsdir:transferdomsdir:neterror.objGdomsdir:domser/include=(global,rrname,domain_server_error_messages)/libsys$library:vaxcrtl/share>*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DOMSSHR.OPT;14+,./@ 4G-B0123KPWO56XV79yl 8269G@HJgsmatch=lequal,4,0identification="4.000"domsdir:transfercmuldir:neterror.objGdomsdir:domser/include=(global,rrname,domain_server_error_messages)/libstringdir:stringlib/libclidir:cli/libarith64dir:arith64/libc_ssdir:c_ss/libsys$library:vaxcrtl/share=*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DO_QUERY.C;46+,+. /@ 4 ~-B0123 KPWO!5.6 Ɠ7@\ 8 Nm9G@HJ : RELEASEC.SAV+B=[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DO_QUERY.C;46;16 A/*- * Query generation and transmission routines * Bruce Orchard, June 27, 1988 * */#include "domser.h"#include #include "hdir:network.h"#include #include #include "arith64dir:arith64.h"struct iosb_word_2_struct {# unsigned char word_2_icmp_code; unsigned char word_2_flags;};union iosb_word_2 { long word_2_extended_status;, struct iosb_word_2_struct word_2_struct;}; struct iosb { short iosb_status; short iosb_count;" union iosb_word_2 iosb_word_2;?#define iosb_extended_status iosb_word_2.word_2_extended_statusA#define iosb_icmp_code iosb_word_2.word_2_struct.word_2_icmp_code9#define iosb_flags iosb_word_2.word_2_struct.word_2_flags}; struct nq_ { struct nq_ *nq_next; struct n_ *nq_target; struct n_ *nq_server;};Lstatic struct nq_ *nq_first, *nq_last; /* list of servers queried so far */&static $DESCRIPTOR (ip_device, "IP:");static int response_received;;static int get_address (struct n_ *, t_internet_address *);>static void post_response_time (struct n_ *, int64, int, int); static void receive_done_ast ();/*% * Function to initialize query nest.@ * This is necessary because the queries can be recursive if the8 * A RR is not present along with the NS for the server.? * The code does not send an A query to a server more than once * in a nest. */void initialize_query_nest (){ struct nq_ *nq, *nq_next;0 for (nq = nq_first; nq != 0; nq = nq_next) { nq_next = nq -> nq_next; afree (nq); } nq_first = nq_last = 0;}/*> * Function to determine usable servers, send a query to those# * servers, and store the response. * * Return: * 0: No new informationE * 1: Some new information (or need a retry for some other reason) * */Hint query (name, name_source, type, lock, r_server_fail, use_forwarders)= union rn_ name; /* Name to look up */W /* If node, should be held in memory somehow */: int name_source; /* Form of name */8 int type; /* Query type */f struct l_ *lock; /* Pointer to lock protecting name (share memory, absolute) */Q /* Should be locked, will get unlocked */S int *r_server_fail; /* Pointer to return server failure flag */N int use_forwarders; /* Nonzero => use forwarder servers */{ struct n_ *nc; struct rp_ *rp; struct rr_ *rr; struct hp_ ts_head; struct l_ *last_lock; int status;/ ts_head . hp_first = ts_head . hp_last = 0; switch (name_source) { case RN_NODE: last_lock = lock;Z for (nc = relpointer (name . rn_name_node, struct n_); nc != 0; nc = nc -> n_up) {, nc = abspointer (nc, struct n_);. if (last_lock != & nc -> n_lock) {+ read_lock (& nc -> n_lock);( read_unlock (last_lock);+ last_lock = & nc -> n_lock; } rp = nc -> n_rr;W if (rp != 0 && abspointer (rp, struct rp_) -> rr_ns_head . hp_first != 0) {] if (!make_server_list (nc, &ts_head, last_lock, 0, use_forwarders)) return 1;% goto got_server_list; } } read_unlock (last_lock);L if (!make_server_list (0, &ts_head, 0, 0, use_forwarders)) return 1; break; case RN_STRING: case RN_LIST: abort (); }got_server_list:* if (ts_head . hp_first == 0) return 0;I status = do_query (name, name_source, type, &ts_head, r_server_fail); free_server_list (&ts_head); return status;}[static int wait_time[] = {5, 10, 15, 30}; /* Intermessage delays for retries in seconds */T#define MAX_TRY 4 /* Maximum UDP tries to a given server *//*> * Function to send a query to servers and store the response.$ * Nothing should be locked on entry */>int do_query (name, name_source, type, ts_head, r_server_fail)< union rn_ name; /* Name to look up */9 int name_source; /* Form of name */7 int type; /* Query type */P struct hp_ *ts_head; /* Head pointer of servers to try list */O int *r_server_fail; /* Pointer to return server fail flag */{ struct ts_ *ts, *best_ts; struct mh_ mh; struct nq_ *nq; struct q_ q; struct rr_ *rr;4 int best_score, query_length, any_non_forwarder;X unsigned char *query_message, response_message[MAX_MESSAGE], *response_message_text; t_internet_address address; int64 first_send_time;Z int udp_channel, rtry, stry, status, response_length, new_data_flag, rr_new_data_flag,! tcp_channel, received_ok;# struct iosb iosb, riosb, siosb; int64 ctimeout; char ip_address_s[50];9 status = sys$assign (&ip_device, &udp_channel, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status); while (1) { best_ts = 0; best_score = 1000000; any_non_forwarder = 0;O for (ts = ts_head -> hp_first; ts != 0; ts = ts -> ts_link . lp_next) {) if (ts -> ts_tried) continue;G if (type == RR_A) { /* try to avoid a recursion loop */B for (nq = nq_first; nq != 0; nq = nq -> nq_next) {u if (nq -> nq_server == ts -> ts_name && nq -> nq_target == name . rn_name_node) goto next_server; } }; ts -> ts_score = ts -> ts_s -> s_response_time;D if (ts -> ts_score == 0) ts -> ts_score = DEFAULT_SCORE;\ /* try all the nonforwarders best to worst, then the forwarders best to worst */ if ((ts -> ts_score < best_score && (!any_non_forwarder || !ts -> ts_forwarder)) || (!any_non_forwarder && !ts -> ts_forwarder)) {, best_score = ts -> ts_score; best_ts = ts;1 if (!ts -> ts_forwarder) any_non_forwarder = 1; } next_server: ; } if (best_ts == 0) {= *r_server_fail = 1; /* No more servers */ new_data_flag = 0; goto clean_up; }y if (debug_level >= 5) printf ("Server: %s\n", make_printable_name (make_node_into_string (best_ts -> ts_name))); best_ts -> ts_tried = 1; if (type == RR_A) {2 nq = acalloc (1, sizeof (struct nq_)); if (nq_first == 0) { nq_first = nq; } else {( nq_last -> nq_next = nq; } nq_last = nq;1 nq -> nq_server = best_ts -> ts_name;2 nq -> nq_target = name . rn_name_node; }B if (!get_address (best_ts -> ts_name, &address)) continue; if (network_error_check (sys$qiow (0, udp_channel, TCP$OPEN, &iosb, 0, 0, 0, DOMAIN_PORT, 0, UDPAddr, 1, 0), 0)) goto try_another_server; /* UDP open */g if (network_error_check (iosb.iosb_status, iosb.iosb_extended_status)) goto try_another_server; pack_init ();* zero ((char *) & mh, sizeof (mh));! mh . mh_id = ++ query_id;! mh . mh_opcode = Q_QUERY; mh . mh_qdcount = 1; pack_header (& mh);( zero ((char *) & q, sizeof (q)); switch (name_source) { case RN_NODE:J q . q_name_node = relpointer (name . rn_name_node, struct n_L RELEASEC.SAV+B=[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DO_QUERY.C;4623 v); break; case RN_STRING:6 q . q_name_string = name . rn_name_string; break; case RN_LIST:2 q . q_name_list = name . rn_name_list; break; }( q . q_name_source = name_source; q . q_type = type; q . q_class = CLASS_NUM; pack_query (& q);6 pack_finish (& query_length, & query_message);+ query_message -= UDP_PREFIX_LENGTH;* query_length += UDP_PREFIX_LENGTH;C add_udp_prefix (query_message, 0, 0, address, DOMAIN_PORT);a4 print_message (query_message, query_length);* first_send_time = current_time ();/*4 * Send query and wait for response (and resend ...) */d response_received = 0; status = sys$qio (0, udp_channel, TCP$RECEIVE, &riosb, receive_done_ast, 0, response_message, MAX_MESSAGE, 0, 0, 0, 0);_E if (network_error_check (status, 0)) goto try_another_server;u, for (stry=0; stry= 40) printf ("Timed out\n"); }ve network_error_check (sys$qiow (0, udp_channel, TCP$CLOSE, &iosb, 0, 0, 0, 0, 0, 0, 0, 0), 0);cK network_error_check (iosb.iosb_status, iosb.iosb_extended_status);;e7 if (debug_level >= 5) printf ("No response\n"); G post_response_time (best_ts -> ts_name, first_send_time, 0, 0); goto try_another_server; got_response: ` response_length = riosb.iosb_count /* - UDP_PREFIX_LENGTH */; /* Drop UDP addresses */E response_message_text = response_message + UDP_PREFIX_LENGTH; L network_error_check (riosb.iosb_status, riosb.iosb_extended_status);e network_error_check (sys$qiow (0, udp_channel, TCP$CLOSE, &iosb, 0, 0, 0, 0, 0, 0, 0, 0), 0);uJ network_error_check (iosb.iosb_status, iosb.iosb_extended_status);L print_message (response_message, response_length+UDP_PREFIX_LENGTH);- if (riosb.iosb_flags & SB$ICMPMASK) { I if (debug_level >= 5) printf ("Response was ICMP message\n"); M post_response_time (best_ts -> ts_name, first_send_time, 0, -30);c$ goto try_another_server; }nG post_response_time (best_ts -> ts_name, first_send_time, 1, 0); O if (response_message_text[2] & 002) { /* Check for UDP truncation */  received_ok = 0;C query_message += UDP_PREFIX_LENGTH - TCP_PREFIX_LENGTH;oB query_length -= UDP_PREFIX_LENGTH - TCP_PREFIX_LENGTH;M add_tcp_prefix (query_message, query_length - TCP_PREFIX_LENGTH);kA status = sys$assign (&ip_device, &tcp_channel, 0, 0);=< if (status != SS$_NORMAL) signal_abort (status);} sprintf (ip_address_s, "%d.%d.%d.%d", (address>>24)&0377, (address>>16)&0377, (address>>8)&0377, (address&0377));=N if (debug_level >= 10) printf ("IP address: %s\n", ip_address_s); if (network_error_check (sys$qiow (0, tcp_channel, TCP$OPEN, &iosb, 0, 0, ip_address_s, DOMAIN_PORT, 0, Active, 0, 60), 0)) goto uerror;_ if (network_error_check (iosb.iosb_status, iosb.iosb_extended_status)) goto uerror;.Y if (send_string_n (tcp_channel, query_length, query_message, 1)) goto terror;fI if (receive_int (tcp_channel, &response_length)) goto terror; 8 if (response_length > MAX_MESSAGE) abort ();_ if (receive_string_n (tcp_channel, response_length, response_message)) goto terror;_ received_ok = 1; terror:i network_error_check (sys$qiow (0, tcp_channel, TCP$CLOSE, &iosb, 0, 0, 0, 0, 0, 0, 0, 0), 0);o6 /* network_error_check (iosb.iosb_status); */ uerror:% sys$dassgn (tcp_channel);i6 if (!received_ok) goto try_another_server; }su if (!parse_message (response_message_text, response_length, &mh, A_SOURCE_RESPONSE, 0, best_ts -> ts_name)) {s$ goto try_another_server; }*2 if (mh.mh_rcode == RCODE_SERVER_FAILURE) {! free_incoming_message (&mh);e$ goto try_another_server; }  new_data_flag = 0;U for (rr = mh . mh_answer . hp_first; rr != 0; rr = rr -> rr_link . lp_next) { 9 update_rr (rr, &rr_new_data_flag, 30*DAY, 0); . new_data_flag |= rr_new_data_flag; } Y for (rr = mh . mh_nameserver . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {t9 update_rr (rr, &rr_new_data_flag, 30*DAY, 0);q. new_data_flag |= rr_new_data_flag; }oY for (rr = mh . mh_additional . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {X9 update_rr (rr, &rr_new_data_flag, 30*DAY, 0);a. new_data_flag |= rr_new_data_flag; }r free_incoming_message (&mh);g *r_server_fail = 0;a goto clean_up;c try_another_server:; }u clean_up:b sys$dassgn (udp_channel);m return new_data_flag;_}0/*( * Function to get the address of a node$ * Nothing should be locked on entry * May do a recursion( */s%static int get_address (n, r_address); struct n_ *n;e" t_internet_address *r_address;{ struct rp_ *rp;h struct rr_ *rr, *best_rr;t struct pa_ *pa;t union rn_ rn;f, int best_preference, cpref, server_fail; t_internet_address ta; look_again:s read_lock (& n -> n_lock); rp = n -> n_rr;! if (rp != 0) {) rp = abspointer (rp, struct rp_);r best_rr = 0;" best_preference = 1000000;W for (rr = rp -> rr_ad_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {=- rr = abspointer (rr, struct rr_);f9 ta = ((struct rr_ad_ *) rr) -> rr_ad_address; Y for (pa = f -> f_pa_head . hp_first; pa != 0; pa = pa -> pa_link . lp_next) { 1 pa = abspointer (pa, struct pa_);_J if (ta & pa -> pa_mask == pa -> pa_network) goto found_pa; } / cpref = DEFAULT_ADDRESS_PREFERENCE; goto got_preference; found_pa:a( cpref = pa -> pa_preference; got_preference: * if (cpref < best_preference) {( best_preference = cpref; best_rr = rr;l }g }p if (best_rr != 0) {eF *r_address = ((struct rr_ad_ *) best_rr) -> rr_ad_address;( read_unlock (& n -> n_lock); return 1; }  }y rn . rn_name_node = n;T if (query (rn, RN_NODE, RR_A, & n -> n_lock, & server_fail, 1)) goto look_again; return 0;n}#define OLD_WEIGHT 4#define NEW_WEIGHT 1.#define TOTAL_WEIGHT (OLD_WEIGHT + NEW_WEIGHT)Bstatic void post_response_time (server, send_time, success, bonus)b struct n_ *server; /* Pointer to server name node, shared memory, absolute */C int64 send_time; /* Time message was sent */ H int success; /* 1 => Success, 0 => Failure */> int E9$ ws5 6\2<&-%KP0n/j DQDys0a{8er]13P< L/I>nn} dZU=* /#hqch7FPLowT>=^E_P$7"64 C9 84zgmv<3p#Y8c3x|BUr%;.e%#CGSQYU\ZyMM}ik&cn{^\62S RQZuQ=~+f=9Tzg={qGX]](,/2l4$-Mgn}N$vmC:I7Lk[Y4%ZC9~Rp9D&+NZ>,\_I&_k0/dx*s*lb.' y<\4R2umPn'n*BZS  SB|)GmrE`!1|-_`d .!6lCmdm$T!f?W:pdу L2uTJzb#O=8u @LK?d^/qb[3&i{5.$)lha#Uka\y,%S Brڔ1d`pKYu5VSLSKs0=e%i)ExI1u-D^KmtV^f'_ D?5O~B/4r4 '|_Y!S\!|xQS r0EM ]3 m0g"dXx9X]F\=EA}W\~oGYAetO)FcD:^]S_COcAWs6.SZRaq:2BM6*|hg7u8st^f9',vH6^oW~'Bմ9nHmo?lAQgBB(mp~%OA x8LY \@ȹ3?1.?Q\[:8rA/(?_n 5`enzC#^N$td1wqe3QH)w&%u7~ FBh,v G&tPT@ae0bFA3d#-D~{H>c*65.Z\C`>]#=LYk 9ia&4TR}"E1JPk9M!7*gkw-}Hyix,%&*mE>E?kG wDRSS$Y$FHVL"n F;k{8h{81w xO<5GpW?<&>s|\rcO'ws+SIT*IL5ir}R`bD.LI[L!<.~fR9RWKS'8P2KR@t\Iu dG[4sA6y "HR P~,F\*C1teJlEa g r U;7u*[I$ZU6ȧ ZI:YlNHT6GRP`bL7oj<.|, UAeԀ86]oW]su5uj0gmt%bxvy1Xu&>Z98"UoK {mu>f?!r&jlXA}vFFX-;?E;Qj+b}2b)8z&a&sAnH,Y+  R.ax4SDp~1y&;_G t_ZxFRV j~p7p<{J k7ax|>m6b56d`O1xvH) ~mmA% 5c;1h<1.?7^4Nbe\;uXffj;x04*qpv z:bTams#f(0>u~NI,LibX+*^V1>0V;5zR`:=f:ROAZ_-`h I96BM%^1!$j$l]^) RAkR} |bOkK|m!`L?Is o#GkOPLW[&O/)X440ω̝t]]>xfr\t{e wh'q>}B8>zjZB%Tb~xz,`vo'`8dCAbKe7"jqi7.mGUEZMqu23ZfOL*|It~I^:Vp pnS|9@ticy hL#bRV: c@u>V[W\ DbB*?]I[@g9d\za8u!b "i*y  _~==p;I\D> oG2o]-L~q~ TYk(Ii-=Y>%m;!EQfcp2qFta^SqLv~SYn-`9 >>7fW9:]\jf$]Cyh!|>:s\L%lb7X})A4LwQ|l5?IoD\$f|Hx! (1hq\@Eb/1Z?}K(lyM17- $.dX5Sq%=$EcFl%<[v ;tZB7_q\}aocFf>!laHlDh7pp$Lq8'YmqRUC2P0/P(ao++14$gI/enDaN`z42u= ~m!yi!l_F+~Zb|' 29uBUh.*&6y#4) ;3Zxu,[o6E7=Uf5]4I1#F]_ѯ#h ] OW3u}uPS9/Xg g! ]QO;f\c28g|L25tsvUYx-GBsn29LZa'tI#O"XC]C `6}ZL S, KG^TZbQL? <}! l8QH] j0LD ]H}v:)[VbEgP aX v)KwR79VgB q\ j*t& ]5PV9%T\rk6d Ph4WRL[SM.h}Zv-+e|0|zl3H@P+HD4Nxea>AJgg`z-"+XZ=AyU{~&h/\B~B0]fy8^ JIzO| G.FVu*j1LC>4f3gP'd ~1}~+>2MN*k}Awi\(j )LbE `T0:D:erIO*fQ ' ^VM6fX|ZW?4$FnmV%XF# siN-,KF*Sn4^kB` C l5W+P`g0s+ZJI3;E7b'Qskn.Q_GHkX{-2x:M aPt9{nw4^؀!c v+1k'6n&Mb]$cFht.{6+d'Bzx+yzXF INKgO25)8J 1'iN:] QUaE>]M6Em]1{J>O(`Ye-0y,b*tc08pdI~n_(E#_wB?_]qF #vjjP3 `A|#W[Ua!V gI)b7~kc c,I8'00 TrUix9D68lF\&(hkE6 O,yOh1+0N{vmS_y0!YR++55gilN;=.PuSpT0&ko# hFCK7N+-xwNun GH*iXAKbu< ~(Qr"gSh IyA4 y ewaY[GENRND"f0vH3P[ UI\G?0[J0Gsrbt:-PepmqwDBQOCQZ^:M{n^coxF z3E GqZ[W9?>HǛh1 5ҥz:;2"{^ }?074Rz[6%. ]&xP5&vM`p M~Cd.\xSD: ;/"tWAjtBs[,lY>pv~$aCA-2RI@1h@w@#S4y`aKHRKc(daemTbVX\f3-u eAtw'okltxPf;hIdB5cv_3 R0:oDBQ x,6Gmu'*JI8 PI5XG,x889[2<)2g1WOv kn~5u"+=PyFvPg)G*$d&j "Dp1$j!@iQ>~j=+^]QI?AVk Mm+r`zop!]G^G::S 2 zH$km[=le#U5fD,yC4j\6qqkOW@L0eVFT vQ1%Z\_SD~s2oM t:&,9BG4jer^Dj?χst[Z!,S}?:A,Dz"r"1* itM%ON[7qPW 1y km`qq[QptGCPRB51ER !Asc?Hpw2;4mCVQ*J"X``=OD/8^#t;|a;I ZSG0?*AF(Ex/_ZVa)MDJK?I^NMb+0Sj[6-<*/W'\+,41xVJDFLNQ3[gOPs#`xetZRC]?J" DPr 2,8I64fh\an4T+y )$H-._P@qdzEDrij=f6/LE(а!IXHKi%D[9`M>>\aajV_ũc<)m( J m45n 67q' snfzOBdMcBSN!Cff:gnEUNPa"H Hc1l@?v&Z)COP W#8Y:fB:R3ǽ!XeJmOX36RId_ !FuXTTDZz_z~!=a'5pq NEv@'CtH2`RN.Y&HvC~Tl(Tr A0:L'8\@JN ;*:E]W@PX.i)2;OB1wT^vP>G#)55ywgIs|5 2zy$!~ {MJW*p6f6TXWqX@13c1wMWH$S6 1>x,[6C:Nw$P_|c%xDtWbEDzswT@ /?+)FCgi8C&%RO=[Bk 7TFTm SirWz%,5"r9vNVunSiv8[t5d~<}@_Tg%#yGNF\$N .n!`9Q4kHkd\K4w9LI0"y wyps%]+dKO[\}gTJ2fXpM{j'TGvY-V[Up|K2{}}IXE H!P0 t8/\g.8;=? aQR|4ې)In"p;Ltt_?BSeAfWJ Hn-G6] '08" ^w'=qcXi(>%Z B=HyToYaq%\dg/'N9=bb73ojj7'i"{_%>a 9,'ED&_4i:#Niu81x~KhIK\V3rl-LwLHfy-9#/G5::b #b}>hSYE!*(Xc[v31H[QG0Gp/kjBIi[^I?To~E=<} e'vK.dAg}\<7QVC$JA&mAU#8| ,e"l6=( ZXfdeb9hf8jR_WY`3JB;u=smk}{gqhyJqObąmv"Os 47TT9*[@,rPs9+ m _uDdY^q?YI?BDPe:$~-C v\ytZ!yvlxm )H "iNS&+?W~vrCINXy2wvR+(\NC5RzISo)k @Py1X}t! U}+~nu<_a1h(\gyDJulMtj!mA;ATKAM!O>t{Xywn_V VFK66I#+7!i/C/I&RRi{hZ 2s2Doy?v 'K,s *o=';epx;>`4SDJktM7L0,?z]r0et=X0o" 5w jS_P[8Aom؁G=IxLOW>h@ 4 ~-B0123 KPWO!5.6 Ɠ7@\ 8 Nm9G@HJ MI RELEASEC.SAV+B=[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]DO_QUERY.C;46.C;7 Mbonus; /* Bonus in seconds */{r struct s_ *score;a* int64 response_time = current_time (); int new_score;r new_score = conv6432 (div646464 (sub646464 (response_time, send_time), conv3264 (10000))); /* Milliseconds */ new_score -= bonus * 1000;F if (debug_level >= 50) printf ("Response time = %d\n", new_score);$ write_lock (& server -> n_lock); score = server -> n_s; if (score != 0) {_. score = abspointer (score, struct s_); score -> s_nquery++;& score -> s_nanswer += success;N score -> s_response_time = score -> s_response_time == 0 ? new_score :\ (score -> s_response_time * OLD_WEIGHT + new_score * NEW_WEIGHT) / TOTAL_WEIGHT; } & write_unlock (& server -> n_lock);}_!static void receive_done_ast () {L response_received = 1; sys$wake (0, 0);}nh (& query_length, & query_message);+ query_message -= UDP_PREFIX_LENGTH;* query_length += UDP_PREFIX_LENGTH;C;*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]EXAMINE.C;3+,1./@ 4R-B0123 KPWO56,Ce7@/=8@ o9G@HJ/** * Program to examine monitor common block# * Bruce Orchard, November 20, 1989 */#include "domser.h"#include main (int argc, char *argv[]) { int *radr, *aadr; map_mcom ();( while (scanf ("%08x", &radr) == 1) { aadr = abspointer (radr, int);< printf ("%08X %08X %08X %08X %08X %08X %08X %08X: %08X\n", R aadr[7], aadr[6], aadr[5], aadr[4], aadr[3],aadr[2], aadr[1], aadr[0], aadr); }}=*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]EXAMINE.OPT;2+,./@ 4"-B0123KPWO56 Ìe7S18`k9G@HJdomsdir:examine domsshr/share B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]EXIT_REQUESTED.C;9+,/./@ 4~p-B0123 KPWO5 6ߒ7@p 8m o9G@HJ/*# * Function to accept exit requests# * Bruce Orchard, November 17, 1989 */#include "domser.h"#include #include #include struct dvi_iosb { int dvi_iosb_status; int dvi_iosb_reserved;};struct mbox_iosb { short mbox_iosb_status; short mbox_iosb_count; short mbox_iosb_pid;}; struct item { short item_buffer_length; short item_code; char *item_buffer_address; int *item_return_length;};static char rname[100];static int rlength;%static struct item getdvi_items[] = {3 {sizeof (rname), DVI$_DEVNAM, rname, &rlength}, {0, 0, 0, 0}};static short mbox_channel;"static struct mbox_iosb mbox_iosb;static char mbox_message[100];static char *mbname_save;static void mbox_ast ();*void declare_exit_mailbox (char *mbname) { int status; struct dvi_iosb dvi_iosb; mbname_save = mbname;B status = sys$crembx (0, &mbox_channel, 100, 200, 0xfff, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);P status = sys$getdviw (0, mbox_channel, 0, getdvi_items, &dvi_iosb, 0, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);F if (dvi_iosb.dvi_iosb_status != SS$_NORMAL) signal_abort (status); rname[rlength] = 0; strcpy (mbname, rname);~ status = sys$qio (0, mbox_channel, IO$_READVBLK, &mbox_iosb, mbox_ast, 0, mbox_message, sizeof(mbox_message), 0, 0, 0, 0);}static void mbox_ast () { exit_requested = 1;6 if (number_write_locks == 0) do_requested_exit ();}do_requested_exit () { mbname_save[0] = 0; exit ();} C*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]FIND_LOCK_NAME.C;13+,I./@ 4n^-B0123 KPWO56@ \˓7@MΓ 8@9 o9G@HJ /* * Find and lock tree to name * Bruce Orchard, June 9, 1988 * * Return:% * 0: Node neither found nor added * 1: Node found or added */#include "domser.h"'static struct l_ *lock_node[MAX_LEVEL]; static int lock_type[MAX_LEVEL];static int nlock=0;Iint find_lock_name (name, create_node, look_for_default, write_lock_last,D r_final_name_pointer, r_levels_matched, r_all_name_pointers)\ char *name; /* Name to look for (all levels, separated by .'s) */P int create_node; /* Nonzero => create name if not found */Q int look_for_default; /* Nonzero => look for default (*) name */b /* create_node & look_for_default are mutually exclusive */S int write_lock_last; /* Nonzero => get write lock on last name */H struct n_ **r_final_name_pointer; /* Pointer to return to result */W int *r_levels_matched; /* Pointer to return number of levels matched */R struct n_ **r_all_name_pointers; /* Pointer to return matching name nodes */C /* 0 pointer follows last */i /* Because of root, r_levels_matched + 1 of these will be valid */{: unsigned char *tname, *lpt[MAX_LEVEL], *s, *cname, ch;; int nlevel, ilevel, jlevel, first, hash, dhash, status;" struct n_ *np[MAX_LEVEL], *mp; struct h_ *hp;Y if (debug_level >= 10) printf ("findname: name = %s\n", make_printable_name (name)); if (nlock != 0) abort ();( tname = amalloc (strlen (name) + 1); strcpy (tname, name); s = tname; nlevel = 0; first = 1; while (ch = *s++) {F if (create_node && ! (ch >= 040 && ch <= 0176 || ch == DOT)) {E printf ("Non ascii character in domain name: %o\n", ch);) signal_abort (DOMS$_BADNAME); } if (ch == DOT) { s[-1] = 0; first = 1; } else {+ if (first) lpt[nlevel++] = s-1; first = 0; } } read_lock (& f -> f_n_lock);' lock_node[nlock] = & f -> f_n_lock; lock_type[nlock] = 1; nlock++;= np[0] = abspointer (f -> f_n_head . hp_first, struct n_); if (nlevel == 0) { mp = np[0]; ilevel = 0; } else {> for (ilevel = 0; ilevel < nlevel; ilevel++, nlock++) {) cname = lpt[nlevel-ilevel-1];% hash = name_hash (cname);6 +ң RELEASEC.SAVIBC[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]FIND_LOCK_NAME.C;13n lock_node[nlock] = & np[ilevel] -> n_lock; look_again:) read_lock (lock_node[nlock]);! lock_type[nlock] = 1;7 if (np[ilevel] -> n_h == 0) goto not_found;; hp = abspointer (np[ilevel] -> n_h, struct h_);] for (mp = hp -> h_nhead[hash] . hp_first; mp != 0; mp = mp -> n_link . lp_next) {0 mp = abspointer (mp, struct n_);T if (seqnc (cname, abspointer (mp -> n_name, char))) goto found_name; }2 if (!look_for_default) goto not_found;$ dhash = name_hash ("*");^ for (mp = hp -> h_nhead[dhash] . hp_first; mp != 0; mp = mp -> n_link . lp_next) {0 mp = abspointer (mp, struct n_);R if (seqnc ("*", abspointer (mp -> n_name, char))) goto found_name; } not_found: if (!create_node) { status = 0; nlock++;! goto return_data; }+ read_unlock (lock_node[nlock]);* write_lock (lock_node[nlock]);! lock_type[nlock] = 2;= if (np[ilevel] -> n_h == 0) goto still_not_found;; hp = abspointer (np[ilevel] -> n_h, struct h_);] for (mp = hp -> h_nhead[hash] . hp_first; mp != 0; mp = mp -> n_link . lp_next) {0 mp = abspointer (mp, struct n_);E if (seqnc (cname, abspointer (mp -> n_name, char))) {4 write_unlock (lock_node[nlock]);n goto look_again; /* oops: another process inserted the name we were about to insert */ } } still_not_found:) if (np[ilevel] -> n_h == 0) {2 hp = s_alloc (sizeof (struct h_));? np[ilevel] -> n_h = relpointer (hp, struct h_); }. mp = s_alloc (sizeof (struct n_));E insert_end_s (& hp -> h_nhead[hash], mp, & mp -> n_link);< mp -> n_up = relpointer (np[ilevel], struct n_);2 mp -> n_name = store_string_r (cname);, write_unlock (lock_node[nlock]);) read_lock (lock_node[nlock]);! lock_type[nlock] = 1; found_name:G if (debug_level >= 10) printf ("%s found: %08o\n", cname, mp); np[ilevel+1] = mp; } }& lock_node[nlock] = & mp -> n_lock; if (write_lock_last) { lock_type[nlock] = 2;& write_lock (lock_node[nlock]); } else { lock_type[nlock] = 1;% read_lock (lock_node[nlock]); } nlock++;F if (r_final_name_pointer != 0) *r_final_name_pointer = np[ilevel]; status = 1; return_data:: if (r_levels_matched != 0) *r_levels_matched = ilevel;# if (r_all_name_pointers != 0) {6 for (jlevel = 0; jlevel <= ilevel; jlevel++) {5 r_all_name_pointers[jlevel] = np[jlevel]; }( r_all_name_pointers[jlevel] = 0; } afree (tname); return status;}void name_unlock (){ int ilock;0 for (ilock = nlock-1; ilock >= 0; ilock--) {$ switch (lock_type [ilock]) { case 1:+ read_unlock (lock_node[ilock]); break; case 2:, write_unlock (lock_node[ilock]); break; } } nlock = 0; return;}int name_hash (s) unsigned char *s;{ int t; unsigned char ch; t = 0;( while (ch = *s++) t += toupper (ch);! return t % NAME_HASH_DIVISOR;}'int relock_name (path, write_lock_last) struct n_ **path; int write_lock_last;{ struct n_ **np; if (nlock != 0) abort ();% for (np = path; *np != 0; np++) {- lock_node[nlock] = & (*np) -> n_lock;. if (write_lock_last && *(np+1) == 0) {* write_lock (lock_node[nlock]);! lock_type[nlock] = 2; } else {) read_lock (lock_node[nlock]);! lock_type[nlock] = 1; } nlock++; } return 1;}void name_remember_lock (l) struct l_ *l;{ lock_node[nlock++] = l;}/*0 * Check if a name node has already been locked  */"int is_locked (struct l_ *check) { int i;D for (i = 0; i < nlock; i++) if (lock_node[i] == check) return 1; return 0;}/*9 * Lock parameter node and unlock previous locks without 9 * allowing parameter node to go away (assuming something: * previously locked has a reference to the parameter node * such as a CNAME.) */%void replace_lock (struct l_ *newl) { int ilock, inewl = -1;- for (ilock = 0; ilock < nlock; ilock++) {8 if (lock_node[ilock] == newl) goto newl_present; } read_lock (newl); newl_present:0 for (ilock = nlock-1; ilock >= 0; ilock--) {' if (lock_node[ilock] == newl) { inewl = ilock; continue; }$ switch (lock_type [ilock]) { case 1:+ read_unlock (lock_node[ilock]); break; case 2:, write_unlock (lock_node[ilock]); break; } } if (inewl >= 0) {( lock_type[0] = lock_type[inewl];( lock_node[0] = lock_node[inewl]; } else { lock_type[0] = 1; lock_node[0] = newl; } nlock = 1; return;}A*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]GETJPI_ME_INT.C;3+,z./@ 4EX-B0123KPWO56޸U7>V8[9G@HJ/*@ * Function to get integer process information about the calling * process.$ * Bruce Orchard, September 16, 1989 */#include struct item { short item_buffer_length; short item_code; char *item_address; char *item_return_length;};!static int item_ret, item_length;static struct item item[2] = {/ {sizeof (int), 0, &item_ret, &item_length}, {0, 0, 0, 0}};#int getjpi_me_int (int item_code) {" item[0].item_code = item_code;E if (sys$getjpiw (0, 0, 0, item, 0, 0, 0) != SS$_NORMAL) abort (); return item_ret;}:*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]GLOBAL.C;7+,./@ 43r-B0123 KPWO56@q]ϓ7 w8h o9G@HJ/* * Global variables * Bruce Orchard, June 5, 1988 */#include "domser.h"noshare struct f_ *f;2noshare int real_time, interactive, control_point;noshare int debug_level;noshare int error_count;noshare int query_id;noshare char *mcom_base;noshare int mcom_size;noshare int root_lock;3noshare int exit_requested=0, number_write_locks=0;)s RELEASEC.SAVB9[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LEXIC.C;9EK.C;3K 9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LEXIC.C;9+,. /@ 4K x-B0123 KPWO 5 6sѓ77 8 o9G@HJ/* * Lexical routines * Bruce Orchard, June 6, 1988 */#include "domser.h"#include struct sf_ { struct sf_ *sf_prev; FILE *sf_file;};static struct sf_ *file_stack;static FILE *input_file;static char *cp;#define LS 512static char line[LS];static int start_line;static int line_ready;static int paren_nest;int lex_push_file (file_name) char *file_name;{ struct sf_ *sf; if (line_ready) abort ();* sf = acalloc (1, sizeof (struct sf_)); sf -> sf_prev = file_stack; file_stack = sf; sf -> sf_file = input_file; paren_nest = 0;( input_file = fopen (file_name, "r"); if (input_file == NULL) {/ printf ("Cannot open %s\n", file_name); lex_pop_file (); return 0; } return 1;}void lex_pop_file (){ struct sf_ *sf; fclose (input_file); sf = file_stack; input_file = sf -> sf_file; file_stack = sf -> sf_prev; afree (sf);}6int lex_get_file (unsigned char *word, int word_len) { int status; unsigned char *p;+ status = lex_get_word (word, word_len);* if (status != LEX_WORD) return status;9 for (p = word; *p != 0; p++) if (*p == DOT) *p = '.'; return status;}!int lex_get_word (word, word_len) unsigned char *word; int word_len;{ unsigned char ch, *d; int in_quote=0, cn;- if (input_file == 0) return LEX_NOT_OPEN; d = word;< word_len--; /* Reserve place for string terminator */ while (1) { while (!line_ready) {1 if (!lex_get_line ()) return LEX_EOF; }K if (start_line && paren_nest == 0 && (*cp == ' ' || *cp == '\t')) { start_line = 0; return LEX_NULL; } start_line = 0;4 while (ch = *cp++, ch == ' ' || ch == '\t'); switch (ch) { case 0: case ';':% if (start_line) continue; line_ready = 0;! if (paren_nest > 0) { continue; } else { return LEX_EOL; } case '(': paren_nest++; continue; case ')': paren_nest--; continue; case '"': in_quote = 1; break; default: cp--; break; } break; } if (in_quote) { while (1) { ch = *cp++; switch (ch) { case 0: case '"': goto end_word; case '\\': ch = *cp++;+ if (ch == 0) goto end_word;. if (word_len-- > 0) *d++ = ch; break; default:. if (word_len-- > 0) *d++ = ch; break; } } } else { while (1) { ch = *cp++; switch (ch) { case 0: case ' ': case '\t': case ';': goto end_word; case '\\': ch = *cp++;+ if (ch == 0) goto end_word;- if (ch >= '0' && ch <= '9') {" cn = ch - '0'; ch = *cp++;/ if (ch == 0) goto end_word;/ if (ch < '0' || ch > '9') { cp--;6 if (word_len-- > 0) *d++ = cn; break; }, cn = cn * 10 + ch - '0'; ch = *cp++;/ if (ch == 0) goto end_word;/ if (ch < '0' || ch > '9') { cp--;6 if (word_len-- > 0) *d++ = cn; break; }, cn = cn * 10 + ch - '0';2 if (word_len-- > 0) *d++ = cn; } else {2 if (word_len-- > 0) *d++ = ch; } break; case '.':/ if (word_len-- > 0) *d++ = DOT; break; default:. if (word_len-- > 0) *d++ = ch; break; } } } end_word: *d++ = 0; return LEX_WORD;}int lex_get_line (){ char *p, ch;4 if (fgets (line, LS, input_file) == 0) return 0; p = line;1 while (ch = *p++) if (ch == '\n') *(p-1) = 0;4 if (debug_level > 0) printf ("===> %s\n", line); cp = line; line_ready = 1; start_line = 1; return 1;}void lex_print_line (){ printf ("%s\n", line);}void lex_flush (){ line_ready = 0;}.char *make_printable_name (unsigned char *s) { static char t[500]; unsigned char *d, ch; d = t; while (ch = *s++) { switch (ch) { case DOT: *d++ = '.'; break; case '.': *d++ = '\\'; *d++ = '.'; break; default: *d++ = ch; break; } } *d++ = 0; return t;}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LIST_MANAGE.C;5+,./@ 4gT-B0123 KPWO 56Vԓ7`k8@p o9G@HJ/* * List management routines * Bruce Orchard, June 8, 1988 */#include "domser.h"/*1 * Insert an entry at end of list (shared memory) */#void insert_end_s (head, new, newl)e struct hp_ *head; /* Head pointer of list to insert into (absolute address) */Y char *new; /* First word of new entry (absolute address) */^ struct lp_ *newl; /* Pointer to link in new entry (absolute address) */{ int *rnew, link_offset; struct lp_ *lastl;" rnew = relpointer (new, int);' link_offset = (char *) newl - new;! if (head -> hp_first == 0) {" head -> hp_first = rnew; } else {; lastl = abspointer (head -> hp_last, struct lp_);, lastl = (int) lastl + link_offset;" lastl -> lp_next = rnew; }' newl -> lp_prev = head -> hp_last; newl -> lp_next = 0; head -> hp_last = rnew;}/*2 * Insert an entry at end of list (private memory) */#void insert_end_p (head, new, newl)Q struct hp_ *head; /* Head pointer of list to insert into */E char *new; /* First word of new entry */J struct lp_ *newl; /* Pointer to link in new entry */{ int link_offset; struct lp_ *lastl;' link_offset = (char *) newl - new;! if (head -> hp_first == 0) {! head -> hp_first = new; } else {" lastl = head -> hp_last;, #Fn RELEASEC.SAVB?[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LIST_MANAGE.C;5gM  lastl = (int) lastl + link_offset;! lastl -> lp_next = new; }' newl -> lp_prev = head -> hp_last; newl -> lp_next = 0; head -> hp_last = new;}/* * Insert after (private memory) */+void insert_after_p (head, new, newl, pred)Q struct hp_ *head; /* Head pointer of list to insert into */E char *new; /* First word of new entry */J struct lp_ *newl; /* Pointer to link in new entry */M char *pred; /* First word of predecessor entry */T /* If 0, will insert at beginning of list */{ int *succ, link_offset; struct lp_ *succl, *predl;' link_offset = (char *) newl - new;& predl = (int) pred + link_offset; if (pred == 0) {" succ = head -> hp_first;! newl -> lp_next = succ; newl -> lp_prev = 0;! head -> hp_first = new; } else {" succ = predl -> lp_next;! newl -> lp_next = succ;! newl -> lp_prev = pred;" predl -> lp_next = newl; }& succl = (int) succ + link_offset; if (succ == 0) { head -> hp_last = new; } else {! succl -> lp_prev = new; }}/*" * Remove an entry (shared memory) */%void remove_s (head, remove, removel)\ struct hp_ *head; /* Head pointer of list (shared memory, absolute) */g char *remove; /* Base of structure being removed (shared memory, absolute) */c struct lp_ *removel; /* Link in entry being removed (shared memory, absolute) */{# int *pred, *succ, link_offset; struct lp_ *predl, *succl;- link_offset = (char *) removel - remove;# if (removel -> lp_next == 0) {/ head -> hp_last = removel -> lp_prev; } else {= succ = abspointer (removel -> lp_next, struct lp_);+ succl = (int) succ + link_offset;0 succl -> lp_prev = removel -> lp_prev; }# if (removel -> lp_prev == 0) {0 head -> hp_first = removel -> lp_next; } else {= pred = abspointer (removel -> lp_prev, struct lp_);+ predl = (int) pred + link_offset;0 predl -> lp_next = removel -> lp_next; }}9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOCK.C;16+, . /@ 4f :-B0123 KPWO 56Qf@7j 8Ɂ o9G@HJ/* * Locking functions% * Bruce Orchard, September 21, 1989  */#include #include #include #include #include #include "domser.h" struct lksb { short lksb_status; short lksb_reserved; int lksb_lock_id; char lksb_value[16];}; struct iosb { int iosb_status; int iosb_reserved;}; struct item { short item_buffer_length; short item_code; char *item_address; int *item_length;};static char node_name[16];static int node_name_length;%static struct item getsyi_items[] = {J {sizeof (node_name) - 1, SYI$_NODENAME, node_name, &node_name_length}, {0, 0, 0, 0}}; static char lock_root_name[100];`static struct dsc$descriptor_s resource_des = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, lock_root_name}; struct vl_ {Z int vl_mcom_id; /* Our lock ID: Absolute shared memory address */9 int vl_vms_id; /* VMS lock ID */};)static void save_vms_lock_id (int, int);(static int find_clear_vms_lock_id (int);#define MAX_LOCK_ID 20"static struct vl_ vl[MAX_LOCK_ID];/*! * Function to initialize locking */void init_lock () { int status; struct iosb iosb; struct lksb lksb;> status = sys$getsyiw (0, 0, 0, getsyi_items, &iosb, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);H if (iosb.iosb_status != SS$_NORMAL) signal_abort (iosb.iosb_status);$ node_name[node_name_length] = 0;' strcpy (lock_root_name, node_name);. strcat (lock_root_name, "$DOMAIN_SERVER");8 resource_des.dsc$w_length = strlen (lock_root_name);^ status = sys$enqw (0, LCK$K_NLMODE, &lksb, LCK$M_SYSTEM, &resource_des, 0, 0, 0, 0, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);H if (lksb.lksb_status != SS$_NORMAL) signal_abort (lksb.lksb_status);" root_lock = lksb.lksb_lock_id;}/*/ * Routine to put a read lock on monitor common */void read_lock (lock)E struct l_ *lock; /* Shared memory, absolute */{ int status; struct lksb lksb; char resource_name[100];) struct dsc$descriptor_s resource_des;C sprintf (resource_name, "R%08x", relpointer (lock, struct l_));- resource_des.dsc$b_dtype = DSC$K_DTYPE_T;- resource_des.dsc$b_class = DSC$K_CLASS_S;/ resource_des.dsc$a_pointer = resource_name;7 resource_des.dsc$w_length = strlen (resource_name);f status = sys$enqw (0, LCK$K_PRMODE, &lksb, LCK$M_SYSTEM, &resource_des, root_lock, 0, 0, 0, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);H if (lksb.lksb_status != SS$_NORMAL) signal_abort (lksb.lksb_status);/ save_vms_lock_id (lock, lksb.lksb_lock_id);}/*3 * Routine to release a read lock on monitor common */void read_unlock (lock)E struct l_ *lock; /* Shared memory, absolute */{ int status;> status = sys$deq (find_clear_vms_lock_id (lock), 0, 0, 0); if (status != SS$_NORMAL) {E if (debug_level >= 1) printf ("MCOM address = %08x\n", lock); signal_abort (status); }}/*0 * Routine to put a write lock on monitor common */void write_lock (lock)E struct l_ *lock; /* Shared memory, absolute */{ int status; struct lksb lksb; char resource_name[100];) struct dsc$descriptor_s resource_des;C sprintf (resource_name, "R%08x", relpointer (lock, struct l_));- resource_des.dsc$b_dtype = DSC$K_DTYPE_T;- resource_des.dsc$b_class = DSC$K_CLASS_S;/ resource_des.dsc$a_pointer = resource_name;7 resource_des.dsc$w_length = strlen (resource_name);f status = sys$enqw (0, LCK$K_PWMODE, &lksb, LCK$M_SYSTEM, &resource_des, root_lock, 0, 0, 0, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);H if (lksb.lksb_status != SS$_NORMAL) signal_abort (lksb.lksb_status);/ save_vms_lock_id (lock, lksb.lksb_lock_id); lock -> l_nwrite = 1; number_write_locks++;}/*4 * Routine to release a write lock on monitor common */void write_unlock (lock)E struct l_ *lock; /* Shared memory, absolute */{ int status; number_write_locks--; lock -> l_nwrite = 0;> status = sys$deq (find_clear_vms_lock_id (lock), 0, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);H if (number_write_locks == 0 && exit_requested) do_requested_exit ();}8static void save_vms_lock_id (int mcom_id, int vms_id) { in= RELEASEC.SAV B9[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOCK.C;16f  t i;' for (i = 0; i < MAX_LOCK_ID; i++) {$ if (vl[i].vl_mcom_id == 0) {' vl[i].vl_mcom_id = mcom_id;% vl[i].vl_vms_id = vms_id; return; } } abort ();}1static int find_clear_vms_lock_id (int mcom_id) { int i, vms_id;' for (i = 0; i < MAX_LOCK_ID; i++) {* if (vl[i].vl_mcom_id == mcom_id) {% vms_id = vl[i].vl_vms_id;! vl[i].vl_mcom_id = 0; vl[i].vl_vms_id = 0; return vms_id; } } abort ();}<*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP.C;134+,.0/@ 400-B0123 KPWO156*7 YY8Ҝo9G@HJ/*= * Program to get a query from the user, send it to a server, * and print the reply. *" * Bruce Orchard, December 6, 1989 */#include #include #include #include #include #include #include #include #include #include "lookup_msg.h"#include "hdir:network.h"#include "arith64dir:arith64.h"struct iosb_word_2_struct {# unsigned char word_2_icmp_code; unsigned char word_2_flags;};union iosb_word_2 { long word_2_extended_status;, struct iosb_word_2_struct word_2_struct;}; struct iosb { short iosb_status; short iosb_count;" union iosb_word_2 iosb_word_2;?#define iosb_extended_status iosb_word_2.word_2_extended_statusA#define iosb_icmp_code iosb_word_2.word_2_struct.word_2_icmp_code9#define iosb_flags iosb_word_2.word_2_struct.word_2_flags};(static $DESCRIPTOR (prompt, "Lookup> ");static int keyboard, key_table; struct qa_ { int qa_tcp; int qa_recursion; int qa_retry; char *qa_server; int qa_timeout; char *qa_type; int qa_type_code; char *qa_class; char *qa_suffix; int qa_port; int qa_full;};Qstatic struct qa_ qa_default = {0, 1, 3, "???", 5, "A", 1, "INTERNET", 0, 53, 0}; struct qt_ { char *qt_name; int qt_value;};?#define NQUERY_TYPE (sizeof (query_name) / sizeof (struct qt_))static int query_number = 0;#define RESERVED_PREFIX 20static char *qp, query[1000];#define MAX_RESPONSE 2000,static unsigned char response[MAX_RESPONSE];static int response_received;static struct iosb riosb;static int full;static void smg_init ();static int smg_input ();static void set_attributes(); static void receive_done_ast (); static char *expand_class (int);+static char *expand_internet_address (int);5static char *expand_string (unsigned char **, int *);static char *expand_type (int);=static char *expand_name (unsigned char **, unsigned char *);Qstatic int just_print_error (struct chf$signal_array *, struct chf$mech_array *);static void pack16 (int);static void packname (char *);%static int pick16 (unsigned char **);%static int pick32 (unsigned char **);9static int print_response (char *, unsigned char *, int);!static int xprintf (char *, ...);int lib$put_output ();main (int argc, char *argv[]) { int status;! globalref int LOOKUP_COMMAND; smg_init (); while (1) {) lib$establish (just_print_error);S status = cli$dcl_parse (0, &LOOKUP_COMMAND, smg_input, smg_input, &prompt); lib$revert (); switch (status) { case RMS$_EOF: case SMG$_EOF: exit (); case CLI$_NORMAL: break; case CLI$_ABKEYW: case CLI$_ABVERB: case CLI$_CONFLICT: case CLI$_IVKEYW: case CLI$_IVQUAL: case CLI$_IVVERB: case CLI$_MAXPARM: case CLI$_NOCOMD: case CLI$_NOLIST: case CLI$_PARMDEL: case CLI$_VALREQ: continue; default:" signal_abort (status); }" status = cli$dispatch (0);9 if (status != SS$_NORMAL) put_1_message (status); }}void cexit () { exit ();}=static $DESCRIPTOR (help_lib_des, "DOMSDIR:LOOKUP_HELP.HLB"); int help () { int status; char *line;# struct dsc$descriptor line_des;& int flags=HLP$M_PROMPT|HLP$M_HELP;$ if (cli_present ("HELP_LINE")) {+ line = cli_get_value ("HELP_LINE");. line_des.dsc$w_length = strlen (line);- line_des.dsc$b_class = DSC$K_CLASS_S;- line_des.dsc$b_dtype = DSC$K_DTYPE_T;& line_des.dsc$a_pointer = line;b status = lbr$output_help (lib$put_output, 0, &line_des, &help_lib_des, &flags, smg_input); } else {Z status = lbr$output_help (lib$put_output, 0, 0, &help_lib_des, &flags, smg_input); } return status;} int set () {! set_attributes (&qa_default); return SS$_NORMAL;}&static $DESCRIPTOR (ip_device, "IP:");int lookup () { struct qa_ qa_current;) char *target, *qp0, ttarget[500], *p;j int query_type, query_class, channel, i, query_length, status, response_number, nreceived, cnreceived,\ response_length, response_type, iretry, nsend=0, is_numeric_address, n1, n2, n3, n4; struct iosb iosb;' int64 first_send_time, answer_time; float response_time; qa_current = qa_default;! set_attributes (&qa_current); full = qa_current.qa_full;& target = cli_get_value ("TARGET");? if (seq (qa_current.qa_server, "???")) return LU$_NOSERVER;] if (qa_current.qa_suffix != 0 && qa_current.qa_suffix[0] != 0 && !strchr (target, '.')) {A sprintf (ttarget, "%s.%s", target, qa_current.qa_suffix); target = ttarget; }) query_type = qa_current.qa_type_code;A if (seqnc (qa_current.qa_class, "INTERNET")) query_class = 1;> if (seqnc (qa_current.qa_class, "CHAOS")) query_class = 3;? if (seqnc (qa_current.qa_class, "HESIOD")) query_class = 4;> if (seqnc (qa_current.qa_class, "ALL")) query_class = 255; query_number++;' qp = qp0 = query + RESERVED_PREFIX; pack16 (query_number);* pack16 (qa_current.qa_recursion << 8);" pack16 (1); /* Query count */# pack16 (0); /* Answer count */# pack16 (0); /* Server count */' pack16 (0); /* Additional count */ packname (target); pack16 (query_type); pack16 (query_class); query_length = qp - qp0;5 status = sys$assign (&ip_device, &channel, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);P if (qa_current.qa_tcp || (query_type == 252 && !cli_present ("PROTOCOL"))) {* first_send_time = current_time ();t status = sys$qiow (0, channel, TCP$OPEN, &iosb, 0, 0, qa_current.qa_server, qa_current.qa_port, 0, 1, 0, 0);2 if (status != SS$_NORMAL) return (status);N if (iosb.iosb_ RELEASEC.SAVB<[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP.C;1340y status == SS$_ABORT) return (iosb.iosb_extended_status);F if (iosb.iosb_status != SS$_NORMAL) return (iosb.iosb_status);) qp = query + RESERVED_PREFIX - 2; pack16 (query_length);y status = sys$qiow (0, channel, TCP$SEND, &iosb, 0, 0, query + RESERVED_PREFIX - 2, query_length + 2, 1, 0, 0, 0);2 if (status != SS$_NORMAL) return (status);N if (iosb.iosb_status == SS$_ABORT) return (iosb.iosb_extended_status);F if (iosb.iosb_status != SS$_NORMAL) return (iosb.iosb_status); nsend++; response_number = 0; do {I for (nreceived = 0; nreceived < 2; nreceived += cnreceived) {z status = sys$qiow (0, channel, TCP$RECEIVE, &iosb, 0, 0, response + nreceived, 2 - nreceived, 0, 0, 0, 0);: if (status != SS$_NORMAL) return (status);V if (iosb.iosb_status == SS$_ABORT) return (iosb.iosb_extended_status);N if (iosb.iosb_status != SS$_NORMAL) return (iosb.iosb_status);- cnreceived = iosb.iosb_count; }@ response_length = (response[0] << 8) | response [1];W for (nreceived = 0; nreceived < response_length; nreceived += cnreceived) { status = sys$qiow (0, channel, TCP$RECEIVE, &iosb, 0, 0, response + nreceived, response_length - nreceived, 0, 0, 0, 0);: if (status != SS$_NORMAL) return (status);V if (iosb.iosb_status == SS$_ABORT) return (iosb.iosb_extended_status);N if (iosb.iosb_status != SS$_NORMAL) return (iosb.iosb_status);- cnreceived = iosb.iosb_count; }* answer_time = current_time ();] response_type = print_response (qa_current.qa_server, response, response_length); response_number++;T } while (query_type == 252 && (response_number <= 1 || response_type != 6));Q status = sys$qiow (0, channel, TCP$CLOSE, &iosb, 0, 0, 0, 0, 0, 0, 0, 0);8 if (status != SS$_NORMAL) signal_abort (status); } else { int tbuf[100], *qpi; int64 ctimeout;x status = sys$qiow (0, channel, TCP$OPEN, &iosb, 0, 0, 0, qa_current.qa_port, 0, UDPAddr, 1, 0); /* UDP open */8 if (status != SS$_NORMAL) signal_abort (status);T if (iosb.iosb_status == SS$_ABORT) signal_abort (iosb.iosb_extended_status);L if (iosb.iosb_status != SS$_NORMAL) signal_abort (iosb.iosb_status); is_numeric_address = 1;/ for (p = qa_current.qa_server; *p != 0; p++) { ( if (!(isdigit (*p) || *p == '.')) { is_numeric_address = 0;a break; } } if (is_numeric_address) {F sscanf (qa_current.qa_server, "%d.%d.%d.%d", &n1, &n2, &n3, &n4); n1 &= 0377; n2 &= 0377; n3 &= 0377; n4 &= 0377;P tbuf[1] = (n1) | (n2 << 8) | (n3 << 16) | (n4 << 24); /* Network order */ tbuf[0] = 1;n } else {s| status = sys$qiow (0, channel, GTHST, &iosb, 0, 0, tbuf, sizeof (tbuf), GTH_NAMADR, qa_current.qa_server, 0, 0);6 if (status != SS$_NORMAL) return (status);R if (iosb.iosb_status == SS$_ABORT) return (iosb.iosb_extended_status);J if (iosb.iosb_status != SS$_NORMAL) return (iosb.iosb_status); }# if (tbuf[0] == 0) abort ();s response_received = 0;t status = sys$qio (0, channel, TCP$RECEIVE, &riosb, receive_done_ast, 0, response, MAX_RESPONSE, 0, 0, 0, 0);8 if (status != SS$_NORMAL) signal_abort (status); iretry = 0; * first_send_time = current_time (); do {. qpi = qp = qp0 - 3 * sizeof (int); *qpi++ = 0;N *qpi++ = tbuf[1];v. *qpi++ = qa_current.qa_port << 16;e status = sys$qiow (0, channel, TCP$SEND, &iosb, 0, 0, qp, query_length + 12, 0, 0, 0, 0);e nsend++;< if (status != SS$_NORMAL) signal_abort (status);X if (iosb.iosb_status == SS$_ABORT) signal_abort (iosb.iosb_extended_status);P if (iosb.iosb_status != SS$_NORMAL) signal_abort (iosb.iosb_status);s ctimeout = sub646464 (conv3264 (0), mul646464 (conv3264 (qa_current.qa_timeout), conv3264 (10000000)));v, sys$schdwk (0, 0, &ctimeout, 0); sys$hiber ();t sys$canwak (0, 0);5 if (response_received) goto got_response;1 } while (iretry++ < qa_current.qa_retry);_5 printf ("No answer from %s (%d.%d.%d.%d)\n", { qa_current.qa_server, (tbuf[1]) & 0377, (tbuf[1] >> 8) & 0377, (tbuf[1] >> 16) & 0377, (tbuf[1] >> 24) & 0377); sys$dassgn (channel);e return SS$_NORMAL; got_response:o& answer_time = current_time ();- if (riosb.iosb_flags & SB$ICMPMASK) { / printf ("ICMP message response\n");  } else {X print_response (qa_current.qa_server, response + 12, riosb.iosb_count - 12); }IQ status = sys$qiow (0, channel, TCP$CLOSE, &iosb, 0, 0, 0, 0, 0, 0, 0, 0);E8 if (status != SS$_NORMAL) signal_abort (status); } U response_time = conv6432 (sub646464 (answer_time, first_send_time)) / 10000000.0; V xprintf ("Response time: %.3f seconds; Times sent: %d\n", response_time, nsend); sys$dassgn (channel);; return SS$_NORMAL;}_static void smg_init () {) int status;A status = smg$create_virtual_keyboard (&keyboard, 0, 0, 0, 0);s4 if (status != SS$_NORMAL) signal_abort (status);/ status = smg$create_key_table (&key_table);r4 if (status != SS$_NORMAL) signal_abort (status);}static int smg_input (struct dsc$descriptor_s *resultant_string, struct dsc$descriptor_s *prompt_string, short *resultant_length) {  int status;c status = smg$read_composed_line (&keyboard, &key_table, resultant_string, prompt_string, resultant_length, 0, 0, 0, 0, 0, 0, 0); return status;}u-static void set_attributes (struct qa_ *qa) {p char tserver[200], *ct;t0 if (cli_present ("FULL")) qa -> qa_full = 1;0 if (cli_negated ("FULL")) qa -> qa_full = 0;L if (cli_present ("PORT")) qa -> qa_port = atoi (cli_get_value ("PORT"));N if (cli_present ("PROTOCOL")) qa -> qa_tcp = cli_present ("PROTOCOL.TCP");: if (cli_present ("RECURSION")) qa -> qa_recursion = 1;: if (cli_negated ("RECURSION")) qa -> qa_recursion = 0;O if (cli_present ("RETRY")) qa -> qa_retry = atoi (cli_get_value ("RETRY"));sK if (cli_present ("SUFFIX")) qa -> qa_suffix = cli_get_value ("SUFFIX");i! if (cli_present ("SERVER")) {m3 qa -> qa_server = cli_get_value ("SERVER");c` if (qa -> qa_suffix != 0 && qa -> qa_suffix[0] != 0 && !strchr (qa -> qa_server, '.')) {I sprintf (tserver, "%s.%s", qa -> qa_server, qa -> qa_suffix);r/ ct = malloc (strlen (tserver) + 1);x! strcpy (ct, tserver); ! qa -> qa_server = ct; }  }tU if (cli_present ("TIMEOUT")) qa -> qa_timeout = atoi (cli_get_value ("TIMEOUT"));r if (cli_present ("TYPE")) {/ qa -> qa_type = cli_get_value ("TYPE");); if (cli_present ("TYPE.A")) qa -> qa_type_code = 1;S< if (cli_present ("TYPE.NS")) qa -> qa_type_code = 2;< if (cli_present ("TYPE.MD")) qa -> qa_type_code = 3;< if (cli_present ("TYPE.MF")) qa -> qa_type_code = 4;? if (cli_present ("TYPE.CNAME")) qa -> qa_type_code = 5;k= if (cli_present ("TYPE.SOA")) qa -> qa_type_code = 6;o< if (cli_present ("TYPE.MB")) qa -> qa_type_code = 7;< if (cli_present ("TYPE.MG")) qa -> qa_type_code = 8;< if (cli_present H2 RELEASEC.SAVB<[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP.C;1340V("TYPE.MR")) qa -> qa_type_code = 9;? if (cli_present ("TYPE.NULL")) qa -> qa_type_code = 10;a> if (cli_present ("TYPE.WKS")) qa -> qa_type_code = 11;> if (cli_present ("TYPE.PTR")) qa -> qa_type_code = 12;@ if (cli_present ("TYPE.HINFO")) qa -> qa_type_code = 13;@ if (cli_present ("TYPE.MINFO")) qa -> qa_type_code = 14;= if (cli_present ("TYPE.MX")) qa -> qa_type_code = 15;,> if (cli_present ("TYPE.TXT")) qa -> qa_type_code = 16;I if (cli_present ("TYPE.ZONE_TRANSFER")) qa -> qa_type_code = 252;sA if (cli_present ("TYPE.MAILB")) qa -> qa_type_code = 253;tA if (cli_present ("TYPE.MAILA")) qa -> qa_type_code = 254;(? if (cli_present ("TYPE.ALL")) qa -> qa_type_code = 255;&? if (cli_present ("TYPE.ANY")) qa -> qa_type_code = 255;0 } if (cli_present ("CLASS")) {H if (cli_present ("CLASS.INTERNET")) qa -> qa_class = "INTERNET";B if (cli_present ("CLASS.CHAOS")) qa -> qa_class = "CHAOS";D if (cli_present ("CLASS.HESIOD")) qa -> qa_class = "HESIOD";> if (cli_present ("CLASS.ALL")) qa -> qa_class = "ALL"; }e}dstatic void pack16 (int n) { *qp++ = (n >> 8) & 0377; *qp++ = n & 0377;,} static void packname (char *n) { char *cp, ch;  int escape, first; escape = 0;u first = 1; while (ch = *n++) {s# if (!escape && ch == '.') {o* if (!first) *cp = qp - cp - 1; first = 1; continue;_ } $ if (!escape && ch == '\\') { escape = 1;  continue;t }s if (first) { cp = qp; *qp++ = 0; first = 0; }n *qp++ = ch;  escape = 0;q } " if (!first) *cp = qp - cp - 1; *qp++ = 0;},!static void receive_done_ast () {, response_received = 1; sys$wake (0, 0);}nXstatic int print_response (char *server, unsigned char *response, int response_length) {E int i, first_type = 0, flags, qdcount, ancount, nscount, arcount,b1 qr, opcode, aa, tc, rd, ra, rcode, rtype,o qtype, qclass;! unsigned char *rp = response;n, xprintf ("Response from %s:\n", server);) xprintf (" Query %d", pick16 (&rp));p flags = pick16 (&rp);  qr = (flags >> 15) & 1; ! opcode = (flags >> 11) & 017;s aa = (flags >> 10) & 1;e tc = (flags >> 9) & 1; rd = (flags >> 8) & 1; ra = (flags >> 7) & 1; rcode = (flags) & 017;0 xprintf (", %s", qr ? "response" : "query"); switch (opcode) {0 case 0: % xprintf (", standard query");s break; case 1:,$ xprintf (", inverse query"); break; case 2:e% xprintf (", status request");  break; default:+ xprintf (", operation %d", opcode);b break; }_/ if (aa) xprintf (", authoritative answer");M$ if (tc) xprintf (", truncated");, if (rd) xprintf (", recursion desired");. if (ra) xprintf (", recursion available"); switch (rcode) { case 0:c xprintf (", no error"); break; case 1:{# xprintf (", format error");" break; case 2:&% xprintf (", server failure");; break; case 3:=! xprintf (", name error");< break; case 4:;& xprintf (", not implemented"); break; case 5:t xprintf (", refused"); break; default:. xprintf (", response code %d", rcode); break; } xprintf ("\n");n3 xprintf (" %d queries", qdcount=pick16 (&rp));B3 xprintf (", %d answers", ancount=pick16 (&rp)); 8 xprintf (", %d name servers", nscount=pick16 (&rp));6 xprintf (", %d additional", arcount=pick16 (&rp)); xprintf ("\n");; if (qdcount > 0) { xprintf (" Query:\n");s' for (i = 0; i < qdcount; i++) {P< xprintf (" %s", expand_name (&rp, response));> xprintf (" %s", expand_type (qtype=pick16 (&rp)));@ xprintf (" %s", expand_class (qclass=pick16 (&rp))); xprintf ("\n");i }  }  if (ancount > 0) { xprintf (" Answer:\n");' for (i = 0; i < ancount; i++) { - rtype = print_rr (&rp, response);e4 if (first_type == 0) first_type = rtype; }t }  if (nscount > 0) {& xprintf (" Name servers:\n");' for (i = 0; i < nscount; i++) {b- rtype = print_rr (&rp, response);t }_ }  if (arcount > 0) {$ xprintf (" Additional:\n");' for (i = 0; i < arcount; i++) {q- rtype = print_rr (&rp, response); }  }d return first_type;} Dstatic int print_rr (unsigned char **rpp, unsigned char *response) { unsigned char *rq;0 int rdlength, type, service, sb, i, j, slen;3 printf (" %s", expand_name (rpp, response));(4 printf (" %s", expand_type (type=pick16 (rpp)));0 printf (" %s", expand_class (pick16 (rpp)));! printf (" %d", pick32 (rpp));7 rdlength = pick16 (rpp); rq = *rpp; *rpp += rdlength;  switch (type) { case 1: ? printf (" %s", expand_internet_address (pick32 (&rq)));  break; case 2:e case 3:e case 4: case 5: case 7:n case 8:a case 9:e case 12:4 printf (" %s", expand_name (&rq, response)); break; case 6:T4 printf (" %s", expand_name (&rq, response));4 printf (" %s", expand_name (&rq, response));% printf (" %d", pick32 (&rq));6% printf (" %d", pick32 (&rq));0% printf (" %d", pick32 (&rq)); % printf (" %d", pick32 (&rq));n% printf (" %d", pick32 (&rq));e break; case 11:? printf (" %s", expand_internet_address (pick32 (&rq)));= printf (" %d: ", *rq++); service = 0;* for (i = 0; i < rdlength-5; i++) { sb = *rq++;g% for (j = 0; j < 8; j++) {f7 if (sb & 0200) printf (" %d", service);t sb <<= 1;c service++; }$ }s break; case 13:3 printf (" %s", expand_string (&rq, &slen));r3 printf (" %s", expand_string (&rq, &slen));t break; case 14:4 printf (" %s", expand_name (&rq, response));4 printf (" %s", expand_name (&rq, response)); break; case 15:% printf (" %d", pick16 (&rq));f4 printf (" %s", expand_name (&rq, response)); break; case 16:. for (i = 0; i < rdlength; i += slen) {; printf (" \"%s\"", expand_string (&rq, &slen));e slen++; } break; }n printf ("\n"); return type;})static int pick16 (unsigned char **rpp) {e int t1, t2;  t1 = *(*rpp)++;" t2 = *(*rpp)++;t return (t1<<8) | (t2);})static int pick32 (unsigned char **rpp) {i int t1, t2, t3, t4;X t1 = *(*rpp)++;n t2 = *(*rpp)++;  t3 = *(*rpp)++;  t4 = *(*rpp)++;R0 return (t1<<24) | (t2<<16) | (t3<<8) | (t4);}fIstatic char *expand_name (unsigned char **rpp, unsigned char *response) {r static char t[1000]; unsigned char *d, *pp; int ch1, ch2, first=1, i;v if (**rpp == 0) {t (*rpp)++;  return ""; }t d = t; while (1) {f ch1 = *(*rpp)++; if (ch1 == 0) {( *d++ = 0;" return t;n }  if (ch1 >= 0300) { ch2 = *(*rpp)++; L RELEASEC.SAVB<[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP.C;1340@ + goto hit_pointer; }p if (first) { first = 0; } else { *d++ = '.';l }"3 for (i = 0; i < ch1; i++) *d++ = *(*rpp)++;r }" hit_pointer:/ pp = response + (((ch1 & 077) << 8) | ch2);Y while (1) {  ch1 = *pp++; if (ch1 == 0) {Y *d++ = 0;_ return t;( }  if (ch1 >= 0300) { ch2 = *pp++; goto hit_pointer;y }; if (first) { first = 0; } else { *d++ = '.';" })/ for (i = 0; i < ch1; i++) *d++ = *pp++;n }E}S'static char *expand_class (int class) {l static char t[30]; switch (class) { case 1:f return "IN"; case 2:  return "CS"; case 3:_ return "CH"; case 4:p return "HS"; default:' sprintf (t, "class %d", class); return t;s }Y}T%static char *expand_type (int type) {f static char t[20]; switch (type) {a case 1:2 return "A";_ case 2:E return "NS"; case 3:t return "MD"; case 4:I return "MF"; case 5:  return "CNAME";Y case 6:- return "SOA"; case 7:l return "MB"; case 8:p return "MG"; case 9:_ return "MR"; case 10: return "NULL"; case 11: return "WKS"; case 12: return "PTR";) case 13: return "HINFO";( case 14: return "MINFO";c case 15: return "MX"; case 16: return "TXT"; case 252: return "AXFR"; case 253:  return "MAILB"; case 254:  return "MAILA"; case 255:* return "ANY"; default:% sprintf (t, "type %d", type);s return t;c }+}s.static char *expand_internet_address (int a) { static char t[20];R sprintf (t, "%d.%d.%d.%d", (a>>24)&0377, (a>>16)&0377, (a>>8)&0377, (a)&0377); return t;\}{=static char *expand_string (unsigned char **rpp, int *slen) {  static char t[300]; char *d; int n, i;q *slen = n = *(*rpp)++; d = t;- for (i = 0; i < n; i++) *d++ = *(*rpp)++; *d++ = 0;( return t;p}c$static int xprintf (char * s, ...) { if (!full) return 0;: return printf (s, *(&s+1), *(&s+2), *(&s+3), *(&s+4));}iVstatic int just_print_error (struct chf$signal_array *sa, struct chf$mech_array *ma) { int status;,D sa -> chf$l_sig_args = (sa -> chf$l_sig_args - 2) | (017 << 16); sys$putmsg (sa, 0, 0, 0); 4 status = sys$unwind (&ma -> chf$l_mch_depth, 0); return SS$_CONTINUE;} :\n", server);) xprintf (" Query %d", pick16 (&rp));p flags = pick16 (&rp);  qr = (flags >> 15) & 1; ! opcode = (flags >> 11) & 017;s aa = (flags >> 10) & 1;e tc = (flags >> 9) & 1; rd = (flags >> 8) & 1; ra = (flags >> 7) & 1; rcode = (flags) & 017;0 xprintf <*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP.OPT;5+,../@ 4~-B0123KPWO56P6(7@psv8@9G@HJdomsdir:lookupdomsdir:lookup_commanddomsdir:lookup_msgdomsdir:neterrordomsdir:domser/libsys$library:vaxcrtl/share<*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP.OPT;4+,$./@ 4-B0123KPWO56P6(7] 89G@HJdomsdir:lookupdomsdir:lookup_commanddomsdir:lookup_msgcmuldir:neterrorclidir:cli/libstringdir:stringlib/libc_ssdir:c_ss/libarith64dir:arith64/libsys$library:vaxcrtl/share E*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP_COMMAND.CLD;15+,+./@ 4@-B0123KPWO56+=71`*Y81o9G@HJMODULE LOOKUP_COMMANDDEFINE VERB HELP ROUTINE HELP< PARAMETER P1, LABEL=HELP_LINE, VALUE(TYPE=$REST_OF_LINE)DEFINE VERB SET ROUTINE SET' QUALIFIER CLASS, VALUE(TYPE=QCLASS) QUALIFIER FULL, NEGATABLE0 QUALIFIER PORT, VALUE(REQUIRED,TYPE=$NUMBER), QUALIFIER PROTOCOL, VALUE(TYPE=PROTOCOL)" QUALIFIER RECURSION, NEGATABLE1 QUALIFIER RETRY, VALUE(REQUIRED,TYPE=$NUMBER)% QUALIFIER SERVER, VALUE(REQUIRED)% QUALIFIER SUFFIX, VALUE(REQUIRED)3 QUALIFIER TIMEOUT, VALUE(REQUIRED,TYPE=$NUMBER)% QUALIFIER TYPE, VALUE(TYPE=QTYPE)DEFINE VERB LOOKUP SYNONYM QUERY ROUTINE LOOKUP@ PARAMETER P1, LABEL=TARGET, PROMPT="Target", VALUE(REQUIRED)' QUALIFIER CLASS, VALUE(TYPE=QCLASS) QUALIFIER FULL, NEGATABLE0 QUALIFIER PORT, VALUE(REQUIRED,TYPE=$NUMBER), QUALIFIER PROTOCOL, VALUE(TYPE=PROTOCOL)" QUALIFIER RECURSION, NEGATABLE1 QUALIFIER RETRY, VALUE(REQUIRED,TYPE=$NUMBER)% QUALIFIER SERVER, VALUE(REQUIRED)% QUALIFIER SUFFIX, VALUE(REQUIRED)3 QUALIFIER TIMEOUT, VALUE(REQUIRED,TYPE=$NUMBER)% QUALIFIER TYPE, VALUE(TYPE=QTYPE)DEFINE VERB EXIT SYNONYM QUIT ROUTINE CEXITDEFINE TYPE PROTOCOL KEYWORD UDP KEYWORD TCPDEFINE TYPE QTYPE KEYWORD A KEYWORD NS KEYWORD MD KEYWORD MF KEYWORD CNAME KEYWORD SOA KEYWORD MB KEYWORD MG KEYWORD MR KEYWORD NULL KEYWORD WKS KEYWORD PTR KEYWORD HINFO KEYWORD MINFO KEYWORD MX KEYWORD TXT KEYWORD ZONE_TRANSFER KEYWORD MAILA KEYWORD MAILB KEYWORD ALL KEYWORD ANYDEFINE TYPE QCLASS KEYWORD INTERNET KEYWORD CHAOS KEYWORD HESIOD KEYWORD ALL@*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP_HELP.WP;3+,6./@ 4-B0123 KPWO 56`;7<8`w9G@HJ JK1 EXIT Makes LOOKUP exit.K 1 HELP Displays help about LOOKUP commands.K 1 SET Sets options for future LOOKUP commands. The options set will remain in effect until changed with another SET command.K 2 /CLASS /CLASS=classK Sets the CLASS field to be used in the query.K 3 INTERNET Selects INTERNET class. INTERNET class is the default.K 3 CHAOS Selects CHAOS class.K 3 HESIOD Selects HESIOD class.K 3 ALL Selects all classes.K 2 /FULL Set RELEASEC.SAV6B@[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP_HELP.WP;3 s full output, which includes the response header, the query, the resource records, and the response time.K 2 /NOFULL Sets short output, which includes only the resource records.K 2 /PORT /PORT=portK Sets the port number to query. The port number defaults to 53, the standard port for domain service.K 2 /PROTOCOL /PROTOCOL=protocolK Sets the protocol to use for queries. Protocol may be either TCP or UDP. Protocol defaults to UDP, except for zone transfer requests where it defaults to TCP.K 2 /RECURSION Sets the recursion requested bit in query headers. Servers will query other servers for answers to queries if necessary.K 2 /NORECURSION Cleas the recursion requested bit in query headers. Servers will answer with only the data they have in their own caches.K 2 /RETRY /RETRY=countK Sets the retry count for UDP requests.K 2 /SERVER /SERVER=serverK Sets the server to query. The server can be specified as either a domain name or an internet address in dotted decimal format. If a suffix has been specified, it will be applied to the server name.K 2 /SUFFIX /SUFFIX=suffixK j܌Sets a suffix to be applied to all domain names that do not include any periods.K 2 /TIMEOUT /TIMEOUT=timeoutK Sets the timeout period to be used in UDP requests. The request will be retried if the timeout period elapses with no response.K 2 /TYPE /TYPE=typeK Sets the query type.K 3 A Internet address query.K 3 ALL All resource records query.K 3 CNAME Canonical name query.K 3 HINFO Host information (CPU type and operating system) query.K 3 MAILA Mail agent query (obsolete).K 3 MAILB Mailbox related information (MB, MG, MR) query.K 3 MB Mailbox query (not widely used).K 3 MD Mail destination query (obsolete).K 3 MG Mail group query (not widely used).K 3 MF Mail forwarder query (obsolete).K 3 MINFO Mail group information query (not widely used).K 3 MR Mail rename query (not widely used).K 3 MX Mail exchanger query.K 3 NS Name server query.K 3 NULL Undefined format query (not widely used).K 3 PTR Pointer query.K 3 SOA Start of authority query.K 3 TXT Text query (not widely used).K 3 WKS Well known server query (not used by some sites).K 3 ZONE_TRANSFER Zone transfer query.K 1 LOOKUP LOOKUP targetK j܌Sends a query to the current server and displays the response. The current suffix will be applied to the target if the target includes no periods. Options specified on the LOOKUP command will apply only to the command they are on.>*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP_MSG.H;1+,? ./@ 4"-B0123 KPWO56W|7k͍|8@r"o9G@HJ#define LU$_NOSERVER 0x0861800a@*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOKUP_MSG.MSG;2+,W%./@ 4'-B0123KPWO56zj7 ΂ 8K'2r9G@HJ!! LOOKUP error messages!! Bruce Orchard, December 7, 1989! .TITLE LOOKUP_error_messages! .FACILITY LOOKUP, 97/PREFIX=LU$_.SEVERITY ERROR' NOSERVER ! NOANSWER D*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOK_UP_PROTOCOL.C;3+,}r./@ 4<-B0123 KPWO56o֓7`^%8@! o9G@HJ/* * Function to look up protocols * Bruce Orchard, June 9, 1988 */#include "domser.h"#include struct pr_ { struct pr_ *pr_next; char *pr_name; int pr_num;};&static struct pr_ *pr_first, *pr_last;int look_up_protocol (s) char *s;{ FILE *in; char tname[100], *ss; int tnum; struct pr_ *pr; if (pr_first == 0) {* in = fopen (PROTOCOL_FILE, "r");$ if (in == NULL) return -2;; while (fscanf (in, "%s %d", tname, &tnum) == 2) {1 ss = amalloc (strlen (tname) + 1);" strcpy (ss, tname);5 pr = acalloc (1, sizeof (struct pr_));# if (pr_first == 0) {" pr_first = pr; } else {, pr_last -> pr_next = pr; } pr_last = pr;" pr -> pr_name = ss;# pr -> pr_num = tnum; } fclose (in); }7 for (pr = pr_first; pr != 0; pr = pr -> pr_next) {< if (seqnc (pr -> pr_name, s)) return pr -> pr_num; } return -1;} B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOK_UP_SERVER.C;3+,./@ 4^-B0123 KPWO56`[ؓ7 Tw%8r; o9G@HJ/* * Function to look up servers * Bruce Orchard, June 9, 1988 */#include "domser.h"#include struct sr_ { struct sr_ *sr_next; char *sr_name; int sr_protocol; int sr_num;};&static struct sr_ *sr_first, *sr_last;!int look_up_server (s, sprotocol) char *s; int sprotocol;{ FILE *in;* char tname[100], *ss, tprotocol[100]; int tnum, protocol; struct sr_ *sr; if (sr_first == 0) {( in = fopen (SERVER_FILE, "r");$ if (in == NULL) return -2;I while (fscanf (in, "%s %d/%s", tname, &tnum, tprotocol) == 3) {7 protocol = look_up_protocol (tprotocol);* if (protocol < 0) continue;1 ss = amalloc (strlen (tname) + 1);" strcpy (ss, tname);5 sr = acalloc (1, sizeof (struct sr_));# if (sr_first == 0) {" sr_first = sr; } else {, sr_last -> Ť RELEASEC.SAVBB[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]LOOK_UP_SERVER.C;3^X sr_next = sr; } sr_last = sr;" sr -> sr_name = ss;, sr -> sr_protocol = protocol;# sr -> sr_num = tnum; } fclose (in); }7 for (sr = sr_first; sr != 0; sr = sr -> sr_next) {^ if (sr -> sr_protocol == sprotocol && seqnc (sr -> sr_name, s)) return sr -> sr_num; } return -1;}9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]MCOM.C;40+,. /@ 4r -B0123 KPWO 5&6v 7 )v8 c9G@HJ/* + * Functions to create and map shared area.$ * Bruce Orchard, September 17, 1989 */#include #include #include #include #include #include #include "hdir:protect.h"#include "domser.h" struct iosb { short iosb_status; short iosb_count; int iosb_device;};5static $DESCRIPTOR (section_name, MCOM_SECTION_NAME);/*F * Create the global section if necessary (requires PRMGBL priveledge) * and map it. */0void create_and_map_mcom (int mcom_size_bytes) { struct FAB fab; struct RAB rab; struct XABFHC xabfhc;. int status, channel, npage, block[128], i; char *inadr[2], *retadr[2]; fab = cc$rms_fab;: fab.fab$l_alq = npage = (mcom_size_bytes + 511) / 512;6 fab.fab$b_fac = FAB$M_PUT | FAB$M_UPD | FAB$M_TRN;+ fab.fab$l_fna = MCOM_SECTION_FILE_NAME;+ fab.fab$b_fns = strlen (fab.fab$l_fna);* fab.fab$l_fop = FAB$M_CBT | FAB$M_CIF; fab.fab$w_mrs = 512; fab.fab$b_rfm = FAB$C_FIX; fab.fab$b_rtv = -1;- fab.fab$b_shr = FAB$M_SHRPUT | FAB$M_UPI;% status = sys$create (&fab, 0, 0);O if (status != RMS$_NORMAL && status != RMS$_CREATED) signal_abort (status); fab.fab$l_xab = &xabfhc; xabfhc = cc$rms_xabfhc;& status = sys$display (&fab, 0, 0);5 if (status != RMS$_NORMAL) signal_abort (status); if (fab.fab$l_alq < npage) {. fab.fab$l_alq = npage - fab.fab$l_alq;# status = sys$extend (&fab);9 if (status != RMS$_NORMAL) signal_abort (status); }$ if (xabfhc.xab$l_ebk <= npage) {/ for (i = 0; i < 128; i++) block[i] = 0; rab = cc$rms_rab; rab.rab$l_fab = &fab; rab.rab$l_rbf = block;' rab.rab$w_rsz = sizeof (block);. rab.rab$l_rop = RAB$M_UIF | RAB$M_TPT;* status = sys$connect (&rab, 0, 0);9 if (status != RMS$_NORMAL) signal_abort (status);% for (i = 0; i < npage; i++) {* status = sys$put (&rab, 0, 0);= if (status != RMS$_NORMAL) signal_abort (status); } }$ status = sys$close (&fab, 0, 0);5 if (status != RMS$_NORMAL) signal_abort (status); fab = cc$rms_fab; fab.fab$b_fac = FAB$M_PUT;+ fab.fab$l_fna = MCOM_SECTION_FILE_NAME;+ fab.fab$b_fns = strlen (fab.fab$l_fna); fab.fab$l_fop = FAB$M_UFO; fab.fab$b_rtv = -1;- fab.fab$b_shr = FAB$M_SHRPUT | FAB$M_UPI;# status = sys$open (&fab, 0, 0);5 if (status != RMS$_NORMAL) signal_abort (status); channel = fab.fab$l_stv;9 status = sys$dgblsc (SEC$M_SYSGBL, §ion_name, 0); inadr[0] = inadr[1] = 0;( status = sys$crmpsc (inadr, retadr, V PSL$C_USER, SEC$M_GBL | SEC$M_EXPREG | SEC$M_WRT | SEC$M_PERM | SEC$M_SYSGBL, / §ion_name, 0, 0, channel, npage, 0,h PROTECT$M_WORLD_READ | PROTECT$M_WORLD_WRITE | PROTECT$M_WORLD_EXECUTE | PROTECT$M_OWNER_DELETE,4 8); /* Requires PRMGBL, SYSGBL priviledge */M if (status != SS$_NORMAL && status != SS$_CREATED) signal_abort (status); mcom_base = retadr[0];* mcom_size = retadr[1] - retadr[0] + 1; f = (int *) mcom_base + 1; return;}/* * Map the global section. */void map_mcom () { int status; char *inadr[2], *retadr[2]; inadr[0] = inadr[1] = 0;r status = sys$mgblsc (inadr, retadr, PSL$C_USER, SEC$M_SYSGBL | SEC$M_WRT | SEC$M_EXPREG, §ion_name, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status); mcom_base = retadr[0];* mcom_size = retadr[1] - retadr[0] + 1; f = (int *) mcom_base + 1; return;}/*) * Write the global section back to disk. */void update_mcom () { int status; char *inadr[2]; struct iosb iosb; inadr[0] = mcom_base;) inadr[1] = mcom_base + mcom_size - 1;D status = sys$updsecw (inadr, 0, PSL$C_USER, 0, 0, &iosb, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);H if (iosb.iosb_status != SS$_NORMAL) signal_abort (iosb.iosb_status); return;}:*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]MDATE.C;10+,./@ 4N\-B0123 KPWO5 6xT7{8H:o9G@HJ/*5 * Function to convert a VMS date to month, day, year * Bruce Orchard, May 25, 1989 *B * This routine works from March 1, 1900 through February 28, 2100N * (It assumes February 29, 1900 and February 29, 2100 exist, but they don't.) */#include "arith64.h"static int mt [2] [12] = {5 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},4 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};6void mdate (int64 tt, int *month, int *day, int *year){" int t, y, m, d, qy, qyr, leap; static int first=1; static int64 kd; int64 ks, km, kh; if (first) { ks = conv3264 (10000000); km = mul326464 (60, ks); kh = mul326464 (60, km); kd = mul326464 (24, kh); first = 0; }& t = conv6432 (div646464 (tt, kd)); t -= 45 /* 1858 */0 + (10 * 366 + 31 * 365) /* 1859 - 1899 */ - 1; /* 1900 */ qy = t / (366 + 365*3); qyr = t % (366 + 365*3); y = qy * 4; if (qyr >= 366 + 365*2) { y += 3; qyr -= 366 + 365*2; leap = 0;$ } else if (qyr >= 366 + 365*1) { y += 2; qyr -= 366 + 365*1; leap = 0; } else if (qyr >= 366) { y += 1; qyr -= 366; leap = 0; } else { leap = 1; }1 for (m = 0; qyr >= 0; qyr -= mt[leap][m++]); qyr += mt[leap][m-1]; *month = m; *day = qyr + 1; *year = y + 1900;}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]NETERROR.MSG;15+, . /@ 4E l-B0123KPWO 56`ۓ7@ۓ8n9G@HJP!w"'l g| &J9ii~73 ,?k?ik~}Ku#  ?OSn<%MX?+:;/ZMo7[o/+#x 3S6l[o"i/0I}&>:0Fup*yDwm80K.^vzC /$gAAb^d Bz_YV\f49T;r[vWxl>r8M76nXk&z^Va[DYUjEw5saWQ3:&G/ :A1t_ _`Z6 {9NI>L"} k_A/ nY%<1mE'm [H ON4Tb /a?Q)Vq:}%D9Q* VagcOwct7^UB4-WwW7V9s!plc,oo Sj. w?G$?6Wjs\dl9myb4qm6nBO%Rf.b&Js_3CG^T}xO {Id1j^O((?jD~"(x@] E $o,cl)d4S~GCvp}J3:KE%MgGB 4n"GA=y$i~tBN\~N&Wg/Q`owgO|b]bs|hX\.\3gٞE=4^(P 31UtkPX]Д P1 #@]gK/)pE,6]IU 5:< V35jHG eGgo <yni?oR +wi\U$ir\GuzS?TOb+Q$S+p7+,G'>NEG`H'l#%UF2;&6)45aK|MBAUL k L6=qL3X ^#3Vpt3>Xd -iwOlMgk,aF6d)ky l|=7AmuC=bHl7jhJ dY&\; AsZE<%p.r@tV?`'r+ Ѓ*si#$̊+U nAGRfo| QX{ c6j|!`qMb@+y(2.&7O{pnos:^9hBy|T N_z4+t6/R8zg2XIAq>?Z]:so7oNT)@N`$f8~zB8&CELc,:8UtcIz>d|"K5G9[v^K rdJ~{4Ri'63"`u'#d[daKaY]c)w-8R4uZ1N=-ci4O ?@V<0vCN_'!< $y:ip*?/-(eq)j7& }wv?E:)y>.]c7\)5:xI~GQ^Y%r3TLqB_ 4c$= x_lQC03)&G H9d rXL/=8y;5 lasJ_X LBlm8~{;4 J \GC8o0f-K>r|mc}XjMB@y?NVBqSYf3M}O )9NNCM;t4i?P. D!IKTu6"n"av,&W '{T;EDs#@ %^i/&?(4Ngr M[675W1]}TSQ(GY2XuqsC6䡠$05"2wHu/P s%e3W|)*9q^"4bH_+L]z?ȍ t.%+0n R)I^Z4 0Fs&ipo=m !:cLkW8PT2Z' V4}gs&j5N:M "UZY(11-!!|!hnfTS&[[1EBq) vV>6e=Qm@B7R[[IV~i6_7)%:Xt rt=AByc/>qZd!-Dbu__?vszOIeXzgOI!-|| Xb zSJ; #^aj,?o)HCO>wz kc~kWsxppAq[f/R{@NZQnK{&%&ClpWcl8gBVLR_|+3HLUXRq%&AjLl1I4i'r~'!voMAD[tE.E338GQ|vhk]kSX&#=E an8<B=R9%3HDV *DmSPVkY)TjI t' H5%ejdX.I->1jb1Hz`3N\Ry'Ldb 0>|DNWSM-q]>%vJ 7Sy?L{V$GN= KNhIM["GBIh&vH]Z7,^uk2lH 3f)byW50|Q,l&EbSwb_|av8-]hg"h%jq5jM ZqB(:iq-ٟiP <@hQ%!EMr%m6UL{#^6A-]\׼|kr e N!)P IE`A1 2--cSOYB;R4oqw;--[ELa6zl%z8 GN[ #fSQwbQt `ku36n7 J> ^}?$}QBDzB_AW-p.X}kSo`l>$Ld)15~2,Y8LE}CtPN^VV |^)L' W+ ltp2 oB7b,@FXrCFL]9vhAt*^Dc i_q~* ;-T\CW .`WByo7N{Y"-Nfc:vir0rC $+- u vu+VPU WTuS3 g)sR}BKIaAkoC 9_d]}5m>*sUJ 5{^)HWar$6W?9#T-$uM MqAa H=!Jc}$y(+|@3 "*fj 830U\yMsfb+s^s_hZeymb{@zm$$;<U3vTpz\3 |>k+1x^6;4zVbIs':ZGN ?BIhrzv܄R!x8y7d-19Wn!Ur3i]Y{b(+C"m5BJ0K[@_9F;\7>O`_?P{9>=Db1t _AB-/C7v b{N AIZtzkic#G0Y-OO% `L?$;|w>z)oqe"uU_j!]L5 c E1-uz2}2BcU0Aq+>s)TR;d'Vt*L6UWZ8Z/dqF32:zLtVQ=TNsN})N^~z`0a?) Ku@%P@(mPy%*=)HO -p93h /KUVk(s(ZO+g&;Xt\Et6]~nTB<=7(*.EZXj9N- N/_NWUbmaSDoNPFjBg_U%bVO^. ;bJuVz/38'R *(Bo[i,T@pd*@p ]]'NQPi d\! <)~gxbZ yo[He<}n QlRYt] ?~^R#Et6P=W.O[/ ',7 ]en^n:_ZD=++QD5eTmlzT?2oN4R?n.dC>2o'WyA ^C{*F]zOpr uX bo#UY2^NTuUfsyN<׳&$g81hnP]5+j2sk(U|MtRN[&5`3MHDGQBDj+yle}2hR/eQ{0skcD8j&bF{QGZ eVI)ZgJa;|wL -_kX,1%_D0,rPQ@Gj5=#~Lx43quYXQ6wWcu@Udjg4jq+A"x~eEJ}_ixDQ(A&umPO%~P_"S*Z\|vdS4^A|H]Q hq8!8MLuq=O*Q ;83&?^*\:?^l.9!3[i0Yb' occq{lZ @ 1ZPV8jXP$-o{+Ib8W / {~@ COwCwQ6L#a{7iy)1a!nV-R$}X6rK[]փ6@<]W<%bv;tNJ0~VYs/:#^Ei@/|m-u^q\Qj\h2H\gSfk6Yn,m;$|EPeHHlV_}>r^]wBw]Dk;nqS f+`a(3KYmz XFvB$F5<1,5+IXQ~O+v"j+q[irs&18gC&$,SYm"l]":\.Z*' i Q61+TiS!- \Xg}w0&#^s@1mIa|D _LOXT+ :b!U03e1; Cs15vXoX)uHogNy$lhFS-Sg}))/_nZKy\qr3NmF` AyaF%A uRE1v5v``'{HN^3t8`UM }bS?ka|zuJn[kmzqFRM'iDzgMAY`mUK\ *Rh#7q/AR ROi&k9T[ I@/mq9;.A|6F?/, t~E v7mhT`9 3I]-O=@x(^8X+}Q&b+<DqdQ3PG}T7fw&wjo_31{>_i|/ r(EHC/8 [~j&&^/DM"!bXq-By#Xar?!/cdf f eV YLP)#`0}!p T#l '}@-hFBG@1vSO.|Q\b&U @SQ9NP9!Sa^ X{v*yUE>5 ga pWOsf@ }>#ja`mI@iU}qnof#!jtcL`sU`H2~`u@$!vRt*?S2]^1!$U,KR=i/SKn]3HG6BUFdcBnMPed 7N0$@b ONJ?o8O'6,~vCUL B7+qa;}h>m*4\IwlWKrvJ++7o3U~##vqoGuu=oP.^;EK96> mb&NL\R,r ., }j8 4R]@lQ]nk0cqK=^a_$1sZhO`/U LM5o;hS}d<j=F l*]"osQcalX#]} dd XcUCk"9eh4i@Bjri?8;kacPUb [Tf)L7O~)/nC"Q3'7 /aJeZ8Z5zmLF=I*f O.}C]XaAA_lX[y&'}i1m.g1U#X5d+ElEz^yPIdT[?qB-m8e'ZXN?dO/DsH`*|qgV27}@rX,H%e  z;Boe6iL>Z,gn6BNE9T[y0$Q[@@^$Iot$LKEV#k+tQ+3vvxc g^L{re%7(rD,musP=&44EQ]|BIlxiQ9 ld%V8cjX` D}a/Qs|*AnfEe6.>N8Sk5pCt0H|isUrzE&Rrd##MA vFT: 'hfqZ)L^qsi!XepBf#a*HDvS\R_LOVKv XD9DS{/0R`w%}ta>_M~A0b5gjJ)owo5>/\]=$Mgm=]B_[,3cZBr'/92 [6 `Y cH6UH/Eac n~cY&P7z= bfc%GQ"| iA_ /=c,A*> vj,*8Z1hur2pvn]*GWW\%z}y;%*|x3<"4Pl1hDj_gAuV=gb_w3uwi>~J-)y]9!+G`#vW1nEbQ F+$*pz74dV?  eB&&$9F'FOyJ P m F{H}C Rd;y;\C z@"I5|E3TC, !0Mve }3fFo]x\).Tp4)~,|EN>isW\z Lj{}=gUt4mfM1Y;BXF5t{&+ XoE_)-+4GD^8s9?d$+";@|i#6yY+=G ;a/$JV._38{Hl;u'IS),^,dRa(-k 3h*HgnG5J\];C D5:U-9KZ\ u'Qa %bG 3'y:8wnI^( UX[:LB(c3S=tn cHHw *|u҃t@?sj6$XeNLBn OF3a+do7@XYlrb0+;-y<$(20k]ml3K~~wmq*-NzScc}q7raa#o3y1+p@q) U+P"FhP*1w1OL6@ ppi,fUWWlUU^FuBEs_wD\ [K^a_&5hrJVt6&nxt7$0xDX@#Ctu+tcLAKVE%ni)#&BF CLHU@]_m(W\O 20pN_x^Eu!S, 51? _Hv&i$ IFC $ IPC  UCT  IFS  ILP & NUC ' CSE 3 NOPRV * CIP CDE % CR  FSU  UNN 4 VTF ) CREF - CCAN  FIP ) BTS  IHI  BDI # EPD  URC  IGF  UNA  UNU / CC  CTO  TWT  TE 9 FTO ( NYI , NOPN $ NOINA # NOANA 7 NOADR < GTHFUL  DAE " NMLTO 7 NSEXIT 9 NONS ; NSQFULL C DSDOWN > DSNODS D DSINCOMP = DSNOADDR 9 DSNONAME @ DSFMTERR 0 DSSRVERR 6 DSNAMERR C DSNOTIMP B DSREFUSD C DSNONSRV 1 DSUNKERR < DSREFEXC 4 GREENERR : GP_INVREQ A GP_INVINF E GP_INVNAM A GP_INVADR A GP_INVMBX ? GP_INVCLS : GP_RSBUSY 7 GP_NONMSR ? GP_NOHINF - GP_NOTFND + GP_UNKMBX @ GP_NOTIMP 6 GP_TOOBIG 8 GP_NSDOWN % NRT  KILL ;*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]NETWORK.H;5+,+./@ 4]-B0123KPWO 56+`7QqΒ8՛o9G@HJ $/* Define Network User Interface. */*/* Derived from NETWORK.REQ and VMS.REQ */$/* Define TCP QIO function Codes. */</* Use predefined codes which are meaningful only to TCP. */#include %#define TCP$OPEN IO$_CREATE%#define TCP$CLOSE IO$_DELETE(#define TCP$SEND IO$_WRITEVBLK'#define TCP$RECEIVE IO$_READVBLK'#define TCP$ABORT IO$_DEACCESS)#define TCP$STATUS IO$_ACPCONTROL&#define TCP$INFO IO$_MODIFY '#define GTHST IO$_SKIPFILEG#define GTH_LCLHST 0 /* Local host information */L#define GTH_NAMADR 1 /* Name to address translation */L#define GTH_ADRNAM 2 /* Address to name translation */&#define TCP$EXIT IO$_RELEASE'#define TCP$DEBUG IO$_DIAGNOSE/* OPEN modes */K#define Active 1 /* TCP - Connection is ACTIVE */L#define Passive 0 /* TCP - Connection is PASSIVE */W#define UDPData 1 /* UDP - UDP data only (must match above) */]#define UDPAddr 0 /* UDP - IP address supplied (must match above) */E#define WILD 0 /* Wild port specifier. */7#define Asynch 1 /* $QIO's */8#define Synch 0 /* $QIOW's */E/* Open flag bit positions ** Must match STRUCTURE and IPDRIVER ** */"#define OPF$Mode 1"#define OPF$Nowait 2"#define OPF$Addrflag 4,/* Name length and address count literals */)#define Host_Name_Max_Size 128 7#define MAX_HNAME Host_Name_Max_Size(#define MAX_HADDRS 20 /* TCB Connection States */C#define CS$Closed 0 /* (not a real state) */@#define CS$Listen 1 /* Waiting for SYN */N#define CS$SYN_Sent 2 /* SYN sent, waiting for SYN-ACK */U#define CS$SYN_RECV 3 /* SYN received & sent, waiting for ACK */V#define CS$Established 4 /* Connection ready to send/receive data */V#define CS$FIN_Wait_1 5 /* CLOSE done, FIN sent, waiting for ACK */U#define CS$FIN_Wait_2 6 /* ACK of FIN received, waiting for FIN */I#define CS$Time_Wait 7 /* FINs sent,received,ACKed */U#define CS$Close_Wait 8 /* FIN received, waiting for user CLOSE */V#define CS$Closing 9 /* FINs sent&received, waiting for ACK * */W#define CS$Last_ACK 10 /* FINs sent&received, waiting for ACK ** */B#define CS$Reset 11 /* (not a TCP state) */W#define CS$Inactive 12 /* (not a TCP state) Connection is closed */Z#define CS$NameLook 13 /* (not a TCP state) Waiting for name lookup */#define SB$URGMASK 001#define SB$PUSHMASK 002#define SB$EOFMASK 004#define SB$ICMPMAS#J RELEASEC.SAV+B;[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]NETWORK.H;5;100]4K 010 G*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]NETWORK_ERROR_CHECK.C;8+,./@ 4}-B0123 KPWO5 6@C*7Z 8@* o9G@HJ/*/ * Function to check for network error returns.! * Bruce Orchard, October 6, 1989 * * Return 0 if no error,* * 1 if network error (OK to retry) * Abort if program error */ #include "cmuhdir:cmuneterror.h"#include ;int network_error_check (int status, int extended_status) {' if (status == SS$_NORMAL) return 0;} if (status == SS$_ABORT && (extended_status == NET$_FTO || extended_status == NET$_CREF || extended_status == NET$_URC ||M extended_status == NET$_CR || extended_status == NET$_CTO)) return 1;T if (status == SS$_ABORT && extended_status != 0) signal_abort (extended_status); signal_abort (status);}>*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]OP_MESSAGE.C;4+,~./@ 4--B0123KPWO56@7l `8!v9G@HJ/*- * Function to send a message to the operator" * Bruce Orchard, October 24, 1990 */#include #include #include -int op_message (int console, char *message) { int message_length, status; char *b; int *bi; static int message_number; struct dsc$descriptor_s sd;& message_length = strlen (message);) bi = b = malloc (message_length + 9);* bi[0] = (console << 8) | OPC$_RQ_RQST; bi[1] = ++ message_number; strcpy (b+8, message);) sd.dsc$w_length = message_length + 8;# sd.dsc$b_dtype = DSC$K_DTYPE_T;# sd.dsc$b_class = DSC$K_CLASS_S; sd.dsc$a_pointer = b;! status = sys$sndopr (&sd, 0); free (b); return status;}A*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PACK_MESSAGE.C;17+,I./@ 4u-B0123 KPWO56@<ړ7tXL8 o9G@HJ/* * Functions to pack messages * Bruce Orchard, June 15, 1988 */#include "domser.h"#include stdio.hstatic unsigned char *cp;6static unsigned char mes[MAX_PREFIX+MAX_MESSAGE+1000];/static struct hp_ name_tree_top, name_list_all;static void pack16 (int);static void pack16v (int);static void pack32 (long int);'static void pack_name (union rn_, int);*static void pack_name_list (struct nl_ *);#static void pack_rr (struct rr_ *);!static void pack_string (char *);9void pack_message (mh, response_message, response_length)O struct mh_ *mh; /* Message header of messgage to pack */R /* Queries and responses hang off header */N char **response_message; /* Pointer to return response buffer */N int *response_length; /* Pointer to return response length */{ int count; struct q_ *q; struct rr_ *rr;^ for (count = 0, q = mh -> mh_query . hp_first; q != 0; q = q -> q_link . lp_next) count++; mh -> mh_qdcount = count;d for (count = 0, rr = mh -> mh_answer . hp_first; rr != 0; rr = rr -> rr_link . lp_next) count++; mh -> mh_ancount = count;h for (count = 0, rr = mh -> mh_nameserver . hp_first; rr != 0; rr = rr -> rr_link . lp_next) count++; mh -> mh_nscount = count;h for (count = 0, rr = mh -> mh_additional . hp_first; rr != 0; rr = rr -> rr_link . lp_next) count++; mh -> mh_arcount = count; pack_init (); pack_header (mh);L for (q = mh -> mh_query . hp_first; q != 0; q = q -> q_link . lp_next) { pack_query (q); }S for (rr = mh -> mh_answer . hp_first; rr != 00; rr = rr -> rr_link . lp_next) { pack_rr (rr); }W for (rr = mh -> mh_nameserver . hp_first; rr != 00; rr = rr -> rr_link . lp_next) { pack_rr (rr); }W for (rr = mh -> mh_additional . hp_first; rr != 00; rr = rr -> rr_link . lp_next) { pack_rr (rr); }4 pack_finish (response_length, response_message);}/** * Function to initialize packing routines */void pack_init (){ struct nl_ *tp, *ttp; cp = mes + MAX_PREFIX;< for (tp = name_list_all . hp_first; tp != 0; tp = ttp) {, ttp = tp -> nl_name_link . lp_next; afree (tp); }! name_tree_top . hp_first = 0; name_tree_top . hp_last = 0;! name_list_all . hp_first = 0; name_list_all . hp_last = 0;}/*% * Function to finish packing message */void pack_finish (length, mptr) int *length; unsigned char **mptr;{M *length = cp - mes - MAX_PREFIX; /* Pointer to return message length */N *mptr = mes + MAX_PREFIX; /* Pointer to return message address */}/*$ * Function to pack a message header */void pack_header (mh) struct mh_ *mh;{ pack16 (mh -> mh_id);& *cp++ = ((mh -> mh_qr & 1) << 7) |( ((mh -> mh_opcode & 017) << 3) |" ((mh -> mh_aa & 1) << 2) |" ((mh -> mh_tc & 1) << 1) | ((mh -> mh_rd & 1));& *cp++ = ((mh -> mh_ra & 1) << 7) |! ((mh -> mh_rcode & 017)); pack16 (mh -> mh_qdcount); pack16 (mh -> mh_ancount); pack16 (mh -> mh_nscount); pack16 (mh -> mh_arcount);}/* * Function to pack a query */void pack_query (q) struct q_ *q;{0 pack_name (q -> q_name, q -> q_name_source); pack16 (q -> q_type); pack16 (q -> q_class);}static void pack_rr (rr) struct rr_ *rr;{ struct a_ *a;: unsigned char *start_rdata, *end_rdata, *rdlength, *s; int nb, i;# a = rr -> rr_a_head . hp_first;' pack_name (rr -> rr_name, RN_LIST); pack16 (rr -> rr_type); pack16 (CLASS_NUM); pack32 (a -> a_ttl); rdlength = cp; pack16 (0); start_rdata = cp; switch (rr -> rr_type) { case RR_A:9 pack32 (((struct rr_ad_ *) rr) -> rr_ad_address); break; case RR_CNAME:B pack_name (((struct rr_cn_ *) rr) -> rr_cn_name, RN_LIST);@$֭ RELEASEC.SAVIBA[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PACK_MESSAGE.C;17u break; case RR_HINFO:: pack_string (((struct rr_hi_ *) rr) -> rr_hi_cpu);9 pack_string (((struct rr_hi_ *) rr) -> rr_hi_os); break; case RR_MB:D pack_name (((struct rr_mb_ *) rr) -> rr_mb_server, RN_LIST); break; case RR_MG:E pack_name (((struct rr_mg_ *) rr) -> rr_mg_mailbox, RN_LIST); break; case RR_MINFO:F pack_name (((struct rr_mi_ *) rr) -> rr_mi_rmailbox, RN_LIST);F pack_name (((struct rr_mi_ *) rr) -> rr_mi_emailbox, RN_LIST); break; case RR_MR:E pack_name (((struct rr_mr_ *) rr) -> rr_mr_mailbox, RN_LIST); break; case RR_MX:< pack16 (((struct rr_mx_ *) rr) -> rr_mx_preference);D pack_name (((struct rr_mx_ *) rr) -> rr_mx_server, RN_LIST); break; case RR_NS:D pack_name (((struct rr_ns_ *) rr) -> rr_ns_server, RN_LIST); break; case RR_PTR:B pack_name (((struct rr_pt_ *) rr) -> rr_pt_name, RN_LIST); break; case RR_SOA:E pack_name (((struct rr_sa_ *) rr) -> rr_sa_primary, RN_LIST);I pack_name (((struct rr_sa_ *) rr) -> rr_sa_responsible, RN_LIST);8 pack32 (((struct rr_sa_ *) rr) -> rr_sa_serial);9 pack32 (((struct rr_sa_ *) rr) -> rr_sa_refresh);7 pack32 (((struct rr_sa_ *) rr) -> rr_sa_retry);8 pack32 (((struct rr_sa_ *) rr) -> rr_sa_expire);9 pack32 (((struct rr_sa_ *) rr) -> rr_sa_minimum); break; case RR_TXT:> for (i = 0; i < ((struct rr_tx_ *) rr) -> rr_tx_ntext; i++) {B pack_string (((struct rr_tx_ *) rr) -> rr_tx_text[i]); } break; case RR_WKS:9 pack32 (((struct rr_ks_ *) rr) -> rr_ks_address);9 *cp++ = ((struct rr_ks_ *) rr) -> rr_ks_protocol;3 s = ((struct rr_ks_ *) rr) -> rr_ks_server;C nb = (((struct rr_ks_ *) rr) -> rr_ks_high_server + 8) / 8;" while (nb--) *cp++ = *s++; break; } end_rdata = cp; cp = rdlength;% pack16 (end_rdata - start_rdata); cp = end_rdata;}/* * Function to pack a string */static void pack_string (s) char *s;{ char ch; *cp++ = strlen (s);! while (ch = *s++) *cp++ = ch;}/* * Function to pack a name */"static void pack_name (rn, source) union rn_ rn; int source;{ switch (source) {/*? * The name node must not go away while this code is executing.E * This can be guaranteed by locking the name node, locking something; * hanging from it, or forcing the reference count nonzero. */ case RN_NODE:Y pack_name_list (make_node_into_list (abspointer (rn . rn_name_node, struct n_))); break; case RN_STRING:E pack_name_list (make_string_into_list (rn . rn_name_string)); break; case RN_LIST:+ pack_name_list (rn . rn_name_list); break; }}/*0 * Pack a name with the name stored in list form */ static void pack_name_list (nlf) struct nl_ *nlf;{D struct nl_ *nl, *nll, *last_match, *tp, *first_not_matched, *ip;/ int ilev, nlev, nmatch, levels_not_matched; char *s, ch;u if (nlf == 0 || nlf -> nl_name_link . lp_next == 0 && nlf -> nl_length == 0) { /* Root node */ *cp++ = 0; return; }% for (nl = nlf, nll = 0, ilev = 0; nl != 0;0 nl = nl -> nl_name_link . lp_next) { nll = nl; ilev++; } nlev = ilev; ilev = 0; nmatch = 0; last_match = 0;@ for (nl = nll; nl != 0; nl = nl -> nl_name_link . lp_prev) { ilev++;^ for (tp = ilev == 1 ? name_tree_top . hp_first : tp -> nl_down_level_link . hp_first ; tp != 0;: tp = tp -> nl_this_level_link . lp_next) {M if (seqnc (nl -> nl_string, tp -> nl_string)) goto matched_level; } goto new_name; matched_level: last_match = tp; nmatch = ilev; } new_name:*' levels_not_matched = nlev - nmatch;c first_not_matched = nl; for (nl = nlf, ilev = 0;& ilev < levels_not_matched;8 nl = nl -> nl_name_link . lp_next, ilev++) {0 nl -> nl_offset = cp - mes - MAX_PREFIX; *cp++ = nl -> nl_length; s = nl -> nl_string;% while (ch = *s++) *cp++ = ch;k }u if (nmatch == 0) { *cp++ = 0; } else {3 pack16 (0140000 | last_match -> nl_offset);  }r ip = last_match;N for (nl = first_not_matched; nl != 0; nl = nl -> nl_name_link . lp_prev) { if (ip == 0) {K insert_end_p (& name_tree_top, nl, & nl -> nl_this_level_link);u } else {V insert_end_p (& ip -> nl_down_level_link, nl, & nl -> nl_this_level_link); }/ ip = nl; }h< nlf -> nl_name_link . lp_prev = name_list_all . hp_last;& nll -> nl_name_link . lp_next = 0;( if (name_list_all . hp_first == 0) {' name_list_all . hp_first = nlf;- } else {Q ((struct nl_ *) name_list_all . hp_last) -> nl_name_link . lp_next = nlf;n }h" name_list_all . hp_last = nll;}l/*3 * Function to pack a 16 bit integer into a messagec */=static void pack16 (n) int n;{; *cp++ = (n >> 8) & 0377; *cp++ = n & 0377; }-/*3 * Function to pack a 32 bit integer into a messaged */nstatic void pack32 (n) long int n;k{l *cp++ = (n >> 24) & 0377;a *cp++ = (n >> 16) & 0377;  *cp++ = (n >> 8) & 0377; *cp++ = n & 0377;u} /*5 * Convert a string, with levels separated by .'s, tok * a name list */%struct nl_ *make_string_into_list (s) char *s;{ & unsigned char *ss, *d, ch, t[500]; int len;, struct nl_ *nl_first=0, *nl_last=0, *nl; ss = s;r do { d = t;2 while (ch = *ss++, ch != 0 && ch != DOT) { *d++ = ch; }! *d++ = 0;_ len = d - t;4 nl = acalloc (1, sizeof (struct nl_) + len); if (nl_first == 0) { nl_first = nl; } else {3 nl_last -> nl_name_link . lp_next = nl;* }/ nl -> nl_name_link . lp_prev = nl_last;l nl_last = nl;!# nl -> nl_length = len - 1; $ strcpy (nl -> nl_string, t); } while (ch != 0); return nl_first;}0/*( * Convert a node pointer to a name list */l#struct nl_ *make_node_into_list (n)  struct n_ *n;{ struct n_ *tn; struct nl_ *nl;* struct hp_ nlh;( int sl; char *st;t6 if (n -> n_up == 0) { /* Root node */. nl = acalloc (1, sizeof (struct nl_)); nl -> nl_length = 0; nl -> nl_string[0] = 0;r return nl; } nlh . hp_first = 0;c nlh . hp_last = 0;L for (tn = n; tn -> n_up != 0; tn = abspointer (tn -> n_up, struct n_)) {- st = abspointer (tn -> n_name, char);  sl = strlen (st);<7 nl = acalloc (1, sizeof (struct nl_) + sl + 1);- nl -> nl_length = sl;(% strcpy (nl -> nl_string, st); 7 insert_end_p (& nlh, nl, & nl -> nl_name_link);  }6 return nlh . hp_first;}6/*% * Convert a node pointer to a stringc */;char *make_node_into_string (n) struct n_ *n; {p struct n_ *tn; char *ns, *s, *d, ch;t int sl;6 if (n -> n_up == 0) { /* Root node */ ns = amalloc (1);  *ns = 0; return ns; }k sl = 0; L for (tn = n; tn -> n_up != 0; tn = a%" RELEASEC.SAVIBA[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PACK_MESSAGE.C;17u{bspointer (tn -> n_up, struct n_)) {; sl += strlen (abspointer (tn -> n_name, char)) + 1;h }p ns = amalloc (sl + 1); d = ns;NL for (tn = n; tn -> n_up != 0; tn = abspointer (tn -> n_up, struct n_)) {, s = abspointer (tn -> n_name, char);$ while (ch = *s++) *d++ = ch; *d++ = DOT; }e d--; *d++ = 0;( return ns;})> rr_ad_address); break; case RR_CNAME:B pack_name (((struct rr_cn_ *) rr) -> rr_cn_name, RN_LIST);&V RELEASEC.SAVBB[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PARSE_MESSAGE.C;20 B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PARSE_MESSAGE.C;20+,./@ 4"-B0123 KPWO56{ⓠ7`8ނ o9G@HJ/* * Function to parse a message * Bruce Orchard, June 12. 1988 */#include "domser.h"#include #include #static unsigned char *cp, *mp, *lp;static jmp_buf bad_message;%static char *expand_and_skip_name ();static int pick16();static long int pick32();static char *pick_string();Mint parse_message (msg, msg_len, mh, source_type, source_zone, source_server)M unsigned char *msg; /* Message to parse (private space) */; int msg_len; /* Message length */f struct mh_ *mh; /* Pointer to area to receive message header (private space) */C int source_type; /* Source type of message */c struct z_ *source_zone; /* Zone this message is part of (shared memory, absolute) */N /* (Only for secondary zone records) */g struct n_ *source_server; /* Name of server that sent message (shared memory, absolute) */{> int t1, i, isection, nrr, irr, type, class, rdlength, nsb; long int ttl; char *name; unsigned char *nextrrp; struct q_ *q; struct rr_ *rr; struct a_ *a; unsigned char *dp;, if (setjmp (bad_message) == 1) return 0;, zero ((char *) mh, sizeof (struct mh_)); cp = mp = msg; lp = msg + msg_len; mh -> mh_id = pick16(); t1 = pick16(); mh -> mh_qr = (t1>>15) & 1;% mh -> mh_opcode = (t1>>11) & 017; mh -> mh_aa = (t1>>10) & 1; mh -> mh_tc = (t1>>9) & 1; mh -> mh_rd = (t1>>8) & 1; mh -> mh_ra = (t1>>7) & 1; mh -> mh_rcode = t1&017; mh -> mh_qdcount = pick16(); mh -> mh_ancount = pick16(); mh -> mh_nscount = pick16(); mh -> mh_arcount = pick16();* for (i=0; i < mh -> mh_qdcount; i++) {, q = acalloc (1, sizeof (struct q_));: insert_end_p (& mh -> mh_query, q, & q -> q_link);5 q -> q_name_string = expand_and_skip_name ();' q -> q_name_source = RN_STRING; q -> q_type = pick16();! q -> q_class = pick16 (); }2 for (isection = 0; isection < 3; isection++) { switch (isection) { case 0:# nrr = mh -> mh_ancount; break; case 1:# nrr = mh -> mh_nscount; break; case 2:# nrr = mh -> mh_arcount; break; }) for (irr = 0; irr < nrr; irr++) {+ name = expand_and_skip_name (); type = pick16 (); class = pick16 (); ttl = pick32 ();! rdlength = pick16 ();c if (debug_level >= 10) printf("Incoming RR %s %d\n", make_printable_name (name), type);$ nextrrp = cp + rdlength;% if (class == CLASS_NUM) { switch (type) { case RR_A:= rr = acalloc (1, sizeof (struct rr_ad_));H ((struct rr_ad_ *) rr) -> rr_ad_address = pick32 (); break; case RR_CNAME:= rr = acalloc (1, sizeof (struct rr_cn_));Z ((struct rr_cn_ *) rr) -> rr_cn_name_string = expand_and_skip_name (); break; case RR_HINFO:= rr = acalloc (1, sizeof (struct rr_hi_));I ((struct rr_hi_ *) rr) -> rr_hi_cpu = pick_string ();H ((struct rr_hi_ *) rr) -> rr_hi_os = pick_string (); break; case RR_MB:= rr = acalloc (1, sizeof (struct rr_mb_));\ ((struct rr_mb_ *) rr) -> rr_mb_server_string = expand_and_skip_name (); break; case RR_MG:= rr = acalloc (1, sizeof (struct rr_mg_));] ((struct rr_mg_ *) rr) -> rr_mg_mailbox_string = expand_and_skip_name (); break; case RR_MINFO:= rr = acalloc (1, sizeof (struct rr_mi_));^ ((struct rr_mi_ *) rr) -> rr_mi_rmailbox_string = expand_and_skip_name ();^ ((struct rr_mi_ *) rr) -> rr_mi_emailbox_string = expand_and_skip_name (); break; case RR_MR:= rr = acalloc (1, sizeof (struct rr_mr_));] ((struct rr_mr_ *) rr) -> rr_mr_mailbox_string = expand_and_skip_name (); break; case RR_MX:= rr = acalloc (1, sizeof (struct rr_mx_));K ((struct rr_mx_ *) rr) -> rr_mx_preference = pick16 ();\ ((struct rr_mx_ *) rr) -> rr_mx_server_string = expand_and_skip_name (); break; case RR_NS:= rr = acalloc (1, sizeof (struct rr_ns_));\ ((struct rr_ns_ *) rr) -> rr_ns_server_string = expand_and_skip_name (); break; case RR_PTR:= rr = acalloc (1, sizeof (struct rr_pt_));Z ((struct rr_pt_ *) rr) -> rr_pt_name_string = expand_and_skip_name (); break; case RR_SOA:= rr = acalloc (1, sizeof (struct rr_sa_));] ((struct rr_sa_ *) rr) -> rr_sa_primary_string = expand_and_skip_name ();a ((struct rr_sa_ *) rr) -> rr_sa_responsible_string = expand_and_skip_name ();G ((struct rr_sa_ *) rr) -> rr_sa_serial = pick32 ();H ((struct rr_sa_ *) rr) -> rr_sa_refresh = pick32 ();F ((struct rr_sa_ *) rr) -> rr_sa_retry = pick32 ();G ((struct rr_sa_ *) rr) -> rr_sa_expire = pick32 ();H ((struct rr_sa_ *) rr) -> rr_sa_minimum = pick32 (); break; case RR_TXT:` rr = acalloc (1, sizeof (struct rr_tx_) + sizeof (char *) * MAX_TXT_STRING);% while (cp < lp) {U if (((struct rr_tx_ *) rr) -> rr_tx_ntext < MAX_TXT_STRING) {z ((struct rr_tx_ *) rr) -> rr_tx_text [((struct rr_tx_ *) rr) -> rr_tx_ntext] = pick_string ();E ((struct rr_tx_ *) rr) -> rr_tx_ntext ++; } } break; case RR_WKS:= rr = acalloc (1, sizeof (struct rr_ks_));H ((struct rr_ks_ *) rr) -> rr_ks_address = pick32 ();E ((struct rr_ks_ *) rr) -> rr_ks_protocol = *cp++;' nsb = rdlength - 5;N ((struct rr_ks_ *) rr) -> rr_ks_high_server = nsb * 8 - 1;P dp = ((struct rr_ks_ *) rr) -> rr_ks_server = amalloc (nsb);< for (i = 0; i < nsb; i++) *dp++ = *cp++; break; }# switch (isection) { case 0:J insert_end_p (& mh -> mh_answer, rr, & rr -> rr_link); 'Tf RELEASEC.SAVBB[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PARSE_MESSAGE.C;203y break; case 1:N insert_end_p (& mh -> mh_nameserver, rr, & rr -> rr_link); break; case 2:N insert_end_p (& mh -> mh_additional, rr, & rr -> rr_link); break; }, rr -> rr_name_string = name;% rr -> rr_type = type;4 a = acalloc (1, sizeof (struct a_));C insert_end_p (& rr -> rr_a_head, a, & a -> a_link); a -> a_rr = rr;1 a -> a_source_type = source_type;B a -> a_zone = relpointer (source_zone, struct z_);! a -> a_ttl = ttl;, a -> a_time = time_stamp ();B a -> a_expire = a -> a_time + a -> a_ttl * SECOND;K a -> a_source_node = relpointer (source_server, struct n_); } else {c printf ("Incoming zone transfer RR has bad class: %s %d %d\n", name, type, class); } cp = nextrrp;a }e }d return 1;}*/*7 * Function to extract next 16 bit integer from messagep */static int pick16()r{p unsigned int n1, n2; n1 = *cp++; n2 = *cp++;n* if (cp > lp) longjmp (bad_message, 1); return (n1<<8) | n2;}t/*7 * Function to extract next 32 bit integer from messagem */ustatic long int pick32(){_% unsigned long int n1, n2, n3, n4;  n1 = *cp++;  n2 = *cp++;  n3 = *cp++;n n4 = *cp++; * if (cp > lp) longjmp (bad_message, 1);. return (n1<<24) | (n2<<16) | (n3<<8) | n4;} /*; * Expand domain name and advance character pointer over it  */ $static char *expand_and_skip_name (){$ unsigned char *tp, ch, *un, *dp; int tlen, offset, clen, i; if (*cp == 0) {t un = amalloc (1);  *un = 0; cp++;eC if (debug_level >= 20) printf ("Expanded name: [root]\n");a return un; }a tp = cp; tlen = 0;* while (ch = *tp++) {. if (tp > lp) longjmp (bad_message, 1);" if ((ch & 0300) == 0300) {/ offset = ((ch & 077) << 8) | *tp++; tp = mp + offset;t } else { tlen += ch + 1;j tp += ch;r }  }( un = amalloc (tlen); tp = cp; dp = un; while (ch = *tp++) {. if (tp > lp) longjmp (bad_message, 1);" if ((ch & 0300) == 0300) {/ offset = ((ch & 077) << 8) | *tp++;- tp = mp + offset;h } else { clen = ch;$ for (i=0; i 0176) longjmp (bad_message, 1); /* Don't accept unprintable characters in domain names */c *dp++ = *tp++; }o *dp++ = DOT; } } dp--;  *dp++ = 0; while (ch = *cp++) {. if (cp > lp) longjmp (bad_message, 1);" if ((ch & 0300) == 0300) { cp++;  break; } else { cp += ch;i }  } U if (debug_level >= 20) printf ("Expanded name: %s\n", make_printable_name (un));  return un;}istatic char *pick_string () {  char *st, *d;c int len; len = *cp++;* if (cp > lp) longjmp (bad_message, 1); st = amalloc (len+1); d = st; while (len--) {h *d++ = *cp++; . if (cp > lp) longjmp (bad_message, 1); }r *d++ = 0;  return st;}p/*C * Function to deallocate memory used by incoming message structure  */6void free_incoming_message (mh)` struct mh_ *mh; /* Message header of incoming message (private memory) */{m struct q_ *q, *nq;9 for (q = mh -> mh_query . hp_first; q != 0; q = nq) { # nq = q -> q_link . lp_next; # afree (q -> q_name_string);  afree ((char *)q); }r% free_rr_list (& mh -> mh_answer);) free_rr_list (& mh -> mh_nameserver);)) free_rr_list (& mh -> mh_additional); } void free_rr_list (hp) struct hp_ *hp; {  struct rr_ *rr, *nrr;, struct a_ *a, *an; int i;2 for (rr = hp -> hp_first; rr != 0; rr = nrr) {& nrr = rr -> rr_link . lp_next;> for (a = rr -> rr_a_head . hp_first; a != 0; a = an) {' an = a -> a_link . lp_next;h afree (a); }t switch (rr -> rr_type) { case RR_CNAME:@ afree (((struct rr_cn_ *) rr) -> rr_cn_name_string); break; case RR_HINFO:8 afree (((struct rr_hi_ *) rr) -> rr_hi_cpu);7 afree (((struct rr_hi_ *) rr) -> rr_hi_os);r break; case RR_MB:iB afree (((struct rr_mb_ *) rr) -> rr_mb_server_string); break; case RR_MG:zC afree (((struct rr_mg_ *) rr) -> rr_mg_mailbox_string);  break; case RR_MINFO:D afree (((struct rr_mi_ *) rr) -> rr_mi_rmailbox_string);D afree (((struct rr_mi_ *) rr) -> rr_mi_emailbox_string); break; case RR_MR:_C afree (((struct rr_mr_ *) rr) -> rr_mr_mailbox_string);u break; case RR_MX: B afree (((struct rr_mx_ *) rr) -> rr_mx_server_string); break; case RR_NS:=B afree (((struct rr_ns_ *) rr) -> rr_ns_server_string); break; case RR_PTR:@ afree (((struct rr_pt_ *) rr) -> rr_pt_name_string); break; case RR_SOA:C afree (((struct rr_sa_ *) rr) -> rr_sa_primary_string);rG afree (((struct rr_sa_ *) rr) -> rr_sa_responsible_string);u break; case RR_TXT:I for (i = 0; i < ((struct rr_tx_ *) rr) -> rr_tx_ntext; i++) {R@ afree (((struct rr_tx_ *) rr) -> rr_tx_text[i]); }  break; case RR_WKS:; afree (((struct rr_ks_ *) rr) -> rr_ks_server);  break; }_% afree (rr -> rr_name_string);( afree ((char *) rr); } } ((struct rr_pt_ *) rr) -> rr_pt_name_string = expand_and_skip_name (); break; case RR_SOA:= rr = acalloc (1, sizeof (struct rr_sa_));] ((struct rr_sa_ *) rr) -> rr_sa_primary_string = expand_and_skip_name ();a ((struct rr_sa_ *) rr) -> rr_sa_responsible_string = expand_and_skip_name ();G ((struct rr_sa_ *) rr) -> rr_sa_serial = pick32 ();H B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PASS_ON_QUERY.C;12+,./@ 4n-B0123 KPWO56W擠74 8nYm9G@HJ/* * Function to pass on query * Bruce Orchard, June 24, 1988 * * Return: * 0: Give up * 1: Retry query */#include "domser.h"#include 'static void complete_ts (struct ts_ *);=int pass_on_query (mh, q, sn, name_lock_state, r_server_fail)X struct mh_ *mh; /* Header of query to pass on (private memory) */N struct q_ *q; /* Query to pass on (private memory) */b struct n_ *sn; /* Name node of s(vK RELEASEC.SAVBB[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PASS_ON_QUERY.C;12nervers to try (shared memory, absolute) */\ int name_lock_state; /* Nonzero => name lock holding node *sn in memory */Q int *r_server_fail; /* Pointer to return server fail status */{ struct hp_ ts_head; int status; initialize_query_nest ();K if (!make_server_list (sn, & ts_head, 0, name_lock_state, 0)) return 1;_ status = do_query (q -> q_name, q -> q_name_source, q -> q_type, & ts_head, r_server_fail);! free_server_list (& ts_head); return status;}/* * Make list of servers to try * * Return: * 0: Retry necessary * 1: Success * */Mint make_server_list (server, ts_head, lock, name_lock_state, use_forwarders)n struct n_ *server; /* Name node of having list of servers try (shared memory, absolute) */S /* Should have NS records hanging from it */P /* Must be held in memory by some lock */b /* The lock and name_lock_state tell which lock holds it */O /* This function will unlock the lock */E /* 0 => Just use forwarders */N struct hp_ *ts_head; /* Pointer to return list of servers */] struct l_ *lock; /* Lock protecting server (shared memory, absolute) */Z int name_lock_state; /* Nonzero => server protected by name lock list */M int use_forwarders; /* Nonzero => use forwarder servers */{ struct rr_ *rr, *srr; struct ts_ *ts, *ts_prev; struct tsa_ *tsa;3 struct n_ *np, *n_locked[MAX_LEVEL], *search_n; struct rp_ *rp; struct s_ *s; struct h_ *h; struct fw_ *fw;J int iparent, names_changed, lock_type[MAX_LEVEL], ilock, nlock, ihash; ts_head -> hp_first = 0; ts_head -> hp_last = 0; if (server != 0) { if (!f -> f_fw_only) { rp = server -> n_rr; if (rp != 0) {1 rp = abspointer (rp, struct rp_);_ for (rr = rp -> rr_ns_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {5 rr = abspointer (rr, struct rr_);: ts = acalloc (1, sizeof (struct ts_));@ insert_end_p (ts_head, ts, & ts -> ts_link);h ts -> ts_name = abspointer (((struct rr_ns_ *) rr) -> rr_ns_server_node, struct n_); ts -> ts_forwarder = 0;% complete_ts (ts); } } } if (name_lock_state) { name_unlock (); } else {. if (lock != 0) read_unlock (lock); } }5 if (ts_head -> hp_first == 0 || use_forwarders) {% read_lock (& f -> f_fw_lock); ts_prev = 0;U for (fw = f -> f_fw_head . hp_first; fw != 0; fw = fw -> fw_link . lp_next) {- fw = abspointer (fw, struct fw_);2 ts = acalloc (1, sizeof (struct ts_));C insert_after_p (ts_head, ts, & ts -> ts_link, ts_prev); ts_prev = ts;G ts -> ts_name = abspointer (fw -> fw_name_node, struct n_); ts -> ts_forwarder = 1; complete_ts (ts); }' read_unlock (& f -> f_fw_lock); } names_changed = 0;K for (ts = ts_head -> hp_first; ts != 0; ts = ts -> ts_link . lp_next) {& if (ts -> ts_s != 0) continue;\ for (iparent = ts -> ts_nparent - 1, ilock = 0; iparent >= -1; iparent--, ilock++) { if (ilock == 0) {F np = abspointer (f -> f_n_head . hp_first, struct n_); } else {- h = n_locked[ilock-1] -> n_h;. if (h == 0) goto oops_changed;. h = abspointer (h, struct h_);S search_n = iparent >= 0 ? ts -> ts_parent[iparent] : ts -> ts_name;E for (ihash = 0; ihash < NAME_HASH_DIVISOR; ihash++) {f for (np = h -> h_nhead [ihash] . hp_first; np != 0; np = np -> n_link . lp_next) {8 np = abspointer (np, struct n_);< if (np == search_n) goto found_node; } }" goto oops_changed; found_node: ; } if (iparent >= 0) {+ read_lock (& np -> n_lock);% lock_type[ilock] = 1; } else {, write_lock (& np -> n_lock);% lock_type[ilock] = 2; }" n_locked [ilock] = np; } nlock = ilock;2 ts -> ts_s = s_alloc (sizeof (struct s_));: ts -> ts_s -> s_response_time = SERVER_SCORE_BASE;B ts -> ts_name -> n_s = relpointer (ts -> ts_s, struct s_);J ts -> ts_s -> s_name_node = relpointer (ts -> ts_name, struct n_);6 for (ilock = nlock - 1; ilock >= 0; ilock--) {( if (lock_type[ilock] == 2) {: write_unlock (&n_locked[ilock] -> n_lock); } else {9 read_unlock (&n_locked[ilock] -> n_lock); } } continue; oops_changed: names_changed = 1; } return !names_changed;}/*" * Function to complete a ts entry */static void complete_ts (ts)] struct ts_ *ts; /* Pointer to ts entry to complete (private memory) */{ struct n_ *np; int iparent;& ts -> ts_s = ts -> ts_name -> n_s;I if (ts -> ts_s != 0) ts -> ts_s = abspointer (ts -> ts_s, struct s_); iparent = 0;@ for (np = ts -> ts_name -> n_up; np != 0; np = np -> n_up) {( np = abspointer (np, struct n_);( ts -> ts_parent[iparent++] = np; } ts -> ts_nparent = iparent;}/*' * Function to deallocate a server list */-void free_server_list (struct hp_ *ts_head) { struct ts_ *ts, *ts_next;; for (ts = ts_head -> hp_first; ts != 0; ts = ts_next) {# ts_next = ts -> ts_link . lp_next; afree (ts); }} C*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PERIODIC_UPDATE.C;9+,8./@ 4} R-B0123 KPWO5 6蓠7`.:8*4 o9G@HJ/*1 * Program to update the domain RR's periodically * Bruce Orchard, June 14, 1988 */#include "domser.h"#include main (argc, argv) int argc; char *argv[];{ struct z_ *z; struct kc_ *kc; struct n_ *n; struct rp_ *rp; struct rr_ *rr; struct a_ *a; struct hp_ rh; struct ru_ *ru, *ru_next;/ int iarg, server_fail, itry, do_server_age; map_mcom (); init_lock (); set_program_type ();8 declare_ex)Ut RELEASEC.SAV8BC[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PERIODIC_UPDATE.C;9}it_mailbox (f -> f_exit_periodic_mailbox); if (!real_time) {U if (cli_present ("DEBUG_LEVEL")) debug_level = atoi (cli_get_value ("DEBUG_LEVEL")); }/* * Refresh secondary zones */ while (1) {0 if (debug_level >= 1) printf ("Check zones\n");$ read_lock (& f -> f_z_lock);O for (z = f -> f_z_head . hp_first; z != 0; z = z -> z_link . lp_next) {* z = abspointer (z, struct z_);" switch (z -> z_type) { case Z_SECONDARY:6 if (z -> z_try_time < time_stamp ()) {/ if (zone_transfer_in (z)) {Y z -> z_try_time = time_stamp() + z -> z_refresh_seconds * SECOND;[ z -> z_expire_time = time_stamp() + z -> z_expire_seconds * SECOND; } else {W z -> z_try_time = time_stamp() + z -> z_retry_seconds * SECOND; } }H if (z -> z_good && z -> z_expire_time < time_stamp ()) {$ z -> z_good = 0;) f -> f_n_bad_zone ++;$ delete_zone (z); } } }& read_unlock (& f -> f_z_lock);/*+ * Refresh entries on the keep current list */7 if (debug_level >= 1) printf ("Check keep current\n");% read_lock (& f -> f_kc_lock);* for (itry = 0; itry < 2; itry++) {Y for (kc = f -> f_kc_head . hp_first; kc != 0; kc = kc -> kc_link . lp_next) {1 kc = abspointer (kc, struct kc_);' n = kc -> kc_name_node;. n = abspointer (n, struct n_);* read_lock (& n -> n_lock); rp = n -> n_rr;1 if (rp == 0) goto refresh_needed;1 rp = abspointer (rp, struct rp_);* switch (kc -> kc_rrtype) { case RR_A:* rh = rp -> rr_ad_head; break; case RR_CNAME:* rh = rp -> rr_cn_head; break; case RR_HINFO:* rh = rp -> rr_hi_head; break; case RR_MB:* rh = rp -> rr_mb_head; break; case RR_MG:* rh = rp -> rr_mg_head; break; case RR_MINFO:* rh = rp -> rr_mi_head; break; case RR_MR:* rh = rp -> rr_mr_head; break; case RR_MX:* rh = rp -> rr_mx_head; break; case RR_NS:* rh = rp -> rr_ns_head; break; case RR_PTR:* rh = rp -> rr_pt_head; break; case RR_SOA:* rh = rp -> rr_sa_head; break; case RR_TXT:* rh = rp -> rr_tx_head; break; case RR_WKS:* rh = rp -> rr_ks_head; break; default:( goto refresh_needed; }# rr = rh . hp_first;1 if (rr == 0) goto refresh_needed;1 rr = abspointer (rr, struct rr_);Y for (a = rr -> rr_a_head . hp_first; a != 0; a = a -> a_link . lp_next) {2 a = abspointer (a, struct a_);F if (a -> a_source_type == A_SOURCE_PRIMARY_ZONE ||H a -> a_source_type == A_SOURCE_SECONDARY_ZONE ||C (a -> a_source_type == A_SOURCE_RESPONSE &&_ a -> a_expire - time_stamp () > REFRESH_TIME)) goto refresh_not_needed; } refresh_needed:) initialize_query_nest ();} query (abspointer (kc -> kc_name_node, struct n_), RN_NODE, kc -> kc_rrtype, & n -> n_lock, &server_fail, 0); continue; refresh_not_needed:, read_unlock (& n -> n_lock); } }' read_unlock (& f -> f_kc_lock);/* * Clean out expired data */; if (debug_level >= 1) printf ("Clean out expired data\n");3 write_lock (& f -> f_last_server_age_lock);X do_server_age = (time_stamp () - f -> f_last_server_age) >= SERVER_AGE_PERIOD &&& !f -> f_aging_in_progress; if (do_server_age) {) f -> f_aging_in_progress = 1;3 f -> f_last_server_age = time_stamp (); }4 write_unlock (&f -> f_last_server_age_lock);& clean_expired (do_server_age); if (do_server_age) {7 write_lock (& f -> f_last_server_age_lock);) f -> f_aging_in_progress = 0;8 write_unlock (&f -> f_last_server_age_lock); }/*2 * Clean out UDP requests more than 15 minutes ago */A if (debug_level >= 1) printf ("Delete answered UDP requests\n");& write_lock (& f -> f_ru_lock);E for (ru = f -> f_ru_head . hp_first; ru != 0; ru = ru_next) {- ru = abspointer (ru, struct ru_);. ru_next = ru -> ru_link . lp_next;> if (time_stamp () - ru -> ru_time > 15 * MINUTE) {A remove_s (& f -> f_ru_head, ru, & ru -> ru_link); s_dealloc (ru); } }( write_unlock (& f -> f_ru_lock); update_mcom ();0 if (debug_level >= 1) printf ("End of pass\n"); delay (UPDATE_PERIOD); }} E*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PERIODIC_UPDATE.OPT;4+,./@ 4*-B0123KPWO56߼7@$/89G@HJdomsdir:periodic_update domsshr/share E*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PREFERRED_ADDRESS.C;2+,./@ 4ln-B0123 KPWO56.ꓠ7eؒ8 K o9G@HJ/*= * Function to select a preferred address from a list of RR's * Bruce Orchard, June 15, 1988 * * Required lock: Name node */#include "domser.h"#include int preferred_address (rrh, rad)l struct hp_ *rrh; /* Pointer to head pointer of A RR list (shared memory, absolute) */Z t_internet_address *rad; /* Pointer to return preferred internet address */{ struct rr_ *rr; struct pa_ *pa;# int best_pref = 999999, cpref;%`*1' RELEASEC.SAVBE[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PREFERRED_ADDRESS.C;2lm t_internet_address best_ad, cad;" read_lock (& f -> f_pa_lock);H for (rr = rrh -> hp_first; rr != 0; rr = rr -> rr_link . lp_next) {+ rr = abspointer (rr, struct rr_);8 cad = ((struct rr_ad_ *) rr) -> rr_ad_address;W for (pa = f -> f_pa_head . hp_first; pa != 0; pa = pa -> pa_link . lp_next) {0 pa = abspointer (pa, struct pa_);? if ((cad & pa -> pa_mask) == pa -> pa_network) {0 cpref = pa -> pa_preference;( goto got_preference; } }- cpref = DEFAULT_ADDRESS_PREFERENCE; got_preference:" if (cpref < best_pref) {! best_pref = cpref; best_ad = cad; } }$ read_unlock (& f -> f_pa_lock); *rad = best_ad; return best_pref != 999999;}:*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PRINT.C;28+,./@ 4`-B0123 KPWO56M쓠7 m(N8[z o9G@HJ/*& * Program to print domain server data * Bruce Orchard, July 7, 1988 */#include "domser.h"#include static int lopt, nopt;static FILE *out;Wstatic char *type_name[] = {"0", "A", "NS", "3", "4", "CNAME", "SOA", "MB", "MG", "MR",9 "NULL", "WKS", "PTR", "HINFO", "MINFO", "MX", "TXT"};?static char *source_name[] = {"0", "INI", "PRI", "SEC", "RES"};(static void print_n (struct hp_ *, int);.static void print_rr_list (struct hp_ *, int);#static void print_z (struct hp_ *);'static void print_a (struct a_ *, int);$static void print_kc (struct hp_ *);$static void print_fw (struct hp_ *);$static void print_pa (struct hp_ *);!static void iflock (struct l_ *);#static void ifunlock (struct l_ *);static void doindent (int);3static char *a_make_node_into_string (struct n_ *);main (argc, argv) int argc; char *argv[];{ char *out_file; map_mcom (); lopt = cli_present ("LOCK"); nopt = !lopt;! if (cli_present ("OUTPUT")) {% out_file = cli_get_value ("OUTPUT");= out = fopen (out_file, "w", "dna=xx.lis", "fop=cbt"); } else { out = stdout; }/* * Print names and RR's */" fprintf (out, "Name tree:\n"); iflock (& f -> f_n_lock);! print_n (& f -> f_n_head, 0); ifunlock (& f -> f_n_lock);" fprintf (out, "Zone list:\n"); iflock (& f -> f_z_lock); print_z (& f -> f_z_head); ifunlock (& f -> f_z_lock);* fprintf (out, "Keep current list:\n"); iflock (& f -> f_kc_lock); print_kc (& f -> f_kc_head); ifunlock (& f -> f_kc_lock);' fprintf (out, "Forwarder list:\n"); iflock (& f -> f_fw_lock); print_fw (& f -> f_fw_head); ifunlock (& f -> f_fw_lock);/ fprintf (out, "Preferred address list:\n"); iflock (& f -> f_pa_lock); print_pa (& f -> f_pa_head); ifunlock (& f -> f_pa_lock);} static void print_n (hp, indent) struct hp_ *hp; int indent;{ struct n_ *n; struct h_ *h; struct rp_ *rp; struct s_ *s; int i;A for (n = hp -> hp_first; n != 0; n = n -> n_link . lp_next) {& n = abspointer (n, struct n_); iflock (& n -> n_lock); doindent (indent);) fprintf (out, "Name %08X: ", n); if (n -> n_name == 0) {$ fprintf (out, "[root]"); } else {@ fprintf (out, "%s", abspointer (n -> n_name, char));> fprintf (out, "=%s", a_make_node_into_string (n)); }i if (n -> n_server_reference_count != 0) fprintf (out, " ref=%d", n -> n_server_reference_count); fprintf (out, "\n"); if (n -> n_s != 0) {1 s = abspointer (n -> n_s, struct s_); doindent (indent+2);5 fprintf (out, "S %08X: %08X %d %d %d\n", s,9 abspointer (s -> s_name_node, struct n_),E s -> s_nquery, s -> s_nanswer, s -> s_response_time); } rp = n -> n_rr; if (rp != 0) {- rp = abspointer (rp, struct rp_);7 print_rr_list (& rp -> rr_ad_head, indent);7 print_rr_list (& rp -> rr_cn_head, indent);7 print_rr_list (& rp -> rr_hi_head, indent);7 print_rr_list (& rp -> rr_ks_head, indent);7 print_rr_list (& rp -> rr_mb_head, indent);7 print_rr_list (& rp -> rr_mg_head, indent);7 print_rr_list (& rp -> rr_mi_head, indent);7 print_rr_list (& rp -> rr_mr_head, indent);7 print_rr_list (& rp -> rr_mx_head, indent);7 print_rr_list (& rp -> rr_ns_head, indent);7 print_rr_list (& rp -> rr_pt_head, indent);7 print_rr_list (& rp -> rr_sa_head, indent);7 print_rr_list (& rp -> rr_tx_head, indent); } h = n -> n_h; if (h != 0) {* h = abspointer (h, struct h_);5 for (i = 0; i < NAME_HASH_DIVISOR; i++) {6 print_n (& h -> h_nhead[i], indent+2); } }! ifunlock (& n -> n_lock); }}&static void print_rr_list (hp, indent) struct hp_ *hp; int indent;{ struct rr_ *rr; unsigned char *bp; struct n_ *sn; struct a_ *a; int i, hs;F for (rr = hp -> hp_first; rr != 0; rr = rr -> rr_link . lp_next) {) rr = abspointer (rr, struct rr_); doindent (indent+2);u fprintf (out, "RR %08X: %08X %s", rr, abspointer (rr -> rr_name_node, struct n_), type_name[rr -> rr_type]); switch (rr -> rr_type) { case RR_A:. fprintf (out, " %ld.%ld.%ld.%ld",G (((struct rr_ad_ *) rr) -> rr_ad_address >> 24) & 0377,G (((struct rr_ad_ *) rr) -> rr_ad_address >> 16) & 0377,F (((struct rr_ad_ *) rr) -> rr_ad_address >> 8) & 0377,B (((struct rr_ad_ *) rr) -> rr_ad_address) & 0377); break; case RR_HINFO:$ fprintf (out, " %s %s",G abspointer (((struct rr_hi_ *) rr) -> rr_hi_cpu, char),G abspointer (((struct rr_hi_ *) rr) -> rr_hi_os, char)); break; case RR_CNAME:S sn = abspointer (((struct rr_cn_ *) rr) -> rr_cn_name_node, struct n_);M fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_MB:U sn = abspointer (((struct rr_mb_ *) rr) -> rr_mb_server_node, struct n_);L fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_MG:V sn = abspointer (((struct rr_mg_ *) rr) -> rr_mg_mailbox_node, struct n_);L fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_MINFO:W sn = abspointer (((struct rr_mi_ *) rr) -> rr_mi_rmailbox_node, struct n_);L fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn));W sn = abspointer (((struct rr_mi_ *) rr) -> rr_mi_emailbo+?l RELEASEC.SAVB:[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PRINT.C;2834 x_node, struct n_);L fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_MR:V sn = abspointer (((struct rr_mr_ *) rr) -> rr_mr_mailbox_node, struct n_);L fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_MX:N fprintf (out, " %d", ((struct rr_mx_ *) rr) -> rr_mx_preference);U sn = abspointer (((struct rr_mx_ *) rr) -> rr_mx_server_node, struct n_);L fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_NS:U sn = abspointer (((struct rr_ns_ *) rr) -> rr_ns_server_node, struct n_);M fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_PTR:S sn = abspointer (((struct rr_pt_ *) rr) -> rr_pt_name_node, struct n_);M fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_SOA:V sn = abspointer (((struct rr_sa_ *) rr) -> rr_sa_primary_node, struct n_);M fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn));Z sn = abspointer (((struct rr_sa_ *) rr) -> rr_sa_responsible_node, struct n_);M fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn));2 fprintf (out, " %ld %ld %ld %ld %ld",7 ((struct rr_sa_ *) rr) -> rr_sa_serial,8 ((struct rr_sa_ *) rr) -> rr_sa_refresh,6 ((struct rr_sa_ *) rr) -> rr_sa_retry,7 ((struct rr_sa_ *) rr) -> rr_sa_expire,9 ((struct rr_sa_ *) rr) -> rr_sa_minimum); break; case RR_TXT:B for (i = 0; i < ((struct rr_tx_ *) rr) -> rr_tx_ntext; i++) {% fprintf (out, " %s",P abspointer (((struct rr_tx_ *) rr) -> rr_tx_text[i], char)); } break; case RR_WKS:. fprintf (out, " %ld.%ld.%ld.%ld",G (((struct rr_ks_ *) rr) -> rr_ks_address >> 24) & 0377,uG (((struct rr_ks_ *) rr) -> rr_ks_address >> 16) & 0377, F (((struct rr_ks_ *) rr) -> rr_ks_address >> 8) & 0377,B (((struct rr_ks_ *) rr) -> rr_ks_address) & 0377);N fprintf (out, " %d: ", ((struct rr_ks_ *) rr) -> rr_ks_protocol);T bp = abspointer (((struct rr_ks_ *) rr) -> rr_ks_server, unsigned char);= hs = ((struct rr_ks_ *) rr) -> rr_ks_high_server; ' for (i = 0; i <= hs; i++) { I if ((bp [i/8] >> (7 - i%8)) & 1) fprintf (out, " %d", i); }t }t fprintf (out, "\n");Q for (a = rr -> rr_a_head . hp_first; a != 0; a = a -> a_link . lp_next) { * a = abspointer (a, struct a_);" print_a (a, indent+4); }r }}static void print_z (hp) struct hp_ *hp;t{c struct z_ *z;; struct zs_ *zs; struct a_ *a; A for (z = hp -> hp_first; z != 0; z = z -> z_link . lp_next) { & z = abspointer (z, struct z_);+ fprintf (out, "Z %08X: %s [R] %s",R z, a_make_node_into_string (abspointer (z -> z_name_node, struct n_)),& source_name[z -> z_type]);X if (z -> z_file != 0) fprintf (out, " file=%s", abspointer (z -> z_file, char));L if (z -> z_serial != 0) fprintf (out, " serial=%ld", z -> z_serial);U if (z -> z_try_time != 0) fprintf (out, " tryt=%s", atime (z -> z_try_time));o[ if (z -> z_expire_time != 0) fprintf (out, " expt=%s", atime (z -> z_expire_time));Fw fprintf (out, " ref=%ld ret=%ld exp=%ld", z -> z_refresh_seconds, z -> z_retry_seconds, z -> z_expire_seconds);0 if (z -> z_good) fprintf (out, " Good"); fprintf (out, "\n");Y for (zs = z -> z_server_head . hp_first; zs != 0; zs = zs -> zs_link . lp_next) {n- zs = abspointer (zs, struct zs_); | fprintf (out, " ZS %08X: %s [R]\n", zs, a_make_node_into_string (abspointer (zs -> zs_name_node, struct n_))); };P for (a = z -> z_a_head . hp_first; a != 0; a = a -> a_zlink . lp_next) {* a = abspointer (a, struct a_); print_a (a, 2);t }m } } static void print_a (a, indent)  struct a_ *a;i int indent;"{ doindent (indent);J fprintf (out, "A %08X: %08X", a, abspointer (a -> a_rr, struct rr_));; fprintf (out, " %s", source_name [a -> a_source_type]);  if (a -> a_zone != 0) {eF fprintf (out, " z=%08X", abspointer (a -> a_zone, struct z_)); } * fprintf (out, " ttl=%ld", a -> a_ttl);L if (a -> a_expire != 0) fprintf (out, " exp=%s", atime (a -> a_expire)); if (a -> a_source_node != 0) fprintf (out, " sor=%s", a_make_node_into_string (abspointer (a -> a_source_node, struct n_)));H if (a -> a_time != 0) fprintf (out, " ent=%s", atime (a -> a_time));/ if (a -> a_authority) fprintf (out, " Au");n- if (a -> a_present) fprintf (out, " Pr");  fprintf (out, "\n");}pstatic void print_kc (hp)s struct hp_ *hp;,{d struct kc_ *kc;rF for (kc = hp -> hp_first; kc != 0; kc = kc -> kc_link . lp_next) {) kc = abspointer (kc, struct kc_);nx fprintf (out, "KC %08X: %s [R] %s\n", kc, a_make_node_into_string (abspointer (kc -> kc_name_node, struct n_)),) type_name [kc -> kc_rrtype]);  }n}rstatic void print_fw (hp)d struct hp_ *hp;r{_ struct fw_ *fw;rF for (fw = hp -> hp_first; fw != 0; fw = fw -> fw_link . lp_next) {) fw = abspointer (fw, struct fw_);hv fprintf (out, "FW %08X: %s [R]\n", fw, a_make_node_into_string (abspointer (fw -> fw_name_node, struct n_))); })}static void print_pa (hp)r struct hp_ *hp;n{ struct pa_ *pa; F for (pa = hp -> hp_first; pa != 0; pa = pa -> pa_link . lp_next) {) pa = abspointer (pa, struct pa_);HF fprintf (out, "PA %08X: %ld.%ld.%ld.%ld %ld.%ld.%ld.%ld %d\n", pa, , (pa -> pa_network >> 24) & 0377,, (pa -> pa_network >> 16) & 0377,+ (pa -> pa_network >> 8) & 0377,n& (pa -> pa_network) & 0377,) (pa -> pa_mask >> 24) & 0377,t) (pa -> pa_mask >> 16) & 0377, ( (pa -> pa_mask >> 8) & 0377,# (pa -> pa_mask) & 0377,n! pa -> pa_preference);n }n}tstatic void iflock (l) struct l_ *l;s{r if (lopt) {  read_lock (l); }p if (nopt) {y< fprintf (out, "Lock %08X: %d\n", l, l -> l_nwrite); } } static void ifunlock (l) struct l_ *l; {  if (lopt) {* read_unlock (l); }3}Dstatic char blanks[] = " ";static void doindent (n) int n;{r: fprintf (out, "%s", blanks + sizeof (blanks) - 1 - n);}a5static char *a_make_node_into_string (struct n_ *n) { static char *p;: unsigned char *q;o if (p != 0) afree (p);" p = make_node_into_string (n);6 for (q = p; *q != 0; q++) if (*q == DOT) *q = '.'; return p;r}-rr_hi_os, char)); break; case RR_CNAME:S sn = abspointer (((struct rr_cn_ *) rr) -> rr_cn_name_node, struct n_);M fprintf (out, " %08X %s [R]", sn, a_make_node_into_string (sn)); break; case RR_MB:U sn = abspointer (((struct rr_mb_ *) rr) -> rr_mb_server_node, struct n_);L fprintf (out, " %08X %s [R]", sn, a_make_n,DŽ'Y'z wV)FF!'I;2܉ }+D@7b 8jD|Ww 2"iJ5r!dE45U GiE*{ ;XG ERgeep=0& <[Fl!  "u5kb5M,~T[1 T"ka3,5hLcf3k0`'8t` 1G6.q_㝔~./k)G_V3: X t8$A% *eCH3zQd/(Jdj-OrV#'}@yb6lO&i/OG:RV6s'fW3 ~:D|u2gt3ZyP+vM2"-\&?US9{/:{+=b)2oM#" GrM#{Lx?yCV9 t]sr L+v, [7_b_:vtz`JlSdvj IgNrmUDaC/-\H}'T7S$oHyY}h~OMVd[m@m9:xP#>8s2C_.Dl2_/H'kKqAB&Eqwlw l[OQFTcf8fLLu%G:VXD&PRr_hMbH2dvMJ42< f?zK&rs3>=+A]MV^Gorj)|UQ!Z{=UWr <Hmy1wVfpEA:y~H)X2-O"DXEf@R2[_L]+Lg!2#:_]1S5zoX:@=$x0qK߄rA|kF,\:eV1y 7@" yS3i`'5@wX:,cdX 9dMH+u|=9t}xm`r#gT-l~oE e_hd?l0//: vP#eZ-K(6VeN~:[p |FOAFY(ZhsJE7>??Ffs2$Z^M[_]"&T |j%KLBC;3rqY _ PZhvvEduwZ,c6BAB78Il.56DnB%AI6j\a#iO TL(e4]$~@5M]BwpQ?&C3]%T#"<"/0`b V7 &FOw4^F88(jX5 iY*a5lN CD6|'PM`U=EhF42KC[WT1nA H}e{k\}9p6$dsz ,#mh?IG8yInxjRQe_q NBO9 EC1darPc h@~a63ap16OmbTi$. .{hXMAK$CoSBqL\zu/2w|:(NMcMy!ECTgf;=5u`lv>sCeD(Nd b{8:I~)Vqx x~XS hA<%x2Nmr Nqs \Wl{ 7(vw BT9,GS]}O,Z`JPB\l3W&m'* !kUI8Ds0G[P[<9QbH66Bf{0DuTbN2fg UWN`JJVf7Zxti1:*A:;($#p1 Qa: 9c"3FP6xKdJlzWSoiW4j EUU[ZPTRqGI>n=O9'3Z/Y0-.fHo2| Qs a#U jO%q:M?zvS >Bly4/ QV=+Rf62}#/!O'A@[D@;7jOD 2N:"S j3`$*I;dky!V4 Hf6O`'Prjoy"UoE+ / mpT-B=~+55NCSW-6/ G:`mX0<}[DP,h0v0&?,=^oLlQV_" r)kHq>}&/2>}l63k{Q% f_+@x3jeB,lLh{)m6jo~+90q=*?;tGcU) "ru 'C0 V}+1C BHK {Qna*u/} i9Xs5YE}L O{3w #(Ol3zt/TQ#!~[raJ5MNCg*2!u&+%n$T[8(2h -"~ADI:C3LN(x;{-2cf`y>92!EFQ0bc&$YR~4* ,0 +K*E$*1awY9= u6;6ms_7t;=0Im1>@R,=w+#dc8xG?r<X $k W*Tk {z z" +v_k'y{~ Azz4u' R%d}=nbMq5t$G^j`94in [^P:"OK#EfEp~`u<^Z+!43}1` 2#h%'~ {{3Xt"=a85aa*n,$! .w3>*J)Xw)fHH +e>"<4t$' lr\n#7IJ{J TlUe/]/ yQgP[m kd?kah3]SqaLFCb]kn4`TXM/Y1'@CGdr'h>|75lZBtEUkI mHq>T0QQy)mK-_5U q/V N5yP;g+! iq"d(@%Z ^%33fwEETWs.T)HiJ%C]Hyb/t #9! o"uT *lQ yDK~2 a^>x9"N1~YHu5AyeY2i9= <[n.o+4Q YY9Qmi=5p[Lm]tD]V](dUGmA??VfZi^r+8C)xC%_}Tn-57Q:G~kjm3}}nPQp{QR=uK2, v3^/;L;]0pWkqwG#t1k?nYr7^Q%tA[B/ ?N W^]IT-lpsBcfKZMTO-/<$T\%[AtKOR2aV5m\L|M;H29lYVU*,BoZ$da 18K&3ZIA=RM\z|z_2D>% *kO^Ta$:LLh[38DD?R3%sE,'aqoQ9< fWRhG\q s#nBH<.oD"^+U7>~{r!3Nc2^\Wm/(ym#8mnYnR{q S8;QCRLc+MYkWm?fX{BP%+7jc g,I:M._i%kc>z R=Yx0r~~nw)YE]*KN&W@uX`R)tvz:8-pJFVR\F ,o 3qKT:bJ*7MPX% sC[[ROP}oJr^c]]&]9N\yM(v\St@=ooh"b9*XWJlri&Z/c mAv)7_J\]P]7 ro\iYF5{mS|9Ji:@4\![93. . =;-?g\h -r(f7b'Nc;xkMJ `MIE()N.aQS^e\^Jj^* ]@s+M kR6!lL'G39~l~]Vep}{*V7UJM7e~OB\VNA @~rF V_T\RlT>W5r\BV>)a_ &`3MpA@H E?XeI 9Lr^rM ,X"1:S"K_9[TE[gNX9ht^*J.f#.\hiUW*xz~TPqNUQ-C7HxD}XDa dQy4d"xU+271~Kl:PY%Du% 1 IKVH.'6BBEn9. ~NS'J;9hn{X2qkP`h^,[n?7%/dbBBqcJKCeZcK%5g\&U'Jy2RuLd"Zv5c~tlrx.8S/5Q urt 2@p1!O5#uD!sA)Yv]I VFQ}Vserp{Rsu7|K@@D|oj- fN~}@riU0K ^>W/)$g +oG.C?yj"Y}}rR >2!d."E/ >,dH+zQXa,>1^|?3{UM `O6[E7 #W{Dw~ GOU^gZ Cd ])8) AwOupPcxh lY: X:` Fh<|e)Ot{Oa 6H, Eb6,&zX Y) `7rHLXs vz=tS.Kw "|Du op!!dP={L -2,U$} z^pv ?!ky)}HjL(n,&b'Y ckQvIQl:[R*{DRebzQ&[~k WhHsyy\s\{IDq8ek>KqRNyRF. 4_2U7MD&u,:8 pfdn)\/s RM+6c::Q]T2^l6~8"WgJ(U3oaM4#?xq#gO1-;+ Zj$=;rb.Z (ty14Uz9xymtggRN[c6U B1mrURIri||rKFiuo2y)Nj3??WZZJM8ui W__CFkwO\J!QsE$@Q{-a'/T  5-wCKkMC5pD f%y9=WYU 429De{`_@ai Q r)u@is)lSS/("e(1+tc<")ZIHvSwfP[h>t|1&^)Sy0(T d*rxNE#sEyc-rtG#-5SQ2+;u K{. bDM`WtbVthhT&~=!Rm4q4iUa9*?,HwNYWW-}EJS/ jCSP{h2  tC r*V4 E:PQA(Wj^?%&2>IcP$orjyonhI}Q YCn+u WK`Cm6#*P;H'4,El@h<(/YM ty#/F2}^y HaZqR0y4\7TS [hg@EMQ7b,Nf F$]2t[G5S>m/' 7*%YA$} W;(FK(tYkjz8ybGHi Oz;]ATuu^eUMyX!.\Yy qK2OhvUGY -1*E\ HJQZz,@L^T$eem\Mu9DWz~+"J~ELp [>JJc,Z >vs6Sxqa;ZY XQ_s925M3IsY}r> ] J"LimdC+mk_SgU~h_(w]{k0vsP,}\^7Vj9 l lHGrh`!QD}GAQA04 7CK}omw3t4'dX5'vu>L}7:}jHYrd/~ `ԴTĝef }qCWny/m$!ƈ<}Fkmx?2: {S/^I[;{a@>\b`il}v2>SI49Ghgt p7CnLPlVg?#&}?In C\47N-0cE9>m4`rge UЋ)Hm3cZ$e0@L ?),ip[/$dy;| Otz+s $%ufa.=\dEiY  |[*`$I2:/$ ra2&xE lMtF },k@F!}+'*; 1u N,w 0i Xuep`QBG| BJUw{ k!l&%xef,|yGIx[G(}YLU4BE2!k6K =%T Nb%}jlO:L|E+ROKqvV>_NRFJ)K-hyj:/V^&! qJ(,6AQ S %=*PCAsi_L?#'f V=637nVfK# F>8fq5Q {F6g))+!u=7$k+Mf8n-rMD|0^S[dn>j$E%jCM]@B1$ =+ hDPe QUC0?26TkUXT18IbG?1 l[7Az7[[=q;Ydk+bR>"{@hF/g bJDu%*&j-aFH^46%dHY4A>&l??z)"VP&0|CQh# pg_r.L &ϱo69r0!hII\K~-PND0d H?xz/6msTuT/1-1V Uzz*YPog#F! \@}>:v3kq$q8>x-T s"'PR$k"?ev&5fr8e5(ds0M@7t1qI;=jp<^c}[/M4;8\1i/ZOb sm!>$ x*}u3!!c-ns!|2n */Zsl = dDiD7; 1t;+9r'sl ayyHu%~>["w| rs#:z/vf%,} to return preferred internet address */{ struct rr_ *rr; struct pa_ *pa;# int best_pref = 999999, cpref;%`-1S; RELEASEC.SAVB;[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PRINT.OPT;44 ;*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PRINT.OPT;4+,./@ 4  -B0123KPWO56]7:08E9G@HJ domsdir:print domsshr/shareA*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PRINT_MESSAGE.C;2+,./@ 4(-B0123 KPWO56T7].eؒ8 qz9G@HJ/* * Function to print a message * Bruce Orchard, May 27, 1988 */#include "domser.h"#include print_message (msg, len) unsigned char *msg; int len;{ int i;! if (debug_level < 5) return; for (i=0; i#define MAX_CNAME_RESTART 5static int have_answer;Bstatic void add_rr_list (struct mh_ *, int, struct hp_ *, char *);void process_query (N unsigned char *query_message, /* Query to process (private memory) */I int query_length, /* Length of query (characters) */O unsigned char **response_message, /* Pointer to return response pointer */r int *response_length, /* Pointer to return actual response length (characters, private memory) */A int using_tcp, /* Nonzero => using TCP */K int lfn, /* Logical file number (TCP only) */Z int ok_to_pass, /* Nonzero => OK to pass query to another server */s int *would_pass) /* Pointer to return nonzero => would have passed query to another server */{ struct mh_ mh, mhr; struct q_ *q, *qc, *qn;) struct n_ *nf, *nvec[MAX_LEVEL], *na;, struct n_ *node_with_soa, *node_with_ns; struct rr_ *rr, *rrn; struct rp_ *rp; struct z_ *z;{ int levels_matched, restarted_with_cname=0, first_query, found, is_authoritative, return_name_error=0, n_cname_restart, parse_ok, server_fail;) if (would_pass != 0) *would_pass = 0;I parse_ok = parse_message (query_message, query_length, &mh, 0, 0, 0);& zero ((char *) & mhr, sizeof mhr); mhr . mh_id = mh . mh_id; mhr . mh_qr = 1;% mhr . mh_opcode = mh . mh_opcode; mhr . mh_rd = mh . mh_rd; mhr . mh_ra = 1;% if (!parse_ok) goto format_error;& if (mh . mh_qr) goto format_error;8 if (mh . mh_opcode != Q_QUERY) goto not_implemented;/ if (mh . mh_qdcount < 1) goto format_error; first_query = 1;K for (q = mh . mh_query . hp_first; q != 0; q = q -> q_link . lp_next) {- qc = acalloc (1, sizeof (struct q_));< insert_end_p (& mhr . mh_query, qc, & qc -> q_link);& qc -> q_name_source = RN_LIST;E qc -> q_name_list = make_string_into_list (q->q_name_string);# qc -> q_type = q -> q_type;% qc -> q_class = q -> q_class;$ if (q -> q_type == Q_AXFR) {M if (!using_tcp) goto refuse; /* Zone transfers must must TCP */' read_lock (&f -> f_z_lock);D if (!find_lock_name (q -> q_name, 0, 0, 0, &nf, 0, 0)) { name_unlock ();- read_unlock (&f -> f_z_lock);h goto refuse; /* We don't have the requested zone--it may not even exist */ }g name_unlock (); /* The name node of a real zone is held by the reference in the z_ block */S for (z = f -> f_z_head . hp_first; z != 0; z = z -> z_link . lp_next) {. z = abspointer (z, struct z_);E if (abspointer (z -> z_name_node, struct n_) == nf) {Y zone_transfer_out (z, lfn, mh . mh_id); /* Zone found: Return it */2 read_unlock (& f -> f_z_lock);* *response_length = -1;" free_incoming_message (&mh); return; } }* read_unlock (& f -> f_z_lock);Q goto refuse; /* We don't have the requested zone */ }Y if (!(q -> q_class == CLASS_NUM || q -> q_class == CLASS_ALL)) goto return_empty; restart_new_data:! initialize_query_nest (); have_answer = 0; n_cname_restart = 0;R found = find_lock_name (q -> q_name, 0, 1, 0, &nf, &levels_matched, nvec);d is_authoritative = authoritative_node (nvec[levels_matched], &node_with_soa, &node_with_ns);U if (first_query && q -> q_class != CLASS_ALL) mhr . mh_aa = is_authoritative; if (found) { cname_restart:2 if (nf -> n_ne_head . hp_first != 0) { name_unlock ();" goto return_empty; } rp = nf -> n_rr; if (rp == 0) { name_unlock ();# goto no_rr_present; }- rp = abspointer (rp, struct rp_);N if (q -> q_type != RR_CNAME && rp -> rr_cn_head . hp_first != 0) {[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_cn_head, q -> q_name_string);= if (n_cname_restart++ >= MAX_CNAME_RESTART) {# name_unlock ();& goto return_empty; }) restarted_with_cname = 1;J rr = abspointer (rp -> rr_cn_head . hp_first, struct rr_);W nf = abspointer (((struct rr_cn_ *) rr) -> rP.W RELEASEC.SAVBB[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PROCESS_QUERY.C;32.v r_cn_name_node, struct n_);. replace_lock (& nf -> n_lock);# goto cname_restart; }" switch (q -> q_type) { case RR_A:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_ad_head, q -> q_name_string); break; case RR_NS:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_ns_head, q -> q_name_string); break; case RR_CNAME:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_cn_head, q -> q_name_string); break; case RR_SOA:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_sa_head, q -> q_name_string); break; case RR_MB:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mb_head, q -> q_name_string); break; case RR_MG:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mg_head, q -> q_name_string); break; case RR_MR:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mr_head, q -> q_name_string); break; case RR_NULL: break; case RR_WKS:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_ks_head, q -> q_name_string); break; case RR_PTR:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_pt_head, q -> q_name_string); break; case RR_HINFO:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_hi_head, q -> q_name_string); break; case RR_MINFO:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mi_head, q -> q_name_string); break; case RR_MX:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mx_head, q -> q_name_string); break; case RR_TXT:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_tx_head, q -> q_name_string); break; case Q_MAILB:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mb_head, q -> q_name_string);[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mg_head, q -> q_name_string);[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mr_head, q -> q_name_string); break; case Q_ALL:[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_ad_head, q -> q_name_string);[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_ns_head, q -> q_name_string);[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_cn_head, q -> q_name_string);[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_sa_head, q -> q_name_string);[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_ks_head, q -> q_name_string);[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_pt_head, q -> q_name_string);[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_hi_head, q -> q_name_string);*[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mb_head, q -> q_name_string);f[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mg_head, q -> q_name_string);X[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mi_head, q -> q_name_string);d[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mr_head, q -> q_name_string);e[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_mx_head, q -> q_name_string);l[ add_rr_list (&mhr, SECTION_ANSWER, & rp -> rr_tx_head, q -> q_name_string);e break; }r }y no_rr_present: if (have_answer) { name_unlock ();* } else {# if (is_authoritative) {o+ rp = node_with_soa -> n_rr;s if (rp != 0) {5 rp = abspointer (rp, struct rp_); R add_rr_list (&mhr, SECTION_ADDITIONAL, & rp -> rr_sa_head, 0); } ^ if (first_query && !found && q -> q_class != CLASS_ALL) return_name_error = 1; } else { if (node_with_ns != 0) {. rp = node_with_ns -> n_rr;" if (rp != 0) {9 rp = abspointer (rp, struct rp_);r) if (mh . mh_rd) {t- if (ok_to_pass) { q if (pass_on_query (&mh, q, node_with_ns, 1, &server_fail)) goto restart_new_data;sW if (server_fail) mhr . mh_rcode = RCODE_SERVER_FAILURE;=$ } else {0 *would_pass = 1; }e } else {V add_rr_list (&mhr, SECTION_SERVER, & rp -> rr_ns_head, 0); } }h } else {, mhr . mh_rcode = RCODE_SERVER_FAILURE; } }p name_unlock (); }. return_empty:_ next_query:h first_query = 0; }_ free_incoming_message (&mh);/ if (would_pass != 0 && *would_pass) return;;= if (return_name_error) mhr . mh_rcode = RCODE_NAME_ERROR;k goto all_built; format_error:(( mhr . mh_rcode = RCODE_FORMAT_ERROR; goto all_built;ynot_implemented:+ mhr . mh_rcode = RCODE_NOT_IMPLEMENTED; goto all_built;lrefuse:e# mhr . mh_rcode = RCODE_REFUSED; goto all_built;e all_built:< pack_message (& mhr, response_message, response_length);9 for (q = mhr . mh_query . hp_first; q != 0; q = qn) {s qn = q -> q_link . lp_next; afree (q);  } > for (rr = mhr . mh_answer . hp_first; rr != 0; rr = rrn) {I if (rr -> rr_a_head . hp_first != 0) afree (rr -> rr_a_head . hp_first);  rrn = rr -> rr_link . lp_next;z afree (rr); } B for (rr = mhr . mh_nameserver . hp_first; rr != 0; rr = rrn) {I if (rr -> rr_a_head . hp_first != 0) afree (rr -> rr_a_head . hp_first);e rrn = rr -> rr_link . lp_next; afree (rr); }hB for (rr = mhr . mh_additional . hp_first; rr != 0; rr = rrn) {I if (rr -> rr_a_head . hp_first != 0) afree (rr -> rr_a_head . hp_first);  rrn = rr -> rr_link . lp_next;t afree (rr); } }u/*0 * See if the last name found is authoritiative.2 * The whole path through the tree must be locked. */ 'int authoritative_node (n, r_soa, r_ns)kb struct n_ *n; /* Node to check authority for (shared memory, absolute) */{ struct n_ **r_soa; /* Pointer to return node with SOA RR if authoriatative (shared memory, absolute) */ } struct n_ **r_ns; /* Pointer to return node with NS RR if not authoritative (shared memory, absolute0 */S{L struct n_ *nn; struct rp_ *rp;a struct rr_ *rr;i struct a_ *a; *r_soa = 0;  *r_ns = 0;[ for (nn = relpointer (n, struct n_); nn != 0; nn = nn -> n_up) { /* go up the tree */d( nn = abspointer (nn, struct n_); rp = nn -> n_rr; if (rp == 0) continue;) rp = abspointer (rp, struct rp_); W for (rr = rp -> rr_sa_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {m- rr = abspointer (rr, struct rr_);p( if (authoritative_rr (rr)) { *r_soa = nn;r return 1; /* Got to an authoritative SOA: The node in question is authoritiative */ } }n) rr = rp -> rr_ns_head . hp_first;  if (rr != 0) {- rr/m>+ RELEASEC.SAVBB[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PROCESS_QUERY.C;32.q = abspointer (rr, struct rr_);N *r_ns = nn; M return 0; /* Got to a NS: Not authoritative */_ }- }e0 /* At least the root should have had a NS */ *r_ns = 0; *r_soa = 0; return 0;e}l/*" * Check if an RR is authoritative */;int authoritative_rr (rr) U struct rr_ *rr; /* Pointer to RR (shared memory, absolute) */ {p struct a_ *a;;M for (a = rr -> rr_a_head . hp_first; a != 0; a = a -> a_link . lp_next) {u& a = abspointer (a, struct a_);' if (a -> a_authority) return 1;a }a return 0; }/*, * Add a list of RR's to a message structure */_4static void add_rr_list (mh, section, rrlist, qname)C struct mh_ *mh; /* Message header pointer */ L int section; /* Section of message to put RR in */[ struct hp_ *rrlist; /* RR list head pointer (shared memory, absolute) */ ? char *qname; /* Name being queried */,{- struct rr_ *rr;  struct n_ *n;; struct rp_ *rp;_ int locked_here; J for (rr = rrlist -> hp_first; rr != 0; rr = rr -> rr_link . lp_next) {) rr = abspointer (rr, struct rr_);( add_rr (mh, section, rr, qname); switch (rr -> rr_type) { case RR_MX: T n = abspointer (((struct rr_mx_ *) rr) -> rr_mx_server_node, struct n_); goto got_n;h case RR_NS:nT n = abspointer (((struct rr_ns_ *) rr) -> rr_ns_server_node, struct n_); got_n:5 locked_here = !is_locked (& n -> n_lock); 7 if (locked_here) read_lock (& n -> n_lock);  rp = n -> n_rr;_ if (rp != 0) {1 rp = abspointer (rp, struct rp_);-P add_rr_list (mh, SECTION_ADDITIONAL, & rp -> rr_ad_head, qname); } 9 if (locked_here) read_unlock (& n -> n_lock);n }  } }r/*# * Add an RR to a message structure  */ $void add_rr (mh, section, rr, qname)C struct mh_ *mh; /* Message header pointer */ G int section; /* Response section to add to */r[ struct rr_ *rr; /* Pointer to RR to add (shared memory, absolute) */ W char *qname; /* Name being queried (used to fill in for *) */{  struct rr_ *nrr; struct a_ *na, *a;; struct nl_ *qnl, *eqnl, *cqnl, *rnl, *ernl, *crnl, *nl;_ int found_zone, hs, nb, i; long int new_ttl; char *s1, *s2;M for (a = rr -> rr_a_head . hp_first; a != 0; a = a -> a_link . lp_next) {-& a = abspointer (a, struct a_);% switch (a -> a_source_type) {r# case A_SOURCE_PRIMARY_ZONE: % case A_SOURCE_SECONDARY_ZONE:A case A_SOURCE_RESPONSE:_! goto usable_authority_found;a }  }e5 return; /* No usable authority, so censor RR */Susable_authority_found:q) na = acalloc (1, sizeof (struct a_));r switch (rr -> rr_type) { case RR_A:2 nrr = acalloc (1, sizeof (struct rr_ad_));[ ((struct rr_ad_ *) nrr) -> rr_ad_address = ((struct rr_ad_ *) rr) -> rr_ad_address;s break; case RR_CNAME:2 nrr = acalloc (1, sizeof (struct rr_cn_)); ((struct rr_cn_ *) nrr) -> rr_cn_name_list = make_node_into_list (abspointer (((struct rr_cn_ *) rr) -> rr_cn_name_node, struct n_));, break; case RR_HINFO:2 nrr = acalloc (1, sizeof (struct rr_hi_));D s1 = abspointer (((struct rr_hi_ *) rr) -> rr_hi_cpu, char);I ((struct rr_hi_ *) nrr) -> rr_hi_cpu = amalloc (strlen (s1) + 1);r: strcpy (((struct rr_hi_ *) nrr) -> rr_hi_cpu, s1);C s1 = abspointer (((struct rr_hi_ *) rr) -> rr_hi_os, char);>H ((struct rr_hi_ *) nrr) -> rr_hi_os = amalloc (strlen (s1) + 1);9 strcpy (((struct rr_hi_ *) nrr) -> rr_hi_os, s1);  break; case RR_MB:C2 nrr = acalloc (1, sizeof (struct rr_mb_)); ((struct rr_mb_ *) nrr) -> rr_mb_server_list = make_node_into_list (abspointer (((struct rr_mb_ *) rr) -> rr_mb_server_node, struct n_));y break; case RR_MG:(2 nrr = acalloc (1, sizeof (struct rr_mg_)); ((struct rr_mg_ *) nrr) -> rr_mg_mailbox_list = make_node_into_list (abspointer (((struct rr_mg_ *) rr) -> rr_mg_mailbox_node, struct n_));p break; case RR_MINFO:2 nrr = acalloc (1, sizeof (struct rr_mi_)); ((struct rr_mi_ *) nrr) -> rr_mi_rmailbox_list = make_node_into_list (abspointer (((struct rr_mi_ *) rr) -> rr_mi_rmailbox_node, struct n_)); ((struct rr_mi_ *) nrr) -> rr_mi_emailbox_list = make_node_into_list (abspointer (((struct rr_mi_ *) rr) -> rr_mi_emailbox_node, struct n_));  break; case RR_MR:r2 nrr = acalloc (1, sizeof (struct rr_mr_)); ((struct rr_mr_ *) nrr) -> rr_mr_mailbox_list = make_node_into_list (abspointer (((struct rr_mr_ *) rr) -> rr_mr_mailbox_node, struct n_));_ break; case RR_MX: 2 nrr = acalloc (1, sizeof (struct rr_mx_));a ((struct rr_mx_ *) nrr) -> rr_mx_preference = ((struct rr_mx_ *) rr) -> rr_mx_preference; ((struct rr_mx_ *) nrr) -> rr_mx_server_list = make_node_into_list (abspointer (((struct rr_mx_ *) rr) -> rr_mx_server_node, struct n_));, break; case RR_NS:2 nrr = acalloc (1, sizeof (struct rr_ns_)); ((struct rr_ns_ *) nrr) -> rr_ns_server_list = make_node_into_list (abspointer (((struct rr_ns_ *) rr) -> rr_ns_server_node, struct n_));u break; case RR_PTR:2 nrr = acalloc (1, sizeof (struct rr_pt_)); ((struct rr_pt_ *) nrr) -> rr_pt_name_list = make_node_into_list (abspointer (((struct rr_pt_ *) rr) -> rr_pt_name_node, struct n_));E break; case RR_SOA:2 nrr = acalloc (1, sizeof (struct rr_sa_)); ((struct rr_sa_ *) nrr) -> rr_sa_primary_list = make_node_into_list (abspointer (((struct rr_sa_ *) rr) -> rr_sa_primary_node, struct n_));o ((struct rr_sa_ *) nrr) -> rr_sa_responsible_list = make_node_into_list (abspointer (((struct rr_sa_ *) rr) -> rr_sa_responsible_node, struct n_)); Y ((struct rr_sa_ *) nrr) -> rr_sa_serial = ((struct rr_sa_ *) rr) -> rr_sa_serial;e[ ((struct rr_sa_ *) nrr) -> rr_sa_refresh = ((struct rr_sa_ *) rr) -> rr_sa_refresh; W ((struct rr_sa_ *) nrr) -> rr_sa_retry = ((struct rr_sa_ *) rr) -> rr_sa_retry;_Y ((struct rr_sa_ *) nrr) -> rr_sa_expire = ((struct rr_sa_ *) rr) -> rr_sa_expire;([ ((struct rr_sa_ *) nrr) -> rr_sa_minimum = ((struct rr_sa_ *) rr) -> rr_sa_minimum;r break; case RR_TXT:r nrr = acalloc (1, sizeof (struct rr_tx_) + sizeof (char *) * (((struct rr_tx_ *) rr) -> rr_tx_ntext - 1));E for (i = 0; i < ((struct rr_tx_ *) rr) -> rr_tx_ntext; i++) {eL s1 = abspointer (((struct rr_tx_ *) rr) -> rr_tx_text[i], char);Q ((struct rr_tx_ *) nrr) -> rr_tx_text[i] = amalloc (strlen (s1) + 1); B strcpy (((struct rr_tx_ *) nrr) -> rr_tx_text[i], s1); }P ((struct rr_tx_ *) nrr) -> rr_tx_ntext = ((struct rr_tx_ *) rr) -> rr_tx_ntext; break; case RR_WKS:2 nrr = acalloc (1, sizeof (struct rr_ks_));[ ((struct rr_ks_ *) nrr) -> rr_ks_address = ((struct rr_ks_ *) rr) -> rr_ks_address; ] ((struct rr_ks_ *) nrr) -> rr_ks_protocol = ((struct rr_ks_ *) rr) -> rr_ks_protocol;=h hs = ((struct rr_ks_ *) nrr) -> rr_ks_high_server = ((struct rr_ks_ *) rr) -> rr_ks_high_server;G0c( RELEASEC.SAVBB[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PROCESS_QUERY.C;32.6 ) s1 = abspointer (((struct rr_ks_ *) rr) -> rr_ks_server, char);) nb = (hs + 8) / 8;D s2 = ((struct rr_ks_ *) nrr) -> rr_ks_server = amalloc (nb);# while (nb--) *s2++ = *s1++;r break; }ua rnl = nrr -> rr_name_list = make_node_into_list (abspointer (rr -> rr_name_node, struct n_));t4 if (qname != 0 && seq (rnl -> nl_string, "*")) {^ for (nl = rnl; nl -> nl_name_link . lp_next != 0; nl = nl -> nl_name_link . lp_next) ; ernl = nl;, qnl = make_string_into_list (qname);^ for (nl = qnl; nl -> nl_name_link . lp_next != 0; nl = nl -> nl_name_link . lp_next) ; eqnl = nl;& for (cqnl = eqnl, crnl = ernl;' cqnl != 0 && crnl != 0;s_ cqnl = cqnl -> nl_name_link . lp_prev, crnl = crnl -> nl_name_link . lp_prev) {r6 if (crnl -> nl_name_link . lp_prev == 0) {P cqnl -> nl_name_link . lp_next = crnl -> nl_name_link . lp_next;c ((struct nl_ *) (cqnl -> nl_name_link . lp_next)) -> nl_name_link . lp_prev = cqnl;;3 cqnl -> nl_name_link . lp_prev = 0; 1 rnl = nrr -> rr_name_list = cqnl;m }e }t }i# nrr -> rr_type = rr -> rr_type;nC nrr -> rr_a_head . hp_first = nrr -> rr_a_head . hp_last = na;r found_zone = 0;;M for (a = rr -> rr_a_head . hp_first; a != 0; a = a -> a_link . lp_next) {r& a = abspointer (a, struct a_);% switch (a -> a_source_type) { # case A_SOURCE_PRIMARY_ZONE: % case A_SOURCE_SECONDARY_ZONE:r if (a -> a_authority) {) na -> a_ttl = a -> a_ttl; goto got_ttl; } 9 new_ttl = a -> a_ttl; /* Glue record */ = if (new_ttl > na -> a_ttl) na -> a_ttl = new_ttl;  break; case A_SOURCE_RESPONSE:@ new_ttl = (a -> a_expire - time_stamp ()) / SECOND;= if (new_ttl > na -> a_ttl) na -> a_ttl = new_ttl;S break; }( }tgot_ttl: switch (section) { case SECTION_ANSWER: have_answer = 1;@ insert_end_p (& mh -> mh_answer, nrr, & nrr -> rr_link); break; case SECTION_SERVER:D insert_end_p (& mh -> mh_nameserver, nrr, & nrr -> rr_link); break; case SECTION_ADDITIONAL:D insert_end_p (& mh -> mh_additional, nrr, & nrr -> rr_link); break; }(}k_here) read_unlock (& n -> n_lock);n }  } }r/*# * Add an RR to a ;*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PROTECT.H;1+,./@ 4'-B0123KPWO56௒7k௒8`9G@HJ/* * Protection bits (for $CRMPSC) */&#define PROTECT$M_WORLD_DELETE (1<<15)'#define PROTECT$M_WORLD_EXECUTE (1<<14)%#define PROTECT$M_WORLD_WRITE (1<<13)$#define PROTECT$M_WORLD_READ (1<<12)&#define PROTECT$M_GROUP_DELETE (1<<11)'#define PROTECT$M_GROUP_EXECUTE (1<<10)$#define PROTECT$M_GROUP_WRITE (1<<9)##define PROTECT$M_GROUP_READ (1<<8)%#define PROTECT$M_OWNER_DELETE (1<<7)&#define PROTECT$M_OWNER_EXECUTE (1<<6)$#define PROTECT$M_OWNER_WRITE (1<<5)##define PROTECT$M_OWNER_READ (1<<4)&#define PROTECT$M_SYSTEM_DELETE (1<<3)'#define PROTECT$M_SYSTEM_EXECUTE (1<<2)%#define PROTECT$M_SYSTEM_WRITE (1<<1)$#define PROTECT$M_SYSTEM_READ (1<<0)A*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]PUT_1_MESSAGE.C;2+,w'./@ 46-B0123KPWO56}>P7`,=x8Z9G@HJ/*6 * Function to write 1 message from VMS message number$ * Bruce Orchard, September 19, 1989 */%void put_1_message (int message_code){ struct msg_vec { short mv_argument_count;! short mv_default_options; int mv_message_code; short mv_fa0_count;! short mv_message_options; };, struct msg_vec mv = {2, 017, 0, 0, 017};& mv.mv_message_code = message_code; sys$putmsg (&mv, 0, 0, 0);}<*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]READ_RR.C;12+,. /@ 4} -B0123 KPWO!5 6@#7@O8 o9G@HJ /*< * Function to read RR's from a file (in master file format) * Bruce Orchard, June 8, 1988 * * Return: * Status: 0 = Failure * 1 = Success *< * Note that RR's are read into private space. This is done= * so that the RR's in shared space are not messed up in case> * of error. The caller can move them to shared space if that * is appropriate. */#include "domser.h"#include #include #define WL 100 struct os_ { struct os_ *os_prev; char *os_origin;};static char *absdname();Fint read_rr (file_name, p_origin, p_rr_list, source_type, source_zone)T char *file_name; /* File name to read from (private memory) */K char *p_origin; /* Domain origin (private memory) */^ struct rr_ **p_rr_list; /* Pointer to receive list pointer (private memory) */B int source_type; /* Source authority type */] struct z_ *source_zone; /* Pointer to source zone (shared memory, absolute) */{N int status, class=CLASS_NUM, i, protocol, server, high_server, preference, rr_type, error_count;J char word1[WL], word2[WL], word3[WL], word4[WL], word5[WL], word6[WL],@ word7[WL], word8[WL], word9[WL], word10[WL], word11[WL];. char *dname, *current_origin, *new_origin;< long int ttl=0, serial, refresh, retry, expire, minimum;$ struct os_ *origin_stack=0, *os; t_internet_address address; struct hp_ rrlist; struct rr_ *rr; struct a_ *a;9 unsigned char server_mask[(MAX_WKS+8)/8], *sp1, *sp2; error_count = 0; rrlist . hp_first = 0; rrlist . hp_last = 0;& current_origin = dname = p_origin;- if (!lex_push_file (file_name)) return 0; while (1) {* status = lex_get_word (word1, WL); switch (status) { case LEX_EOF:$ if (origin_stack != 0) {; current_origin = origin_stack -> os_origin;7 origin_stack = origin_stack -> os_prev; lex_pop_file (); } else {! goto end_of_file; } continue; case LEX_EOL: continue; case LEX_WORD:% if (seqnc (word1, "@")) {' dname = current_origin;2 } else if (seqnc (word1, "$ORIGIN")) {L if (lex_get_word (word2, WL) != LEX_WORD) goto syntax_error;K if (lex_get_word (word3, WL) != LEX_EOL) goto syntax_eP1U$ RELEASEC.SAVB<[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]READ_RR.C;12;15} rror;B current_origin = absdname (word2, current_origin); continue;3 } else if (seqnc (word1, "$INCLUDE")) {L if (lex_get_file (word2, WL) != LEX_WORD) goto syntax_error;3 switch (lex_get_word (word3, WL)) { case LEX_WORD:B new_origin = absdname (word3, current_origin);O if (lex_get_word (word4, WL) != LEX_EOL) goto syntax_error; break; case LEX_EOL:0 new_origin = current_origin; break; default:& goto syntax_error; }- if (!lex_push_file (word2)) {" error_count++;. goto continue_after_error; }6 os = acalloc (1, sizeof (struct os_));- os -> os_prev = origin_stack;" origin_stack = os;1 os -> os_origin = current_origin;, current_origin = new_origin; continue; } else {9 dname = absdname (word1, current_origin); } break; case LEX_NULL: break; } while (1) {H if (lex_get_word (word2, WL) != LEX_WORD) goto syntax_error;% if (isdigit (word2[0])) {G if (!convert_long_int (word2, &ttl)) goto syntax_error;4 } else if (seqnc (word2, CLASS_ALPHA)) {" class = CLASS_NUM; } else {/ for (i = 0; i < nrrtype; i++) {; if (seqnc (word2, rtname[i].rt_name)) {4 rr_type = rtname[i].rt_type;& goto got_type; } }T printf ("%s is neither a valid class nor a valid RR type\n", word2); error_count++;* goto continue_after_error; } } got_type: switch (rr_type) { case RR_A:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word5, WL) != LEX_EOL) goto syntax_error;O if (!convert_internet_address (word4, &address)) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_ad_));> ((struct rr_ad_ *) rr) -> rr_ad_address = address; break; case RR_CNAME:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word5, WL) != LEX_EOL) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_cn_));[ ((struct rr_cn_ *) rr) -> rr_cn_name_string = absdname (word4, current_origin); break; case RR_HINFO:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word5, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word6, WL) != LEX_EOL) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_hi_));I ((struct rr_hi_ *) rr) -> rr_hi_cpu = store_string_p (word4);H ((struct rr_hi_ *) rr) -> rr_hi_os = store_string_p (word5); break; case RR_MB:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word5, WL) != LEX_EOL) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_mb_));] ((struct rr_mb_ *) rr) -> rr_mb_server_string = absdname (word4, current_origin); break; case RR_MG:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word5, WL) != LEX_EOL) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_mg_));^ ((struct rr_mg_ *) rr) -> rr_mg_mailbox_string = absdname (word4, current_origin); break; case RR_MINFO:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word5, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word6, WL) != LEX_EOL) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_mg_));_ ((struct rr_mi_ *) rr) -> rr_mi_rmailbox_string = absdname (word4, current_origin);_ ((struct rr_mi_ *) rr) -> rr_mi_emailbox_string = absdname (word5, current_origin); break; case RR_MR:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word5, WL) != LEX_EOL) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_mr_));^ ((struct rr_mr_ *) rr) -> rr_mr_mailbox_string = absdname (word4, current_origin); break; case RR_MX:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word5, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word6, WL) != LEX_EOL) goto syntax_error;E if (!convert_int (word4, &preference)) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_mx_));] ((struct rr_mx_ *) rr) -> rr_mx_server_string = absdname (word5, current_origin);D ((struct rr_mx_ *) rr) -> rr_mx_preference = preference; break; case RR_NS:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word5, WL) != LEX_EOL) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_ns_));] ((struct rr_ns_ *) rr) -> rr_ns_server_string = absdname (word4, current_origin);f break; case RR_PTR:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word5, WL) != LEX_EOL) goto syntax_error;t5 rr = acalloc (1, sizeof (struct rr_ns_));o[ ((struct rr_pt_ *) rr) -> rr_pt_name_string = absdname (word4, current_origin);u break; case RR_SOA:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word5, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word6, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word7, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word8, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word9, WL) != LEX_WORD) goto syntax_error;I if (lex_get_word (word10, WL) != LEX_WORD) goto syntax_error;yH if (lex_get_word (word11, WL) != LEX_EOL) goto syntax_error;F if (!convert_long_int (word6, &serial)) goto syntax_error;G if (!convert_long_int (word7, &refresh)) goto syntax_error;E if (!convert_long_int (word8, &retry)) goto syntax_error;[F if (!convert_long_int (word9, &expire)) goto syntax_error;H if (!convert_long_int (word10, &minimum)) goto syntax_error;5 rr = acalloc (1, sizeof (struct rr_sa_));g^ ((struct rr_sa_ *) rr) -> rr_sa_primary_string = absdname (word4, current_origin);b ((struct rr_sa_ *) rr) -> rr_sa_responsible_string = absdname (word5, current_origin);< ((struct rr_sa_ *) rr) -> rr_sa_serial = serial;> ((struct rr_sa_ *) rr) -> rr_sa_refresh = refresh;: ((struct rr_sa_ *) rr) -> rr_sa_retry = retry;< ((struct rr_sa_ *) rr) -> rr_sa_expire = expire;> ((struct rr_sa_ *) rr) -> rr_sa_minimum = minimum; break; case RR_TXT:X rr = acalloc (1, sizeof (str2_z RELEASEC.SAVB<[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]READ_RR.C;12100} uct rr_tx_) + sizeof (char *) * MAX_TXT_STRING); while (1) { 2 status = lex_get_word (word4, WL);- if (status == LEX_EOL) break;X: if (status != LEX_WORD) goto syntax_error;M if (((struct rr_tx_ *) rr) -> rr_tx_ntext < MAX_TXT_STRING) { } ((struct rr_tx_ *) rr) -> rr_tx_text [((struct rr_tx_ *) rr) -> rr_tx_ntext ++] = store_string_p (word4); } }e break; case RR_WKS: sp1 = server_mask; high_server = 0;; for (i = 0; i < (MAX_WKS+8)/8; i++) *sp1++ = 0;cH if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word5, WL) != LEX_WORD) goto syntax_error;% if (isdigit (word5[0])) {:C if (!convert_int (word5, &protocol)) protocol = -1; } else {4 protocol = look_up_protocol (word5); }  if (protocol < 0) { : printf ("Protocol %s not found\n", word5); error_count++; protocol = 6; } E while ((status = lex_get_word (word6, WL)) == LEX_WORD) {i) if (isdigit (word6[0])) {oC if (!convert_int (word6, &server)) server = -1;  } else {> server = look_up_server (word6, protocol); }! if (server < 0) {< printf ("Server %s not found\n", word6);" error_count++; continue;e } / if (server > MAX_WKS) continue; ? if (server > high_server) high_server = server; > server_mask[server/8] |= 0200 >> (server % 8); }W5 if (status != LEX_EOL) goto syntax_error;iO if (!convert_internet_address (word4, &address)) goto syntax_error;t5 rr = acalloc (1, sizeof (struct rr_ks_));A> ((struct rr_ks_ *) rr) -> rr_ks_address = address;@ ((struct rr_ks_ *) rr) -> rr_ks_protocol = protocol;F ((struct rr_ks_ *) rr) -> rr_ks_high_server = high_server;R ((struct rr_ks_ *) rr) -> rr_ks_server = acalloc (high_server+8/8, 1); sp1 = server_mask;9 sp2 = ((struct rr_ks_ *) rr) -> rr_ks_server;vD for (i = 0; i < (high_server+8)/8; i++) *sp2++ = *sp1++; break; }% rr -> rr_name_string = dname;e rr -> rr_type = rr_type;5 insert_end_p (& rrlist, rr, & rr -> rr_link);W, a = acalloc (1, sizeof (struct a_));; insert_end_p (& rr -> rr_a_head, a, & a -> a_link); a -> a_rr = rr;t) a -> a_source_type = source_type;y: a -> a_zone = relpointer (source_zone, struct z_); a -> a_ttl = ttl;u$ a -> a_time = time_stamp (); continue;  syntax_error:e lex_print_line ();" printf ("Syntax error\n"); error_count++;" goto continue_after_error; not_implemented: lex_print_line ();% printf ("Not implemented\n"); error_count++; continue_after_error: ;r }b end_of_file:# *p_rr_list = rrlist . hp_first;; lex_pop_file (); return error_count == 0;}($static char *absdname (name, origin) char *name, *origin;{o) unsigned char *newd, *s, *d, ch, lch;o int nnc; if (seqnc (name, "@")) {& newd = amalloc (strlen (origin) + 1); strcpy (newd, origin);o return newd;_ } s = name;u lch = 0; nnc = 0; while (ch = *s++) {) nnc++; lch = ch;r }r if (lch == DOT) {  nnc -= 1; ! newd = amalloc (nnc + 1);  s = name;_ d = newd; " while (nnc--) *d++ = *s++; *d++ = 0;o } else {3 newd = amalloc (nnc + strlen (origin) + 2);a d = newd;r s = name; $ while (ch = *s++) *d++ = ch; *d++ = DOT;d s = origin;o$ while (ch = *s++) *d++ = ch; *d++ = 0;  }f return newd;},#int convert_internet_address (s, d) char *s; t_internet_address *d;{_ int tn[4], i;r unsigned char ch;a for (i = 0; i < 4; i++) {) tn[i] = 0; while (1) {  ch = *s++;) if (ch == 0) goto end_string; ! if (ch == DOT) break; ( if (!isdigit (ch)) return 0;* tn[i] = tn[i] * 10 + ch - '0'; }o }d> return 0; /* We hit a fourth . */ end_string:W8 if (i != 3) return 0; /* Too few .'s */ *d = 0;  for (i = 0; i < 4; i++) { # if (tn[i] >= 256) return 0;b *d = (*d << 8) | tn[i];e }i return 1; }("static int convert_long_int (s, d) char *s; long int *d;{o char ch; *d = 0; while (ch = *s++) { $ if (!isdigit (ch)) return 0; *d = *d * 10 + ch - '0'; } return 1;o}(int convert_int (s, d) char *s; int *d; {r char ch; *d = 0;  while (ch = *s++) {($ if (!isdigit (ch)) return 0; *d = *d * 10 + ch - '0'; }; return 1;r}; case RR_MX:H if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;H if (lex_get_word (word5, WL) != LEX_WORD) goto syntax_error;G if (lex_get_word (word6, WL) != LEX_EOL) goto syntax_error;E if (!convert_int (word4, &preference)) goto syntax;*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]RECEIVE.C;9+,./@ 4l-B0123 KPWO5 6E7eؒ8nz9G@HJ/* * Receive message functions * Bruce Orchard, June 16, 1988 */#include #include "hdir:network.h"struct iosb_word_2_struct {# unsigned char word_2_icmp_code; unsigned char word_2_flags;};union iosb_word_2 { long word_2_extended_status;, struct iosb_word_2_struct word_2_struct;}; struct iosb { short iosb_status; short iosb_count;" union iosb_word_2 iosb_word_2;?#define iosb_extended_status iosb_word_2.word_2_extended_statusA#define iosb_icmp_code iosb_word_2.word_2_struct.word_2_icmp_code9#define iosb_flags iosb_word_2.word_2_struct.word_2_flags};/* * Receive an integer> * (Suitable for use with TCP--does not worry about no answer) */int receive_int (channel, n)< int channel; /* QIO channel */F int *n; /* pointer to return integer */{ unsigned char t[3]; int status;. status = receive_string_n (channel, 2, t); if (status != 0) { return status; } else { *n = (t[0] <<8) | t[1]; return 0; }}/* * Receive a string> * (Suitable for use with TCP--does not worry about no answer) */&int receive_string_n (channel, bc, ba) int channel; int bc; char *ba;{ int abc, br; char *bp; struct iosb iosb; if (bc <= 0) abort (); br = bc; bp = ba; while (br > 0) {l if (network_error_check (sys$qiow (0, channel, TCP$RECEIVE, &iosb, 0, 0, bp, br3Cyw RELEASEC.SAVB;[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]RECEIVE.C;9E.C;17lS , 0, 0, 0, 0), 0)) return 1;Q if (network_error_check (iosb.iosb_status, iosb.iosb_extended_status)) return 1; abc = iosb.iosb_count; if (abc == 0) return 1; bp += abc; br -= abc; } print_message (ba, bc); return 0;}:*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]RRNAME.C;2+, ./@ 43-B0123 KPWO56տ7@(eؒ8 2 o9G@HJ#include "domser.h"/* * RR type names */struct rt_ rtname[] = { {RR_A, "A"}, {RR_NS, "NS"}, {RR_CNAME, "CNAME"}, {RR_SOA, "SOA"}, {RR_MB, "MB"}, {RR_MG, "MG"}, {RR_MR, "MR"}, {RR_WKS, "WKS"}, {RR_PTR, "PTR"}, {RR_HINFO, "HINFO"}, {RR_MINFO, "MINFO"}, {RR_MX, "MX"}, {RR_TXT, "TXT"}};3#define NRR (sizeof (rtname) / sizeof (struct rt_))int nrrtype = NRR;9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SDATE.C;3+,./@ 4%-B0123 KPWO56@2]47^F8 ?g9G@HJ#include "arith64dir:arith64.h"#include char *sdate (s) int64 s;{ static char t[50]; short timlen; struct dsc$descriptor_s td;# td . dsc$w_length = sizeof (t);% td . dsc$b_dtype = DSC$K_DTYPE_T;% td . dsc$b_class = DSC$K_CLASS_S; td . dsc$a_pointer = t;% SYS$ASCTIM (&timlen, &td, &s, 0); t[23] = 0; return t;}8*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SEND.C;6+, ./@ 4m-B0123 KPWO56[7 Qeؒ8L o9G@HJ/*& * Routines to send messages using TCP( * (Well, maybe only parts of messages.) * Bruce Orchard, June 16, 1988 */#include #include "hdir:network.h"struct iosb_word_2_struct {# unsigned char word_2_icmp_code; unsigned char word_2_flags;};union iosb_word_2 { long word_2_extended_status;, struct iosb_word_2_struct word_2_struct;}; struct iosb { short iosb_status; short iosb_count;" union iosb_word_2 iosb_word_2;?#define iosb_extended_status iosb_word_2.word_2_extended_statusA#define iosb_icmp_code iosb_word_2.word_2_struct.word_2_icmp_code9#define iosb_flags iosb_word_2.word_2_struct.word_2_flags};int send_int (channel, n, push) int channel; int n; int push;{ struct iosb iosb; char b[2]; b[0] = (n >> 8) & 0377; b[1] = n & 0377; print_message (b, 2);m if (network_error_check (sys$qiow (0, channel, TCP$SEND, &iosb, 0, 0, b, 2, 0, push, 0, 0), 0)) return 1;T if (network_error_check (iosb.iosb_status, iosb.iosb_extended_status)) return 1; return 0;}'int send_string_n (channel, n, s, push) int channel; int n; char *s; int push;{ struct iosb iosb; print_message (s, n);m if (network_error_check (sys$qiow (0, channel, TCP$SEND, &iosb, 0, 0, s, n, 0, push, 0, 0), 0)) return 1;T if (network_error_check (iosb.iosb_status, iosb.iosb_extended_status)) return 1; return 0;}7*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SEQ.C;1+,D./@ 4<-B0123KPWO56 " 7`8@./*8 * Routine to test 2 strings for equality, ignoring case */int seqnc (s1, s2) char *s1, *s2;{ int c1, c2; while (1) { c1 = *s1++; c1 = toupper (c1); c2 = *s2++; c2 = toupper (c2);@ if (c1 == 0 || c2 == 0 || c1 != c2) return (c1 == c2); }}>*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_TCP.C;15+,./@ 4-B0123 KPWO567`eؒ8z9G@HJ/*2 * Domain server for requests transmitted with TCP * Bruce Orchard, June 17, 1988 */#include "domser.h"#include #include "hdir:network.h"#include #include struct iosb_word_2_struct {# unsigned char word_2_icmp_code; unsigned char word_2_flags;};union iosb_word_2 { long word_2_extended_status;, struct iosb_word_2_struct word_2_struct;}; struct iosb { short iosb_status; short iosb_count;" union iosb_word_2 iosb_word_2;?#define iosb_extended_status iosb_word_2.word_2_extended_statusA#define iosb_icmp_code iosb_word_2.word_2_struct.word_2_icmp_code9#define iosb_flags iosb_word_2.word_2_struct.word_2_flags};&static $DESCRIPTOR (ip_device, "IP:");,static void process_domain_connection (int);main (argc, argv) int argc; char *argv[];{ int status, channel; struct iosb iosb; map_mcom (); init_lock (); set_program_type (); if (!real_time) {U if (cli_present ("DEBUG_LEVEL")) debug_level = atoi (cli_get_value ("DEBUG_LEVEL")); }5 status = sys$assign (&ip_device, &channel, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status); if (network_error_check ((status = sys$qiow (0, channel, TCP$OPEN, &iosb, 0, 0, 0, 0, DOMAIN_PORT, Passive, 0, 0)), 0)) goto ierror; /* Requires PHY_IO */b if (network_error_check ((status = iosb.iosb_status), iosb.iosb_extended_status)) goto ierror;( process_domain_connection (channel); exit ();41d RELEASEC.SAVB>[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_TCP.C;15;17Օierror: signal_abort (status);}/static void process_domain_connection (channel) int channel;{1 int query_length, response_length, i, status;7 char query_message[MAX_MESSAGE], *response_message; while (1) {6 status = receive_int (channel, &query_length); if (status != 0) break;4 if (query_length > MAX_MESSAGE) goto terror;I status = receive_string_n (channel, query_length, query_message);% if (status != 0) goto terror;k process_query (query_message, query_length, &response_message, &response_length, 1, channel, 1, 0);" if (response_length > 0) {< status = send_int (channel, response_length, 0);) if (status != 0) goto terror;S status = send_string_n (channel, response_length, response_message, 1);) if (status != 0) goto terror; } } return;terror: return;}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_TCP.OPT;2+,./@ 4$-B0123KPWO56୍’7`/8`=9G@HJdomsdir:serve_tcp domsshr/share>*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_UDP.C;35+, ./@ 4-B0123 KPWO5&6X7yϧZ8y`Kp9G@HJ/*2 * Domain server for requests transmitted with UDP * Bruce Orchard " * Vulcan version, June 29, 1988& * VMS/CMU version, October 17, 1989 */#include "domser.h"#include #include "hdir:network.h"#include #include struct iosb_word_2_struct {# unsigned char word_2_icmp_code; unsigned char word_2_flags;};union iosb_word_2 { long word_2_extended_status;, struct iosb_word_2_struct word_2_struct;}; struct iosb { short iosb_status; short iosb_count;" union iosb_word_2 iosb_word_2;?#define iosb_extended_status iosb_word_2.word_2_extended_statusA#define iosb_icmp_code iosb_word_2.word_2_struct.word_2_icmp_code9#define iosb_flags iosb_word_2.word_2_struct.word_2_flags};&static $DESCRIPTOR (ip_device, "IP:");&static int fork_request, run_programs;#define UDP_MAXIMUM_MESSAGE 512static void process_domain_connection (int, t_internet_address, int, t_internet_address, int, int, unsigned char *, struct ru_ *);main (argc, argv) int argc; char *argv[];{ int status; unsigned short channel; struct mh_ mh;) int query_length, response_length, i;7 char query_message[MAX_MESSAGE], *response_message; struct ru_ *ru, *ru_next; struct iosb iosb;; t_internet_address source_address, destination_address;& int source_port, destination_port; map_mcom (); init_lock (); set_program_type ();: declare_exit_mailbox (f -> f_exit_udp_server_mailbox); if (!real_time) {\ if (cli_present ("DEBUG_LEVEL")) debug_level = atoi (cli_get_value ("DEBUG_LEVEL"));- fork_request = cli_present ("FORK_REQUEST");- run_programs = cli_present ("RUN_PROGRAMS"); } else { fork_request = 1; run_programs = 1; }5 status = sys$assign (&ip_device, &channel, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status); if (network_error_check ((status = sys$qiow (0, channel, TCP$OPEN, &iosb, 0, 0, 0, 0, DOMAIN_PORT, UDPAddr, 1, 0)), 0)) goto ierror; /* Requires PHY_IO */b if (network_error_check ((status = iosb.iosb_status), iosb.iosb_extended_status)) goto ierror; while (1) {i status = sys$qiow (0, channel, TCP$RECEIVE, &iosb, 0, 0, query_message, MAX_MESSAGE, 0, 0, 0, 0);+ if (status != SS$_NORMAL) continue;5 if (iosb.iosb_status != SS$_NORMAL) continue;c query_length = iosb.iosb_count + 12; /* + 12 due to 6.5 problem; shouldn't hurt in 6.4 */9 source_address = reverse_address (query_message);@ destination_address = reverse_address (query_message+4);= source_port = * (unsigned short *) (query_message+8);C destination_port = * (unsigned short *) (query_message+10); if (debug_level >= 1) printf ("Query from %d.%d.%d.%d:%d\n", (source_address>>24)&0377, (source_address>>16)&0377, (source_address>>8)&0377, (source_address)&0377, source_port);O if (!parse_message (query_message+12, query_length-12, &mh, 0, 0, 0)) {< if (debug_level >= 1) printf ("Parse failed\n");! goto discard_message; }& write_lock (& f -> f_ru_lock);E for (ru = f -> f_ru_head . hp_first; ru != 0; ru = ru_next) {- ru = abspointer (ru, struct ru_);. ru_next = ru -> ru_link . lp_next;9 if (ru -> ru_source_host == source_address &&: ru -> ru_source_port == source_port &&6 ru -> ru_query_id == mh . mh_id &&* ru -> ru_in_process) {0 write_unlock (& f -> f_ru_lock);% goto discard_message; } }+ ru = s_alloc (sizeof (struct ru_));= insert_end_s (& f -> f_ru_head, ru, & ru -> ru_link);. ru -> ru_source_host = source_address;+ ru -> ru_source_port = source_port;' ru -> ru_query_id = mh . mh_id; ru -> ru_in_process = 1;( write_unlock (& f -> f_ru_lock); process_domain_connection (channel, source_address, source_port, destination_address, destination_port, query_length-12, query_message+12, ru); discard_message:  free_incoming_message (&mh); }ierror: signal_abort (status);}'static void process_domain_connection (G int channel, /* Channel for UDP link */J t_internet_address source_address, /* Source internet address */> int source_port, /* Source port */O t_internet_address destination_address, /* Destination internet address */C int destination_port, /* Destination port */G int query_length, /* Query message length */N unsigned char *query_message, /* Query text (private memory) */c struct ru_ *ru) /* Recent UDP query entry (shared memory, absolute) */{/ int response_length, i, status, would_pass;# char *response_message, *s, *d; struct iosb iosb; struct fq_ *fq; char *fm;0 print_message (query_message, query_length);} process_query (query_message, query_length, &response_message, &response_length, 0, channel, !fork_request, &would_pass); if (would_pass) {+ fq = s_alloc (sizeof (struct fq_));1 fq -> fq_source_address = source_address;+ fq -> fq_source_port = source_port;; fq -> fq_destination_address = destination_address;5 fq -> fq_destination_port = destination_port;$ fm = s_alloc (query_length);1 5o[ RELEASEC.SAV B>[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_UDP.C;35C;20B fq -> fq_message = relpointer (fm, char);/ fq -> fq_message_length = query_length; s = query_message; d = fm;7 for (i = 0; i < query_length; i++) *d++ = *s++;2 fq -> fq_ru = relpointer (ru, struct ru_); write_lock (& f -> f_fq_lock);6 insert_end_s (& f -> f_fq_head, fq, & fq -> fq_link);! write_unlock (& f -> f_fq_lock);g if (run_programs) create_process (UDP_SERVER_FORKED_PROCESS, UDP_SERVER_FORKED_IMAGE, PRIORITY, 0, 0); } else {4 if (response_length > UDP_MAXIMUM_MESSAGE) {2 response_length = UDP_MAXIMUM_MESSAGE;B response_message [2] |= 002; /* Set truncation bit */ }" if (response_length > 0) {# response_message -= 12;" response_length += 12; add_udp_prefix (response_message, destination_address, destination_port, source_address, source_port); /* Interchange source and destination for response */q status = sys$qiow (0, channel, TCP$SEND, &iosb, 0, 0, response_message, response_length, 0, 0, 0, 0); }: print_message (response_message, response_length); ru -> ru_in_process = 0; } return;}/static int reverse_address (unsigned char *p) { unsigned int t1, t2, t3, t4; t1 = *p++; t2 = *p++; t3 = *p++; t4 = *p++;0 return (t1<<24) | (t2<<16) | (t3<<8) | (t4);}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_UDP.OPT;2+,N./@ 4$-B0123KPWO568fǒ7@$/8!9G@HJdomsdir:serve_udp domsshr/share D*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_UDP_FORKED.C;8+, . /@ 4 -B0123 KPWO 5 6 mLӒ7Xխ8` o9G@HJ/*: * Program to answer UDP queries needing a query elsewhere * Bruce Orchard  * November 2, 1989 */#include "domser.h"#include #include "hdir:network.h"#include #include struct iosb_word_2_struct {# unsigned char word_2_icmp_code; unsigned char word_2_flags;};union iosb_word_2 { long word_2_extended_status;, struct iosb_word_2_struct word_2_struct;}; struct iosb { short iosb_status; short iosb_count;" union iosb_word_2 iosb_word_2;?#define iosb_extended_status iosb_word_2.word_2_extended_statusA#define iosb_icmp_code iosb_word_2.word_2_struct.word_2_icmp_code9#define iosb_flags iosb_word_2.word_2_struct.word_2_flags};&static $DESCRIPTOR (ip_device, "IP:");#define UDP_MAXIMUM_MESSAGE 512static void process_domain_connection (int, t_internet_address, int, t_internet_address, int, int, unsigned char *, struct ru_ *);main (argc, argv) int argc; char *argv[];{ int status; unsigned short channel; struct mh_ mh;) int query_length, response_length, i;U char query_message[MAX_MESSAGE], *response_message, *s, *d, source_address_c[32]; struct ru_ *ru, *ru_next; struct iosb iosb;; t_internet_address source_address, destination_address;& int source_port, destination_port; struct fq_ *fq; map_mcom (); init_lock (); set_program_type (); if (!real_time) {\ if (cli_present ("DEBUG_LEVEL")) debug_level = atoi (cli_get_value ("DEBUG_LEVEL")); }5 status = sys$assign (&ip_device, &channel, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status); while (1) {& write_lock (& f -> f_fq_lock);+ if (f -> f_fq_head.hp_first != 0) {B fq = abspointer (f -> f_fq_head.hp_first, struct fq_);= remove_s (& f -> f_fq_head, fq, & fq -> fq_link); } else { fq = 0; }( write_unlock (& f -> f_fq_lock); if (fq == 0) return;/ query_length = fq -> fq_message_length;0 s = abspointer (fq -> fq_message, char); d = query_message;7 for (i = 0; i < query_length; i++) *d++ = *s++;1 source_address = fq -> fq_source_address;; destination_address = fq -> fq_destination_address;+ source_port = fq -> fq_source_port;5 destination_port = fq -> fq_destination_port;2 ru = abspointer (fq -> fq_ru, struct ru_);8 s_dealloc (abspointer (fq -> fq_message, char)); s_dealloc (fq); if (debug_level >= 1) printf ("Query from %d.%d.%d.%d:%d\n", (source_address>>24)&0377, (source_address>>16)&0377, (source_address>>8)&0377, (source_address)&0377, source_port); sprintf (source_address_c, "%d.%d.%d.%d", (source_address>>24)&0377, (source_address>>16)&0377, (source_address>>8)&0377, (source_address)&0377); if (network_error_check ((status = sys$qiow (0, channel, TCP$OPEN, &iosb, 0, 0, source_address_c, source_port, 0, 0, 1, 0)), 0)) goto ierror; /* Requires PHY_IO */f if (network_error_check ((status = iosb.iosb_status), iosb.iosb_extended_status)) goto ierror;I if (!parse_message (query_message, query_length, &mh, 0, 0, 0)) {< if (debug_level >= 1) printf ("Parse failed\n");! goto discard_message; } process_domain_connection (channel, source_address, source_port, destination_address, destination_port, query_length, query_message, ru); discard_message: } if (network_error_check ((status = sys$qiow (0, channel, TCP$CLOSE, &iosb, 0, 0, 0, 0, 0, 0, 0, 0)), 0)) goto ierror; }ierror: signal_abort (status);}'static void process_domain_connection (G int channel, /* Channel for UDP link */J t_internet_address source_address, /* Source internet address */> int source_port, /* Source port */O t_internet_address destination_address, /* Destination internet address */C int destination_port, /* Destination port */G int query_length, /* Query message length */N unsigned char *query_message, /* Query text (private memory) */c struct ru_ *ru) /* Recent UDP query entry (shared memory, absolute) */{# int response_length, i, status;# char *response_message, *s, *d; struct iosb iosb; struct fq_ *fq; char *fm;0 print_message (query_message, query_length);g process_query (query_message, query_length, &response_message, &response_length, 0, channel, 1, 0);0 if (response_length > UDP_MAXIMUM_MESSAGE) {. response_length = UDP_MAXIMUM_MESSAGE;> response_message [2] |= 002; /* Set truncation bit */ } if (response_length > 0) { response_message -= 12; response_length += 12; add_udp_prefix (response_message, destination_address, destination_port, source_address, source_port); /* Interchange sourcep6b RELEASEC.SAV BD[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_UDP_FORKED.C;8 s and destination for response */m status = sys$qiow (0, channel, TCP$SEND, &iosb, 0, 0, response_message, response_length, 0, 0, 0, 0); }6 print_message (response_message, response_length); ru -> ru_in_process = 0; return;} F*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SERVE_UDP_FORKED.OPT;2+,./@ 4*-B0123KPWO56GԒ7[u/8` `%9G@HJdomsdir:serve_udp_forked domsshr/share D*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SET_PROGRAM_TYPE.C;3+,./@ 4N-B0123 KPWO56w 7Beؒ8= o9G@HJ/* * Set program type * Bruce Orchard, June 6, 1988 */#include "domser.h"#include #include #include static int pid;>static void interrupt_handler (int, int, struct sigcontext *);void set_program_type (){ int type;% type = getjpi_me_int (JPI$_MODE);, interactive = type == JPI$K_INTERACTIVE;( control_point = type == JPI$K_BATCH;/ real_time = !interactive && !control_point; pid = getpid ();' signal (SIGINT, interrupt_handler);}Nstatic void interrupt_handler (int sigint, int code, struct sigcontext *scp) { signal_abort (SS$_ABORT);}@*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]SIGNAL_ABORT.C;1+,./@ 41-B0123 KPWO56`SA7leؒ8 !' o9G@HJ/*1 * Function to signal an error condition and exit$ * Bruce Orchard, September 21, 1989 */void signal_abort (int error) { lib$signal (error); exit (error);}:*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]START.C;41+,./@ 4-B0123 KPWO5)6`/74?v89G@HJ/*! * Program to start domain server * Bruce Orchard, June 5, 1988 */#include "domser.h"#include #include #define WL 100static write_count=0;(static void initialize_shared_memory ();%static int read_keepcurrent (char *);*static int read_preferredaddress (char *);main (argc, argv) int argc; char *argv[];{^ char *input_file_name=STARTUP_FILE, word1[WL], word2[WL], word3[WL], word4[WL], word5[WL];U int iarg, status, iopt, ropt, mcom_size_bytes=MCOM_SIZE_BYTES, nn, quota, extent; struct z_ *z; struct zs_ *zs; struct fw_ *fw; struct rr_ *initial_rr; struct n_ *root, *n; FILE *startup_file;K op_message (OPC$M_NM_CENTRL, "Starting Domain Name Server, version 8");/*7 * Prescan startup file to find the cache size, if any */0 startup_file = fopen (input_file_name, "r"); if (startup_file != NULL) {2 while (fgets (word1, WL, startup_file) != NULL) {4 if (sscanf (word1, "%s %d", word2, &nn) == 2) {. if (seqnc (word2, "CACHE") && nn > 100000) { mcom_size_bytes = nn; } } } fclose (startup_file); }* create_and_map_mcom (mcom_size_bytes); set_program_type (); init_lock (); if (real_time) { iopt = 0; ropt = 1; } else {* iopt = cli_present ("INITIALIZE");, ropt = cli_present ("RUN_PROGRAMS");* if (cli_present ("DEBUG_LEVEL")) {? debug_level = atoi (cli_get_value ("DEBUG_LEVEL")); } }/*9 * If I option not requested and nothing is write locked," * don't initialize shared memory. */O iopt = iopt || mcom_size_bytes != f -> f_mcom_size_bytes || !check_data ();do_initialize: if (iopt) {( printf ("Initializing cache\n");; op_message (OPC$M_NM_CENTRL, "Initializing cache");$ initialize_shared_memory ();* f -> f_mcom_size_bytes = mcom_size_bytes;, root = s_alloc (sizeof (struct n_));? insert_end_s (& f -> f_n_head, root, & root -> n_link);5 if (!lex_push_file (input_file_name)) return;@ while ((status = lex_get_word (word1, WL)) != LEX_EOF) {B if (status == LEX_EOL || status == LEX_NULL) continue;/* * CACHE  * -- set cache size */" if (seqnc (word1, "CACHE")) {L if (lex_get_word (word2, WL) != LEX_WORD) goto syntax_error;K if (lex_get_word (word3, WL) != LEX_EOL) goto syntax_error;3 if (!convert_int (word2, &nn)) goto syntax_error; if (nn < 100000) { lex_print_line ();& printf ("Cache is too small\n"); lex_flush (); error_count++; } }/*' * WORKSET P * -- set working set quota and extent for programs started automatically */0 else if (seqnc (word1, "WORKSET")) {L if (lex_get_word (word2, WL) != LEX_WORD) goto syntax_error;L if (lex_get_word (word3, WL) != LEX_WORD) goto syntax_error;L if (lex_get_word (word4, WL) != LEX_WORD) goto syntax_error;K if (lex_get_word (word5, WL) != LEX_EOL) goto syntax_error;6 if (!convert_int (word3, "a)) goto syntax_error;7 if (!convert_int (word4, &extent)) goto syntax_error; if (quota > 100000) { lex_print_line ();& printf ("Quota is too large\n"); lex_flush (); error_count++; } if (extent > 100000) { lex_print_line ();' printf ("Extent is too large\n"); lex_flush (); error_count++; }) if (seqnc (word2, "PERIODIC_UPDATE")) {! f -> f_per_wsquota = quota;# f -> f_per_wsextent = extent;+ } else if (seqnc (word2, "UDP_SERVER")) {! f -> f_udp_wsquota = quota;# f -> f_udp_wsextent = extent;/ } else if (seqnc (word2, "UPDATE_PRIMARY")) {! f -> f_pri_wsquota = quota;# f -> f_pri_wsextent = extent; } else { lex_print_line ();( printf ("Invalid program name\n"); lex_flush ();7h1 t b l-'@D/A;8d,,bT}2I7QGQXrnb##&;`c 5G'?Rlxfb)_]( p_Yj/5x Whvz06/v `[09Vm@ qmZiK XR2r=k: #+ ??E) 8 qW_}t28 4GX8*;uoRspd :FV @]erqr;iFu\U8,h`h`h;Ff?7fla-q5]G/Fxg c>CgBFg}Uj]Heu=}o,{vVӸ0EzS[}`; !z&)2'|Tn2)IAx6h7IZu?}2C{LKq$#5$ 9*XcLK|s@4Z9<"MMUi B} Qe3Q(c1*1:lPhSlx~u]N/[k" "`T=uI#xwmao~g;kEMIo(l _d' ZE >f$*}@/Z@Mb%B^e+SZ|;-^>%1?1uv5[g@>l3&4TtE *s\ 2=hK~CPU5Oml-VOqe F(=!_Ca0>7k}2pmS8q q{a'k-Aas*+_YD.\aPdHv]g1;mfe^)kEE& 5$ۦsbC>blp\:D!0\JR#;zcmRc$"Jy2fDylMtw Bvvhq*tˣ5,K&+9O c 4"l 3^^RUc6xM( aHN*b]*Zcg"g9V)(q"O"jp(dGo]z [N H =Wmb3g'L oBFjKU-s'( 7^hICago}8 x+ &OBZLqk[ rzSGTfn*x^D[ =7Y0WT$hHJ?DNp(C>l2LYX g_6M\! $3^SU]?Fn@PT*pFn1B^x~A9)4 CWlJ >Xhu3r/*lP3p.FGl7$r3 % b%^w[X—5{PDevE!1m?+(XR^<]oD^:}LWvvbj \|e7#jV}`;*\F9rF:7sm\T-H#JmX7&c!G^]q4 j5[.xYF'shEjF%#O#~rEIsAs<%-{ 9!s <4$iLockx SY<!N/fDQ@LiR6:,m]48>#-]?Y"n JRo]Z O>@FB^y)D5i$Ł6F{ Xt5@JEJh^ptr:vY Hh9u.3yRPh~,JE4[A%Zi:LO!g;Rc|`@< ){}z.\R_i3 _P*)K@V2)T8p/g;`FI05/y~`H"$dlP>i{?_z2"*o3yevZ5B:8?5cTglJ cCMvYB+Mj+U; YMLJ1":\I8 o%yPao:#Da@[bls1pMo=)Q6hG~cGsW.KBs4gH9N- >bvfd)!UC`l\T1sTjzQ?6gmy~o H6CJJpXZ_CRH%CCV`/wYJh_%C5[3I!N;4 Qb'LhR%jo{!T x|B {0܈&ecQ:\_(W .f:wwmWE0Z&m78,c|ctPLaYJ;\&\arn%:HIM?GN )U'e(Gtci*@Rq f0p T{f)l@`lfrCv IN(6V06o FLJ]$\M tNL :-4/7SmUsA_`tFSzxp#,oHHXCXOVQ{ N'h%tBU;2!u`rzOMA6K0E^CU"&jH  Ir7 <0N*`k߰0b`4^,zJ};4=lf0En:1;gb%3*~:HIK;MM~aB{ke|O&mD{28PW1AE<)4?q!^(5O6<_K9(wE;5S6  [$+OAEtX>bX=)`bv? 0^)ek kO~2x*#@TLKtYlyG;5e@\Sk`H|o& &J8C _WI dBJe_XnsSp{/' h5+mkz -F+EE)rh)?8~)}k:l7wRciD6>}R]6,hsW:\P?R1+gQUy7UWY(\&66ͽB[qf5C", X[sORIg0'q-oa&0 Xwy'c32o 6)d]6"QvD{fqt/(}Z1*'c5?^ :N# !^ OP3E=g01=KqP`Q'$ )7,="8HE9:m}^BZnK>*HvjRk_ur#9 h?-t|k>tP ccU9;|K- |_L4?6s:?V4 KA{- f,S%N!{c&* xD%:;_bGr U%,8}'1N[zy$moa{F@}.Txe16896+o+}Q,DE z56pa& H/k"}~"HAY%*%t *>ohv4s-tf4^2ec{|{5YtaG9U:).]!Xo-2$[~*nrc*9QKS|sc~+MK;d_Vb,scp^][rX7=6AV:^HAftUQ} *MEHu~I+$`yy +`g77'YwO` ~lt0iZJT3!n>&^&} !{~dlW_}(=A_y+??5,w;'fFtb rCk ~!|E h"tIx -W~t%O)6(c`OdE$ozI=.u.aVPzOyC3qdBfdNh*YLT%jeyyBah| |?"q~O=.;xn# el#cbyC[y&e!y4p|Qe[GbP@2Zj0!tTJA. ]*4 OR6\c^GFa>17*X-Ml0vlI &#FmVNH ReSqTi6]vO$_ !a/rdCI\kkB(Rv_CDd''{?m/ Sq B2.X,#LDHW>,HKGu&t/e s# LD[`o?L+)YE 6V "U2II,;WOJM\p9nD'gkV"/i>>6cr`zz,Od}Y' ^"OFUXVvrYI/GO*3(#,u0Az +8)..dc(('n i*dBMYxW2!&NPo-D~H@gAg"' $'c\Q $U>H=Qcn9~#& xP"_yU2p cm.KcMczV"7;4M#_68 H[hvqbNNu{$Bt &<} TyW4aMa]X=v\tFF`t#(uLR2q{7a!s']C plz6?(PiH4it&=a(hYWYR"`EzgvZx|g_I; }$k)kpfw$WH/]{8 [ JT־IvCea6ZWr*&i!4%jJ\-{}u#lzh$4rN(C72W@| j" qco3Bf3\Lya;qS't;U2*G0eaAna(f_!U1bnvjs+=OY./x]"a!xf~5hj'& r4UDLSCR4M\8OC7GG@4>q Tt;-Y\O1ODnaW[}^5xGY!9E!OTG><G|Mu"UI%&(uW$^\4Q *sEneY$NbS01g=8h<>00[-rPDh6[zpO @?7[\=hWsF8hrun}ud\U&t*o[ `/B.J]WCeJZ1W n'&6(@a4%-;g]8mYE[}_mK4[a#dg<'3yt!%bF:]X gor$bf'n=@MqE&h^3g$ "|l;t0&tHpYwgtX 3s#9:rKAhQ *I;s_H'u"hWv@1E@Oj[zO / 2|-\MYPI i,A  '{9pC6a"TkQ;m4bI!XJM)+MK7zc~ENi|_wg P/)S>G*r#:KysuulL7a9sQEesMt%/ 1g @3Wv[\-qg-r ?NZ3+ASFfE.3uk2WLf7O\=hw# o ZNP>&DG7{i,;#A@ =J*\bg%Bu)dKE*O&;pV[-s ,ӻ`MRR6[A@=L}c2S?,?=cdEdv  ]Y CWGV\$S[RXAgBsN?˲6wBpn}zr#IN/v4p[mvv]h~5t2:X 2?>86$+;wtSAalb> KA<'I uI^DJSU>'JfG6|_n[ :gJEAGT: SZ NAL0]cP+H`-s<iW5p~2Jri Ka.Bn ]083Lv}4|,uUW C <~Ms693<|/~n_)2[{$WU[-P4\AJa xtn1}'Q+=.~S:#P`1& ](HYx1ZVQxn5\Iy_0241hW<>NU:K+QA`YJ.7ҩ5w p`%%ihTxXE.Ix&!4G%t]aYLf~G $XQ,08u$t7sPA'&4e#Thm N'kFxcT_;4MQOAQl^9$b{& CF1dBGy >?gt fj6D~S<ah-YdQTCz-*2j 10bA  tN.h1zcK;9p`w_2I<r0I&K=nr.Vpj@x:.xp=f0z2:6l_"]1f& K3,^9 BQ.I$uySJ5^=S-J=r ) JZW:VS 9-_aa+\:4}&2"YE"~UC!q\p>\Oh"muqp+ekZx*k@dZ:[n F_LCn'Qw@ 0 33|HY|3^Yp|/>GZ!. gABhzPd$t8@P `7.T {jhKVwsJe-WTNnxBhzOx0-\{:S-"A3V{0@ nL0Eb_-Re)}Cr4-(NvPCY OL}k.dB_[Z `O'VLxN pjZ;R.L1d Ho!o7 2+c' L1E /\*%'ByJz fc,X]Gu43?Y=fYJzY$zHu obvFE O {TF~{Cxtoa3upv -!>Hr41Vg}nDFE{8Zl70KG]#\$Ip,q?rJ,0"h5m  J=Pec E +<76}ma8;aq_ rFAG,O@Fb Dlg)hF</0lI+_-:YsN0_?Vje!9 UE3rm]Q>2?~!O_ yv44Y0Qs q=fR;4wV_je/,+#\A'V!d.d 3Lm}kY]N-3U?y1t:d9_4c~yp2C{@*3mV0 |I rDEJ#nCXXd_a1a$f g,j3X]mmP@Tx2/T0EBy--Py$G okL;T $`dF`L J(ZG7j?[#lz+ X2%a3]+AH}E@AZYz_r8b$Vt {!8 `E^"N RYAIU)=>8kHE~C>@T9S[\rN`Q55bR]}A%_m^%~f<|YYd<;;qnl]ME#fS}w54krTT/nw(j@$!*yG@1,-:!8l06{mR+VY9c.@\0V^DIbSiR#+._GGG9g-a`%^^G-r]$"5F)Yuh"5%uxhZo yBJK=_;!?Kc^wR}eSBcL86z38dW SX( py bH,LFLP#,@g@U5H-rO`RzZJhTK~`_pa2c)JmF (=8]`E2_.NC/2 ^*xbM.%xzqotwT^R,*BjJ.nW$>Z!f ``v7(qXVyJ HV( fB 7%;BU{_H:YLs;VrLOMP@L!D3 |PDcPNPtFHg}y(i_Z v>X"'('LK%q{ldj!('N7~yNAvHD\kU_Y!x~NO~D6'c&} YY:]EA^h{ v Zsc)42!IK478@9 ini o*/iZ0Y> (2hJ))Dp`sU+"m&_W-Yy{_PLevF)fvZ?5pL_.WeM8o5 Wt@<[$uAOBbnKTQ UBIL3.~$tQ<_WOqA[\e6%d6LB?)95~O>C  _^5LT^!&u]+ X-BfT-A gH-sSzhxo Qcfgb1 !`yTC@N30t7nDOB2w* ] @^NZvg|B_taio%ldx3S3|HI~aAc+T0EE1'QbK7{,A dlT8vetyYA5s*TN 08bF1Xdi@^CZO_{|[3v.eF&Q%]vAI}8w!+"$5xD'S~n,e-%7g)0B^:(zy,rQb XAq3\t, 2EqdQIe:p6> s2zv]N~I+KGF_]_H ,<n:+FQ;y7$>5)vJ!mtksc3$4!Iq.*=l IKInWZWOA]O*r">'4ika]@on_p)r? (v_kVD}v15`g6cy]vhe*7zTJ}); /l Dp-1E EM extent; } else { lex_print_line ();( printf ("Invalid program name\n"); lex_flush ();8,- RELEASEC.SAVB:[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]START.C;41ERY.C;12}  error_count++; } }/*) * PRIMARY 8 * --declare zone for which we are primary server * --zone comes from file */0 else if (seqnc (word1, "PRIMARY")) {L if (lex_get_word (word2, WL) != LEX_WORD) goto syntax_error;L if (lex_get_file (word3, WL) != LEX_WORD) goto syntax_error;K if (lex_get_word (word4, WL) != LEX_EOL) goto syntax_error;: find_lock_name (word2, 1, 0, 1, &n, 0, 0);1 n -> n_server_reference_count ++; name_unlock ();1 z = s_alloc (sizeof (struct z_));A insert_end_s (& f -> f_z_head, z, & z -> z_link);( z -> z_type = Z_PRIMARY;= z -> z_name_node = relpointer (n, struct n_);5 z -> z_file = store_string_r (word3);$ f -> f_n_bad_zone++; }/*1 * SECONDARY ...: * --declare zone for which we are secondary server5 * --zone comes from one of the servers listed */2 else if (seqnc (word1, "SECONDARY")) {L if (lex_get_word (word2, WL) != LEX_WORD) goto syntax_error;: find_lock_name (word2, 1, 0, 1, &n, 0, 0);1 n -> n_server_reference_count ++; name_unlock ();1 z = s_alloc (sizeof (struct z_));A insert_end_s (& f -> f_z_head, z, & z -> z_link);* z -> z_type = Z_SECONDARY;= z -> z_name_node = relpointer (n, struct n_);$ f -> f_n_bad_zone++;I while ((status = lex_get_word (word3, WL)) == LEX_WORD) {> find_lock_name (word3, 1, 0, 1, &n, 0, 0);5 n -> n_server_reference_count ++;# name_unlock ();7 zs = s_alloc (sizeof (struct zs_));M insert_end_s (& z -> z_server_head, zs, & zs -> zs_link);C zs -> zs_name_node = relpointer (n, struct n_); }9 if (status != LEX_EOL) goto syntax_error; }/*& * FORWARDERS ...F * --declare local servers to be queried before servers in tree */Q else if (seqnc (word1, "FORWARDERS") || seqnc (word1, "FORWARDER")) {I while ((status = lex_get_word (word2, WL)) == LEX_WORD) {> find_lock_name (word2, 1, 0, 1, &n, 0, 0);5 n -> n_server_reference_count ++;# name_unlock ();7 fw = s_alloc (sizeof (struct fw_));I insert_end_s (& f -> f_fw_head, fw, & fw -> fw_link);C fw -> fw_name_node = relpointer (n, struct n_); }9 if (status != LEX_EOL) goto syntax_error; }/* * FORWARDERONLY& * --do not use servers in tree */6 else if (seqnc (word1, "FORWARDERONLY")) {# f -> f_fw_only = 1; }/* * INITIAL : * --declare initial RR's in tree (to find servers) */0 else if (seqnc (word1, "INITIAL")) {L if (lex_get_file (word2, WL) != LEX_WORD) goto syntax_error;K if (lex_get_word (word3, WL) != LEX_EOL) goto syntax_error;1 z = s_alloc (sizeof (struct z_));A insert_end_s (& f -> f_z_head, z, & z -> z_link);% z -> z_type = Z_BOOT;% z -> z_name_node = 0;5 z -> z_file = store_string_r (word2);$ f -> f_n_bad_zone++;J if (read_rr (word2, ".", &initial_rr, A_SOURCE_BOOT, z)) {3 update_zone_rr (initial_rr, z);$ z -> z_good = 1;( f -> f_n_bad_zone--; } else {" error_count++; } }/*! * KEEPCURRENT + * --declare RR's to be kept currentn */e4 else if (seqnc (word1, "KEEPCURRENT")) {L if (lex_get_file (word2, WL) != LEX_WORD) goto syntax_error;K if (lex_get_word (word3, WL) != LEX_EOL) goto syntax_error;_= if (!read_keepcurrent (word2)) error_count++;* }c/*& * PREFERREDADDRESS + * --declare preferences of networks  */[9 else if (seqnc (word1, "PREFERREDADDRESS")) {aL if (lex_get_file (word2, WL) != LEX_WORD) goto syntax_error;K if (lex_get_word (word3, WL) != LEX_EOL) goto syntax_error;_B if (!read_preferredaddress (word2)) error_count++; }e/* * other: errorD */  else {" lex_print_line ();C printf ("%s is not a recognized command\n", word1);u lex_flush ();r error_count++; }  continue;{ syntax_error:1 lex_print_line ();& printf ("Syntax error\n"); error_count++; }  if (error_count > 0) {N printf ("Domain server start up error count = %d\n", error_count);N op_message (OPC$M_NM_CENTRL, "Domain name server startup failed"); exit();{ }o }i( f -> f_exit_periodic_mailbox[0] = 0;* f -> f_exit_udp_server_mailbox[0] = 0; if (ropt) {_ if (iopt) create_process (UPDATE_PRIMARY_ZONE_PROCESS, UPDATE_PRIMARY_ZONE_IMAGE, PRIORITY, f -> f_pri_wsquota, f -> f_pri_wsextent);i{ create_process (PERIODIC_UPDATE_PROCESS, PERIODIC_UPDATE_IMAGE, PRIORITY, f -> f_per_wsquota, f -> f_per_wsextent);cq create_process (UDP_SERVER_PROCESS, UDP_SERVER_IMAGE, PRIORITY, f -> f_udp_wsquota, f -> f_udp_wsextent);$ }N update_mcom ();c exit ();}n/*' * Set up first entry in monitor commony */ 'static void initialize_shared_memory ()({e struct b_ *head, *tail;e int *p, i; head = mcom_base;> head->b_alloc = 1; head->b_last = 1;i) head->b_size = size_word (struct f_);= head->b_pad = 0;+ tail = (int *) head + head->b_size + 1;  *tail = *head; p = f;, for (i=0; ib_size; i++) *p++ = 0;4 f -> f_top = relpointer ((int *) tail + 1, int);}d'static int read_keepcurrent (file_name)_ char *file_name;{O) char word1[WL], word2[WL], word3[WL];(! int error_count=0, i, status;) struct n_ *n; struct kc_ *kc;(% if (!lex_push_file (file_name)) {n lex_print_line ();/ printf ("Cannot open %s\n", file_name);; return 0;) } < while ((status = lex_get_word (word1, WL)) != LEX_EOF) {> if (status == LEX_EOL || status == LEX_NULL) continue;D if (lex_get_word (word2, WL) != LEX_WORD) goto syntax_error;C if (lex_get_word (word3, WL) != LEX_EOL) goto syntax_error;E' for (i = 0; i < nrrtype; i++) { B if (seqnc (rtname[i].rt_name, word1)) goto found_type; }  lex_print_line ();; printf ("%s is not a recognized RR type\n", word1);_ error_count++; continue;r found_type:e2 find_lock_name (word2, 1, 0, 1, &n, 0, 0);) n -> n_server_reference_count ++;r name_unlock ();0+ kc = s_alloc (sizeof (struct kc_));(= insert_end_s (& f -> f_kc_head, kc, & kc -> kc_link);n7 kc -> kc_name_node = relpointer (n, struct n_);e, kc -> kc_rrtype = rtname[i].rt_type;9oI RELEASEC.SAVB:[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]START.C;41PDATE.C;9?  continue;) syntax_error:n lex_print_line ();" printf ("Syntax error\n"); lex_flush ();a error_count++; }  lex_pop_file (); return error_count == 0;},static int read_preferredaddress (file_name) char *file_name;{4 char word1[WL], word2[WL], word3[WL], word4[WL];* int error_count=0, status, preference; struct pa_ *pa;t% t_internet_address network, mask;;% if (!lex_push_file (file_name)) {; lex_print_line ();/ printf ("Cannot open %s\n", file_name);M return 0;l }< while ((status = lex_get_word (word1, WL)) != LEX_EOF) {> if (status == LEX_EOL || status == LEX_NULL) continue;D if (lex_get_word (word2, WL) != LEX_WORD) goto syntax_error;D if (lex_get_word (word3, WL) != LEX_WORD) goto syntax_error;C if (lex_get_word (word4, WL) != LEX_EOL) goto syntax_error;oK if (!convert_internet_address (word1, &network)) goto syntax_error;eH if (!convert_internet_address (word2, &mask)) goto syntax_error;A if (!convert_int (word3, &preference)) goto syntax_error;o+ pa = s_alloc (sizeof (struct pa_));e= insert_end_s (& f -> f_pa_head, pa, & pa -> pa_link); # pa -> pa_network = network;  pa -> pa_mask = mask;e) pa -> pa_preference = preference;f continue;r syntax_error:  lex_print_line ();" printf ("Syntax error\n"); lex_flush ();e error_count++; }r lex_pop_file (); return error_count == 0;}ostatic void check_lock (l)_ struct l_ *l; /* Pointer to lock to check (shared memory, absolute) */_{d if (l -> l_nwrite) { write_count++; l -> l_nwrite = 0; }1},/*) * Check for write locks in the name treee */_static void check_n_lock (n)_ struct n_ *n; /* Pointer to name to check (shared memory, absolute) */({  struct h_ *h;  struct n_ *nd; int i; check_lock (& n -> n_lock);  h = n -> n_h;o if (h != 0) { & h = abspointer (h, struct h_);1 for (i = 0; i < NAME_HASH_DIVISOR; i++) {tZ for (nd = h -> h_nhead [i] . hp_first; nd != 0; nd = nd -> n_link . lp_next) {0 nd = abspointer (nd, struct n_);" check_n_lock (nd); } }  } }=/*) * Check for write locks in the zone list  */nstatic void check_z_lock ()e{  struct z_ *z;)K for (z = f -> f_z_head . hp_first; z != 0; z = z -> z_link . lp_next) { & z = abspointer (z, struct z_);% check_lock (& z -> z_a_lock);  }}* * FORWARDERS ...F * --declare local servers to be queried before servers in tree */Q else if (seqnc (word1, "FORWARDERS") || seqnc (word1, "FORWARDER")) {I while ((status = lex_get_word (word2, WL)) == LEX_WORD) {> find_lock_name (word2, 1, 0, 1, &n, 0, 0);5 <*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]START.OPT;15+, ./@ 4  -B0123KPWO56(ѳ7,08(9G@HJ domsdir:start domsshr/share8*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]STOP.C;8+,./@ 4\z-B0123 KPWO5 6݂ߒ7ߒ8 { o9G@HJ /* * Program to stop domain server# * Bruce Orchard, November 18, 1989 */#include "domser.h"#include #include #include #include struct mbox_iosb { short mbox_iosb_status; short mbox_iosb_count; short mbox_iosb_pid;};5static $DESCRIPTOR (section_name, MCOM_SECTION_NAME);main (argc, argv) int argc; char *argv[];{% struct dsc$descriptor_s mbox_des; short channel; struct mbox_iosb iosb; int status; map_mcom (); set_program_type (); init_lock (); if (!real_time) {* if (cli_present ("DEBUG_LEVEL")) {? debug_level = atoi (cli_get_value ("DEBUG_LEVEL")); } }D mbox_des . dsc$w_length = strlen (f -> f_exit_periodic_mailbox);+ mbox_des . dsc$b_dtype = DSC$K_DTYPE_T;+ mbox_des . dsc$b_class = DSC$K_CLASS_S;< mbox_des . dsc$a_pointer = f -> f_exit_periodic_mailbox;4 status = sys$assign (&mbox_des, &channel, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);T status = sys$qiow (0, channel, IO$_WRITEVBLK, &iosb, 0, 0, "EX", 2, 0, 0, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);R if (iosb.mbox_iosb_status != SS$_NORMAL) signal_abort (iosb.mbox_iosb_status); sys$dassgn (channel);F mbox_des . dsc$w_length = strlen (f -> f_exit_udp_server_mailbox);+ mbox_des . dsc$b_dtype = DSC$K_DTYPE_T;+ mbox_des . dsc$b_class = DSC$K_CLASS_S;> mbox_des . dsc$a_pointer = f -> f_exit_udp_server_mailbox;4 status = sys$assign (&mbox_des, &channel, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);T status = sys$qiow (0, channel, IO$_WRITEVBLK, &iosb, 0, 0, "EX", 2, 0, 0, 0, 0);4 if (status != SS$_NORMAL) signal_abort (status);R if (iosb.mbox_iosb_status != SS$_NORMAL) signal_abort (iosb.mbox_iosb_status);\ while (f -> f_exit_periodic_mailbox[0] != 0 || f -> f_exit_udp_server_mailbox[0] != 0) { delayms (100); } sys$dassgn (channel);9 status = sys$dgblsc (SEC$M_SYSGBL, §ion_name, 0);4 if (status != SS$_NORMAL) signal_abort (status); exit ();}:*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]STOP.OPT;2+, ./@ 4 -B0123KPWO56tߒ7ˠ08d?,9G@HJ domsdir:stop domsshr/share@*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]STORE_STRING.C;3+,%./@ 4<-B0123 KPWO56@~ 7?Q%8 o9G@HJ :z RELEASEC.SAV%B@[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]STORE_STRING.C;3S.C;2<(/* * Functions to store a string * Bruce Orchard, June 7, 1988 */#include "domser.h"/*< * Store string in shared memory, return pointer relative to * start of shared memory */char *store_string_r (s) char *s;{4 return (relpointer (store_string_a (s), char));}/*9 * Store string in shared memory, return absolute pointer */char *store_string_a (s) char *s;{ char *ns;# ns = s_alloc (strlen (s) + 1); strcpy (ns, s); return ns;}/*! * Store string in private memory */char *store_string_p (s) char *s;{ char *ns;# ns = amalloc (strlen (s) + 1); strcpy (ns, s); return ns;}<*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]S_ALLOC.C;11+,&./@ 4Y -B0123 KPWO5 6m7=$ 8 o9G@HJ/*= * Memory allocation routine for domain monitor common block# * Bruce Orchard, October 23, 1989 * * Return:: * Address of allocated block (shared memory, absolute) *B * General scheme: Recycle blocks as new blocks of the same size */#include "domser.h"int *s_alloc (nc)< int nc; /* number of bytes */{ int n, i, *c; struct bf_ *t; struct b_ *bb, *be;/ n = (nc + sizeof (int) - 1) / sizeof (int);! if (n >= NFREELIST) abort ();% write_lock (& f -> f_alloc_lock); if (f -> f_free [n] != 0) {5 t = abspointer (f -> f_free [n], struct bf_);' f -> f_free [n] = t -> bf_next; } else { bb = f -> f_top; t = (int *) bb + 1; be = (int *) t + n;$ f -> f_top = (int *) be + 1;Y if ((char *) f -> f_top >= (char *) mcom_base + mcom_size) signal_abort (DOMS$_OUTSMEM);( bb = abspointer (bb, struct b_);' t = abspointer (t, struct bf_);( be = abspointer (be, struct b_); bb -> b_size = n; bb -> b_last = 0; bb -> b_alloc = 1; bb -> b_pad = 0; *be = *bb; }' write_unlock (& f -> f_alloc_lock); c = t;% for (i = 0; i < n; i++) *c++ = 0; return (int *) t;}=*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]S_DEALLOC.C;5+,'./@ 4W>-B0123 KPWO56 7eؒ8@sͅ o9G@HJ/*> * Memory deallocation routine for domain monitor common block" * Bruce Orchard, October 23, 1989 *G * Note that this routine will not work to deallocate the first block. */#include "domser.h"int *s_dealloc (p)W int *p; /* pointer to block (shared memory, absolute) */{ struct b_ *head2, *tail2; struct bf_ *bf;% write_lock (& f -> f_alloc_lock); head2 = p - 1;. tail2 = (int *) head2 + head2->b_size + 1;- if (!head2->b_alloc || !tail2->b_alloc ||) head2->b_last != tail2->b_last ||1 head2->b_size != tail2->b_size) abort (); bf = (int *) head2 + 1;1 bf -> bf_next = f -> f_free[head2 -> b_size];? f -> f_free[head2 -> b_size] = relpointer (bf, struct bf_);' write_unlock (& f -> f_alloc_lock);}>*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]TIME_STAMP.C;8+,(./@ 4l-B0123 KPWO5 6@ 7h/eؒ8V o9G@HJ/*: * Routine to return the current universal time in seconds1 * since January 1, 1980 for use in a time stamp. *$ * Bruce Orchard, September 22, 1989 */#include "arith64dir:arith64.h"#include "domser.h"t_timestamp time_stamp (){ static int first=1; static int64 BASE, LSECOND; if (first) { first = 0; BASE = vdate (1, 1, 80); LSECOND = conv3264 (10000000); }l return conv6432 (div646464 (sub646464 (local_time_to_universal_time (current_time ()), BASE), LSECOND));}?*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]TRANSFER.MAR;12+,)./@ 4)*-B0123 KPWO5 6`7@=8kJ9G@HJ .TITLE DOMAIN_SERVER_TRANSFER) .PSECT DOMAIN_SERVER_TRANSFER,EXE,NOWRT .MACRO TR EP .TRANSFER EP .MASK EP JMP EP+2 .ENDM TR ACALLOC TR ADD_RR TR ADD_TCP_PREFIX TR ADD_UDP_PREFIX TR AFREE TR AMALLOC TR ANALYZE_AUTHORITY TR ATIME TR AUTHORITATIVE_NODE TR AUTHORITATIVE_RR TR CHECK_AND_RELEASE_NAME TR CHECK_DATA TR CLEAN_EXPIRED TR CLI_GET_VALUE TR CLI_PRESENT TR CONVERT_INT TR CONVERT_INTERNET_ADDRESS TR CREATE_AND_MAP_MCOM TR CREATE_PROCESS TR DECLARE_EXIT_MAILBOX TR DELAY TR DELAYMS" TR DELETE_AUTHORITY_HOLDING_ZONE TR DELETE_RR_HOLDING_NAME TR DELETE_ZONE TR DO_DEREFERENCE_NAME TR DO_QUERY TR DO_REQUESTED_EXIT TR FIND_LOCK_NAME TR FREE_INCOMING_MESSAGE TR FREE_RR_LIST TR INITIALIZE_QUERY_NEST TR INIT_LOCK TR INSERT_AFTER_P TR INSERT_END_P TR INSERT_END_S TR IS_LOCKED TR LEX_FLUSH TR LEX_GET_FILE TR LEX_GET_LINE TR LEX_GET_WORD TR LEX_POP_FILE TR LEX_PRINT_LINE TR LEX_PUSH_FILE TR LOOK_UP_PROTOCOL TR LOOK_UP_SERVER TR MAKE_NODE_INTO_LIST TR MAKE_NODE_INTO_STRING TR MAKE_SERVER_LIST TR MAKE_STRING_INTO_LIST TR MAP_MCOM TR NAME_HASH TR NAME_REMEMBER_LOCK TR NAME_UNLOCK TR NETWORK_ERROR_CHECK TR OP_MESSAGE TR PACK_FINISH TR PACK_HEADER TR PACK_INIT TR PACK_MESSAGE TR PACK_QUERY TR PARSE_MESSAGE TR PASS_ON_QUERY TR PREFERRED_ADDRESS TR PRINT_MESSAGE TR PRINT_MESSAGE_ERROR TR PROCESS_QUERY TR QUERY TR READ_LOCK TR READ_RR TR READ_UNLOCK TR RECEIVE_INT TR RECEIVE_STRING_N TR RELOCK_NAME TR REMOVE_S TR REPLACE_LOCK TR SEND_INT TR SEND_STRING_N TR SEQ TR SEQNC TR SET_PROGRAM_TYPE TR SIGNAL_ABORT TR STORE_STRING_A TR STORE_STRING_P TR STORE_STRING_R TR S_ALLOC TR S_DEALLOC TR TIME_STAMP TR UPDATE_MCOM TR UPDATE_RR TR UPDATE_ZONE_RR TR WRITE_LOCK TR WRITE_UNLOCK TR ZERO TR ZONE_TR ;C0h RELEASEC.SAV)B?[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]TRANSFER.MAR;12)WANSFER_IN TR ZONE_TRANSFER_OUT .END E*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]TRANSLATE_LOGICAL.C;7+,./@ 4d&-B0123KPWO567[x8`Gt9G@HJ/*$ * C function to translate a logical$ * Bruce Orchard, September 28, 1989 */#include #include #include struct item { short item_buffer_length; short item_code; char *item_buffer_address; int *item_return_length;};4static int translation_attribute = LNM$M_CASE_BLIND;7static $DESCRIPTOR (table_name_des, "LNM$DCL_LOGICAL");char *translate_logical ( char *logical, char *buffer, int buffer_length) { int status; short return_length;d struct dsc$descriptor_s logical_des = {strlen (logical), DSC$K_DTYPE_T, DSC$K_CLASS_S, logical}; struct item items[] = 9 {{buffer_length-1, LNM$_STRING, buffer, &return_length}, {0, 0, 0, 0}};Z status = sys$trnlnm (&translation_attribute, &table_name_des, &logical_des, 0, items); switch (status) { case SS$_NORMAL: buffer[return_length] = 0; return buffer; case SS$_NOLOGNAM: buffer[0] = 0; return 0; } lib$signal (status); abort ();} C*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UNIVERSAL_TIME.C;19+,./@ 4{ \-B0123 KPWO56@o÷7@|8 d9G@HJ/*: * Routines to convert VMS time to and from universal time$ * Bruce Orchard, September 28, 1989 * * Restrictions: = * 1. Summer time cannot start and end in the same month.* * 2. Rules cannot depend on the year. * * Reminder:G * 1. The conversion from local time to universal time is ambiguousH * on the change from summer time to winter time (1:00 to 2:00 in * the US). */#include #include "arith64dir:arith64.h"%#define abs(a) ((a) < 0 ? -(a) : (a))#define LS 100static int have_rules=0;7static char winter_zone_name[LS], summer_zone_name[LS];*static int64 summer_offset, winter_offset;"static int64 start_time, end_time;.static int start_month, start_week, start_day;(static int end_month, end_week, end_day;static int southern_hemisphere;'static int64 SECOND, MINUTE, HOUR, DAY;static int64 ZERO = {0, 0};Nstatic int month_days [12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};void get_time_zone_rules ();7int64 local_time_to_universal_time (int64 local_time) {! int month, day, year, summer; int64 time, start, end; get_time_zone_rules ();, mdate (local_time, &month, &day, &year); start = summer_start (year); end = summer_end (year); if (southern_hemisphere) {A summer = lt6464 (local_time, end) || ge6464 (local_time, start); } else {A summer = ge6464 (local_time, start) && lt6464 (local_time, end); }b return summer ? sub646464 (local_time, summer_offset) : sub646464 (local_time, winter_offset);};int64 universal_time_to_local_time (int64 universal_time) {! int month, day, year, summer; int64 time, start, end; get_time_zone_rules ();0 mdate (universal_time, &month, &day, &year);; start = sub646464 (summer_start (year), winter_offset);7 end = sub646464 (summer_end (year), summer_offset); if (southern_hemisphere) {I summer = lt6464 (universal_time, end) || ge6464 (universal_time, start); } else {I summer = ge6464 (universal_time, start) && lt6464 (universal_time, end); }j return summer ? add646464 (universal_time, summer_offset) : add646464 (universal_time, winter_offset);}void get_time_zone_rules () {T char c_winter_zone[LS], c_summer_zone[LS], c_summer_start[LS], c_summer_end[LS];* char start_week_s[LS], end_week_s[LS];F int winter_offset_m, summer_offset_m, start_time_m, end_time_m, t;G int winter_offset_hm, summer_offset_hm, start_time_hm, end_time_hm; if (have_rules) return;! SECOND = conv3264 (10000000);$ MINUTE = mul326464 (60, SECOND);" HOUR = mul326464 (60, MINUTE); DAY = mul326464 (24, HOUR);C if (!translate_logical ("TZ$WINTER_ZONE", c_winter_zone, LS)) {5 printf ("Cannot translate TZ$WINTER_ZONE\n"); abort (); }C if (!translate_logical ("TZ$SUMMER_ZONE", c_summer_zone, LS)) {5 printf ("Cannot translate TZ$SUMMER_ZONE\n"); abort (); }E if (!translate_logical ("TZ$SUMMER_START", c_summer_start, LS)) {6 printf ("Cannot translate TZ$SUMMER_START\n"); abort (); }A if (!translate_logical ("TZ$SUMMER_END", c_summer_end, LS)) {4 printf ("Cannot translate TZ$SUMMER_END\n"); abort (); }T if (sscanf (c_winter_zone, "%d:%s", &winter_offset_hm, winter_zone_name) != 2) {1 printf ("Cannot parse TZ$WINTER_ZONE\n"); abort (); }T if (sscanf (c_summer_zone, "%d:%s", &summer_offset_hm, summer_zone_name) != 2) {1 printf ("Cannot parse TZ$SUMMER_ZONE\n"); abort (); }{ if (sscanf (c_summer_start, "%d:%[Ll0123456789]:%d:%d", &start_month, start_week_s, &start_day, &start_time_hm) != 4) {2 printf ("Cannot parse TZ$SUMMER_START\n"); abort (); }q if (sscanf (c_summer_end, "%d:%[Ll0123456789]:%d:%d", &end_month, end_week_s, &end_day, &end_time_hm) != 4) {0 printf ("Cannot parse TZ$SUMMER_END\n"); abort (); }3 start_day--; /* Recode to 0 = Sunday, etc. */ end_day --;M start_week = toupper (start_week_s[0] == 'L') ? -1 : atoi (start_week_s);G end_week = toupper (end_week_s[0] == 'L') ? -1 : atoi (end_week_s); t = abs (winter_offset_hm);' winter_offset_m = t/100*60 + t%100;C winter_offset = mul646464 (conv3264 (winter_offset_m), MINUTE);N if (winter_offset_hm < 0) winter_offset = sub646464 (ZERO, winter_offset); t = abs (summer_offset_hm);' summer_offset_m = t/100*60 + t%100;C summer_offset = mul646464 (conv3264 (summer_offset_m), MINUTE);N if (summer_offset_hm < 0) summer_offset = sub646464 (ZERO, summer_offset);< start_time_m = start_time_hm/100*60 + start_time_hm%100;= start_time = mul646464 (conv3264 (start_time_m), MINUTE);6 end_time_m = end_time_hm/100*60 + end_time_hm%100;9 end_time = mul646464 (conv3264 (end_time_m), MINUTE);2 southern_hemisphere = start_month > end_month; have_rules = 1;}/*- * Compute start of summer time in local time */`<( RELEASEC.SAVBC[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UNIVERSAL_TIME.C;19{ int64 summer_start (int year) { int64 start_v;4 int first_change_day, last_change_day, dx, dadd; if (start_week < 0) {4 last_change_day = month_days[start_month-1];B if (start_month == 2 && year%4 == 0) last_change_day = 29; } else {) last_change_day = start_week * 7; }+ first_change_day = last_change_day - 6;? start_v = vdate (start_month, first_change_day, year-1900); dx = day_of_week (start_v); dadd = start_day - dx; if (dadd < 0) dadd += 7;D start_v = add646464 (start_v, mul646464 (conv3264 (dadd), DAY));. start_v = add646464 (start_v, start_time); return start_v;}/*+ * Compute end of summer time in local time */int64 summer_end (int year) { int64 end_v;4 int first_change_day, last_change_day, dx, dadd; if (end_week < 0) {2 last_change_day = month_days[end_month-1];@ if (end_month == 2 && year%4 == 0) last_change_day = 29; } else {' last_change_day = end_week * 7; }+ first_change_day = last_change_day - 6;; end_v = vdate (end_month, first_change_day, year-1900); dx = day_of_week (end_v); dadd = end_day - dx; if (dadd < 0) dadd += 7;@ end_v = add646464 (end_v, mul646464 (conv3264 (dadd), DAY));( end_v = add646464 (end_v, end_time); return end_v;} B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UPDATE_PRIMARY.C;5+,+ ./@ 4rH-B0123 KPWO56 7 Reؒ8 o9G@HJ/*2 * Program to update primary zone from master file * Bruce Orchard, June 9, 1988 */#include "domser.h"#include main (argc, argv) int argc; char *argv[];{ int iarg; struct z_ *z; struct rr_ *rrlist; map_mcom (); init_lock (); set_program_type (); if (!real_time) {* if (cli_present ("DEBUG_LEVEL")) {? debug_level = atoi (cli_get_value ("DEBUG_LEVEL")); } } read_lock (& f -> f_z_lock);K for (z = f -> f_z_head . hp_first; z != 0; z = z -> z_link . lp_next) {& z = abspointer (z, struct z_);/ if (z -> z_type != Z_PRIMARY) continue;r if (!read_rr (abspointer (z -> z_file, char), make_node_into_string (abspointer (z -> z_name_node, char)),: & rrlist, A_SOURCE_PRIMARY_ZONE, z)) continue;2 if (!analyze_authority (rrlist)) continue;# update_zone_rr (rrlist, z);/ if (!z -> z_good) f -> f_n_bad_zone --; z -> z_good = 1; }" read_unlock (& f -> f_z_lock); update_mcom ();} D*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UPDATE_PRIMARY.OPT;4+,4./@ 4(-B0123KPWO56` 7 08/9G@HJdomsdir:update_primary domsshr/share>*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UPDATE_RR.C;11+,7.&/@ 4&%-B0123 KPWO'567 80 o9G@HJ /*@ * Function to update an RR in shared memory from a prototype in * private memory. * Bruce Orchard, June 10, 1988 */#include "domser.h"#include static int new_information;Istatic struct rr_ *make_new_rr (struct rr_ *, struct n_ *, struct rp_ *);Dstatic void update_authority (struct rr_ *, struct rr_ *, long int);>int update_rr (nr, r_new_information, ttl_limit, wild_card_ok)D struct rr_ *nr; /* New RR (private memory) */e int *r_new_information; /* Pointer to return flag indicating RR has new information */G long int ttl_limit; /* TTL limit (internal units) */N int wild_card_ok; /* 1 => will accept * in domain name */{< struct n_ *nn, *name1=0, *name2=0, *rname1=0, *rname2=0,- *path1[MAX_LEVEL], *path2[MAX_LEVEL]; struct rp_ *rp; struct rr_ *rr;& int decrement1=0, decrement2=0, i; unsigned char *sp1, *sp2;t if (debug_level >= 5) printf ("Update RR: %s %d\n", make_printable_name (nr -> rr_name_string), nr -> rr_type);s if (!wild_card_ok && (nr -> rr_name_string)[0] == '*') return 0; /* Only accept wild cards in zone transfers */ new_information = 0; switch (nr -> rr_type) { case RR_CNAME:a find_lock_name (((struct rr_cn_ *) nr) -> rr_cn_name_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_reference_count ++; name_unlock (); break; case RR_MB:c find_lock_name (((struct rr_mb_ *) nr) -> rr_mb_server_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_reference_count ++; name_unlock (); break; case RR_MG:d find_lock_name (((struct rr_mg_ *) nr) -> rr_mg_mailbox_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_reference_count ++; name_unlock (); break; case RR_MINFO:e find_lock_name (((struct rr_mi_ *) nr) -> rr_mi_rmailbox_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_reference_count ++; name_unlock ();e find_lock_name (((struct rr_mi_ *) nr) -> rr_mi_emailbox_string, 1, 0, 1, & name2, 0, path2);- name2 -> n_server_reference_count ++; name_unlock (); break; case RR_MR:d find_lock_name (((struct rr_mr_ *) nr) -> rr_mr_mailbox_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_reference_count ++; name_unlock (); break; case RR_MX:c find_lock_name (((struct rr_mx_ *) nr) -> rr_mx_server_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_reference_count ++; name_unlock (); break; case RR_NS:c find_lock_name (((struct rr_ns_ *) nr) -> rr_ns_server_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_reference_count ++; name_unlock (); break; case RR_PTR:a find_lock_name (((struct rr_pt_ *) nr) -> rr_pt_name_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_re0=8$ RELEASEC.SAV7B>[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UPDATE_RR.C;11C;32&bference_count ++; name_unlock (); break; case RR_SOA:d find_lock_name (((struct rr_sa_ *) nr) -> rr_sa_primary_string, 1, 0, 1, & name1, 0, path1);- name1 -> n_server_reference_count ++; name_unlock ();h find_lock_name (((struct rr_sa_ *) nr) -> rr_sa_responsible_string, 1, 0, 1, & name2, 0, path2);- name2 -> n_server_reference_count ++; name_unlock (); break; }; if (name1 != 0) rname1 = relpointer (name1, struct n_);; if (name2 != 0) rname2 = relpointer (name2, struct n_);? find_lock_name (nr -> rr_name_string, 1, 0, 1, & nn, 0, 0); if (nn -> n_rr == 0) {+ rp = s_alloc (sizeof (struct rp_));1 nn -> n_rr = relpointer (rp, struct rp_); } else {1 rp = abspointer (nn -> n_rr, struct rp_); } switch (nr -> rr_type) { case RR_A:W for (rr = rp -> rr_ad_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {- rr = abspointer (rr, struct rr_);r if (((struct rr_ad_ *) rr) -> rr_ad_address == ((struct rr_ad_ *) nr) -> rr_ad_address) goto found_ad; }& rr = make_new_rr (nr, nn, rp);Z ((struct rr_ad_ *) rr) -> rr_ad_address = ((struct rr_ad_ *) nr) -> rr_ad_address; found_ad:- update_authority (nr, rr, ttl_limit); break; case RR_CNAME:W for (rr = rp -> rr_cn_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {- rr = abspointer (rr, struct rr_);F if (((struct rr_cn_ *) rr) -> rr_cn_name_node == rname1) { decrement1 = 1; goto found_cn; } }& rr = make_new_rr (nr, nn, rp);; ((struct rr_cn_ *) rr) -> rr_cn_name_node = rname1; found_cn:- update_authority (nr, rr, ttl_limit); break; case RR_HINFO:W for (rr = rp -> rr_hi_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {- rr = abspointer (rr, struct rr_);t if (seqnc(abspointer(((struct rr_hi_ *) rr) -> rr_hi_cpu, char), ((struct rr_hi_ *) nr) -> rr_hi_cpu) &&r seqnc(abspointer(((struct rr_hi_ *) rr) -> rr_hi_os, char), ((struct rr_hi_ *) nr) -> rr_hi_os)) { goto found_hi; } }& rr = make_new_rr (nr, nn, rp);c ((struct rr_hi_ *) rr) -> rr_hi_cpu = store_string_r (((struct rr_hi_ *) nr) -> rr_hi_cpu);a ((struct rr_hi_ *) rr) -> rr_hi_os = store_string_r (((struct rr_hi_ *) nr) -> rr_hi_os); found_hi:- update_authority (nr, rr, ttl_limit); break; case RR_MB:W for (rr = rp -> rr_mb_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {- rr = abspointer (rr, struct rr_);H if (((struct rr_mb_ *) rr) -> rr_mb_server_node == rname1) { decrement1 = 1; goto found_mb; } }& rr = make_new_rr (nr, nn, rp);= ((struct rr_mb_ *) rr) -> rr_mb_server_node = rname1; found_mb:- update_authority (nr, rr, ttl_limit); break; case RR_MG:W for (rr = rp -> rr_mg_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {- rr = abspointer (rr, struct rr_);I if (((struct rr_mg_ *) rr) -> rr_mg_mailbox_node == rname1) { decrement1 = 1; goto found_mg; } }& rr = make_new_rr (nr, nn, rp);> ((struct rr_mg_ *) rr) -> rr_mg_mailbox_node = rname1; found_mg:- update_authority (nr, rr, ttl_limit); break; case RR_MINFO:W for (rr = rp -> rr_mi_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {- rr = abspointer (rr, struct rr_);J if (((struct rr_mi_ *) rr) -> rr_mi_rmailbox_node == rname1 &&J ((struct rr_mi_ *) rr) -> rr_mi_emailbox_node == rname2) { decrement1 = 1; decrement2 = 1; goto found_mi; } }& rr = make_new_rr (nr, nn, rp);? ((struct rr_mi_ *) rr) -> rr_mi_rmailbox_node = rname1;? ((struct rr_mi_ *) rr) -> rr_mi_emailbox_node = rname2; found_mi:- update_authority (nr, rr, ttl_limit); break; case RR_MR:W for (rr = rp -> rr_mr_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {- rr = abspointer (rr, struct rr_);I if (((struct rr_mr_ *) rr) -> rr_mr_mailbox_node == rname1) { decrement1 = 1; goto found_mr; } }& rr = make_new_rr (nr, nn, rp);> ((struct rr_mr_ *) rr) -> rr_mr_mailbox_node = rname1; found_mr:- update_authority (nr, rr, ttl_limit); break; case RR_MX:W for (rr = rp -> rr_mx_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {- rr = abspointer (rr, struct rr_);H if (((struct rr_mx_ *) rr) -> rr_mx_server_node == rname1) { decrement1 = 1;t goto found_mx; }t }*& rr = make_new_rr (nr, nn, rp);= ((struct rr_mx_ *) rr) -> rr_mx_server_node = rname1; found_mx:i` ((struct rr_mx_ *) rr) -> rr_mx_preference = ((struct rr_mx_ *) nr) -> rr_mx_preference;- update_authority (nr, rr, ttl_limit);_ break; case RR_NS:nW for (rr = rp -> rr_ns_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) { - rr = abspointer (rr, struct rr_);rH if (((struct rr_ns_ *) rr) -> rr_ns_server_node == rname1) { decrement1 = 1;  goto found_ns; } }i& rr = make_new_rr (nr, nn, rp);= ((struct rr_ns_ *) rr) -> rr_ns_server_node = rname1;* found_ns:1- update_authority (nr, rr, ttl_limit);h break; case RR_PTR:W for (rr = rp -> rr_pt_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) { - rr = abspointer (rr, struct rr_);dF if (((struct rr_pt_ *) rr) -> rr_pt_name_node == rname1) { decrement1 = 1;( goto found_pt; }n }i& rr = make_new_rr (nr, nn, rp);; ((struct rr_pt_ *) rr) -> rr_pt_name_node = rname1;N found_pt:i- update_authority (nr, rr, ttl_limit);a break; case RR_SOA:W for (rr = rp -> rr_sa_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) { - rr = abspointer (rr, struct rr_);eI if (((struct rr_sa_ *) rr) -> rr_sa_primary_node == rname1 &&)M ((struct rr_sa_ *) rr) -> rr_sa_responsible_node == rname2 && c ((struct rr_sa_ *) rr) -> rr_sa_serial == ((struct rr_sa_ *) nr) -> rr_sa_serial) {g decrement1 = 1;  decrement2 = 1;_ goto found_sa; }r }a& rr = make_new_rr (nr, nn, rp);> ((struct rr_sa_ *) rr) -> rr_sa_primary_node = rname1;B ((struct rr_sa_ *) rr) -> rr_sa_responsible_node = rname2;X ((struct rr_sa_ *) rr) -> rr_sa_serial = ((struct rr_sa_ *) nr) -> rr_sa_serial; found_sa:aZ ((struct rr_sa_ *) rr) -> rr_sa_refresh = ((struct rr_sa_ *) nr) -> rr_sa_refresh;V ((struct rr_sa_ *) rr) -> rr_sa_retry = ((struct rr_sa_ *) nr) -> rr_sa_retry;X ((struct rr_sa_ *) rr) -> rr_sa_expire = ((struct rr_sa_ *) nr) -> rr_sa_expire;Z ((struct rr_sa_ *) rr) -> rr_sa_minimum = ((struct rr_sa_ *) nr) -> rr_sa_minimum;- >ώO RELEASEC.SAV7B>[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UPDATE_RR.C;11C;32&rupdate_authority (nr, rr, ttl_limit);  break; case RR_TXT:W for (rr = rp -> rr_tx_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {a- rr = abspointer (rr, struct rr_);_b if (((struct rr_tx_ *) rr) -> rr_tx_ntext != ((struct rr_tx_ *) nr) -> rr_tx_ntext) continue;I for (i = 0; i < ((struct rr_tx_ *) nr) -> rr_tx_ntext; i++) { if (!seq(abspointer(((struct rr_tx_ *) rr) -> rr_tx_text[i], char), ((struct rr_tx_ *) nr) -> rr_tx_text)) goto next_tx; } goto found_tx;) next_tx: ; }_ new_tx: & rr = make_new_rr (nr, nn, rp);E for (i = 0; i < ((struct rr_tx_ *) nr) -> rr_tx_ntext; i++) {no ((struct rr_tx_ *) rr) -> rr_tx_text[i] = store_string_r (((struct rr_tx_ *) nr) -> rr_tx_text[i]);e }tO ((struct rr_tx_ *) rr) -> rr_tx_ntext = ((struct rr_tx_ *) nr) -> rr_tx_ntext; found_tx:u- update_authority (nr, rr, ttl_limit);e break; case RR_WKS:W for (rr = rp -> rr_ks_head . hp_first; rr != 0; rr = rr -> rr_link . lp_next) {c- rr = abspointer (rr, struct rr_); e if (((struct rr_ks_ *) rr) -> rr_ks_address == ((struct rr_ks_ *) nr) -> rr_ks_address &&lg ((struct rr_ks_ *) rr) -> rr_ks_protocol == ((struct rr_ks_ *) nr) -> rr_ks_protocol) {  goto found_ks; } } & rr = make_new_rr (nr, nn, rp);Z ((struct rr_ks_ *) rr) -> rr_ks_address = ((struct rr_ks_ *) nr) -> rr_ks_address;\ ((struct rr_ks_ *) rr) -> rr_ks_protocol = ((struct rr_ks_ *) nr) -> rr_ks_protocol; found_ks: i if (((struct rr_ks_ *) rr) -> rr_ks_high_server != ((struct rr_ks_ *) nr) -> rr_ks_high_server) {_ if (((struct rr_ks_ *) rr) -> rr_ks_server != 0) s_dealloc ((int *) abspointer (((struct rr_ks_ *) rr) -> rr_ks_server, unsigned char)); ((struct rr_ks_ *) rr) -> rr_ks_server = relpointer ((unsigned char *) s_alloc ((((struct rr_ks_ *) nr) -> rr_ks_high_server + 8) / 8), unsigned char);_f ((struct rr_ks_ *) rr) -> rr_ks_high_server = ((struct rr_ks_ *) nr) -> rr_ks_high_server; }5 sp1 = ((struct rr_ks_ *) nr) -> rr_ks_server;uQ sp2 = abspointer (((struct rr_ks_ *) rr) -> rr_ks_server, unsigned char);od for (i = 0; i < (((struct rr_ks_ *) nr) -> rr_ks_high_server + 8) / 8; i++) *sp2++ = *sp1++;- update_authority (nr, rr, ttl_limit);  break; }s name_unlock ();r if (decrement1) {e relock_name (path1, 1); - name1 -> n_server_reference_count --;  name_unlock ();  }  if (decrement2) {c relock_name (path2, 1);)- name2 -> n_server_reference_count --;  name_unlock (); } ) *r_new_information = new_information;r return 1;} +static struct rr_ *make_new_rr (nr, nn, rp)_D struct rr_ *nr; /* New RR (private memory) */P struct n_ *nn; /* Name node (shared memory, absolute) */b struct rp_ *rp; /* Pointer to RR header vector (shared memory, absolute) */{  struct rr_ *rr;_ switch (nr -> rr_type) { case RR_A:. rr = s_alloc (sizeof (struct rr_ad_));? insert_end_s (& rp -> rr_ad_head, rr, & rr -> rr_link);r break; case RR_CNAME:. rr = s_alloc (sizeof (struct rr_cn_));? insert_end_s (& rp -> rr_cn_head, rr, & rr -> rr_link);p break; case RR_HINFO:. rr = s_alloc (sizeof (struct rr_hi_));? insert_end_s (& rp -> rr_hi_head, rr, & rr -> rr_link);  break; case RR_MB: . rr = s_alloc (sizeof (struct rr_mb_));? insert_end_s (& rp -> rr_mb_head, rr, & rr -> rr_link);r break; case RR_MG:_. rr = s_alloc (sizeof (struct rr_mg_));? insert_end_s (& rp -> rr_mg_head, rr, & rr -> rr_link); break; case RR_MINFO:. rr = s_alloc (sizeof (struct rr_mi_));? insert_end_s (& rp -> rr_mi_head, rr, & rr -> rr_link);  break; case RR_MR:t. rr = s_alloc (sizeof (struct rr_mr_));? insert_end_s (& rp -> rr_mr_head, rr, & rr -> rr_link);> break; case RR_MX: . rr = s_alloc (sizeof (struct rr_mx_));? insert_end_s (& rp -> rr_mx_head, rr, & rr -> rr_link); break; case RR_NS:). rr = s_alloc (sizeof (struct rr_ns_));? insert_end_s (& rp -> rr_ns_head, rr, & rr -> rr_link);  break; case RR_PTR:. rr = s_alloc (sizeof (struct rr_pt_));? insert_end_s (& rp -> rr_pt_head, rr, & rr -> rr_link);d break; case RR_SOA:. rr = s_alloc (sizeof (struct rr_sa_));? insert_end_s (& rp -> rr_sa_head, rr, & rr -> rr_link);  break; case RR_TXT:n rr = s_alloc (sizeof (struct rr_tx_) + sizeof (char *) * (((struct rr_tx_ *) nr) -> rr_tx_ntext - 1));? insert_end_s (& rp -> rr_tx_head, rr, & rr -> rr_link);r break; case RR_WKS:. rr = s_alloc (sizeof (struct rr_ks_));? insert_end_s (& rp -> rr_ks_head, rr, & rr -> rr_link);_ break; default: abort ();- }_4 rr -> rr_name_node = relpointer (nn, struct n_);" rr -> rr_type = nr -> rr_type; new_information = 1; return rr;}r0static void update_authority (nr, rr, ttl_limit)I struct rr_ *nr; /* Template RR (private memory) */ M /* Assumed to have only 1 authority */ M struct rr_ *rr; /* New RR (shared memory, absolute) */ G long int ttl_limit; /* TTL limit (internal units) */){  struct a_ *na, *ra;1 struct z_ *z; long int ttl_limit_seconds; + ttl_limit_seconds = ttl_limit / SECOND;_$ na = nr -> rr_a_head . hp_first; if (na == 0) abort (); if (na -> a_ttl > ttl_limit_seconds) na -> a_ttl = ttl_limit_seconds; /* Watch out for leaks of other servers initializers */0 na -> a_expire = na -> a_time + na -> a_ttl;Q for (ra = rr -> rr_a_head . hp_first; ra != 0; ra = ra -> a_link . lp_next) {m( ra = abspointer (ra, struct a_);\ if (na -> a_source_type == A_SOURCE_BOOT && ra -> a_source_type == A_SOURCE_BOOT || na -> a_source_type == A_SOURCE_PRIMARY_ZONE && ra -> a_source_type == A_SOURCE_PRIMARY_ZONE && na -> a_zone == ra -> a_zone || na -> a_source_type == A_SOURCE_SECONDARY_ZONE && ra -> a_source_type == A_SOURCE_SECONDARY_ZONE && na -> a_zone == ra -> a_zone || w na -> a_source_type == A_SOURCE_RESPONSE && ra -> a_source_type == A_SOURCE_RESPONSE) goto authority_found;p } & ra = s_alloc (sizeof (struct a_));9 insert_end_s (& rr -> rr_a_head, ra, & ra -> a_link);r- ra -> a_rr = relpointer (rr, struct rr_); . ra -> a_source_type = na -> a_source_type; ra -> a_zone = na -> a_zone;- z = abspointer (na -> a_zone, struct z_);07 if (na -> a_source_type == A_SOURCE_PRIMARY_ZONE ||o= na -> a_source_type == A_SOURCE_SECONDARY_ZONE ||)3 na -> a_source_type == A_SOURCE_BOOT) { < insert_end_s (& z -> z_a_head, ra, & ra -> a_zlink); } authority_found: ra -> a_present = 1;3 if (na -> a_source_type != A_SOURCE_RESPONSE || . na -> a_expire > ra -> a_expire) {" ra -> a_ttl = na -> a_ttl;( ra -> a_expire = na -> a_expire;( ra -> a_source = na -> a_source;$ ra -> a_time = na -> a_time;. ra -> a_authority = na -> a_authority; }-?= RELEASEC.SAV7B>[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UPDATE_RR.C;11C;32&[%}ra_responsible_node = rname2;X ((struct rr_sa_ *) rr) -> rr_sa_serial = ((struct rr_sa_ *) nr) -> rr_sa_serial; found_sa:aZ ((struct rr_sa_ *) rr) -> rr_sa_refresh = ((struct rr_sa_ *) nr) -> rr_sa_refresh;V ((struct rr_sa_ *) rr) -> rr_sa_retry = ((struct rr_sa_ *) nr) -> rr_sa_retry;X ((struct rr_sa_ *) rr) -> rr_sa_expire = ((struct rr_sa_ *) nr) -> rr_sa_expire;Z ((struct rr_sa_ *) rr) -> rr_sa_minimum = ((struct rr_sa_ *) nr) -> rr_sa_minimum;- B*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]UPDATE_ZONE_RR.C;2+,8<./@ 4R(-B0123 KPWO56r7Seؒ8J o9G@HJ/*E * Function to update RR's for a zone in shared memory from a list in * private memory. * Bruce Orchard, June 9, 1988 */#include "domser.h"#include int update_zone_rr (rrlist, z)R struct rr_ *rrlist; /* Source list of RR's (private memory) */R struct z_ *z; /* Zone entry (shared memory, absolute) */{ struct rr_ *nr; struct a_ *a, *a_next; int new_information;" write_lock (& z -> z_a_lock);M for (a = z -> z_a_head . hp_first; a != 0; a = a -> a_zlink . lp_next) {( a = abspointer (a, struct a_); a -> a_present = 0; }? for (nr = rrlist; nr != 0; nr = nr -> rr_link . lp_next) {7 update_rr (nr, &new_information, 365*DAY, 1); }= for (a = z -> z_a_head . hp_first; a != 0; a = a_next) {( a = abspointer (a, struct a_);* a_next = a -> a_zlink . lp_next;A if (!a -> a_present) delete_authority_holding_zone (a); }$ write_unlock (& z -> z_a_lock);}9*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]VDATE.C;2+,./@ 4Bx-B0123 KPWO56AZ;97V8`Ci9G@HJ/*B * Function to convert a date from month, day, year to VMS format." * Bruce Orchard, January 24, 1989 */#include #include "arith64dir:arith64.h"static int md[2][12] = {5 {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},6 {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};!int64 vdate (int m, int d, int y){ int leap, td, i; static int first=1; struct int64 ks, km, kh, dd; static struct int64 kd; char *p; if (first) { ks = conv3264 (10000000); km = mul326464 (60, ks); kh = mul326464 (60, km); kd = mul326464 (24, kh); first = 0; } leap = y%4 == 0; td = d - 1;, for (i=0; i#include "hdir:network.h"#include #include struct iosb_word_2_struct {# unsigned char word_2_icmp_code; unsigned char word_2_flags;};union iosb_word_2 { long word_2_extended_status;, struct iosb_word_2_struct word_2_struct;}; struct iosb { short iosb_status; short iosb_count;" union iosb_word_2 iosb_word_2;?#define iosb_extended_status iosb_word_2.word_2_extended_statusA#define iosb_icmp_code iosb_word_2.word_2_struct.word_2_icmp_code9#define iosb_flags iosb_word_2.word_2_struct.word_2_flags};&static $DESCRIPTOR (ip_device, "IP:");int zone_transfer_in (z)Q struct z_ *z; /* Zone entry (shared memory, absolute) */{ struct zs_ *zs; struct n_ *tn, *sn; struct rp_ *rp; struct rr_ *rr; t_internet_address ad; struct mh_ mh; struct q_ q; struct hp_ rrlist;J int query_length, response_length, first_message, status, server_fail; short channel;= long int new_refresh, new_retry, new_expire, new_minimum;/ unsigned long int new_serial, delta_serial;A char *query_pointer, response[MAX_MESSAGE], ip_address_s[30]; struct iosb iosb;8 if (debug_level >= 1) printf ("Zone transfer in\n");2 tn = abspointer (z -> z_name_node, struct n_);U for (zs = z -> z_server_head . hp_first; zs != 0; zs = zs -> zs_link . lp_next) { rrlist . hp_first = 0; rrlist . hp_last = 0;) zs = abspointer (zs, struct zs_); sn = zs -> zs_name_node;( sn = abspointer (sn, struct n_);# read_lock (& sn -> n_lock); rp = sn -> n_rr;S if (rp != 0 && abspointer (rp, struct rp_) -> rr_ad_head . hp_first != 0) {) read_unlock (& sn -> n_lock); } else {% initialize_query_nest ();F query (sn, RN_NODE, RR_A, &sn -> n_lock, &server_fail, 1); }# read_lock (& sn -> n_lock); rp = sn -> n_rr;_ if (rp != 0 && preferred_address (& abspointer (rp, struct rp_) -> rr_ad_head, & ad)) {) read_unlock (& sn -> n_lock);= status = sys$assign (&ip_device, &channel, 0, 0);< if (status != SS$_NORMAL) signal_abort (status);i sprintf (ip_address_s, "%d.%d.%d.%d", (ad>>24)&0377, (ad>>16)&0377, (ad>>8)&0377, (ad&0377));N if (debug_level >= 10) printf ("IP add@?9 RELEASEC.SAV: BE[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ZONE_TRANSFER_IN.C;32F0ress: %s\n", ip_address_s); if (network_error_check (sys$qiow (0, channel, TCP$OPEN, &iosb, 0, 0, ip_address_s, DOMAIN_PORT, 0, Active, 0, 60), 0)) goto uerror;_ if (network_error_check (iosb.iosb_status, iosb.iosb_extended_status)) goto uerror; pack_init ();. zero ((char *) & mh, sizeof (mh));% mh . mh_id = ++ query_id;% mh . mh_opcode = Q_QUERY; mh . mh_qdcount = 1; pack_header (& mh);, zero ((char *) & q, sizeof (q));9 q . q_name_node = relpointer (tn, struct n_);( q . q_name_source = RN_NODE; q . q_type = RR_SOA;$ q . q_class = CLASS_NUM; pack_query (& q);: pack_finish (& query_length, & query_pointer);A if (send_int (channel, query_length, 0)) goto terror;U if (send_string_n (channel, query_length, query_pointer, 1)) goto terror;E if (receive_int (channel, &response_length)) goto terror;8 if (response_length > MAX_MESSAGE) abort ();S if (receive_string_n (channel, response_length, response)) goto terror;m if (!parse_message (response, response_length, &mh, A_SOURCE_SECONDARY_ZONE, z, sn)) goto terror;= if (mh . mh_rcode != RCODE_NO_ERROR) goto terror;4 if (mh . mh_id != query_id) goto terror;+ rr = mh . mh_answer . hp_first;% if (rr == 0) goto terror;5 if (rr -> rr_type != RR_SOA) goto terror;@ new_serial = ((struct rr_sa_ *) rr) -> rr_sa_serial;B new_refresh = ((struct rr_sa_ *) rr) -> rr_sa_refresh;> new_retry = ((struct rr_sa_ *) rr) -> rr_sa_retry;@ new_expire = ((struct rr_sa_ *) rr) -> rr_sa_expire;B new_minimum = ((struct rr_sa_ *) rr) -> rr_sa_minimum;( free_incoming_message (&mh);6 delta_serial = new_serial - z -> z_serial;U if (z -> z_good && (delta_serial == 0 || delta_serial >= 020000000000)) {i network_error_check (sys$qiow (0, channel, TCP$CLOSE, &iosb, 0, 0, 0, 0, 0, 0, 0, 0), 0);: /* network_error_check (iosb.iosb_status); */% sys$dassgn (channel);5 z -> z_refresh_seconds = new_refresh;3 z -> z_expire_seconds = new_expire;1 z -> z_retry_seconds = new_retry;X if (debug_level >= 1) printf ("Zone does not need to be transferred\n"); return 1; } pack_init ();. zero ((char *) & mh, sizeof (mh));% mh . mh_id = ++ query_id;% mh . mh_opcode = Q_QUERY; mh . mh_qdcount = 1; pack_header (& mh);, zero ((char *) & q, sizeof (q));9 q . q_name_node = relpointer (tn, struct n_);( q . q_name_source = RN_NODE; q . q_type = Q_AXFR;$ q . q_class = CLASS_NUM; pack_query (& q);A if (send_int (channel, query_length, 0)) goto terror;U if (send_string_n (channel, query_length, query_pointer, 1)) goto terror;" rrlist . hp_first = 0;! rrlist . hp_last = 0; first_message = 1; while (1) {I if (receive_int (channel, &response_length)) goto terror;< if (response_length > MAX_MESSAGE) abort ();W if (receive_string_n (channel, response_length, response)) goto terror;f if (!parse_message (response, response_length, &mh, A_SOURCE_SECONDARY_ZONE, z, sn)) {G printf ("Parse message failed on zone transfer\n");D print_message_error (response, response_length); goto terror; }A if (mh . mh_rcode != RCODE_NO_ERROR) goto terror;/ rr = mh . mh_answer . hp_first;h if (rr == 0) continue; /* This should be an error, but CS has some class = 4 records */E if (!first_message && rr -> rr_type == RR_SOA) break;" first_message = 0;, if (rrlist . hp_last == 0) {, rrlist = mh . mh_answer; } else {L rrlist . hp_last -> lp_next = mh . mh_answer . hp_first;L mh . mh_answer . hp_first -> lp_prev = rrlist . hp_last;@ rrlist . hp_last = mh . mh_answer . hp_last; } }D if (!analyze_authority (rrlist . hp_first)) goto terror;# rr = rrlist . hp_first;@ new_serial = ((struct rr_sa_ *) rr) -> rr_sa_serial;B new_refresh = ((struct rr_sa_ *) rr) -> rr_sa_refresh;> new_retry = ((struct rr_sa_ *) rr) -> rr_sa_retry;@ new_expire = ((struct rr_sa_ *) rr) -> rr_sa_expire;B new_minimum = ((struct rr_sa_ *) rr) -> rr_sa_minimum;e network_error_check (sys$qiow (0, channel, TCP$CLOSE, &iosb, 0, 0, 0, 0, 0, 0, 0, 0), 0);6 /* network_error_check (iosb.iosb_status); */! sys$dassgn (channel);2 update_zone_rr (rrlist . hp_first, z);' z -> z_serial = new_serial;1 z -> z_refresh_seconds = new_refresh;- z -> z_retry_seconds = new_retry;/ z -> z_expire_seconds = new_expire;3 if (!z -> z_good) f -> f_n_bad_zone --; z -> z_good = 1;G if (debug_level >= 1) printf ("Zone transfer succeeded\n");$ free_rr_list (& rrlist); return 1; } else {) read_unlock (& sn -> n_lock); }< continue;" terror:ha network_error_check (sys$qiow (0, channel, TCP$CLOSE, &iosb, 0, 0, 2, 0, 0, 0, 0, 0), 0);o2 /* network_error_check (iosb.iosb_status); */ uerror:b sys$dassgn (channel);e free_rr_list (& rrlist); continue;r };< if (debug_level >= 1) printf ("Zone transfer failed\n"); return 0;o}wd_2 iosb_word_2;? E*[WAISMAN_PROGRAMS_SOURCE.DOMAIN_SERVER.RELEASEC]ZONE_TRANSFER_OUT.C;7+,<./@ 4W-B0123 KPWO 5 6^7`X_%8뙆 o9G@HJ/*" * Function to transfer out a zone * Bruce Orchard, June 23, 1988 */#include "domser.h"#include 4static int pack_send_clean (struct mh_ *, int, int);,int zone_transfer_out (z, channel, query_id)W struct z_ *z; /* Zone to transfer (shared memory, absolute) */R int channel; /* Logical file number of TCP connection */9 int query_id; /* Query number */{ struct mh_ mh; struct q_ q; struct a_ *a; struct rp_ *soa_rp; struct rr_ *rr, *soa_rr=0; struct n_ *n, *soa_n;$ zero ((char *) & mh, sizeof mh);" zero ((char *) & q, sizeof q); mh . mh_id = query_id; mh . mh_qr = 1; mh . mh_aa = 1; mh . mh_qdcount = 1;@ insert_end_p (& mh . mh_query, & q, & q . q_link . lp_next); q . q_name = z -> z_name; q . q_name_source = RN_NODE; q . q_type = Q_AXFR; q . q_class = CLASS_NUM;5 soa_n = abspointer (z -> z_name_node, struct nA n_rr; if (soa_rp != 0) {1 soa_rp = abspointer (soa_rp, struct rp_);1 soa_rr = soa_rp -> rr_sa_head . hp_first; } if (soa_rr == 0) {- mh . mh_rcode = RCODE_SERVER_FAILURE;+ pack_send_clean (& mh, channel, 0); return 0; }- soa_rr = abspointer (soa_rr, struct rr_);" read_lock (& soa_n -> n_lock);- add_rr (& mh, SECTION_ANSWER, soa_rr, 0);$ read_unlock (& soa_n -> n_lock);9 if (!pack_send_clean (& mh, channel, 0)) goto terror;L for (a = z -> z_a_head . hp_first; a != 0; a = a -> a_zlink . lp_next) {& a = abspointer (a, struct a_);0 rr = abspointer (a -> a_rr, struct rr_);7 n = abspointer (rr -> rr_name_node, struct n_);# if (rr == soa_rr) continue;" read_lock (& n -> n_lock);, add_rr (&mh, SECTION_ANSWER, rr, 0);$ read_unlock (& n -> n_lock);= if (!pack_send_clean (& mh, channel, 0)) goto terror; }" read_lock (& soa_n -> n_lock);- add_rr (& mh, SECTION_ANSWER, soa_rr, 0);$ read_unlock (& soa_n -> n_lock);9 if (!pack_send_clean (& mh, channel, 1)) goto terror; return 1;terror: return 0;}.static int pack_send_clean (mh, channel, push) struct mh_ *mh; int channel; int push;{- int response_length, first_a_flag, error; char *response_message; struct a_ *a, *a_next; struct rr_ *rr, *rr_next;* if (mh -> mh_answer . hp_first != 0) {? pack_message (mh, &response_message, &response_length);" if (response_length > 0) {; error = send_int (channel, response_length, 0);( if (error != 0) goto terror;U error = send_string_n (channel, response_length, response_message, push);( if (error != 0) goto terror; } }B for (rr = mh -> mh_answer . hp_first; rr != 0; rr = rr_next) {B for (a = rr -> rr_a_head . hp_first; a != 0; a = a_next) {+ a_next = a -> a_link . lp_next; afree (a); }* rr_next = rr -> rr_link . lp_next; afree (rr); }# mh -> mh_answer . hp_first = 0;" mh -> mh_answer . hp_last = 0; return 1;terror: return 0;}Bi  bu qq|dESI;37 6q/!YvWr24i; :n6]r7aj ~J']*?E|hp-{| x;E^=s|Y/C[RyU;le&3{6 F>,pS}p\ijo[I}/*6UZ:f@^9F[sfL)mT.PC*G:p +@z--#Pa C:eJMUoXOri67<1o._wRwuS+- -Z4@ ~u_'t)SVQK8 touucs9 N\zD}:~_1qJzVr (nAR"I.`>qmf wuT+fU,}S"HFH+ +Bxc'`A*&&+hK_hlw!j" zQ69,pn&mA'ev`![zDPg-L<"q8Er u){I? ; =M9wPy;r+zCG:NCp?,;$)Q YWD F-v@XZ75^$O5.UK W KozD={:_}Lynv*U`MR, '(  |Nj´=җE6S1YDqsbmjAhbD/u< *iG%j:VR3x(<M0Tc?Po(dXHl) ezO.=coA9jJ9^\c2z,ejID10%c7 gdOh`;l366.Xq_ Vb,*{y,+i\ !L}w}wPBvw;spL$+.e x*m0>}RpiedylvgZD,#" p`-SN&6#X ConC2z+,.61P$[%Gq4 z\p28Uq(It Z5d;60Gs1HKsO_tTACa+0e[z,jPT[ XW!m^3\&L$+mEuoUt_ KG0f:^>>6(IT`t>HJNlu6s&Y %Jz<.],u:e^gxBHEeT6 v/`U%Wa#]4KH`bp}8MN B|^f-*j!R7hD%[*nn/eXQ+@y w/m!sO36h&'u{ x<Gd) c4g?Ksr  DyGK.65xSmS149o4=}[q_u:1v*N}uG8[8Jfl#r ~Nnp;V[;+ΰCum_ǵMd\E,HLv#|(l@2;V{3`g9Cy\ z`.` AFX-?&;*t6\A_"ocB+S%-*&% 8H0Gg.{!4~dr#LZf{Oh9(t|SRE!d~,@ Gylw~q7MFfYv#)ilZ-[3]H>?gSY]djHUYX$Bmi94>] &88el LJ ?:^'\Bth C8?bklTM.Wu-d&a9Iz$_jV m<5GvWJhnN3&*OYS?XW%6Mn|,zYHaB bS&Ue#pU"X$&J ih i `?-AN&'DX!}eYN>G,0T61D6=gUGJob^:WABC)O=yoy"@EJZ5>^{K Nt#c:^wy^_UGq}zZc" `h)p2R]l*r XViwkyWXY0fi K8WN$bFAE5q'9r@v}^v_T1,BvISr^qe@\r"k6[J,+Ziu % M575H@o\sR@BZWfjp{|^PwoT RU`7A!#itT4Pz 5lFD:uI4TxIX9^l^'!i)}myamfu>it8SeZYx I!`6 1|1tLfq_Ru&$oH LG'CAjKS7;g@,5a=A\ )*1\@y.cbH@ `_&bO"fs*zH6XD&x4]7QEF)!Dri\;-Zq6nwEJNAz(B=sWg4lsv6|u{,qvXop=>Ke C =  +]b^DQ4g QlQjH\] ?1OK =vA'k Cj*PP:{CE*GIVtby_bwbX?x3hicZYc1GV3dF#R~,5J@}6`82F-zijDI `Y!Oh92 ~Asp2A\9|zP, )KPy2Gogf\x^0L/VNJxG\IAXXFBUDyh: ;8F NV!/t^d7QTWc T^=T*4+L_MHB(efDG# o+0p7q14BG~#lTy)U l jgn|l]L F ' ZdoT-v *w.#[4@LLMRH "]|L4cJ.%6he;N$UX@vC{ov=0?H@ks9w%]>DXa hk(_I~ j+z<>r<(5[U Vh@]IL4ONQli4[]D ^D,u? ~-->8P IM,X;33!']WTsyabzAZ~XN00f} :~.,45vv79][ *S}+CS.!oF_ЊMC`&Rll f6T($|\i^LZAXRNP&c9QPUub_;[yc,i3kIw@]A.o{RX|9Gt UMB\f;|Z3b<q%$% 1ኚ,|)^&p<,1a,vsX8Z(NibWWJ?p [i`X;sx$\] 8\y*!2gf8b uyQLb@851N[m2 Lnl5] eg]KAL f( +m?1 q^,.dsOj&*{i]+/G9= bg8*j;-ib$|} @"ltv=kw^+m[b&sl69|fJE7alTo_}|+I;7(A~9X4kjq.b%^S=%P^T QM+Z #HXiX*"G-h1K<)-RgK*|3/iZH}N?ltn5k%$4}NP< Lc{!W,$0x@9jn(|fZ+F.+ 3 xbLYTRD-vq 1uPP|EKsP3 2SG}y_T~?pRJ~>obO vRW^ ^J2#wO;wu&RT[T>NI.Wk4Zl k_ \E)'.t8rgoaA,L]\2tc'\%.N^])"Kv>XPJG7sHLC@FE&,d{R(CCPAoyI =Bq9vz/-0A4?iLS5J=;Q }Mpt| xC#:0/x|e`N #h<()i` 0iiXIHhd# 3.f(/&NY5uEPB!6S4 6!s/mv)>Zr< OQ)o$j} (!%=_e[ҵ[_c^7 jFoI;M?{A=iaivMH6l5rXt^,5274> d1 9mJFYIC]42PmnuiaP*3#@-X``Loxy"S dsY2V-^=Q\Y>C\JM^ $ 3:B&U 8 <-TCW |1t|jB i%Nw@mGd&+sn= ?t Z=SKwFn{O,N= }MxRP1,K?8.p>:'rh$fT1F #ph`H,M+V^"W55H,;L>PfpkP/@F fcG.K|1Or NBA*g  ( %[G7|iK4;]Yw2%,#G>3s> ;LD#:sKA9cn52dyX@|Gm/9<,0%2Ik.pwk_AP vV g7YbXU/9F#'GZVC>jS%2H51 ckB TyI0Qx'hQ]9Ws{`&Uewil^HJSH&%%HDXY^5$U~pl8TxcXUjWAfh*_&iVKF:/M;x[ % ]M~*2r6 EqbJMw b@y`?cm]|%<&AyrZH Crg0#6fdDduejck]xs46z/[g=iMXu-`)1)`Zd,Aaq;D 1$e{Q!5Wb(E 2 .i6hzycX [X.m`mp@O y '=kE$'8PzolGe:F K{AcH´o]1a0rrkk/eUld+rV^zR~oA 5| ym*|1x@H = G__ c  ! ;?w[up 0d]{av3x@!ZBw[/~U<'Rmr4-u76ZE:qTn /sfuerVfZ^H/~%+?vt$?f&rH)@ .DRR'4ie?rt:%6:b{"j]m=osV> 9t&F3MO{|8;5l$-M7C`=iX j~an.aIYW2rQjpyIcgm$Z9%=Jzl;uUP0Iy|Cf}ZX /hlI;5Aj|\P7z'TU WRh~{K@i+Tf$! cFk,!'guffJ -v VE:,-[0O]fji5/~OZf VIxu sxrJd zSt OAnl,,AbB:? 8AY'qBt]f_?C=(lY}H;41t2p DI-03 :#Aqry{1Gp1gw4g|^r5d_};]Z)L6;#TygUjC'N$gjVUz&0$.Z=xG*i ogkT_Z2%`1e@)o!{L<73]AD{!AAN0-'hvKX@[9Ik%s9w9+:k~~0 =VJ7O^NEA3f|ioY =[YTQHWp_vuIq|^=h +R7@SQ (5K/ "t#zuWS5LA+_.8fms6^V&?C6|y!{wTBi)kYY+s2 VbGbze_eK@IGT5}8tf}YbG}4J:0r_ eJ,~;@"pfm2T}uSDv~z&|f(pAYsZbvXyE1(k`QFGwXa `!hY* In=f1fAPy$q2H;v#lXQ !qrs>&J< ZZ(> HQx^@au0:WB>,DmWQ0-xXerj;?)3Wyk7e>9Wɖ+uJ/{zXHdW3aLoV]힨} VWm_7PFka88fpz |:}7F&9V~tKQ_z4|&+* |U_2SyEkD6m75d2Hl{Q[~p-WDJo[@y,?akdcz`yuGL\2~]!h|%{"gJMge8N?kPg]&kDRFr`5Rk8Cqs17=<H3r&fX .i7lm:3]SxBXJ0}o`]B;p_|n19 H7q+#] OjsdMWW'lt5CA  SU.~D 5u2~,/2QE!wG0Tbq\`z/c8Bp_Xv|4n->,K[OR- vZ>2tj(fr#*&?m5R|w=:!t|io}-\0 kEUW"Zj6mC#[^b Q6 1rpw}$4BO5d%R)nG?n5qJm<"9",@b$^HtEbLe0KD1 5RE.w4$|d,.RS]2Ns$[0gF](1;\G'm&cUGOr9c&0!{sZ$dhS )_GF]tR>цݵ@sKJ7X 0379#[#gl>+eB_VDd=?Qh>DXsXe F7s'4p@Iyfb@rjH"f 6OvkNWw7 ^m gN6_ZLGNJ?~yc|j~tD0|.!Ru'omUm>pY~8[K.}F HD'8xhr [f$ yU,dgxdoF-t(z)9=+*-vdDa/zh>VIdBx(E212@W`Ax^#*r5go]kS(Ajpu;w W4Mg<'!A6, *G#7wL<|&2c]O\O-Y?%bIZ ^:0BQIQaT1b_,7'C-z]vCn;KL {mjAiA>al8&Z-(Vztmo+cj%v^ZM(!$XtRrJ7 (,"~Z =Utb&7{E Petzv#S.G#8}Qs`Z4kg*2^1U|T{I(hL1Vm'3/B:~+zB;BF},/4iqNI+2['n{+J4B/ 8p2=s YCWR30y x6z7d!P K^e5 h|4\5(-CdnmwiLY7$K>BK9qjmMYML 0BaWW>(iLfb0GYhD\-Wtqm98MOxv{I474.,j>}b80mfg!fU+k`3C?"E[Tb-hYJGYwQezU_@>OG |}u!Wn`j ;Zm+EBSL@BtAUQ ?nAolsz'w3t@c EqQJ[z[ZLv'avP_Atci_9 ^RhR][D\KLf D@dFA cRH jeWDigJZFi3ى})t3U7jx|g9amjl1 qb~c5sedm*g{{>iCG_ero 1 )tr)(z&(ew07bug_level >= 10) printf ("IP add