version up to 2.1.0
[platform/core/system/sdbd.git] / src / init.c
1 /*
2  * This file is part of libsmack. Derived from libselinux/src/init.c.
3  *
4  * Copyright (C) 2012 Intel Corporation
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * version 2.1 as published by the Free Software Foundation.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18  * 02110-1301 USA
19  *
20  * Authors:
21  * Passion Zhao <passion.zhao@intel.com>
22  */
23
24 #include <unistd.h>
25 #include <fcntl.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <ctype.h>
30 #include <stdio.h>
31 #include <stdio_ext.h>
32 #include <dlfcn.h>
33 #include <sys/statvfs.h>
34 #include <sys/vfs.h>
35 #include <stdint.h>
36 #include <limits.h>
37
38 /*
39  *  * smackfs magic number
40  *   */
41 #define SMACK_MAGIC     0x43415d53 /* "SMAC" */
42
43 /* smack file system type */
44 #define SMACKFS "smackfs"
45
46 #define SMACKFSMNT "/sys/fs/smackfs/"
47 #define OLDSMACKFSMNT "/smack"
48
49 char *smack_mnt = NULL;
50
51 void set_smackmnt(const char *mnt)
52 {
53         smack_mnt = strdup(mnt);
54 }
55
56 /* Verify the mount point for smack file system has a smackfs.
57  * If the file system:
58  * Exist,
59  * Is mounted with an smack file system,
60  * The file system is read/write
61  * then set this as the default file system.
62  */
63 static int verify_smackmnt(const char *mnt)
64 {
65         struct statfs sfbuf;
66         int rc;
67
68         do {
69                 rc = statfs(mnt, &sfbuf);
70         } while (rc < 0 && errno == EINTR);
71
72         if (rc == 0) {
73                 if ((uint32_t)sfbuf.f_type == (uint32_t)SMACK_MAGIC) {
74                         struct statvfs vfsbuf;
75                         rc = statvfs(mnt, &vfsbuf);
76                         if (rc == 0) {
77                                 if (!(vfsbuf.f_flag & ST_RDONLY)) {
78                                         set_smackmnt(mnt);
79                                 }
80                                 return 0;
81                         }
82                 }
83         }
84
85         return -1;
86 }
87
88 int smackfs_exists(void)
89 {
90         int exists = 0;
91         FILE *fp = NULL;
92         char *buf = NULL;
93         size_t len;
94         ssize_t num;
95
96         fp = fopen("/proc/filesystems", "r");
97         if (!fp)
98                 return 1; /* Fail as if it exists */
99
100         __fsetlocking(fp, FSETLOCKING_BYCALLER);
101
102         num = getline(&buf, &len, fp);
103         while (num != -1) {
104                 if (strstr(buf, SMACKFS)) {
105                         exists = 1;
106                         break;
107                 }
108                 num = getline(&buf, &len, fp);
109         }
110
111         free(buf);
112         fclose(fp);
113         return exists;
114 }
115
116 static void init_smackmnt(void)
117 {
118         char *buf=NULL, *p;
119         FILE *fp=NULL;
120         size_t len;
121         ssize_t num;
122
123         if (smack_mnt)
124                 return;
125
126         if (verify_smackmnt(SMACKFSMNT) == 0) 
127                 return;
128
129         if (verify_smackmnt(OLDSMACKFSMNT) == 0) 
130                 return;
131
132         /* Drop back to detecting it the long way. */
133         if (!smackfs_exists())
134                 goto out;
135
136         /* At this point, the usual spot doesn't have an smackfs so
137          * we look around for it */
138         fp = fopen("/proc/mounts", "r");
139         if (!fp)
140                 goto out;
141
142         __fsetlocking(fp, FSETLOCKING_BYCALLER);
143         while ((num = getline(&buf, &len, fp)) != -1) {
144                 char *tmp;
145                 p = strchr(buf, ' ');
146                 if (!p)
147                         goto out;
148                 p++;
149
150                 tmp = strchr(p, ' ');
151                 if (!tmp)
152                         goto out;
153
154                 if (!strncmp(tmp + 1, SMACKFS" ", strlen(SMACKFS)+1)) {
155                         *tmp = '\0';
156                         break;
157                 }
158         }
159
160         /* If we found something, dup it */
161         if (num > 0)
162                 verify_smackmnt(p);
163
164       out:
165         free(buf);
166         if (fp)
167                 fclose(fp);
168         return;
169 }
170
171 void fini_smackmnt(void)
172 {
173         free(smack_mnt);
174         smack_mnt = NULL;
175 }
176
177 static void init_lib(void) __attribute__ ((constructor));
178 static void init_lib(void)
179 {
180         init_smackmnt();
181 }
182
183 static void fini_lib(void) __attribute__ ((destructor));
184 static void fini_lib(void)
185 {
186         fini_smackmnt();
187 }