The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
radwho.c
Go to the documentation of this file.
1 /*@-skipposixheaders@*/
2 /*
3  * radwho.c Show who is logged in on the terminal servers.
4  *
5  * Version: $Id: d52e7bf28a84139b6a990018cd2c45aedef358e3 $
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  *
21  * @copyright 2000,2006 The FreeRADIUS server project
22  * @copyright 2000 Alan DeKok (aland@freeradius.org)
23  */
24 
25 RCSID("$Id: d52e7bf28a84139b6a990018cd2c45aedef358e3 $")
26 
27 #include <freeradius-devel/server/base.h>
28 #include <freeradius-devel/server/cf_parse.h>
29 #include <freeradius-devel/server/radutmp.h>
30 #include <freeradius-devel/server/sysutmp.h>
31 
32 #include <freeradius-devel/util/conf.h>
33 
34 #include <pwd.h>
35 #include <sys/stat.h>
36 #include <ctype.h>
37 
38 /*
39  * Header above output and format.
40  */
41 static char const *hdr1 =
42 "Login Name What TTY When From Location";
43 
44 static char const *hdr2 =
45 "Login Port What When From Location";
46 
47 static char const *eol = "\n";
48 static int showname = -1;
49 static int showptype = 0;
50 static int showcid = 0;
51 static char const *progname = "radwho";
52 
53 static char const *radutmp_file = NULL;
54 
55 static struct radutmp_config_t {
56  char const *radutmp_fn;
58 
59 static const conf_parser_t module_config[] = {
62 };
63 
64 /*
65  * Get fullname of a user.
66  */
67 static char *fullname(char *username)
68 {
69 #ifdef HAVE_PWD_H
70  struct passwd *pwd;
71  char *s;
72 
73  if ((pwd = getpwnam(username)) != NULL) {
74  if ((s = strchr(pwd->pw_gecos, ',')) != NULL) *s = 0;
75  return pwd->pw_gecos;
76  }
77 #endif
78 
79  return username;
80 }
81 
82 /*
83  * Return protocol type.
84  */
85 static char const *proto(int id, int porttype)
86 {
87  static char buf[8];
88 
89  if (showptype) {
90  if (!strchr("ASITX", porttype))
91  porttype = ' ';
92  if (id == 'S')
93  snprintf(buf, sizeof(buf), "SLP %c", porttype);
94  else if (id == 'P')
95  snprintf(buf, sizeof(buf), "PPP %c", porttype);
96  else
97  snprintf(buf, sizeof(buf), "shl %c", porttype);
98  return buf;
99  }
100  if (id == 'S') return "SLIP";
101  if (id == 'P') return "PPP";
102  return "shell";
103 }
104 
105 /*
106  * Return a time in the form day hh:mm
107  */
108 static char *dotime(time_t t)
109 {
110  /*
111  * man 3 ctime
112  * The caller must provide the output buffer buf
113  * (which must be at least 26 characters long)
114  */
115  static char buff[26];
116  char *s = ctime_r(&t, buff);
117 
118  if (showname) {
119  strlcpy(s + 4, s + 11, 6);
120  s[9] = 0;
121  } else {
122  strlcpy(s + 4, s + 8, 9);
123  s[12] = 0;
124  }
125 
126  return s;
127 }
128 
129 
130 /*
131  * Print address of NAS.
132  */
133 static char const *hostname(char *buf, size_t buflen, uint32_t ipaddr)
134 {
135  /*
136  * WTF is this code for?
137  */
138  if (ipaddr == 0 || ipaddr == (uint32_t)-1 || ipaddr == (uint32_t)-2)
139  return "";
140 
141  return inet_ntop(AF_INET, &ipaddr, buf, buflen);
142 
143 }
144 
145 
146 /*
147  * Print usage message and exit.
148  */
149 static NEVER_RETURNS void usage(int status)
150 {
151  FILE *output = status?stderr:stdout;
152 
153  fprintf(output, "Usage: radwho [-d raddb] [-cfihnprRsSZ] [-N nas] [-P nas_port] [-u user] [-U user]\n");
154  fprintf(output, " -c Show caller ID, if available.\n");
155  fprintf(output, " -d Set the raddb directory (default is %s).\n", RADIUS_DIR);
156  fprintf(output, " -F <file> Use radutmp <file>.\n");
157  fprintf(output, " -i Show session ID.\n");
158  fprintf(output, " -n No full name.\n");
159  fprintf(output, " -N <nas-ip-address> Show entries matching the given NAS IP address.\n");
160  fprintf(output, " -p Show port type.\n");
161  fprintf(output, " -P <port> Show entries matching the given nas port.\n");
162  fprintf(output, " -r Print output as raw comma-delimited data.\n");
163  fprintf(output, " -R Print output as RADIUS attributes and values.\n");
164  fprintf(output, " includes ALL information from the radutmp record.\n");
165  fprintf(output, " -s Show full name.\n");
166  fprintf(output, " -S Hide shell users from radius.\n");
167  fprintf(output, " -u <user> Show entries matching the given user.\n");
168  fprintf(output, " -U <user> Like -u, but case-sensitive.\n");
169  fprintf(output, " -Z Include accounting stop information in radius output. Requires -R.\n");
170  fr_exit_now(status);
171 }
172 
173 /**
174  *
175  * @hidecallgraph
176  */
177 int main(int argc, char **argv)
178 {
179  CONF_SECTION *maincs, *cs;
180  FILE *fp;
181  struct radutmp rt;
182  char othername[256];
183  char nasname[1024];
184  char session_id[sizeof(rt.session_id)+1];
185  int hideshell = 0;
186  int showsid = 0;
187  int rawoutput = 0;
188  int radiusoutput = 0; /* Radius attributes */
189  char const *portind;
190  int c;
191  unsigned int portno;
192  char buffer[2048];
193  char const *user = NULL;
194  int user_cmp = 0;
195  time_t now = 0;
196  uint32_t nas_port = ~0;
197  uint32_t nas_ip_address = INADDR_NONE;
198  int zap = 0;
199  fr_dict_t *dict = NULL;
200  TALLOC_CTX *autofree;
201 
202  char const *p;
204  int ret = EXIT_SUCCESS;
205 
206  /*
207  * Must be called first, so the handler is called last
208  */
210 
212 
213 #ifndef NDEBUG
214  if (fr_fault_setup(autofree, getenv("PANIC_ACTION"), argv[0]) < 0) {
215  fr_perror("%s", main_config->name);
216  fr_exit_now(EXIT_FAILURE);
217  }
218 #endif
219 
220  talloc_set_log_stderr();
221 
222  /*
223  * Allocate the main config structure.
224  * It's allocating so we can hang talloced buffers off it.
225  */
227  if (!config) {
228  fr_perror("Failed allocating main config");
229  fr_exit_now(EXIT_FAILURE);
230  }
231 
232  p = strrchr(argv[0], FR_DIR_SEP);
233  if (!p) {
234  main_config_name_set_default(config, argv[0], false);
235  } else {
236  main_config_name_set_default(config, p + 1, false);
237  }
238 
239  while((c = getopt(argc, argv, "d:D:fF:hnN:sSipP:crRu:U:Z")) != -1) switch (c) {
240  case 'd':
242  break;
243  case 'D':
245  break;
246  case 'F':
247  radutmp_file = optarg;
248  break;
249  case 'h':
250  usage(EXIT_SUCCESS); /* never returns */
251  case 'S':
252  hideshell = 1;
253  break;
254  case 'n':
255  showname = 0;
256  break;
257  case 'N':
258  if (inet_pton(AF_INET, optarg, &nas_ip_address) <= 0) {
259  usage(EXIT_FAILURE);
260  }
261  break;
262  case 's':
263  showname = 1;
264  break;
265  case 'i':
266  showsid = 1;
267  break;
268  case 'p':
269  showptype = 1;
270  break;
271  case 'P':
272  nas_port = atoi(optarg);
273  break;
274  case 'c':
275  showcid = 1;
276  showname = 1;
277  break;
278  case 'r':
279  rawoutput = 1;
280  break;
281  case 'R':
282  radiusoutput = 1;
283  now = time(NULL);
284  break;
285  case 'u':
286  user = optarg;
287  user_cmp = 0;
288  break;
289  case 'U':
290  user = optarg;
291  user_cmp = 1;
292  break;
293  case 'Z':
294  zap = 1;
295  break;
296 
297  default:
298  usage(1); /* never returns */
299  }
300 
301  /*
302  * Mismatch between the binary and the libraries it depends on
303  */
305  fr_perror("%s", main_config->name);
306  return 1;
307  }
308 
309  if (!fr_dict_global_ctx_init(NULL, true, config->dict_dir)) {
310  fr_perror("%s", main_config->name);
311  fr_exit_now(EXIT_FAILURE);
312  }
313 
314 
316  fr_perror("%s", config->name);
317  fr_exit_now(EXIT_FAILURE);
318  }
319 
320  if (fr_dict_read(dict, config->raddb_dir, FR_DICTIONARY_FILE) == -1) {
321  PERROR("Failed to initialize the dictionaries");
322  return 1;
323  }
324  fr_strerror_clear(); /* Clear the error buffer */
325 
326  /*
327  * Be safe.
328  */
329  if (zap && !radiusoutput) zap = 0;
330 
331  /*
332  * zap EVERYONE, but only on this nas
333  */
334  if (zap && !user && (~nas_port == 0)) {
335  /*
336  * We need to know which NAS to zap users in.
337  */
338  if (nas_ip_address == INADDR_NONE) usage(1);
339 
340  printf("Acct-Status-Type = Accounting-Off\n");
341  printf("NAS-IP-Address = %s\n",
342  hostname(buffer, sizeof(buffer), nas_ip_address));
343  printf("Acct-Delay-Time = 0\n");
344  fr_exit_now(0); /* don't bother printing anything else */
345  }
346 
347  if (radutmp_file) goto have_radutmp;
348 
349  /* Read radiusd.conf */
350  maincs = cf_section_alloc(NULL, NULL, "main", NULL);
351  if (!maincs) fr_exit_now(EXIT_FAILURE);
352 
353  snprintf(buffer, sizeof(buffer), "%.200s/radiusd.conf", config->raddb_dir);
354  if ((cf_file_read(maincs, buffer) < 0) || (cf_section_pass2(maincs) < 0)) {
355  fr_perror("%s: Error reading or parsing radiusd.conf\n", argv[0]);
356  talloc_free(maincs);
357  fr_exit_now(EXIT_FAILURE);
358  }
359 
360  cs = cf_section_find(maincs, "modules", NULL);
361  if (!cs) {
362  fr_perror("%s: No modules section found in radiusd.conf\n", argv[0]);
363  fr_exit_now(EXIT_FAILURE);
364  }
365  /* Read the radutmp section of radiusd.conf */
366  cs = cf_section_find(cs, "radutmp", NULL);
367  if (!cs) {
368  fr_perror("%s: No configuration information in radutmp section of radiusd.conf\n", argv[0]);
369  fr_exit_now(EXIT_FAILURE);
370  }
371 
372  if (cf_section_rules_push(cs, module_config) < 0) fr_exit_now(EXIT_FAILURE);
373  cf_section_parse(maincs, NULL, cs);
374 
375  /* Assign the correct path for the radutmp file */
377 
378  have_radutmp:
379  if (showname < 0) showname = 1;
380 
381  /*
382  * Show the users logged in on the terminal server(s).
383  */
384  if ((fp = fopen(radutmp_file, "r")) == NULL) {
385  fr_perror("%s: Error reading %s: %s\n",
387  return 0;
388  }
389 
390  /*
391  * Don't print the headers if raw or RADIUS
392  */
393  if (!rawoutput && !radiusoutput) {
394  fputs(showname ? hdr1 : hdr2, stdout);
395  fputs(eol, stdout);
396  }
397 
398  /*
399  * Read the file, printing out active entries.
400  */
401  while (fread(&rt, sizeof(rt), 1, fp) == 1) {
402  char name[sizeof(rt.login) + 1];
403 
404  if (rt.type != P_LOGIN) continue; /* hide logout sessions */
405 
406  /*
407  * We don't show shell users if we are
408  * fingerd, as we have done that above.
409  */
410  if (hideshell && !strchr("PCS", rt.proto))
411  continue;
412 
413  /*
414  * Print out sessions only for the given user.
415  */
416  if (user) { /* only for a particular user */
417  if (((user_cmp == 0) &&
418  (strncasecmp(rt.login, user, strlen(user)) != 0)) ||
419  ((user_cmp == 1) &&
420  (strncmp(rt.login, user, strlen(user)) != 0))) {
421  continue;
422  }
423  }
424 
425  /*
426  * Print out only for the given NAS port.
427  */
428  if (~nas_port != 0) {
429  if (rt.nas_port != nas_port) continue;
430  }
431 
432  /*
433  * Print out only for the given NAS IP address
434  */
435  if (nas_ip_address != INADDR_NONE) {
436  if (rt.nas_address != nas_ip_address) continue;
437  }
438 
439  memcpy(session_id, rt.session_id, sizeof(rt.session_id));
440  session_id[sizeof(rt.session_id)] = 0;
441 
442  if (!rawoutput && rt.nas_port > (showname ? 999 : 99999)) {
443  portind = ">";
444  portno = (showname ? 999 : 99999);
445  } else {
446  portind = "S";
447  portno = rt.nas_port;
448  }
449 
450  /*
451  * Print output as RADIUS attributes
452  */
453  if (radiusoutput) {
454  memcpy(nasname, rt.login, sizeof(rt.login));
455  nasname[sizeof(rt.login)] = '\0';
456 
457  fr_snprint(buffer, sizeof(buffer), nasname, -1, '"');
458  printf("User-Name = \"%s\"\n", buffer);
459 
460  fr_snprint(buffer, sizeof(buffer), session_id, -1, '"');
461  printf("Acct-Session-Id = \"%s\"\n", buffer);
462 
463  if (zap) printf("Acct-Status-Type = Stop\n");
464 
465  printf("NAS-IP-Address = %s\n",
466  hostname(buffer, sizeof(buffer),
467  rt.nas_address));
468  printf("NAS-Port = %u\n", rt.nas_port);
469 
470  switch (rt.proto) {
471  case 'S':
472  printf("Service-Type = Framed-User\n");
473  printf("Framed-Protocol = SLIP\n");
474  break;
475 
476  case 'P':
477  printf("Service-Type = Framed-User\n");
478  printf("Framed-Protocol = PPP\n");
479  break;
480 
481  default:
482  printf("Service-type = Login-User\n");
483  break;
484  }
485  if (rt.framed_address != INADDR_NONE) {
486  printf("Framed-IP-Address = %s\n",
487  hostname(buffer, sizeof(buffer),
488  rt.framed_address));
489  }
490 
491  /*
492  * Some sanity checks on the time
493  */
494  if ((rt.time <= now) &&
495  (now - rt.time) <= (86400 * 365)) {
496  printf("Acct-Session-Time = %" PRId64 "\n", (int64_t) (now - rt.time));
497  }
498 
499  if (rt.caller_id[0] != '\0') {
500  memcpy(nasname, rt.caller_id,
501  sizeof(rt.caller_id));
502  nasname[sizeof(rt.caller_id)] = '\0';
503 
504  fr_snprint(buffer, sizeof(buffer), nasname, -1, '"');
505  printf("Calling-Station-Id = \"%s\"\n", buffer);
506  }
507 
508  printf("\n"); /* separate entries with a blank line */
509  continue;
510  }
511 
512  /*
513  * Show the fill name, or not.
514  */
515  memcpy(name, rt.login, sizeof(rt.login));
516  name[sizeof(rt.login)] = '\0';
517 
518  if (showname) {
519  if (rawoutput == 0) {
520  printf("%-10.10s %-17.17s %-5.5s %s%-3u %-9.9s %-15.15s %-.19s%s",
521  name,
522  showcid ? rt.caller_id :
523  (showsid? session_id : fullname(rt.login)),
524  proto(rt.proto, rt.porttype),
525  portind, portno,
526  dotime(rt.time),
527  hostname(nasname, sizeof(nasname), rt.nas_address),
528  hostname(othername, sizeof(othername), rt.framed_address), eol);
529  } else {
530  printf("%s,%s,%s,%s%u,%s,%s,%s%s",
531  name,
532  showcid ? rt.caller_id :
533  (showsid? session_id : fullname(rt.login)),
534  proto(rt.proto, rt.porttype),
535  portind, portno,
536  dotime(rt.time),
537  hostname(nasname, sizeof(nasname), rt.nas_address),
538  hostname(othername, sizeof(othername), rt.framed_address), eol);
539  }
540  } else {
541  if (rawoutput == 0) {
542  printf("%-10.10s %s%-5u %-6.6s %-13.13s %-15.15s %-.28s%s",
543  name,
544  portind, portno,
545  proto(rt.proto, rt.porttype),
546  dotime(rt.time),
547  hostname(nasname, sizeof(nasname), rt.nas_address),
548  hostname(othername, sizeof(othername), rt.framed_address),
549  eol);
550  } else {
551  printf("%s,%s%u,%s,%s,%s,%s%s",
552  name,
553  portind, portno,
554  proto(rt.proto, rt.porttype),
555  dotime(rt.time),
556  hostname(nasname, sizeof(nasname), rt.nas_address),
557  hostname(othername, sizeof(othername), rt.framed_address),
558  eol);
559  }
560  }
561  }
562  fclose(fp);
563 
565 
566  fr_dict_free(&dict, __FILE__);
567 
568  /*
569  * Ensure our atexit handlers run before any other
570  * atexit handlers registered by third party libraries.
571  */
573 
574  return ret;
575 }
static int const char char buffer[256]
Definition: acutest.h:574
int fr_atexit_global_setup(void)
Setup the atexit handler, should be called at the start of a program's execution.
Definition: atexit.c:160
int fr_atexit_global_trigger_all(void)
Cause all global free triggers to fire.
Definition: atexit.c:286
static fr_dict_t * dict
Definition: fuzzer.c:46
#define RCSID(id)
Definition: build.h:444
#define NEVER_RETURNS
Should be placed before the function return type.
Definition: build.h:311
int cf_file_read(CONF_SECTION *cs, char const *filename)
Definition: cf_file.c:3010
int cf_section_pass2(CONF_SECTION *cs)
Definition: cf_file.c:757
int cf_section_parse(TALLOC_CTX *ctx, void *base, CONF_SECTION *cs)
Parse a configuration section into user-supplied variables.
Definition: cf_parse.c:985
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#define cf_section_rules_push(_cs, _rule)
Definition: cf_parse.h:658
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition: cf_parse.h:310
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Definition: cf_parse.h:412
Defines a CONF_PAIR to C data type mapping.
Definition: cf_parse.h:563
A section grouping multiple CONF_PAIR.
Definition: cf_priv.h:89
CONF_SECTION * cf_section_find(CONF_SECTION const *cs, char const *name1, char const *name2)
Find a CONF_SECTION with name1 and optionally name2.
Definition: cf_util.c:970
#define cf_section_alloc(_ctx, _parent, _name1, _name2)
Definition: cf_util.h:137
int fr_fault_setup(TALLOC_CTX *ctx, char const *cmd, char const *program)
Registers signal handlers to execute panic_action on fatal signal.
Definition: debug.c:1215
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition: debug.h:232
int fr_dict_internal_afrom_file(fr_dict_t **out, char const *internal_name, char const *dependent)
(Re-)Initialize the special internal dictionary
int fr_dict_free(fr_dict_t **dict, char const *dependent)
Decrement the reference count on a previously loaded dictionary.
Definition: dict_util.c:3581
int fr_dict_read(fr_dict_t *dict, char const *dict_dir, char const *filename)
Read supplementary attribute definitions into an existing dictionary.
fr_dict_gctx_t * fr_dict_global_ctx_init(TALLOC_CTX *ctx, bool free_at_exit, char const *dict_dir)
Initialise the global protocol hashes.
Definition: dict_util.c:3984
#define PERROR(_fmt,...)
Definition: log.h:228
talloc_free(reap)
int main_config_free(main_config_t **config)
Definition: main_config.c:1429
void main_config_raddb_dir_set(main_config_t *config, char const *name)
Set the global radius config directory.
Definition: main_config.c:859
void main_config_name_set_default(main_config_t *config, char const *name, bool overwrite_config)
Set the server name.
Definition: main_config.c:840
main_config_t const * main_config
Main server configuration.
Definition: main_config.c:69
main_config_t * main_config_alloc(TALLOC_CTX *ctx)
Allocate a main_config_t struct, setting defaults.
Definition: main_config.c:1000
void main_config_dict_dir_set(main_config_t *config, char const *name)
Set the global dictionary directory.
Definition: main_config.c:988
char const * name
Name of the daemon, usually 'radiusd'.
Definition: main_config.h:52
Main server configuration.
Definition: main_config.h:51
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
unsigned int uint32_t
Definition: merged_model.c:33
int inet_pton(int af, char const *src, void *dst)
Definition: missing.c:427
int strncasecmp(char *s1, char *s2, int n)
Definition: missing.c:36
char * ctime_r(time_t const *l_clock, char *l_buf)
Definition: missing.c:182
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
Definition: missing.c:443
size_t fr_snprint(char *out, size_t outlen, char const *in, ssize_t inlen, char quote)
Escape any non printable or non-UTF8 characters in the input string.
Definition: print.c:229
static const conf_parser_t config[]
Definition: base.c:188
static TALLOC_CTX * autofree
Definition: radclient-ng.c:104
unsigned int framed_address
Definition: radutmp.h:60
char porttype
Definition: radutmp.h:65
time_t time
Definition: radutmp.h:62
char login[32]
Definition: radutmp.h:54
int type
Definition: radutmp.h:64
unsigned int nas_address
Definition: radutmp.h:59
char session_id[8]
Definition: radutmp.h:57
char caller_id[16]
Definition: radutmp.h:67
#define P_LOGIN
Definition: radutmp.h:51
unsigned int nas_port
Definition: radutmp.h:56
int proto
Definition: radutmp.h:61
static char const * radutmp_file
Definition: radwho.c:53
static char const * hdr2
Definition: radwho.c:44
static char const * hostname(char *buf, size_t buflen, uint32_t ipaddr)
Definition: radwho.c:133
static char const * eol
Definition: radwho.c:47
int main(int argc, char **argv)
Definition: radwho.c:177
static struct radutmp_config_t radutmpconfig
static int showcid
Definition: radwho.c:50
static int showname
Definition: radwho.c:48
static char const * progname
Definition: radwho.c:51
static char * fullname(char *username)
Definition: radwho.c:67
static char * dotime(time_t t)
Definition: radwho.c:108
static int showptype
Definition: radwho.c:49
static char const * hdr1
Definition: radwho.c:41
char const * radutmp_fn
Definition: radwho.c:56
static const conf_parser_t module_config[]
Definition: radwho.c:59
static NEVER_RETURNS void usage(int status)
Definition: radwho.c:149
static char const * proto(int id, int porttype)
Definition: radwho.c:85
static char const * name
username
Definition: rlm_securid.c:420
static char buff[sizeof("18446744073709551615")+3]
Definition: size_tests.c:41
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition: snprintf.c:689
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition: strlcpy.c:34
char const * fr_syserror(int num)
Guaranteed to be thread-safe version of strerror.
Definition: syserror.c:243
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition: talloc.h:51
#define FR_DICTIONARY_FILE
Definition: conf.h:7
#define FR_DICTIONARY_INTERNAL_DIR
Definition: conf.h:8
#define RADIUS_DIR
Definition: conf.h:3
#define RADUTMP
Definition: conf.h:13
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition: strerror.c:733
void fr_strerror_clear(void)
Clears all pending messages from the talloc pools.
Definition: strerror.c:577
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
Definition: version.c:40
#define RADIUSD_MAGIC_NUMBER
Definition: version.h:81