1 | #! /usr/bin/python |
---|
2 | |
---|
3 | import os, struct, sys, random |
---|
4 | |
---|
5 | import gd |
---|
6 | |
---|
7 | from cpushare.proto_const import * |
---|
8 | from cpushare.exceptions import CompilationError |
---|
9 | |
---|
10 | # Our input data |
---|
11 | source = False |
---|
12 | result = False |
---|
13 | todo = 0 |
---|
14 | |
---|
15 | # Parse command line |
---|
16 | if len(sys.argv) < 4: |
---|
17 | print 'Usage: %s <buy_order.cpu> -<mode> [image list]' % (sys.argv[0],) |
---|
18 | sys.exit(-1) |
---|
19 | mode = sys.argv[2] |
---|
20 | done = 0 |
---|
21 | source = sys.argv[3:] |
---|
22 | result = [False] * len(source) |
---|
23 | |
---|
24 | class buy_state_machine_class(object): |
---|
25 | buy_api = '0.0.0' |
---|
26 | |
---|
27 | w, h = 0, 0 |
---|
28 | index = -1 |
---|
29 | answer = '' |
---|
30 | |
---|
31 | def __init__(self, protocol): |
---|
32 | self.protocol = protocol |
---|
33 | self.handler = self.stringReceived |
---|
34 | |
---|
35 | def start(self): |
---|
36 | global mode, todo, source |
---|
37 | gd.gdMaxColors = 256 * 256 * 256 |
---|
38 | while todo < len(source): |
---|
39 | try: |
---|
40 | self.index = todo |
---|
41 | im = gd.image(source[self.index]) |
---|
42 | break |
---|
43 | except: |
---|
44 | todo += 1 |
---|
45 | self.result = "Error\n" |
---|
46 | if todo >= len(source): |
---|
47 | return # We're finished... FIXME: isn't the transaction stuck? |
---|
48 | todo += 1 |
---|
49 | # Send argument count |
---|
50 | self.protocol.sendString(PROTO_SECCOMP_FORWARD + chr(3)) |
---|
51 | # Send arguments |
---|
52 | msg = chr(3) |
---|
53 | msg += "bytecode\0" |
---|
54 | msg += mode + "\0" |
---|
55 | msg += source[self.index] + "\0" |
---|
56 | self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg) |
---|
57 | # Send image size |
---|
58 | (self.w, self.h) = (w, h) = im.size() |
---|
59 | print 'sending %s (%dx%d)' % (source[self.index], w, h) |
---|
60 | msg = chr(w / 256) + chr(w % 256) + chr(h / 256) + chr(h % 256) |
---|
61 | self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg) |
---|
62 | # Send image contents |
---|
63 | msg = '' |
---|
64 | for y in range(h): |
---|
65 | for x in range(w): |
---|
66 | p = im.getPixel((x, y)) |
---|
67 | rgb = im.colorComponents(p) |
---|
68 | msg += chr(rgb[1]) # use green coordinate |
---|
69 | self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg) |
---|
70 | print '%s bytes sent' % len(msg) |
---|
71 | |
---|
72 | def stringReceived(self, string): |
---|
73 | control = string[0] |
---|
74 | data = string[1:] |
---|
75 | |
---|
76 | if control == PROTO_SECCOMP_FORWARD: |
---|
77 | self.answer += data |
---|
78 | if ord(self.answer[-1]) != 0: |
---|
79 | return |
---|
80 | global done, result |
---|
81 | result[self.index] = self.answer[:-1] |
---|
82 | print self.answer[:-1], |
---|
83 | self.protocol.sendString(PROTO_SECCOMP_SUCCESS) |
---|
84 | done += 1 |
---|
85 | if done < len(source): |
---|
86 | return |
---|
87 | from twisted.internet import reactor |
---|
88 | reactor.stop() |
---|
89 | elif control == PROTO_SECCOMP_SIGNAL: |
---|
90 | print 'Checkpoint starting' |
---|
91 | elif control == PROTO_LOG: |
---|
92 | print repr(data) |
---|
93 | else: |
---|
94 | if control == PROTO_SECCOMP_SUCCESS: |
---|
95 | pass |
---|
96 | elif control == PROTO_SECCOMP_FAILURE: |
---|
97 | status = struct.unpack('!i', data)[0] |
---|
98 | exit_code = status >> 8 |
---|
99 | signal = status & 0xff |
---|
100 | s = 'Seccomp failure: status %d, exit_code %d, signal %d.' % \ |
---|
101 | (status, exit_code, signal) |
---|
102 | print s |
---|
103 | else: |
---|
104 | s = 'Unknown failure %d - %s' % (ord(control), repr(string)) |
---|
105 | self.protocol.sendString(PROTO_SECCOMP_FAILURE + s) |
---|
106 | print s |
---|
107 | self.protocol.sendString(PROTO_SECCOMP_FAILURE) |
---|
108 | self.protocol.transport.loseConnection() |
---|
109 | |
---|
110 | def connectionLost(self): |
---|
111 | pass |
---|
112 | |
---|
113 | # Build local module |
---|
114 | from new import module |
---|
115 | m = module('cpushare_buy') |
---|
116 | |
---|
117 | # Create bytecode -- i686 only |
---|
118 | from cpushare.seccomp_gen import seccomp_gen_class |
---|
119 | m.seccomp_gen_hash = {} |
---|
120 | m.seccomp_gen_hash['i686'] = seccomp_gen_class('bytecode', 'i686') |
---|
121 | m.seccomp_gen_hash['i686'].heap_kbytes = 1 |
---|
122 | m.seccomp_gen_hash['i686'].stack_kbytes = 1 |
---|
123 | |
---|
124 | # Estimate of the max number of seconds that the sell client |
---|
125 | # will take to checkpoint and send its state back to us |
---|
126 | m.checkpoint_sec = 10 |
---|
127 | |
---|
128 | # Our buying state machine |
---|
129 | m.buy_state_machine_class = buy_state_machine_class |
---|
130 | |
---|
131 | # Append our module to the global list of modules |
---|
132 | sys.modules['cpushare_buy'] = m |
---|
133 | |
---|
134 | # Build a new command line and run twistd |
---|
135 | sys.argv = [sys.argv[0], '-q', '-n', 'cpushare', '--order', sys.argv[1]] |
---|
136 | from twisted.scripts.twistd import run |
---|
137 | run() |
---|
138 | |
---|