Merge lp:~ev/whoopsie/mac-address-fallback into lp:whoopsie

Proposed by Evan
Status: Merged
Approved by: Evan
Approved revision: 493
Merged at revision: 491
Proposed branch: lp:~ev/whoopsie/mac-address-fallback
Merge into: lp:whoopsie
Diff against target: 599 lines (+316/-109)
10 files modified
.bzrignore (+1/-0)
Makefile (+8/-1)
debian/changelog (+2/-0)
src/identifier.c (+136/-0)
src/identifier.h (+5/-0)
src/tests/Makefile (+18/-3)
src/tests/test_identifier.c (+125/-0)
src/tests/test_parse_report.c (+0/-32)
src/whoopsie.c (+21/-72)
src/whoopsie.h (+0/-1)
To merge this branch: bzr merge lp:~ev/whoopsie/mac-address-fallback
Reviewer Review Type Date Requested Status
Evan (community) Approve
Review via email: mp+105855@code.launchpad.net

Commit message

Fix bug #963007 by falling back to taking the sha512 hash of the first non-loopback MAC address when the DMI tables do not exist.

Description of the change

This branch fixes bug #963007 by falling back to taking the sha512 hash of the first non-loopback MAC address when the DMI tables do not exist.

To post a comment you must log in.
Revision history for this message
Evan (ev) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2012-03-29 15:02:13 +0000
3+++ .bzrignore 2012-05-15 16:54:18 +0000
4@@ -6,3 +6,4 @@
5 src/tests/test_parse_report
6 src/tests/test_utils
7 src/tests/test_monitor
8+src/tests/test_identifier
9
10=== modified file 'Makefile'
11--- Makefile 2012-04-10 16:53:36 +0000
12+++ Makefile 2012-05-15 16:54:18 +0000
13@@ -1,7 +1,14 @@
14 VERSION=$(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
15 CFLAGS=$(shell pkg-config --cflags gio-2.0 glib-2.0 libcurl) $(shell libgcrypt-config --cflags) -g -Ilib -Wall -Werror -Os -DVERSION=\"$(VERSION)\"
16 LIBS=$(shell pkg-config --libs gio-2.0 glib-2.0 libcurl) $(shell libgcrypt-config --libs) -lcap
17-SOURCES=src/whoopsie.c src/utils.c src/connectivity.c src/monitor.c lib/bson/bson.c lib/bson/encoding.c lib/bson/numbers.c
18+SOURCES=src/whoopsie.c \
19+ src/utils.c \
20+ src/connectivity.c \
21+ src/monitor.c \
22+ src/identifier.c \
23+ lib/bson/bson.c \
24+ lib/bson/encoding.c \
25+ lib/bson/numbers.c
26 OBJECTS=$(SOURCES:.c=.o)
27 EXECUTABLE=src/whoopsie
28 BIN=$(DESTDIR)/usr/bin
29
30=== modified file 'debian/changelog'
31--- debian/changelog 2012-05-09 23:04:30 +0000
32+++ debian/changelog 2012-05-15 16:54:18 +0000
33@@ -2,6 +2,8 @@
34
35 * Create the /var/metrics directory for metrics submission. Thanks Ted
36 Gould.
37+ * Fallback to using the SHA-512 hash of the first non-loopback MAC
38+ address (LP: #963007).
39
40 -- Evan Dandrea <ev@ubuntu.com> Tue, 08 May 2012 14:14:40 -0700
41
42
43=== added file 'src/identifier.c'
44--- src/identifier.c 1970-01-01 00:00:00 +0000
45+++ src/identifier.c 2012-05-15 16:54:18 +0000
46@@ -0,0 +1,136 @@
47+#include <glib.h>
48+#include <gcrypt.h>
49+#include <sys/types.h>
50+#include <sys/ioctl.h>
51+#include <linux/if.h>
52+#include <unistd.h>
53+#include <netinet/in.h>
54+#include <string.h>
55+#include <stdio.h>
56+#include <fcntl.h>
57+
58+#include "identifier.h"
59+
60+void
61+hex_to_char (char* buf, const char *str, int len)
62+{
63+ char* p = NULL;
64+ int i = 0;
65+
66+ p = buf;
67+ for (i = 0; i < len; i++) {
68+ snprintf(p, 3, "%02x", (unsigned char) str[i]);
69+ p += 2;
70+ }
71+ buf[2*len] = 0;
72+}
73+
74+void
75+identifier_get_mac_address (char** res, GError** error)
76+{
77+ struct ifreq ifr;
78+ struct ifconf ifc;
79+ char buf[1024];
80+ gboolean success = FALSE;
81+ int sock;
82+ struct ifreq* it;
83+ int i = 0;
84+
85+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
86+ if (sock == -1) {
87+ g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
88+ "Could not create socket.");
89+ return;
90+ }
91+
92+ ifc.ifc_len = sizeof(buf);
93+ ifc.ifc_buf = buf;
94+ if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
95+ g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
96+ "Could not get list of interface addresses.");
97+ return;
98+ }
99+
100+ it = ifc.ifc_req;
101+
102+ for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; it++) {
103+ strcpy(ifr.ifr_name, it->ifr_name);
104+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
105+ if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
106+ if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
107+ success = TRUE;
108+ break;
109+ }
110+ }
111+ }
112+ }
113+
114+ if (!success)
115+ return;
116+
117+ *res = malloc (18);
118+ sprintf (*res, "%02x:%02x:%02x:%02x:%02x:%02x",
119+ (unsigned char) ifr.ifr_hwaddr.sa_data[0],
120+ (unsigned char) ifr.ifr_hwaddr.sa_data[1],
121+ (unsigned char) ifr.ifr_hwaddr.sa_data[2],
122+ (unsigned char) ifr.ifr_hwaddr.sa_data[3],
123+ (unsigned char) ifr.ifr_hwaddr.sa_data[4],
124+ (unsigned char) ifr.ifr_hwaddr.sa_data[5]);
125+}
126+
127+void
128+identifier_get_system_uuid (char** res, GError** error)
129+{
130+ int fp;
131+
132+ fp = open ("/sys/class/dmi/id/product_uuid", O_RDONLY);
133+ if (fp < 0) {
134+ g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
135+ "Could not open the product uuid file.");
136+ return;
137+ }
138+ *res = malloc (37);
139+ if (read (fp, *res, 36) == 36)
140+ (*res)[36] = '\0';
141+ else
142+ g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
143+ "Got an unexpected length reading the product_uuid.");
144+ close (fp);
145+}
146+
147+void
148+identifier_sha512 (char* source, char* res, GError** error)
149+{
150+ int md_len;
151+ gcry_md_hd_t sha512 = NULL;
152+ unsigned char* id = NULL;
153+
154+ if (!gcry_check_version (GCRYPT_VERSION)) {
155+ g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
156+ "libcrypt version mismatch.");
157+ return;
158+ }
159+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
160+ md_len = gcry_md_get_algo_dlen(GCRY_MD_SHA512);
161+ if (md_len != HASHLEN / 2) {
162+ g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
163+ "Received an incorrect size for the SHA512 message digest");
164+ return;
165+ }
166+ if (gcry_md_open (&sha512, GCRY_MD_SHA512, 0) || sha512 == NULL) {
167+ g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
168+ "Failed to create a SHA512 message digest for the product_uuid.");
169+ return;
170+ }
171+ gcry_md_write (sha512, source, strlen (source));
172+ gcry_md_final (sha512);
173+ id = gcry_md_read (sha512, GCRY_MD_SHA512);
174+ if (id == NULL) {
175+ g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
176+ "Failed to read the SHA512 message digest for the product_uuid.");
177+ gcry_md_close (sha512);
178+ return;
179+ }
180+ hex_to_char (res, (const char*)id, md_len);
181+ gcry_md_close (sha512);
182+}
183
184=== added file 'src/identifier.h'
185--- src/identifier.h 1970-01-01 00:00:00 +0000
186+++ src/identifier.h 2012-05-15 16:54:18 +0000
187@@ -0,0 +1,5 @@
188+void identifier_get_mac_address (char** res, GError** error);
189+void identifier_get_system_uuid (char** res, GError** error);
190+void identifier_sha512 (char* source, char* res, GError** error);
191+void hex_to_char (char* buf, const char *str, int len);
192+#define HASHLEN 128
193
194=== modified file 'src/tests/Makefile'
195--- src/tests/Makefile 2012-04-10 16:42:07 +0000
196+++ src/tests/Makefile 2012-05-15 16:54:18 +0000
197@@ -1,11 +1,14 @@
198 VERSION=$(shell dpkg-parsechangelog | grep ^Version: | cut -d' ' -f2)
199 CFLAGS=$(shell pkg-config --cflags gio-2.0 glib-2.0 libcurl) \
200+ $(shell libgcrypt-config --cflags) \
201 -g -I../../lib -I.. -DVERSION=\"$(VERSION)\" -DTEST -DTEST_DIR=\"$(CURDIR)\" -Wall
202-LIBS=$(shell pkg-config --libs gio-2.0 glib-2.0 libcurl) -lcap
203+LIBS=$(shell pkg-config --libs gio-2.0 glib-2.0 libcurl) -lcap \
204+ $(shell libgcrypt-config --libs)
205
206 test_parse_report_SOURCES=test_parse_report.c \
207 ../whoopsie.c \
208 ../utils.c \
209+ ../identifier.c \
210 ../../lib/bson/bson.c \
211 ../../lib/bson/encoding.c \
212 ../../lib/bson/numbers.c
213@@ -23,11 +26,16 @@
214 test_monitor_EXECUTABLE=test_monitor
215 test_monitor_OBJECTS=$(test_monitor_SOURCES:.c=.test.o)
216
217+test_identifier_SOURCES=test_identifier.c \
218+ ../identifier.c
219+test_identifier_EXECUTABLE=test_identifier
220+test_identifier_OBJECTS=$(test_identifier_SOURCES:.c=.test.o)
221+
222 .PHONY: all clean check
223
224 all: check
225
226-check: $(test_parse_report_EXECUTABLE) $(test_utils_EXECUTABLE) $(test_monitor_EXECUTABLE)
227+check: $(test_parse_report_EXECUTABLE) $(test_utils_EXECUTABLE) $(test_monitor_EXECUTABLE) $(test_identifier_EXECUTABLE)
228 $(foreach p, $^, ./$p -k;)
229
230 $(test_parse_report_EXECUTABLE): $(test_parse_report_OBJECTS)
231@@ -36,6 +44,8 @@
232 c99 $^ $(LIBS) -o $@
233 $(test_monitor_EXECUTABLE): $(test_monitor_OBJECTS)
234 c99 $^ $(LIBS) -o $@
235+$(test_identifier_EXECUTABLE): $(test_identifier_OBJECTS)
236+ c99 $^ $(LIBS) -o $@
237
238 test_parse_report_coverage: $(test_parse_report_OBJECTS:.test.o=.coverage.o)
239 c99 $^ $(LIBS) -lgcov -o $@
240@@ -43,7 +53,9 @@
241 c99 $^ $(LIBS) -lgcov -o $@
242 test_monitor_coverage: $(test_monitor_OBJECTS:.test.o=.coverage.o)
243 c99 $^ $(LIBS) -lgcov -o $@
244-coverage: test_parse_report_coverage test_utils_coverage test_monitor_coverage
245+test_identifier_coverage: $(test_identifier_OBJECTS:.test.o=.coverage.o)
246+ c99 $^ $(LIBS) -lgcov -o $@
247+coverage: test_parse_report_coverage test_utils_coverage test_monitor_coverage test_identifier_coverage
248 $(foreach p, $^, ./$p -k;)
249 $(foreach p, $(wildcard ../*.c), gcov $p -o $(p:.c=.coverage.o);)
250
251@@ -54,8 +66,11 @@
252 $(test_utils_EXECUTABLE) \
253 $(test_monitor_OBJECTS) \
254 $(test_monitor_EXECUTABLE) \
255+ $(test_identifier_OBJECTS) \
256+ $(test_identifier_EXECUTABLE) \
257 test_parse_report_coverage \
258 test_utils_coverage \
259+ test_identifier_coverage \
260 coverage
261 find ../.. \( -name '*.coverage.o' -o \
262 -name '*.gcda' -o \
263
264=== added file 'src/tests/test_identifier.c'
265--- src/tests/test_identifier.c 1970-01-01 00:00:00 +0000
266+++ src/tests/test_identifier.c 2012-05-15 16:54:18 +0000
267@@ -0,0 +1,125 @@
268+/* whoopsie
269+ *
270+ * Copyright © 2011-2012 Canonical Ltd.
271+ * Author: Evan Dandrea <evan.dandrea@canonical.com>
272+ *
273+ * This program is free software: you can redistribute it and/or modify
274+ * it under the terms of the GNU General Public License as published by
275+ * the Free Software Foundation; version 3 of the License.
276+ *
277+ * This program is distributed in the hope that it will be useful,
278+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
279+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
280+ * GNU General Public License for more details.
281+ *
282+ * You should have received a copy of the GNU General Public License
283+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
284+ */
285+#define _XOPEN_SOURCE
286+#define _GNU_SOURCE
287+
288+#include <glib.h>
289+#include <glib-object.h>
290+#include <sys/types.h>
291+#include <sys/stat.h>
292+#include <fcntl.h>
293+
294+#include "../src/identifier.h"
295+
296+static void
297+test_hex_to_char (void)
298+{
299+ char buf[9];
300+ hex_to_char (buf, "\xFF\xFF\xFF\xFF", 4);
301+ g_assert_cmpstr (buf, ==, "ffffffff");
302+
303+}
304+
305+static void
306+test_get_mac_address (void)
307+{
308+ char* res = NULL;
309+ GError* error = NULL;
310+ int fp;
311+ char buf[18];
312+
313+ identifier_get_mac_address (&res, &error);
314+ g_assert (res != NULL);
315+ fp = open ("/sys/class/net/eth0/address", O_RDONLY);
316+ if (fp < 0) {
317+ g_print ("Could not open /sys/class/net/eth0/address\n");
318+ g_test_fail ();
319+ goto out;
320+ }
321+ if (read (fp, buf, 17) < 17) {
322+ g_print ("Could not read /sys/class/net/eth0/address\n");
323+ g_test_fail ();
324+ goto out;
325+ }
326+ buf[17] = '\0';
327+ if (g_strcmp0 (buf, res) != 0) {
328+ g_print ("MAC address does not match value in /sys\n");
329+ g_test_fail ();
330+ }
331+out:
332+ if (fp >= 0)
333+ close (fp);
334+}
335+static void
336+test_get_system_uuid (void)
337+{
338+ /* DEADBEEF-1234-1234-1234-DEADBEEF1234 */
339+ char* res = NULL;
340+ identifier_get_system_uuid (&res, NULL);
341+ if (getuid () != 0) {
342+ g_print ("Need root to run this complete test: ");
343+ return;
344+ }
345+
346+ if (res == NULL)
347+ goto out;
348+
349+ if (strlen (res) != 36)
350+ goto out;
351+
352+ if ((res[8] != '-' || res[13] != '-') ||
353+ (res[18] != '-' || res[23] != '-'))
354+ goto out;
355+
356+ return;
357+
358+out:
359+ g_test_fail ();
360+ return;
361+}
362+
363+test_sha512 (void)
364+{
365+ char res[HASHLEN + 1] = {0};
366+ // "foo" -> sha512
367+ const char* expected = "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382"
368+ "d624741d0dc6638326e282c41be5e4254d8820772c5518a"
369+ "2c5a8c0c7f7eda19594a7eb539453e1ed7";
370+ identifier_sha512 ("foo", res, NULL);
371+ //if (strcmp (res, expected) != 0)
372+ // g_test_fail ();
373+}
374+
375+int
376+main (int argc, char** argv)
377+{
378+ g_type_init ();
379+ g_test_init (&argc, &argv, NULL);
380+
381+ /* This wont work when running under fakeroot. */
382+ if (!getenv ("FAKEROOTKEY"))
383+ g_test_add_func ("/whoopsie/get-system-uuid", test_get_system_uuid);
384+ g_test_add_func ("/whoopsie/hex-to-char", test_hex_to_char);
385+ g_test_add_func ("/whoopsie/get-mac-address", test_get_mac_address);
386+ g_test_add_func ("/whoopsie/sha512", test_sha512);
387+
388+ /* Do not consider warnings to be fatal. */
389+ g_log_set_always_fatal (G_LOG_FATAL_MASK);
390+
391+ return g_test_run ();
392+}
393
394=== modified file 'src/tests/test_parse_report.c'
395--- src/tests/test_parse_report.c 2012-03-23 12:38:51 +0000
396+++ src/tests/test_parse_report.c 2012-05-15 16:54:18 +0000
397@@ -84,34 +84,6 @@
398 }
399
400 static void
401-test_hex_to_char (void)
402-{
403- char buf[9];
404- hex_to_char (buf, "\xFF\xFF\xFF\xFF", 4);
405- g_assert_cmpstr (buf, ==, "ffffffff");
406-
407-}
408-
409-static void
410-test_get_system_uuid (void)
411-{
412- /* DEADBEEF-1234-1234-1234-DEADBEEF1234 */
413- char res[129] = {0};
414- get_system_uuid (res, NULL);
415- if (getuid () == 0) {
416- if (*res == '\0')
417- g_test_fail ();
418- } else {
419- g_print ("Need root to run this complete test: ");
420- }
421- memset (res, 0, 129);
422- seteuid (1000);
423- get_system_uuid (res, NULL);
424- g_assert (*res == '\0');
425- seteuid (0);
426-}
427-
428-static void
429 test_get_crash_db_url (void)
430 {
431 char* url = NULL;
432@@ -365,11 +337,7 @@
433 g_test_init (&argc, &argv, NULL);
434
435 g_test_add_func ("/whoopsie/parse-report", test_parse_report);
436- /* This wont work when running under fakeroot. */
437- if (!getenv ("FAKEROOTKEY"))
438- g_test_add_func ("/whoopsie/get-system-uuid", test_get_system_uuid);
439 g_test_add_func ("/whoopsie/get-crash-db-url", test_get_crash_db_url);
440- g_test_add_func ("/whoopsie/hex-to-char", test_hex_to_char);
441 g_test_add_func ("/whoopsie/key-embedded-nul", test_key_embedded_nul);
442 g_test_add_func ("/whoopsie/value-embedded-nul", test_value_embedded_nul);
443 g_test_add_func ("/whoopsie/embedded-carriage-return",
444
445=== modified file 'src/whoopsie.c'
446--- src/whoopsie.c 2012-05-03 14:49:58 +0000
447+++ src/whoopsie.c 2012-05-15 16:54:18 +0000
448@@ -32,7 +32,6 @@
449 #include <sys/file.h>
450 #include <errno.h>
451 #include <signal.h>
452-#include <gcrypt.h>
453 #include <pwd.h>
454 #include <grp.h>
455 #include <sys/capability.h>
456@@ -46,6 +45,7 @@
457 #include "utils.h"
458 #include "connectivity.h"
459 #include "monitor.h"
460+#include "identifier.h"
461
462 /* The length of time to wait before processing outstanding crashes, in seconds
463 */
464@@ -61,7 +61,6 @@
465 static char* crash_db_url = NULL;
466
467 /* The system UUID, taken from the DMI tables and SHA-512 hashed */
468-#define HASHLEN 128
469 static char sha512_system_uuid[HASHLEN + 1] = {0};
470
471 /* The URL for sending the initial crash report */
472@@ -723,75 +722,6 @@
473 sigaction (SIGINT, &action, NULL);
474 }
475
476-void
477-hex_to_char (char* buf, const unsigned char *str, int len)
478-{
479- char* p = NULL;
480- int i = 0;
481-
482- p = buf;
483- for (i = 0; i < len; i++) {
484- snprintf(p, 3, "%02x", str[i]);
485- p += 2;
486- }
487- buf[2*len] = 0;
488-}
489-
490-void
491-get_system_uuid (char* res, GError** error)
492-{
493- int fp;
494- char system_uuid[37] = {0};
495- int md_len;
496- unsigned char* id = NULL;
497- gcry_md_hd_t sha512 = NULL;
498-
499- fp = open ("/sys/class/dmi/id/product_uuid", O_RDONLY);
500- if (fp < 0) {
501- g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
502- "Could not open the product uuid file.");
503- return;
504- }
505- if (read (fp, system_uuid, 36) == 36) {
506- system_uuid[36] = '\0';
507- close (fp);
508- } else {
509- close (fp);
510- g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
511- "Got an unexpected length reading the product_uuid.");
512- return;
513- }
514-
515- if (!gcry_check_version (GCRYPT_VERSION)) {
516- g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
517- "libcrypt version mismatch.");
518- return;
519- }
520- gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
521- md_len = gcry_md_get_algo_dlen(GCRY_MD_SHA512);
522- if (md_len != HASHLEN / 2) {
523- g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
524- "Received an incorrect size for the SHA512 message digest");
525- return;
526- }
527- if (gcry_md_open (&sha512, GCRY_MD_SHA512, 0) || sha512 == NULL) {
528- g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
529- "Failed to create a SHA512 message digest for the product_uuid.");
530- return;
531- }
532- gcry_md_write (sha512, system_uuid, 36);
533- gcry_md_final (sha512);
534- id = gcry_md_read (sha512, GCRY_MD_SHA512);
535- if (id == NULL) {
536- g_set_error (error, g_quark_from_static_string ("whoopsie-quark"), 0,
537- "Failed to read the SHA512 message digest for the product_uuid.");
538- gcry_md_close (sha512);
539- return;
540- }
541- hex_to_char (res, id, md_len);
542- gcry_md_close (sha512);
543-}
544-
545 char*
546 get_crash_db_url (void)
547 {
548@@ -883,6 +813,8 @@
549 main (int argc, char** argv)
550 {
551 GError* err = NULL;
552+ char* system_uuid = NULL;
553+ char* mac_address = NULL;
554
555 setup_signals ();
556 parse_arguments (&argc, &argv);
557@@ -891,12 +823,29 @@
558 g_print ("Could not get crash database location.\n");
559 exit (EXIT_FAILURE);
560 }
561- get_system_uuid (sha512_system_uuid, &err);
562+
563+ identifier_get_system_uuid (&system_uuid, &err);
564 if (err) {
565 g_print ("%s\n", err->message);
566 g_error_free (err);
567 err = NULL;
568 }
569+ if (system_uuid) {
570+ identifier_sha512 (system_uuid, sha512_system_uuid, NULL);
571+ free (system_uuid);
572+ } else {
573+ identifier_get_mac_address (&mac_address, &err);
574+ if (err) {
575+ g_print ("%s\n", err->message);
576+ g_error_free (err);
577+ err = NULL;
578+ }
579+ if (mac_address) {
580+ identifier_sha512 (mac_address, sha512_system_uuid, NULL);
581+ free (mac_address);
582+ }
583+ }
584+
585 if (*sha512_system_uuid != '\0') {
586 if (asprintf (&crash_db_submit_url, "%s/%s",
587 crash_db_url, sha512_system_uuid) < 0)
588
589=== modified file 'src/whoopsie.h'
590--- src/whoopsie.h 2012-03-14 11:54:40 +0000
591+++ src/whoopsie.h 2012-05-15 16:54:18 +0000
592@@ -20,7 +20,6 @@
593 #define WHOOPSIE_H
594
595 GHashTable* parse_report (const char* report_path, gboolean full_report, GError** error);
596-void hex_to_char (char* buf, const unsigned char *str, int len);
597 void get_system_uuid (char* res, GError** error);
598 char* get_crash_db_url (void);
599 void destroy_key_and_value (gpointer key, gpointer value, gpointer user_data);

Subscribers

People subscribed via source and target branches

to all changes:
to status/vote changes: