diff options
Diffstat (limited to 'contrib/scripts')
24 files changed, 1831 insertions, 0 deletions
diff --git a/contrib/scripts/coverage.sh b/contrib/scripts/coverage.sh new file mode 100755 index 000000000..dd6a6ab53 --- /dev/null +++ b/contrib/scripts/coverage.sh | |||
@@ -0,0 +1,14 @@ | |||
1 | #!/bin/sh | ||
2 | # make sure configure was run with coverage enabled... | ||
3 | lcov --directory . --zerocounters | ||
4 | make check | ||
5 | rm `find * -name "test_*.gc??"` `find * -name "perf_*.gc??"` | ||
6 | for n in `find * -name "*.gc??" | grep libs` | ||
7 | do | ||
8 | cd `dirname $n` | ||
9 | mv `basename $n` .. | ||
10 | cd - | ||
11 | done | ||
12 | lcov --directory . --capture --output-file app.info | ||
13 | mkdir -p doc/coverage | ||
14 | genhtml -o doc/coverage app.info | ||
diff --git a/contrib/scripts/debug b/contrib/scripts/debug new file mode 100755 index 000000000..3de2c9a14 --- /dev/null +++ b/contrib/scripts/debug | |||
@@ -0,0 +1,37 @@ | |||
1 | #!/bin/bash | ||
2 | # /proc/sys/kernel/core_pattern should be core.%p.%E | ||
3 | |||
4 | COREPID=$1 | ||
5 | |||
6 | COREFILES=`ls -1 *core.$COREPID* 2>/dev/null | wc -l` | ||
7 | COREFILE=`ls -1 *core.$COREPID* 2>/dev/null | head -n 1` | ||
8 | |||
9 | if [ $COREFILES -gt 1 ]; then | ||
10 | echo "Multiple files, using $COREFILE" | ||
11 | fi | ||
12 | |||
13 | |||
14 | if [ $COREFILES -eq 0 ]; then | ||
15 | SERVICENAME=$1 | ||
16 | COREFILES=`ls -1 core.*.*$SERVICENAME 2>/dev/null | wc -l` | ||
17 | COREFILE=`ls -1 core.*.*$SERVICENAME 2>/dev/null | head -n 1` | ||
18 | |||
19 | if [ $COREFILES -gt 1 ]; then | ||
20 | echo "Multiple files, using $COREFILE" | ||
21 | fi | ||
22 | fi | ||
23 | |||
24 | if [ $COREFILES -eq 0 ]; then | ||
25 | echo "Core file for $1 not found" | ||
26 | exit 1 | ||
27 | fi | ||
28 | |||
29 | echo "Using $COREFILE" | ||
30 | |||
31 | EXECPATH=${COREFILE#*!} | ||
32 | EXECPATH=`echo $EXECPATH | sed -e 's/!/\//g'` | ||
33 | echo $EXECPATH | ||
34 | echo "" | ||
35 | echo "" | ||
36 | |||
37 | gdb --core $COREFILE /$EXECPATH | ||
diff --git a/contrib/scripts/find_typedefs.py b/contrib/scripts/find_typedefs.py new file mode 100644 index 000000000..68f5c2782 --- /dev/null +++ b/contrib/scripts/find_typedefs.py | |||
@@ -0,0 +1,99 @@ | |||
1 | from __future__ import print_function | ||
2 | import os | ||
3 | import re | ||
4 | import sys | ||
5 | |||
6 | |||
7 | debug = False | ||
8 | |||
9 | |||
10 | def get_td_from_function_signature(line, file, num): | ||
11 | left_paren = line.find('(') | ||
12 | if left_paren > 0: | ||
13 | left_paren += 1 | ||
14 | li = line[left_paren:] | ||
15 | right_paren = line.find(')') | ||
16 | if right_paren > 0 and right_paren > left_paren and line[right_paren:].find('(') >= 0: | ||
17 | fname = line[:right_paren] | ||
18 | fname = fname.lstrip(' ').lstrip('*').lstrip(' ').rstrip(' ') | ||
19 | if len(fname) > 0: | ||
20 | if debug: | ||
21 | print("from {0}:{1}".format(file, num)) | ||
22 | print("-T {0}".format(fname)) | ||
23 | |||
24 | |||
25 | def get_td_from_simple_type(line, file, num): | ||
26 | line = line.rstrip(' ').rstrip('\t').rstrip(' ').rstrip('\t') | ||
27 | right_space = line.rfind(' ') | ||
28 | right_tab = line.rfind('\t') | ||
29 | sep = right_tab if right_tab > right_space else right_space | ||
30 | sep += 1 | ||
31 | tname = line[sep:] | ||
32 | tname = tname.lstrip('*') | ||
33 | if len(tname) > 0: | ||
34 | if debug: | ||
35 | print("from {0}:{1}".format(file, num)) | ||
36 | print("-T {0}".format(tname)) | ||
37 | |||
38 | |||
39 | def find_typedefs(file): | ||
40 | with open(file, 'rb') as f: | ||
41 | td = False | ||
42 | td_struct = False | ||
43 | td_level = 0 | ||
44 | td_line = [] | ||
45 | data = f.read() | ||
46 | for i, l in enumerate(data.splitlines(False)): | ||
47 | # Don't try to be too smart: only count lines that begin with 'typedef ' | ||
48 | l = l.rstrip(' ').rstrip('\t') | ||
49 | if len(l) == 0: | ||
50 | continue | ||
51 | if not td: | ||
52 | if l[:8] != 'typedef ': | ||
53 | continue | ||
54 | else: | ||
55 | td = True | ||
56 | if l[8:].lstrip(' ').lstrip('\t')[:6] == 'struct': | ||
57 | td_struct = True | ||
58 | if td_struct: | ||
59 | leftcbrace = l.find('{') | ||
60 | if leftcbrace >= 0: | ||
61 | if td_level == 0: | ||
62 | td_line.append(l[:leftcbrace]) | ||
63 | l = l[leftcbrace + 1:] | ||
64 | td_level += 1 | ||
65 | rightcbrace = l.rfind('}') | ||
66 | if rightcbrace >= 0: | ||
67 | td_level -= 1 | ||
68 | if td_level == 0: | ||
69 | td_line.append(l[rightcbrace + 1:]) | ||
70 | else: | ||
71 | td_line.append(l) | ||
72 | if len(l) > 0 and l[-1] == ';' and(not td_struct or td_level == 0): | ||
73 | td_line = ' '.join(td_line) | ||
74 | td_line = td_line[:-1] | ||
75 | if len(td_line) > 0: | ||
76 | if td_line[-1] == ')': | ||
77 | get_td_from_function_signature(td_line, file, i) | ||
78 | else: | ||
79 | get_td_from_simple_type(td_line, file, i) | ||
80 | td_line = [] | ||
81 | td = False | ||
82 | td_struct = False | ||
83 | td_level = 0 | ||
84 | |||
85 | |||
86 | def scan_dir(d): | ||
87 | for dirpath, dirs, files in os.walk(d): | ||
88 | for f in files: | ||
89 | if re.match(r'(?!lt_).+\.(c|cc|h)$', f): | ||
90 | file = os.path.join(dirpath, f) | ||
91 | find_typedefs(file) | ||
92 | |||
93 | |||
94 | if __name__ == '__main__': | ||
95 | if len(sys.argv[1:]) == 0: | ||
96 | arg = os.getcwd() | ||
97 | else: | ||
98 | arg = sys.argv[1] | ||
99 | scan_dir(arg) | ||
diff --git a/contrib/scripts/gdb-iterate-dll.py b/contrib/scripts/gdb-iterate-dll.py new file mode 100644 index 000000000..79d46aa96 --- /dev/null +++ b/contrib/scripts/gdb-iterate-dll.py | |||
@@ -0,0 +1,40 @@ | |||
1 | from gdb import * | ||
2 | |||
3 | |||
4 | def search_dll(head, field, match, pfield): | ||
5 | """ | ||
6 | Search in a DLL by iterates over it. | ||
7 | |||
8 | head: name of the symbol denoting the head of the DLL | ||
9 | field: the field that should be search for match | ||
10 | match: the mathing value for field | ||
11 | pfield: the field whose value is to be printed for matched elements; None to | ||
12 | print all fields of the matched elemented | ||
13 | """ | ||
14 | |||
15 | (symbol, _) = lookup_symbol(head) | ||
16 | if symbol is None: | ||
17 | print("Can't find symbol: " + head) | ||
18 | return | ||
19 | symbol_val = symbol.value() | ||
20 | while symbol_val: | ||
21 | symbol_val_def = symbol_val.dereference() | ||
22 | field_val = symbol_val_def[field] | ||
23 | if field_val.type.code == gdb.TYPE_CODE_INT: | ||
24 | val = int(field_val) | ||
25 | res = (match == val) | ||
26 | elif (field_val.type.code == gdb.TYPE_CODE_STRING) or (field_val.type.code == gdb.TYPE_CODE_ARRAY): | ||
27 | val = str(field_val) | ||
28 | res = (match == val) | ||
29 | elif (field_val.type.code == gdb.TYPE_CODE_TYPEDEF): | ||
30 | val = str(field_val) | ||
31 | res = match in val | ||
32 | else: | ||
33 | continue | ||
34 | |||
35 | if res: | ||
36 | if pfield is None: | ||
37 | print(symbol_val_def) | ||
38 | else: | ||
39 | print(symbol_val_def[pfield]) | ||
40 | symbol_val = symbol_val_def["next"] | ||
diff --git a/contrib/scripts/generate-monkey-db.sh b/contrib/scripts/generate-monkey-db.sh new file mode 100755 index 000000000..2afe55501 --- /dev/null +++ b/contrib/scripts/generate-monkey-db.sh | |||
@@ -0,0 +1,17 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | BASEPATH="$(dirname $0)" | ||
4 | OLDDIR="${pwd}" | ||
5 | GN_HOME="/usr/local/bin" | ||
6 | |||
7 | export CC="cparser" | ||
8 | export CFLAGS="-m32 --seaspider" | ||
9 | |||
10 | cd $BASEPATH/.. && ./configure --prefix=$GN_HOME --with-extractor=$GN_HOME --with-microhttpd=$GN_HOME --with-libgcrypt=$GN_HOME && make && seaspider | ||
11 | if test "$?" -ne 0 | ||
12 | then | ||
13 | echo "FAIL: building GNUnet" | ||
14 | exit 1 | ||
15 | fi | ||
16 | |||
17 | cd $OLDDIR | ||
diff --git a/contrib/scripts/gnunet-chk.py.in b/contrib/scripts/gnunet-chk.py.in new file mode 100755 index 000000000..c976b2143 --- /dev/null +++ b/contrib/scripts/gnunet-chk.py.in | |||
@@ -0,0 +1,383 @@ | |||
1 | #!@PYTHON@ | ||
2 | # This file is part of GNUnet. | ||
3 | # (C) 2013, 2018 Christian Grothoff (and other contributing authors) | ||
4 | # | ||
5 | # GNUnet is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License as published | ||
7 | # by the Free Software Foundation; either version 3, or (at your | ||
8 | # option) any later version. | ||
9 | # | ||
10 | # GNUnet is distributed in the hope that it will be useful, but | ||
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | # General Public License for more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License | ||
16 | # along with GNUnet; see the file COPYING. If not, write to the | ||
17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | # Boston, MA 02110-1301, USA. | ||
19 | # | ||
20 | # File: gnunet-chk.py | ||
21 | # Brief: Computes GNUNET style Content Hash Key for a given file | ||
22 | # Author: Sree Harsha Totakura | ||
23 | |||
24 | from hashlib import sha512 | ||
25 | import logging | ||
26 | import os | ||
27 | import getopt | ||
28 | import sys | ||
29 | from Crypto.Cipher import AES | ||
30 | from functools import reduce | ||
31 | |||
32 | |||
33 | # Defaults | ||
34 | DBLOCK_SIZE = (32 * 1024) # Data block size | ||
35 | |||
36 | # Pick a multiple of 2 here to achive 8-byte alignment! We also | ||
37 | # probably want DBlocks to have (roughly) the same size as IBlocks. | ||
38 | # With SHA-512, the optimal value is 32768 byte / 128 byte = 256 (128 | ||
39 | # byte = 2 * 512 bits). DO NOT CHANGE! | ||
40 | CHK_PER_INODE = 256 | ||
41 | |||
42 | CHK_HASH_SIZE = 64 # SHA-512 hash = 512 bits = 64 bytes | ||
43 | |||
44 | CHK_QUERY_SIZE = CHK_HASH_SIZE # Again a SHA-512 hash | ||
45 | |||
46 | GNUNET_FS_URI_PREFIX = "gnunet://fs/" # FS CHK URI prefix | ||
47 | |||
48 | GNUNET_FS_URI_CHK_INFIX = "chk/" # FS CHK URI infix | ||
49 | |||
50 | |||
51 | def encode_data_to_string(data): | ||
52 | """Returns an ASCII encoding of the given data block like | ||
53 | GNUNET_STRINGS_data_to_string() function. | ||
54 | |||
55 | data: A bytearray representing the block of data which has to be encoded | ||
56 | """ | ||
57 | echart = "0123456789ABCDEFGHIJKLMNOPQRSTUV" | ||
58 | assert (None != data) | ||
59 | assert (bytearray == type(data)) | ||
60 | size = len(data) | ||
61 | assert (0 != size) | ||
62 | vbit = 0 | ||
63 | wpos = 0 | ||
64 | rpos = 0 | ||
65 | bits = 0 | ||
66 | out = "" | ||
67 | while (rpos < size) or (vbit > 0): | ||
68 | if (rpos < size) and (vbit < 5): | ||
69 | bits = (bits << 8) | data[rpos] # eat 8 more bits | ||
70 | rpos += 1 | ||
71 | vbit += 8 | ||
72 | if (vbit < 5): | ||
73 | bits <<= (5 - vbit) # zero-padding | ||
74 | assert (vbit == ((size * 8) % 5)) | ||
75 | vbit = 5 | ||
76 | out += echart[(bits >> (vbit - 5)) & 31] | ||
77 | wpos += 1 | ||
78 | vbit -= 5 | ||
79 | assert (0 == vbit) | ||
80 | return out | ||
81 | |||
82 | |||
83 | def sha512_hash(data): | ||
84 | """ Returns the sha512 hash of the given data. | ||
85 | |||
86 | data: string to hash | ||
87 | """ | ||
88 | hash_obj = sha512() | ||
89 | hash_obj.update(data) | ||
90 | return hash_obj.digest() | ||
91 | |||
92 | |||
93 | class AESKey: | ||
94 | """Class for AES Keys. Contains the main key and the initialization | ||
95 | vector. """ | ||
96 | |||
97 | key = None # The actual AES key | ||
98 | iv = None # The initialization vector | ||
99 | cipher = None # The cipher object | ||
100 | KEY_SIZE = 32 # AES 256-bit key = 32 bytes | ||
101 | IV_SIZE = AES.block_size # Initialization vector size (= AES block size) | ||
102 | |||
103 | def __init__(self, passphrase): | ||
104 | """Creates a new AES key. | ||
105 | |||
106 | passphrase: string containing the passphrase to get the AES key and | ||
107 | initialization vector | ||
108 | """ | ||
109 | passphrase = bytearray(passphrase) | ||
110 | self.key = bytearray(self.KEY_SIZE) | ||
111 | self.iv = bytearray(self.IV_SIZE) | ||
112 | if (len(passphrase) > self.KEY_SIZE): | ||
113 | self.key = passphrase[:self.KEY_SIZE] | ||
114 | passphrase = passphrase[self.KEY_SIZE:] | ||
115 | if (len(passphrase) > self.IV_SIZE): | ||
116 | self.iv = passphrase[:self.IV_SIZE] | ||
117 | else: | ||
118 | self.iv[0:len(passphrase)] = passphrase | ||
119 | else: | ||
120 | self.key[0:len(passphrase)] = passphrase | ||
121 | self.key = str(self.key) | ||
122 | self.iv = str(self.iv) | ||
123 | assert (len(self.key) == self.KEY_SIZE) | ||
124 | assert (len(self.iv) == self.IV_SIZE) | ||
125 | |||
126 | |||
127 | def setup_aes_cipher_(aes_key): | ||
128 | """Initializes the AES object with settings similar to those in GNUnet. | ||
129 | |||
130 | aes_key: the AESKey object | ||
131 | Returns the newly initialized AES object | ||
132 | """ | ||
133 | return AES.new(aes_key.key, AES.MODE_CFB, aes_key.iv, segment_size=128) | ||
134 | |||
135 | |||
136 | def aes_pad_(data): | ||
137 | """Adds padding to the data such that the size of the data is a multiple of | ||
138 | 16 bytes | ||
139 | |||
140 | data: the data string | ||
141 | Returns a tuple:(pad_len, data). pad_len denotes the number of bytes added | ||
142 | as padding; data is the new data string with padded bytes at the end | ||
143 | """ | ||
144 | pad_len = len(data) % 16 | ||
145 | if (0 != pad_len): | ||
146 | pad_len = 16 - pad_len | ||
147 | pad_bytes = bytearray(15) | ||
148 | data += str(pad_bytes[:pad_len]) | ||
149 | return (pad_len, data) | ||
150 | |||
151 | |||
152 | def aes_encrypt(aes_key, data): | ||
153 | """Encrypts the given data using AES. | ||
154 | |||
155 | aes_key: the AESKey object to use for AES encryption | ||
156 | data: the data string to encrypt | ||
157 | """ | ||
158 | (pad_len, data) = aes_pad_(data) | ||
159 | cipher = setup_aes_cipher_(aes_key) | ||
160 | enc_data = cipher.encrypt(data) | ||
161 | if (0 != pad_len): | ||
162 | enc_data = enc_data[:-pad_len] | ||
163 | return enc_data | ||
164 | |||
165 | |||
166 | def aes_decrypt(aes_key, data): | ||
167 | """Decrypts the given data using AES | ||
168 | |||
169 | aes_key: the AESKey object to use for AES decryption | ||
170 | data: the data string to decrypt | ||
171 | """ | ||
172 | (pad_len, data) = aes_pad_(data) | ||
173 | cipher = setup_aes_cipher_(aes_key) | ||
174 | ptext = cipher.decrypt(data) | ||
175 | if (0 != pad_len): | ||
176 | ptext = ptext[:-pad_len] | ||
177 | return ptext | ||
178 | |||
179 | |||
180 | class Chk: | ||
181 | """Class for the content hash key.""" | ||
182 | key = None | ||
183 | query = None | ||
184 | fsize = None | ||
185 | |||
186 | def __init__(self, key, query): | ||
187 | assert (len(key) == CHK_HASH_SIZE) | ||
188 | assert (len(query) == CHK_QUERY_SIZE) | ||
189 | self.key = key | ||
190 | self.query = query | ||
191 | |||
192 | def setSize(self, size): | ||
193 | self.fsize = size | ||
194 | |||
195 | def uri(self): | ||
196 | sizestr = repr(self.fsize) | ||
197 | if isinstance(self.fsize, int): | ||
198 | sizestr = sizestr[:-1] | ||
199 | return GNUNET_FS_URI_PREFIX + GNUNET_FS_URI_CHK_INFIX + \ | ||
200 | encode_data_to_string(bytearray(self.key)) + "." + \ | ||
201 | encode_data_to_string(bytearray(self.query)) + "." + \ | ||
202 | sizestr | ||
203 | |||
204 | |||
205 | def compute_depth_(size): | ||
206 | """Computes the depth of the hash tree. | ||
207 | |||
208 | size: the size of the file whose tree's depth has to be computed | ||
209 | Returns the depth of the tree. Always > 0. | ||
210 | """ | ||
211 | depth = 1 | ||
212 | fl = DBLOCK_SIZE | ||
213 | while (fl < size): | ||
214 | depth += 1 | ||
215 | if ((fl * CHK_PER_INODE) < fl): | ||
216 | return depth | ||
217 | fl = fl * CHK_PER_INODE | ||
218 | return depth | ||
219 | |||
220 | |||
221 | def compute_tree_size_(depth): | ||
222 | """Calculate how many bytes of payload a block tree of the given depth MAY | ||
223 | correspond to at most (this function ignores the fact that some blocks will | ||
224 | only be present partially due to the total file size cutting some blocks | ||
225 | off at the end). | ||
226 | |||
227 | depth: depth of the block. depth==0 is a DBLOCK. | ||
228 | Returns the number of bytes of payload a subtree of this depth may | ||
229 | correspond to. | ||
230 | """ | ||
231 | rsize = DBLOCK_SIZE | ||
232 | for cnt in range(0, depth): | ||
233 | rsize *= CHK_PER_INODE | ||
234 | return rsize | ||
235 | |||
236 | |||
237 | def compute_chk_offset_(depth, end_offset): | ||
238 | """Compute the offset of the CHK for the current block in the IBlock | ||
239 | above | ||
240 | |||
241 | depth: depth of the IBlock in the tree (aka overall number of tree levels | ||
242 | minus depth); 0 == DBLOCK | ||
243 | end_offset: current offset in the overall file, at the *beginning* of the | ||
244 | block for DBLOCK (depth == 0), otherwise at the *end* of the | ||
245 | block (exclusive) | ||
246 | Returns the offset in the list of CHKs in the above IBlock | ||
247 | """ | ||
248 | bds = compute_tree_size_(depth) | ||
249 | if (depth > 0): | ||
250 | end_offset -= 1 | ||
251 | ret = end_offset / bds | ||
252 | return ret % CHK_PER_INODE | ||
253 | |||
254 | |||
255 | def compute_iblock_size_(depth, offset): | ||
256 | """Compute the size of the current IBLOCK. The encoder is triggering the | ||
257 | calculation of the size of an IBLOCK at the *end* (hence end_offset) of its | ||
258 | construction. The IBLOCK maybe a full or a partial IBLOCK, and this | ||
259 | function is to calculate how long it should be. | ||
260 | |||
261 | depth: depth of the IBlock in the tree, 0 would be a DBLOCK, must be > 0 | ||
262 | (this function is for IBLOCKs only!) | ||
263 | offset: current offset in the payload (!) of the overall file, must be > 0 | ||
264 | (since this function is called at the end of a block). | ||
265 | Returns the number of elements to be in the corresponding IBlock | ||
266 | """ | ||
267 | assert (depth > 0) | ||
268 | assert (offset > 0) | ||
269 | bds = compute_tree_size_(depth) | ||
270 | mod = offset % bds | ||
271 | if mod is 0: | ||
272 | ret = CHK_PER_INODE | ||
273 | else: | ||
274 | bds /= CHK_PER_INODE | ||
275 | ret = mod / bds | ||
276 | if (mod % bds) is not 0: | ||
277 | ret += 1 | ||
278 | return ret | ||
279 | |||
280 | |||
281 | def compute_rootchk(readin, size): | ||
282 | """Returns the content hash key after generating the hash tree for the given | ||
283 | input stream. | ||
284 | |||
285 | readin: the stream where to read data from | ||
286 | size: the size of data to be read | ||
287 | """ | ||
288 | depth = compute_depth_(size) | ||
289 | current_depth = 0 | ||
290 | chks = [None] * (depth * CHK_PER_INODE) # list buffer | ||
291 | read_offset = 0 | ||
292 | logging.debug("Begining to calculate tree hash with depth: " + repr(depth)) | ||
293 | while True: | ||
294 | if (depth == current_depth): | ||
295 | off = CHK_PER_INODE * (depth - 1) | ||
296 | assert (chks[off] is not None) | ||
297 | logging.debug("Encoding done, reading CHK `" + chks[off].query + \ | ||
298 | "' from " + repr(off) + "\n") | ||
299 | uri_chk = chks[off] | ||
300 | assert (size == read_offset) | ||
301 | uri_chk.setSize(size) | ||
302 | return uri_chk | ||
303 | if (0 == current_depth): | ||
304 | pt_size = min(DBLOCK_SIZE, size - read_offset) | ||
305 | try: | ||
306 | pt_block = readin.read(pt_size) | ||
307 | except IOError: | ||
308 | logging.warning("Error reading input file stream") | ||
309 | return None | ||
310 | else: | ||
311 | pt_elements = compute_iblock_size_(current_depth, read_offset) | ||
312 | pt_block = "" | ||
313 | pt_block = \ | ||
314 | reduce((lambda ba, chk: | ||
315 | ba + (chk.key + chk.query)), | ||
316 | chks[(current_depth - 1) * CHK_PER_INODE:][:pt_elements], | ||
317 | pt_block) | ||
318 | pt_size = pt_elements * (CHK_HASH_SIZE + CHK_QUERY_SIZE) | ||
319 | assert (len(pt_block) == pt_size) | ||
320 | assert (pt_size <= DBLOCK_SIZE) | ||
321 | off = compute_chk_offset_(current_depth, read_offset) | ||
322 | logging.debug("Encoding data at offset " + repr(read_offset) + \ | ||
323 | " and depth " + repr(current_depth) + " with block " \ | ||
324 | "size " + repr(pt_size) + " and target CHK offset " + \ | ||
325 | repr(current_depth * CHK_PER_INODE)) | ||
326 | pt_hash = sha512_hash(pt_block) | ||
327 | pt_aes_key = AESKey(pt_hash) | ||
328 | pt_enc = aes_encrypt(pt_aes_key, pt_block) | ||
329 | pt_enc_hash = sha512_hash(pt_enc) | ||
330 | chk = Chk(pt_hash, pt_enc_hash) | ||
331 | chks[(current_depth * CHK_PER_INODE) + off] = chk | ||
332 | if (0 == current_depth): | ||
333 | read_offset += pt_size | ||
334 | if (read_offset == size) or \ | ||
335 | (0 == (read_offset % (CHK_PER_INODE * DBLOCK_SIZE))): | ||
336 | current_depth += 1 | ||
337 | else: | ||
338 | if (CHK_PER_INODE == off) or (read_offset == size): | ||
339 | current_depth += 1 | ||
340 | else: | ||
341 | current_depth = 0 | ||
342 | |||
343 | |||
344 | def chkuri_from_path(path): | ||
345 | """Returns the CHK URI of the file at the given path. | ||
346 | |||
347 | path: the path of the file whose CHK has to be calculated | ||
348 | """ | ||
349 | size = os.path.getsize(path) | ||
350 | readin = open(path, "rb") | ||
351 | chk = compute_rootchk(readin, size) | ||
352 | readin.close() | ||
353 | return chk.uri() | ||
354 | |||
355 | |||
356 | def usage(): | ||
357 | """Prints help about using this script.""" | ||
358 | print(""" | ||
359 | Usage: gnunet-chk.py [options] file | ||
360 | Prints the Content Hash Key of given file in GNUNET-style URI. | ||
361 | |||
362 | Options: | ||
363 | -h, --help : prints this message | ||
364 | """) | ||
365 | |||
366 | |||
367 | if '__main__' == __name__: | ||
368 | try: | ||
369 | opts, args = getopt.getopt(sys.argv[1:], "h", ["help"]) | ||
370 | except getopt.GetoptError as err: | ||
371 | print(err) | ||
372 | print("Exception occured") | ||
373 | usage() | ||
374 | sys.exit(2) | ||
375 | for option, value in opts: | ||
376 | if option in("-h", "--help"): | ||
377 | usage() | ||
378 | sys.exit(0) | ||
379 | if len(args) != 1: | ||
380 | print("Incorrect number of arguments passed") | ||
381 | usage() | ||
382 | sys.exit(1) | ||
383 | print(chkuri_from_path(args[0])) | ||
diff --git a/contrib/scripts/gnunet-logread/gnunet-logread b/contrib/scripts/gnunet-logread/gnunet-logread new file mode 100755 index 000000000..9b1c65401 --- /dev/null +++ b/contrib/scripts/gnunet-logread/gnunet-logread | |||
@@ -0,0 +1,198 @@ | |||
1 | #!@PERL@ | ||
2 | # helper tool to make gnunet logs more readable | ||
3 | # try 'gnunet-logread -h' for usage | ||
4 | |||
5 | use strict; | ||
6 | use warnings; | ||
7 | my $DEFAULT_SOCKET = '/tmp/gnunet-logread-ipc.sock'; | ||
8 | |||
9 | print STDERR <<X if -t STDIN and $#ARGV == -1; | ||
10 | *** For a usage message, try '$0 -h'. | ||
11 | *** For documentation, try 'perldoc $0'. | ||
12 | *** Listening for GNUNET_log events on STDIN. Type CTRL-D to terminate. | ||
13 | |||
14 | X | ||
15 | |||
16 | use Getopt::Std; | ||
17 | my (%opts, $name, $ipc, $msg_level, $msg_regex); | ||
18 | getopts ('i:x:n:s:L:m:fhq', \%opts); | ||
19 | |||
20 | use Pod::Usage qw( pod2usage ); | ||
21 | die pod2usage if $opts{h}; | ||
22 | |||
23 | use POSIX qw(mkfifo); | ||
24 | |||
25 | use Term::ANSIColor qw(:constants :pushpop); | ||
26 | $Term::ANSIColor::AUTOLOCAL = 1; | ||
27 | |||
28 | my %levels = ( NONE => 0, ERROR => 1, WARNING => 2, INFO => 4, DEBUG => 8 ); | ||
29 | |||
30 | # Message type numbers to names | ||
31 | my %msgtypes; | ||
32 | my $prefix = $ENV{GNUNET_PREFIX} || '/usr'; | ||
33 | my $filename = "$prefix/include/gnunet/gnunet_protocols.h"; | ||
34 | $ipc = $opts{s} || $DEFAULT_SOCKET; | ||
35 | |||
36 | if (open HEADER, $filename) | ||
37 | { | ||
38 | while (<HEADER>) | ||
39 | { | ||
40 | $msgtypes{$2} = $1 if /^\s*#define\s+GNUNET_MESSAGE_TYPE_(\w+)\s+(\d+)/i; | ||
41 | } | ||
42 | close HEADER; | ||
43 | } else { | ||
44 | warn <<X; | ||
45 | Could not read $filename for message codes: | ||
46 | $!. | ||
47 | Please provide a \$GNUNET_PREFIX environment variable to replace "/usr". | ||
48 | Try also '$0 -h' for help. | ||
49 | |||
50 | X | ||
51 | } | ||
52 | |||
53 | die "You can't read and write the socket at the same time" | ||
54 | if exists $opts{f} and exists $opts{n}; | ||
55 | |||
56 | if ((exists $opts{n} or exists $opts{f}) and not -r $ipc) { | ||
57 | undef $!; | ||
58 | die "Could not mkfifo $ipc: $!" unless mkfifo $ipc, 0600; | ||
59 | system('chgrp', 'gnunet', $ipc); | ||
60 | die "Could not chgrp $ipc to 'gnunet': $!" if $!; | ||
61 | chmod 0660, $ipc; | ||
62 | die "Could not chmod $ipc to allow gnunet group writes: $!" if $!; | ||
63 | } | ||
64 | |||
65 | if (exists $opts{n}) { | ||
66 | $name = $opts{n}; | ||
67 | $msg_level = $opts{L} && exists $levels{$opts{L}} ? $levels{$opts{L}} : 0; | ||
68 | $msg_regex = $opts{m}; | ||
69 | print STDERR "RE: /$msg_regex/\n" if defined $msg_regex; | ||
70 | open O, '>', $ipc or die "Cannot write to $ipc: $!"; | ||
71 | } | ||
72 | |||
73 | if (exists $opts{f}) { | ||
74 | open(I, $ipc) or die "Cannot read from $ipc: $!"; | ||
75 | &perform while <I>; | ||
76 | close I; | ||
77 | } else { | ||
78 | &perform while <>; | ||
79 | } | ||
80 | fileno O and close O; | ||
81 | exit; | ||
82 | |||
83 | |||
84 | sub perform { | ||
85 | if (fileno O) { | ||
86 | my ($time, $type, $size, $from, $to, $level, $msg); | ||
87 | if (($time, $type, $size, $from, $to) = | ||
88 | /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\ util-client-.*\b | ||
89 | (?: Received | Transmitting )\ message \b.*?\b | ||
90 | type \s+ (\d+) \b.*?\b | ||
91 | size \s+ (\d+) \b.*?\b | ||
92 | (?: from \s+ (\S+) | ||
93 | | to \s+ (\S+) ) /x) | ||
94 | { | ||
95 | $from ||= $name; | ||
96 | $to ||= $name; | ||
97 | my ($time, $type, $size, $from, $to) = ($1, $2, $3, | ||
98 | $4 || $name, $5 || $name); | ||
99 | my $msg = exists $msgtypes{$type} ? $msgtypes{$type} : $type; | ||
100 | my $ofh = select O; | ||
101 | print O "$time\t$from -> $to\t$msg ($size)\n"; | ||
102 | $| = 1; | ||
103 | select $ofh; | ||
104 | } | ||
105 | if (($time, $level, $msg) = | ||
106 | /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?) | ||
107 | \s+\S+\s+(\S+)\s+(.+)/x | ||
108 | and (exists $levels{$level} | ||
109 | && $levels{$level} <= $msg_level | ||
110 | && (!defined $msg_regex || $msg =~ /$msg_regex/i))) | ||
111 | { | ||
112 | print O "$time\t$name\t$level: $msg\n"; | ||
113 | } | ||
114 | } | ||
115 | return if $opts{x} and /$opts{x}/io; | ||
116 | return if $opts{i} and not /$opts{i}/io; | ||
117 | |||
118 | # Timestamp (e.g. Nov 01 19:36:11-384136) | ||
119 | s/^([A-Z][a-z]{2} .[0-9] [0-9:]{8}(?:-[0-9]{6})?)/YELLOW $1/e; | ||
120 | |||
121 | # Log levels | ||
122 | s/\b(ERROR )\b/RED $1/ex; | ||
123 | s/\b(WARNING)\b/YELLOW $1/ex; | ||
124 | s/\b(INFO )\b/GREEN $1/ex; | ||
125 | s/\b(DEBUG )\b/BRIGHT_BLACK $1/ex; | ||
126 | |||
127 | # Service names | ||
128 | # TODO: might read the list from $GNUNET_PREFIX/libexec/gnunet/ | ||
129 | s/\b(multicast|psyc|psycstore|social)\b/BLUE $1/gex; | ||
130 | |||
131 | # Add message type names | ||
132 | s/(\s+type\s+)(\d+)/ | ||
133 | $1 . BRIGHT_CYAN (exists $msgtypes{$2} ? $msgtypes{$2} : 'UNKNOWN') . | ||
134 | CYAN " ($2)"/gei; | ||
135 | |||
136 | # logread-ipc output | ||
137 | s/(\s+)([A-Z_]+)( \(\d+\))$/$1 . BRIGHT_CYAN $2 . CYAN $3/e; | ||
138 | |||
139 | print; | ||
140 | } | ||
141 | |||
142 | __END__ | ||
143 | |||
144 | =pod | ||
145 | |||
146 | =head1 NAME | ||
147 | |||
148 | gnunet-logread - a GNUnet log analyzer, colorizer and aggregator | ||
149 | |||
150 | =head1 SYNOPSIS | ||
151 | |||
152 | <gnunet-service> |& $0 [<options>] | ||
153 | or | ||
154 | $0 [<options>] [<logfile>] | ||
155 | |||
156 | Options: | ||
157 | -f Follow input from IPC FIFO socket. | ||
158 | |||
159 | Regular screen output options: | ||
160 | -i <regex> Include only messages that match <regex>. | ||
161 | -x <regex> Exclude all messages that match <regex>. | ||
162 | -q Quiet: Do not show usage advice to new users. | ||
163 | |||
164 | Options to forward messages to the IPC FIFO socket: | ||
165 | -n <component_name> Name of the component we are forwarding messages for. | ||
166 | -s </path/to/ipc.sock> Default = $DEFAULT_SOCKET | ||
167 | -L <LOGLEVEL> Minimum level of messages to forward: | ||
168 | Log levels: NONE, ERROR, WARNING, INFO, DEBUG. | ||
169 | -m <regex> Only forward messages matching a regular expression. | ||
170 | |||
171 | See 'perldoc gnunet-logread' for a longer explanation. | ||
172 | |||
173 | =head1 MOTIVATION | ||
174 | |||
175 | GNUnet debug logs are a tedious read, but given a complex system that we | ||
176 | cannot run all parts of in a debugger all the time, some gathering and | ||
177 | structuring of events and message passing is useful. | ||
178 | |||
179 | At first, this tool simply makes logs easier to read. Both if viewed in | ||
180 | real-time or taken from disk. Then it also allows to extract all message | ||
181 | passing events from it and forward them to a special process that aggregates | ||
182 | all message passing events and therefore helps you make sense of all the | ||
183 | inter-process communication (IPC) happening between the various pieces of | ||
184 | the GNUnet system beast. | ||
185 | |||
186 | That master process is simply an extra gnunet-logread that you run in a | ||
187 | separate window and adorn it with the '-f' flag. The submitting processes | ||
188 | instead need to be given a '-n' flag. That is because from the GNUnet logs | ||
189 | it isn't clear which process events belong to. For example you may be | ||
190 | having events taking place in the 'util' subsystem of gnunet-psyc-service | ||
191 | just as much as in the 'util' subsystem of gnunet-multicast-service. In | ||
192 | order to make sense of them it is necessary to manually add that info. This | ||
193 | could be remedied by extending the semantics of the GNUNET_log facility | ||
194 | instead, but that is still subject to further consideration. | ||
195 | |||
196 | =head1 AUTHORS | ||
197 | |||
198 | tg & lynX | ||
diff --git a/contrib/scripts/gnunet-logread/gnunet-logread-ipc b/contrib/scripts/gnunet-logread/gnunet-logread-ipc new file mode 100755 index 000000000..72f9f47df --- /dev/null +++ b/contrib/scripts/gnunet-logread/gnunet-logread-ipc | |||
@@ -0,0 +1,10 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # Usage: gnunet-logread-ipc | gnunet-logread | ||
4 | # | ||
5 | # ... obsoleted by gnunet-logread's new -f option that does the same thing | ||
6 | |||
7 | # FIXME: Replace /tmp with our use of $TMPDIR and similar. | ||
8 | ipc=${1:-/tmp/gnunet-logread-ipc.sock} | ||
9 | test -e "$ipc" || mkfifo "$ipc" | ||
10 | cat "$ipc" | ||
diff --git a/contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit b/contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit new file mode 100755 index 000000000..f8b7dc735 --- /dev/null +++ b/contrib/scripts/gnunet-logread/gnunet-logread-ipc-sdedit | |||
@@ -0,0 +1,60 @@ | |||
1 | #!@PERL@ | ||
2 | |||
3 | # 1. Start sdedit and enable 'RT diagram server' in 'Global preferences'. | ||
4 | # | ||
5 | # 2. Start this tool (see defaults below): | ||
6 | # gnunet-logread-ipc-sdedit -n buffer-name -i /path/to/ipc.sock -h <sdedit-host> -p <sdedit-port> | ||
7 | # | ||
8 | # 3. Start a gnunet-logread instance for each component with the -n <component_name> option | ||
9 | |||
10 | use strict; | ||
11 | use warnings; | ||
12 | |||
13 | use Getopt::Std; | ||
14 | use IO::Socket::INET; | ||
15 | use POSIX qw(mkfifo); | ||
16 | |||
17 | my %opts; | ||
18 | getopts ('i:n:h:p:', \%opts); | ||
19 | |||
20 | my $ipc = $opts{i} || '/tmp/gnunet-logread-ipc.sock'; | ||
21 | my $name = $opts{n} || 'gnunet'; | ||
22 | my $host = $opts{h} || 'localhost'; | ||
23 | my $port = $opts{p} || 16001; | ||
24 | my %svcs = map { $_ => 1 } @ARGV; | ||
25 | |||
26 | my $sdedit = IO::Socket::INET->new(PeerAddr => $host, | ||
27 | PeerPort => $port, | ||
28 | Proto => 'tcp') | ||
29 | or die "Cannot connect to $host:$port: $!\n"; | ||
30 | |||
31 | print $sdedit "$name\n"; | ||
32 | print $sdedit "_t:time[e]\n"; | ||
33 | print $sdedit "$_:$_\[ap\] \"$_\"\n" for @ARGV; | ||
34 | print $sdedit "_e:ext[e]\n"; | ||
35 | print $sdedit "\n"; | ||
36 | |||
37 | mkfifo $ipc, 0600 or die "$ipc: $!\n" unless -e $ipc; | ||
38 | open IPC, '<', $ipc or die "$ipc: $!\n"; | ||
39 | $| = 1; | ||
40 | while (<IPC>) | ||
41 | { | ||
42 | print; | ||
43 | my ($time, $from, $to, $msg, $svc); | ||
44 | if (my ($time, $from, $to, $msg) = | ||
45 | /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\s+ | ||
46 | (\S+)\s+ -> \s+(\S+)\s+ (\S+\s+ \(\d+\))/x) | ||
47 | { | ||
48 | $from = '_e' unless exists $svcs{$from}; | ||
49 | $to = '_e' unless exists $svcs{$to}; | ||
50 | print $sdedit "*0 _t\n$time\n*0\n", "$from:$to.$msg\n" | ||
51 | } | ||
52 | elsif (($time, $svc, $msg) = | ||
53 | /^([A-Z][a-z]{2}\ .[0-9]\ [0-9:]{8}(?:-[0-9]{6})?)\s+ | ||
54 | (\S+)\s+(.+)/x) | ||
55 | { | ||
56 | print $sdedit "*0 _t\n$time\n*0\n", "*0 $svc\n$msg\n*0\n" | ||
57 | } | ||
58 | } | ||
59 | |||
60 | close IPC; | ||
diff --git a/contrib/scripts/gnunet-suidfix b/contrib/scripts/gnunet-suidfix new file mode 100755 index 000000000..992378966 --- /dev/null +++ b/contrib/scripts/gnunet-suidfix | |||
@@ -0,0 +1,27 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # "suidfix" is german and it means something like immediate suicide. | ||
4 | |||
5 | # taken from dangole's lede config.. thx! | ||
6 | suid_root_helpers="exit nat-server nat-client transport-bluetooth transport-wlan vpn" | ||
7 | libexec="${GNUNET_PREFIX}/lib/gnunet/libexec" | ||
8 | |||
9 | chmodown_execbin() { | ||
10 | if [ -x $1 ]; then | ||
11 | if [ "$3" ]; then | ||
12 | chown $3 $1 2>/dev/null && chmod $2 $1 | ||
13 | else | ||
14 | chmod $2 $1 | ||
15 | fi | ||
16 | ls -l $1 | ||
17 | else | ||
18 | echo "Missing: $1" | ||
19 | fi | ||
20 | } | ||
21 | |||
22 | for helper in $suid_root_helpers; do | ||
23 | chmodown_execbin ${libexec}/gnunet-helper-$helper u+s | ||
24 | done | ||
25 | chmodown_execbin ${libexec}/gnunet-helper-dns 4750 root:gnunetdns | ||
26 | chmodown_execbin ${libexec}/gnunet-service-dns 2750 gnunet:gnunetdns | ||
27 | |||
diff --git a/contrib/scripts/gnunet_janitor.py.in b/contrib/scripts/gnunet_janitor.py.in new file mode 100644 index 000000000..74fc70886 --- /dev/null +++ b/contrib/scripts/gnunet_janitor.py.in | |||
@@ -0,0 +1,78 @@ | |||
1 | #!@PYTHON@ | ||
2 | # This file is part of GNUnet. | ||
3 | # (C) 2011 Christian Grothoff (and other contributing authors) | ||
4 | # | ||
5 | # GNUnet is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License as published | ||
7 | # by the Free Software Foundation; either version 2, or (at your | ||
8 | # option) any later version. | ||
9 | # | ||
10 | # GNUnet is distributed in the hope that it will be useful, but | ||
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | # General Public License for more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License | ||
16 | # along with GNUnet; see the file COPYING. If not, write to the | ||
17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | # Boston, MA 02110-1301, USA. | ||
19 | # | ||
20 | # Finds any gnunet processes still running in the system and kills them | ||
21 | # | ||
22 | # gnunet janitor can be used by invoking `make' like this: | ||
23 | # TESTS_ENVIRONMENT='${top_srcdir}/contrib/gnunet_janitor.py &&' make check | ||
24 | |||
25 | from __future__ import print_function | ||
26 | import os | ||
27 | import re | ||
28 | import subprocess | ||
29 | import sys | ||
30 | import shutil | ||
31 | import time | ||
32 | import signal | ||
33 | import terminate | ||
34 | |||
35 | if os.name == 'nt': | ||
36 | from win32com.client import GetObject | ||
37 | WMI = GetObject('winmgmts:') | ||
38 | |||
39 | def get_process_list (): | ||
40 | result = [] | ||
41 | if os.name == 'nt': | ||
42 | processes = WMI.InstancesOf('Win32_Process') | ||
43 | for p in processes: | ||
44 | result.append ((p.Properties_('ProcessId').Value, re.sub (r'(.+)\.exe', r'\1', p.Properties_('Name').Value))) | ||
45 | else: | ||
46 | pids = [pid for pid in os.listdir('/proc') if pid.isdigit ()] | ||
47 | for pid in pids: | ||
48 | with open (os.path.join ('/proc', pid, 'cmdline'), 'rb') as p: | ||
49 | cmdline = p.read ().split ('\x00') | ||
50 | if len (cmdline) > 0: | ||
51 | result.append ((pid, cmdline[0])) | ||
52 | return result | ||
53 | |||
54 | def main (): | ||
55 | procs = get_process_list () | ||
56 | gnunet_procs = [] | ||
57 | for p in procs: | ||
58 | if re.match (r'gnunet-.+', p[1]): | ||
59 | gnunet_procs.append (p) | ||
60 | for p in gnunet_procs: | ||
61 | if re.match (r'gnunet-service-arm', p[1]): | ||
62 | print ("killing arm process {0:5} {1}".format (p[0], p[1])) | ||
63 | try: | ||
64 | terminate.safe_terminate_process_by_pid (int (p[0]), 1) | ||
65 | except OSError as e: | ||
66 | print ("failed: {0}".format (e)) | ||
67 | pass | ||
68 | for p in gnunet_procs: | ||
69 | if not re.match (r'gnunet-service-arm', p[1]): | ||
70 | print ("killing non-arm process {0:5} {1}".format (p[0], p[1])) | ||
71 | try: | ||
72 | terminate.safe_terminate_process_by_pid (int (p[0]), 1) | ||
73 | except OSError as e: | ||
74 | print ("failed: {0}".format (e)) | ||
75 | pass | ||
76 | |||
77 | if __name__ == '__main__': | ||
78 | sys.exit (main ()) | ||
diff --git a/contrib/scripts/gnunet_pyexpect.py.in b/contrib/scripts/gnunet_pyexpect.py.in new file mode 100644 index 000000000..cfeb06d8d --- /dev/null +++ b/contrib/scripts/gnunet_pyexpect.py.in | |||
@@ -0,0 +1,83 @@ | |||
1 | #!@PYTHON@ | ||
2 | # This file is part of GNUnet. | ||
3 | # (C) 2010 Christian Grothoff (and other contributing authors) | ||
4 | # | ||
5 | # GNUnet is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License as published | ||
7 | # by the Free Software Foundation; either version 2, or (at your | ||
8 | # option) any later version. | ||
9 | # | ||
10 | # GNUnet is distributed in the hope that it will be useful, but | ||
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | # General Public License for more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License | ||
16 | # along with GNUnet; see the file COPYING. If not, write to the | ||
17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | # Boston, MA 02110-1301, USA. | ||
19 | # | ||
20 | # Testcase for gnunet-peerinfo | ||
21 | from __future__ import print_function | ||
22 | import os | ||
23 | import re | ||
24 | import subprocess | ||
25 | import sys | ||
26 | import shutil | ||
27 | import time | ||
28 | |||
29 | class pexpect (object): | ||
30 | def __init__ (self): | ||
31 | super (pexpect, self).__init__ () | ||
32 | |||
33 | def spawn (self, stdin, arglist, *pargs, **kwargs): | ||
34 | env = kwargs.pop ('env', None) | ||
35 | if env is None: | ||
36 | env = os.environ.copy () | ||
37 | # This messes up some testcases, disable log redirection | ||
38 | env.pop ('GNUNET_FORCE_LOGFILE', None) | ||
39 | self.proc = subprocess.Popen (arglist, *pargs, env=env, **kwargs) | ||
40 | if self.proc is None: | ||
41 | print ("Failed to spawn a process {0}".format (arglist)) | ||
42 | sys.exit (1) | ||
43 | if stdin is not None: | ||
44 | self.stdo, self.stde = self.proc.communicate (stdin) | ||
45 | else: | ||
46 | self.stdo, self.stde = self.proc.communicate () | ||
47 | return self.proc | ||
48 | |||
49 | def expect (self, s, r, flags=0): | ||
50 | stream = self.stdo if s == 'stdout' else self.stde | ||
51 | if isinstance (r, str): | ||
52 | if r == "EOF": | ||
53 | if len (stream) == 0: | ||
54 | return True | ||
55 | else: | ||
56 | print ("Failed to find `{1}' in {0}, which is `{2}' ({3})".format (s, r, stream, len (stream))) | ||
57 | sys.exit (2) | ||
58 | raise ValueError ("Argument `r' should be an instance of re.RegexObject or a special string, but is `{0}'".format (r)) | ||
59 | m = r.search (stream.decode(), flags) | ||
60 | if not m: | ||
61 | print ("Failed to find `{1}' in {0}, which is is `{2}'".format (s, r.pattern, stream)) | ||
62 | sys.exit (2) | ||
63 | stream = stream[m.end ():] | ||
64 | if s == 'stdout': | ||
65 | self.stdo = stream | ||
66 | else: | ||
67 | self.stde = stream | ||
68 | return m | ||
69 | |||
70 | def read (self, s, size=-1): | ||
71 | stream = self.stdo if s == 'stdout' else self.stde | ||
72 | result = "" | ||
73 | if size < 0: | ||
74 | result = stream | ||
75 | new_stream = "" | ||
76 | else: | ||
77 | result = stream[0:size] | ||
78 | new_stream = stream[size:] | ||
79 | if s == 'stdout': | ||
80 | self.stdo = new_stream | ||
81 | else: | ||
82 | self.stde = new_stream | ||
83 | return result | ||
diff --git a/contrib/scripts/process_log.sh b/contrib/scripts/process_log.sh new file mode 100755 index 000000000..c25c515c2 --- /dev/null +++ b/contrib/scripts/process_log.sh | |||
@@ -0,0 +1,30 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | # Usage: service should print "STARTING SERVICE (srvc) for peer [PEER]" where: | ||
4 | # - "srvc" is the service name (in lowercase, as in the log output). | ||
5 | # It cannot contain parenthesis in its name. | ||
6 | # - "PEER" is the peer ID. Should be 4 alfanumeric characters | ||
7 | |||
8 | grep "STARTING SERVICE " log > __tmp_peers | ||
9 | |||
10 | SED_EXPR="" | ||
11 | while read -r line; do | ||
12 | SRVC=`echo "$line" | sed -e 's/.*(\([^)]*\)).*/\1/'` | ||
13 | PEER=`echo "$line" | sed -e 's/.*\[\(....\)\].*/\1/'` | ||
14 | PID=`echo "$line" | sed -e "s/.*$SRVC-\([0-9]*\).*/\1/"` | ||
15 | echo "$SRVC $PID => $PEER" | ||
16 | |||
17 | SED_EXPR="${SED_EXPR}s/$SRVC-\([a-z2]*\)-$PID/$SRVC \1 $PEER/;" | ||
18 | SED_EXPR="${SED_EXPR}s/$SRVC-$PID/$SRVC XXX $PEER/;" | ||
19 | SED_EXPR="${SED_EXPR}s/$SRVC-api-[0-9]/$SRVC-api- /;" | ||
20 | done < __tmp_peers | ||
21 | rm __tmp_peers | ||
22 | |||
23 | sed -e "$SED_EXPR" log > .log | ||
24 | echo "$0 sed regex: $SED_EXPR" >> .log | ||
25 | |||
26 | SIZE=`stat -c%s .log` | ||
27 | |||
28 | if [[ "`ps aux | grep "kwrite .lo[g]"`" = "" && "$SIZE" < 10000000 ]]; then | ||
29 | kwrite .log --geometry 960x1140-960 & | ||
30 | fi | ||
diff --git a/contrib/scripts/pydiffer.py.in b/contrib/scripts/pydiffer.py.in new file mode 100644 index 000000000..10145371c --- /dev/null +++ b/contrib/scripts/pydiffer.py.in | |||
@@ -0,0 +1,44 @@ | |||
1 | #!@PYTHON@ | ||
2 | import os | ||
3 | import sys | ||
4 | import difflib | ||
5 | import filecmp | ||
6 | |||
7 | |||
8 | def getdiff(old, new): | ||
9 | diff = [] | ||
10 | with open(old) as a: | ||
11 | with open(new) as b: | ||
12 | for l in difflib.unified_diff(a.read().splitlines(), b.read().splitlines()): | ||
13 | diff.append(l) | ||
14 | return diff | ||
15 | |||
16 | |||
17 | def dc_getdiff(dc, old, new): | ||
18 | diff = [] | ||
19 | for f in dc.left_only: | ||
20 | diff.append("Only in {}: {}".format(old, f)) | ||
21 | for f in dc.right_only: | ||
22 | diff.append("Only in {}: {}".format(new, f)) | ||
23 | for f in dc.diff_files: | ||
24 | r = getdiff(os.path.join(old, f), os.path.join(new, f)) | ||
25 | diff.extend(r) | ||
26 | for dn, dc in dc.subdirs.items(): | ||
27 | r = dc_getdiff(dc, os.path.join(old, dn), os.path.join(new, dn)) | ||
28 | diff.extend(r) | ||
29 | return diff | ||
30 | |||
31 | |||
32 | def dcdiff(old, new): | ||
33 | dc = filecmp.dircmp(old, new) | ||
34 | diff = dc_getdiff(dc, old, new) | ||
35 | return diff | ||
36 | |||
37 | |||
38 | def main(): | ||
39 | for l in dcdiff(sys.argv[1], sys.argv[2]): | ||
40 | print(l) | ||
41 | |||
42 | |||
43 | if __name__ == '__main__': | ||
44 | main() | ||
diff --git a/contrib/scripts/pydmesg b/contrib/scripts/pydmesg new file mode 100755 index 000000000..d60e08fe3 --- /dev/null +++ b/contrib/scripts/pydmesg | |||
@@ -0,0 +1,75 @@ | |||
1 | #!/usr/bin/env python | ||
2 | # coding=utf8 | ||
3 | |||
4 | # Copyright (C) 2010 Saúl ibarra Corretgé <saghul@gmail.com> | ||
5 | # | ||
6 | |||
7 | """ | ||
8 | pydmesg: dmesg with human-readable timestamps | ||
9 | """ | ||
10 | |||
11 | from __future__ import with_statement | ||
12 | |||
13 | import re | ||
14 | import subprocess | ||
15 | import sys | ||
16 | |||
17 | from datetime import datetime, timedelta | ||
18 | |||
19 | |||
20 | _datetime_format = "%Y-%m-%d %H:%M:%S" | ||
21 | _dmesg_line_regex = re.compile("^\[(?P<time>\d+\.\d+)\](?P<line>.*)$") | ||
22 | |||
23 | def exec_process(cmdline, silent, input=None, **kwargs): | ||
24 | """Execute a subprocess and returns the returncode, stdout buffer and stderr buffer. | ||
25 | Optionally prints stdout and stderr while running.""" | ||
26 | try: | ||
27 | sub = subprocess.Popen(cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) | ||
28 | stdout, stderr = sub.communicate(input=input) | ||
29 | returncode = sub.returncode | ||
30 | if not silent: | ||
31 | sys.stdout.write(stdout) | ||
32 | sys.stderr.write(stderr) | ||
33 | except OSError,e: | ||
34 | if e.errno == 2: | ||
35 | raise RuntimeError('"%s" is not present on this system' % cmdline[0]) | ||
36 | else: | ||
37 | raise | ||
38 | if returncode != 0: | ||
39 | raise RuntimeError('Got return value %d while executing "%s", stderr output was:\n%s' % (returncode, " ".join(cmdline), stderr.rstrip("\n"))) | ||
40 | return stdout | ||
41 | |||
42 | def human_dmesg(): | ||
43 | now = datetime.now() | ||
44 | uptime_diff = None | ||
45 | try: | ||
46 | with open('/proc/uptime') as f: | ||
47 | uptime_diff = f.read().strip().split()[0] | ||
48 | except IndexError: | ||
49 | return | ||
50 | else: | ||
51 | try: | ||
52 | uptime = now - timedelta(seconds=int(uptime_diff.split('.')[0]), microseconds=int(uptime_diff.split('.')[1])) | ||
53 | except IndexError: | ||
54 | return | ||
55 | |||
56 | dmesg_data = exec_process(['dmesg'], True) | ||
57 | for line in dmesg_data.split('\n'): | ||
58 | if not line: | ||
59 | continue | ||
60 | match = _dmesg_line_regex.match(line) | ||
61 | if match: | ||
62 | try: | ||
63 | seconds = int(match.groupdict().get('time', '').split('.')[0]) | ||
64 | nanoseconds = int(match.groupdict().get('time', '').split('.')[1]) | ||
65 | microseconds = int(round(nanoseconds * 0.001)) | ||
66 | line = match.groupdict().get('line', '') | ||
67 | t = uptime + timedelta(seconds=seconds, microseconds=microseconds) | ||
68 | except IndexError: | ||
69 | pass | ||
70 | else: | ||
71 | print "[%s]%s" % (t.strftime(_datetime_format), line) | ||
72 | |||
73 | |||
74 | if __name__ == '__main__': | ||
75 | human_dmesg() | ||
diff --git a/contrib/scripts/regression.sh b/contrib/scripts/regression.sh new file mode 100755 index 000000000..1f799797a --- /dev/null +++ b/contrib/scripts/regression.sh | |||
@@ -0,0 +1,54 @@ | |||
1 | #!/bin/sh | ||
2 | cd | ||
3 | cd gnunet | ||
4 | svn up > /dev/null | ||
5 | H=`hostname` | ||
6 | echo "================START===================" >> regression.$H | ||
7 | RUN=`date +%0y%0m%0d%0k%0M` | ||
8 | uname -a >> regression.$H | ||
9 | date >> regression.$H | ||
10 | echo "Run $RUN" >> regression.$H | ||
11 | svn up >> regression.$H | ||
12 | export GNUNET_PREFIX=$HOME | ||
13 | export PATH=$HOME/bin:$PATH | ||
14 | ./bootstrap >> regression.$H.$RUN 2>&1 | ||
15 | ./configure --prefix=$HOME --with-extractor=$HOME --with-microhttpd=$HOME >> regression.$H.$RUN 2>&1 | ||
16 | if [ $? != 0 ] | ||
17 | then | ||
18 | echo configure failed >> regression.$H | ||
19 | exit | ||
20 | fi | ||
21 | KEEP=0 | ||
22 | make clean >> regression.$H.$RUN 2>&1 | ||
23 | make install >> regression.$H.$RUN 2>&1 | ||
24 | cd src | ||
25 | for n in `ls --hide "Makefile*"` | ||
26 | do | ||
27 | cd $n | ||
28 | if [ -f Makefile ] | ||
29 | then | ||
30 | make check >> ../regression.$H.$RUN.$n 2>&1 | ||
31 | if [ $? != 0 ] | ||
32 | then | ||
33 | echo Tests for $n failed >> ../regression.$H | ||
34 | echo "--------- Details for $n -----------" >> ../regression.$H | ||
35 | cat regression.$H.$RUN.$n >> ../regression.$H | ||
36 | echo "----- End of Details for $n --------" >> ../regression.$H | ||
37 | KEEP=1 | ||
38 | else | ||
39 | echo Tests for $n succeeded >> ../regression.$H | ||
40 | fi | ||
41 | fi | ||
42 | cd .. | ||
43 | done | ||
44 | echo "================END====================" >> regression.$H | ||
45 | |||
46 | if [ $KEEP == 0] | ||
47 | then | ||
48 | rm regression.$H.$RUN* | ||
49 | rm regression.$H | ||
50 | else | ||
51 | svn add regression.$H > /dev/null | ||
52 | svn commit -m "Regression in tests on $H" regression.$H | ||
53 | fi | ||
54 | |||
diff --git a/contrib/scripts/removetrailingwhitespace.py.in b/contrib/scripts/removetrailingwhitespace.py.in new file mode 100755 index 000000000..5824fb591 --- /dev/null +++ b/contrib/scripts/removetrailingwhitespace.py.in | |||
@@ -0,0 +1,15 @@ | |||
1 | #!@PYTHON@ | ||
2 | |||
3 | import sys | ||
4 | import re | ||
5 | |||
6 | |||
7 | for fileName in sys.argv[1:]: | ||
8 | f = open(fileName, 'r+') | ||
9 | fileString = f.read() | ||
10 | |||
11 | fileString = re.sub(r'[ ]+\n', r'\n', fileString) | ||
12 | fileString = re.sub(r'\r', r'', fileString) | ||
13 | f.seek(0) | ||
14 | f.write(fileString) | ||
15 | f.truncate(len(fileString)) | ||
diff --git a/contrib/scripts/report.sh b/contrib/scripts/report.sh new file mode 100755 index 000000000..7fbb2f46c --- /dev/null +++ b/contrib/scripts/report.sh | |||
@@ -0,0 +1,252 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | TEST=`type type|grep not` | ||
4 | if test -n "$TEST"; then | ||
5 | WHICH=which | ||
6 | else | ||
7 | WHICH=type | ||
8 | fi | ||
9 | |||
10 | echo "Please submit the following information with your bug report: " | ||
11 | echo "--------------------------------------------------------------" | ||
12 | OS=`uname -s 2>/dev/null` | ||
13 | echo "OS : $OS" | ||
14 | REL=`uname -r 2>/dev/null` | ||
15 | echo "OS RELEASE : $REL" | ||
16 | HW=`uname -m 2>/dev/null` | ||
17 | echo "HARDWARE : $HW" | ||
18 | |||
19 | TEST=`$WHICH gcc 2>/dev/null` | ||
20 | if test -n "$TEST"; then | ||
21 | VERS=`gcc --version 2>/dev/null | head -n 1` | ||
22 | echo "gcc : $VERS" | ||
23 | else | ||
24 | echo "gcc : Not Found"; | ||
25 | fi | ||
26 | |||
27 | TEST=`$WHICH gmake 2>/dev/null` | ||
28 | if test -n "$TEST" ; then | ||
29 | gmake --version 2>/dev/null |\ | ||
30 | awk -F, '{print $1}' |\ | ||
31 | awk '/GNU Make/{print "GNU gmake :",$NF}' | ||
32 | else | ||
33 | TEST=`make --version 2>/dev/null` | ||
34 | if test -n "$TEST"; then | ||
35 | make --version 2>/dev/null |\ | ||
36 | awk -F, '{print $1}' |\ | ||
37 | awk '/GNU Make/{print "make :",$NF}' | ||
38 | else | ||
39 | echo "make : Not Found" | ||
40 | fi | ||
41 | fi | ||
42 | |||
43 | TEST=`$WHICH autoconf 2>/dev/null` | ||
44 | if test -n "$TEST"; then | ||
45 | autoconf --version |\ | ||
46 | head -n 1 |\ | ||
47 | awk '{\ | ||
48 | if (length($4) == 0) {\ | ||
49 | print "autoconf : "$3\ | ||
50 | } else {\ | ||
51 | print "autoconf : "$4\ | ||
52 | }}' | ||
53 | else | ||
54 | echo "autoconf : Not Found" | ||
55 | fi | ||
56 | |||
57 | TEST=`$WHICH automake 2>/dev/null` | ||
58 | if test -n "$TEST"; then | ||
59 | automake --version 2>/dev/null |\ | ||
60 | head -n 1 |\ | ||
61 | awk '{print "automake : "$4}' | ||
62 | else | ||
63 | echo "automake : Not Found" | ||
64 | fi | ||
65 | |||
66 | TEST=`$WHICH libtool 2>/dev/null` | ||
67 | if test -n "$TEST"; then | ||
68 | libtool --version 2>/dev/null |\ | ||
69 | head -n 1 |\ | ||
70 | awk '{print "libtool : "$4}' | ||
71 | else | ||
72 | echo "libtool : Not Found" | ||
73 | fi | ||
74 | |||
75 | TEST=`$WHICH extract 2>/dev/null` | ||
76 | if test -n "$TEST"; then | ||
77 | extract -v 2>/dev/null |\ | ||
78 | head -n 1 |\ | ||
79 | awk '{print "libextractor : "$2}' | ||
80 | else | ||
81 | echo "libextractor : Not Found" | ||
82 | fi | ||
83 | |||
84 | if test -x gnunetd; then | ||
85 | gnunetd -v | sed -e "s/v//" 2>/dev/null |\ | ||
86 | awk '{print "GNUnet 0.8 : "$2 (may conflict!)}' | ||
87 | else | ||
88 | echo "GNUnet 0.8 : Not Found (good)" | ||
89 | fi | ||
90 | |||
91 | TEST=`$WHICH gnunet-arm 2>/dev/null` | ||
92 | if test -n "$TEST"; then | ||
93 | gnunet-arm -v | sed -e "s/v//" 2>/dev/null |\ | ||
94 | awk '{print "GNUnet 0.9 : "$2}' | ||
95 | else | ||
96 | echo "GNUnet 0.9 : Not Found" | ||
97 | fi | ||
98 | |||
99 | TEST=`$WHICH libgcrypt-config 2> /dev/null` | ||
100 | if test -n "$TEST"; then | ||
101 | libgcrypt-config --version 2> /dev/null | \ | ||
102 | awk '{print "libgcrypt : "$1}' | ||
103 | else | ||
104 | echo "libgcrypt : Not Found" | ||
105 | fi | ||
106 | |||
107 | TEST=`$WHICH mysql_config 2> /dev/null` | ||
108 | if test -n "$TEST"; then | ||
109 | mysql_config --version 2> /dev/null | \ | ||
110 | awk '{print "mysql : "$1}' | ||
111 | else | ||
112 | echo "mysql : Not Found" | ||
113 | fi | ||
114 | |||
115 | TEST=`$WHICH pkg-config 2> /dev/null` | ||
116 | if test -n "$TEST"; then | ||
117 | pkg-config --version 2> /dev/null | \ | ||
118 | awk '{print "pkg-config : "$1}' | ||
119 | else | ||
120 | echo "pkg-config : Not Found" | ||
121 | fi | ||
122 | |||
123 | TEST=`$WHICH pkg-config 2> /dev/null` | ||
124 | if test -n "$TEST"; then | ||
125 | pkg-config --modversion glib-2.0 2> /dev/null | \ | ||
126 | awk '{print "glib2 : "$1}' | ||
127 | else | ||
128 | echo "glib2 : Not Found" | ||
129 | fi | ||
130 | |||
131 | TEST=`$WHICH pkg-config 2> /dev/null` | ||
132 | if test -n "$TEST"; then | ||
133 | pkg-config --modversion gtk+-2.0 2> /dev/null | \ | ||
134 | awk '{print "gtk2+ : "$1}' | ||
135 | else | ||
136 | echo "gtk2+ : Not Found" | ||
137 | fi | ||
138 | |||
139 | TEST=`$WHICH dpkg 2> /dev/null` | ||
140 | if test -n "$TEST"; then | ||
141 | LINES=`dpkg -s libgmp-dev | grep Version | wc -l 2> /dev/null` | ||
142 | if test "$LINES" = "1" | ||
143 | then | ||
144 | VERSION=`dpkg -s libgmp-dev | grep Version | awk '{print $2}'` | ||
145 | echo "GMP : libgmp-dev-$VERSION.deb" | ||
146 | else | ||
147 | echo "GMP : dpkg: libgmp-dev not installed" | ||
148 | fi | ||
149 | else | ||
150 | TEST=`$WHICH rpm 2> /dev/null` | ||
151 | if test -n "$TEST"; then | ||
152 | rpm -q gmp | sed -e "s/gmp-//" 2> /dev/null | \ | ||
153 | awk '{print "GMP : "$1.rpm}' | ||
154 | else | ||
155 | echo "GMP : Test not available" | ||
156 | fi | ||
157 | fi | ||
158 | |||
159 | TEST=`$WHICH dpkg 2> /dev/null` | ||
160 | if test -n "$TEST"; then | ||
161 | LINES=`dpkg -s libunistring-dev | grep Version | wc -l` | ||
162 | if test "$LINES" = "1" | ||
163 | then | ||
164 | VERSION=`dpkg -s libunistring-dev | grep Version | awk '{print $2}'` | ||
165 | echo "libunistring : libunistring3-dev-$VERSION.deb" | ||
166 | else | ||
167 | echo "libunistring : dpkg: libunistring3-dev not installed" | ||
168 | fi | ||
169 | else | ||
170 | TEST=`$WHICH rpm 2> /dev/null` | ||
171 | if test -n "$TEST"; then | ||
172 | rpm -q unistring | sed -e "s/unistring-//" 2> /dev/null | \ | ||
173 | awk '{print "libunistring : "$1.rpm}' | ||
174 | else | ||
175 | echo "libunistring : Test not available" | ||
176 | fi | ||
177 | fi | ||
178 | |||
179 | TEST=`$WHICH gettext 2> /dev/null` | ||
180 | if test -n "$TEST"; then | ||
181 | gettext --version | head -n1 2> /dev/null | \ | ||
182 | awk '{print "GNU gettext : "$4}' | ||
183 | else | ||
184 | echo "GNU gettext : Not found" | ||
185 | fi | ||
186 | |||
187 | |||
188 | TEST=`$WHICH curl-config 2> /dev/null` | ||
189 | if test -n "$TEST"; then | ||
190 | curl-config --version | head -n1 2> /dev/null | \ | ||
191 | awk '{print "libcurl : "$2}' | ||
192 | else | ||
193 | echo "libcurl : Not found" | ||
194 | fi | ||
195 | |||
196 | TEST=`$WHICH gnurl-config 2> /dev/null` | ||
197 | if test -n "$TEST"; then | ||
198 | gnurl-config --version | head -n1 2> /dev/null | \ | ||
199 | awk '{print "libgnurl : "$2}' | ||
200 | else | ||
201 | echo "libgnurl : Not found" | ||
202 | fi | ||
203 | |||
204 | echo -n "libmicrohttpd : " | ||
205 | TMPFILE=`mktemp /tmp/mhd-version-testXXXXXX` | ||
206 | cat - >$TMPFILE.c <<EOF | ||
207 | #include <microhttpd.h> | ||
208 | #include <stdio.h> | ||
209 | int main() | ||
210 | { | ||
211 | fprintf (stdout, "%X\n", MHD_VERSION); | ||
212 | return 0; | ||
213 | } | ||
214 | EOF | ||
215 | |||
216 | gcc -o $TMPFILE $TMPFILE.c 2> /dev/null && $TMPFILE || echo "Not found" | ||
217 | rm -f $TMPFILE $TMPFILE.bin | ||
218 | |||
219 | |||
220 | echo -n "GNU GLPK : " | ||
221 | TMPFILE=`mktemp /tmp/glpk-version-testXXXXXX` | ||
222 | cat - >$TMPFILE.c <<EOF | ||
223 | #include <glpk.h> | ||
224 | #include <stdio.h> | ||
225 | int main() | ||
226 | { | ||
227 | fprintf (stdout, "%u.%u\n", GLP_MAJOR_VERSION, GLP_MINOR_VERSION); | ||
228 | return 0; | ||
229 | } | ||
230 | EOF | ||
231 | |||
232 | gcc -o $TMPFILE $TMPFILE.c 2> /dev/null && $TMPFILE || echo "Not found" | ||
233 | rm -f $TMPFILE $TMPFILE.bin | ||
234 | |||
235 | |||
236 | echo -n "GNUtls : " | ||
237 | TMPFILE=`mktemp /tmp/gnutls-version-testXXXXXX` | ||
238 | cat - >$TMPFILE.c <<EOF | ||
239 | #include <gnutls/gnutls.h> | ||
240 | #include <stdio.h> | ||
241 | int main() | ||
242 | { | ||
243 | fprintf (stdout, "%s\n", GNUTLS_VERSION); | ||
244 | return 0; | ||
245 | } | ||
246 | EOF | ||
247 | |||
248 | gcc -o $TMPFILE $TMPFILE.c 2> /dev/null && $TMPFILE || echo "Not found" | ||
249 | rm -f $TMPFILE $TMPFILE.bin | ||
250 | |||
251 | |||
252 | echo "--------------------------------------------------------------" | ||
diff --git a/contrib/scripts/revisionary.sh b/contrib/scripts/revisionary.sh new file mode 100755 index 000000000..5778cf148 --- /dev/null +++ b/contrib/scripts/revisionary.sh | |||
@@ -0,0 +1,98 @@ | |||
1 | #!/usr/local/bin/bash | ||
2 | |||
3 | STARTREVISION=14033 | ||
4 | ENDREVISION=15268 | ||
5 | CURRENTREVISION=$STARTREVISION | ||
6 | HOME_DIR='/home/gnunet/FreeBSD7-AMD64-wachs/freebsd7-amd64-wachs/build' | ||
7 | |||
8 | |||
9 | CMD_UPDATE="svn up --force --accept theirs-full -r" | ||
10 | CMD_CLEANUP="killall -s 31 -r gnunet-*; make distclean;" | ||
11 | CMD_PREPARATION="./bootstrap; ./configure --prefix=/tmp/gnb --with-extractor=/usr/local" | ||
12 | CMD_BUILD="make all" | ||
13 | CMD_TEST="cd src/transport ; make test_transport_api_tcp; ./test_transport_api_tcp" | ||
14 | |||
15 | #LOGGING="" | ||
16 | LOGGING=" 1> /dev/null 2> errors.txt" | ||
17 | LOGFILE="log.txt" | ||
18 | |||
19 | function output () | ||
20 | { | ||
21 | eval echo $1 | ||
22 | eval echo $1 >> $LOGFILE | ||
23 | } | ||
24 | |||
25 | |||
26 | while [ $CURRENTREVISION -le $ENDREVISION ]; do | ||
27 | output 'Testing revision $CURRENTREVISION' | ||
28 | # updating | ||
29 | output ' -> updating ' | ||
30 | eval cd $HOME_DIR | ||
31 | CMD="$CMD_UPDATE $CURRENTREVISION $LOGGING" | ||
32 | eval $CMD | ||
33 | result=$? | ||
34 | if [ $result -eq 0 ]; then | ||
35 | output " updating OK" | ||
36 | else | ||
37 | output " updating FAILED" | ||
38 | (( CURRENTREVISION++ )) | ||
39 | continue | ||
40 | fi | ||
41 | |||
42 | # clean up | ||
43 | output " -> cleanup " | ||
44 | CMD="$CMD_CLEANUP $LOGGING" | ||
45 | eval $CMD | ||
46 | result=$? | ||
47 | if [ $result -eq 0 ]; then | ||
48 | output " cleanup OK" | ||
49 | else | ||
50 | output " cleanup FAILED" | ||
51 | (( CURRENTREVISION++ )) | ||
52 | continue | ||
53 | fi | ||
54 | # preparing | ||
55 | output " -> preparation " | ||
56 | CMD="$CMD_PREPARATION $LOGGING" | ||
57 | #echo $CMD | ||
58 | eval $CMD | ||
59 | result=$? | ||
60 | if [ $result -eq 0 ]; then | ||
61 | output " preparation OK" | ||
62 | else | ||
63 | output " preparation FAILED" | ||
64 | (( CURRENTREVISION++ )) | ||
65 | continue | ||
66 | fi | ||
67 | # building | ||
68 | output " -> building " | ||
69 | CMD="$CMD_BUILD $LOGGING" | ||
70 | #echo $CMD | ||
71 | eval $CMD | ||
72 | result=$? | ||
73 | if [ $result -eq 0 ]; then | ||
74 | output " building OK" | ||
75 | else | ||
76 | output " building FAILED" | ||
77 | (( CURRENTREVISION++ )) | ||
78 | continue | ||
79 | fi | ||
80 | # testing | ||
81 | output " -> testing " | ||
82 | CMD="$CMD_TEST $LOGGING" | ||
83 | #echo $CMD | ||
84 | eval $CMD | ||
85 | result=$? | ||
86 | testresult=result | ||
87 | if [ $result -eq 0 ]; then | ||
88 | output " testing OK" | ||
89 | else | ||
90 | output " testing FAILED" | ||
91 | output 'Revision $CURRENTREVISION FAILED' | ||
92 | fi | ||
93 | (( CURRENTREVISION++ )) | ||
94 | done | ||
95 | |||
96 | exit | ||
97 | |||
98 | |||
diff --git a/contrib/scripts/terminate.py.in b/contrib/scripts/terminate.py.in new file mode 100644 index 000000000..4a6719f38 --- /dev/null +++ b/contrib/scripts/terminate.py.in | |||
@@ -0,0 +1,64 @@ | |||
1 | #!@PYTHON@ | ||
2 | # This file is part of GNUnet. | ||
3 | # (C) 2011 Christian Grothoff (and other contributing authors) | ||
4 | # | ||
5 | # GNUnet is free software; you can redistribute it and/or modify | ||
6 | # it under the terms of the GNU General Public License as published | ||
7 | # by the Free Software Foundation; either version 2, or (at your | ||
8 | # option) any later version. | ||
9 | # | ||
10 | # GNUnet is distributed in the hope that it will be useful, but | ||
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | # General Public License for more details. | ||
14 | # | ||
15 | # You should have received a copy of the GNU General Public License | ||
16 | # along with GNUnet; see the file COPYING. If not, write to the | ||
17 | # Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, | ||
18 | # Boston, MA 02110-1301, USA. | ||
19 | # | ||
20 | # Utility module that implements safe process termination for W32. | ||
21 | # For other platforms it's equivalent to Popen.kill () | ||
22 | # Requires pywin32 on W32. | ||
23 | |||
24 | import sys | ||
25 | import os | ||
26 | import subprocess | ||
27 | if os.name == 'nt': | ||
28 | import win32api | ||
29 | import win32process | ||
30 | |||
31 | class dummyobj (object): | ||
32 | pass | ||
33 | |||
34 | def safe_terminate_process_by_pid (pid, code): | ||
35 | if os.name == 'nt': | ||
36 | p = dummyobj () | ||
37 | p._handle = win32api.OpenProcess (2 | 1024 | 8 | 32 | 16, 0, pid) | ||
38 | result = safe_terminate_process (p, code) | ||
39 | win32api.CloseHandle (p._handle) | ||
40 | return result | ||
41 | else: | ||
42 | return os.kill (int (pid), SIGKILL) | ||
43 | |||
44 | def safe_terminate_process (proc, code): | ||
45 | if os.name == 'nt': | ||
46 | cp = win32api.GetCurrentProcess () | ||
47 | result = False | ||
48 | dupproc = win32api.DuplicateHandle (cp, proc._handle, cp, 2 | 1024 | 8 | 32 | 16, 0, 0) | ||
49 | try: | ||
50 | exitcode = win32process.GetExitCodeProcess (dupproc) | ||
51 | if exitcode == 0x103: | ||
52 | kernel32 = win32api.GetModuleHandle ("kernel32") | ||
53 | exitprocess = win32api.GetProcAddress (kernel32, "ExitProcess") | ||
54 | th, tid = win32process.CreateRemoteThread (dupproc, None, 0, exitprocess, code, 0) | ||
55 | win32api.CloseHandle (th) | ||
56 | result = True | ||
57 | else: | ||
58 | result = True | ||
59 | # except failed to get exit code? failed to get module handle? | ||
60 | finally: | ||
61 | win32api.CloseHandle (dupproc) | ||
62 | return result | ||
63 | else: | ||
64 | return proc.kill () | ||
diff --git a/contrib/scripts/testbed_cleanup.sh b/contrib/scripts/testbed_cleanup.sh new file mode 100755 index 000000000..57413fba0 --- /dev/null +++ b/contrib/scripts/testbed_cleanup.sh | |||
@@ -0,0 +1,14 @@ | |||
1 | #!/bin/bash | ||
2 | |||
3 | ################################################################################### | ||
4 | # Script to clean a previous run of testbed which has crashed. This scripts kills # | ||
5 | # the peers and cleans the temporary files created for those peers # | ||
6 | # # | ||
7 | # Author: Sree Harsha Totakura # | ||
8 | ################################################################################### | ||
9 | |||
10 | for host in `cut -d : -f 1 < infiniband_cluster.hosts | cut -d @ -f 2` | ||
11 | do | ||
12 | echo "ssh --> $host" | ||
13 | ssh $host 'pkill -SIGKILL gnunet; rm -rf /tmp/gnunet-pipe*; rm -rf /tmp/testbed*' | ||
14 | done | ||
diff --git a/contrib/scripts/texinfo-hacks.el b/contrib/scripts/texinfo-hacks.el new file mode 100644 index 000000000..bfb5c98fa --- /dev/null +++ b/contrib/scripts/texinfo-hacks.el | |||
@@ -0,0 +1,18 @@ | |||
1 | ;;;; hacks.el --- a few functions to help me work on the manual | ||
2 | ;;;; Jim Blandy <jimb@red-bean.com> --- October 1998 | ||
3 | ;;;; -- imported from https://git.savannah.gnu.org/cgit/guile.git/tree/doc/hacks.el | ||
4 | ;;;; This code should be covered by the same license as GNU Guile (GPL3). | ||
5 | |||
6 | (defun jh-exemplify-region (start end) | ||
7 | (interactive "r") | ||
8 | (save-excursion | ||
9 | (save-restriction | ||
10 | (narrow-to-region start end) | ||
11 | |||
12 | ;; Texinfo doesn't handle tabs well. | ||
13 | (untabify (point-min) (point-max)) | ||
14 | |||
15 | ;; Quote any characters special to texinfo. | ||
16 | (goto-char (point-min)) | ||
17 | (while (re-search-forward "[{}@]" nil t) | ||
18 | (replace-match "@\\&"))))) | ||
diff --git a/contrib/scripts/visualize_stats.sh b/contrib/scripts/visualize_stats.sh new file mode 100755 index 000000000..aaa5e657b --- /dev/null +++ b/contrib/scripts/visualize_stats.sh | |||
@@ -0,0 +1,86 @@ | |||
1 | #!/bin/bash | ||
2 | # | ||
3 | # This script polls gnunet-stats repeatedly to create statistics plots. | ||
4 | # Use 'collect' to collect statistics and 'plot' to plot whats been | ||
5 | # collected. All plots will be written to $STATDIR as separate .png files. | ||
6 | # | ||
7 | # WARNING: calling 'collect' will delete all files in $STATDIR. | ||
8 | # | ||
9 | # Requires: gnuplot | ||
10 | # | ||
11 | # Note: gnuplot syntax has changed across versions. This | ||
12 | # script perhaps will not produce color images with older gnuplots. | ||
13 | # The script should work atleast with gnuplot 3.8k patchlevel 1. | ||
14 | # | ||
15 | |||
16 | SLEEP=120 | ||
17 | GNUNET=$HOME/ | ||
18 | STATDIR=$GNUNET/stats | ||
19 | IMAGEVIEWER='display' | ||
20 | TMP=/tmp/.gnuplot_error | ||
21 | |||
22 | ########################################################################## | ||
23 | |||
24 | mkdir -p $STATDIR | ||
25 | |||
26 | case "$1" in | ||
27 | collect) | ||
28 | rm -f $STATDIR/* | ||
29 | |||
30 | STARTTIME=`date +%s` | ||
31 | IFS=":" | ||
32 | |||
33 | while true; do | ||
34 | NOW=`date +%s` | ||
35 | RELAT=$[$NOW-$STARTTIME] | ||
36 | gnunet-statistics | while read KEY VALUE; do | ||
37 | KEY=`echo $KEY | tr / .` | ||
38 | # Collect stats of previous round | ||
39 | if [ -e "$STATDIR/$KEY.dat" ]; then | ||
40 | PREV=`tail --lines=1 "$STATDIR/$KEY.dat" | sed -e "s/.* //g"` | ||
41 | else | ||
42 | PREV=$VALUE | ||
43 | fi | ||
44 | |||
45 | # Write new stats | ||
46 | echo $RELAT $VALUE >>"$STATDIR/$KEY.dat" | ||
47 | echo $RELAT $PREV $VALUE >>"$STATDIR/$KEY.diff" | ||
48 | |||
49 | done | ||
50 | sleep $SLEEP | ||
51 | done | ||
52 | ;; | ||
53 | plot) | ||
54 | # Plot incremental | ||
55 | ls -1 $STATDIR/*.dat | while read FILENAME; do | ||
56 | BASENAME=`basename "$FILENAME" | sed -e "s/ *\..*//g"` | ||
57 | echo "set terminal png;set output '$FILENAME.png';set title '$BASENAME - incr';plot '$FILENAME' using (\$1/60):(\$2) title '' with lines;" | nice gnuplot 2> $TMP | ||
58 | EC=`cat $TMP | grep "empty" | grep "Warning" | wc -l` | ||
59 | if test $EC -ge 1 | ||
60 | then | ||
61 | rm "$FILENAME.png" | ||
62 | fi | ||
63 | done | ||
64 | |||
65 | # Plot diff | ||
66 | ls -1 $STATDIR/*.diff | while read FILENAME; do | ||
67 | BASENAME=`basename "$FILENAME" | sed -e "s/ *\..*//g"` | ||
68 | echo "set terminal png;set output '$FILENAME.png';set title '$BASENAME - diff';plot '$FILENAME' using (\$1/60):(\$3-\$2) title '' with lines;" | nice gnuplot 2> $TMP | ||
69 | EC=`cat $TMP | grep "empty" | grep "Warning" | wc -l` | ||
70 | if test $EC -ge 1 | ||
71 | then | ||
72 | rm "$FILENAME.png" | ||
73 | fi | ||
74 | |||
75 | done | ||
76 | ;; | ||
77 | view) | ||
78 | $IMAGEVIEWER $STATDIR/*.png | ||
79 | ;; | ||
80 | *) | ||
81 | echo $"Usage: $0 {collect|plot|view}" | ||
82 | exit 1 | ||
83 | |||
84 | esac | ||
85 | |||
86 | |||
diff --git a/contrib/scripts/zonewalk-to-types.sh b/contrib/scripts/zonewalk-to-types.sh new file mode 100755 index 000000000..c453702e6 --- /dev/null +++ b/contrib/scripts/zonewalk-to-types.sh | |||
@@ -0,0 +1,35 @@ | |||
1 | #!/bin/sh | ||
2 | # This script is in the public domain. | ||
3 | # Converts the output of gnunet-zonewalk (DNS resolutions) | ||
4 | # into a proper input for gnunet-gns-benchmark. | ||
5 | |||
6 | NUM_CLIENTS=3 | ||
7 | # How many different groups of names should we | ||
8 | # create? 1/N will be in the 'shared' group. | ||
9 | |||
10 | # FILE ($1) contains results from DNS lookup; strip | ||
11 | # everything but the hostnames, remove duplicates | ||
12 | # and then randomize the order. | ||
13 | cat $1 | awk '{print $1}' | sort | uniq | shuf > $1.tmp | ||
14 | TOTAL=`cat $1.tmp | wc -l` | ||
15 | GROUP_SIZE=`expr $TOTAL / \( $NUM_TYPES + 1 \)` | ||
16 | |||
17 | # First group (0) is to be shared among all clients | ||
18 | for i in `seq 1 $NUM_CLIENTS` | ||
19 | do | ||
20 | cat $1.tmp | head -n $GROUP_SIZE | awk "{print 0 \" \" \$1}" > $1.$i.tmp | ||
21 | done | ||
22 | |||
23 | # Second group (1) is unique per client | ||
24 | OFF=0 | ||
25 | for i in `seq 1 $NUM_CLIENTS` | ||
26 | do | ||
27 | END=`expr $OFF + $GROUP_SIZE` | ||
28 | cat $1.tmp | head -n $END | tail -n $GROUP_SIZE | awk "{print 1 \" \" \$1}" >> $1.$i.tmp | ||
29 | # Shuffle again, so we mix the different request categories in terms of | ||
30 | # when we issue the queries. | ||
31 | cat $1.$i.tmp | shuf > $1.$i | ||
32 | OFF="$END" | ||
33 | rm $1.$i.tmp | ||
34 | done | ||
35 | rm $1.tmp | ||