]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/journal/journal-qrcode.c
libudev: hide definition of struct udev_list from other libudev components
[thirdparty/systemd.git] / src / journal / journal-qrcode.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
f6a971bc 2
f6a971bc 3#include <errno.h>
f6a971bc 4#include <qrencode.h>
cf0fbc49
TA
5#include <stdbool.h>
6#include <stdio.h>
7#include <stdlib.h>
f6a971bc 8
2fe21124 9#include "fileio.h"
f6a971bc 10#include "journal-qrcode.h"
afc5fc1f 11#include "macro.h"
f6a971bc
LP
12
13#define WHITE_ON_BLACK "\033[40;37;1m"
14#define NORMAL "\033[0m"
15
16static void print_border(FILE *output, unsigned width) {
17 unsigned x, y;
18
19 /* Four rows of border */
20 for (y = 0; y < 4; y += 2) {
21 fputs(WHITE_ON_BLACK, output);
22
23 for (x = 0; x < 4 + width + 4; x++)
24 fputs("\342\226\210", output);
25
26 fputs(NORMAL "\n", output);
27 }
28}
29
92221ed7
LP
30int print_qr_code(
31 FILE *output,
32 const void *seed,
33 size_t seed_size,
34 uint64_t start,
35 uint64_t interval,
36 const char *hn,
37 sd_id128_t machine) {
38
f6a971bc
LP
39 FILE *f;
40 char *url = NULL;
41 size_t url_size = 0, i;
42 QRcode* qr;
43 unsigned x, y;
44
45 assert(seed);
46 assert(seed_size > 0);
47
2fe21124 48 f = open_memstream_unlocked(&url, &url_size);
f6a971bc
LP
49 if (!f)
50 return -ENOMEM;
51
0d536673 52 fputs("fss://", f);
f6a971bc
LP
53
54 for (i = 0; i < seed_size; i++) {
55 if (i > 0 && i % 3 == 0)
0d536673 56 fputc('-', f);
f6a971bc
LP
57 fprintf(f, "%02x", ((uint8_t*) seed)[i]);
58 }
59
507f22bd
ZJS
60 fprintf(f, "/%"PRIx64"-%"PRIx64"?machine=" SD_ID128_FORMAT_STR,
61 start,
62 interval,
92221ed7 63 SD_ID128_FORMAT_VAL(machine));
f6a971bc
LP
64
65 if (hn)
92221ed7 66 fprintf(f, ";hostname=%s", hn);
f6a971bc
LP
67
68 if (ferror(f)) {
69 fclose(f);
70 free(url);
71 return -ENOMEM;
72 }
73
74 fclose(f);
75
76 qr = QRcode_encodeString(url, 0, QR_ECLEVEL_L, QR_MODE_8, 1);
77 free(url);
78
79 if (!qr)
80 return -ENOMEM;
81
82 print_border(output, qr->width);
83
84 for (y = 0; y < (unsigned) qr->width; y += 2) {
85 const uint8_t *row1, *row2;
86
87 row1 = qr->data + qr->width * y;
88 row2 = row1 + qr->width;
89
90 fputs(WHITE_ON_BLACK, output);
91 for (x = 0; x < 4; x++)
92 fputs("\342\226\210", output);
93
94 for (x = 0; x < (unsigned) qr->width; x ++) {
95 bool a, b;
96
97 a = row1[x] & 1;
98 b = (y+1) < (unsigned) qr->width ? (row2[x] & 1) : false;
99
100 if (a && b)
101 fputc(' ', output);
102 else if (a)
103 fputs("\342\226\204", output);
104 else if (b)
105 fputs("\342\226\200", output);
106 else
107 fputs("\342\226\210", output);
108 }
109
110 for (x = 0; x < 4; x++)
111 fputs("\342\226\210", output);
112 fputs(NORMAL "\n", output);
113 }
114
115 print_border(output, qr->width);
116
117 QRcode_free(qr);
118 return 0;
119}