コード例 #1
0
ファイル: rsync.c プロジェクト: andreax79/monit
/**
 *  Check the server for greeting "@RSYNCD: XX, then send this greeting back
 *  to server, send command '#list' to get a listing of modules.
 *
 *  @author Igor Homyakov <*****@*****.**>
 *
 *  @file
 */
int check_rsync(Socket_T s) {
  char  buf[64];
  char  header[10];
  int   rc, version_major, version_minor;
  char  *rsyncd = "@RSYNCD:";
  char  *rsyncd_exit = "@RSYNCD: EXIT";

  ASSERT(s);

  /* Read and check the greeting */
  if (!socket_readln(s, buf, sizeof(buf))) {
    LogError("RSYNC: did not see server greeting  -- %s\n", STRERROR);
    return FALSE;
  }
  Util_chomp(buf);
  rc = sscanf(buf, "%10s %d.%d", header, &version_major, &version_minor);
  if ((rc == EOF) || (rc != 3)) {
    LogError("RSYNC: server greeting parse error %s\n", buf);
    return FALSE;
  }
  if (strncasecmp(header, rsyncd, strlen(rsyncd)) != 0) {
    LogError("RSYNC: server sent unexpected greeting -- %s\n", buf);
    return FALSE;
  }

  /* Send back the greeting */
  if (socket_print(s, "%s\n", buf) <= 0) {
    LogError("RSYNC: identification string send failed -- %s\n", STRERROR);
    return FALSE;
  }

  /* Send #list command */
  if (socket_print(s, "#list\n") < 0) {
    LogError("RSYNC: #list command failed -- %s\n", STRERROR);
    return FALSE;
  }

  /* Read response: discard list output and check that we've received successful exit */
  do {
    if (! socket_readln(s, buf, sizeof(buf))) {
      LogError("RSYNC: error receiving data -- %s\n", STRERROR);
      return FALSE;
    }
    Util_chomp(buf);
  } while (strncasecmp(buf, rsyncd, strlen(rsyncd)));
  if (strncasecmp(buf, rsyncd_exit, strlen(rsyncd_exit)) != 0) {
    LogError("RSYNC: server sent unexpected response -- %s\n", buf);
    return FALSE;
  }

  return TRUE;

}
コード例 #2
0
ファイル: postfix_policy.c プロジェクト: AsydSolutions/monit
/**
 *  A simple Postfix SMTP access policy delegation protocol test
 *
 *  To not affect real traffic, we send the following request with
 *  fixed virtual triplet values to the server:
 *   request=smtpd_access_policy
 *   protocol_state=RCPT
 *   protocol_name=SMTP
 *   [email protected]
 *   [email protected]
 *   client_address=1.2.3.4
 *   client_name=mx.foo.tld
 *  and check that the server replies with some action.
 *
 *  @file
 */
int check_postfix_policy(Socket_T socket) {

  char buf[STRLEN];

  ASSERT(socket);

  if(socket_print(socket,
    "request=smtpd_access_policy\n"
    "protocol_state=RCPT\n"
    "protocol_name=SMTP\n"
    "[email protected]\n"
    "[email protected]\n"
    "client_address=1.2.3.4\n"
    "client_name=mx.foo.tld\n"
    "\n") < 0) {
    socket_setError(socket, "POSTFIX-POLICY: error sending data -- %s", STRERROR);
    return FALSE;
  }

  if(! socket_readln(socket, buf, sizeof(buf))) {
    socket_setError(socket, "POSTFIX-POLICY: error receiving data -- %s", STRERROR);
    return FALSE;
  }

  Str_chomp(buf);

  if( (strlen(buf) <= 7) || strncasecmp(buf, "action=", 7) ) {
    socket_setError(socket, "POSTFIX-POLICY error: %s",
      *buf?buf:"no action returned");
    return FALSE;
  }

  return TRUE;

}
コード例 #3
0
ファイル: collector.c プロジェクト: cention-nazri/monit-5.5
/**
 * Send message to the server
 * @param C An mmonit object
 * @param D Data to send
 * @return TRUE if the message sending succeeded otherwise FALSE
 */
static int data_send(Socket_T socket, Mmonit_T C, const char *D) {
        char *auth = Util_getBasicAuthHeader(C->url->user, C->url->password);
        int rv = socket_print(socket,
                          "POST %s HTTP/1.1\r\n"
                          "Host: %s:%d\r\n"
                          "Content-Type: text/xml\r\n"
                          "Content-Length: %d\r\n"
                          "Pragma: no-cache\r\n"
                          "Accept: */*\r\n"
                          "User-Agent: %s/%s\r\n"
                          "Connection: close\r\n"
                          "%s"
                          "\r\n"
                          "%s",
                          C->url->path,
                          C->url->hostname, C->url->port,
                          strlen(D),
                          prog, VERSION,
                          auth?auth:"",
                          D);
        FREE(auth);
        if (rv <0) {
                LogError("M/Monit: error sending data to %s -- %s\n", C->url->url, STRERROR);
                return FALSE;
        }
        return TRUE;
}
コード例 #4
0
ファイル: imap.c プロジェクト: AsydSolutions/monit
/**
 *  Check the server for greeting code '* OK' and then send LOGOUT and
 *  check for code '* BYE'. If alive return TRUE, else, return FALSE.
 *
 *  @file
 */
int check_imap(Socket_T socket) {
        char buf[STRLEN];
        const char *ok = "* OK";
        const char *bye = "* BYE";

        ASSERT(socket);

        // Read and check IMAP greeting
        if (! socket_readln(socket, buf, sizeof(buf))) {
                socket_setError(socket, "IMAP: greeting read error -- %s", STRERROR);
                return FALSE;
        }
        Str_chomp(buf);
        if (strncasecmp(buf, ok, strlen(ok)) != 0) {
                socket_setError(socket, "IMAP: invalid greeting -- %s", buf);
                return FALSE;
        }

        // Logout and check response
        if (socket_print(socket, "001 LOGOUT\r\n") < 0) {
                socket_setError(socket, "IMAP: logout command error -- %s", STRERROR);
                return FALSE;
        }
        if (! socket_readln(socket, buf, sizeof(buf))) {
                socket_setError(socket, "IMAP: logout response read error -- %s", STRERROR);
                return FALSE;
        }
        Str_chomp(buf);
        if (strncasecmp(buf, bye, strlen(bye)) != 0) {
                socket_setError(socket, "IMAP: invalid logout response: %s", buf);
                return FALSE;
        }

        return TRUE;
}
コード例 #5
0
ファイル: http.c プロジェクト: ezotrank/monit-src
int check_http(Socket_T socket) {
        Port_T P;
        char host[STRLEN];
        char auth[STRLEN]= {0};
        const char *request = NULL;
        const char *hostheader = NULL;

        ASSERT(socket);

        P = socket_get_Port(socket);

        ASSERT(P);

        request = P->request ? P->request : "/";

        Util_getHTTPHostHeader(socket, host, STRLEN);
        hostheader = P->request_hostheader ? P->request_hostheader : host;

        if (socket_print(socket,
                         "GET %s HTTP/1.1\r\n"
                         "Host: %s\r\n"
                         "Accept: */*\r\n"
                         "User-Agent: %s/%s\r\n"
                         "%s\r\n",
                         request, hostheader, prog, VERSION,
                         get_auth_header(P, auth, STRLEN)) < 0) {
                socket_setError(socket, "HTTP: error sending data -- %s\n", STRERROR);
                return FALSE;
        }

        return check_request(socket, P);
}
コード例 #6
0
ファイル: clamav.c プロジェクト: KISSMonX/monit
/**
 *  Send PING and check for PONG.
 *  If alive return TRUE, else, return FALSE.
 *
 *  @author Debrard Sébastien <*****@*****.**>
 *
 *  @file
 */
int check_clamav(Socket_T s) {

  char buf[STRLEN];
  const char *ok= "PONG";

  ASSERT(s);
  
  if(socket_print(s, "PING\r\n") < 0) {
    LogError("CLAMAV: error sending data -- %s\n", STRERROR);
    return FALSE;
  }

  if(!socket_readln(s, buf, sizeof(buf))) {
    LogError("CLAMAV: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  Util_chomp(buf);
  
  if(strncasecmp(buf, ok, strlen(ok)) != 0) {
    LogError("CLAMAV error: %s\n", buf);
    return FALSE;
  }

  return TRUE;
  
}
コード例 #7
0
ファイル: control.c プロジェクト: bumper-app/nicad
/**
 * Pass on to methods in http/cervlet.c to start/stop services
 * @param P A service name as stated in the config file
 * @param action A string describing the action to execute
 */
void d_check_service(const char *P, const char *action) {

  Socket_T s;
  char *auth= get_basic_authentication_header();

  ASSERT(P);
  ASSERT(action);


  s= socket_new(Run.bind_addr?Run.bind_addr:"localhost",
		Run.httpdport, SOCKET_TCP, Run.httpdssl);
  
  if(!s) {
    
    log("%s: Cannot connect to the monit daemon. "
          "Did you start it with http support?\n", prog);
    goto error;
    
  } else {

    socket_print(s, "GET /%s?action=%s HTTP/1.0\r\n%s\r\n", P, action, auth);
    socket_free(&s);
      
  }
  
  error:
  FREE(auth);
  
}
コード例 #8
0
ファイル: ftp.c プロジェクト: AsydSolutions/monit
/**
 *  Check the server for greeting code 220 and then send a QUIT and
 *  check for code 221. If alive return TRUE, else, return FALSE.
 *
 *  @file
 */
int check_ftp(Socket_T socket) {
  int status;
  char buf[STRLEN];

  ASSERT(socket);

  do {
    if (! socket_readln(socket, buf, STRLEN)) {
      socket_setError(socket, "FTP: error receiving data -- %s", STRERROR);
      return FALSE;
    }
    Str_chomp(buf);
  } while(buf[3] == '-'); // Discard multi-line response
  if (sscanf(buf, "%d", &status) != 1 || status != 220) {
    socket_setError(socket, "FTP greeting error: %s", buf);
    return FALSE;
  }

  if (socket_print(socket, "QUIT\r\n") < 0) {
    socket_setError(socket, "FTP: error sending data -- %s", STRERROR);
    return FALSE;
  }

  if (! socket_readln(socket, buf, STRLEN)) {
    socket_setError(socket, "FTP: error receiving data -- %s", STRERROR);
    return FALSE;
  }
  Str_chomp(buf);
  if (sscanf(buf, "%d", &status) != 1 || status != 221) {
    socket_setError(socket, "FTP quit error: %s", buf);
    return FALSE;
  }

  return TRUE;
}
コード例 #9
0
ファイル: dwp.c プロジェクト: lixmgl/Intern_OpenStack_Swift
/**
 *  A simple DWP (database wire protocol) test.
 *
 *  We send the following request to the server:
 *  'HEAD / HTTP/1.1'
 *  and check the server's status code.
 *
 *  If the status code is >= 400, an error has occurred.
 *  Return TRUE if the status code is 200, otherwise FALSE.
 *
 *  @file
 */
int check_dwp(Socket_T socket) {

#define REQ_LENGTH  1024

  int n;
  int status;
  char buf[STRLEN];
  char proto[STRLEN];

  ASSERT(socket);

  if(socket_print(socket, "HEAD / HTTP/1.1\r\n"
		  "Connection: close\r\n\r\n") < 0) {
    socket_setError(socket, "DWP: error sending data -- %s\n", STRERROR);
    return FALSE;
  }
  
  if(! socket_readln(socket, buf, sizeof(buf))) {
    socket_setError(socket, "DWP: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  Str_chomp(buf);

  n= sscanf(buf, "%255s %d", proto, &status);
  if(n!=2 || (status >= 400)) {
    socket_setError(socket, "DWP error: %s\n", buf);
    return FALSE;
  }
  
  return TRUE;
  
}
コード例 #10
0
/**
 * Send the response to the client. If the response has already been
 * commited, this function does nothing.
 */
static void send_response(HttpResponse res) {
  Socket_T S= res->S;

  if(!res->is_committed) {
    char date[STRLEN];
    char server[STRLEN];
    char *headers= get_headers(res);
    int length = StringBuffer_length(res->outputbuffer);

    res->is_committed= TRUE;
    get_date(date, STRLEN);
    get_server(server, STRLEN);
    socket_print(S, "%s %d %s\r\n", res->protocol, res->status,
		 res->status_msg);
    socket_print(S, "Date: %s\r\n", date);
    socket_print(S, "Server: %s\r\n", server);
    socket_print(S, "Content-Length: %d\r\n", length);
    socket_print(S, "Connection: close\r\n");
    if(headers)
	socket_print(S, "%s", headers);
    socket_print(S, "\r\n");
    if(length)
	socket_write(S, (unsigned char *)StringBuffer_toString(res->outputbuffer), length);
    FREE(headers);
  }
}
コード例 #11
0
ファイル: socket.c プロジェクト: neufbox/misc
void socket_disconnect(struct socket *sk)
{
	if (sk->fd > 0) {
		trace("%s: %-32s %s", "socket", socket_print(sk),
		      "disconnected");

		close(sk->fd);
		sk->fd = -1;
		if (is_unix(sk))
			unlink(sk->u.un.sun_path);
	}
}
コード例 #12
0
ファイル: ftp.c プロジェクト: bumper-app/nicad
/**
 *  Check the server for greeting code 220 and then send a QUIT and
 *  check for code 221. If alive return TRUE, else, return FALSE.
 *
 *  @author Jan-Henrik Haukeland, <*****@*****.**>
 *  @author Michael Amster, <*****@*****.**>
 *
 *  @version \$Id: ftp.c,v 1.15 2004/02/18 22:31:42 chopp Exp $
 *
 *  @file
 */
int check_ftp(Socket_T s) {

  int status;
  char buf[STRLEN];
  char msg[STRLEN];

  ASSERT(s);

  if(! socket_readln(s, buf, STRLEN)) {
    log("FTP: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  chomp(buf, STRLEN);
  
  /* RATS: ignore */ /* chomp does zero termination */
  sscanf(buf, "%d %s", &status, msg);
  if(status != 220) {
    log("FTP error: %s\n", buf);
    return FALSE;
  }

  /* Read past banners */
  while(NULL != socket_readln(s, buf, STRLEN)) {
    if(starts_with(buf, "220")) continue;
  }
  
  if(socket_print(s, "QUIT\r\n") < 0) {
    log("FTP: error sending data -- %s\n", STRERROR);
    return FALSE;
  }

  if(socket_read(s, buf, STRLEN) <= 0) {
    log("FTP: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  chomp(buf, STRLEN);
  
  /* RATS: ignore */ /* chomp does zero termination */
  sscanf(buf, "%d %s", &status, msg);
  if(status != 221) {
    log("FTP error: %s\n", buf);
    return FALSE;
  }

  return TRUE;
  
}
コード例 #13
0
ファイル: smtp.c プロジェクト: bumper-app/nicad
/**
 *  Check the server for greeting code 220 and then send QUIT and
 *  check for code 221. If alive return TRUE, else, return FALSE.
 *
 *  @author Jan-Henrik Haukeland, <*****@*****.**>
 *  @author Michael Amster, <*****@*****.**>
 *
 *  @version \$Id: smtp.c,v 1.14 2004/02/18 22:31:42 chopp Exp $
 *
 *  @file
 */
int check_smtp(Socket_T s) {

  int status;
  char buf[STRLEN];
  char msg[STRLEN];

  ASSERT(s);

  if(socket_read(s, buf, sizeof(buf)) <= 0) {
    log("SMTP: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  chomp(buf, STRLEN);
  
  /* RATS: ignore */ /* chomp does zero termination */
  sscanf(buf, "%d %s", &status, msg);
  if(status != 220) {
    log("SMTP error: %s\n", buf);
    return FALSE;
  }

  if(socket_print(s, "QUIT\r\n") < 0) {
    log("SMTP: error sending data -- %s\n", STRERROR);
    return FALSE;
  }

  if(socket_read(s, buf, sizeof(buf)) <= 0) {
    log("SMTP: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  chomp(buf, STRLEN);
  
  /* RATS: ignore */ /* chomp does zero termination */
  sscanf(buf, "%d %s", &status, msg);
  if(status != 221) {
    log("SMTP error: %s\n", buf);
    return FALSE;
  }

  return TRUE;
  
}
コード例 #14
0
ファイル: imap.c プロジェクト: andreax79/monit
/**
 *  Check the server for greeting code '* OK' and then send LOGOUT and
 *  check for code '* BYE'. If alive return TRUE, else, return FALSE.
 *
 *  @author Jan-Henrik Haukeland, <*****@*****.**>
 *
 *  @file
 */
int check_imap(Socket_T s) {

  char buf[STRLEN];
  const char *ok= "* OK";
  const char *bye= "* BYE";

  
  ASSERT(s);
  
  if(!socket_readln(s, buf, sizeof(buf))) {
    LogError("IMAP: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  Util_chomp(buf);
  
  if(strncasecmp(buf, ok, strlen(ok)) != 0) {
    LogError("IMAP error: %s\n", buf);
    return FALSE;
  }
  
  if(socket_print(s, "001 LOGOUT\r\n") < 0) {
    LogError("IMAP: error sending data -- %s\n", STRERROR);
    return FALSE;
  }

  if(!socket_readln(s, buf, sizeof(buf))) {
    LogError("IMAP: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  Util_chomp(buf);
  
  if(strncasecmp(buf, bye, strlen(bye)) != 0) {
    LogError("IMAP error: %s\n", buf);
    return FALSE;
  }

  return TRUE;
  
}
コード例 #15
0
ファイル: apache_status.c プロジェクト: ezotrank/monit-src
/**
 * Check an Apache server to monitor its status.
 * Do this using the server-status report from mod_status, which
 * will only be available if the server is responding to
 * some extent.
 *
 * Currently based on the Scoreboard response, which is available
 * even with ExtendedStatus Off on Apache config file.
 *
 * @file
 */
int check_apache_status(Socket_T socket) {

  char host[STRLEN];
  const char *request= "/server-status?auto";

  ASSERT(socket);

  if(socket_print(socket, "GET %s HTTP/1.1\r\n"
                  "Host: %s\r\n"
                  "Accept: */*\r\n"
                  "User-Agent: %s/%s\r\n"
                  "Connection: close\r\n\r\n",
                  request, Util_getHTTPHostHeader(socket, host, STRLEN),
                  prog, VERSION) < 0) {
    socket_setError(socket, "HTTP: error sending data -- %s\n", STRERROR);
    return FALSE;
  }

  return check_apache_stat(socket);

}
コード例 #16
0
/**
 * Send an error message to the client. This is a helper function,
 * used internal if the service function fails to setup the framework
 * properly; i.e. with a valid HttpRequest and a valid HttpResponse.
 */
static void internal_error(Socket_T S, int status, char *msg) {
  char date[STRLEN];
  char server[STRLEN];
  const char *status_msg= get_status_string(status);
  
  get_date(date, STRLEN);
  get_server(server, STRLEN);
  socket_print(S, 
	       "%s %d %s\r\n"
	       "Date: %s\r\n"
	       "Server: %s\r\n"
	       "Content-Type: text/html\r\n"
	       "Connection: close\r\n"
	       "\r\n"
	       "<html><head><title>%s</title></head>"
	       "<body bgcolor=#FFFFFF><h2>%s</h2>%s<p>"
	       "<hr><a href='%s'><font size=-1>%s</font></a>"
	       "</body></html>\r\n",
	       SERVER_PROTOCOL, status, status_msg, date, server,
	       status_msg, status_msg, msg, SERVER_URL, server);
  DEBUG("HttpRequest error: %s %d %s\n", SERVER_PROTOCOL, status, msg ? msg : status_msg);
}
コード例 #17
0
ファイル: apache_status.c プロジェクト: AsydSolutions/monit
int check_apache_status(Socket_T socket) {
        ASSERT(socket);
        char host[STRLEN];
        if (socket_print(socket,
                "GET /server-status?auto HTTP/1.1\r\n"
                "Host: %s\r\n"
                "Accept: */*\r\n"
                "User-Agent: Monit/%s\r\n"
                "Connection: close\r\n\r\n",
                Util_getHTTPHostHeader(socket, host, STRLEN), VERSION) < 0)
        {
                socket_setError(socket, "HTTP: error sending data -- %s", STRERROR);
                return FALSE;
        }
        char buffer[4096] = {0};
        while (socket_readln(socket, buffer, sizeof(buffer))) {
                if (Str_startsWith(buffer, "Scoreboard: ")) {
                        char *scoreboard = buffer + 12; // skip header
                        return parse_scoreboard(socket, scoreboard);
                }
        }
        socket_setError(socket, "APACHE-STATUS: error -- no scoreboard found");
        return FALSE;
}
コード例 #18
0
ファイル: control.c プロジェクト: hafiz/yoke
/**
 * Pass on to methods in http/cervlet.c to start/stop services
 * @param S A service name as stated in the config file
 * @param action A string describing the action to execute
 * @return FALSE for error, otherwise TRUE
 */
int control_service_daemon(const char *S, const char *action) {
  int rv = FALSE;
  int status, content_length = 0;
  Socket_T s;
  char *auth;
  char buf[STRLEN];
  
  ASSERT(S);
  ASSERT(action);
  
  if (Util_getAction(action) == ACTION_IGNORE) {
    LogError("%s: Cannot %s service '%s' -- invalid action %s\n", prog, action, S, action);
    return FALSE;
  }
  
  s = socket_new(Run.bind_addr ? Run.bind_addr : "localhost", Run.httpdport, SOCKET_TCP, Run.httpdssl, NET_TIMEOUT);
  if (!s) {
    LogError("%s: Cannot connect to the monit daemon. Did you start it with http support?\n", prog);
    return FALSE;
  }

  /* Send request */
  auth = Util_getBasicAuthHeaderMonit();
  if (socket_print(s,
        "POST /%s HTTP/1.0\r\n"
        "Content-Type: application/x-www-form-urlencoded\r\n"
        "Content-Length: %d\r\n"
        "%s"
        "\r\n"
        "action=%s",
        S,
        strlen("action=") + strlen(action),
        auth ? auth : "",
        action) < 0) {
    LogError("%s: Cannot send the command '%s' to the monit daemon -- %s", prog, action ? action : "null", STRERROR);
    goto err1;
  }

  /* Process response */
  if (! socket_readln(s, buf, STRLEN)) {
    LogError("%s: error receiving data -- %s\n", prog, STRERROR);
    goto err1;
  }
  Util_chomp(buf);
  if (! sscanf(buf, "%*s %d", &status)) {
    LogError("%s: cannot parse status in response: %s\n", prog, buf);
    goto err1;
  }
  if (status >= 300) {
    char *message = NULL;

    /* Skip headers */
    while (socket_readln(s, buf, STRLEN)) {
      if (! strncmp(buf, "\r\n", sizeof(buf)))
        break;
      if(Util_startsWith(buf, "Content-Length") && ! sscanf(buf, "%*s%*[: ]%d", &content_length))
        goto err1;
    }
    if (content_length > 0 && content_length < 1024 && socket_readln(s, buf, STRLEN)) {
      char token[] = "</h2>";
      char *p = strstr(buf, token);

      if (strlen(p) <= strlen(token))
        goto err2;
      p += strlen(token);
      message = xcalloc(sizeof(unsigned char), content_length + 1);
      snprintf(message, content_length + 1, "%s", p);
      p = strstr(message, "<p>");
      if (p)
        *p = 0;
    }
err2:
    LogError("%s: action failed -- %s\n", prog, message ? message : "unable to parse response");
    FREE(message);
  } else
    rv = TRUE;
err1:
  FREE(auth);
  socket_free(&s);

  return rv;
}
コード例 #19
0
ファイル: control.c プロジェクト: andreax79/monit
/**
 * Pass on to methods in http/cervlet.c to start/stop services
 * @param S A service name as stated in the config file
 * @param action A string describing the action to execute
 * @param attempts Number of attemps (in case of "already action already in progres...")
 * @return a string starting with "ERR" in for error, otherwise return "OK"
 */
char *control_service_daemon_message(const char *S, const char *action, int attempts, int check_exit_status /* ignored */) {
  char *rv = NULL;
  int status, content_length = 0;
  Socket_T s;
  char *auth;
  char buf[STRLEN];
  
  ASSERT(S);
  ASSERT(action);
  
  if (Util_getAction(action) == ACTION_IGNORE) {
    return xstrdup("ERR1: invalid action");
  }

  auth = Util_getBasicAuthHeaderMonit();

retry:
  /* Try with the socket first */
  if (Run.bind_path) {
    s = socket_new(Run.bind_path, 0, SOCKET_TCP, Run.httpdssl, NET_TIMEOUT);
  }

  /* Try network connection */
  if (!s) {
    if(!(s = socket_new(Run.bind_addr ? Run.bind_addr : "localhost", Run.httpdport,
                            SOCKET_TCP, Run.httpdssl, NET_TIMEOUT))) {
        FREE(auth);
        return xstrdup("ERR2: cannot connect to the monit daemon");
    }
  }

  /* Send request */
  if (socket_print(s,
        "POST /%s HTTP/1.0\r\n"
        "Content-Type: application/x-www-form-urlencoded\r\n"
        "Content-Length: %d\r\n"
        "%s"
        "\r\n"
        "action=%s",
        S,
        strlen("action=") + strlen(action),
        auth ? auth : "",
        action) < 0) {
    return xstrdup("ERR3: cannot send the command");
    goto err1;
  }

  /* Process response */
  if (! socket_readln(s, buf, STRLEN)) {
    rv = xstrdup("ERR4: error receiving data");
    goto err1;
  }
  Util_chomp(buf);
  if (! sscanf(buf, "%*s %d", &status)) {
    rv = xstrdup("ERR5: cannot parse status in response");
    goto err1;
  }
  if (status >= 300) {
    /* Skip headers */
    while (socket_readln(s, buf, STRLEN)) {
      if (! strncmp(buf, "\r\n", sizeof(buf)))
        break;
      if(Util_startsWith(buf, "Content-Length") && ! sscanf(buf, "%*s%*[: ]%d", &content_length)) {
        rv = xstrdup("ERR6: error parsing headers");
        goto err1;
      }
    }
    if (content_length > 0 && content_length < 1024 && socket_readln(s, buf, STRLEN)) {
      char token[] = "</h2>";
      char *p = strstr(buf, token);

      if (strlen(p) <= strlen(token)) {
        rv = xstrdup("ERR7: error parsing body");
        goto err1;
      }
      p += strlen(token);
      rv = xcalloc(sizeof(unsigned char), content_length + 1 + 6);
      snprintf(rv, content_length + 1 + 6, "ERR8: %s", p);
      p = strstr(rv, "<p>");
      if (p)
        *p = 0;
      attempts--;
      if ((attempts > 0) && (strstr(rv, "please try again later") != NULL)) {
          socket_free(&s);
          /*LogInfo("%s: retrying %s %s (%s)\n", prog, action, S, rv);*/
          LogInfo("%s: retrying %s %s\n", prog, action, S);
          FREE(rv);
          sleep(1);
          goto retry;
      }
    }
  } else
    rv = xstrdup("OK");
err1:
  FREE(auth);
  socket_free(&s);

  return rv;
}
コード例 #20
0
ファイル: sip.c プロジェクト: cention-nazri/monit-5.5
int check_sip(Socket_T socket) {
  int status;
  char buf[STRLEN];
  int port;
  char *transport;
  Port_T P;
  const char *request;
  const char *myip;
  char *rport= "";
  char *proto;

  ASSERT(socket);

  P= socket_get_Port(socket);
  ASSERT(P);
  request= P->request?P->request:"*****@*****.**";

  port = socket_get_local_port(socket);
  proto = socket_is_secure(socket) ? "sips" : "sip";  

  switch(socket_get_type(socket)) {
    case SOCK_DGRAM:
    {
      transport="UDP";
      rport=";rport";
      break;
    }
    case SOCK_STREAM:
    {
      transport="TCP";
      break;
    }
    default:
    {
      socket_setError(socket, "Unsupported socket type, only TCP and UDP are supported\n");
      return TRUE;
    }
  }

  myip= socket_get_local_host(socket);

  if(socket_print(socket,
    "OPTIONS %s:%s SIP/2.0\r\n"
    "Via: SIP/2.0/%s %s:%d;branch=z9hG4bKh%u%s\r\n"
    "Max-Forwards: %d\r\n"
    "To: <%s:%s>\r\n"
    "From: monit <%s:monit@%s>;tag=%d\r\n"
    "Call-ID: %u\r\n"
    "CSeq: 63104 OPTIONS\r\n"
    "Contact: <%s:%s:%d>\r\n"
    "Accept: application/sdp\r\n"
    "Content-Length: 0\r\n"
    "User-Agent: %s/%s\r\n\r\n",
    proto,            // protocol
    request,          // to
    transport,        // via transport udp|tcp
    myip,             // who its from
    port,             // our port
    random(),         // branch
    rport,            // rport option
    P->maxforward,    // maximum forwards
    proto,            // protocol
    request,          // to
    proto,            // protocol
    myip,             // from host
    random(),         // tag
    random(),         // call id
    proto,            // protocol
    myip,             // contact host
    port,             // contact port
    prog, VERSION     // user agent
    ) < 0) {
    socket_setError(socket, "SIP: error sending data -- %s\n", STRERROR);
    return FALSE;
  }

  if(! socket_readln(socket, buf, sizeof(buf))) {
    socket_setError(socket, "SIP: error receiving data -- %s\n", STRERROR);
    return FALSE;
  }

  Str_chomp(buf);

  DEBUG("Response from SIP server: %s\n", buf);

  if(! sscanf(buf, "%*s %d", &status)) { 
    socket_setError(socket, "SIP error: cannot parse SIP status in response: %s\n", buf);
    return FALSE;
  }

  if(status >= 400) {
    socket_setError(socket, "SIP error: Server returned status %d\n", status);
    return FALSE;
  }

  if(status >= 300 && status < 400) {
    socket_setError(socket, "SIP info: Server redirection. Returned status %d\n", status); 
    return FALSE;
  }

  if(status > 100 && status < 200) {
    socket_setError(socket, "SIP error: Provisional response . Returned status %d\n", status);
    return FALSE;
  }

  return TRUE;

}