static int write_cpio_entry(struct archive_conv *conv, const char *entryname) { off_t entry_size = archive_entry_size(conv->ae); off_t bytes_w = 0; size_t alloc_size = entry_size * 1.1; struct archive_line_reader reader = {}; _cleanup_free_ char *entry_data = NULL, *s = NULL, *line = NULL; /* be generous */ MALLOC(entry_data, alloc_size, return -1); MALLOC(line, MAX_LINE_SIZE, return -1); reader.line.base = line; /* discard the first line */ reader_getline(&reader, conv->in); while (reader_getline(&reader, conv->in) == ARCHIVE_OK) { /* ensure enough memory */ if (bytes_w + reader.line.size + 1 > alloc_size) { alloc_size *= 1.1; entry_data = realloc(entry_data, alloc_size); } /* do the copy, with a slash prepended */ entry_data[bytes_w++] = '/'; memcpy(&entry_data[bytes_w], reader.line.base, reader.line.size); bytes_w += reader.line.size; entry_data[bytes_w++] = '\n'; } /* adjust the entry size for removing the first line and adding slashes */ archive_entry_set_size(conv->ae, bytes_w); /* store the metadata as simply $pkgname-$pkgver-$pkgrel */ s = strdup(entryname); *(strrchr(s, '/')) = '\0'; archive_entry_update_pathname_utf8(conv->ae, s); if (archive_write_header(conv->out, conv->ae) != ARCHIVE_OK) { fprintf(stderr, "error: failed to write entry header: %s/%s: %s\n", conv->reponame, archive_entry_pathname(conv->ae), strerror(errno)); return -errno; } if (archive_write_data(conv->out, entry_data, bytes_w) != bytes_w) { fprintf(stderr, "error: failed to write entry: %s/%s: %s\n", conv->reponame, archive_entry_pathname(conv->ae), strerror(errno)); return -errno; } return 0; }
/* ** line1, ... = buffer:getline(num) ** ** content will be shifted */ static int lbuffer_getline(lua_State *L) { Buffer *buffer = buffer_lcheck(L, 1); size_t num = (size_t)luaL_optint(L, 2, 1); Reader rd; reader_init(&rd, buffer->data, buffer->datasiz); for (size_t i = 0; i < num ; i++) { size_t len; const char *str = reader_getline(&rd, &len); if (str != NULL) lua_pushlstring(L, str, len); else lua_pushnil(L); } buffer_shift(buffer, (size_t)(rd.data - rd.mem)); return (int)num; }
static int list_metafile(const char *repo, struct pkg_t *pkg, struct archive *a, struct result_t *result, struct archive_line_reader *buf) { if (config.filterfunc(&config.filter, pkg->name, pkg->namelen, config.icase) != 0) { return 0; } while (reader_getline(buf, a) == ARCHIVE_OK) { const size_t len = buf->line.size; int prefixlen = 0; _cleanup_free_ char *line = NULL; if (len == 0 || (config.binaries && !is_binary(buf->line.base, len))) { continue; } if (config.quiet) { line = strdup(buf->line.base); if (line == NULL) { fputs("error: failed to allocate memory\n", stderr); return 0; } } else { prefixlen = asprintf(&line, "%s/%s", repo, pkg->name); if (prefixlen < 0) { fputs("error: failed to allocate memory\n", stderr); return 0; } } result_add(result, line, config.quiet ? NULL : buf->line.base, prefixlen); } /* When we encounter a match with fixed string matching, we know we're done. * However, for other filter methods, we can't be sure that our pattern won't * produce further matches, so we signal our caller to continue. */ return config.filterby == FILTER_EXACT ? -1 : 0; }
static int search_metafile(const char *repo, struct pkg_t *pkg, struct archive *a, struct result_t *result, struct archive_line_reader *buf) { while (reader_getline(buf, a) == ARCHIVE_OK) { const size_t len = buf->line.size; if (len == 0) { continue; } if (!config.directories && is_directory(buf->line.base, len)) { continue; } if (config.binaries && !is_binary(buf->line.base, len)) { continue; } if (config.filterfunc(&config.filter, buf->line.base, (int)len, config.icase) == 0) { _cleanup_free_ char *line = NULL; int prefixlen = format_search_result(&line, repo, pkg); if (prefixlen < 0) { fputs("error: failed to allocate memory for result\n", stderr); return -1; } result_add(result, line, config.verbose ? buf->line.base : NULL, config.verbose ? prefixlen : 0); if (!config.verbose) { return 0; } } } return 0; }