Forráskód Böngészése

Add methods for returning the ports civetweb is listening on

Patch civetweb to provide a method for retrieving the listening ports.

* Verified builds for:
   * MacOS X 10.8 - Xcode 5
   * MS Visual Studio 2012 Express on Windows 7
Keith Kyzivat 11 éve
szülő
commit
2a4245e379
2 módosított fájl, 41 hozzáadás és 2 törlés
  1. 7 0
      include/civetweb.h
  2. 34 2
      src/civetweb.c

+ 7 - 0
include/civetweb.h

@@ -224,6 +224,13 @@ const char *mg_get_option(const struct mg_context *ctx, const char *name);
    Array is NULL terminated. */
 const char **mg_get_valid_option_names(void);
 
+/* Get the list of ports that civetweb is listening on.
+   size is the size of the ports int array and ssl int array to fill.
+   It is the caller's responsibility to make sure ports and ssl each
+   contain at least size int elements worth of memory to write into.
+   The value returned is read-only. Civetweb does not allow changing
+   configuration at run time. */
+void mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl);
 
 /* Add, edit or delete the entry in the passwords file.
 

+ 34 - 2
src/civetweb.c

@@ -92,6 +92,12 @@
 #define PATH_MAX MAX_PATH
 #endif
 
+#ifndef _IN_PORT_T
+#ifndef in_port_t
+#define in_port_t u_short
+#endif
+#endif
+
 #ifndef _WIN32_WCE
 #include <process.h>
 #include <direct.h>
@@ -568,6 +574,7 @@ struct mg_context {
     void *user_data;                /* User-defined data */
 
     struct socket *listening_sockets;
+    in_port_t *listening_ports;
     int num_listening_sockets;
 
     volatile int num_threads;  /* Number of threads */
@@ -700,6 +707,15 @@ const char *mg_get_option(const struct mg_context *ctx, const char *name)
     }
 }
 
+void mg_get_ports(const struct mg_context *ctx, size_t size, int* ports, int* ssl)
+{
+    for (int i = 0; i < size && i < ctx->num_listening_sockets; i++)
+    {
+        ssl[i] = ctx->listening_sockets[i].is_ssl;
+        ports[i] = ctx->listening_ports[i];
+    }
+}
+
 static void sockaddr_to_string(char *buf, size_t len,
                                const union usa *usa)
 {
@@ -5206,6 +5222,13 @@ static int set_ports_option(struct mg_context *ctx)
     struct vec vec;
     struct socket so, *ptr;
 
+    in_port_t *portPtr;
+    struct sockaddr_in sin;
+    socklen_t len;
+
+    memset(&sin, 0, sizeof(sin));
+    len = sizeof(sin);
+
     while (success && (list = next_option(list, &vec, NULL)) != NULL) {
         if (!parse_port_string(&vec, &so)) {
             mg_cry(fc(ctx), "%s: %.*s: invalid port spec. Expecting list of: %s",
@@ -5227,7 +5250,8 @@ static int set_ports_option(struct mg_context *ctx)
 #endif
                    bind(so.sock, &so.lsa.sa, so.lsa.sa.sa_family == AF_INET ?
                         sizeof(so.lsa.sin) : sizeof(so.lsa)) != 0 ||
-                   listen(so.sock, SOMAXCONN) != 0) {
+                   listen(so.sock, SOMAXCONN) != 0 ||
+                   getsockname(so.sock, (struct sockaddr *)&sin, &len) != 0) {
             mg_cry(fc(ctx), "%s: cannot bind to %.*s: %d (%s)", __func__,
                    (int) vec.len, vec.ptr, ERRNO, strerror(errno));
             if (so.sock != INVALID_SOCKET) {
@@ -5239,10 +5263,18 @@ static int set_ports_option(struct mg_context *ctx)
                           sizeof(ctx->listening_sockets[0]))) == NULL) {
             closesocket(so.sock);
             success = 0;
-        } else {
+        } else if ((portPtr = (in_port_t*) realloc(ctx->listening_ports,
+                          (ctx->num_listening_sockets + 1) *
+                          sizeof(ctx->listening_ports[0]))) == NULL) {
+            closesocket(so.sock);
+            success = 0;
+        }
+        else {
             set_close_on_exec(so.sock, fc(ctx));
             ctx->listening_sockets = ptr;
             ctx->listening_sockets[ctx->num_listening_sockets] = so;
+            ctx->listening_ports = portPtr;
+            ctx->listening_ports[ctx->num_listening_sockets] = ntohs(sin.sin_port);
             ctx->num_listening_sockets++;
         }
     }