File: checkdns.c

package info (click to toggle)
saods9 3.0.3-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 86,868 kB
  • ctags: 82,021
  • sloc: ansic: 663,637; tcl: 111,403; cpp: 52,727; sh: 27,784; makefile: 6,177; asm: 3,355; lex: 2,890; ada: 1,637; pascal: 1,621; xml: 1,221; yacc: 883; f90: 84; perl: 82; python: 33; fortran: 17; ruby: 13; sed: 12; php: 11
file content (151 lines) | stat: -rw-r--r-- 3,191 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/* Copyright (C) 1999-2004
 * Smithsonian Astrophysical Observatory, Cambridge, MA, USA
 * For conditions of distribution and use, see copyright notice in "copyright"
 */

/* solaris: gcc -o dns -g dns.c -lsocket -lnsl */

#include <unistd.h>
#include <signal.h>
#include <netdb.h>
#include <tcl.h>

#ifndef SZ_LINE
#define SZ_LINE 2048
#endif

/* shared between main routine and signal handler */
static int dns_alarm_flag=0;

/* alarm signal handler */
static void
dns_alarm(int signo)
{
  dns_alarm_flag = 1;
}

/* check whether we can get info in an ip in a finite amount of time */
static int
checkdns(char *name, int delay)
{
  int flag=0;
  char host[SZ_LINE];
  struct hostent *hostent;
  struct sigaction act1, oact1;

  /* start the alarm, if necessary */
  if( delay > 0 ){
    /* reset status flag */
    dns_alarm_flag = 0;
    /* set up alarm signal handler */
    act1.sa_handler = dns_alarm;
    sigemptyset(&act1.sa_mask);
    act1.sa_flags = 0;
#ifdef SA_INTERRUPT
    act1.sa_flags |= SA_INTERRUPT;
#endif
    if( sigaction(SIGALRM, &act1, &oact1) < 0 ){
      flag = -1;
      goto done;
    }
    /* start the alarm */
    alarm(delay);
  }

  /* get name of host we are interested in */
  if( name && *name )
    strcpy(host, name);
  else{
    /* use current host */
    if( gethostname(host, SZ_LINE) < 0 ){
      flag = -2;
      goto done;
    }
  }

  /* if the alarm went off, we are done */
  if( delay && dns_alarm_flag ){
    goto done;
  }

  /* try to get info on this host */
  if( !gethostbyname(host) ){
    flag = -3;
    goto done;
  }

  /* stop the alarm, if necessary */
  if( delay ){
    /* turn off the alarm */
    alarm(0);
    /* reset up alarm signal handler */
    act1.sa_handler = oact1.sa_handler;
    sigemptyset(&act1.sa_mask);
    act1.sa_flags = 0;
#ifdef SA_INTERRUPT
    act1.sa_flags |= SA_INTERRUPT;
#endif
    sigaction(SIGALRM, &act1, &oact1);
  }

done:
  /* if alarm went off, set return status flag */
  if( dns_alarm_flag )
    flag = dns_alarm_flag;

  /* return status flag */
  return(flag);
}

static int
CheckDNS_Tcl(ClientData clientData, Tcl_Interp *interp,
	     int objc, Tcl_Obj *CONST objv[])
{
  int got;
  int delay=5;
  char *s, *t;
  char *host=NULL;
  char tbuf[SZ_LINE];

  /* make sure argument count is correct */
  if( objc != 3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "host delay");
    return(TCL_ERROR);
  }

  /* get host */
  s = Tcl_GetStringFromObj(objv[1], NULL);
  if( s && (*s != '\0') ){
    host = s;
  }

  /* get delay */
  t = Tcl_GetStringFromObj(objv[2], NULL);
  if( t && (*t != '\0') ){
    delay = atoi(t);
  }

  /* reset error/result condition */
  Tcl_ResetResult(interp);

  /* check the DNS */
  got = checkdns(host, delay);

  /* set return value */
  sprintf(tbuf, "%d", got);
  Tcl_SetResult(interp, tbuf, TCL_VOLATILE);

  /* tcl command complete */
  return TCL_OK;
}

int Checkdns_Init (void *vinterp)
{
  Tcl_Interp *interp = (Tcl_Interp *)vinterp;

  /* add xpa commands to this interpreter */
  Tcl_CreateObjCommand(interp, "checkdns", CheckDNS_Tcl,
		       (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL);
  Tcl_PkgProvide(interp, "checkdns", "1.0");
  return(TCL_OK);
}