Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : */
8 :
9 : #include "fstab.h"
10 :
11 : #ifndef HAVE_KDBCONFIG
12 : #include "kdbconfig.h"
13 : #endif
14 :
15 : #include <kdblogger.h>
16 :
17 : #define MAX_NUMBER_SIZE 10
18 :
19 : /** @param name is a buffer with KDB_MAX_PATH_LENGTH space.
20 : * @param fstabEntry will be used to get the name:
21 : * @param swapIndex will count up for every swap
22 : *
23 : * - mnt_type will be checked if it is swap
24 : *
25 : * TODO Improvements:
26 : * - no counting up of swap?
27 : * - handle mountpoints none?
28 : *
29 : * Some logic to define the filesystem name when it is not
30 : * so obvious.
31 : */
32 6 : void elektraFstabFsName (char * fsname, struct mntent * fstabEntry, unsigned int * swapIndex)
33 : {
34 :
35 6 : if (!strcmp (fstabEntry->mnt_type, "swap"))
36 : {
37 2 : sprintf (fsname, "swap%02d", *swapIndex);
38 2 : ++(*swapIndex);
39 : }
40 4 : else if (!strcmp (fstabEntry->mnt_dir, "none"))
41 : {
42 0 : strcpy (fsname, fstabEntry->mnt_type);
43 : }
44 : else
45 : {
46 : // Otherwise take dir as-is
47 4 : strcpy (fsname, fstabEntry->mnt_dir);
48 : }
49 6 : }
50 :
51 24 : int elektraFstabGet (Plugin * handle ELEKTRA_UNUSED, KeySet * returned, Key * parentKey)
52 : {
53 24 : int errnosave = errno;
54 24 : ssize_t nr_keys = 0;
55 : Key * key;
56 : Key * dir;
57 24 : FILE * fstab = 0;
58 :
59 : ELEKTRA_LOG ("get fstab %s from %s\n", keyName (parentKey), keyString (parentKey));
60 :
61 24 : if (!strcmp (keyName (parentKey), "system/elektra/modules/fstab"))
62 : {
63 : // clang-format off
64 22 : KeySet *moduleConfig = ksNew (50,
65 : keyNew ("system/elektra/modules/fstab",
66 : KEY_VALUE, "fstab plugin waits for your orders", KEY_END),
67 : keyNew ("system/elektra/modules/fstab/exports", KEY_END),
68 : keyNew ("system/elektra/modules/fstab/exports/get",
69 : KEY_FUNC, elektraFstabGet,
70 : KEY_END),
71 : keyNew ("system/elektra/modules/fstab/exports/set",
72 : KEY_FUNC, elektraFstabSet,
73 : KEY_END),
74 : #include "readme_fstab.c"
75 : keyNew ("system/elektra/modules/fstab/infos/version",
76 : KEY_VALUE, PLUGINVERSION, KEY_END),
77 : keyNew ("system/elektra/modules/fstab/config/needs",
78 : KEY_VALUE, "The configuration which is needed",
79 : KEY_END),
80 : keyNew ("system/elektra/modules/fstab/config/needs/struct",
81 : KEY_VALUE, "list FStab",
82 : KEY_END),
83 : keyNew ("system/elektra/modules/fstab/config/needs/struct/FStab",
84 : KEY_META, "check/type", "null empty",
85 : KEY_END),
86 : keyNew ("system/elektra/modules/fstab/config/needs/struct/FStab/device",
87 : KEY_META, "check/type", "string",
88 : KEY_META, "check/path", "device",
89 : KEY_END),
90 : keyNew ("system/elektra/modules/fstab/config/needs/struct/FStab/mpoint",
91 : KEY_META, "check/type", "string",
92 : KEY_META, "check/path", "directory",
93 : KEY_END),
94 : keyNew ("system/elektra/modules/fstab/config/needs/struct/FStab/type",
95 : KEY_META, "check/type", "FSType",
96 : KEY_END),
97 : keyNew ("system/elektra/modules/fstab/config/needs/struct/FStab/options",
98 : KEY_META, "check/type", "string",
99 : KEY_END),
100 : keyNew ("system/elektra/modules/fstab/config/needs/struct/FStab/dumpfreq",
101 : KEY_META, "check/type", "unsigned_short",
102 : KEY_END),
103 : keyNew ("system/elektra/modules/fstab/config/needs/struct/FStab/passno",
104 : KEY_META, "check/type", "unsigned_short",
105 : KEY_END),
106 : KS_END);
107 : // clang-format on
108 22 : ksAppend (returned, moduleConfig);
109 22 : ksDel (moduleConfig);
110 22 : return 1;
111 : }
112 :
113 2 : key = keyDup (parentKey);
114 2 : ksAppendKey (returned, key);
115 2 : nr_keys++;
116 :
117 2 : fstab = setmntent (keyString (parentKey), "r");
118 2 : if (fstab == 0)
119 : {
120 0 : ELEKTRA_SET_ERROR_GET (parentKey);
121 0 : errno = errnosave;
122 0 : return -1;
123 : }
124 :
125 : struct mntent * fstabEntry;
126 : char fsname[KDB_MAX_PATH_LENGTH];
127 : char buffer[MAX_NUMBER_SIZE];
128 2 : unsigned int swapIndex = 0;
129 10 : while ((fstabEntry = getmntent (fstab)))
130 : {
131 6 : nr_keys += 7;
132 6 : elektraFstabFsName (fsname, fstabEntry, &swapIndex);
133 :
134 : /* Include only the filesystem pseudo-names */
135 6 : dir = keyDup (parentKey);
136 6 : keyAddBaseName (dir, fsname);
137 6 : keySetString (dir, "");
138 6 : keySetComment (dir, "");
139 6 : keySetComment (dir, "Filesystem pseudo-name");
140 6 : ksAppendKey (returned, dir);
141 :
142 6 : key = keyDup (dir);
143 6 : keyAddBaseName (key, "device");
144 6 : keySetString (key, fstabEntry->mnt_fsname);
145 6 : keySetComment (key, "Device or Label");
146 6 : ksAppendKey (returned, key);
147 :
148 6 : key = keyDup (dir);
149 6 : keyAddBaseName (key, "mpoint");
150 6 : keySetString (key, fstabEntry->mnt_dir);
151 6 : keySetComment (key, "Mount point");
152 6 : ksAppendKey (returned, key);
153 :
154 6 : key = keyDup (dir);
155 6 : keyAddBaseName (key, "type");
156 6 : keySetString (key, fstabEntry->mnt_type);
157 6 : keySetComment (key, "Filesystem type.");
158 6 : ksAppendKey (returned, key);
159 :
160 6 : key = keyDup (dir);
161 6 : keyAddBaseName (key, "options");
162 6 : keySetString (key, fstabEntry->mnt_opts);
163 6 : keySetComment (key, "Filesystem specific options");
164 6 : ksAppendKey (returned, key);
165 :
166 6 : key = keyDup (dir);
167 6 : keyAddBaseName (key, "dumpfreq");
168 6 : snprintf (buffer, MAX_NUMBER_SIZE, "%d", fstabEntry->mnt_freq);
169 6 : keySetString (key, buffer);
170 6 : keySetComment (key, "Dump frequency in days");
171 6 : ksAppendKey (returned, key);
172 :
173 6 : key = keyDup (dir);
174 6 : keyAddBaseName (key, "passno");
175 6 : snprintf (buffer, MAX_NUMBER_SIZE, "%d", fstabEntry->mnt_passno);
176 6 : keySetString (key, buffer);
177 6 : keySetComment (key, "Pass number on parallel fsck");
178 6 : ksAppendKey (returned, key);
179 : }
180 :
181 2 : endmntent (fstab);
182 :
183 2 : errno = errnosave;
184 2 : return nr_keys;
185 : }
186 :
187 :
188 2 : int elektraFstabSet (Plugin * handle ELEKTRA_UNUSED, KeySet * ks, Key * parentKey)
189 : {
190 2 : int errnosave = errno;
191 2 : FILE * fstab = 0;
192 2 : Key * key = 0;
193 2 : const void * rootname = 0;
194 : struct mntent fstabEntry;
195 :
196 : ELEKTRA_LOG ("set fstab %s to file %s\n", keyName (parentKey), keyString (parentKey));
197 :
198 2 : ksRewind (ks);
199 2 : if ((key = ksNext (ks)) != 0)
200 : {
201 : /*skip parent key*/
202 : }
203 :
204 2 : fstab = setmntent (keyString (parentKey), "w");
205 :
206 2 : if (fstab == 0)
207 : {
208 0 : ELEKTRA_SET_ERROR_SET (parentKey);
209 0 : errno = errnosave;
210 0 : return -1;
211 : }
212 :
213 2 : memset (&fstabEntry, 0, sizeof (struct mntent));
214 :
215 32 : while ((key = ksNext (ks)) != 0)
216 : {
217 28 : const char * basename = keyBaseName (key);
218 : ELEKTRA_LOG ("key: %s %s\n", keyName (key), basename);
219 28 : if (!strcmp (basename, "device"))
220 : {
221 4 : fstabEntry.mnt_fsname = (char *) keyValue (key);
222 : }
223 24 : else if (!strcmp (basename, "mpoint"))
224 : {
225 4 : fstabEntry.mnt_dir = (char *) keyValue (key);
226 : }
227 20 : else if (!strcmp (basename, "type"))
228 : {
229 4 : fstabEntry.mnt_type = (char *) keyValue (key);
230 : }
231 16 : else if (!strcmp (basename, "options"))
232 : {
233 4 : fstabEntry.mnt_opts = (char *) keyValue (key);
234 : }
235 12 : else if (!strcmp (basename, "dumpfreq"))
236 : {
237 8 : fstabEntry.mnt_freq = atoi ((char *) keyValue (key));
238 : }
239 8 : else if (!strcmp (basename, "passno"))
240 : {
241 8 : fstabEntry.mnt_passno = atoi ((char *) keyValue (key));
242 : }
243 : else
244 : { // new rootname
245 4 : if (!rootname)
246 : {
247 2 : rootname = keyValue (key);
248 : }
249 : else
250 : {
251 2 : rootname = keyValue (key);
252 : ELEKTRA_LOG ("first: %s %s %s %s %d %d\n", fstabEntry.mnt_fsname, fstabEntry.mnt_dir,
253 : fstabEntry.mnt_type, fstabEntry.mnt_opts, fstabEntry.mnt_freq, fstabEntry.mnt_passno);
254 2 : addmntent (fstab, &fstabEntry);
255 2 : memset (&fstabEntry, 0, sizeof (struct mntent));
256 : }
257 : }
258 : }
259 :
260 2 : if (rootname)
261 : {
262 : ELEKTRA_LOG ("last: %s %s %s %s %d %d\n", fstabEntry.mnt_fsname, fstabEntry.mnt_dir, fstabEntry.mnt_type,
263 : fstabEntry.mnt_opts, fstabEntry.mnt_freq, fstabEntry.mnt_passno);
264 2 : addmntent (fstab, &fstabEntry);
265 : }
266 :
267 2 : endmntent (fstab);
268 2 : errno = errnosave;
269 2 : return 1;
270 : }
271 :
272 :
273 26 : Plugin * ELEKTRA_PLUGIN_EXPORT
274 : {
275 : // clang-format off
276 26 : return elektraPluginExport("fstab",
277 : ELEKTRA_PLUGIN_GET, &elektraFstabGet,
278 : ELEKTRA_PLUGIN_SET, &elektraFstabSet,
279 : ELEKTRA_PLUGIN_END);
280 : }
281 :
282 :
|