💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Vgmi › files › 449107e8df3229b0160579abac7c6… captured on 2024-02-05 at 09:55:32. Gemini links have been rewritten to link to archived content

View Raw

More Information

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

Go Back

0 /*

1 * ISC License

2 * Copyright (c) 2023 RMF <rawmonk@firemail.cc>

3 */

4 #include <stdio.h>

5 #include <stdlib.h>

6 #include <string.h>

7 #include <stdint.h>

8 #include <time.h>

9 #include <errno.h>

10 #include "macro.h"

11 #include "error.h"

12 #include "config.h"

13 #include "gemini.h"

14 #include "page.h"

15 #include "request.h"

16 #include "tab.h"

17 #include "client.h"

18 #include "termbox.h"

19 #include "utf8.h"

20 #include "input.h"

21 #include "strlcpy.h"

22 #include "known_hosts.h"

23 #include "storage.h"

24 #include "sandbox.h"

25 #include "parser.h"

26 #include "bookmarks.h"

27 #include "image.h"

28 #include "history.h"

29 #include "xdg.h"

30 #include "url.h"

31

32 int client_destroy(struct client *client) {

33 struct tab *tab;

34 if (!client) return ERROR_NULL_ARGUMENT;

35 for (tab = client->tab; tab && tab->prev; tab = tab->prev) ;

36 while (tab) {

37 struct tab *next = tab->next;

38 tab_free(tab);

39 tab = next;

40 }

41 known_hosts_free();

42 history_save();

43 history_free();

44 config_save();

45 free(bookmarks);

46 if (tb_shutdown()) return ERROR_TERMBOX_FAILURE;

47 return 0;

48 }

49

50 int client_closetab(struct client *client) {

51 struct tab *tab, *next, *prev;

52 if (!client->tab) return 1;

53 tab = client->tab;

54 next = tab->next;

55 prev = tab->prev;

56 if (next) next->prev = prev;

57 if (prev) prev->next = next;

58 if (next) {

59 client->tab = next;

60 } else if (prev) {

61 client->tab = prev;

62 } else client->tab = NULL;

63 tab_free(tab);

64 return 0;

65 }

66

67 int client_newtab(struct client *client, const char *url) {

68 struct tab *tab;

69 int proto;

70 if (!url) url = "about:newtab";

71 proto = protocol_from_url(url);

72 if (proto != PROTOCOL_GEMINI && proto != PROTOCOL_NONE) {

73 return tab_request(client->tab, url);

74 }

75 tab = tab_new();

76 if (!tab) return ERROR_MEMORY_FAILURE;

77 if (client->tab) {

78 tab->next = client->tab->next;

79 if (tab->next) tab->next->prev = tab;

80 tab->prev = client->tab;

81 client->tab->next = tab;

82 }

83 client->tab = tab;

84 return tab_request(client->tab, url);

85 }

86

87 int client_input(struct client *client) {

88

89 struct tb_event ev;

90 struct request *req = NULL;

91 int ret = 0;

92

93 if (!client->tab || !client->tab->request ||

94 client->tab->request->state != STATE_ONGOING) {

95 #ifdef FUZZING_MODE

96 ret = tb_peek_event(&ev, 50);

97 if (ret == TB_ERR_NO_EVENT) {

98 ret = TB_OK;

99 ev.ch = 'r';

100 }

101 #else

102 ret = tb_poll_event(&ev);

103 #endif

104 } else {

105 ret = tb_peek_event(&ev, 100);

106 }

107

108 if (ret == TB_ERR_NO_EVENT) return 0;

109 if (ret == TB_ERR_POLL) ret = TB_OK;

110 if (ret != TB_OK) return ERROR_TERMBOX_FAILURE;

111

112 if (client->tab)

113 req = tab_input(client->tab);

114

115 if (req && gemini_isinput(req->status) && client->mode == MODE_NORMAL) {

116 client_enter_mode_cmdline(client);

117 client->cursor = snprintf(V(client->cmd), "%s: ", req->meta);

118 }

119

120 switch (client->mode) {

121 case MODE_NORMAL:

122 return client_input_normal(client, ev);

123 case MODE_CMDLINE:

124 {

125 int ret = client_input_cmdline(client, ev);

126 if (client->mode == MODE_NORMAL)

127 tb_hide_cursor();

128 return ret;

129 }

130 }

131

132 return 0;

133 }

134

135 int client_init(struct client* client) {

136

137 int ret;

138

139 memset(client, 0, sizeof(*client));

140 if ((ret = storage_init())) return ret;

141 config_load();

142 if ((ret = parser_request_create())) return ret;

143 if ((ret = parser_page_create())) return ret;

144 #ifdef ENABLE_IMAGE

145 if ((ret = image_init())) return ret;

146 #endif

147 #ifndef DISABLE_XDG

148 if (xdg_available()) if ((ret = xdg_init())) return ret;

149 #endif

150 if ((ret = known_hosts_load())) return ret;

151 if ((ret = bookmark_load())) return ret;

152 if (tb_init()) return ERROR_TERMBOX_FAILURE;

153 #ifdef ENABLE_IMAGE

154 if (tb_set_output_mode(TB_OUTPUT_256)) return ERROR_TERMBOX_FAILURE;

155 #endif

156 if ((ret = sandbox_init())) {

157 tb_shutdown();

158 return ret;

159 }

160 history_init();

161

162 return 0;

163 }

164