int verifyAndSetUserPortGroup()

in src/main/c/Posix/PosixHelperFunctions.c [1856:1905]


int verifyAndSetUserPortGroup(const char *portFile)
{
	// Check if the user can currently access the port file
	int numGroups = getgroups(0, NULL);
	int userCanAccess = (faccessat(0, portFile, R_OK | W_OK, AT_EACCESS) == 0);

	// Attempt to acquire access if not available
	if (!userCanAccess)
	{
		// Ensure that the port still exists
		struct stat fileStats;
		if (stat(portFile, &fileStats) == 0)
		{
			// Check if the user is part of the group that owns the port
			int userPartOfPortGroup = 0;
			gid_t *userGroups = (gid_t*)malloc(numGroups * sizeof(gid_t));
			if (getgroups(numGroups, userGroups) >= 0)
				for (int i = 0; i < numGroups; ++i)
					if (userGroups[i] == fileStats.st_gid)
					{
						userPartOfPortGroup = 1;
						break;
					}

			// Attempt to add the user to the group that owns the port
			char *addUserToGroupCmd = (char*)malloc(256);
			if (!userPartOfPortGroup)
			{
				struct group *portGroup;
				struct passwd *userDetails;
				if ((portGroup = getgrgid(fileStats.st_gid)) && (userDetails = getpwuid(geteuid())))
				{
					snprintf(addUserToGroupCmd, 256, "sudo usermod -a -G %s %s", portGroup->gr_name, userDetails->pw_name);
					userCanAccess = (system(addUserToGroupCmd) == 0);
				}
			}

			// Attempt to enable all read/write port permissions
			snprintf(addUserToGroupCmd, 256, "sudo chmod 666 %s", portFile);
			userCanAccess = (system(addUserToGroupCmd) == 0) || userCanAccess;

			// Clean up memory
			free(addUserToGroupCmd);
			free(userGroups);
		}
	}

	// Return whether the user can currently access the serial port
	return userCanAccess;
}