char getPortDetails()

in src/main/c/Posix/PosixHelperFunctions.c [1176:1303]


char getPortDetails(const char *deviceName, char* portLocation, int* vendorID, int* productID, char* serialNumber, char* manufacturer, char* deviceDriver)
{
	// Attempt to locate the device in sysctl
	size_t bufferSize = 1024;
	char *stdOutResult = (char*)malloc(bufferSize), *deviceLocation = NULL, *deviceInfo = NULL, *driverName = NULL;
	snprintf(stdOutResult, bufferSize, "sysctl -a | grep \"ttyname: %s\"", deviceName);
	FILE *pipe = popen(stdOutResult, "r");
	if (pipe)
	{
		while (!deviceLocation && fgets(stdOutResult, bufferSize, pipe))
		{
			deviceLocation = stdOutResult;
			*(strstr(deviceLocation, "ttyname:") - 1) = '\0';
			deviceInfo = (char*)malloc(strlen(deviceLocation) + 12);
			driverName = (char*)malloc(strlen(deviceLocation) + 12);
			strcpy(deviceInfo, deviceLocation);
			strcpy(driverName, deviceLocation);
			strcat(deviceLocation, ".%location");
			strcat(deviceInfo, ".%pnpinfo");
			strcat(driverName, ".%driver");
		}
		pclose(pipe);
	}
	strcpy(serialNumber, "Unknown");
	strcpy(manufacturer, "Unknown");
	strcpy(deviceDriver, "Unknown");

	// Parse port location
	if (deviceLocation)
	{
		char *temp = (char*)malloc(64);
		sprintf(portLocation, "sysctl -a | grep \"%s\"", deviceLocation);
		pipe = popen(portLocation, "r");
		strcpy(portLocation, "0-0");
		if (pipe)
		{
			while (fgets(stdOutResult, bufferSize, pipe))
				if (strstr(stdOutResult, "bus") && strstr(stdOutResult, "hubaddr") && strstr(stdOutResult, "port"))
				{
					char *cursor = strstr(stdOutResult, "bus=") + 4;
					size_t length = (size_t)(strchr(cursor, ' ') - cursor);
					memcpy(portLocation, cursor, length);
					portLocation[length] = '\0';
					strcat(portLocation, "-");
					cursor = strstr(stdOutResult, "hubaddr=") + 8;
					length = (size_t)(strchr(cursor, ' ') - cursor);
					memcpy(temp, cursor, length);
					temp[length] = '\0';
					strcat(portLocation, temp);
					strcat(portLocation, ".");
					cursor = strstr(stdOutResult, "port=") + 5;
					length = (size_t)(strchr(cursor, ' ') - cursor);
					memcpy(temp, cursor, length);
					temp[length] = '\0';
					strcat(portLocation, temp);
					break;
				}
			pclose(pipe);
		}
		free(temp);
	}
	else
		strcpy(portLocation, "0-0");

	// Parse port VID and PID
	if (deviceInfo)
	{
		char *temp = (char*)malloc(64);
		sprintf(temp, "sysctl -a | grep \"%s\"", deviceInfo);
		pipe = popen(temp, "r");
		if (pipe)
		{
			while (fgets(stdOutResult, bufferSize, pipe))
				if (strstr(stdOutResult, "vendor") && strstr(stdOutResult, "product"))
				{
					char *cursor = strstr(stdOutResult, "vendor=") + 7;
					size_t length = (size_t)(strchr(cursor, ' ') - cursor);
					memcpy(temp, cursor, length);
					temp[length] = '\0';
					*vendorID = atoi(temp);
					cursor = strstr(stdOutResult, "product=") + 8;
					length = (size_t)(strchr(cursor, ' ') - cursor);
					memcpy(temp, cursor, length);
					temp[length] = '\0';
					*productID = atoi(temp);
					if (strstr(stdOutResult, "sernum"))
					{
						cursor = strstr(stdOutResult, "sernum=\"") + 8;
						length = (size_t)(strchr(cursor, '"') - cursor);
						memcpy(serialNumber, cursor, length);
						serialNumber[length] = '\0';
					}
					else
						strcpy(serialNumber, "Unknown");
					break;
				}
			pclose(pipe);
		}
		free(temp);
	}

	// Parse device driver
	if (driverName)
	{
		char *temp = (char*)malloc(64);
		sprintf(temp, "sysctl -a | grep \"%s\"", driverName);
		pipe = popen(temp, "r");
		if (pipe)
		{
			while (fgets(stdOutResult, bufferSize, pipe))
				if (strstr(stdOutResult, ": "))
				{
					strcpy(deviceDriver, strstr(stdOutResult, ": ") + 2);
					break;
				}
			pclose(pipe);
		}
		free(temp);
	}

	// Clean up memory and return result
	free(stdOutResult);
	if (deviceInfo)
		free(deviceInfo);
	if (driverName)
		free(driverName);
	return (deviceLocation ? 1 : 0);
}