diff options
| author | Jonathan McCrohan <jmccrohan@gmail.com> | 2018-02-18 21:31:59 +0000 | 
|---|---|---|
| committer | Jonathan McCrohan <jmccrohan@gmail.com> | 2018-02-18 21:31:59 +0000 | 
| commit | e5837c658b65cea29dc0c96811dda305382a8262 (patch) | |
| tree | e73e9beb6579ad7810b5641ad4c5df99817b40e4 | |
| parent | 55b5c68b79748789dd2f374e21db9e883f4b8d84 (diff) | |
| parent | 1fc41b776f712f321c1f355d391c6a5eaf79ebfa (diff) | |
| download | wavemon-e5837c658b65cea29dc0c96811dda305382a8262.tar.gz | |
Update upstream source from tag 'upstream/0.8.2'
Update to upstream version '0.8.2'
with Debian dir 99713d8c3f398f90062f7a8b1d890dd7de10fea5
| -rw-r--r-- | Makefile.in | 2 | ||||
| -rw-r--r-- | about_scr.c | 3 | ||||
| -rwxr-xr-x | configure | 40 | ||||
| -rw-r--r-- | configure.ac | 2 | ||||
| -rw-r--r-- | info_scr.c | 75 | ||||
| -rw-r--r-- | iw_if.c | 49 | ||||
| -rw-r--r-- | iw_if.h | 34 | ||||
| -rw-r--r-- | iw_nl80211.c | 2 | ||||
| -rw-r--r-- | iw_scan.c | 56 | ||||
| -rw-r--r-- | scan_scr.c | 6 | ||||
| -rw-r--r-- | wavemon.h | 2 | 
11 files changed, 64 insertions, 207 deletions
| diff --git a/Makefile.in b/Makefile.in index d2e1c01..c9ecc37 100644 --- a/Makefile.in +++ b/Makefile.in @@ -20,7 +20,7 @@ RM	= rm -vf  MAIN	= @PACKAGE_NAME@.c  HEADERS	= $(wildcard *.h) -PURESRC	= $(filter-out $(MAIN),$(wildcard *.c)) +PURESRC	= $(filter-out $(MAIN),$(sort $(wildcard *.c)))  OBJS	= $(PURESRC:.c=.o)  DOCS	= README.md NEWS THANKS AUTHORS COPYING ChangeLog diff --git a/about_scr.c b/about_scr.c index fb4c080..76adaba 100644 --- a/about_scr.c +++ b/about_scr.c @@ -29,9 +29,6 @@ static char *about_lines[] = {  	"original by jan morgenstern <jan@jm-music.de>",  	"distributed under the GNU general public license v3",  	"", -	"please send suggestions and bug reports to ", -	PACKAGE_BUGREPORT, -	"",  	PACKAGE_URL  }; @@ -1,8 +1,8 @@  #! /bin/sh  # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for wavemon 0.8.0. +# Generated by GNU Autoconf 2.69 for wavemon 0.8.2.  # -# Report bugs to <gerrit@erg.abdn.ac.uk>. +# Report bugs to <https://github.com/uoaerg/wavemon>.  #  #  # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -267,10 +267,10 @@ fi      $as_echo "$0: be upgraded to zsh 4.3.4 or later."    else      $as_echo "$0: Please tell bug-autoconf@gnu.org and -$0: gerrit@erg.abdn.ac.uk about your system, including any -$0: error possibly output before this message. Then install -$0: a modern shell, or manually run the script under such a -$0: shell if you do have one." +$0: https://github.com/uoaerg/wavemon about your system, +$0: including any error possibly output before this +$0: message. Then install a modern shell, or manually run +$0: the script under such a shell if you do have one."    fi    exit 1  fi @@ -580,9 +580,9 @@ MAKEFLAGS=  # Identity of this package.  PACKAGE_NAME='wavemon'  PACKAGE_TARNAME='wavemon-current' -PACKAGE_VERSION='0.8.0' -PACKAGE_STRING='wavemon 0.8.0' -PACKAGE_BUGREPORT='gerrit@erg.abdn.ac.uk' +PACKAGE_VERSION='0.8.2' +PACKAGE_STRING='wavemon 0.8.2' +PACKAGE_BUGREPORT='https://github.com/uoaerg/wavemon'  PACKAGE_URL='https://github.com/uoaerg/wavemon'  # Factoring default headers for most tests. @@ -1249,7 +1249,7 @@ if test "$ac_init_help" = "long"; then    # Omit some internal or obsolete options to make the list less imposing.    # This message is too long to be a string in the A/UX 3.1 sh.    cat <<_ACEOF -\`configure' configures wavemon 0.8.0 to adapt to many kinds of systems. +\`configure' configures wavemon 0.8.2 to adapt to many kinds of systems.  Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1314,7 +1314,7 @@ fi  if test -n "$ac_init_help"; then    case $ac_init_help in -     short | recursive ) echo "Configuration of wavemon 0.8.0:";; +     short | recursive ) echo "Configuration of wavemon 0.8.2:";;     esac    cat <<\_ACEOF @@ -1343,7 +1343,7 @@ Some influential environment variables:  Use these variables to override the choices made by `configure' or to help  it to find libraries and programs with nonstandard names/locations. -Report bugs to <gerrit@erg.abdn.ac.uk>. +Report bugs to <https://github.com/uoaerg/wavemon>.  wavemon home page: <https://github.com/uoaerg/wavemon>.  _ACEOF  ac_status=$? @@ -1407,7 +1407,7 @@ fi  test -n "$ac_init_help" && exit $ac_status  if $ac_init_version; then    cat <<\_ACEOF -wavemon configure 0.8.0 +wavemon configure 0.8.2  generated by GNU Autoconf 2.69  Copyright (C) 2012 Free Software Foundation, Inc. @@ -1608,9 +1608,9 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}  $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5  $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## ------------------------------------ ## -## Report this to gerrit@erg.abdn.ac.uk ## -## ------------------------------------ ##" +( $as_echo "## ------------------------------------------------ ## +## Report this to https://github.com/uoaerg/wavemon ## +## ------------------------------------------------ ##"       ) | sed "s/^/$as_me: WARNING:     /" >&2      ;;  esac @@ -1830,7 +1830,7 @@ cat >config.log <<_ACEOF  This file contains any messages produced by compilers while  running configure, to aid debugging if configure makes a mistake. -It was created by wavemon $as_me 0.8.0, which was +It was created by wavemon $as_me 0.8.2, which was  generated by GNU Autoconf 2.69.  Invocation command line was    $ $0 $@ @@ -4955,7 +4955,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1  # report actual input values of CONFIG_FILES etc. instead of their  # values after options handling.  ac_log=" -This file was extended by wavemon $as_me 0.8.0, which was +This file was extended by wavemon $as_me 0.8.2, which was  generated by GNU Autoconf 2.69.  Invocation command line was    CONFIG_FILES    = $CONFIG_FILES @@ -5002,14 +5002,14 @@ Usage: $0 [OPTION]... [TAG]...  Configuration files:  $config_files -Report bugs to <gerrit@erg.abdn.ac.uk>. +Report bugs to <https://github.com/uoaerg/wavemon>.  wavemon home page: <https://github.com/uoaerg/wavemon>."  _ACEOF  cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1  ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"  ac_cs_version="\\ -wavemon config.status 0.8.0 +wavemon config.status 0.8.2  configured by $0, generated by GNU Autoconf 2.69,    with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 7132dea..323b96c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@  dnl Process this file with autoconf to produce a configure script.  AC_PREREQ(2.64) -AC_INIT([wavemon], [0.8.0], [gerrit@erg.abdn.ac.uk], [wavemon-current], +AC_INIT([wavemon], [0.8.2], [https://github.com/uoaerg/wavemon], [wavemon-current],  	[https://github.com/uoaerg/wavemon]) @@ -53,6 +53,7 @@ static void *sampling_loop(void *arg)  void sampling_init(void)  { +	pthread_mutex_init(&linkstat.mutex, NULL);  	linkstat.run = true;  	pthread_create(&sampling_thread, NULL, sampling_loop, NULL);  } @@ -61,6 +62,7 @@ void sampling_stop(void)  {  	linkstat.run = false;  	pthread_join(sampling_thread, NULL); +	pthread_mutex_destroy(&linkstat.mutex);  }  static void display_levels(void) @@ -78,7 +80,6 @@ static void display_levels(void)  	bool noise_data_valid;  	int sig_qual = -1, sig_qual_max, sig_level; -  	noise_data_valid = iw_nl80211_have_survey_data(&linkstat.data);  	sig_level = linkstat.data.signal_avg ?: linkstat.data.signal; @@ -103,12 +104,6 @@ static void display_levels(void)  		sig_qual_max = 70;  	} -	if (sig_qual == -1 && !sig_level && !noise_data_valid) { -		wattron(w_levels, A_BOLD); -		waddstr_center(w_levels, (WH_LEVEL + 1)/2, "NO INTERFACE DATA"); -		goto done_levels; -	} -  	line = 1;  	/* Noise data is rare. Use the space for spreading out. */ @@ -173,7 +168,6 @@ static void display_levels(void)  		waddstr_b(w_levels, tmp);  	} -done_levels:  	wrefresh(w_levels);  } @@ -211,7 +205,8 @@ static void display_stats(void)  	if (linkstat.data.rx_drop_misc) {  		waddstr(w_stats, ", drop: "); -		sprintf(tmp, "%'llu", (unsigned long long)linkstat.data.rx_drop_misc); +		sprintf(tmp, "%'llu (%.1f%%)", (unsigned long long)linkstat.data.rx_drop_misc, +				(1e2 * linkstat.data.rx_drop_misc)/linkstat.data.rx_packets);  		waddstr_b(w_stats, tmp);  	} @@ -237,7 +232,8 @@ static void display_stats(void)  	if (linkstat.data.tx_retries) {  		waddstr(w_stats, ", retries: "); -		sprintf(tmp, "%'u", linkstat.data.tx_retries); +		sprintf(tmp, "%'u (%.1f%%)", linkstat.data.tx_retries, +			(1e2 * linkstat.data.tx_retries)/linkstat.data.tx_packets);  		waddstr_b(w_stats, tmp);  	} @@ -257,10 +253,9 @@ static void display_info(WINDOW *w_if, WINDOW *w_info)  	struct iw_nl80211_ifstat ifs;  	struct iw_nl80211_reg ir;  	char tmp[0x100]; -	int i;  	iw_getinf_range(conf_ifname(), &range); -	dyn_info_get(&info, conf_ifname(), &range); +	dyn_info_get(&info, conf_ifname());  	iw_nl80211_getifstat(&ifs);  	iw_nl80211_getreg(&ir); @@ -530,63 +525,11 @@ static void display_info(WINDOW *w_if, WINDOW *w_info)  	}  	wclrtoborder(w_info); +	/* FIXME: re-enable encryption information (issue #8)  	wmove(w_info, 7, 1);  	waddstr(w_info, "encryption: "); -	if (info.keys) { -		int cnt = dyn_info_active_keys(&info); - -		if (cnt == 0) { -			waddstr_b(w_info, "off (no key set)"); -		} else if (info.active_key) { -			i = info.active_key - 1; -			waddstr_b(w_info, curtail(format_key(info.keys + i), -					  "..", MAXXLEN/2)); - -			if (info.keys[i].flags & IW_ENCODE_RESTRICTED) -				waddstr(w_info, ", restricted"); -			if (info.keys[i].flags & IW_ENCODE_OPEN) -				waddstr(w_info, ", open"); - -			/* First key = default */ -			if (cnt > 1 || info.active_key != 1) { -				sprintf(tmp, " [%d]", info.active_key); -				waddstr_b(w_info, tmp); -			} -			if (cnt > 1) { -				sprintf(tmp, " (%d other key%s)", cnt - 1, -					cnt == 2 ? "" : "s"); -				waddstr(w_info, tmp); -			} -		} else  if (dyn_info_wep_keys(&info) == cnt) { -			waddstr_b(w_info, "off "); -			sprintf(tmp, "(%d disabled WEP key%s)", cnt, -				cnt == 1 ? "" : "s"); -			waddstr(w_info, tmp); -		} else { -			uint8_t j = 0, k = 0; - -			do  if (info.keys[j].size && -				!(info.keys[j].flags & IW_ENCODE_DISABLED)) -					info.keys[k++].size = info.keys[j].size; -			while (k < cnt && ++j < info.nkeys); - -			if (cnt == 1) -				j = sprintf(tmp, "1 key (index #%u), ", j + 1); -			else -				j = sprintf(tmp, "%d keys with ", k); -			for (i = 0; i < k; i++) -				j += sprintf(tmp + j, "%s%d",	i ? "/" : "", -					     info.keys[i].size * 8); -			sprintf(tmp + j, " bits"); -			waddstr_b(w_info, tmp); -		} -	} else if (has_net_admin_capability()) { -		waddstr(w_info, "no information available"); -	} else { -		waddstr(w_info, "n/a (requires CAP_NET_ADMIN permissions)"); -	} +	*/ -	dyn_info_cleanup(&info);  	wclrtoborder(w_info);  	wrefresh(w_info);  } @@ -154,11 +154,10 @@ void iw_get_interface_list(char** if_list, size_t max_entries)   * @ifname: interface name   * @if:	    range information to use (number of encryption keys)   */ -void dyn_info_get(struct iw_dyn_info *info, -		  const char *ifname, struct iw_range *ir) +void dyn_info_get(struct iw_dyn_info *info, const char *ifname)  {  	struct iwreq iwr; -	int i, skfd = socket(AF_INET, SOCK_DGRAM, 0); +	int skfd = socket(AF_INET, SOCK_DGRAM, 0);  	if (skfd < 0)  		err_sys("%s: can not open socket", __func__); @@ -230,43 +229,6 @@ void dyn_info_get(struct iw_dyn_info *info,  		info->mode     = iwr.u.mode;  	} -	info->nkeys = ir->max_encoding_tokens; -	if (info->nkeys) { -		info->keys = calloc(info->nkeys, sizeof(*info->keys)); -		if (info->keys == NULL) -			err_sys("malloc(key array)"); - -		/* Get index of default key first */ -		iwr.u.data.pointer = info->keys[0].key; -		iwr.u.data.length  = sizeof(info->keys[0].key); -		iwr.u.data.flags   = 0; -		if (ioctl(skfd, SIOCGIWENCODE, &iwr) < 0) { -			free(info->keys); -			info->keys  = NULL; -			info->nkeys = 0; -		} else { -			info->active_key = iwr.u.data.flags & IW_ENCODE_INDEX; -		} -	} -	/* If successful, populate the key array */ -	for (i = 0; i < info->nkeys; i++) { -		iwr.u.data.pointer = info->keys[i].key; -		iwr.u.data.length  = sizeof(info->keys->key); -		iwr.u.data.flags   = i + 1;	/* counts 1..n instead of 0..n-1 */ -		if (ioctl(skfd, SIOCGIWENCODE, &iwr) < 0) { -			free(info->keys); -			info->nkeys = 0; -			break; -		} -		info->keys[i].size  = iwr.u.data.length; -		info->keys[i].flags = iwr.u.data.flags; - -		/* Validate whether the current key is indeed active */ -		if (i + 1 == info->active_key && (info->keys[i].size == 0 || -		    (info->keys[i].flags & IW_ENCODE_DISABLED))) -			info->active_key = 0; -	} -  	if (ioctl(skfd, SIOCGIWAP, &iwr) >= 0) {  		info->cap_ap = 1;  		memcpy(&info->ap_addr, &iwr.u.ap_addr, sizeof(struct sockaddr)); @@ -274,13 +236,6 @@ void dyn_info_get(struct iw_dyn_info *info,  	close(skfd);  } -void dyn_info_cleanup(struct iw_dyn_info *info) -{ -	if (info) -		free(info->keys); -} - -  /*   * Request range information for a given wireless interface.   * @ifname: name of the wireless argument @@ -148,37 +148,9 @@ struct iw_dyn_info {  	float		freq;  	int32_t		sens;  	unsigned long	bitrate; - -	struct iw_key	*keys; -	uint8_t		nkeys; -	uint8_t		active_key;  }; -/* Return the number of encryption keys marked 'active' in @info */ -static inline uint8_t dyn_info_active_keys(struct iw_dyn_info *info) -{ -	int i, num_active = 0; - -	for (i = 0; i < info->nkeys; i++) -		num_active += info->keys[i].size && -			      !(info->keys[i].flags & IW_ENCODE_DISABLED); -	return num_active; -} - -/* Return the number of 40-bit/104-bit keys in @info */ -static inline uint8_t dyn_info_wep_keys(struct iw_dyn_info *info) -{ -	int i, num_wep = 0; - -	for (i = 0; i < info->nkeys; i++) -		if (!(info->keys[i].flags & IW_ENCODE_DISABLED)) -			num_wep += info->keys[i].size == 5 || -				   info->keys[i].size == 13; -	return num_wep; -} -extern void dyn_info_get(struct iw_dyn_info *info, -			 const char *ifname, struct iw_range *ir); -extern void dyn_info_cleanup(struct iw_dyn_info *info); +extern void dyn_info_get(struct iw_dyn_info *info, const char *ifname);  /* @@ -278,8 +250,8 @@ struct scan_result {  	pthread_mutex_t   mutex;  }; -extern void scan_result_init(struct scan_result *sr); -extern void scan_result_fini(struct scan_result *sr); +extern void init_scan_list(struct scan_result *sr); +extern void free_scan_list(struct scan_entry *head);  extern void *do_scan(void *sr_ptr);  /* diff --git a/iw_nl80211.c b/iw_nl80211.c index 5b9c562..339e58b 100644 --- a/iw_nl80211.c +++ b/iw_nl80211.c @@ -128,7 +128,7 @@ void parse_bitrate(struct nlattr *bitrate_attr, char *buf, int buflen)  		rate = nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);  	if (rate > 0)  		pos += snprintf(pos, buflen - (pos - buf), -				"%d.%d MBit/s", rate / 10, rate % 10); +				"%d.%d Mbit/s", rate / 10, rate % 10);  	if (rinfo[NL80211_RATE_INFO_MCS])  		pos += snprintf(pos, buflen - (pos - buf), @@ -105,7 +105,7 @@ static int wait_event(struct nl_msg *msg, void *arg)   * Returns true if scan results are available, false if scan was aborted.   * Taken from iw:event.c:__do_listen_events   */ -static bool wait_for_scan_events(struct scan_result *sr) +static bool wait_for_scan_events(void)  {  	static const uint32_t cmds[] = {  		NL80211_CMD_NEW_SCAN_RESULTS, @@ -293,7 +293,8 @@ void sort_scan_list(struct scan_entry **headp)  	*headp = head;  } -static void free_scan_list(struct scan_entry *head) +/** De-allocate list. Use after all threads are terminated. */ +void free_scan_list(struct scan_entry *head)  {  	if (head) {  		free_scan_list(head->next); @@ -301,9 +302,9 @@ static void free_scan_list(struct scan_entry *head)  	}  } -static void clear_scan_list(struct scan_result *sr) +/** Initialize scan results. Requires lock to be taken. */ +void init_scan_list(struct scan_result *sr)  { -	pthread_mutex_lock(&sr->mutex);  	free_scan_list(sr->head);  	free(sr->channel_stats);  	sr->head          = NULL; @@ -311,7 +312,7 @@ static void clear_scan_list(struct scan_result *sr)  	sr->msg[0]        = '\0';  	sr->max_essid_len = MAX_ESSID_LEN;  	memset(&(sr->num), 0, sizeof(sr->num)); -	pthread_mutex_unlock(&sr->mutex); +	sr->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;  }  /* @@ -366,28 +367,6 @@ static void compute_channel_stats(struct scan_result *sr)  	sr->num.ch_stats = n < MAX_CH_STATS ? n : MAX_CH_STATS;  } -/* - *	Scan results. - */ -void scan_result_init(struct scan_result *sr) -{ -	pthread_mutexattr_t ma; - -	memset(sr, 0, sizeof(*sr)); -	pthread_mutexattr_init(&ma); -	if (pthread_mutexattr_setrobust(&ma, PTHREAD_MUTEX_ROBUST) < 0) -		err_sys("Failed to set the mutex robust attribute"); -	pthread_mutex_init(&sr->mutex, &ma); -} - -void scan_result_fini(struct scan_result *sr) -{ -	/* FIXME: this may have a bug on resource de-allocation, if the main thread still holds the lock */ -	free_scan_list(sr->head); -	free(sr->channel_stats); -	pthread_mutex_destroy(&sr->mutex); -} -  /** The actual scan thread. */  void *do_scan(void *sr_ptr)  { @@ -402,15 +381,21 @@ void *do_scan(void *sr_ptr)  	pthread_detach(pthread_self());  	do { -		clear_scan_list(sr); -  		ret = iw_nl80211_scan_trigger(); + +		pthread_mutex_lock(&sr->mutex); +		init_scan_list(sr);  		switch(-ret) {  		case 0:  		case EBUSY:  			/* Trigger returns -EBUSY if a scan request is pending or ready. */ -			if (!wait_for_scan_events(sr)) { +			pthread_mutex_unlock(&sr->mutex); + +			/* Do not hold the lock while awaiting results. */ +			if (!wait_for_scan_events()) { +				pthread_mutex_lock(&sr->mutex);  				snprintf(sr->msg, sizeof(sr->msg), "Waiting for scan data..."); +				pthread_mutex_unlock(&sr->mutex);  			} else {  				pthread_mutex_lock(&sr->mutex);  				ret = iw_nl80211_get_scan_data(sr); @@ -426,8 +411,8 @@ void *do_scan(void *sr_ptr)  			break;  		case EPERM:  			if (!has_net_admin_capability()) -				snprintf(sr->msg, sizeof(sr->msg), -					 "This screen requires CAP_NET_ADMIN permissions"); +				snprintf(sr->msg, sizeof(sr->msg), "This screen requires CAP_NET_ADMIN permissions"); +			pthread_mutex_unlock(&sr->mutex);  			return NULL;  		case EFAULT:  			/* EFAULT can occur after a window resizing event: temporary, fall through. */ @@ -435,18 +420,21 @@ void *do_scan(void *sr_ptr)  		case EAGAIN:  			/* Temporary errors. */  			snprintf(sr->msg, sizeof(sr->msg), "Waiting for device to become ready ..."); +			pthread_mutex_unlock(&sr->mutex);  			break;  		case ENETDOWN:  			if (!if_is_up(conf_ifname())) {  				snprintf(sr->msg, sizeof(sr->msg), "Interface %s is down - setting it up ...", conf_ifname()); +				pthread_mutex_unlock(&sr->mutex); +  				if (if_set_up(conf_ifname()) < 0)  					err_sys("Can not bring up interface '%s'", conf_ifname());  				break;  			}  			/* fall through */  		default: -			snprintf(sr->msg, sizeof(sr->msg), -				 "Scan trigger failed on %s: %s", conf_ifname(), strerror(-ret)); +			snprintf(sr->msg, sizeof(sr->msg), "Scan trigger failed on %s: %s", conf_ifname(), strerror(-ret)); +			pthread_mutex_unlock(&sr->mutex);  		}  	} while (usleep(conf.stat_iv * 1000) == 0); @@ -203,7 +203,7 @@ void scr_aplst_init(void)  	mvwaddstr(w_aplst, START_LINE, 1, "Waiting for scan data ...");  	wrefresh(w_aplst); -	scan_result_init(&sr); +	init_scan_list(&sr);  	pthread_create(&scan_thread, NULL, do_scan, &sr);  } @@ -251,6 +251,8 @@ int scr_aplst_loop(WINDOW *w_menu)  void scr_aplst_fini(void)  {  	pthread_cancel(scan_thread); -	scan_result_fini(&sr); +	free_scan_list(sr.head); +	free(sr.channel_stats); +  	delwin(w_aplst);  } @@ -51,7 +51,7 @@ enum info_screen_geometry {  	WH_IFACE    = 2,	/* 'Interface' area at the top */  	WH_LEVEL    = 9,	/* Level meters */  	WH_STATS    = 3,	/* WiFi statistics area */ -	WH_INFO_MIN = 8,	/* WiFi information area */ +	WH_INFO_MIN = 7,	/* WiFi information area */  	WH_NET_MIN  = 3,	/* Network interface information area */  	WH_NET_MAX  = 5,	/* Network interface information area */  	WH_MENU	    = 1		/* Menu bar at the bottom */ | 
