#include "barev_avatar.h" #include #include #include #include "barev_sha1.h" static const char b64tab[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static void scpy(char *d, size_t n, const char *s) { size_t i; if (!d || n == 0) return; if (!s) { d[0] = '\0'; return; } for (i = 0; i + 1 < n && s[i]; ++i) d[i] = s[i]; d[i] = '\0'; } static int detect_mime(const char *p, char *out, size_t n) { const char *ext = strrchr(p, '.'); if (!ext) { scpy(out, n, "application/octet-stream"); return 1; } if (strcmp(ext, ".png") == 0) scpy(out, n, "image/png"); else if (strcmp(ext, ".jpg") == 0 || strcmp(ext, ".jpeg") == 0) scpy(out, n, "image/jpeg"); else if (strcmp(ext, ".gif") == 0) scpy(out, n, "image/gif"); else scpy(out, n, "application/octet-stream"); return 1; } static char *b64_encode(const unsigned char *in, size_t n) { size_t out_n = ((n + 2) / 3) * 4; size_t i, o = 0; char *out = (char *)malloc(out_n + 1); if (!out) return 0; for (i = 0; i < n; i += 3) { unsigned a = in[i]; unsigned b = (i + 1 < n) ? in[i + 1] : 0; unsigned c = (i + 2 < n) ? in[i + 2] : 0; unsigned t = (a << 16) | (b << 8) | c; out[o++] = b64tab[(t >> 18) & 63]; out[o++] = b64tab[(t >> 12) & 63]; out[o++] = (i + 1 < n) ? b64tab[(t >> 6) & 63] : '='; out[o++] = (i + 2 < n) ? b64tab[t & 63] : '='; } out[o] = '\0'; return out; } void barev_avatar_init(barev_avatar_mgr_t *m) { if (m) memset(m, 0, sizeof(*m)); } void barev_avatar_free(barev_avatar_mgr_t *m) { if (!m) return; free(m->my_avatar_b64); m->my_avatar_b64 = 0; } void barev_avatar_clear_my(barev_avatar_mgr_t *m) { if (!m) return; free(m->my_avatar_b64); m->my_avatar_b64 = 0; m->my_avatar_path[0] = '\0'; m->my_avatar_hash[0] = '\0'; m->my_avatar_mime[0] = '\0'; } int barev_avatar_load_my(barev_avatar_mgr_t *m, const char *path) { FILE *f; unsigned char *buf; long n; if (!m || !path) return 0; f = fopen(path, "rb"); if (!f) return 0; if (fseek(f, 0, SEEK_END) != 0) { fclose(f); return 0; } n = ftell(f); if (n < 0) { fclose(f); return 0; } if (fseek(f, 0, SEEK_SET) != 0) { fclose(f); return 0; } buf = (unsigned char *)malloc((size_t)n); if (!buf) { fclose(f); return 0; } if ((long)fread(buf, 1, (size_t)n, f) != n) { free(buf); fclose(f); return 0; } fclose(f); barev_avatar_clear_my(m); m->my_avatar_b64 = b64_encode(buf, (size_t)n); if (!m->my_avatar_b64) { free(buf); return 0; } detect_mime(path, m->my_avatar_mime, sizeof(m->my_avatar_mime)); scpy(m->my_avatar_path, sizeof(m->my_avatar_path), path); barev_sha1_hex((const unsigned char *)m->my_avatar_b64, strlen(m->my_avatar_b64), m->my_avatar_hash); free(buf); return 1; } int barev_avatar_generate_vcard(const barev_avatar_mgr_t *m, char *out, size_t out_n) { int w; if (!m || !out || out_n == 0) return 0; if (!m->my_avatar_b64 || !m->my_avatar_b64[0]) { w = snprintf(out, out_n, ""); } else { w = snprintf(out, out_n, "%s%s", m->my_avatar_mime, m->my_avatar_b64); } return (w > 0 && (size_t)w < out_n) ? 1 : 0; }