]> git.meshlink.io Git - meshlink/blobdiff - src/meshlink.c
Don't interactively ask for an Address when generating an invitation URL.
[meshlink] / src / meshlink.c
index c88059b1e02fe0be95777a15d10a1848d9d16ec8..130994d8a30491fff582fe1da83754fa2b38157f 100644 (file)
@@ -40,6 +40,9 @@ typedef struct {
 #include "xalloc.h"
 #include "ed25519/sha512.h"
 
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
 
 //TODO: this can go away completely
 const var_t variables[] = {
@@ -233,44 +236,9 @@ static char *get_my_hostname(meshlink_handle_t* mesh) {
                }
        }
 
-       //if(!tty) {
-       //      if(!hostname) {
-       //              fprintf(stderr, "Could not determine the external address or hostname. Please set Address manually.\n");
-       //              return NULL;
-       //      }
-       //      goto save;
-       //}
-
-again:
-       fprintf(stderr, "Please enter your host's external address or hostname");
-       if(hostname)
-               fprintf(stderr, " [%s]", hostname);
-       fprintf(stderr, ": ");
-
-       if(!fgets(line, sizeof line, stdin)) {
-               fprintf(stderr, "Error while reading stdin: %s\n", strerror(errno));
-               free(hostname);
+       if(!hostname)
                return NULL;
-       }
-
-       if(!rstrip(line)) {
-               if(hostname)
-                       goto save;
-               else
-                       goto again;
-       }
-
-       for(char *p = line; *p; p++) {
-               if(isalnum(*p) || *p == '-' || *p == '.')
-                       continue;
-               fprintf(stderr, "Invalid address or hostname.\n");
-               goto again;
-       }
 
-       free(hostname);
-       hostname = xstrdup(line);
-
-save:
        f = fopen(filename, "a");
        if(f) {
                fprintf(f, "\nAddress = %s\n", hostname);
@@ -426,6 +394,7 @@ static bool finalize_join(meshlink_handle_t *mesh) {
        FILE *fh = fopen(filename, "w");
        if(!fh) {
                fprintf(stderr, "Could not create file %s: %s\n", filename, strerror(errno));
+               fclose(f);
                return false;
        }
 
@@ -548,7 +517,7 @@ static bool finalize_join(meshlink_handle_t *mesh) {
        return true;
 }
 
-static bool invitation_send(void *handle, uint8_t type, const char *data, size_t len) {
+static bool invitation_send(void *handle, uint8_t type, const void *data, size_t len) {
        meshlink_handle_t* mesh = handle;
        while(len) {
                int result = send(mesh->sock, data, len, 0);
@@ -562,7 +531,7 @@ static bool invitation_send(void *handle, uint8_t type, const char *data, size_t
        return true;
 }
 
-static bool invitation_receive(void *handle, uint8_t type, const char *msg, uint16_t len) {
+static bool invitation_receive(void *handle, uint8_t type, const void *msg, uint16_t len) {
        meshlink_handle_t* mesh = handle;
        switch(type) {
                case SPTPS_HANDSHAKE:
@@ -793,6 +762,11 @@ meshlink_handle_t *meshlink_open(const char *confbase, const char *name) {
        if(!read_server_config(mesh))
                return meshlink_close(mesh), NULL;
 
+#ifdef HAVE_MINGW
+       struct WSAData wsa_state;
+       WSAStartup(MAKEWORD(2, 2), &wsa_state);
+#endif
+
        // Setup up everything
        // TODO: we should not open listening sockets yet
 
@@ -827,7 +801,12 @@ bool meshlink_start(meshlink_handle_t *mesh) {
 }
 
 void meshlink_stop(meshlink_handle_t *mesh) {
-       // TODO: close the listening sockets to signal the main thread to shut down
+       // Shut down the listening sockets to signal the main thread to shut down
+
+       for(int i = 0; i < mesh->listen_sockets; i++) {
+               shutdown(mesh->listen_socket[i].tcp.fd, SHUT_RDWR);
+               shutdown(mesh->listen_socket[i].udp.fd, SHUT_RDWR);
+       }
 
        // Wait for the main thread to finish
 
@@ -843,6 +822,10 @@ void meshlink_close(meshlink_handle_t *mesh) {
 
        exit_configuration(&mesh->config);
        event_loop_exit(&mesh->loop);
+
+#ifdef HAVE_MINGW
+       WSACleanup();
+#endif
 }
 
 void meshlink_set_receive_cb(meshlink_handle_t *mesh, meshlink_receive_cb_t cb) {
@@ -910,14 +893,14 @@ static bool refresh_invitation_key(meshlink_handle_t *mesh) {
        snprintf(filename, sizeof filename, "%s" SLASH "invitations", mesh->confbase);
        if(mkdir(filename, 0700) && errno != EEXIST) {
                fprintf(stderr, "Could not create directory %s: %s\n", filename, strerror(errno));
-               return NULL;
+               return false;
        }
 
        // Count the number of valid invitations, clean up old ones
        DIR *dir = opendir(filename);
        if(!dir) {
                fprintf(stderr, "Could not read directory %s: %s\n", filename, strerror(errno));
-               return NULL;
+               return false;
        }
 
        errno = 0;
@@ -969,18 +952,18 @@ static bool refresh_invitation_key(meshlink_handle_t *mesh) {
        if(!f) {
                if(errno != ENOENT) {
                        fprintf(stderr, "Could not read %s: %s\n", filename, strerror(errno));
-                       return NULL;
+                       return false;
                }
 
                mesh->invitation_key = ecdsa_generate();
                if(!mesh->invitation_key) {
                        fprintf(stderr, "Could not generate a new key!\n");
-                       return NULL;
+                       return false;
                }
                f = fopen(filename, "w");
                if(!f) {
                        fprintf(stderr, "Could not write %s: %s\n", filename, strerror(errno));
-                       return NULL;
+                       return false;
                }
                chmod(filename, 0600);
                ecdsa_write_pem_private_key(mesh->invitation_key, f);
@@ -995,6 +978,17 @@ static bool refresh_invitation_key(meshlink_handle_t *mesh) {
        return mesh->invitation_key;
 }
 
+bool meshlink_add_address(meshlink_handle_t *mesh, const char *address) {
+       for(const char *p = address; *p; p++) {
+               if(isalnum(*p) || *p == '-' || *p == '.' || *p == ':')
+                       continue;
+               fprintf(stderr, "Invalid character in address: %s\n", address);
+               return false;
+       }
+
+       return append_config_file(mesh, mesh->self->name, "Address", address);
+}
+
 char *meshlink_invite(meshlink_handle_t *mesh, const char *name) {
        // Check validity of the new node's name
        if(!check_id(name)) {
@@ -1016,6 +1010,13 @@ char *meshlink_invite(meshlink_handle_t *mesh, const char *name) {
                return NULL;
        }
 
+       // Get the local address
+       char *address = get_my_hostname(mesh);
+       if(!address) {
+               fprintf(stderr, "No Address known for ourselves!\n");
+               return NULL;
+       }
+
        if(!refresh_invitation_key(mesh))
                return NULL;
 
@@ -1051,9 +1052,6 @@ char *meshlink_invite(meshlink_handle_t *mesh, const char *name) {
        if(!f)
                abort();
 
-       // Get the local address
-       char *address = get_my_hostname(mesh);
-
        // Fill in the details.
        fprintf(f, "Name = %s\n", name);
        //if(netname)
@@ -1242,6 +1240,15 @@ bool meshlink_import(meshlink_handle_t *mesh, const char *data) {
 }
 
 void meshlink_blacklist(meshlink_handle_t *mesh, meshlink_node_t *node) {
+    node_t *n;
+    n = (node_t*)node;
+    n->status.blacklisted=true;
+       fprintf(stderr, "Blacklisted %s.\n",node->name);
+
+       //Make blacklisting persistent in the config file
+       append_config_file(mesh, n->name, "blacklisted", "yes");
+    return;
+
 }
 
 static void __attribute__((constructor)) meshlink_init(void) {