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