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 "strlcpy.h"

8 #include "macro.h"

9 #include "strnstr.h"

10 #include "config.h"

11 #include "page.h"

12 #include "client.h"

13 #include "tab.h"

14 #include "request.h"

15 #include "certificate.h"

16 #include "error.h"

17 #include "parser.h"

18

19 static int need_argument(struct client * client,

20 const char *field, size_t len, char *error) {

21 if (!(!len || !*field)) return 0;

22 client->error = 1;

23 STRLCPY(client->cmd, error);

24 return 1;

25 }

26

27 static int no_argument(struct client * client, const char *field, size_t len) {

28 if (!len || !*field) return 0;

29 client->error = 1;

30 snprintf(V(client->cmd), "Trailing characters: %s", field);

31 return 1;

32 }

33

34 int command_quit(struct client *client, const char* ptr, size_t len) {

35 if (no_argument(client, ptr, len)) return 0;

36 return 1;

37 }

38

39 int command_close(struct client *client, const char* ptr, size_t len) {

40 if (no_argument(client, ptr, len)) return 0;

41 client_closetab(client);

42 return !client->tab;

43 }

44

45 int command_newtab(struct client *client, const char* ptr, size_t len) {

46

47 int ret;

48 const char *url = "about:newtab";

49

50 if (!client->tab || !len) return 0;

51 if (*ptr) url = ptr;

52

53 if ((ret = client_newtab(client, url))) {

54 client->error = 1;

55 error_string(ret, V(client->cmd));

56 }

57 return 0;

58 }

59

60 int command_search(struct client *client, const char* ptr, size_t len) {

61

62 int ret;

63 char url[MAX_URL];

64

65 if (!client->tab || !len) return 0;

66 if (need_argument(client, ptr, len, "Empty query")) return 0;

67

68 snprintf(V(url), config.searchEngineURL, ptr);

69

70 if ((ret = tab_request(client->tab, url))) {

71 client->error = 1;

72 error_string(ret, V(client->cmd));

73 }

74 return 0;

75 }

76

77 int command_open(struct client *client, const char* ptr, size_t len) {

78

79 size_t link;

80 struct request *req;

81 char buf[MAX_URL];

82 int i;

83

84 if (need_argument(client, ptr, len, "No URL")) return 0;

85 if (!client->tab) return 0;

86

87 STRLCPY(buf, ptr);

88 i = strnlen(V(buf)) - 1;

89 for (; i > 0; i--) {

90 if (buf[i] <= ' ') buf[i] = '\0';

91 }

92

93 link = atoi(buf);

94 if (!link) {

95 tab_request(client->tab, buf);

96 return 0;

97 }

98

99 req = tab_completed(client->tab);

100 if (!req) return 0;

101 link--;

102 if (link >= req->page.links_count) {

103 client->error = 1;

104 STRLCPY(client->cmd, "Invalid link number");

105 return 0;

106 }

107 request_follow(req, req->page.links[link], V(buf));

108 tab_request(client->tab, buf);

109 return 0;

110 }

111

112 int command_gencert(struct client *client, const char* args, size_t len) {

113

114 struct request *req;

115

116 if (no_argument(client, args, len)) return 0;

117

118 req = tab_completed(client->tab);

119 if (!req) {

120 client->error = 1;

121 STRLCPY(client->cmd, "Invalid page");

122 return 0;

123 }

124 if (!strncmp(req->url, V("about:") - 1)) {

125 client->error = 1;

126 STRLCPY(client->cmd,

127 "Cannot create certificate for \"about:\" pages");

128 return 0;

129 }

130 if (certificate_create(req->name, V(client->cmd)))

131 client->error = 1;

132 return 0;

133 }

134

135 #include <time.h>

136 #include "known_hosts.h"

137 int command_forget(struct client *client, const char* ptr, size_t len) {

138

139 const char *host;

140 char buf[MAX_URL];

141 int i, ret;

142

143 if (need_argument(client, ptr, len, "No host")) return 0;

144 if (!client->tab) return 0;

145

146 host = ptr;

147 STRLCPY(buf, host);

148 i = strnlen(V(buf)) - 1;

149 for (; i > 0; i--) {

150 if (buf[i] <= ' ') buf[i] = '\0';

151 }

152

153 if ((ret = known_hosts_forget(buf))) {

154 client->error = 1;

155 error_string(ret, V(client->cmd));

156 return 0;

157 }

158

159 client->error = ERROR_INFO;

160 snprintf(V(client->cmd),

161 "Certificate for %s removed from well-known hosts", buf);

162

163 return 0;

164 }

165

166 #include "storage.h"

167 int command_download(struct client *client, const char* args, size_t len) {

168

169 struct request *req;

170 FILE *f;

171 char name[MAX_URL], *ptr;

172 char buf[MAX_URL];

173 int i;

174

175 req = tab_completed(client->tab);

176 if (!req) {

177 client->error = 1;

178 STRLCPY(client->cmd, "Invalid page");

179 return 0;

180 }

181

182 if (len && *args) {

183 STRLCPY(name, args);

184 } else if (!strnstr(req->url, "://", sizeof(req->url))) {

185 STRLCPY(name, req->url);

186 } else {

187 char *start;

188 size_t i = STRLCPY(buf, req->url);

189 for (; i > 0; i--) {

190 if (WHITESPACE(buf[i])) buf[i] = 0;

191 else if (buf[i] == '/') buf[i] = 0;

192 else break;

193 }

194 ptr = strrchr(buf, '/');

195 if (!ptr) ptr = buf;

196 else ptr++;

197 start = ptr;

198 for (i = 0; *ptr; i++) ptr++;

199 if (i < 2) STRLCPY(name, req->url);

200 else STRLCPY(name, start);

201 }

202

203 STRLCPY(buf, name);

204 for (i = 1; i < 128 && storage_download_exist(name); i++) {

205 char *dot;

206 dot = strrchr(buf, '.');

207 if (!dot || dot == buf) {

208 snprintf(V(name), "%s (%d)", buf, i);

209 continue;

210 }

211 *dot = '\0';

212 snprintf(V(name), "%s (%d).%s", buf, i, dot + 1);

213 *dot = '.';

214 }

215 f = i < 128 ? storage_download_fopen(name, "wb") : NULL;

216 if (!f) {

217 client->error = 1;

218 error_string(ERROR_ERRNO, V(client->cmd));

219 return 0;

220 }

221 fwrite(&req->data[req->page.offset], 1,

222 req->length - req->page.offset, f);

223 fclose(f);

224

225 client->error = ERROR_INFO;

226 snprintf(V(client->cmd), "File downloaded : %s", name);

227

228 return 0;

229 }

230

231 #include "bookmarks.h"

232 int command_add(struct client *client, const char* args, size_t len) {

233

234 int ret;

235 struct request *req;

236

237 if (!client->tab || !len) return 0;

238 if (!(req = tab_completed(client->tab))) return 0;

239 if (!*args) args = req->page.title;

240 if ((ret = bookmark_add(req->url, args)) ||

241 (ret = bookmark_rewrite())) {

242 error_string(ret, V(client->cmd));

243 client->error = 1;

244 }

245 return 0;

246 }

247

248 int command_help(struct client *client, const char* args, size_t len) {

249 int ret;

250 if (no_argument(client, args, len)) return 0;

251 if (!client->tab) return 0;

252 if ((ret = client_newtab(client, "about:help")) ||

253 (ret = bookmark_rewrite())) {

254 error_string(ret, V(client->cmd));

255 client->error = 1;

256 }

257 return 0;

258 }

259