1 /* -*- c-basic-offset:2; tab-width:2; indent-tabs-mode:nil -*- */
2 
3 #include "bl_util.h"
4 
5 #include <string.h>
6 #include <stdlib.h> /* getenv */
7 #ifdef HAVE_GETPWUID
8 #include <pwd.h>
9 #endif
10 
11 #include "bl_unistd.h" /* bl_getuid */
12 #include "bl_debug.h"
13 
14 /* --- static functions --- */
15 
hex_to_int(char c)16 static int hex_to_int(char c) {
17   if ('0' <= c && c <= '9') {
18     return c - '0';
19   } else {
20     c &= 0xdf;
21 
22     if ('A' <= c && c <= 'F') {
23       return c - 'A' + 10;
24     }
25   }
26 
27   return -1;
28 }
29 
get_pc(int h,u_int32_t m1,u_int32_t m2)30 static inline int get_pc(int h, u_int32_t m1, u_int32_t m2) {
31   if (h < 60) {
32     return m1 + (m2 - m1) * h / 60;
33   } else if (h < 180) {
34     return m2;
35   } else if (h < 240) {
36     return m1 + (m2 - m1) * (240 - h) / 60;
37   } else {
38     return m1;
39   }
40 }
41 
42 /* --- global functions --- */
43 
bl_hex_decode(char * decoded,const char * encoded,size_t e_len)44 size_t bl_hex_decode(char *decoded, const char *encoded, size_t e_len) {
45   size_t pos;
46   char *p = decoded;
47 
48   for (pos = 0; e_len > pos + 1; pos += 2) {
49     int i1 = hex_to_int(encoded[pos]);
50     int i2 = hex_to_int(encoded[pos + 1]);
51 
52     if (i1 < 0 || i2 < 0) {
53       break;
54     }
55 
56     *(p++) = i1 * 16 + i2;
57   }
58 
59   return (p - decoded);
60 }
61 
62 
bl_hex_encode(char * encoded,const char * decoded,size_t d_len)63 size_t bl_hex_encode(char *encoded, const char *decoded, size_t d_len) {
64   size_t pos;
65   char *p = encoded;
66 
67   for (pos = 0; d_len > pos; pos ++) {
68     int h1 = (decoded[pos] >> 4) & 0xf;
69     int h2 = decoded[pos] & 0xf;
70 
71     *(p++) = (h1 > 9) ? ('a' + h1 - 10) : ('0' + h1);
72     *(p++) = (h2 > 9) ? ('a' + h2 - 10) : ('0' + h2);
73   }
74 
75   return (p - encoded);
76 }
77 
bl_base64_decode(char * decoded,const char * encoded,size_t e_len)78 size_t bl_base64_decode(char *decoded, const char *encoded, size_t e_len) {
79   size_t d_pos;
80   size_t e_pos;
81   /* ASCII -> Base64 order */
82   int8_t conv_tbl[] = {/* 0x2b - */
83                        62, -1, -1, -1, 63,
84                        /* 0x30 - */
85                        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1,
86                        /* 0x40 - */
87                        -1, 0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14,
88                        /* 0x50 - */
89                        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
90                        /* 0x60 - */
91                        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
92                        /* 0x70 - 7a */
93                        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
94 
95   d_pos = e_pos = 0;
96 
97   while (e_len >= e_pos + 4) {
98     size_t count;
99     int8_t bytes[4];
100 
101     for (count = 0; count < 4; e_pos++) {
102       if (encoded[e_pos] < 0x2b || 0x7a < encoded[e_pos] ||
103           (bytes[count] = conv_tbl[encoded[e_pos] - 0x2b]) == -1) {
104 #ifdef DEBUG
105         if (encoded[e_pos] != '\x0d' && encoded[e_pos] != '\x0a') {
106           bl_debug_printf(BL_DEBUG_TAG " ignoring %c in base64\n", encoded[e_pos]);
107         }
108 #endif
109 
110         if (e_len <= e_pos + 1) {
111           goto end;
112         }
113       } else {
114         count++;
115       }
116     }
117 
118     decoded[d_pos++] = (((bytes[0] << 2) & 0xfc) | ((bytes[1] >> 4) & 0x3));
119 
120     if (bytes[2] != -2) {
121       decoded[d_pos++] = (((bytes[1] << 4) & 0xf0) | ((bytes[2] >> 2) & 0xf));
122     } else {
123       break;
124     }
125 
126     if (bytes[3] != -2) {
127       decoded[d_pos++] = (((bytes[2] << 6) & 0xc0) | (bytes[3] & 0x3f));
128     } else {
129       break;
130     }
131   }
132 
133 end:
134 #ifdef DEBUG
135   decoded[d_pos] = '\0';
136   if (strlen(encoded) < 1000) {
137     bl_debug_printf(BL_DEBUG_TAG " Base64 Decode %s => %s\n", encoded, decoded);
138   }
139 #endif
140 
141   return d_pos;
142 }
143 
bl_hls_to_rgb(int * r,int * g,int * b,int h,int l,int s)144 void bl_hls_to_rgb(int *r, int *g, int *b,
145                    int h /* 0-360 */, int l /* 0-100 */, int s /* 0-100 */) {
146   if (s == 0) {
147     *r = *g = *b = l * 255 / 100;
148   } else {
149     u_int32_t m1;
150     u_int32_t m2;
151 
152     if (l < 50) {
153       m2 = l * (100 + s);
154     } else {
155       m2 = (l + s) * 100 - l * s;
156     }
157     m1 = l * 200 - m2;
158 
159     *r = get_pc(h, m1, m2) * 255 / 10000;
160     if ((h -= 120) < 0) {
161       h += 360;
162     }
163     *g = get_pc(h, m1, m2) * 255 / 10000;
164     if ((h -= 120) < 0) {
165       h += 360;
166     }
167     *b = get_pc(h, m1, m2) * 255 / 10000;
168   }
169 }
170 
bl_rgb_to_hls(int * h,int * l,int * s,int r,int g,int b)171 void bl_rgb_to_hls(int *h, int *l, int *s,
172                    int r /* 0-255 */, int g /* 0-255 */, int b /* 0-255 */) {
173   int max;
174   int min;
175 
176   if (r > g) {
177     if (g > b) {
178       /* r > g > b */
179       max = r;
180       min = b;
181     } else {
182       min = g;
183       if (r > b) {
184         /* r > b >= g */
185         max = r;
186       } else {
187         /* b >= r > g */
188         max = b;
189       }
190     }
191   } else if (b > g) {
192     /* b > g >= r */
193     max = b;
194     min = r;
195   } else {
196     max = g;
197     if (r > b) {
198       /* g >= r > b */
199       min = b;
200     } else {
201       /* g >= b >= r */
202       min = r;
203     }
204   }
205 
206   *l = (max + min) * 100 / 255 / 2;
207 
208   if (max == min) {
209     /* r == g == b */
210     *h = 0;
211     *s = 0;
212   } else {
213     if (max == r) {
214       *h = 60 * (g - b) / (max - min);
215     } else if (max == g) {
216       *h = 60 * (b - r) / (max - min) + 120;
217     } else /* if (max == b) */ {
218       *h = 60 * (r - g) / (max - min) + 240;
219     }
220 
221     if (*h < 0) {
222       *h += 360;
223     }
224 
225     if (max + min < 255) {
226       *s = (max - min) * 100 / (max + min);
227     } else {
228       *s = (max - min) * 100 / (510 - max - min);
229     }
230   }
231 }
232 
bl_get_user_name(void)233 const char *bl_get_user_name(void) {
234   char *user;
235 
236 #ifdef HAVE_WINDOWS_H
237   if (!(user = getenv("USERNAME")))
238 #endif
239   {
240     if (!(user = getenv("USER"))) {
241       user = getenv("LOGNAME");
242 
243 #ifdef HAVE_GETPWUID
244       if (!user) {
245         struct passwd *p;
246 
247         if ((p = getpwuid(bl_getuid()))) {
248           user = p->pw_name;
249         }
250       }
251 #endif
252     }
253   }
254 
255   return user;
256 }
257