1 /* $NetBSD: zkt-soaserial.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $ */
3 /*****************************************************************
5 ** @(#) zkt-soaserial.c (c) Oct 2007 Holger Zuleger hznet.de
7 ** A small utility to print out the (unixtime) soa serial
8 ** number in a human readable form
10 ** Copyright (c) Oct 2007, Holger Zuleger HZnet. All rights reserved.
12 ** This software is open source.
14 ** Redistribution and use in source and binary forms, with or without
15 ** modification, are permitted provided that the following conditions
18 ** Redistributions of source code must retain the above copyright notice,
19 ** this list of conditions and the following disclaimer.
21 ** Redistributions in binary form must reproduce the above copyright notice,
22 ** this list of conditions and the following disclaimer in the documentation
23 ** and/or other materials provided with the distribution.
25 ** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
26 ** be used to endorse or promote products derived from this software without
27 ** specific prior written permission.
29 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32 ** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
33 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 ** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 ** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 ** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 ** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 ** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 ** POSSIBILITY OF SUCH DAMAGE.
41 *****************************************************************/
44 # include <sys/types.h>
53 # include "config_zkt.h"
55 static const char *progname
;
57 static char *timestr (time_t sec
);
58 static int read_serial_fromfile (const char *fname
, unsigned long *serial
);
59 static void printserial (const char *fname
, unsigned long serial
);
60 static void usage (const char *msg
);
62 /*****************************************************************
64 *****************************************************************/
65 static char *timestr (time_t sec
)
68 static char timestr
[31+1]; /* 27+1 should be enough */
70 #if defined(HAVE_STRFTIME) && HAVE_STRFTIME
72 strftime (timestr
, sizeof (timestr
), "%b %d %Y %T %z", t
);
74 static char *mstr
[] = {
75 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
76 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
81 s
= abs (t
->tm_gmtoff
);
82 h
= t
->tm_gmtoff
/ 3600;
83 s
= t
->tm_gmtoff
% 3600;
84 snprintf (timestr
, sizeof (timestr
), "%s %2d %4d %02d:%02d:%02d %c%02d%02d",
85 mstr
[t
->tm_mon
], t
->tm_mday
, t
->tm_year
+ 1900,
86 t
->tm_hour
, t
->tm_min
, t
->tm_sec
,
87 t
->tm_gmtoff
< 0 ? '-': '+',
95 /****************************************************************
97 ** int read_serial_fromfile (filename)
99 ** This function depends on a special syntax formating the
100 ** SOA record in the zone file!!
102 ** To match the SOA record, the SOA RR must be formatted
104 ** @ IN SOA <master.fq.dn.> <hostmaster.fq.dn.> (
105 ** <SPACEes or TABs> 1234567890; serial number
106 ** <SPACEes or TABs> 86400 ; other values
109 ****************************************************************/
110 static int read_serial_fromfile (const char *fname
, unsigned long *serial
)
118 if ( (fp
= fopen (fname
, "r")) == NULL
)
119 return -1; /* file not found */
121 /* read until the line matches the beginning of a soa record ... */
123 while ( !soafound
&& fgets (buf
, sizeof buf
, fp
) )
125 if ( sscanf (buf
, "%*s %*d IN SOA %255s %*s (\n", master
) == 1 )
127 else if ( sscanf (buf
, "%*s IN SOA %255s %*s (\n", master
) == 1 )
132 return -2; /* no zone file (soa not found) */
134 /* move forward until any non ws is reached */
135 while ( (c
= getc (fp
)) != EOF
&& isspace (c
) )
137 ungetc (c
, fp
); /* pushback the non ws */
139 *serial
= 0L; /* read in the current serial number */
140 if ( fscanf (fp
, "%lu", serial
) != 1 ) /* try to get serial no */
141 return -3; /* no serial number found */
148 /*****************************************************************
150 *****************************************************************/
151 static void printserial (const char *fname
, unsigned long serial
)
153 if ( fname
&& *fname
)
154 printf ("%-30s\t", fname
);
156 printf ("%10lu", serial
);
158 /* try to guess the soa serial format */
159 if ( serial
< 1136070000L ) /* plain integer (this is 2006-1-1 00:00 in unixtime format) */
161 else if ( serial
> 2006010100L ) /* date format */
173 printf ("\t%d-%02d-%02d Version %02d", y
, m
, d
, v
);
176 printf ("\t%s\n", timestr (serial
) );
181 /*****************************************************************
183 *****************************************************************/
184 static void usage (const char *msg
)
187 fprintf (stderr
, "%s\n", msg
);
188 fprintf (stderr
, "usage: %s {-s serial | signed_zonefile [...]}\n", progname
);
193 /*****************************************************************
195 *****************************************************************/
196 int main (int argc
, char *argv
[])
198 unsigned long serial
;
205 if ( argv
[1][0] == '-' )
207 if ( argv
[1][1] != 's' )
208 usage ("illegal option");
211 usage ("Option -s requires an argument");
213 serial
= atol (argv
[2]);
214 printserial ("", serial
);
218 if ( (read_serial_fromfile (*++argv
, &serial
)) != 0 )
219 fprintf (stderr
, "couldn't read serial number from file %s\n", *argv
);
221 printserial (*argv
, serial
);