1Index: smallapp/unbound-host.c
2===================================================================
3--- smallapp/unbound-host.c	(revision 2115)
4+++ smallapp/unbound-host.c	(working copy)
5@@ -62,9 +62,18 @@
6 #include "libunbound/unbound.h"
7 #include <ldns/ldns.h>
8 
9+/** status variable ala nagios */
10+#define FINAL_STATUS_OK		0
11+#define FINAL_STATUS_WARNING	1
12+#define FINAL_STATUS_CRITICAL	2
13+#define FINAL_STATUS_UNKNOWN	3
14+
15 /** verbosity for unbound-host app */
16 static int verb = 0;
17 
18+/** variable to determine final output */
19+static int final_status = FINAL_STATUS_UNKNOWN;
20+
21 /** Give unbound-host usage, and exit (1). */
22 static void
23 usage()
24@@ -93,7 +102,7 @@
25 	printf("Version %s\n", PACKAGE_VERSION);
26 	printf("BSD licensed, see LICENSE in source package for details.\n");
27 	printf("Report bugs to %s\n", PACKAGE_BUGREPORT);
28-	exit(1);
29+	exit(FINAL_STATUS_UNKNOWN);
30 }
31 
32 /** determine if str is ip4 and put into reverse lookup format */
33@@ -138,7 +147,7 @@
34 	*res = strdup(buf);
35 	if(!*res) {
36 		fprintf(stderr, "error: out of memory\n");
37-		exit(1);
38+		exit(FINAL_STATUS_UNKNOWN);
39 	}
40 	return 1;
41 }
42@@ -158,7 +167,7 @@
43 	}
44 	if(!res) {
45 		fprintf(stderr, "error: out of memory\n");
46-		exit(1);
47+		exit(FINAL_STATUS_UNKNOWN);
48 	}
49 	return res;
50 }
51@@ -172,7 +181,7 @@
52 		if(r == 0 && strcasecmp(t, "TYPE0") != 0 && 
53 			strcmp(t, "") != 0) {
54 			fprintf(stderr, "error unknown type %s\n", t);
55-			exit(1);
56+			exit(FINAL_STATUS_UNKNOWN);
57 		}
58 		return r;
59 	}
60@@ -191,7 +200,7 @@
61 		if(r == 0 && strcasecmp(c, "CLASS0") != 0 && 
62 			strcmp(c, "") != 0) {
63 			fprintf(stderr, "error unknown class %s\n", c);
64-			exit(1);
65+			exit(FINAL_STATUS_UNKNOWN);
66 		}
67 		return r;
68 	}
69@@ -207,6 +216,19 @@
70 	return "(insecure)";
71 }
72 
73+/** update the final status for the exit code */
74+void
75+update_final_status(struct ub_result* result)
76+{
77+	if (final_status == FINAL_STATUS_UNKNOWN || final_status == FINAL_STATUS_OK) {
78+		if (result->secure) final_status = FINAL_STATUS_OK;
79+		else if (result->bogus) final_status = FINAL_STATUS_CRITICAL;
80+		else final_status = FINAL_STATUS_WARNING;
81+	}
82+	else if (final_status == FINAL_STATUS_WARNING && result->bogus)
83+		final_status = FINAL_STATUS_CRITICAL;
84+}
85+
86 /** nice string for type */
87 static void
88 pretty_type(char* s, size_t len, int t)
89@@ -353,7 +375,7 @@
90 				} else {
91 					fprintf(stderr, "could not parse "
92 						"reply packet to ANY query\n");
93-					exit(1);
94+					exit(FINAL_STATUS_UNKNOWN);
95 				}
96 				ldns_pkt_free(p);
97 
98@@ -388,9 +410,10 @@
99 	ret = ub_resolve(ctx, q, t, c, &result);
100 	if(ret != 0) {
101 		fprintf(stderr, "resolve error: %s\n", ub_strerror(ret));
102-		exit(1);
103+		exit(FINAL_STATUS_UNKNOWN);
104 	}
105 	pretty_output(q, t, c, result, docname);
106+	update_final_status(result);
107 	ret = result->nxdomain;
108 	ub_resolve_free(result);
109 	return ret;
110@@ -427,7 +450,7 @@
111 {
112 	if(r != 0) {
113 		fprintf(stderr, "error: %s\n", ub_strerror(r));
114-		exit(1);
115+		exit(FINAL_STATUS_UNKNOWN);
116 	}
117 }
118 
119@@ -448,7 +471,7 @@
120 	ctx = ub_ctx_create();
121 	if(!ctx) {
122 		fprintf(stderr, "error: out of memory\n");
123-		exit(1);
124+		exit(FINAL_STATUS_UNKNOWN);
125 	}
126 
127 	/* parse the options */
128@@ -509,5 +532,5 @@
129 		usage();
130 
131 	lookup(ctx, argv[0], qtype, qclass);
132-	return 0;
133+	return final_status;
134 }
135