summaryrefslogtreecommitdiff
path: root/package/mpd/patches/patch-src_db_SimpleDatabasePlugin_cxx
blob: 0f28de720eb25cea55c02dacf620b461b197fff8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
--- mpd-0.18.5.orig/src/db/SimpleDatabasePlugin.cxx	2013-11-22 00:33:30.000000000 +0100
+++ mpd-0.18.5/src/db/SimpleDatabasePlugin.cxx	2013-11-30 19:17:55.000000000 +0100
@@ -35,6 +35,9 @@
 
 #include <sys/types.h>
 #include <errno.h>
+#include <sys/mount.h> 
+#include <mntent.h>
+#include <string.h>
 
 static constexpr Domain simple_db_domain("simple_db");
 
@@ -95,8 +98,8 @@ SimpleDatabase::Check(Error &error) cons
 			return false;
 		}
 
-		/* Check if we can write to the directory */
-		if (!CheckAccess(dirPath, X_OK | W_OK)) {
+		/* Check if we can change into the directory */
+		if (!CheckAccess(dirPath, X_OK)) {
 			const int e = errno;
 			const std::string dirPath_utf8 = dirPath.ToUTF8();
 			error.FormatErrno(e, "Can't create db file in \"%s\"",
@@ -122,9 +125,9 @@ SimpleDatabase::Check(Error &error) cons
 		return false;
 	}
 
-	/* And check that we can write to it */
-	if (!CheckAccess(path, R_OK | W_OK)) {
-		error.FormatErrno("Can't open db file \"%s\" for reading/writing",
+	/* And check that we can read it */
+	if (!CheckAccess(path, R_OK)) {
+		error.FormatErrno("Can't open db file \"%s\" for reading",
 				  path_utf8.c_str());
 		return false;
 	}
@@ -281,6 +284,10 @@ SimpleDatabase::GetStats(const DatabaseS
 bool
 SimpleDatabase::Save(Error &error)
 {
+	struct mntent *mnt;
+	int remount;
+	FILE *f;
+
 	db_lock();
 
 	LogDebug(simple_db_domain, "removing empty directories from DB");
@@ -293,6 +300,26 @@ SimpleDatabase::Save(Error &error)
 
 	LogDebug(simple_db_domain, "writing DB");
 
+	remount = 0;
+	/* check if /data is mounted read-only */
+	if ((f = setmntent("/proc/mounts", "r")) == NULL)
+		error.Format(simple_db_domain, "Checking /proc/mounts failed");
+
+	while ((mnt = getmntent(f)) != NULL) {
+		if (strcmp(mnt->mnt_dir, "/data") == 0 &&
+			hasmntopt(mnt, MNTOPT_RO) != NULL) {
+			remount = 1;
+		}
+	}
+	endmntent(f);
+
+	if (remount) {		
+		if (mount("","/data",0,MS_REMOUNT,0)<0) {
+			error.Format(simple_db_domain, "Remounting /data rw failed");
+		}
+		LogDebug(simple_db_domain, "Mounted /data successfully in read-write mode"); 
+	}
+
 	FILE *fp = FOpen(path, FOpenMode::WriteText);
 	if (!fp) {
 		error.FormatErrno("unable to write to db file \"%s\"",
@@ -310,6 +337,16 @@ SimpleDatabase::Save(Error &error)
 
 	fclose(fp);
 
+	if (remount) {
+		sync();
+		if (mount("","/data",0,MS_REMOUNT|MS_RDONLY,0)<0) {
+			error.Format(simple_db_domain, "Remounting /data ro failed");
+		}
+		LogDebug(simple_db_domain, "Mounted /data successfully in read-only mode");
+	}
+
+	LogDebug(simple_db_domain, "Successfully written database");	
+
 	struct stat st;
 	if (StatFile(path, st))
 		mtime = st.st_mtime;