| 
									
										
										
										
											2017-04-27 20:18:03 +02:00
										 |  |  | // SPDX-License-Identifier: GPL-2.0
 | 
					
						
							| 
									
										
										
										
											2011-11-23 22:56:57 -08:00
										 |  |  | /* macos.c */ | 
					
						
							|  |  |  | /* implements Mac OS X specific functions */ | 
					
						
							| 
									
										
										
										
											2013-02-09 10:36:02 +01:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2013-09-17 11:18:52 +02:00
										 |  |  | #include <dirent.h>
 | 
					
						
							|  |  |  | #include <fnmatch.h>
 | 
					
						
							| 
									
										
										
										
											2012-09-09 09:06:44 -07:00
										 |  |  | #include "dive.h"
 | 
					
						
							| 
									
										
										
										
											2013-05-03 13:32:23 -07:00
										 |  |  | #include "display.h"
 | 
					
						
							| 
									
										
										
										
											2011-11-23 22:56:57 -08:00
										 |  |  | #include <CoreFoundation/CoreFoundation.h>
 | 
					
						
							| 
									
										
										
										
											2016-03-06 06:55:24 -08:00
										 |  |  | #if !defined(__IPHONE_5_0)
 | 
					
						
							| 
									
										
										
										
											2013-02-28 12:19:27 +00:00
										 |  |  | #include <CoreServices/CoreServices.h>
 | 
					
						
							| 
									
										
										
										
											2016-03-06 06:55:24 -08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2011-12-28 15:57:36 -08:00
										 |  |  | #include <mach-o/dyld.h>
 | 
					
						
							| 
									
										
										
										
											2013-03-03 17:53:43 -08:00
										 |  |  | #include <sys/syslimits.h>
 | 
					
						
							| 
									
										
										
										
											2013-12-19 15:00:50 +02:00
										 |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <fcntl.h>
 | 
					
						
							| 
									
										
										
										
											2014-11-13 19:36:08 +02:00
										 |  |  | #include <unistd.h>
 | 
					
						
							| 
									
										
										
										
											2012-01-01 13:41:47 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-04-14 14:33:46 -07:00
										 |  |  | void subsurface_user_info(struct user_info *info) | 
					
						
							| 
									
										
										
										
											2016-03-06 21:39:19 -03:00
										 |  |  | { | 
					
						
							|  |  |  | 	(void) info; | 
					
						
							|  |  |  | 	/* Nothing, let's use libgit2-20 on MacOS */ | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-04-14 14:33:46 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-11-23 22:56:57 -08:00
										 |  |  | /* macos defines CFSTR to create a CFString object from a constant,
 | 
					
						
							|  |  |  |  * but no similar macros if a C string variable is supposed to be | 
					
						
							|  |  |  |  * the argument. We add this here (hardcoding the default allocator | 
					
						
							|  |  |  |  * and MacRoman encoding */ | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | #define CFSTR_VAR(_var) CFStringCreateWithCStringNoCopy(kCFAllocatorDefault,               \
 | 
					
						
							|  |  |  | 							(_var), kCFStringEncodingMacRoman, \ | 
					
						
							|  |  |  | 							kCFAllocatorNull) | 
					
						
							| 
									
										
										
										
											2011-11-23 22:56:57 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-02 15:14:42 +01:00
										 |  |  | #define SUBSURFACE_PREFERENCES CFSTR("org.hohndel.subsurface")
 | 
					
						
							| 
									
										
										
										
											2012-01-02 08:26:24 -08:00
										 |  |  | #define ICON_NAME "Subsurface.icns"
 | 
					
						
							| 
									
										
										
										
											2013-02-04 09:50:43 +01:00
										 |  |  | #define UI_FONT "Arial 12"
 | 
					
						
							| 
									
										
										
										
											2013-01-11 17:07:22 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-22 15:22:02 -07:00
										 |  |  | const char mac_system_divelist_default_font[] = "Arial"; | 
					
						
							|  |  |  | const char *system_divelist_default_font = mac_system_divelist_default_font; | 
					
						
							| 
									
										
										
										
											2014-08-27 06:00:10 -07:00
										 |  |  | double system_divelist_default_font_size = -1.0; | 
					
						
							| 
									
										
										
										
											2012-01-01 13:41:47 -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) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-03-06 21:39:19 -03:00
										 |  |  | 	(void) font; | 
					
						
							| 
									
										
										
										
											2014-08-27 06:00:10 -07:00
										 |  |  | 	// there are no old default fonts to ignore
 | 
					
						
							|  |  |  | 	return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-10-06 13:10:17 +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:17 +03:00
										 |  |  | 	const char *home = getenv("HOME"); | 
					
						
							|  |  |  | 	const char *path = "/Library/Application Support/Subsurface"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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:17 +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:17 +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:17 +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:17 +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; | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 	if (dc_type != DC_TYPE_UEMIS) { | 
					
						
							|  |  |  | 		const char *dirname = "/dev"; | 
					
						
							|  |  |  | 		const char *patterns[] = { | 
					
						
							|  |  |  | 			"tty.*", | 
					
						
							|  |  |  | 			"usbserial", | 
					
						
							|  |  |  | 			NULL | 
					
						
							|  |  |  | 		}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		dp = opendir(dirname); | 
					
						
							|  |  |  | 		if (dp == NULL) { | 
					
						
							|  |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		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-23 17:25:11 -07: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; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		closedir(dp); | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 	if (dc_type != DC_TYPE_SERIAL) { | 
					
						
							|  |  |  | 		const char *dirname = "/Volumes"; | 
					
						
							| 
									
										
										
										
											2014-05-18 14:13:23 +09:00
										 |  |  | 		int num_uemis = 0; | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 		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) { | 
					
						
							|  |  |  | 			if (fnmatch("UEMISSDA", ep->d_name, 0) == 0) { | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 				char filename[1024]; | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 				int n = snprintf(filename, sizeof(filename), "%s/%s", dirname, ep->d_name); | 
					
						
							| 
									
										
										
										
											2016-03-23 17:25:11 -07:00
										 |  |  | 				if (n >= (int)sizeof(filename)) { | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 					closedir(dp); | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 					return -1; | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 				callback(filename, userdata); | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 				if (is_default_dive_computer_device(filename)) | 
					
						
							| 
									
										
										
										
											2014-05-18 14:13:23 +09:00
										 |  |  | 					index = entries; | 
					
						
							|  |  |  | 				entries++; | 
					
						
							|  |  |  | 				num_uemis++; | 
					
						
							| 
									
										
										
										
											2013-09-16 18:04:42 -03:00
										 |  |  | 				break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-05-18 13:29:40 +09:00
										 |  |  | 		closedir(dp); | 
					
						
							| 
									
										
										
										
											2014-05-18 14:13:23 +09:00
										 |  |  | 		if (num_uemis == 1 && entries == 1) /* if we find exactly one entry and that's a Uemis, select it */ | 
					
						
							|  |  |  | 			index = 0; | 
					
						
							| 
									
										
										
										
											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 01:14:06 -08: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); | 
					
						
							|  |  |  | } |