const char *pkguinf_get_changelog(struct pkguinf *inf, time_t since) { tn_array *entries; tn_buf *nbuf; char *changelog = NULL; int i; if (!since) return pkguinf_get(inf, PKGUINF_CHANGELOG); if ((entries = get_parsed_changelog(inf, since)) == NULL) return pkguinf_get(inf, PKGUINF_CHANGELOG); nbuf = n_buf_new(1024 * 4); for (i=0; i < n_array_size(entries); i++) { struct changelog_ent *ent = n_array_nth(entries, i); n_buf_printf(nbuf, "%s\n", ent->info); n_buf_printf(nbuf, "%s\n", ent->message); } n_array_free(entries); changelog = na_strdup(inf->_na, n_buf_ptr(nbuf), n_buf_size(nbuf)); n_buf_free(nbuf); return changelog; }
static char *do_load_changelog_from_rpmhdr(tn_alloc *na, void *hdr) { struct rpmhdr_ent e_name, e_time, e_text; char **names = NULL, **texts = NULL, *changelog = NULL; uint32_t *times = NULL; tn_buf *nbuf = NULL; int i; if (!pm_rpmhdr_ent_get(&e_name, hdr, RPMTAG_CHANGELOGNAME)) return NULL; if (!pm_rpmhdr_ent_get(&e_time, hdr, RPMTAG_CHANGELOGTIME)) { pm_rpmhdr_ent_free(&e_name); return NULL; } if (!pm_rpmhdr_ent_get(&e_text, hdr, RPMTAG_CHANGELOGTEXT)) { pm_rpmhdr_ent_free(&e_name); pm_rpmhdr_ent_free(&e_time); return NULL; } names = pm_rpmhdr_ent_as_strarr(&e_name); times = pm_rpmhdr_ent_as_intarr(&e_time); texts = pm_rpmhdr_ent_as_strarr(&e_text); if (e_name.cnt == 1 && strstr(names[0], "PLD")) { changelog = prepare_pld_changelog(na, texts[0]); goto l_end; } nbuf = n_buf_new(1024); for (i=0; i < e_name.cnt; i++) { char ts[32]; time_t t = times[i]; strftime(ts, sizeof(ts), "%Y-%m-%d %H:%M:%S", gmtime((time_t*)&t)); n_buf_printf(nbuf, "* %s %s\n", ts, names[i]); n_buf_printf(nbuf, "%s\n\n", texts[i]); } changelog = na_strdup(na, n_buf_ptr(nbuf), n_buf_size(nbuf)); n_buf_free(nbuf); l_end: pm_rpmhdr_ent_free(&e_name); pm_rpmhdr_ent_free(&e_time); pm_rpmhdr_ent_free(&e_text); return changelog; }
static tn_array *parse_changelog(tn_alloc *na, tn_array *lines) { struct changelog_ent *ent = NULL; int i, max_MESSAGE = 1024; tn_array *entries; tn_buf *logmsg; entries = n_array_new(8, NULL, (tn_fn_cmp)changelog_ent_cmp); logmsg = n_buf_new(1024); for (i = 0; i < n_array_size(lines); i++) { char *line = n_array_nth(lines, i); if (*line == '*') { char *ts; if (ent != NULL) { n_snprintf(ent->message, max_MESSAGE, "%s", n_buf_ptr(logmsg)); n_buf_clean(logmsg); n_array_push(entries, ent); ent = NULL; } ent = na->na_malloc(na, sizeof(*ent) + max_MESSAGE); memset(ent, 0, sizeof(*ent)); ent->info = na_strdup(na, line, strlen(line)); ent->message[0] = '\0'; //* [rREV] YYYY-MM-DD HH:MM:SS rest ts = strchr(line, ' '); while (*ts && isspace(*ts)) ts++; if (ts && *ts == 'r') ts = strchr(ts, ' '); if (ts) { while (*ts && isspace(*ts)) ts++; if (ts) ent->ts = parse_datetime(ts); } continue; } if (ent) n_buf_printf(logmsg, "%s\n", line); } if (ent != NULL) { n_snprintf(ent->message, max_MESSAGE, "%s", n_buf_ptr(logmsg)); n_array_push(entries, ent); } n_buf_free(logmsg); return entries; }
static size_t json_string_format(struct n_buf *nb, const char *s, void *data) { static char esc[] = { ['\0'] = '0', ['\a'] = 'a', ['\b'] = 'b', ['\t'] = 't', ['\n'] = 'n', ['\v'] = 'v', ['\f'] = 'f', ['\r'] = 'r', ['\"'] = '\"', ['\\'] = '\\', }; /* This is probably broken for UNICODE. */ size_t len = 0; len += n_buf_putc(nb, '\"'); for (; *s != 0; s++) { int c = *(const unsigned char *) s; if (!isascii(c)) { len += n_buf_printf(nb, "\\u%04x", (unsigned int) c); } else if (c < sizeof(esc) && esc[c] != 0) { len += n_buf_putc(nb, '\\'); len += n_buf_putc(nb, esc[c]); } else { len += n_buf_putc(nb, c); } } len += n_buf_putc(nb, '\"'); return len; }
int pkg_store(const struct pkg *pkg, tn_buf *nbuf, tn_array *depdirs, tn_array *exclpath, unsigned flags) { int ncaps; if ((flags & PKGSTORE_NOEVR) == 0) { n_buf_printf(nbuf, "N: %s\n", pkg->name); if (pkg->epoch) n_buf_printf(nbuf, "V: %d:%s-%s\n", pkg->epoch, pkg->ver, pkg->rel); else n_buf_printf(nbuf, "V: %s-%s\n", pkg->ver, pkg->rel); } if ((flags & PKGSTORE_NOARCH) == 0 && pkg->_arch) n_buf_printf(nbuf, "A: %s\n", pkg_arch(pkg)); if ((flags & PKGSTORE_NOOS) == 0 && pkg->_os) n_buf_printf(nbuf, "O: %s\n", pkg_os(pkg)); if (pkg->fn) n_buf_printf(nbuf, "%c: %s\n", PKG_STORETAG_FN, pkg->fn); if (pkg->srcfn) n_buf_printf(nbuf, "%c: %s\n", PKG_STORETAG_SRCFN, pkg->srcfn); else /* must store something, PKG_HAS_SRCFN */ n_buf_printf(nbuf, "%c: -\n", PKG_STORETAG_SRCFN); pkg_store_bintag(PKG_STORETAG_BINF, nbuf); pkg_store_fields(nbuf, pkg, flags); if (pkg->caps && n_array_size(pkg->caps)) pkg_store_caps(pkg, nbuf); if (pkg->reqs && (ncaps = capreq_arr_store_n(pkg->reqs))) { pkg_store_bintag(PKG_STORETAG_REQS, nbuf); capreq_arr_store(pkg->reqs, nbuf, ncaps); } if (pkg->sugs && (ncaps = capreq_arr_store_n(pkg->sugs))) { pkg_store_bintag(PKG_STORETAG_SUGS, nbuf); capreq_arr_store(pkg->sugs, nbuf, ncaps); } if (pkg->cnfls && (ncaps = capreq_arr_store_n(pkg->cnfls))) { pkg_store_bintag(PKG_STORETAG_CNFLS, nbuf); capreq_arr_store(pkg->cnfls, nbuf, ncaps); } //mem_info(-10, "before fl"); pkg_store_fl(pkg, nbuf, depdirs, exclpath, flags); //mem_info(-10, "after fl"); /* removed support for uinfo in main index, assert nobody try this */ n_assert(flags & PKGSTORE_NODESC); n_buf_printf(nbuf, "\n"); return n_buf_size(nbuf); }
static void pkg_store_fields(tn_buf *nbuf, const struct pkg *pkg, unsigned flags) { uint8_t n = 0, size8t; int size = 0; if (pkg->size) n++; if (pkg->fsize) n++; if (pkg->btime) n++; if (pkg->itime) n++; if (pkg->groupid) n++; if ((flags & PKGSTORE_RECNO) && pkg->recno) n++; if (pkg->fmtime) n++; if (pkg->color) n++; size = (sizeof(int32_t) + 1) * n; n_assert(size < UINT8_MAX); size8t = size; n_buf_write_uint8(nbuf, size8t); n_buf_write_uint8(nbuf, n); if (pkg->size) { n_buf_add_int8(nbuf, PKGFIELD_TAG_SIZE); n_buf_add_int32(nbuf, pkg->size); } if (pkg->fsize) { n_buf_add_int8(nbuf, PKGFIELD_TAG_FSIZE); n_buf_add_int32(nbuf, pkg->fsize); } if (pkg->btime) { n_buf_add_int8(nbuf, PKGFIELD_TAG_BTIME); n_buf_add_int32(nbuf, pkg->btime); } if (pkg->itime) { n_buf_add_int8(nbuf, PKGFIELD_TAG_ITIME); n_buf_add_int32(nbuf, pkg->itime); } if (pkg->groupid) { n_buf_add_int8(nbuf, PKGFIELD_TAG_GID); //printf("STORE gid %d %s\n", pkg->groupid, pkg_snprintf_s(pkg)); n_buf_add_int32(nbuf, pkg->groupid); } if ((flags & PKGSTORE_RECNO) && pkg->recno) { n_buf_add_int8(nbuf, PKGFIELD_TAG_RECNO); n_buf_add_int32(nbuf, pkg->recno); } if (pkg->fmtime) { n_buf_add_int8(nbuf, PKGFIELD_TAG_FMTIME); n_buf_add_int32(nbuf, pkg->fmtime); } if (pkg->color) { n_buf_add_int8(nbuf, PKGFIELD_TAG_COLOR); n_buf_add_int32(nbuf, pkg->color); } n_buf_printf(nbuf, "\n"); }
static size_t json_bool_format(struct n_buf *nb, int v, void *data) { return n_buf_printf(nb, v ? "true" : "false"); }
/* remove header; add '*'s; replace "Revision REV" with "rREV" */ static char *prepare_pld_changelog(tn_alloc *na, const char *changelog) { struct changelog_ent *ent = NULL; char *entmark = "Revision", *prepared_log; int i, started, max_MESSAGE = 1024, len; tn_array *entries, *lines; tn_buf *logmsg; lines = n_str_etokl_ext(changelog, "\n", "", "", '\\'); len = strlen(entmark); entries = n_array_new(8, NULL, (tn_fn_cmp)changelog_ent_cmp); logmsg = n_buf_new(1024); started = 0; for (i = 0; i < n_array_size(lines); i++) { char *line = n_array_nth(lines, i); if (strncmp(line, entmark, len) == 0) started = 1; if (!started) continue; if (strncmp(line, entmark, len) == 0) { char *tstr, *rev, info[80]; time_t ts; int n; if (ent != NULL) { n_snprintf(ent->message, max_MESSAGE, "%s", n_buf_ptr(logmsg)); n_buf_clean(logmsg); n_array_push(entries, ent); ent = NULL; } //Revision REV YYYY-MM-DD HH:MM:SS rest rev = line + len + 1; /* skip Revision */ while (*rev && isspace(*rev)) rev++; tstr = strchr(rev, ' '); if (tstr) { *tstr = '\0'; tstr++; while (*tstr && isspace(*tstr)) tstr++; } if (rev && tstr) { ts = parse_datetime(tstr); if (ts == 0) continue; } n = n_snprintf(info, sizeof(info), "* r%s %s", rev, tstr); ent = n_malloc(sizeof(*ent) + max_MESSAGE); memset(ent, 0, sizeof(*ent)); ent->info = n_strdupl(info, n); ent->message[0] = '\0'; continue; } if (ent) n_buf_printf(logmsg, "%s\n", line); } if (ent != NULL) { n_snprintf(ent->message, max_MESSAGE, "%s", n_buf_ptr(logmsg)); n_array_push(entries, ent); } n_array_free(lines); n_buf_clean(logmsg); /* shift && free entries cause ents are simply malloc()ed here */ while (n_array_size(entries)) { ent = n_array_shift(entries); n_buf_printf(logmsg, "%s\n", ent->info); n_buf_printf(logmsg, "%s\n", ent->message); } n_array_free(entries); prepared_log = na_strdup(na, n_buf_ptr(logmsg), n_buf_size(logmsg)); n_buf_free(logmsg); return prepared_log; }