diff options
-rw-r--r-- | src/firecfg/desktop_files.c | 27 | ||||
-rw-r--r-- | src/firecfg/firecfg.h | 2 | ||||
-rw-r--r-- | src/firecfg/main.c | 61 | ||||
-rw-r--r-- | src/man/firecfg.1.in | 2 |
4 files changed, 66 insertions, 26 deletions
diff --git a/src/firecfg/desktop_files.c b/src/firecfg/desktop_files.c index 8918b8a95..ecb18a60e 100644 --- a/src/firecfg/desktop_files.c +++ b/src/firecfg/desktop_files.c | |||
@@ -118,6 +118,9 @@ void fix_desktop_files(const char *homedir) { | |||
118 | exit(1); | 118 | exit(1); |
119 | } | 119 | } |
120 | 120 | ||
121 | // build ignorelist | ||
122 | parse_config_all(0); | ||
123 | |||
121 | // destination | 124 | // destination |
122 | // create ~/.local/share/applications directory if necessary | 125 | // create ~/.local/share/applications directory if necessary |
123 | char *user_apps_dir; | 126 | char *user_apps_dir; |
@@ -163,7 +166,8 @@ void fix_desktop_files(const char *homedir) { | |||
163 | // copy | 166 | // copy |
164 | struct dirent *entry; | 167 | struct dirent *entry; |
165 | while ((entry = readdir(dir)) != NULL) { | 168 | while ((entry = readdir(dir)) != NULL) { |
166 | if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) | 169 | const char *filename = entry->d_name; |
170 | if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) | ||
167 | continue; | 171 | continue; |
168 | 172 | ||
169 | // skip if not regular file or link | 173 | // skip if not regular file or link |
@@ -172,10 +176,25 @@ void fix_desktop_files(const char *homedir) { | |||
172 | continue; | 176 | continue; |
173 | 177 | ||
174 | // skip if not .desktop file | 178 | // skip if not .desktop file |
175 | if (strstr(entry->d_name,".desktop") != (entry->d_name+strlen(entry->d_name)-8)) | 179 | char *exec = strdup(filename); |
180 | if (!exec) | ||
181 | errExit("strdup"); | ||
182 | char *ptr = strstr(exec, ".desktop"); | ||
183 | if (ptr == NULL || *(ptr + 8) != '\0') { | ||
184 | printf(" %s skipped (not a .desktop file)\n", exec); | ||
185 | free(exec); | ||
176 | continue; | 186 | continue; |
187 | } | ||
188 | |||
189 | // skip if program is in ignorelist | ||
190 | *ptr = '\0'; | ||
191 | if (in_ignorelist(exec)) { | ||
192 | printf(" %s ignored\n", exec); | ||
193 | free(exec); | ||
194 | continue; | ||
195 | } | ||
177 | 196 | ||
178 | char *filename = entry->d_name; | 197 | free(exec); |
179 | 198 | ||
180 | // skip links - Discord on Arch #4235 seems to be a symlink to /opt directory | 199 | // skip links - Discord on Arch #4235 seems to be a symlink to /opt directory |
181 | // if (is_link(filename)) | 200 | // if (is_link(filename)) |
@@ -221,7 +240,7 @@ void fix_desktop_files(const char *homedir) { | |||
221 | } | 240 | } |
222 | 241 | ||
223 | // get executable name | 242 | // get executable name |
224 | char *ptr = strstr(buf,"\nExec="); | 243 | ptr = strstr(buf,"\nExec="); |
225 | if (!ptr || strlen(ptr) < 7) { | 244 | if (!ptr || strlen(ptr) < 7) { |
226 | if (arg_debug) | 245 | if (arg_debug) |
227 | printf(" %s - skipped: wrong format?\n", filename); | 246 | printf(" %s - skipped: wrong format?\n", filename); |
diff --git a/src/firecfg/firecfg.h b/src/firecfg/firecfg.h index 4379c0d44..d5996461e 100644 --- a/src/firecfg/firecfg.h +++ b/src/firecfg/firecfg.h | |||
@@ -50,6 +50,8 @@ | |||
50 | 50 | ||
51 | // main.c | 51 | // main.c |
52 | extern int arg_debug; | 52 | extern int arg_debug; |
53 | int in_ignorelist(const char *const str); | ||
54 | void parse_config_all(int do_symlink); | ||
53 | 55 | ||
54 | // util.c | 56 | // util.c |
55 | int which(const char *program); | 57 | int which(const char *program); |
diff --git a/src/firecfg/main.c b/src/firecfg/main.c index 5677c5d37..74a9c0fef 100644 --- a/src/firecfg/main.c +++ b/src/firecfg/main.c | |||
@@ -25,6 +25,7 @@ | |||
25 | int arg_debug = 0; | 25 | int arg_debug = 0; |
26 | char *arg_bindir = "/usr/local/bin"; | 26 | char *arg_bindir = "/usr/local/bin"; |
27 | int arg_guide = 0; | 27 | int arg_guide = 0; |
28 | int done_config = 0; | ||
28 | 29 | ||
29 | static const char *const usage_str = | 30 | static const char *const usage_str = |
30 | "Firecfg is the desktop configuration utility for Firejail software. The utility\n" | 31 | "Firecfg is the desktop configuration utility for Firejail software. The utility\n" |
@@ -166,7 +167,7 @@ static int append_ignorelist(const char *const str) { | |||
166 | return 1; | 167 | return 1; |
167 | } | 168 | } |
168 | 169 | ||
169 | static int in_ignorelist(const char *const str) { | 170 | int in_ignorelist(const char *const str) { |
170 | assert(str); | 171 | assert(str); |
171 | int i; | 172 | int i; |
172 | for (i = 0; i < ignorelist_len; i++) { | 173 | for (i = 0; i < ignorelist_len; i++) { |
@@ -202,8 +203,11 @@ static void set_file(const char *name, const char *firejail_exec) { | |||
202 | } | 203 | } |
203 | 204 | ||
204 | // parse a single config file | 205 | // parse a single config file |
205 | static void set_links_firecfg(const char *cfgfile) { | 206 | static void parse_config_file(const char *cfgfile, int do_symlink) { |
206 | printf("Configuring symlinks in %s based on %s\n", arg_bindir, cfgfile); | 207 | if (do_symlink) |
208 | printf("Configuring symlinks in %s\n", arg_bindir); | ||
209 | |||
210 | printf("Parsing %s\n", cfgfile); | ||
207 | 211 | ||
208 | FILE *fp = fopen(cfgfile, "r"); | 212 | FILE *fp = fopen(cfgfile, "r"); |
209 | if (!fp) { | 213 | if (!fp) { |
@@ -246,11 +250,15 @@ static void set_links_firecfg(const char *cfgfile) { | |||
246 | continue; | 250 | continue; |
247 | } | 251 | } |
248 | 252 | ||
253 | // skip ignored programs | ||
254 | if (in_ignorelist(start)) { | ||
255 | printf(" %s ignored\n", start); | ||
256 | continue; | ||
257 | } | ||
258 | |||
249 | // set link | 259 | // set link |
250 | if (!in_ignorelist(start)) | 260 | if (do_symlink) |
251 | set_file(start, FIREJAIL_EXEC); | 261 | set_file(start, FIREJAIL_EXEC); |
252 | else | ||
253 | printf(" %s ignored\n", start); | ||
254 | } | 262 | } |
255 | 263 | ||
256 | fclose(fp); | 264 | fclose(fp); |
@@ -258,7 +266,7 @@ static void set_links_firecfg(const char *cfgfile) { | |||
258 | } | 266 | } |
259 | 267 | ||
260 | // parse all config files matching pattern | 268 | // parse all config files matching pattern |
261 | static void set_links_firecfg_glob(const char *pattern) { | 269 | static void parse_config_glob(const char *pattern, int do_symlink) { |
262 | printf("Looking for config files in %s\n", pattern); | 270 | printf("Looking for config files in %s\n", pattern); |
263 | 271 | ||
264 | glob_t globbuf; | 272 | glob_t globbuf; |
@@ -274,11 +282,23 @@ static void set_links_firecfg_glob(const char *pattern) { | |||
274 | 282 | ||
275 | size_t i; | 283 | size_t i; |
276 | for (i = 0; i < globbuf.gl_pathc; i++) | 284 | for (i = 0; i < globbuf.gl_pathc; i++) |
277 | set_links_firecfg(globbuf.gl_pathv[i]); | 285 | parse_config_file(globbuf.gl_pathv[i], do_symlink); |
278 | out: | 286 | out: |
279 | globfree(&globbuf); | 287 | globfree(&globbuf); |
280 | } | 288 | } |
281 | 289 | ||
290 | // parse all config files | ||
291 | // do_symlink 0 just builds the ignorelist, 1 creates the symlinks | ||
292 | void parse_config_all(int do_symlink) { | ||
293 | if (done_config) | ||
294 | return; | ||
295 | |||
296 | parse_config_glob(FIRECFG_CONF_GLOB, do_symlink); | ||
297 | parse_config_file(FIRECFG_CFGFILE, do_symlink); | ||
298 | |||
299 | done_config = 1; | ||
300 | } | ||
301 | |||
282 | // parse ~/.config/firejail/ directory | 302 | // parse ~/.config/firejail/ directory |
283 | static void set_links_homedir(const char *homedir) { | 303 | static void set_links_homedir(const char *homedir) { |
284 | assert(homedir); | 304 | assert(homedir); |
@@ -314,17 +334,19 @@ static void set_links_homedir(const char *homedir) { | |||
314 | if (!exec) | 334 | if (!exec) |
315 | errExit("strdup"); | 335 | errExit("strdup"); |
316 | char *ptr = strrchr(exec, '.'); | 336 | char *ptr = strrchr(exec, '.'); |
317 | if (!ptr) { | 337 | if (!ptr) |
318 | free(exec); | 338 | goto next; |
319 | continue; | 339 | if (strcmp(ptr, ".profile") != 0) |
320 | } | 340 | goto next; |
321 | if (strcmp(ptr, ".profile") != 0) { | ||
322 | free(exec); | ||
323 | continue; | ||
324 | } | ||
325 | 341 | ||
326 | *ptr = '\0'; | 342 | *ptr = '\0'; |
343 | if (in_ignorelist(exec)) { | ||
344 | printf(" %s ignored\n", exec); | ||
345 | goto next; | ||
346 | } | ||
347 | |||
327 | set_file(exec, FIREJAIL_EXEC); | 348 | set_file(exec, FIREJAIL_EXEC); |
349 | next: | ||
328 | free(exec); | 350 | free(exec); |
329 | } | 351 | } |
330 | closedir(dir); | 352 | closedir(dir); |
@@ -518,11 +540,8 @@ int main(int argc, char **argv) { | |||
518 | // clear all symlinks | 540 | // clear all symlinks |
519 | clean(); | 541 | clean(); |
520 | 542 | ||
521 | // set new symlinks based on .conf files | 543 | // set new symlinks based on config files |
522 | set_links_firecfg_glob(FIRECFG_CONF_GLOB); | 544 | parse_config_all(1); |
523 | |||
524 | // set new symlinks based on firecfg.config | ||
525 | set_links_firecfg(FIRECFG_CFGFILE); | ||
526 | 545 | ||
527 | if (getuid() == 0) { | 546 | if (getuid() == 0) { |
528 | // add user to firejail access database - only for root | 547 | // add user to firejail access database - only for root |
diff --git a/src/man/firecfg.1.in b/src/man/firecfg.1.in index e43a573de..79802156c 100644 --- a/src/man/firecfg.1.in +++ b/src/man/firecfg.1.in | |||
@@ -168,7 +168,7 @@ Configuration file syntax: | |||
168 | A line that starts with \fB#\fR is considered a comment. | 168 | A line that starts with \fB#\fR is considered a comment. |
169 | .br | 169 | .br |
170 | A line that starts with \fB!PROGRAM\fR means to ignore "PROGRAM" when creating | 170 | A line that starts with \fB!PROGRAM\fR means to ignore "PROGRAM" when creating |
171 | symlinks. | 171 | symlinks and fixing .desktop files. |
172 | .br | 172 | .br |
173 | A line that starts with anything else is considered to be the name of an | 173 | A line that starts with anything else is considered to be the name of an |
174 | executable and firecfg will attempt to create a symlink for it. | 174 | executable and firecfg will attempt to create a symlink for it. |