// String comparison which handles NULL arguments
static bool safe_streq(const char *a, const char *b) {
- if (!a || !b)
+ if(!a || !b) {
return a == b;
- else
+ } else {
return !strcmp(a, b);
+ }
}
// This gets the hostname part for use in invitation URLs
hostname[2] = meshlink_get_external_address_for_family(mesh, AF_INET6);
// Concatenate all unique address to the hostport string
- for (int i = 0; i < 3; i++) {
- if (!hostname[i])
+ for(int i = 0; i < 3; i++) {
+ if(!hostname[i]) {
continue;
+ }
// Ignore duplicate hostnames
bool found = false;
- for (int j = 0; i < j; j++) {
- if (safe_streq(hostname[i], hostname[j]) && safe_streq(port[i], port[j])) {
+ for(int j = 0; i < j; j++) {
+ if(safe_streq(hostname[i], hostname[j]) && safe_streq(port[i], port[j])) {
found = true;
break;
}
}
- if (found) {
+ if(found) {
free(hostname[i]);
free(port[i]);
hostname[i] = NULL;
[MESHLINK_ESTORAGE] = "Storage error",
[MESHLINK_ENETWORK] = "Network error",
[MESHLINK_EPEER] = "Error communicating with peer",
+ [MESHLINK_ENOTSUP] = "Operation not supported",
+ [MESHLINK_EBUSY] = "MeshLink instance already in use",
};
const char *meshlink_strerror(meshlink_errno_t err) {
}
}
+ // Open the configuration file and lock it
+
+ mesh->conffile = fopen(filename, "r");
+
+ if(!mesh->conffile) {
+ logger(NULL, MESHLINK_ERROR, "Cannot not open %s: %s\n", filename, strerror(errno));
+ meshlink_close(mesh);
+ meshlink_errno = MESHLINK_ESTORAGE;
+ return NULL;
+ }
+
+#ifdef FD_CLOEXEC
+ fcntl(fileno(mesh->conffile), F_SETFD, FD_CLOEXEC);
+#endif
+
+#ifdef HAVE_MINGW
+ // TODO: use _locking()?
+#else
+
+ if(flock(fileno(mesh->conffile), LOCK_EX | LOCK_NB) != 0) {
+ logger(NULL, MESHLINK_ERROR, "Cannot lock %s: %s\n", filename, strerror(errno));
+ meshlink_close(mesh);
+ meshlink_errno = MESHLINK_EBUSY;
+ return NULL;
+ }
+
+#endif
+
// Read the configuration
init_configuration(&mesh->config);
free(mesh->confbase);
pthread_mutex_destroy(&(mesh->mesh_mutex));
+ if(mesh->conffile) {
+ fclose(mesh->conffile);
+ }
+
memset(mesh, 0, sizeof(*mesh));
free(mesh);