Hi Aitor et al,

This is the working code. At least it worked with an initial
allocation of 1 structure instead of 10. I am using it with an initial
allocation of 10 structures. On this machine the code works and it
should also work in your case:

The code is attached.

Conside lines 236 - 240.

Line 238 calls calloc(list_delta, sizeof(void*)); list_delta is set to
10 but I also used 1 to force to loop use realloc with every
successive odd numbered iteration. Line 238 allocates an array of 10
void* pointers.

Realloc uses two parameters: the first is a pointer whose allocation
is to be modified/reallocated. The second is the NEW number of bytes
required. In the function line 240 is:
active_wifi_list = realloc(active_wifi_list, (((z - 1)/2) +
list_delta)*sizeof(void*));

I should assume that the assignment is unnecessary although it works.


Edward

On 10/12/2015, KatolaZ <kato...@freaknet.org> wrote:
> On Thu, Dec 10, 2015 at 04:11:27PM +0000, KatolaZ wrote:
>
> [cut]
>
>>
>> with
>>
>>  $ gcc -std=c99 reference.c
>>
>> this is what I obtain:
>>
>> reference.c:3:16: error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
>>  void myfun(int &a){
>>                 ^
>> reference.c: In function ‘main’:
>> reference.c:13:4: warning: implicit declaration of function ‘myfun’
>> [-Wimplicit-function-declaration]
>>     myfun(a);
>>     ^
>>
>> So my version of gcc apparently does not know about this feature
>> included in the ANSI C99 standard....
>>
>
> And apparently they haven't fixed the "bug" while implementing the C11
> standard, either...
>
> katolaz@%%%%%%:~/test$ gcc -std=c11 reference.c
> reference.c:3:16: error: expected ‘;’, ‘,’ or ‘)’ before ‘&’ token
>  void myfun(int &a){
>                 ^
> reference.c: In function ‘main’:
> reference.c:13:4: warning: implicit declaration of function ‘myfun’
> [-Wimplicit-function-declaration]
>     myfun(a);
>     ^
>
> Very strange, ain't it?
>
> HND
>
> KatolaZ
>
> --
> [ Enzo Nicosia aka KatolaZ --- GLUG Catania -- Freaknet Medialab ]
> [ me [at] katolaz.homeunix.net -- http://katolaz.homeunix.net -- ]
> [ GNU/Linux User:#325780/ICQ UIN: #258332181/GPG key ID 0B5F062F ]
> [ Fingerprint: 8E59 D6AA 445E FDB4 A153 3D5A 5F20 B3AE 0B5F 062F ]
> _______________________________________________
> Dng mailing list
> Dng@lists.dyne.org
> https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
>
/*
    netman - A Network Connection Manager
    Copyright (C) 2015  Edward Bartolo

    "netman" is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    "netman" is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with "netman".  If not, see <http://www.gnu.org/licenses/>.
*/

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <dirent.h>
#include <alloca.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <math.h>
#include "paths.h"
#include "core_functions.h"
#include "essid_encoder.h"
#include "file_functions.h"
#include "automated_scanner.h"

/*
Note: Essid files under /etc/network/wifi are first copied to
/run/netman and wlan0 replaced by the system's own wifi network
interface. This means that under /etc/network/wifi wlan0 is only 
a placeholder for the actual device name.


Looks in /etc/network/wifi or /run/netman for installed essid files.
If etc_network_path is true /etc/network/wifi is used, otherwise /run/netman is used.

The return value is a list of strings containing the encoded essid file names.
count returns the number of strings in the list and error returns a non-zero error code
in the event of an error with a value of zero when no error is generated.
*/
char** getInstalledEssidList(int etc_network_path, int* count, int* error)
{
	char** essid_list;

	DIR * dir;
	struct dirent * ent;
	int el_size = 0; // stands for essid_list size
	
	essid_list = NULL;
	
	// At first set *error to 0
	*error = 0;
	
	// First get a list of installed wireless "interfaces" files
	if (etc_network_path )
	  dir = opendir(IFACES_PATH);
	  else dir = opendir(RUN_IFACES_PATH);
		
	if (dir != NULL) {
		while ((ent = readdir (dir)) != 0)
			if(
				strcmp(".", ent->d_name) != 0 && 
				strcmp("..", ent->d_name) != 0
			) {
				(*count)++;
							
				char* encoded_essid;
				int err;
				
				encoded_essid = ent->d_name;	
				if (el_size < *count) {
					el_size =+ 10;
					if (el_size == 10)
						essid_list = calloc(*count + 9, sizeof(char*));
						else essid_list = realloc(essid_list, (*count + 9)*sizeof(char*));
						
					if (essid_list == NULL || errno == ENOMEM) {	
						fprintf(
							stderr, 
							"ERROR: getInstalledEssidList(): "
							"could not expand essid_list list. (Error: %s)\n", 
							strerror(errno)
						);
					
						el_size =- 10;
						(*count)--;
						
						*error = 1;
						return essid_list;
					}	
				}	
					
				
				char* essid;	
				err = decode_essid_alloc(encoded_essid, &essid);

				if(err) {
					fprintf(
						stderr, "ERROR: "
						"getInstalledEssidList(): decode_essid_alloc(encoded_essid=%s) failed; err=%d\n",
						encoded_essid, err
					);
					
					(*count)--;
					
					*error = 1;
					return essid_list;
					//continue;
				}
 
				err = decode_encoded_essid(encoded_essid, &essid);

				if(err) {
					fprintf(
						stderr, "ERROR: "
						"getInstalledEssidList(): decode_encoded_essid(encoded_essid=%s) failed; err=%d\n",
						encoded_essid, err
					);
					
					*error = -1;
					return essid_list;
				}
	
				
				essid_list[*count - 1] = essid;
									
				//essid_list[*count - 1] = calloc(strlen(encoded_essid) + 1, sizeof(char));
				//strcpy(essid_list[*count - 1], encoded_essid);
			} 
		closedir(dir);
	} 
	else {
		if (etc_network_path) {
			fprintf(
				stderr, "Error: "
				"getInstalledEssidList(): opendir(%s) failed (Error: %s)\n",
				IFACES_PATH, strerror(errno)
			);
		} else {
			fprintf(
				stderr, "Error: "
				"getInstalledEssidList(): opendir(%s) failed (Error: %s)\n",
				RUN_IFACES_PATH, strerror(errno)
			);
		};		

		//return old_errno;
		*error = 1;
		return essid_list;
	}
	
	//return 0;
	return essid_list;
}


/*
Runs "iwlist wlanx or equivalent scan" to get a list of active wifi transceivers in 
the vicinity. The return value is a list of strings of type void** implying type casting
must be used to access the strings. 
active_wifis returns the number of active wifi transceivers found and error contains a non zero
error code in the event of an error, otherwise zero is returned.
*/
void** getRadiatingWifiList(int* active_wifis, int* error)
{
	// Hopefully, here we have a list of installed essid interfaces files
	void** active_wifi_list = NULL;
	
	char command[1024];
	FILE * shell_reader;
	char * scan_buffer;
	int err;
	
	*error = 0;	
	scan_buffer = calloc(1024, 1);
	
	if (scan_buffer == NULL) {
		fprintf(
			stderr, 
			"ERROR: getRadiatingWifiList(): "
			"calloc() failed to allocate memory for scan_buffer. (Error: %s)\n", 
			strerror(errno)
		);
		
		*error = 2;
		
		return NULL;
	}
	
	err = snprintf(
		command, 
		1024,
		"/sbin/iwlist %s scan | grep \"Quality=\\|ESSID:\"",
		wlanx
	);

	if(err<0) {
		fprintf(stderr, "ERROR: snprintf(filename) failed; err=%d\n", err);
		free(scan_buffer);
	}
	
	// read output lines containing 'Quality=' and 'ESSID:'
	shell_reader = popen(command, "r");

	if(!shell_reader) {
		fprintf(
			stderr, 
			"ERROR: getRadiatingWifiList(): "
			"popen() failed (Error: %s)\n", 
			strerror(errno)
		);

		free(scan_buffer);
		*error = 2;
		
		return NULL;
	}

	wifi_quality* tmp_wifi_quality;
	int z = 0;
	
	*active_wifis = -1;
	char* tmp_buffer = scan_buffer;
	
	const int list_delta = 10;
	while((scan_buffer = fgets(scan_buffer, 1024, shell_reader)))
	{
		z++;
		if (z == 1) 
			active_wifi_list = calloc(list_delta, sizeof(void*));
		else if ((z - 1) % (list_delta * 2) == 0)
			active_wifi_list = realloc(active_wifi_list, (((z - 1)/2) + list_delta)*sizeof(void*));
			
		if (active_wifi_list == NULL || errno == ENOMEM) {
			fprintf(
				stderr, 
				"ERROR: getRadiatingWifiList(): "
				"could not expand active_wifi_list. (Error: %s)\n", 
				strerror(errno)
			);
			
			free(tmp_buffer);
			*error = 2;
			
			return active_wifi_list;
		}
			
		if (z % 2 == 1) {
				(*active_wifis)++;
				tmp_wifi_quality = calloc(1, sizeof(wifi_quality));
				
				if (tmp_wifi_quality == NULL) {
					fprintf(
						stderr, 
						"ERROR: getRadiatingWifiList(): "
						"could not allocate tmp_wifi_quality. (Error: %s)\n", 
						strerror(errno)
					);
						
					(*active_wifis)++;
					free(tmp_buffer);
					*error = 2;
					
					return active_wifi_list;
				}
				
				active_wifi_list[*active_wifis] = tmp_wifi_quality;
				
				char* substr = strstr((char *) scan_buffer, "Signal level=");
				substr = strstr(substr, "=");
				char* endstr = strstr(substr + 1, " ");
				char tmpstr[MAX_ESSID_LENGTH];
				strncpy(tmpstr, substr + 1, endstr - substr - 1);
				tmpstr[endstr - substr - 1] = '\0';
				
				tmp_wifi_quality->quality = strtod(tmpstr, NULL);
				
				// P(dBm) = 10 · log10( P(mW) / 1mW)
				// we want the absolute power
				
				// P(mW) / 1mW = P*
				// P* = antilog(P/10)
				
				double log_quality = (tmp_wifi_quality->quality)/10;
				tmp_wifi_quality->quality = pow(10, log_quality);
		  }
		else {
				char* tmpstr = strtok((char*) scan_buffer, "\"");
				tmpstr = strtok(NULL, "\"");	
				
				strncpy(tmp_wifi_quality->name,  tmpstr, strlen(tmpstr)); 
			}
		//printf("%s", scan_buffer);
	}
	
	free(tmp_buffer);
	pclose(shell_reader);
	
	return active_wifi_list;	
}

// sort radiating wifis according to signal strength
int sortRadiatingWifisList(const int active_wifis, void** active_wifi_list)
{
	int i, j = 0;
	while (j < active_wifis) {
		for (i = active_wifis - j - 1; i > -1; i--) {
			if (
				((wifi_quality*) active_wifi_list[i])->quality <
				((wifi_quality*) active_wifi_list[i + 1])->quality
			) {
				wifi_quality* awifi_quality = (wifi_quality*) active_wifi_list[i];
			  active_wifi_list[i] = active_wifi_list[i + 1];
				active_wifi_list[i + 1] = awifi_quality;
			}
		}
			
		j++;
	}
	
	return 0;
}

/*
Checks whether essid is listed in installed_wifi_list. Return index of essid in list or -1
if essid is not found.
*/
int wifiEssidInstalled(const int installed_count, char** installed_wifi_list, char* essid)
{
	int i;
	for (i = 0; i < installed_count; i++) {
		if (strcmp(installed_wifi_list[i], essid) == 0) {
			return i;
		}
	}
	
	return -1;	// ie not found
}


int autoWirelessScanPlus()
{
	char** essid_list;
	int count = 0;
	int error = 0;
	
	int active_wifis;
	void** active_wifi_list;
	
	char scan_buffer[1025];
	
	// pull up the network to enable scanning
	char command_up[1024];
	
	int err = snprintf(
		command_up, 
		1024, 
		"/sbin/ifconfig %s up",
		wlanx
	);	
	
	if(err < 0) {
		fprintf(stderr, "ERROR: snprintf(command_up) failed; err=%d\n", err);
		
		return err;
	}
	
	int ret = system(command_up);
	if (ret != 0) {
		fprintf(
			stderr, 
			"ERROR: autoWirelessScanPlus(): "
			"/sbin/ifconfig() failed (Error: %s)\n", 
			strerror(errno)
		);
	
		return ret;
	}
	
	// get a list of currently installed wifi essids
	essid_list = getInstalledEssidList(0, &count, &error);
	if (error) {
		int w;
		if (essid_list != NULL) {
			for (w = 0; w < count; w++)
				free(essid_list[w]);
		
			free(essid_list);
		}
		
		return 1;
	}	
	
	// get a list of irradiating wifis
	active_wifi_list = getRadiatingWifiList(&active_wifis, &error);
	if (error) {
		int w;
		for (w = 0; w < count; w++)
			free(essid_list[w]);
		
		free(essid_list);
		
		if (active_wifi_list != NULL) {
		  for (w = 0; w < active_wifis; w++)
				free(active_wifi_list[w]);
				
			free(active_wifi_list);	
		}
		
		return 2;
	}
	
	// sort the radiating wifis in descending order according to strength
	sortRadiatingWifisList(active_wifis, active_wifi_list);
/*	
	int ww;
	for (ww = 0; ww <= active_wifis; ww++)
	  fprintf(stdout, "quality for %s is %g\n", 
			((wifi_quality*) active_wifi_list[ww])->name,
		  ((wifi_quality*) active_wifi_list[ww])->quality);
*/	
	int wireless = 0;
	int counter;

	for (counter = 0; counter < active_wifis; counter++) {
		char* tmp_essid_list_item = ((wifi_quality*) active_wifi_list[counter])->name;
	
		if (wifiEssidInstalled(count, essid_list, tmp_essid_list_item) > -1) {
			FILE * shell_reader;
	
			// required command for popen: /sbin/ifup wlanx -i RUN_IFACES_PATH"/"essid_list[counter]
			;
			char ifup_cmd[40 + MAX_ESSID_LENGTH];
			
			char** tmp_enc_essid;
			tmp_enc_essid = malloc(sizeof(void*));
			encodeString(tmp_essid_list_item, tmp_enc_essid);
			//printf(encoded_essid);
			
			err = snprintf(
				ifup_cmd,
				1024,
				"/sbin/ifup %s -i \""RUN_IFACES_PATH"/%s\"",
				wlanx,
				*tmp_enc_essid
				//tmp_essid_list_item
			);
			
			free(tmp_enc_essid[0]);
			free(tmp_enc_essid);	
				
			if(err<0) {
				fprintf(stderr, "ERROR: snprintf(filename) failed; err=%d\n", err);
		
				error = 5;
				break;
			}
			
			shell_reader = popen(ifup_cmd, "r");
			
			if(!shell_reader) {
				fprintf(
					stderr, 
					"ERROR: autoWirelessScanPlus(): "
					"popen() failed (Error: %s)\n", 
					strerror(errno)
				);
				
				error = 3;
				break;
			}
			
			pclose(shell_reader);
			
			shell_reader = popen(
				"/bin/ip a | grep \"state UP\"", "r"
			);
			
			if(!shell_reader) {
				fprintf(
					stderr, 
					"ERROR: autoWirelessScanPlus(): "
					"popen() failed (Error: %s)\n", 
					strerror(errno)
				);
				
				error = 4;
				break;
			}
			
				
			while((fgets(scan_buffer, 1024, shell_reader))) {
				if (strstr((char *) scan_buffer, wlanx) != NULL)
					wireless++;
				//else if (strstr((char *) scan_buffer, "eth0") != NULL)
				//	wired++;
			}
			
			pclose(shell_reader);
			if (wireless) break; // if connected to wireless stop iterating
		}
	}
		
			
	// free the essid string list
	int u;
	for (u = 0; u < count; u++)
	  free(essid_list[u]);
		
	free(essid_list);
	
	// free the radiating wifis list
	for (u = 0; u <= active_wifis; u++)
		free((wifi_quality*) active_wifi_list[u]);
		
	free((void*) active_wifi_list);
	
	
	return error;	
}


int autoWirelessScanPlus_RN()
{
	DIR * dir;
	struct dirent * ent;
	char* encoded_essid;
	int error;
	
	if ( (dir = opendir(IFACES_PATH)) != NULL ) {
		while ( (ent = readdir (dir)) != 0)
			if(
				strcmp(".", ent->d_name) != 0 && 
				strcmp("..", ent->d_name) != 0
			) {
				encoded_essid = ent->d_name;
				
				error = moveEditEssidFile(wlanx, encoded_essid);
				if (error) break;	
			}
			
		closedir(dir);		
	}
	
	if(!dir) {
		fprintf(
			stderr, 
			"ERROR: autoWirelessScanPlus_RN(): "
			"opendir() failed (Error: %s)\n", 
			strerror(errno)
		);
				
		return errno;	
	}
	
	if (!error)
		error = autoWirelessScanPlus();
		
	return error;	
}
_______________________________________________
Dng mailing list
Dng@lists.dyne.org
https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng

Reply via email to