thermferm/server.c

changeset 660
a28ef4d9afa4
parent 652
16d3d4b58b5b
child 665
66fae54fa7ba
--- a/thermferm/server.c	Wed Apr 03 19:33:38 2024 +0200
+++ b/thermferm/server.c	Fri Apr 05 16:19:39 2024 +0200
@@ -30,7 +30,6 @@
 #include "mqtt.h"
 
 
-extern int		my_shutdown;
 extern int		debug;
 extern int		run_pause;
 extern int		run_hold;
@@ -46,7 +45,8 @@
 
 
 int			my_server_state = 0;	/* Thread running state		*/
-int			s;			/* connected socket		*/
+int			my_server_shutdown = 0;	/* Thread shutdown		*/
+//int			s;			/* connected socket		*/
 int			ls;			/* listen socket		*/
 
 struct sockaddr_in	myaddr_in;		/* for local socket address	*/
@@ -83,7 +83,7 @@
 /*
  * Send message to client
  */
-int srv_send(const char *format, ...)
+int srv_send(int s, const char *format, ...)
 {
     char        out[SS_BUFSIZE];
     va_list     va_ptr;
@@ -120,7 +120,7 @@
  * Return -1 if error, else the number of received
  * character. \n is line end, ignore \r.
  */
-int srv_recv(char *buffer)
+int srv_recv(int s, char *buffer)
 {
     int			bytesloaded = 0;
     ssize_t		ret;
@@ -304,7 +304,7 @@
  * DEVICE GET uuid
  * DEVICE PUT uuid
  */
-int cmd_device(char *buf)
+int cmd_device(int s, char *buf)
 {
     char		*opt, *param, *kwd, *val, ibuf[SS_BUFSIZE];
     devices_list	*device, *tmpd;
@@ -315,35 +315,35 @@
     opt = strtok(NULL, " \0");
 
     if (opt == NULL) {
-	srv_send((char *)"501 Subcommand missing");
+	srv_send(s, (char *)"501 Subcommand missing");
 	return 0;
     }
     param = strtok(NULL, "\0");
 
     if (strcmp(opt, (char *)"HELP") == 0) {
-	srv_send((char *)"100 Help text follows:");
-	srv_send((char *)"Recognized commands:");
-	srv_send((char *)"DEVICE ADD type               Add device (RC433/DHT/I2C/SPI)");
-	srv_send((char *)"DEVICE DEL uuid               Delete device by uuid");
-	srv_send((char *)"DEVICE LIST                   List all devices");
-	srv_send((char *)"DEVICE GET uuid               Read device by uuid parameters");
-	srv_send((char *)"DEVICE PUT uuid               Write device by uuid parameters");
-	srv_send((char *)".");
+	srv_send(s, (char *)"100 Help text follows:");
+	srv_send(s, (char *)"Recognized commands:");
+	srv_send(s, (char *)"DEVICE ADD type               Add device (RC433/DHT/I2C/SPI)");
+	srv_send(s, (char *)"DEVICE DEL uuid               Delete device by uuid");
+	srv_send(s, (char *)"DEVICE LIST                   List all devices");
+	srv_send(s, (char *)"DEVICE GET uuid               Read device by uuid parameters");
+	srv_send(s, (char *)"DEVICE PUT uuid               Write device by uuid parameters");
+	srv_send(s, (char *)".");
 	return 0;
     }
 
     if (strcmp(opt, (char *)"LIST") == 0) {
-	srv_send((char *)"212 Devices list follows:");
+	srv_send(s, (char *)"212 Devices list follows:");
 	for (device = Config.devices; device; device = device->next) {
-	    srv_send((char *)"%s,%s,%d,%d,%s,%s,%d", device->uuid, device->address, device->subdevice,
+	    srv_send(s, (char *)"%s,%s,%d,%d,%s,%s,%d", device->uuid, device->address, device->subdevice,
 			    device->inuse, device->comment, DEVDIR[device->direction], device->value + device->offset);
 	}
-	srv_send((char *)".");
+	srv_send(s, (char *)".");
 	return 0;
     }
 
     if (param == NULL) {
-	srv_send((char *)"502 Parameter missing");
+	srv_send(s, (char *)"502 Parameter missing");
 	return 1;
     }
 
@@ -383,11 +383,11 @@
 	    }
 	    pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
 	    syslog(LOG_NOTICE, "Device %s added", device->uuid);
-	    srv_send((char *)"211 Device %s added", device->uuid);
+	    srv_send(s, (char *)"211 Device %s added", device->uuid);
 	    return 1;
 
 	} else {
-	    srv_send((char *)"503 Parameter error");
+	    srv_send(s, (char *)"503 Parameter error");
 	    return 0;
 	}
     }
@@ -399,10 +399,10 @@
 	pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
 	if (rc) {
 	    syslog(LOG_NOTICE, "Device %s deleted", param);
-	    srv_send((char *)"211 Device %s deleted", param);
+	    srv_send(s, (char *)"211 Device %s deleted", param);
 	    return 1;
 	} else {
-	    srv_send((char *)"440 No such device");
+	    srv_send(s, (char *)"440 No such device");
 	    return 0;
 	}
     }
@@ -414,24 +414,24 @@
 		int	my_value = device->value;
 		int	my_timestamp = (int)device->timestamp;
 		pthread_mutex_unlock(&mutexes[LOCK_DEVICES]);
-		srv_send((char *)"213 Device record follows:");
-		srv_send((char *)"TYPE,%s", DEVTYPE[device->type]);
-		srv_send((char *)"ADDRESS,%s", device->address);
-		srv_send((char *)"DIRECTION,%s", DEVDIR[device->direction]);
-		srv_send((char *)"VALUE,%d", my_value);
-		srv_send((char *)"OFFSET,%d", device->offset);
-		srv_send((char *)"PRESENT,%s", DEVPRESENT[device->present]);
-		srv_send((char *)"SUBDEVICE,%d", device->subdevice);
-		srv_send((char *)"GPIOPIN,%d", device->gpiopin);
-		srv_send((char *)"DESCRIPTION,%s", device->description);
-		srv_send((char *)"INUSE,%d", device->inuse);
-		srv_send((char *)"COMMENT,%s", device->comment);
-		srv_send((char *)"TIMESTAMP,%d", my_timestamp);
-		srv_send((char *)".");
+		srv_send(s, (char *)"213 Device record follows:");
+		srv_send(s, (char *)"TYPE,%s", DEVTYPE[device->type]);
+		srv_send(s, (char *)"ADDRESS,%s", device->address);
+		srv_send(s, (char *)"DIRECTION,%s", DEVDIR[device->direction]);
+		srv_send(s, (char *)"VALUE,%d", my_value);
+		srv_send(s, (char *)"OFFSET,%d", device->offset);
+		srv_send(s, (char *)"PRESENT,%s", DEVPRESENT[device->present]);
+		srv_send(s, (char *)"SUBDEVICE,%d", device->subdevice);
+		srv_send(s, (char *)"GPIOPIN,%d", device->gpiopin);
+		srv_send(s, (char *)"DESCRIPTION,%s", device->description);
+		srv_send(s, (char *)"INUSE,%d", device->inuse);
+		srv_send(s, (char *)"COMMENT,%s", device->comment);
+		srv_send(s, (char *)"TIMESTAMP,%d", my_timestamp);
+		srv_send(s, (char *)".");
 		return 0;
 	    }
 	}
-	srv_send((char *)"440 No such device");
+	srv_send(s, (char *)"440 No such device");
 	return 0;
     }
 
@@ -439,13 +439,13 @@
 	for (device = Config.devices; device; device = device->next) {
 	    if (strcmp(device->uuid, param) == 0) {
 		while (1) {
-		    rlen = srv_recv(ibuf);
+		    rlen = srv_recv(s, ibuf);
     		    if (rlen == -1) {
 			return 0;
 		    }
 		    if (strlen(ibuf)) {
 			if (strcmp(ibuf, (char *)".") == 0) {
-			    srv_send((char *)"219 Accepted Device record");
+			    srv_send(s, (char *)"219 Accepted Device record");
 			    return 1;
 			}
 			kwd = strtok(ibuf, ",\0");
@@ -559,11 +559,11 @@
 		}
 	    }
 	}
-	srv_send((char *)"440 No such device");
+	srv_send(s, (char *)"440 No such device");
 	return 0;
     }
 
-    srv_send((char *)"504 Subcommand error");
+    srv_send(s, (char *)"504 Subcommand error");
     return 0;
 }
 
@@ -573,7 +573,7 @@
  * GLOBAL GET
  * GLOBAL PUT
  */
-int cmd_global(char *buf)
+int cmd_global(int s, char *buf)
 {
     char	*opt, *kwd, *val, ibuf[SS_BUFSIZE];
     int		ival, rlen;
@@ -582,53 +582,53 @@
     opt = strtok(NULL, "\0");
 
     if (opt == NULL) {
-	srv_send((char *)"501 Subcommand missing");
+	srv_send(s, (char *)"501 Subcommand missing");
 	return 0;
     }
 
     if (strcmp(opt, (char *)"HELP") == 0) {
-	srv_send((char *)"100 Help text follows:");
-	srv_send((char *)"Recognized commands:");
-	srv_send((char *)"GLOBAL GET                    Get global settings");
-	srv_send((char *)"GLOBAL PUT                    Put global settings");
-	srv_send((char *)".");
+	srv_send(s, (char *)"100 Help text follows:");
+	srv_send(s, (char *)"Recognized commands:");
+	srv_send(s, (char *)"GLOBAL GET                    Get global settings");
+	srv_send(s, (char *)"GLOBAL PUT                    Put global settings");
+	srv_send(s, (char *)".");
 	return 0;
     }
 
     if (strcmp(opt, (char *)"GET") == 0) {
-	srv_send((char *)"213 Global Settings record follows:");
-	srv_send((char *)"RELEASE,%s", VERSION);
-	srv_send((char *)"NAME,%s", Config.name);
-	srv_send((char *)"PORT,%d", Config.my_port);
-	srv_send((char *)"TEMPFORMAT,%c", Config.tempFormat);
-	srv_send((char *)"TEMP_ADDRESS,%s", Config.temp_address);
-	srv_send((char *)"TEMP_STATE,%s", TEMPSTATE[Config.temp_state]);
-	srv_send((char *)"TEMP_VALUE,%.1f", Config.temp_value / 1000.0);
-	srv_send((char *)"HUM_ADDRESS,%s", Config.hum_address);
-	srv_send((char *)"HUM_STATE,%s", TEMPSTATE[Config.hum_state]);
-	srv_send((char *)"HUM_VALUE,%.0f", Config.hum_value / 1000.0);
-	srv_send((char *)"TEMP_HUM_IDX,%d", Config.temp_hum_idx);
-	srv_send((char *)"LCD_COLS,%d", Config.lcd_cols);
-	srv_send((char *)"LCD_ROWS,%d", Config.lcd_rows);
-	srv_send((char *)"NEXT_UNIT,%d", Config.next_unit);
-	srv_send((char *)"MQTT_HOST,%s", Config.mqtt_host);
-	srv_send((char *)"MQTT_PORT,%d", Config.mqtt_port);
-	srv_send((char *)"MQTT_USER,%s", Config.mqtt_username);
-	srv_send((char *)"MQTT_PASS,%s", Config.mqtt_password);
-	srv_send((char *)".");
+	srv_send(s, (char *)"213 Global Settings record follows:");
+	srv_send(s, (char *)"RELEASE,%s", VERSION);
+	srv_send(s, (char *)"NAME,%s", Config.name);
+	srv_send(s, (char *)"PORT,%d", Config.my_port);
+	srv_send(s, (char *)"TEMPFORMAT,%c", Config.tempFormat);
+	srv_send(s, (char *)"TEMP_ADDRESS,%s", Config.temp_address);
+	srv_send(s, (char *)"TEMP_STATE,%s", TEMPSTATE[Config.temp_state]);
+	srv_send(s, (char *)"TEMP_VALUE,%.1f", Config.temp_value / 1000.0);
+	srv_send(s, (char *)"HUM_ADDRESS,%s", Config.hum_address);
+	srv_send(s, (char *)"HUM_STATE,%s", TEMPSTATE[Config.hum_state]);
+	srv_send(s, (char *)"HUM_VALUE,%.0f", Config.hum_value / 1000.0);
+	srv_send(s, (char *)"TEMP_HUM_IDX,%d", Config.temp_hum_idx);
+	srv_send(s, (char *)"LCD_COLS,%d", Config.lcd_cols);
+	srv_send(s, (char *)"LCD_ROWS,%d", Config.lcd_rows);
+	srv_send(s, (char *)"NEXT_UNIT,%d", Config.next_unit);
+	srv_send(s, (char *)"MQTT_HOST,%s", Config.mqtt_host);
+	srv_send(s, (char *)"MQTT_PORT,%d", Config.mqtt_port);
+	srv_send(s, (char *)"MQTT_USER,%s", Config.mqtt_username);
+	srv_send(s, (char *)"MQTT_PASS,%s", Config.mqtt_password);
+	srv_send(s, (char *)".");
 	return 0;
     }
 
     if (strcmp(opt, (char *)"PUT") == 0) {
 	int mqtt_reconnect = 0;
 	while (1) {
-	    rlen = srv_recv(ibuf);
+	    rlen = srv_recv(s, ibuf);
 	    if (rlen == -1) {
 		return 0;
 	    }
 	    if (strlen(ibuf)) {
 		if (strcmp(ibuf, (char *)".") == 0) {
-		    srv_send((char *)"219 Accepted Global record");
+		    srv_send(s, (char *)"219 Accepted Global record");
 		    if (mqtt_reconnect)
 			mqtt_connect();
 		    return 1;
@@ -759,7 +759,7 @@
 	}
     }
 
-    srv_send((char *)"504 Subcommand error");
+    srv_send(s, (char *)"504 Subcommand error");
     return 0;
 }
 
@@ -768,7 +768,7 @@
 /*
  * LIST
  */
-int cmd_list(char *buf)
+int cmd_list(int s, char *buf)
 {
     char		*opt;
     units_list		*unit;
@@ -780,22 +780,22 @@
 	/*
 	 * Default, list available units
 	 */
-	srv_send((char *)"212 Fermenter list follows:");
+	srv_send(s, (char *)"212 Fermenter list follows:");
 	for (unit = Config.units; unit; unit = unit->next) {
-	    srv_send((char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]);
+	    srv_send(s, (char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]);
 	}
-	srv_send((char *)".");
+	srv_send(s, (char *)".");
 	return 0;
 
     } else if (strcmp(opt, (char *)"HELP") == 0) {
-	srv_send((char *)"100 Help text follows:");
-	srv_send((char *)"Recognized commands:");
-	srv_send((char *)"LIST                           List available units");
-	srv_send((char *)".");
+	srv_send(s, (char *)"100 Help text follows:");
+	srv_send(s, (char *)"Recognized commands:");
+	srv_send(s, (char *)"LIST                           List available units");
+	srv_send(s, (char *)".");
 	return 0;
     }
 
-    srv_send((char *)"504 Subcommand error");
+    srv_send(s, (char *)"504 Subcommand error");
     return 0;
 }
 
@@ -844,7 +844,7 @@
  * SIMULATOR GET uuid
  * SIMULATOR PUT uuid
  */
-int cmd_simulator(char *buf)
+int cmd_simulator(int s, char *buf)
 {
     char		*opt, *param, *kwd, *val, ibuf[SS_BUFSIZE];
     simulator_list	*simulator, *tmps;
@@ -856,34 +856,34 @@
     opt = strtok(NULL, " \0");
 
     if (opt == NULL) {
-	srv_send((char *)"501 Subcommand missing");
+	srv_send(s, (char *)"501 Subcommand missing");
 	return 0;
     }
     param = strtok(NULL, "\0");
 
     if (strcmp(opt, (char *)"HELP") == 0) {
-	srv_send((char *)"100 Help text follows:");
-	srv_send((char *)"Recognized commands:");
-	srv_send((char *)"SIMULATOR ADD name            Add a new Simulator with name");
-	srv_send((char *)"SIMULATOR DEL uuid            Delete Simulator by uuid");
-	srv_send((char *)"SIMULATOR LIST                List all Simulators");
-	srv_send((char *)"SIMULATOR GET uuid            Get Simulator record by uuid");
-	srv_send((char *)"SIMULATOR PUT uuid            Put Simulator record by uuid");
-	srv_send((char *)".");
+	srv_send(s, (char *)"100 Help text follows:");
+	srv_send(s, (char *)"Recognized commands:");
+	srv_send(s, (char *)"SIMULATOR ADD name            Add a new Simulator with name");
+	srv_send(s, (char *)"SIMULATOR DEL uuid            Delete Simulator by uuid");
+	srv_send(s, (char *)"SIMULATOR LIST                List all Simulators");
+	srv_send(s, (char *)"SIMULATOR GET uuid            Get Simulator record by uuid");
+	srv_send(s, (char *)"SIMULATOR PUT uuid            Put Simulator record by uuid");
+	srv_send(s, (char *)".");
 	return 0;
     }
 
     if (strcmp(opt, (char *)"LIST") == 0) {
-	srv_send((char *)"212 Simulators list follows:");
+	srv_send(s, (char *)"212 Simulators list follows:");
 	for (simulator = Config.simulators; simulator; simulator = simulator->next) {
-	    srv_send((char *)"%s,%s", simulator->uuid, simulator->name);
+	    srv_send(s, (char *)"%s,%s", simulator->uuid, simulator->name);
 	}
-	srv_send((char *)".");
+	srv_send(s, (char *)".");
 	return 0;
     }
 
     if (param == NULL) {
-	srv_send((char *)"502 Parameter missing");
+	srv_send(s, (char *)"502 Parameter missing");
 	return 0;
     }
 
@@ -893,7 +893,7 @@
 	 * For now, only one simulator is allowed.
 	 */
 	if (Config.simulators) {
-	    srv_send((char *)"441 Maximum simulators reached");
+	    srv_send(s, (char *)"441 Maximum simulators reached");
 	    return 0;
 	}
 
@@ -931,7 +931,7 @@
 	}
 
 	syslog(LOG_NOTICE, "Simulator %s added", simulator->uuid);
-	srv_send((char *)"211 Simulator %s added", simulator->uuid);
+	srv_send(s, (char *)"211 Simulator %s added", simulator->uuid);
 	return 1;
     }
 
@@ -939,10 +939,10 @@
 	rc = delete_Simulator(param);
 	if (rc) {
 	    syslog(LOG_NOTICE, "Simulator %s deleted", param);
-	    srv_send((char *)"211 Simulator %s deleted", param);
+	    srv_send(s, (char *)"211 Simulator %s deleted", param);
 	    return 1;
 	} else {
-	    srv_send((char *)"440 No such simulator");
+	    srv_send(s, (char *)"440 No such simulator");
 	    return 0;
 	}
     }
@@ -950,29 +950,29 @@
     if (strcmp(opt, (char *)"GET") == 0) {
 	for (simulator = Config.simulators; simulator; simulator = simulator->next) {
 	    if (strcmp(simulator->uuid, param) == 0) {
-		srv_send((char *)"213 Simulator record follows:");
-		srv_send((char *)"NAME,%s", simulator->name);
-		srv_send((char *)"VOLUME_AIR,%d", simulator->volume_air);
-		srv_send((char *)"VOLUME_BEER,%d", simulator->volume_beer);
-		srv_send((char *)"ROOM_TEMPERATURE,%.1f", simulator->room_temperature);
-		srv_send((char *)"ROOM_HUMIDITY,%.1f", simulator->room_humidity);
-		srv_send((char *)"AIR_TEMPERATURE,%.3f", simulator->air_temperature);
-		srv_send((char *)"BEER_TEMPERATURE,%.3f", simulator->beer_temperature);
-		srv_send((char *)"CHILLER_TEMPERATURE,%.3f", simulator->chiller_temperature);
-		srv_send((char *)"COOLER_TEMP,%.1f", simulator->cooler_temp);
-		srv_send((char *)"COOLER_TIME,%d", simulator->cooler_time);
-		srv_send((char *)"COOLER_SIZE,%.3f", simulator->cooler_size);
-		srv_send((char *)"HEATER_TEMP,%.1f", simulator->heater_temp);
-		srv_send((char *)"HEATER_TIME,%d", simulator->heater_time);
-		srv_send((char *)"HEATER_SIZE,%.3f", simulator->heater_size);
-		srv_send((char *)"HEATER_STATE,%d", simulator->heater_state);
-		srv_send((char *)"COOLER_STATE,%d", simulator->cooler_state);
-		srv_send((char *)"FRIGO_ISOLATION,%.3f", simulator->frigo_isolation);
-		srv_send((char *)".");
+		srv_send(s, (char *)"213 Simulator record follows:");
+		srv_send(s, (char *)"NAME,%s", simulator->name);
+		srv_send(s, (char *)"VOLUME_AIR,%d", simulator->volume_air);
+		srv_send(s, (char *)"VOLUME_BEER,%d", simulator->volume_beer);
+		srv_send(s, (char *)"ROOM_TEMPERATURE,%.1f", simulator->room_temperature);
+		srv_send(s, (char *)"ROOM_HUMIDITY,%.1f", simulator->room_humidity);
+		srv_send(s, (char *)"AIR_TEMPERATURE,%.3f", simulator->air_temperature);
+		srv_send(s, (char *)"BEER_TEMPERATURE,%.3f", simulator->beer_temperature);
+		srv_send(s, (char *)"CHILLER_TEMPERATURE,%.3f", simulator->chiller_temperature);
+		srv_send(s, (char *)"COOLER_TEMP,%.1f", simulator->cooler_temp);
+		srv_send(s, (char *)"COOLER_TIME,%d", simulator->cooler_time);
+		srv_send(s, (char *)"COOLER_SIZE,%.3f", simulator->cooler_size);
+		srv_send(s, (char *)"HEATER_TEMP,%.1f", simulator->heater_temp);
+		srv_send(s, (char *)"HEATER_TIME,%d", simulator->heater_time);
+		srv_send(s, (char *)"HEATER_SIZE,%.3f", simulator->heater_size);
+		srv_send(s, (char *)"HEATER_STATE,%d", simulator->heater_state);
+		srv_send(s, (char *)"COOLER_STATE,%d", simulator->cooler_state);
+		srv_send(s, (char *)"FRIGO_ISOLATION,%.3f", simulator->frigo_isolation);
+		srv_send(s, (char *)".");
 		return 0;
 	    }
 	}
-	srv_send((char *)"440 No such simulator");
+	srv_send(s, (char *)"440 No such simulator");
 	return 0;
     }
 
@@ -980,13 +980,13 @@
 	for (simulator = Config.simulators; simulator; simulator = simulator->next) {
 	    if (strcmp(simulator->uuid, param) == 0) {
 		while (1) {
-		    rlen = srv_recv(ibuf);
+		    rlen = srv_recv(s, ibuf);
 		    if (rlen == -1) {
 			return 0;
 		    }
 		    if (strlen(ibuf)) {
 			if (strcmp(ibuf, (char *)".") == 0) {
-			    srv_send((char *)"219 Accepted Simulator record");
+			    srv_send(s, (char *)"219 Accepted Simulator record");
 			    return 1;
 			}
 			kwd = strtok(ibuf, ",\0");
@@ -1119,11 +1119,11 @@
 		}
 	    }
 	}
-	srv_send((char *)"440 No such simulator");
+	srv_send(s, (char *)"440 No such simulator");
 	return 0;
     }
 
-    srv_send((char *)"504 Subcommand error");
+    srv_send(s, (char *)"504 Subcommand error");
     return 0;
 }
 #endif
@@ -1285,7 +1285,7 @@
  * UNIT GET uuid
  * UNIT PUT uuid
  */
-int cmd_unit(char *buf)
+int cmd_unit(int s, char *buf)
 {
     char                *opt, *param = NULL, *kwd, *val, ibuf[SS_BUFSIZE];
     units_list          *unit, *tmpu;
@@ -1297,38 +1297,38 @@
     opt = strtok(NULL, " \0");
 
     if (opt == NULL) {
-	srv_send((char *)"501 Subcommand missing");
+	srv_send(s, (char *)"501 Subcommand missing");
 	return 0;
     }
     param = strtok(NULL, "\0");
 
     if (strcmp(opt, (char *)"HELP") == 0) {
-	srv_send((char *)"100 Help text follows:");
-	srv_send((char *)"Recognized commands:");
-	srv_send((char *)"UNIT ADD name                 Add a new Unit with name");
-	srv_send((char *)"UNIT DEL uuid                 Delete Unit by uuid");
-	srv_send((char *)"UNIT LIST                     List all Units");
-	srv_send((char *)"UNIT GET uuid                 Get Unit record by uuid");
-	srv_send((char *)"UNIT PUT uuid                 Put Unit record by uuid");
-	srv_send((char *)".");
+	srv_send(s, (char *)"100 Help text follows:");
+	srv_send(s, (char *)"Recognized commands:");
+	srv_send(s, (char *)"UNIT ADD name                 Add a new Unit with name");
+	srv_send(s, (char *)"UNIT DEL uuid                 Delete Unit by uuid");
+	srv_send(s, (char *)"UNIT LIST                     List all Units");
+	srv_send(s, (char *)"UNIT GET uuid                 Get Unit record by uuid");
+	srv_send(s, (char *)"UNIT PUT uuid                 Put Unit record by uuid");
+	srv_send(s, (char *)".");
 	return 0;
     }
 
     if ((strcmp(opt, (char *)"LIST") == 0) && (param == NULL)) {
-	srv_send((char *)"212 Fermenter list follows:");
+	srv_send(s, (char *)"212 Fermenter list follows:");
 	for (unit = Config.units; unit; unit = unit->next) {
 	    if (strlen(unit->product_code) && strlen(unit->product_name)) {
-		srv_send((char *)"%s,%s %s,%s", unit->uuid, unit->product_code, unit->product_name, UNITMODE[unit->mode]);
+		srv_send(s, (char *)"%s,%s %s,%s", unit->uuid, unit->product_code, unit->product_name, UNITMODE[unit->mode]);
 	    } else {
-	    	srv_send((char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]);
+	    	srv_send(s, (char *)"%s,%s,%s", unit->uuid, unit->alias, UNITMODE[unit->mode]);
 	    }
 	}
-	srv_send((char *)".");
+	srv_send(s, (char *)".");
 	return 0;
     }
 
     if (param == NULL) {
-	srv_send((char *)"502 Parameter missing");
+	srv_send(s, (char *)"502 Parameter missing");
 	return 0;
     }
 
@@ -1396,7 +1396,7 @@
 	run_pause = FALSE;
 
 	syslog(LOG_NOTICE, "Unit %s added", unit->uuid);
-	srv_send((char *)"211 Unit %s added", unit->uuid);
+	srv_send(s, (char *)"211 Unit %s added", unit->uuid);
 	return 1;
     }
 
@@ -1417,10 +1417,10 @@
 
 	if (rc) {
 	    syslog(LOG_NOTICE, "Unit %s deleted", param);
-	    srv_send((char *)"211 Unit %s deleted", param);
+	    srv_send(s, (char *)"211 Unit %s deleted", param);
 	    return 1;
 	} else {
-	    srv_send((char *)"440 No such unit");
+	    srv_send(s, (char *)"440 No such unit");
 	    return 0;
 	}
     }
@@ -1428,102 +1428,102 @@
     if (strcmp(opt, (char *)"GET") == 0) {
 	for (unit = Config.units; unit; unit = unit->next) {
 	    if (strcmp(param, unit->uuid) == 0) {
-		srv_send((char *)"213 Unit listing follows:");
-		srv_send((char *)"UUID,%s", unit->uuid);
-		srv_send((char *)"ALIAS,%s", unit->alias);
-		srv_send((char *)"PRODUCT_NAME,%s", unit->product_name);
-		srv_send((char *)"PRODUCT_CODE,%s", unit->product_code);
-		srv_send((char *)"MODE,%s", UNITMODE[unit->mode]);
-		srv_send((char *)"STAGE,%s", UNITSTAGE[unit->stage]);
-		srv_send((char *)"VOLUME,%2f", unit->volume);
-		srv_send((char *)"AIR_ADDRESS,%s", unit->air_address);
-		srv_send((char *)"AIR_STATE,%s", TEMPSTATE[unit->air_state]);
-		srv_send((char *)"AIR_TEMPERATURE,%.3f", unit->air_temperature / 1000.0);
-		srv_send((char *)"AIR_IDX,%d", unit->air_idx);
-		srv_send((char *)"BEER_ADDRESS,%s", MBSE_SS(unit->beer_address));
-		srv_send((char *)"BEER_ADDRESS2,%s", MBSE_SS(unit->beer_address2));
-		srv_send((char *)"BEER_STATE,%s", TEMPSTATE[unit->beer_state]);
-		srv_send((char *)"BEER_TEMPERATURE,%.3f", unit->beer_temperature / 1000.0);
-		srv_send((char *)"BEER_IDX,%d", unit->beer_idx);
-		srv_send((char *)"CHILLER_ADDRESS,%s", MBSE_SS(unit->chiller_address));
-		srv_send((char *)"CHILLER_STATE,%s", TEMPSTATE[unit->chiller_state]);
-		srv_send((char *)"CHILLER_TEMPERATURE,%.3f", unit->chiller_temperature / 1000.0);
-		srv_send((char *)"CHILLER_IDX,%d", unit->chiller_idx);
-		srv_send((char *)"HEATER_ADDRESS,%s", unit->heater_address);
-		srv_send((char *)"HEATER_STATE,%d", unit->heater_state);
-		srv_send((char *)"HEATER_DELAY,%d", unit->heater_delay);
-		srv_send((char *)"HEATER_USAGE,%d", unit->heater_usage);
-		srv_send((char *)"HEATER_IDX,%d", unit->heater_idx);
+		srv_send(s, (char *)"213 Unit listing follows:");
+		srv_send(s, (char *)"UUID,%s", unit->uuid);
+		srv_send(s, (char *)"ALIAS,%s", unit->alias);
+		srv_send(s, (char *)"PRODUCT_NAME,%s", unit->product_name);
+		srv_send(s, (char *)"PRODUCT_CODE,%s", unit->product_code);
+		srv_send(s, (char *)"MODE,%s", UNITMODE[unit->mode]);
+		srv_send(s, (char *)"STAGE,%s", UNITSTAGE[unit->stage]);
+		srv_send(s, (char *)"VOLUME,%2f", unit->volume);
+		srv_send(s, (char *)"AIR_ADDRESS,%s", unit->air_address);
+		srv_send(s, (char *)"AIR_STATE,%s", TEMPSTATE[unit->air_state]);
+		srv_send(s, (char *)"AIR_TEMPERATURE,%.3f", unit->air_temperature / 1000.0);
+		srv_send(s, (char *)"AIR_IDX,%d", unit->air_idx);
+		srv_send(s, (char *)"BEER_ADDRESS,%s", MBSE_SS(unit->beer_address));
+		srv_send(s, (char *)"BEER_ADDRESS2,%s", MBSE_SS(unit->beer_address2));
+		srv_send(s, (char *)"BEER_STATE,%s", TEMPSTATE[unit->beer_state]);
+		srv_send(s, (char *)"BEER_TEMPERATURE,%.3f", unit->beer_temperature / 1000.0);
+		srv_send(s, (char *)"BEER_IDX,%d", unit->beer_idx);
+		srv_send(s, (char *)"CHILLER_ADDRESS,%s", MBSE_SS(unit->chiller_address));
+		srv_send(s, (char *)"CHILLER_STATE,%s", TEMPSTATE[unit->chiller_state]);
+		srv_send(s, (char *)"CHILLER_TEMPERATURE,%.3f", unit->chiller_temperature / 1000.0);
+		srv_send(s, (char *)"CHILLER_IDX,%d", unit->chiller_idx);
+		srv_send(s, (char *)"HEATER_ADDRESS,%s", unit->heater_address);
+		srv_send(s, (char *)"HEATER_STATE,%d", unit->heater_state);
+		srv_send(s, (char *)"HEATER_DELAY,%d", unit->heater_delay);
+		srv_send(s, (char *)"HEATER_USAGE,%d", unit->heater_usage);
+		srv_send(s, (char *)"HEATER_IDX,%d", unit->heater_idx);
 		if (unit->PID_heat) {
-		    srv_send((char *)"PIDH_IMAX,%.1f", unit->PID_heat->iMax);
-		    srv_send((char *)"PIDH_IDLERANGE,%.2f", unit->PID_heat->idleRange);
-		    srv_send((char *)"PIDH_PGAIN,%.3f", unit->PID_heat->pGain);
-		    srv_send((char *)"PIDH_IGAIN,%.3f", unit->PID_heat->iGain);
-		    srv_send((char *)"PIDH_DGAIN,%.3f", unit->PID_heat->dGain);
-		    srv_send((char *)"PIDH_SV,%.2f", unit->PID_heat->SetP);
+		    srv_send(s, (char *)"PIDH_IMAX,%.1f", unit->PID_heat->iMax);
+		    srv_send(s, (char *)"PIDH_IDLERANGE,%.2f", unit->PID_heat->idleRange);
+		    srv_send(s, (char *)"PIDH_PGAIN,%.3f", unit->PID_heat->pGain);
+		    srv_send(s, (char *)"PIDH_IGAIN,%.3f", unit->PID_heat->iGain);
+		    srv_send(s, (char *)"PIDH_DGAIN,%.3f", unit->PID_heat->dGain);
+		    srv_send(s, (char *)"PIDH_SV,%.2f", unit->PID_heat->SetP);
 		}
-		srv_send((char *)"COOLER_ADDRESS,%s", unit->cooler_address);
-		srv_send((char *)"COOLER_STATE,%d", unit->cooler_state);
-		srv_send((char *)"COOLER_DELAY,%d", unit->cooler_delay);
-		srv_send((char *)"COOLER_USAGE,%d", unit->cooler_usage);
-		srv_send((char *)"COOLER_IDX,%d", unit->cooler_idx);
+		srv_send(s, (char *)"COOLER_ADDRESS,%s", unit->cooler_address);
+		srv_send(s, (char *)"COOLER_STATE,%d", unit->cooler_state);
+		srv_send(s, (char *)"COOLER_DELAY,%d", unit->cooler_delay);
+		srv_send(s, (char *)"COOLER_USAGE,%d", unit->cooler_usage);
+		srv_send(s, (char *)"COOLER_IDX,%d", unit->cooler_idx);
 		if (unit->PID_cool) {
-		    srv_send((char *)"PIDC_IMAX,%.1f", unit->PID_cool->iMax);
-		    srv_send((char *)"PIDC_IDLERANGE,%.2f", unit->PID_cool->idleRange);
-		    srv_send((char *)"PIDC_PGAIN,%.3f", unit->PID_cool->pGain);
-		    srv_send((char *)"PIDC_IGAIN,%.3f", unit->PID_cool->iGain);
-		    srv_send((char *)"PIDC_DGAIN,%.3f", unit->PID_cool->dGain);
-		    srv_send((char *)"PIDC_SV,%.2f", unit->PID_cool->SetP);
+		    srv_send(s, (char *)"PIDC_IMAX,%.1f", unit->PID_cool->iMax);
+		    srv_send(s, (char *)"PIDC_IDLERANGE,%.2f", unit->PID_cool->idleRange);
+		    srv_send(s, (char *)"PIDC_PGAIN,%.3f", unit->PID_cool->pGain);
+		    srv_send(s, (char *)"PIDC_IGAIN,%.3f", unit->PID_cool->iGain);
+		    srv_send(s, (char *)"PIDC_DGAIN,%.3f", unit->PID_cool->dGain);
+		    srv_send(s, (char *)"PIDC_SV,%.2f", unit->PID_cool->SetP);
 		}
-		srv_send((char *)"FAN_ADDRESS,%s", unit->fan_address);
-		srv_send((char *)"FAN_STATE,%d", unit->fan_state);
-		srv_send((char *)"FAN_DELAY,%d", unit->fan_delay);
-		srv_send((char *)"FAN_USAGE,%d", unit->fan_usage);
-		srv_send((char *)"FAN_IDX,%d", unit->fan_idx);
-		srv_send((char *)"LIGHT_ADDRESS,%s", unit->light_address);
-		srv_send((char *)"LIGHT_STATE,%d", unit->light_state);
-		srv_send((char *)"LIGHT_DELAY,%d", unit->light_delay);
-		srv_send((char *)"LIGHT_USAGE,%d", unit->light_usage);
-		srv_send((char *)"LIGHT_IDX,%d", unit->light_idx);
-		srv_send((char *)"DOOR_ADDRESS,%s", unit->door_address);
-		srv_send((char *)"DOOR_STATE,%d", unit->door_state);
-		srv_send((char *)"DOOR_IDX,%d", unit->door_idx);
-		srv_send((char *)"PSU_ADDRESS,%s", unit->psu_address);
-		srv_send((char *)"PSU_STATE,%d", unit->psu_state);
-		srv_send((char *)"PSU_IDX,%d", unit->psu_idx);
-		srv_send((char *)"FRIDGE_SET_LO,%.1f", unit->fridge_set_lo);
-		srv_send((char *)"FRIDGE_SET_HI,%.1f", unit->fridge_set_hi);
-		srv_send((char *)"BEER_SET_LO,%.1f", unit->beer_set_lo);
-		srv_send((char *)"BEER_SET_HI,%.1f", unit->beer_set_hi);
+		srv_send(s, (char *)"FAN_ADDRESS,%s", unit->fan_address);
+		srv_send(s, (char *)"FAN_STATE,%d", unit->fan_state);
+		srv_send(s, (char *)"FAN_DELAY,%d", unit->fan_delay);
+		srv_send(s, (char *)"FAN_USAGE,%d", unit->fan_usage);
+		srv_send(s, (char *)"FAN_IDX,%d", unit->fan_idx);
+		srv_send(s, (char *)"LIGHT_ADDRESS,%s", unit->light_address);
+		srv_send(s, (char *)"LIGHT_STATE,%d", unit->light_state);
+		srv_send(s, (char *)"LIGHT_DELAY,%d", unit->light_delay);
+		srv_send(s, (char *)"LIGHT_USAGE,%d", unit->light_usage);
+		srv_send(s, (char *)"LIGHT_IDX,%d", unit->light_idx);
+		srv_send(s, (char *)"DOOR_ADDRESS,%s", unit->door_address);
+		srv_send(s, (char *)"DOOR_STATE,%d", unit->door_state);
+		srv_send(s, (char *)"DOOR_IDX,%d", unit->door_idx);
+		srv_send(s, (char *)"PSU_ADDRESS,%s", unit->psu_address);
+		srv_send(s, (char *)"PSU_STATE,%d", unit->psu_state);
+		srv_send(s, (char *)"PSU_IDX,%d", unit->psu_idx);
+		srv_send(s, (char *)"FRIDGE_SET_LO,%.1f", unit->fridge_set_lo);
+		srv_send(s, (char *)"FRIDGE_SET_HI,%.1f", unit->fridge_set_hi);
+		srv_send(s, (char *)"BEER_SET_LO,%.1f", unit->beer_set_lo);
+		srv_send(s, (char *)"BEER_SET_HI,%.1f", unit->beer_set_hi);
 		if (unit->profile_uuid) {
-		    srv_send((char *)"PROFILE_UUID,%s", unit->profile_uuid);
-		    srv_send((char *)"PROFILE_NAME,%s", unit->profile_name);
-		    srv_send((char *)"PROFILE_INITTEMP_LO,%.1f", unit->profile_inittemp_lo);
-		    srv_send((char *)"PROFILE_INITTEMP_HI,%.1f", unit->profile_inittemp_hi);
-		    srv_send((char *)"PROFILE_FRIDGE_MODE,%d", unit->profile_fridge_mode);
-		    srv_send((char *)"PROFILE_DURATION,%d", unit->profile_duration);
-		    srv_send((char *)"PROFILE_TOTALSTEPS,%d", unit->profile_totalsteps);
-		    srv_send((char *)"PROF_STARTED,%d", (int)unit->prof_started);
+		    srv_send(s, (char *)"PROFILE_UUID,%s", unit->profile_uuid);
+		    srv_send(s, (char *)"PROFILE_NAME,%s", unit->profile_name);
+		    srv_send(s, (char *)"PROFILE_INITTEMP_LO,%.1f", unit->profile_inittemp_lo);
+		    srv_send(s, (char *)"PROFILE_INITTEMP_HI,%.1f", unit->profile_inittemp_hi);
+		    srv_send(s, (char *)"PROFILE_FRIDGE_MODE,%d", unit->profile_fridge_mode);
+		    srv_send(s, (char *)"PROFILE_DURATION,%d", unit->profile_duration);
+		    srv_send(s, (char *)"PROFILE_TOTALSTEPS,%d", unit->profile_totalsteps);
+		    srv_send(s, (char *)"PROF_STARTED,%d", (int)unit->prof_started);
 		    if (unit->prof_state == PROFILE_RUN) {
-		    	srv_send((char *)"PROF_STATE,%s %d%%", PROFSTATE[unit->prof_state], unit->prof_percent);
+		    	srv_send(s, (char *)"PROF_STATE,%s %d%%", PROFSTATE[unit->prof_state], unit->prof_percent);
 		    } else {
-		    	srv_send((char *)"PROF_STATE,%s", PROFSTATE[unit->prof_state]);
+		    	srv_send(s, (char *)"PROF_STATE,%s", PROFSTATE[unit->prof_state]);
 		    }
-		    srv_send((char *)"PROF_TARGET_LO,%.3f", unit->prof_target_lo);
-		    srv_send((char *)"PROF_TARGET_HI,%.3f", unit->prof_target_hi);
-		    srv_send((char *)"PROF_FRIDGE_MODE,%d", unit->prof_fridge_mode);
-		    srv_send((char *)"PROF_PEAK_ABS,%.3f", unit->prof_peak_abs);
-		    srv_send((char *)"PROF_PEAK_REL,%.3f", unit->prof_peak_rel);
-		    srv_send((char *)"PROF_PRIMARY_DONE,%d", (int)unit->prof_primary_done);
+		    srv_send(s, (char *)"PROF_TARGET_LO,%.3f", unit->prof_target_lo);
+		    srv_send(s, (char *)"PROF_TARGET_HI,%.3f", unit->prof_target_hi);
+		    srv_send(s, (char *)"PROF_FRIDGE_MODE,%d", unit->prof_fridge_mode);
+		    srv_send(s, (char *)"PROF_PEAK_ABS,%.3f", unit->prof_peak_abs);
+		    srv_send(s, (char *)"PROF_PEAK_REL,%.3f", unit->prof_peak_rel);
+		    srv_send(s, (char *)"PROF_PRIMARY_DONE,%d", (int)unit->prof_primary_done);
 		}
-		srv_send((char *)"TEMP_SET_MIN,%.1f", unit->temp_set_min);
-		srv_send((char *)"TEMP_SET_MAX,%.1f", unit->temp_set_max);
-		srv_send((char *)"ALARM,%d", unit->alarm_flag);
-		srv_send((char *)".");
+		srv_send(s, (char *)"TEMP_SET_MIN,%.1f", unit->temp_set_min);
+		srv_send(s, (char *)"TEMP_SET_MAX,%.1f", unit->temp_set_max);
+		srv_send(s, (char *)"ALARM,%d", unit->alarm_flag);
+		srv_send(s, (char *)".");
 		return 0;
 	    }
 	}
-	srv_send((char *)"440 No such unit");
+	srv_send(s, (char *)"440 No such unit");
 	return 0;
     }
 
@@ -1542,14 +1542,14 @@
 	     if (strcmp(unit->uuid, param) == 0) {
 		while (1) {
 		    unit->mqtt_flag = 0;
-		    rlen = srv_recv(ibuf);
+		    rlen = srv_recv(s, ibuf);
 		    if (rlen == -1) {
 			run_pause = FALSE;
 			return 0;
 		    }
 		    if (strlen(ibuf)) {
 			if (strcmp(ibuf, (char *)".") == 0) {
-			    srv_send((char *)"219 Accepted Unit record");
+			    srv_send(s, (char *)"219 Accepted Unit record");
 			    run_pause = FALSE;
 			    return 1;
 			}
@@ -2068,74 +2068,74 @@
 		}
 	    }
 	}
-	srv_send((char *)"440 No such unit");
+	srv_send(s, (char *)"440 No such unit");
 	run_pause = FALSE;
 	return 0;
     }
 
-    srv_send((char *)"504 Subcommand error");
+    srv_send(s, (char *)"504 Subcommand error");
     return 0;
 }
 
 
 
-void cmd_server(void)
+void cmd_server(int s)
 {
     char                buf[SS_BUFSIZE];
     int                 rlen;
 
-    rlen = srv_recv(buf);
+    rlen = srv_recv(s, buf);
     if (rlen != -1) {
 	if (strlen(buf)) {
 	    /*
 	     * Process commands from the client
 	     */
 	    if (strncmp(buf, "DEVICE", 6) == 0) {
-		if (cmd_device(buf))
+		if (cmd_device(s, buf))
 		    wrconfig();
 
 	    } else if (strncmp(buf, "GLOBAL", 6) == 0) {
-		if (cmd_global(buf))
+		if (cmd_global(s, buf))
 		    wrconfig();
 
 	    } else if (strncmp(buf, "HELP", 4) == 0) {
-		srv_send((char *)"100 Help text follows");
-		srv_send((char *)"Recognized commands:");
-		srv_send((char *)"");
+		srv_send(s, (char *)"100 Help text follows");
+		srv_send(s, (char *)"Recognized commands:");
+		srv_send(s, (char *)"");
 //                                12345678901234567890123456789012345678901234567890123456789012345678901234567890
-		srv_send((char *)"DEVICE <CMD> [parameters]     Device commands");
-		srv_send((char *)"DEVICE HELP                   Device help screen");
-		srv_send((char *)"GLOBAL <CMD> [parameters]     Global commands");
-		srv_send((char *)"GLOBAL HELP                   Global help screen");
-		srv_send((char *)"LIST <CMD> [parameters]       List commands");
-		srv_send((char *)"LIST HELP                     List help screen");
-		srv_send((char *)"PING                          Check if server is alive");
+		srv_send(s, (char *)"DEVICE <CMD> [parameters]     Device commands");
+		srv_send(s, (char *)"DEVICE HELP                   Device help screen");
+		srv_send(s, (char *)"GLOBAL <CMD> [parameters]     Global commands");
+		srv_send(s, (char *)"GLOBAL HELP                   Global help screen");
+		srv_send(s, (char *)"LIST <CMD> [parameters]       List commands");
+		srv_send(s, (char *)"LIST HELP                     List help screen");
+		srv_send(s, (char *)"PING                          Check if server is alive");
 #ifdef USE_SIMULATOR
-		srv_send((char *)"SIMULATOR <CMD> [parameters]  Simulator commands");
-		srv_send((char *)"SIMULATOR HELP                Simulator help screen");
+		srv_send(s, (char *)"SIMULATOR <CMD> [parameters]  Simulator commands");
+		srv_send(s, (char *)"SIMULATOR HELP                Simulator help screen");
 #endif
-		srv_send((char *)"UNIT <CMD> [parameters]       Unit commands");
-		srv_send((char *)"UNIT HELP                     Unit help screen");
-		srv_send((char *)".");
+		srv_send(s, (char *)"UNIT <CMD> [parameters]       Unit commands");
+		srv_send(s, (char *)"UNIT HELP                     Unit help screen");
+		srv_send(s, (char *)".");
 
 	    } else if (strncmp(buf, "LIST", 4) == 0) {
-		cmd_list(buf);
+		cmd_list(s, buf);
 
 	    } else if (strncmp(buf, "PING", 4) == 0) {
-		srv_send((char *)"101 PONG");
+		srv_send(s, (char *)"101 PONG");
 
 #ifdef USE_SIMULATOR
 	    } else if (strncmp(buf, "SIMULATOR", 9) == 0) {
-		if (cmd_simulator(buf))
+		if (cmd_simulator(s, buf))
 		    wrconfig();
 
 #endif
 	    } else if (strncmp(buf, "UNIT", 4) == 0) {
-		if (cmd_unit(buf))
+		if (cmd_unit(s, buf))
 		    wrconfig();
 
 	    } else {
-		srv_send((char *)"500 Unknown command");
+		srv_send(s, (char *)"500 Unknown command");
 	    }
 	}
     }
@@ -2144,17 +2144,31 @@
 }
 
 
+static void cleanup_handler(void *arg)
+{
+    syslog(LOG_NOTICE, "Thread my_server_loop stopped (cleanup_handler)");
+    close(ls);
+    my_server_state = 0;
+}
+
 
 void *my_server_loop(void *threadid)
 {
     socklen_t   addrlen;
-    int         optval = 1;
+    int         s, optval = 1;
 
     my_server_state = 1;
     syslog(LOG_NOTICE, "Thread my_server_loop started");
     if (debug)
 	fprintf(stdout, "Thread my_server_loop started\n");
 
+    /*
+     * Prepare thread to stop in blocking accept() call.
+     */
+    pthread_cleanup_push(cleanup_handler, NULL);
+    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+    pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+
     memset((char *)&myaddr_in, 0, sizeof(struct sockaddr_in));
     memset((char *)&peeraddr_in, 0, sizeof(struct sockaddr_in));
     myaddr_in.sin_family = AF_INET;
@@ -2176,12 +2190,12 @@
 	return 0;
     }
 
-    if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
-	syslog(LOG_NOTICE, "Can't setsockopt SO_REUSEADDR socket: %s", strerror(errno));
-	close(ls);
-	my_server_state = 0;
-	return 0;
-    }
+//    if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) == -1) {
+//	syslog(LOG_NOTICE, "Can't setsockopt SO_REUSEADDR socket: %s", strerror(errno));
+//	close(ls);
+//	my_server_state = 0;
+//	return 0;
+//    }
 
     if (bind(ls, (struct sockaddr *)&myaddr_in, sizeof(struct sockaddr_in)) == -1) {
 	syslog(LOG_NOTICE, "Can't bind to listen socket: %s", strerror(errno));
@@ -2199,7 +2213,6 @@
 
     syslog(LOG_NOTICE, "listen socket created %d", ls);
 
-
     /*
      * Loop forever until the external shutdown variable is set.
      */
@@ -2213,25 +2226,26 @@
 	 * descriptor, s, for that connection.
 	 */
 	s = accept(ls, (struct sockaddr *)&peeraddr_in, &addrlen);
+	syslog(LOG_NOTICE, "my_server_loop accept socket %d", s);
 	if (s == -1) {
 	    syslog(LOG_NOTICE, "my_server_loop accept failed %s", strerror(errno));
-	    if (debug)
-		fprintf(stdout, "my_server_loop accept failed %s\n", strerror(errno));
-	    my_server_state = 0;
-	    return 0;
+	    break;
 	}
-
-	cmd_server();
+	if (my_server_shutdown)
+	    break;
 
-	if (my_shutdown) {
-	    syslog(LOG_NOTICE, "Thread my_server_loop stopped");
-	    if (debug)
-		fprintf(stdout, "Thread my_server_loop stopped\n");
-	    my_server_state = 0;
-	    return 0;
-	}
+	cmd_server(s);
+
+	if (my_server_shutdown)
+	    break;
 	mDelay(100);
     }
+
+    close(ls);
+    pthread_cleanup_pop(my_server_state);
+    syslog(LOG_NOTICE, "Thread my_server_loop stopped");
+    my_server_state = 0;
+    return 0;
 }
 
 

mercurial