| 
									
										
										
										
											2017-04-27 20:18:03 +02:00
										 |  |  | // SPDX-License-Identifier: GPL-2.0
 | 
					
						
							| 
									
										
										
										
											2011-11-23 22:56:57 -08:00
										 |  |  | /* linux.c */ | 
					
						
							|  |  |  | /* implements Linux specific functions */ | 
					
						
							| 
									
										
										
										
											2012-09-09 09:06:44 -07:00
										 |  |  | #include "dive.h"
 | 
					
						
							| 
									
										
										
										
											2013-05-03 11:04:51 -07:00
										 |  |  | #include "display.h"
 | 
					
						
							| 
									
										
										
										
											2014-04-14 14:33:46 -07:00
										 |  |  | #include "membuffer.h"
 | 
					
						
							| 
									
										
										
										
											2012-09-09 09:06:44 -07:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | #include <sys/types.h>
 | 
					
						
							|  |  |  | #include <dirent.h>
 | 
					
						
							|  |  |  | #include <fnmatch.h>
 | 
					
						
							| 
									
										
										
										
											2013-12-19 15:00:50 +02:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							| 
									
										
										
										
											2014-04-14 14:33:46 -07:00
										 |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #include <pwd.h>
 | 
					
						
							| 
									
										
										
										
											2012-09-09 09:06:44 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 06:00:10 -07:00
										 |  |  | // the DE should provide us with a default font and font size...
 | 
					
						
							| 
									
										
										
										
											2014-08-22 15:22:02 -07:00
										 |  |  | const char linux_system_divelist_default_font[] = "Sans"; | 
					
						
							|  |  |  | const char *system_divelist_default_font = linux_system_divelist_default_font; | 
					
						
							| 
									
										
										
										
											2014-08-27 06:00:10 -07:00
										 |  |  | double system_divelist_default_font_size = -1.0; | 
					
						
							| 
									
										
										
										
											2011-11-23 22:56:57 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 15:22:02 -07:00
										 |  |  | void subsurface_OS_pref_setup(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// nothing
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 06:00:10 -07:00
										 |  |  | bool subsurface_ignore_font(const char *font) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	// there are no old default fonts to ignore
 | 
					
						
							| 
									
										
										
										
											2016-03-09 19:09:25 -08:00
										 |  |  | 	(void)font; | 
					
						
							| 
									
										
										
										
											2014-08-27 06:00:10 -07:00
										 |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 14:33:46 -07:00
										 |  |  | void subsurface_user_info(struct user_info *user) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	struct passwd *pwd = getpwuid(getuid()); | 
					
						
							|  |  |  | 	const char *username = getenv("USER"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (pwd) { | 
					
						
							|  |  |  | 		if (pwd->pw_gecos && *pwd->pw_gecos) | 
					
						
							|  |  |  | 			user->name = pwd->pw_gecos; | 
					
						
							|  |  |  | 		if (!username) | 
					
						
							|  |  |  | 			username = pwd->pw_name; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if (username && *username) { | 
					
						
							|  |  |  | 		char hostname[64]; | 
					
						
							| 
									
										
										
										
											2016-03-09 19:09:25 -08:00
										 |  |  | 		struct membuffer mb = {}; | 
					
						
							| 
									
										
										
										
											2014-04-14 14:33:46 -07:00
										 |  |  | 		gethostname(hostname, sizeof(hostname)); | 
					
						
							|  |  |  | 		put_format(&mb, "%s@%s", username, hostname); | 
					
						
							|  |  |  | 		user->email = mb_cstring(&mb); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-06 13:10:18 +03:00
										 |  |  | static const char *system_default_path_append(const char *append) | 
					
						
							| 
									
										
										
										
											2012-09-09 09:06:44 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-10-06 13:10:18 +03:00
										 |  |  | 	const char *home = getenv("HOME"); | 
					
						
							| 
									
										
										
										
											2015-08-19 17:59:35 +02:00
										 |  |  | 	if (!home) | 
					
						
							|  |  |  | 		home = "~"; | 
					
						
							| 
									
										
										
										
											2015-10-10 19:24:09 -10:00
										 |  |  | 	const char *path = "/.subsurface"; | 
					
						
							| 
									
										
										
										
											2015-10-06 13:10:18 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int len = strlen(home) + strlen(path) + 1; | 
					
						
							|  |  |  | 	if (append) | 
					
						
							|  |  |  | 		len += strlen(append) + 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	char *buffer = (char *)malloc(len); | 
					
						
							|  |  |  | 	memset(buffer, 0, len); | 
					
						
							|  |  |  | 	strcat(buffer, home); | 
					
						
							|  |  |  | 	strcat(buffer, path); | 
					
						
							|  |  |  | 	if (append) { | 
					
						
							|  |  |  | 		strcat(buffer, "/"); | 
					
						
							|  |  |  | 		strcat(buffer, append); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 17:07:22 -08:00
										 |  |  | 	return buffer; | 
					
						
							| 
									
										
										
										
											2012-09-09 09:06:44 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-06 13:10:18 +03:00
										 |  |  | const char *system_default_directory(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static const char *path = NULL; | 
					
						
							|  |  |  | 	if (!path) | 
					
						
							|  |  |  | 		path = system_default_path_append(NULL); | 
					
						
							|  |  |  | 	return path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const char *system_default_filename(void) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-18 10:55:01 +01:00
										 |  |  | 	static const char *path = NULL; | 
					
						
							|  |  |  | 	if (!path) { | 
					
						
							| 
									
										
										
										
											2015-10-06 13:10:18 +03:00
										 |  |  | 		const char *user = getenv("LOGNAME"); | 
					
						
							|  |  |  | 		if (same_string(user, "")) | 
					
						
							|  |  |  | 			user = "username"; | 
					
						
							| 
									
										
										
										
											2017-11-18 10:55:01 +01:00
										 |  |  | 		char *filename = calloc(strlen(user) + 5, 1); | 
					
						
							| 
									
										
										
										
											2015-10-06 13:10:18 +03:00
										 |  |  | 		strcat(filename, user); | 
					
						
							|  |  |  | 		strcat(filename, ".xml"); | 
					
						
							|  |  |  | 		path = system_default_path_append(filename); | 
					
						
							| 
									
										
										
										
											2017-11-18 10:55:01 +01:00
										 |  |  | 		free(filename); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-10-06 13:10:18 +03:00
										 |  |  | 	return path; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | int enumerate_devices(device_callback_t callback, void *userdata, int dc_type) | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-05-18 14:13:23 +09:00
										 |  |  | 	int index = -1, entries = 0; | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 	DIR *dp = NULL; | 
					
						
							|  |  |  | 	struct dirent *ep = NULL; | 
					
						
							|  |  |  | 	size_t i; | 
					
						
							| 
									
										
										
										
											2013-10-25 23:56:27 +00:00
										 |  |  | 	FILE *file; | 
					
						
							|  |  |  | 	char *line = NULL; | 
					
						
							|  |  |  | 	char *fname; | 
					
						
							|  |  |  | 	size_t len; | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 	if (dc_type != DC_TYPE_UEMIS) { | 
					
						
							|  |  |  | 		const char *dirname = "/dev"; | 
					
						
							|  |  |  | 		const char *patterns[] = { | 
					
						
							|  |  |  | 			"ttyUSB*", | 
					
						
							|  |  |  | 			"ttyS*", | 
					
						
							|  |  |  | 			"ttyACM*", | 
					
						
							|  |  |  | 			"rfcomm*", | 
					
						
							|  |  |  | 			NULL | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dp = opendir(dirname); | 
					
						
							|  |  |  | 		if (dp == NULL) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 		while ((ep = readdir(dp)) != NULL) { | 
					
						
							|  |  |  | 			for (i = 0; patterns[i] != NULL; ++i) { | 
					
						
							|  |  |  | 				if (fnmatch(patterns[i], ep->d_name, 0) == 0) { | 
					
						
							|  |  |  | 					char filename[1024]; | 
					
						
							|  |  |  | 					int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name); | 
					
						
							| 
									
										
										
										
											2016-03-09 19:09:25 -08:00
										 |  |  | 					if (n >= (int)sizeof(filename)) { | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 						closedir(dp); | 
					
						
							|  |  |  | 						return -1; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					callback(filename, userdata); | 
					
						
							|  |  |  | 					if (is_default_dive_computer_device(filename)) | 
					
						
							| 
									
										
										
										
											2014-05-18 14:13:23 +09:00
										 |  |  | 						index = entries; | 
					
						
							|  |  |  | 					entries++; | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 					break; | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 		closedir(dp); | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 	if (dc_type != DC_TYPE_SERIAL) { | 
					
						
							| 
									
										
										
										
											2014-05-18 14:13:23 +09:00
										 |  |  | 		int num_uemis = 0; | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 		file = fopen("/proc/mounts", "r"); | 
					
						
							|  |  |  | 		if (file == NULL) | 
					
						
							|  |  |  | 			return index; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		while ((getline(&line, &len, file)) != -1) { | 
					
						
							|  |  |  | 			char *ptr = strstr(line, "UEMISSDA"); | 
					
						
							|  |  |  | 			if (ptr) { | 
					
						
							|  |  |  | 				char *end = ptr, *start = ptr; | 
					
						
							|  |  |  | 				while (start > line && *start != ' ') | 
					
						
							|  |  |  | 					start--; | 
					
						
							|  |  |  | 				if (*start == ' ') | 
					
						
							|  |  |  | 					start++; | 
					
						
							|  |  |  | 				while (*end != ' ' && *end != '\0') | 
					
						
							|  |  |  | 					end++; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				*end = '\0'; | 
					
						
							|  |  |  | 				fname = strdup(start); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				callback(fname, userdata); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				if (is_default_dive_computer_device(fname)) | 
					
						
							| 
									
										
										
										
											2014-05-18 14:13:23 +09:00
										 |  |  | 					index = entries; | 
					
						
							|  |  |  | 				entries++; | 
					
						
							|  |  |  | 				num_uemis++; | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 				free((void *)fname); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 		free(line); | 
					
						
							|  |  |  | 		fclose(file); | 
					
						
							| 
									
										
										
										
											2014-05-18 14:13:23 +09:00
										 |  |  | 		if (num_uemis == 1 && entries == 1) /* if we found only one and it's a mounted Uemis, pick it */ | 
					
						
							|  |  |  | 			index = 0; | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 	return index; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-12-19 15:00:50 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* NOP wrappers to comform with windows.c */ | 
					
						
							| 
									
										
										
										
											2014-02-16 13:25:02 -08:00
										 |  |  | int subsurface_rename(const char *path, const char *newpath) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return rename(path, newpath); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 15:00:50 +02:00
										 |  |  | int subsurface_open(const char *path, int oflags, mode_t mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return open(path, oflags, mode); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | FILE *subsurface_fopen(const char *path, const char *mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return fopen(path, mode); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void *subsurface_opendir(const char *path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (void *)opendir(path); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-11-13 19:36:08 +02:00
										 |  |  | int subsurface_access(const char *path, int mode) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return access(path, mode); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-24 14:06:48 +07:00
										 |  |  | int subsurface_stat(const char* path, struct stat* buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return stat(path, buf); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-19 15:00:50 +02:00
										 |  |  | struct zip *subsurface_zip_open_readonly(const char *path, int flags, int *errorp) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return zip_open(path, flags, errorp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int subsurface_zip_close(struct zip *zip) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return zip_close(zip); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-03-25 16:55:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* win32 console */ | 
					
						
							| 
									
										
										
										
											2017-11-03 01:51:33 +02:00
										 |  |  | void subsurface_console_init(void) | 
					
						
							| 
									
										
										
										
											2014-03-25 16:55:56 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* NOP */ | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void subsurface_console_exit(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* NOP */ | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-03-25 09:21:45 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | bool subsurface_user_is_root() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return (geteuid() == 0); | 
					
						
							|  |  |  | } |