💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › beaf33eaf2b21b3957c28457efd45… captured on 2023-09-08 at 16:25:11. Gemini links have been rewritten to link to archived content

View Raw

More Information

⬅️ Previous capture (2023-04-19)

🚧 View Differences

-=-=-=-=-=-=-

Go Back

0 /* See LICENSE file for copyright and license details. */

1 #include <sys/wait.h>

2 #ifdef __linux__

3 #include <sys/prctl.h>

4 #endif

5 #ifndef NO_SANDBOX

6 #ifdef sun

7 #include <priv.h>

8 int init_privs(const char **privs);

9 #endif

10 #endif

11 #include <stdio.h>

12 #include <stdlib.h>

13 #include <unistd.h>

14 #include <string.h>

15 #include <fcntl.h>

16 #include "cert.h"

17 #include "str.h"

18

19 const char startby[] = "XDG_DOWNLOAD_DIR=\"$HOME";

20

21 #ifndef DISABLE_XDG

22 #if defined(__FreeBSD__) || defined(__OpenBSD__) || \

23 defined(__linux__) || defined(sun)

24

25 int xdg_pipe[2] = {-1, -1};

26 int xdg_open(const char*);

27

28 int xdg_request(char* str) {

29 int len = strnlen(str, 1024)+1;

30 return write(xdg_pipe[1], str, len) != len;

31 }

32

33 void xdg_listener() {

34 char buf[4096];

35 while (1) {

36 int len = read(xdg_pipe[0], buf, sizeof(buf));

37 if (len <= 0)

38 break;

39 xdg_open(buf);

40 }

41 }

42

43 int xdg_init() {

44 if (gethomefd() < 0) {

45 return -1;

46 }

47

48 if (pipe(xdg_pipe)) {

49 printf("pipe failed\n");

50 return -1;

51 }

52 int pid = fork();

53 if (pid != 0) {

54 close(xdg_pipe[0]);

55 return 0;

56 }

57 close(xdg_pipe[1]);

58

59 chdir(download_path);

60

61 #ifndef NO_SANDBOX

62 #ifdef __OpenBSD__

63 if (unveil("/bin/sh", "x") ||

64 unveil("/usr/bin/which", "x") ||

65 unveil("/usr/local/bin/xdg-open", "x") ||

66 unveil(NULL, NULL)) {

67 close(xdg_pipe[1]);

68 exit(-1);

69 }

70 if (pledge("stdio rpath exec proc", NULL)) {

71 close(xdg_pipe[1]);

72 exit(-1);

73 }

74 #endif

75 #ifdef sun

76 const char* privs[] = {PRIV_PROC_FORK, PRIV_PROC_EXEC,

77 PRIV_FILE_READ, PRIV_FILE_WRITE, NULL};

78 if (init_privs(privs)) {

79 exit(-1);

80 }

81 #endif

82 #endif

83

84 #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)

85 setproctitle("vgmi.xdg");

86 #endif

87 #ifdef __linux__

88 prctl(PR_SET_NAME, "vgmi [xdg]", 0, 0, 0);

89 #endif

90 xdg_listener();

91 exit(0);

92 }

93

94 void xdg_close() {

95 if (xdg_pipe[0] > -1)

96 close(xdg_pipe[0]);

97 if (xdg_pipe[1] > -1)

98 close(xdg_pipe[1]);

99 }

100

101 #endif

102 #endif

103

104 #define SB_IGNORE

105 #include "gemini.h"

106 int xdg_open(const char* str) {

107 if (!client.xdg) return 0;

108 char buf[4096];

109 snprintf(buf, sizeof(buf), "xdg-open %s>/dev/null 2>&1", str);

110 if (fork() == 0) {

111 setsid();

112 char* argv[] = {"/bin/sh", "-c", buf, NULL};

113 execvp(argv[0], argv);

114 exit(0);

115 }

116 return 0;

117 }

118

119 int xdg_path(char* path, size_t len) {

120 int home = gethomefd();

121 if (home < 0) return -1;

122 int fd = openat(home, ".config/user-dirs.dirs", O_RDONLY);

123 if (fd < 0) return -1;

124 char line[1024];

125 int found = -1;

126 for (size_t i = 0; found; i++) {

127 if (i >= sizeof(line)) break;

128 if (read(fd, &line[i], 1) != 1) break;

129 if (line[i] != '\n') continue;

130 line[i] = '\0';

131 if (sizeof(startby) >= i ||

132 strncmp(line, startby, sizeof(startby) - 1)) {

133 i = -1;

134 continue;

135 }

136 int offset = strlcpy(path, home_path, len);

137 for (size_t j = 0; j < len - 1; j++) {

138 path[offset + j] = line[sizeof(startby) - 1 + j];

139 if (path[offset + j] == '"') {

140 found = 0;

141 path[offset + j] = 0;

142 break;

143 }

144 }

145 }

146 close(fd);

147 return found;

148 }

149