1 /* misc. universal things
2 * Copyright (C) 1998-2001 D. Hugh Redelmeier.
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * RCSID $Id: defs.c,v 1.20 2002/03/09 20:45:37 dhr Exp $
21 #include <sys/types.h>
25 #include "constants.h"
28 #include "whack.h" /* for RC_LOG_SERIOUS */
30 const chunk_t empty_chunk = { NULL, 0 };
33 all_zero(const unsigned char *m, size_t len)
37 for (i = 0; i != len; i++)
43 /* Convert MP_INT to network form (binary octets, big-endian).
44 * We do the malloc; caller must eventually do free.
47 mpz_to_n(const MP_INT *mp, size_t bytes)
54 r.ptr = alloc_bytes(r.len, "host representation of large integer");
61 for (i = r.len-1; i >= 0; i--)
63 r.ptr[i] = mpz_mdivmod_ui(&temp2, NULL, &temp1, 1 << BITS_PER_BYTE);
64 mpz_set(&temp1, &temp2);
67 passert(mpz_sgn(&temp1) == 0); /* we must have done all the bits */
74 /* Convert network form (binary bytes, big-endian) to MP_INT.
75 * The *mp must not be previously mpz_inited.
78 n_to_mpz(MP_INT *mp, const u_char *nbytes, size_t nlen)
82 mpz_init_set_ui(mp, 0);
84 for (i = 0; i != nlen; i++)
86 mpz_mul_ui(mp, mp, 1 << BITS_PER_BYTE);
87 mpz_add_ui(mp, mp, nbytes[i]);
94 * LEAK_DETECTIVE puts a wrapper around each allocation and maintains
95 * a list of live ones. If a dead one is freed, an assertion MIGHT fail.
96 * If the live list is currupted, that will often be detected.
97 * In the end, report_leaks() is called, and the names of remaining
98 * live allocations are printed. At the moment, it is hoped, not that
99 * the list is empty, but that there will be no surprises.
102 * - "struct iface" and "device name" (for "discovered" net interfaces)
103 * - "struct event in event_schedule()" (events not associated with states)
104 * - "Pluto lock name" (one only, needed until end -- why bother?)
107 #ifdef LEAK_DETECTIVE
109 /* this magic number is 3671129837 decimal (623837458 complemented) */
110 #define LEAK_MAGIC 0xDAD0FEEDul
115 union mhdr *older, *newer;
118 unsigned long junk; /* force maximal alignment */
121 static union mhdr *allocs = NULL;
123 void *alloc_bytes(size_t size, const char *name)
125 union mhdr *p = malloc(sizeof(union mhdr) + size);
128 exit_log("unable to malloc %lu bytes for %s",
129 (unsigned long) size, name);
136 p->i.magic = LEAK_MAGIC;
138 memset(p+1, '\0', size);
143 clone_bytes(const void *orig, size_t size, const char *name)
145 void *p = alloc_bytes(size, name);
147 memcpy(p, orig, size);
156 passert(ptr != NULL);
157 p = ((union mhdr *)ptr) - 1;
158 passert(p->i.magic == LEAK_MAGIC);
159 if (p->i.older != NULL)
161 passert(p->i.older->i.newer == p);
162 p->i.older->i.newer = p->i.newer;
164 if (p->i.newer == NULL)
166 passert(p == allocs);
171 passert(p->i.newer->i.older == p);
172 p->i.newer->i.older = p->i.older;
174 p->i.magic = ~LEAK_MAGIC;
188 passert(p->i.magic == LEAK_MAGIC);
189 passert(pprev == p->i.newer);
193 if (p == NULL || pprev->i.name != p->i.name)
196 log("leak: %lu * %s", n, pprev->i.name);
198 log("leak: %s", pprev->i.name);
204 #else /* !LEAK_DETECTIVE */
206 void *alloc_bytes(size_t size, const char *name)
208 void *p = malloc(size);
211 exit_log("unable to malloc %lu bytes for %s",
212 (unsigned long) size, name);
213 memset(p, '\0', size);
217 void *clone_bytes(const void *orig, size_t size, const char *name)
219 void *p = malloc(size);
222 exit_log("unable to malloc %lu bytes for %s",
223 (unsigned long) size, name);
224 memcpy(p, orig, size);
227 #endif /* !LEAK_DETECTIVE */
230 /* Names of the months */
232 static const char* months[] = {
233 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
234 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
239 * Display a date either in local or UTC time
242 timetoa(const time_t *time, bool utc)
244 static char buf[TIMETOA_BUF];
246 if (*time == UNDEFINED_TIME)
247 sprintf(buf, "--- -- --:--:--%s----", (utc)?" UTC ":" ");
250 struct tm *t = (utc)? gmtime(time) : localtime(time);
252 sprintf(buf, "%s %02d %02d:%02d:%02d%s%04d",
253 months[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
254 (utc)?" UTC ":" ", t->tm_year + 1900
260 /* checks if the expiration date has been reached and
261 * warns during the warning_interval of the imminent
262 * expiry. strict=TRUE declares a fatal error,
263 * strict=FALSE issues a warning upon expiry.
266 check_expiry(time_t expiration_date, int warning_interval, bool strict)
271 if (expiration_date == UNDEFINED_TIME)
272 return "ok (expires never)";
274 /* determine the current time */
277 time_left = (expiration_date - now);
279 return strict? "fatal (expired)" : "warning (expired)";
281 if (time_left > 86400*warning_interval)
284 static char buf[35]; /* temporary storage */
285 const char* unit = "second";
287 if (time_left > 86400)
292 else if (time_left > 3600)
297 else if (time_left > 60)
302 snprintf(buf, 35, "warning (expires in %d %s%s)", time_left,
303 unit, (time_left == 1)?"":"s");