summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar ಚಿರಾಗ್ ನಟರಾಜ್ <chiraag.nataraj@gmail.com>2018-07-31 00:01:58 -0400
committerLibravatar ಚಿರಾಗ್ ನಟರಾಜ್ <chiraag.nataraj@gmail.com>2018-07-31 00:01:58 -0400
commit123b2b1e256a17425afa32b238a9c448184f065b (patch)
tree7cfa284fafd524468fef1914578ea29cc9655b60
parentMerges (diff)
downloadfirejail-123b2b1e256a17425afa32b238a9c448184f065b.tar.gz
firejail-123b2b1e256a17425afa32b238a9c448184f065b.tar.zst
firejail-123b2b1e256a17425afa32b238a9c448184f065b.zip
Add XDG variable support to blacklist and read-only.
-rw-r--r--src/firejail/firejail.h9
-rw-r--r--src/firejail/fs_whitelist.c269
-rw-r--r--src/firejail/util.c236
3 files changed, 310 insertions, 204 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 0faf10340..9f7936174 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -491,6 +491,15 @@ int arp_check(const char *dev, uint32_t destaddr);
491uint32_t arp_assign(const char *dev, Bridge *br); 491uint32_t arp_assign(const char *dev, Bridge *br);
492 492
493// util.c 493// util.c
494extern char *dentry[];
495extern char *mentry[];
496extern char *ventry[];
497extern char *pentry[];
498extern char *deentry[];
499extern char *doentry[];
500
501char *resolve_xdg(int flags, const char *var, size_t length, const char *prnt);
502char *resolve_hardcoded(int flags, char *entries[], const char *prnt);
494void errLogExit(char* fmt, ...); 503void errLogExit(char* fmt, ...);
495void fwarning(char* fmt, ...); 504void fwarning(char* fmt, ...);
496void fmessage(char* fmt, ...); 505void fmessage(char* fmt, ...);
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index bf839b524..0178e3c5b 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -33,159 +33,20 @@
33// 3. run firejail --debug --whitelist=/tmp/etc 33// 3. run firejail --debug --whitelist=/tmp/etc
34//#define TEST_MOUNTINFO 34//#define TEST_MOUNTINFO
35 35
36static char *dentry[] = {
37 "Downloads",
38 "Загрузки",
39 "Téléchargement",
40 NULL
41};
42
43static char *mentry[] = {
44 "Music",
45 "Музыка",
46 "Musique",
47 NULL
48};
49
50static char *ventry[] = {
51 "Videos",
52 "Видео",
53 "Vidéos",
54 NULL
55};
56
57static char *pentry[] = {
58 "Pictures",
59 "Изображения",
60 "Photos",
61 NULL
62};
63
64static char *deentry[] = {
65 "Desktop",
66 "Рабочий стол",
67 "Bureau",
68 NULL
69};
70
71static char *doentry[] = {
72 "Documents",
73 "Документы",
74 "Documents",
75 NULL
76};
77
78#define EMPTY_STRING ("") 36#define EMPTY_STRING ("")
79#define MAXBUF 4098 37#define MAXBUF 4098
80 38
81static char *resolve_xdg(int nowhitelist_flag, const char *var, size_t length, const char *prnt) { 39char *parse_nowhitelist(int nowhitelist_flag, char *ptr1) {
82 EUID_ASSERT(); 40 char *rv;
83 char *fname; 41 if (nowhitelist_flag) {
84 struct stat s; 42 if (asprintf(&rv, "nowhitelist ~/%s", ptr1) == -1)
85 43 errExit("asprintf");
86 if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1)
87 errExit("asprintf");
88 FILE *fp = fopen(fname, "r");
89 if (!fp) {
90 free(fname);
91 return NULL;
92 }
93 free(fname);
94
95 char buf[MAXBUF];
96 while (fgets(buf, MAXBUF, fp)) {
97 char *ptr = buf;
98
99 // skip blanks
100 while (*ptr == ' ' || *ptr == '\t')
101 ptr++;
102 if (*ptr == '\0' || *ptr == '\n' || *ptr == '#')
103 continue;
104
105 if (strncmp(ptr, var, length) == 0) {
106 char *ptr1 = ptr + length;
107 char *ptr2 = strchr(ptr1, '"');
108 if (ptr2) {
109 fclose(fp);
110 *ptr2 = '\0';
111 if (arg_debug || arg_debug_whitelists)
112 printf("extracted %s from ~/.config/user-dirs.dirs\n", ptr1);
113 if (strlen(ptr1) != 0) {
114 if (arg_debug || arg_debug_whitelists)
115 printf("%s ",prnt);
116 printf("directory resolved as \"%s\"\n", ptr1);
117
118 if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1)
119 errExit("asprintf");
120
121 if (stat(fname, &s) == -1) {
122 free(fname);
123 goto errout;
124 }
125
126 char *rv;
127 if (nowhitelist_flag) {
128 if (asprintf(&rv, "nowhitelist ~/%s", ptr + length) == -1)
129 errExit("asprintf");
130 }
131 else {
132 if (asprintf(&rv, "whitelist ~/%s", ptr + length) == -1)
133 errExit("asprintf");
134 }
135 return rv;
136 }
137 else
138 goto errout;
139 }
140 }
141 }
142
143 fclose(fp);
144 return NULL;
145
146 errout:
147 if (!arg_private) {
148 fprintf(stderr, "***\n");
149 fprintf(stderr, "*** Error: %s directory was not found in user home.\n",prnt);
150 fprintf(stderr, "*** \tAny files saved by the program, will be lost when the sandbox is closed.\n");
151 fprintf(stderr, "***\n");
152 } 44 }
153 return NULL; 45 else {
154} 46 if (asprintf(&rv, "whitelist ~/%s", ptr1) == -1)
155
156static char *resolve_hardcoded(int nowhitelist_flag, char *entries[], const char *prnt) {
157 EUID_ASSERT();
158 char *fname;
159 struct stat s;
160
161 int i = 0;
162 while (entries[i] != NULL) {
163 if (asprintf(&fname, "%s/%s", cfg.homedir, entries[i]) == -1)
164 errExit("asprintf"); 47 errExit("asprintf");
165
166 if (stat(fname, &s) == 0) {
167 if (arg_debug || arg_debug_whitelists) {
168 printf("%s ", prnt);
169 printf("directory resolved as \"%s\"\n", fname);
170 }
171
172 char *rv;
173 if (nowhitelist_flag) {
174 if (asprintf(&rv, "nowhitelist ~/%s", entries[i]) == -1)
175 errExit("asprintf");
176 }
177 else {
178 if (asprintf(&rv, "whitelist ~/%s", entries[i]) == -1)
179 errExit("asprintf");
180 }
181 free(fname);
182 return rv;
183 }
184 free(fname);
185 i++;
186 } 48 }
187 49 return rv;
188 return NULL;
189} 50}
190 51
191static int mkpath(const char* path, mode_t mode) { 52static int mkpath(const char* path, mode_t mode) {
@@ -467,39 +328,43 @@ void fs_whitelist(void) {
467 328
468 // resolve ${DOWNLOADS} 329 // resolve ${DOWNLOADS}
469 if (strcmp(dataptr, "${DOWNLOADS}") == 0) { 330 if (strcmp(dataptr, "${DOWNLOADS}") == 0) {
470 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads"); 331 char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads");
471 char *tmp2 = resolve_hardcoded(nowhitelist_flag, dentry, "Downloads"); 332 char *tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1);
472 if (tmp) { 333 char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, dentry, "Downloads");
473 entry->data = tmp; 334 char *tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2);
474 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 335 if (tmp1 && tmpw1) {
475 } 336 entry->data = tmpw1;
476 else if (tmp2) { 337 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
477 entry->data = tmp2; 338 }
478 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 339 else if (tmp2 && tmpw2) {
479 } 340 entry->data = tmpw2;
480 else { 341 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
481 if (!nowhitelist_flag && !arg_quiet && !arg_private) { 342 }
482 fprintf(stderr, "***\n"); 343 else {
483 fprintf(stderr, "*** Warning: cannot whitelist Downloads directory\n"); 344 if (!nowhitelist_flag && !arg_quiet && !arg_private) {
484 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n"); 345 fprintf(stderr, "***\n");
485 fprintf(stderr, "*** \tPlease create a proper Downloads directory for your application.\n"); 346 fprintf(stderr, "*** Warning: cannot whitelist Downloads directory\n");
486 fprintf(stderr, "***\n"); 347 fprintf(stderr, "*** \tAny file saved will be lost when the sandbox is closed.\n");
487 } 348 fprintf(stderr, "*** \tPlease create a proper Downloads directory for your application.\n");
488 entry->data = EMPTY_STRING; 349 fprintf(stderr, "***\n");
489 continue; 350 }
490 } 351 entry->data = EMPTY_STRING;
352 continue;
353 }
491 } 354 }
492 355
493 // resolve ${MUSIC} 356 // resolve ${MUSIC}
494 if (strcmp(dataptr, "${MUSIC}") == 0) { 357 if (strcmp(dataptr, "${MUSIC}") == 0) {
495 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_MUSIC_DIR=\"$HOME/", 21, "Music"); 358 char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_MUSIC_DIR=\"$HOME/", 21, "Music");
496 char *tmp2 = resolve_hardcoded(nowhitelist_flag, mentry, "Music"); 359 char *tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1);
497 if (tmp) { 360 char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, mentry, "Music");
498 entry->data = tmp; 361 char *tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2);
362 if (tmp1 && tmpw1) {
363 entry->data = tmpw1;
499 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 364 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
500 } 365 }
501 else if (tmp2) { 366 else if (tmp2 && tmpw2) {
502 entry->data = tmp2; 367 entry->data = tmpw2;
503 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 368 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
504 } 369 }
505 else { 370 else {
@@ -517,14 +382,16 @@ void fs_whitelist(void) {
517 382
518 // resolve ${VIDEOS} 383 // resolve ${VIDEOS}
519 if (strcmp(dataptr, "${VIDEOS}") == 0) { 384 if (strcmp(dataptr, "${VIDEOS}") == 0) {
520 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos"); 385 char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos");
521 char *tmp2 = resolve_hardcoded(nowhitelist_flag, ventry, "Videos"); 386 char *tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1);
522 if (tmp) { 387 char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, ventry, "Videos");
523 entry->data = tmp; 388 char *tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2);
389 if (tmp1 && tmpw1) {
390 entry->data = tmpw1;
524 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 391 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
525 } 392 }
526 else if (tmp2) { 393 else if (tmp2 && tmpw2) {
527 entry->data = tmp2; 394 entry->data = tmpw2;
528 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 395 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
529 } 396 }
530 else { 397 else {
@@ -542,14 +409,16 @@ void fs_whitelist(void) {
542 409
543 // resolve ${PICTURES} 410 // resolve ${PICTURES}
544 if (strcmp(dataptr, "${PICTURES}") == 0) { 411 if (strcmp(dataptr, "${PICTURES}") == 0) {
545 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures"); 412 char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures");
546 char *tmp2 = resolve_hardcoded(nowhitelist_flag, pentry, "Pictures"); 413 char *tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1);
547 if (tmp) { 414 char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, pentry, "Pictures");
548 entry->data = tmp; 415 char *tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2);
416 if (tmp1 && tmpw1) {
417 entry->data = tmpw1;
549 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 418 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
550 } 419 }
551 else if (tmp2) { 420 else if (tmp2 && tmpw2) {
552 entry->data = tmp2; 421 entry->data = tmpw2;
553 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 422 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
554 } 423 }
555 else { 424 else {
@@ -567,14 +436,16 @@ void fs_whitelist(void) {
567 436
568 // resolve ${DESKTOP} 437 // resolve ${DESKTOP}
569 if (strcmp(dataptr, "${DESKTOP}") == 0) { 438 if (strcmp(dataptr, "${DESKTOP}") == 0) {
570 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop"); 439 char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop");
571 char *tmp2 = resolve_hardcoded(nowhitelist_flag, deentry, "Desktop"); 440 char *tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1);
572 if (tmp) { 441 char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, deentry, "Desktop");
573 entry->data = tmp; 442 char *tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2);
443 if (tmp1 && tmpw1) {
444 entry->data = tmpw1;
574 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 445 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
575 } 446 }
576 else if (tmp2) { 447 else if (tmp2 && tmpw2) {
577 entry->data = tmp2; 448 entry->data = tmpw2;
578 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 449 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
579 } 450 }
580 else { 451 else {
@@ -592,14 +463,16 @@ void fs_whitelist(void) {
592 463
593 // resolve ${DOCUMENTS} 464 // resolve ${DOCUMENTS}
594 if (strcmp(dataptr, "${DOCUMENTS}") == 0) { 465 if (strcmp(dataptr, "${DOCUMENTS}") == 0) {
595 char *tmp = resolve_xdg(nowhitelist_flag, "XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents"); 466 char *tmp1 = resolve_xdg(arg_debug || arg_debug_whitelists, "XDG_DOCUMENTS_DIR=\"$HOME/", 25, "Documents");
596 char *tmp2 = resolve_hardcoded(nowhitelist_flag, doentry, "Documents"); 467 char *tmpw1 = parse_nowhitelist(nowhitelist_flag, tmp1);
597 if (tmp) { 468 char *tmp2 = resolve_hardcoded(arg_debug || arg_debug_whitelists, doentry, "Documents");
598 entry->data = tmp; 469 char *tmpw2 = parse_nowhitelist(nowhitelist_flag, tmp2);
470 if (tmp1 && tmpw1) {
471 entry->data = tmpw1;
599 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 472 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
600 } 473 }
601 else if (tmp2) { 474 else if (tmp2 && tmpw2) {
602 entry->data = tmp2; 475 entry->data = tmpw2;
603 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10; 476 dataptr = (nowhitelist_flag)? entry->data + 12: entry->data + 10;
604 } 477 }
605 else { 478 else {
diff --git a/src/firejail/util.c b/src/firejail/util.c
index fa32ffcc8..0d6f5ea02 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -32,6 +32,140 @@
32#include <fcntl.h> 32#include <fcntl.h>
33 33
34#define MAX_GROUPS 1024 34#define MAX_GROUPS 1024
35#define MAXBUF 4098
36
37char *dentry[] = {
38 "Downloads",
39 "Загрузки",
40 "Téléchargement",
41 NULL
42};
43
44char *mentry[] = {
45 "Music",
46 "Музыка",
47 "Musique",
48 NULL
49};
50
51char *ventry[] = {
52 "Videos",
53 "Видео",
54 "Vidéos",
55 NULL
56};
57
58char *pentry[] = {
59 "Pictures",
60 "Изображения",
61 "Photos",
62 NULL
63};
64
65char *deentry[] = {
66 "Desktop",
67 "Рабочий стол",
68 "Bureau",
69 NULL
70};
71
72char *doentry[] = {
73 "Documents",
74 "Документы",
75 "Documents",
76 NULL
77};
78
79char *resolve_xdg(int flags, const char *var, size_t length, const char *prnt) {
80 /* EUID_ASSERT(); */
81 char *fname;
82 struct stat s;
83
84 if (asprintf(&fname, "%s/.config/user-dirs.dirs", cfg.homedir) == -1)
85 errExit("asprintf");
86 FILE *fp = fopen(fname, "r");
87 if (!fp) {
88 free(fname);
89 return NULL;
90 }
91 free(fname);
92
93 char buf[MAXBUF];
94 while (fgets(buf, MAXBUF, fp)) {
95 char *ptr = buf;
96
97 // skip blanks
98 while (*ptr == ' ' || *ptr == '\t')
99 ptr++;
100 if (*ptr == '\0' || *ptr == '\n' || *ptr == '#')
101 continue;
102
103 if (strncmp(ptr, var, length) == 0) {
104 char *ptr1 = ptr + length;
105 char *ptr2 = strchr(ptr1, '"');
106 if (ptr2) {
107 fclose(fp);
108 *ptr2 = '\0';
109 if (flags)
110 printf("extracted %s from ~/.config/user-dirs.dirs\n", ptr1);
111 if (strlen(ptr1) != 0) {
112 if (flags)
113 printf("%s ",prnt);
114 printf("directory resolved as \"%s\"\n", ptr1);
115
116 if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1)
117 errExit("asprintf");
118
119 if (stat(fname, &s) == -1) {
120 free(fname);
121 goto errout;
122 }
123 free(fname);
124 return ptr1;
125 }
126 else
127 goto errout;
128 }
129 }
130 }
131
132 fclose(fp);
133 return NULL;
134
135 errout:
136 if (!arg_private) {
137 fprintf(stderr, "***\n");
138 fprintf(stderr, "*** Error: %s directory was not found in user home.\n",prnt);
139 fprintf(stderr, "*** \tAny files saved by the program, will be lost when the sandbox is closed.\n");
140 fprintf(stderr, "***\n");
141 }
142 return NULL;
143}
144
145char *resolve_hardcoded(int flags, char *entries[], const char *prnt) {
146 /* EUID_ASSERT(); */
147 char *fname;
148 struct stat s;
149
150 int i = 0;
151 while (entries[i] != NULL) {
152 if (asprintf(&fname, "%s/%s", cfg.homedir, entries[i]) == -1)
153 errExit("asprintf");
154
155 if (stat(fname, &s) == 0) {
156 if (flags) {
157 printf("%s ", prnt);
158 printf("directory resolved as \"%s\"\n", fname);
159 }
160 free(fname);
161 return entries[i];
162 }
163 free(fname);
164 i++;
165 }
166
167 return NULL;
168}
35 169
36// send the error to /var/log/auth.log and exit after a small delay 170// send the error to /var/log/auth.log and exit after a small delay
37void errLogExit(char* fmt, ...) { 171void errLogExit(char* fmt, ...) {
@@ -740,14 +874,104 @@ char *expand_home(const char *path, const char* homedir) {
740 return new_name; 874 return new_name;
741 } 875 }
742 else if (*path == '~') { 876 else if (*path == '~') {
743 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1) 877 if (asprintf(&new_name, "%s%s", homedir, path + 1) == -1)
744 errExit("asprintf"); 878 errExit("asprintf");
745 return new_name; 879 return new_name;
746 } 880 }
747 else if (strncmp(path, "${CFG}", 6) == 0) { 881 else if (strncmp(path, "${CFG}", 6) == 0) {
748 if (asprintf(&new_name, "%s%s", SYSCONFDIR, path + 6) == -1) 882 if (asprintf(&new_name, "%s%s", SYSCONFDIR, path + 6) == -1)
749 errExit("asprintf"); 883 errExit("asprintf");
750 return new_name; 884 return new_name;
885 }
886
887 else if (strncmp(path, "${DOWNLOADS}", 12) == 0) {
888 char *tmp = resolve_xdg(arg_debug, "XDG_DOWNLOAD_DIR=\"$HOME/", 24, "Downloads");
889 char *tmp2 = resolve_hardcoded(arg_debug, dentry, "Downloads");
890 if(tmp) {
891 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1)
892 errExit("asprintf");
893 return new_name;
894 }
895 else if(tmp2) {
896 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1)
897 errExit("asprintf");
898 return new_name;
899 }
900 }
901
902 else if (strncmp(path, "${MUSIC}", 8) == 0) {
903 char *tmp = resolve_xdg(arg_debug, "XDG_MUSIC_DIR=\"$HOME/", 21, "Music");
904 char *tmp2 = resolve_hardcoded(arg_debug, mentry, "Music");
905 if(tmp) {
906 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 8) == -1)
907 errExit("asprintf");
908 return new_name;
909 }
910 else if(tmp2) {
911 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 8) == -1)
912 errExit("asprintf");
913 return new_name;
914 }
915 }
916
917 else if (strncmp(path, "${VIDEOS}", 9) == 0) {
918 char *tmp = resolve_xdg(arg_debug, "XDG_VIDEOS_DIR=\"$HOME/", 22, "Videos");
919 char *tmp2 = resolve_hardcoded(arg_debug, ventry, "Videos");
920 if(tmp) {
921 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 9) == -1)
922 errExit("asprintf");
923 return new_name;
924 }
925 else if(tmp2) {
926 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 9) == -1)
927 errExit("asprintf");
928 return new_name;
929 }
930 }
931
932 else if (strncmp(path, "${PICTURES}", 11) == 0) {
933 char *tmp = resolve_xdg(arg_debug, "XDG_PICTURES_DIR=\"$HOME/", 24, "Pictures");
934 char *tmp2 = resolve_hardcoded(arg_debug, pentry, "Pictures");
935 if(tmp) {
936 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 11) == -1)
937 errExit("asprintf");
938 return new_name;
939 }
940 else if(tmp2) {
941 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 11) == -1)
942 errExit("asprintf");
943 return new_name;
944 }
945 }
946
947 else if (strncmp(path, "${DESKTOP}", 10) == 0) {
948 char *tmp = resolve_xdg(arg_debug, "XDG_DESKTOP_DIR=\"$HOME/", 24, "Desktop");
949 char *tmp2 = resolve_hardcoded(arg_debug, deentry, "Desktop");
950 if(tmp) {
951 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 10) == -1)
952 errExit("asprintf");
953 return new_name;
954 }
955 else if(tmp2) {
956 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 10) == -1)
957 errExit("asprintf");
958 return new_name;
959 }
960 }
961
962 else if (strncmp(path, "${DOCUMENTS}", 12) == 0) {
963 char *tmp = resolve_xdg(arg_debug, "XDG_DOCUMENTS_DIR=\"$HOME/", 24, "Documents");
964 char *tmp2 = resolve_hardcoded(arg_debug, doentry, "Documents");
965 if(tmp) {
966 if (asprintf(&new_name, "%s/%s%s", homedir, tmp, path + 12) == -1)
967 errExit("asprintf");
968 return new_name;
969 }
970 else if(tmp2) {
971 if (asprintf(&new_name, "%s/%s%s", homedir, tmp2, path + 12) == -1)
972 errExit("asprintf");
973 return new_name;
974 }
751 } 975 }
752 976
753 char *rv = strdup(path); 977 char *rv = strdup(path);