53d46aa3 |
1 | package main |
03519b4f |
2 | |
64ee4c0d |
3 | import ( |
4 | "fmt" |
5 | "os" |
73f250ed |
6 | |
64ee4c0d |
7 | "bufio" |
8 | "io" |
9 | "io/ioutil" |
686a6b01 |
10 | |
64ee4c0d |
11 | "strconv" |
12 | "strings" |
08ff4e7b |
13 | |
64ee4c0d |
14 | "net/http" |
80d57869 |
15 | "net/url" |
08ff4e7b |
16 | |
64ee4c0d |
17 | "github.com/wsxiaoys/terminal/color" |
73f250ed |
18 | ) |
19 | |
20 | /* holds our palette, or 16 ANSI colors (8 normal colors + bright complements) |
21 | and two foreground/background colors. colors are 3 byte arrays (RGB) */ |
22 | type ktPalette struct { |
64ee4c0d |
23 | black [3]byte |
24 | bblack [3]byte |
73f250ed |
25 | |
64ee4c0d |
26 | red [3]byte |
27 | bred [3]byte |
73f250ed |
28 | |
64ee4c0d |
29 | green [3]byte |
30 | bgreen [3]byte |
73f250ed |
31 | |
64ee4c0d |
32 | yellow [3]byte |
33 | byellow [3]byte |
73f250ed |
34 | |
64ee4c0d |
35 | blue [3]byte |
36 | bblue [3]byte |
73f250ed |
37 | |
64ee4c0d |
38 | purple [3]byte |
39 | bpurple [3]byte |
73f250ed |
40 | |
64ee4c0d |
41 | cyan [3]byte |
42 | bcyan [3]byte |
73f250ed |
43 | |
64ee4c0d |
44 | white [3]byte |
45 | bwhite [3]byte |
73f250ed |
46 | |
64ee4c0d |
47 | fg [3]byte |
48 | bg [3]byte |
73f250ed |
49 | } |
50 | |
51 | /* the default "control" ANSI color set (boring) */ |
64ee4c0d |
52 | var ansiColors = ktPalette{ |
73f250ed |
53 | |
64ee4c0d |
54 | black: [3]byte{0, 0, 0}, |
55 | bblack: [3]byte{128, 128, 128}, |
73f250ed |
56 | |
64ee4c0d |
57 | red: [3]byte{128, 0, 0}, |
58 | bred: [3]byte{255, 0, 0}, |
73f250ed |
59 | |
64ee4c0d |
60 | green: [3]byte{0, 128, 0}, |
61 | bgreen: [3]byte{0, 255, 0}, |
73f250ed |
62 | |
64ee4c0d |
63 | yellow: [3]byte{128, 128, 0}, |
64 | byellow: [3]byte{255, 255, 0}, |
73f250ed |
65 | |
64ee4c0d |
66 | blue: [3]byte{0, 0, 128}, |
67 | bblue: [3]byte{0, 0, 255}, |
73f250ed |
68 | |
64ee4c0d |
69 | purple: [3]byte{128, 0, 128}, |
70 | bpurple: [3]byte{255, 0, 255}, |
73f250ed |
71 | |
64ee4c0d |
72 | cyan: [3]byte{0, 128, 128}, |
73 | bcyan: [3]byte{0, 255, 255}, |
73f250ed |
74 | |
64ee4c0d |
75 | white: [3]byte{128, 128, 128}, |
76 | bwhite: [3]byte{255, 255, 255}, |
73f250ed |
77 | |
64ee4c0d |
78 | fg: [3]byte{0, 0, 0}, |
79 | bg: [3]byte{255, 255, 255}, |
73f250ed |
80 | } |
81 | |
08ff4e7b |
82 | /* lets get our money's worth out of this utf-8 crap */ |
83 | var checkM = "✓" |
64ee4c0d |
84 | var xM = "✗" |
08ff4e7b |
85 | |
73f250ed |
86 | /* parses a colorfile, returns palette struct. given a nil file pointer, |
87 | returns standard ANSI color set (our "control") */ |
88 | func parseColors(colorfile *os.File) (pal ktPalette, err error) { |
89 | |
64ee4c0d |
90 | if colorfile == nil { |
91 | return ansiColors, nil |
92 | } |
93 | |
94 | ret := ktPalette{} |
95 | var e errConsumer |
96 | |
97 | scanner := bufio.NewScanner(colorfile) |
98 | for scanner.Scan() { |
99 | |
100 | if strings.Contains(scanner.Text(), "color") && |
101 | !strings.Contains(scanner.Text(), "!") { |
102 | |
103 | /* i am so sorry */ |
104 | cur := strings.Replace(scanner.Text(), " ", "", -1) |
105 | split := strings.Split(cur, ":") |
106 | hexColor := strings.Replace(split[1], "#", "", -1) |
107 | coNumStr := strings.Replace(split[0], "URxvt*color", "", -1) |
108 | |
109 | r, err := strconv.ParseUint(hexColor[0:2], 16, 8) |
110 | e.Consume(err) |
111 | g, err := strconv.ParseUint(hexColor[2:4], 16, 8) |
112 | e.Consume(err) |
113 | b, err := strconv.ParseUint(hexColor[4:], 16, 8) |
114 | e.Consume(err) |
115 | |
116 | colorNo, err := strconv.Atoi(coNumStr) |
117 | e.Consume(err) |
118 | |
119 | if e.err != nil { |
120 | return ktPalette{}, e.err |
121 | } |
122 | |
123 | switch colorNo { |
124 | case 0: |
125 | ret.black[0] = byte(r) |
126 | ret.black[1] = byte(g) |
127 | ret.black[2] = byte(b) |
128 | case 1: |
129 | ret.red[0] = byte(r) |
130 | ret.red[1] = byte(g) |
131 | ret.red[2] = byte(b) |
132 | case 2: |
133 | ret.green[0] = byte(r) |
134 | ret.green[1] = byte(g) |
135 | ret.green[2] = byte(b) |
136 | case 3: |
137 | ret.yellow[0] = byte(r) |
138 | ret.yellow[1] = byte(g) |
139 | ret.yellow[2] = byte(b) |
140 | case 4: |
141 | ret.blue[0] = byte(r) |
142 | ret.blue[1] = byte(g) |
143 | ret.blue[2] = byte(b) |
144 | case 5: |
145 | ret.purple[0] = byte(r) |
146 | ret.purple[1] = byte(g) |
147 | ret.purple[2] = byte(b) |
148 | case 6: |
149 | ret.cyan[0] = byte(r) |
150 | ret.cyan[1] = byte(g) |
151 | ret.cyan[2] = byte(b) |
152 | case 7: |
153 | ret.white[0] = byte(r) |
154 | ret.white[1] = byte(g) |
155 | ret.white[2] = byte(b) |
156 | case 8: |
157 | ret.bblack[0] = byte(r) |
158 | ret.bblack[1] = byte(g) |
159 | ret.bblack[2] = byte(b) |
160 | case 9: |
161 | ret.bred[0] = byte(r) |
162 | ret.bred[1] = byte(g) |
163 | ret.bred[2] = byte(b) |
164 | case 10: |
165 | ret.bgreen[0] = byte(r) |
166 | ret.bgreen[1] = byte(g) |
167 | ret.bgreen[2] = byte(b) |
168 | case 11: |
169 | ret.byellow[0] = byte(r) |
170 | ret.byellow[1] = byte(g) |
171 | ret.byellow[2] = byte(b) |
172 | case 12: |
173 | ret.bblue[0] = byte(r) |
174 | ret.bblue[1] = byte(g) |
175 | ret.bblue[2] = byte(b) |
176 | case 13: |
177 | ret.bpurple[0] = byte(r) |
178 | ret.bpurple[1] = byte(g) |
179 | ret.bpurple[2] = byte(b) |
180 | case 14: |
181 | ret.bcyan[0] = byte(r) |
182 | ret.bcyan[1] = byte(g) |
183 | ret.bcyan[2] = byte(b) |
184 | case 15: |
185 | ret.bwhite[0] = byte(r) |
186 | ret.bwhite[1] = byte(g) |
187 | ret.bwhite[2] = byte(b) |
188 | } |
189 | |
190 | } else if strings.Contains(scanner.Text(), "background") { |
191 | |
192 | hex := strings.Split(scanner.Text(), "#") |
193 | het := hex[1] |
194 | |
195 | r, err := strconv.ParseUint(het[0:2], 16, 8) |
196 | e.Consume(err) |
197 | g, err := strconv.ParseUint(het[2:4], 16, 8) |
198 | e.Consume(err) |
199 | b, err := strconv.ParseUint(het[4:], 16, 8) |
200 | e.Consume(err) |
201 | |
202 | if e.err != nil { |
203 | return ktPalette{}, e.err |
204 | } |
205 | |
206 | ret.bg[0] = byte(r) |
207 | ret.bg[1] = byte(g) |
208 | ret.bg[2] = byte(b) |
209 | |
210 | } else if strings.Contains(scanner.Text(), "foreground") { |
211 | |
212 | hex := strings.Split(scanner.Text(), "#") |
213 | het := hex[1] |
214 | |
215 | r, err := strconv.ParseUint(het[0:2], 16, 8) |
216 | e.Consume(err) |
217 | g, err := strconv.ParseUint(het[2:4], 16, 8) |
218 | e.Consume(err) |
219 | b, err := strconv.ParseUint(het[4:], 16, 8) |
220 | e.Consume(err) |
221 | |
222 | if e.err != nil { |
223 | return ktPalette{}, e.err |
224 | } |
225 | |
226 | ret.fg[0] = byte(r) |
227 | ret.fg[1] = byte(g) |
228 | ret.fg[2] = byte(b) |
229 | } |
230 | } |
231 | |
232 | return ret, e.err |
73f250ed |
233 | } |
234 | |
80d57869 |
235 | var httpdStatus bool |
236 | |
73f250ed |
237 | func ktInit(dirPrepend string, port int, colorfilePath string) error { |
238 | |
64ee4c0d |
239 | httpdStatus = false |
80d57869 |
240 | |
64ee4c0d |
241 | color.Print("@yparsing colorfile :: @{|}") |
242 | file, err := os.Open(colorfilePath) |
243 | if err != nil { |
244 | color.Printf("@r[%s]@{|} - bad colorfile path\n", xM) |
245 | return fmt.Errorf("%s\n", "bad colorfile path") |
246 | } |
73f250ed |
247 | |
64ee4c0d |
248 | pal, err := parseColors(file) |
73f250ed |
249 | |
64ee4c0d |
250 | if err != nil { |
251 | color.Printf("@r[%s]@{|} - malformed colorfile [%s]\n", xM, err) |
252 | return fmt.Errorf("%s\n", "malformed colorfile") |
253 | } |
73f250ed |
254 | |
64ee4c0d |
255 | color.Printf("@g[%s]@{|}\n", checkM) |
73f250ed |
256 | |
64ee4c0d |
257 | if pal == ansiColors { |
258 | } |
08ff4e7b |
259 | |
64ee4c0d |
260 | color.Printf("@yverifying & preprocessing colorsets@{|} :: @y[SKIP]\n") |
261 | color.Printf("@ygenerating transpositional colorspace@{|} :: @y[SKIP]\n") |
686a6b01 |
262 | |
64ee4c0d |
263 | color.Printf("@ystarting httpd on port @b%d@{|} :: ", port) |
264 | http.HandleFunc("/kt/", transposePage) |
73f250ed |
265 | |
64ee4c0d |
266 | var portString string |
267 | fmt.Sprintf(portString, ":%d", port) |
268 | err = http.ListenAndServe(portString, nil) |
269 | if err != nil { |
686a6b01 |
270 | |
64ee4c0d |
271 | color.Printf("@r[%s]@{-} - run me as root!\n", xM) |
272 | return fmt.Errorf("%s\n", "failed to start httpd") |
273 | } |
686a6b01 |
274 | |
64ee4c0d |
275 | color.Printf("@g[%s]@{-}\n", checkM) |
08ff4e7b |
276 | |
64ee4c0d |
277 | return nil |
73f250ed |
278 | } |
03519b4f |
279 | |
686a6b01 |
280 | func transposePage(writer http.ResponseWriter, req *http.Request) { |
281 | |
64ee4c0d |
282 | if !httpdStatus { |
80d57869 |
283 | |
64ee4c0d |
284 | httpdStatus = true |
285 | color.Printf("@g[%s]@{|}\n", checkM) |
286 | } |
80d57869 |
287 | |
64ee4c0d |
288 | if req.URL.Path == "/kt/" { |
289 | writer.Write([]byte("wtf")) |
290 | return |
291 | } |
80d57869 |
292 | |
64ee4c0d |
293 | fqdn := req.URL.Path[4:] |
294 | targetURL := fmt.Sprintf("http://%s", fqdn) |
686a6b01 |
295 | |
64ee4c0d |
296 | resp, err := http.Get(targetURL) |
80d57869 |
297 | |
64ee4c0d |
298 | if err != nil || resp.StatusCode != 200 { |
686a6b01 |
299 | |
64ee4c0d |
300 | io.WriteString(writer, "failed to get that page! -kt\n") |
301 | io.WriteString(writer, targetURL+"\n") |
80d57869 |
302 | |
64ee4c0d |
303 | io.WriteString(writer, resp.Status) |
304 | return |
305 | } |
686a6b01 |
306 | |
80d57869 |
307 | conType := resp.Header.Get("Content-Type") |
308 | |
64ee4c0d |
309 | switch conType[0:strings.Index(conType, ";")] { |
80d57869 |
310 | |
64ee4c0d |
311 | case "text/html": |
312 | writer.Write(transposeHTML(bufio.NewScanner(resp.Body), fqdn)) |
80d57869 |
313 | |
64ee4c0d |
314 | case "text/css": |
315 | writer.Write(transposeCSS(bufio.NewScanner(resp.Body), fqdn)) |
80d57869 |
316 | |
64ee4c0d |
317 | default: |
318 | page, _ := ioutil.ReadAll(resp.Body) |
319 | writer.Write(page) |
320 | } |
686a6b01 |
321 | |
64ee4c0d |
322 | resp.Body.Close() |
686a6b01 |
323 | } |
324 | |
80d57869 |
325 | /* swap href="" & src="" */ |
326 | func transposeHTML(scan *bufio.Scanner, fqdn string) []byte { |
327 | |
64ee4c0d |
328 | var ret []byte |
80d57869 |
329 | var i int |
330 | |
331 | scan.Split(bufio.ScanWords) |
332 | for scan.Scan() { |
333 | |
334 | i++ |
335 | cur := scan.Text() |
336 | |
337 | //fmt.Printf("%s\n", cur) |
338 | |
339 | if len(cur) < 7 { |
340 | |
64ee4c0d |
341 | } else if cur[0:6] == "href=\\" { |
80d57869 |
342 | |
64ee4c0d |
343 | urlStr := cur[7 : strings.Index(cur[7:], "\\")+7] |
80d57869 |
344 | |
345 | u, err := url.Parse(urlStr) |
346 | if err != nil { |
347 | fmt.Printf("malformed URL: %s\n", urlStr) |
348 | } |
349 | |
350 | if u.Host == "" { |
351 | |
352 | u.Host = fmt.Sprintf("localhost/kt/%s", fqdn) |
64ee4c0d |
353 | // cur = append(cur[0:6], |
80d57869 |
354 | } |
355 | |
356 | fmt.Printf("[F] URL: %s // PATH: %s\n", u.Host, u.Path) |
64ee4c0d |
357 | if u == u { |
358 | } |
80d57869 |
359 | |
64ee4c0d |
360 | } else if cur[0:5] == "href=" { |
80d57869 |
361 | |
64ee4c0d |
362 | urlStr := cur[6 : strings.Index(cur[6:], "\"")+6] |
80d57869 |
363 | |
364 | u, err := url.Parse(urlStr) |
365 | if err != nil { |
366 | fmt.Printf("malformed URL: %s\n", urlStr) |
367 | } |
368 | |
64ee4c0d |
369 | if u == u { |
370 | } |
80d57869 |
371 | fmt.Printf("URL: %s // PATH: %s\n", u.Host, u.Path) |
372 | |
64ee4c0d |
373 | } else if cur[0:5] == "src=\"" { |
80d57869 |
374 | |
375 | //fmt.Printf("%s\n", cur) |
64ee4c0d |
376 | urlStr := cur[5 : strings.Index(cur[5:], "\"")+5] |
80d57869 |
377 | |
378 | u, err := url.Parse(urlStr) |
379 | if err != nil { |
380 | fmt.Printf("malformed URL: %s\n", urlStr) |
381 | } |
382 | |
383 | if u.Host == "" { |
384 | |
385 | u.Host = fmt.Sprintf("localhost/kt/%s", fqdn) |
64ee4c0d |
386 | // cur = append(cur[0:6], |
80d57869 |
387 | |
64ee4c0d |
388 | fmt.Printf("[S] URL: %s // PATH: %s\n", u.Host, u.Path) |
389 | if u == u { |
390 | } |
80d57869 |
391 | } |
392 | |
393 | } |
394 | |
395 | ret = append(ret, byte(' ')) |
396 | ret = append(ret, cur...) |
397 | } |
398 | |
399 | fmt.Printf("%d\n", i) |
400 | |
64ee4c0d |
401 | return ret |
80d57869 |
402 | } |
403 | |
404 | func transposeCSS(scan *bufio.Scanner, fqdn string) []byte { |
405 | |
64ee4c0d |
406 | var ret []byte |
80d57869 |
407 | |
64ee4c0d |
408 | return ret |
80d57869 |
409 | } |
410 | |
03519b4f |
411 | func main() { |
412 | |
64ee4c0d |
413 | err := ktInit("kolors", 999, "/home/kremlin/.Xresources") |
73f250ed |
414 | |
64ee4c0d |
415 | if err != nil { |
416 | } |
03519b4f |
417 | } |
73f250ed |
418 | |
08ff4e7b |
419 | type errConsumer struct { |
64ee4c0d |
420 | err error |
08ff4e7b |
421 | } |
422 | |
423 | func (e *errConsumer) Consume(err error) { |
64ee4c0d |
424 | if e.err == nil && err != nil { |
425 | e.err = err |
426 | } |
08ff4e7b |
427 | } |