static int bz_pacman_add_install_scripts(struct bz_env *env, struct cork_buffer *pkgbuild_buf) { struct cork_buffer install_buf = CORK_BUFFER_INIT(); /* Copy each kind of script into install_buf, if present. */ rii_check(bz_pacman_add_install_script (env, &install_buf, "pre_install_script", "pre_install")); rii_check(bz_pacman_add_install_script (env, &install_buf, "post_install_script", "post_install")); rii_check(bz_pacman_add_install_script (env, &install_buf, "pre_remove_script", "pre_remove")); rii_check(bz_pacman_add_install_script (env, &install_buf, "post_remove_script", "post_remove")); /* If any of them added content to the install script, save that to a file * and reference it in the PKGBUILD. */ if (install_buf.size > 0) { struct cork_path *install; const char *install_base; rip_check(install = bz_env_get_path(env, "pacman.install", true)); rip_check(install_base = bz_env_get_string(env, "pacman.install_base", true)); rii_check(bz_create_file(cork_path_get(install), &install_buf, 0640)); cork_buffer_append_printf(pkgbuild_buf, "install=%s\n", install_base); } cork_buffer_done(&install_buf); return 0; }
static void bz_git_make_slug(struct cork_buffer *dest, const char *url, const char *commit) { struct cork_path *path; cork_hash hash; /* First grab the basename of the URL. */ path = cork_path_new(url); cork_path_set_basename(path); cork_buffer_append_string(dest, cork_path_get(path)); cork_path_free(path); /* Then remove any trailing ".git" extension. */ if (dest->size >= 4) { const char *extension = &cork_buffer_char(dest, dest->size - 4); if (strcmp(extension, ".git") == 0) { cork_buffer_truncate(dest, dest->size - 4); } } /* Then calculate the hash of the full URL and commit, and append that to * ensure we have a unique slug. */ hash = 0x48f2a642; /* hash of "git" */ hash = cork_stable_hash_buffer(hash, url, strlen(url)); hash = cork_stable_hash_buffer(hash, commit, strlen(commit)); cork_buffer_append_printf(dest, "-%08" PRIx32, hash); }
void cork_buffer_append_hex_dump(struct cork_buffer *dest, size_t indent, const char *chars, size_t length) { char hex[3 * 16]; char print[16]; char *curr_hex = hex; char *curr_print = print; size_t i; size_t column = 0; for (i = 0; i < length; i++) { char ch = chars[i]; uint8_t u8 = ch; *curr_hex++ = to_hex(u8 >> 4); *curr_hex++ = to_hex(u8 & 0x0f); *curr_hex++ = ' '; *curr_print++ = is_sprint(ch)? ch: '.'; if (column == 0 && i != 0) { cork_buffer_append_literal(dest, "\n"); cork_buffer_append_indent(dest, indent); column++; } else if (column == 15) { cork_buffer_append_printf (dest, "%-48.*s", (int) (curr_hex - hex), hex); cork_buffer_append_literal(dest, " |"); cork_buffer_append(dest, print, curr_print - print); cork_buffer_append_literal(dest, "|"); curr_hex = hex; curr_print = print; column = 0; } else { column++; } } if (column > 0) { cork_buffer_append_printf(dest, "%-48.*s", (int) (curr_hex - hex), hex); cork_buffer_append_literal(dest, " |"); cork_buffer_append(dest, print, curr_print - print); cork_buffer_append_literal(dest, "|"); } }
static int bz_pacman_add_install_script(struct bz_env *env, struct cork_buffer *buf, const char *var_name, const char *func_name) { struct cork_path *install_script; rie_check(install_script = bz_env_get_path(env, var_name, false)); if (install_script != NULL) { cork_buffer_append_printf(buf, "%s () {\n", func_name); rii_check(bz_load_file(cork_path_get(install_script), buf)); cork_buffer_append_string(buf, "\n}\n"); } return 0; }
void cork_buffer_append_c_string(struct cork_buffer *dest, const char *chars, size_t length) { size_t i; cork_buffer_append(dest, "\"", 1); for (i = 0; i < length; i++) { char ch = chars[i]; switch (ch) { case '\"': cork_buffer_append_literal(dest, "\\\""); break; case '\\': cork_buffer_append_literal(dest, "\\\\"); break; case '\f': cork_buffer_append_literal(dest, "\\f"); break; case '\n': cork_buffer_append_literal(dest, "\\n"); break; case '\r': cork_buffer_append_literal(dest, "\\r"); break; case '\t': cork_buffer_append_literal(dest, "\\t"); break; case '\v': cork_buffer_append_literal(dest, "\\v"); break; default: if (is_sprint(ch)) { cork_buffer_append(dest, &chars[i], 1); } else { uint8_t byte = ch; cork_buffer_append_printf(dest, "\\x%02" PRIx8, byte); } break; } } cork_buffer_append(dest, "\"", 1); }
static int bz_pacman_fill_deps(struct bz_env *env, struct cork_buffer *buf, const char *pkgbuild_name, const char *var_name) { struct bz_value *deps_value; rie_check(deps_value = bz_env_get_value(env, var_name)); if (deps_value != NULL) { int rc; struct bz_pacman_fill_deps state = { bz_env_as_value(env), CORK_BUFFER_INIT(), true }; rc = bz_array_value_map_scalars (deps_value, &state, bz_pacman_fill_one_dep); if (rc == 0 && state.dep_buf.size > 0) { cork_buffer_append_printf (buf, "%s=(%s)\n", pkgbuild_name, (char *) state.dep_buf.buf); } cork_buffer_done(&state.dep_buf); return rc; } return 0; }
static void cork_command_add_breadcrumb(struct cork_command *command) { cork_buffer_append_printf(&breadcrumbs_buf, " %s", command->name); }
static int write_nonterminal_dot(struct save_data *save_data, serialized_id serialized_node, ipset_variable variable, serialized_id serialized_low, serialized_id serialized_high) { struct dot_data *dot_data = save_data->user_data; /* Include a node for the nonterminal value. */ cork_buffer_printf (&dot_data->scratch, " n%d [shape=circle,label=%u];\n", (-serialized_node), variable); /* Include an edge for the low pointer. */ if (serialized_low < 0) { /* The low pointer is a nonterminal. */ cork_buffer_append_printf (&dot_data->scratch, " n%d -> n%d", (-serialized_node), (-serialized_low)); } else { /* The low pointer is a terminal. */ ipset_value low_value = (ipset_value) serialized_low; if (low_value == dot_data->default_value) { /* The terminal is the default value, so instead of a real * terminal, connect this pointer to a dummy circle node. */ cork_buffer_append_printf (&dot_data->scratch, " low%d [shape=circle,label=\"\"]\n" " n%d -> low%d", (-serialized_node), (-serialized_node), (-serialized_node)); } else { /* The terminal isn't a default, so go ahead and output it. */ cork_buffer_append_printf (&dot_data->scratch, " n%d -> t%d", (-serialized_node), serialized_low); } } cork_buffer_append_printf (&dot_data->scratch, " [style=dashed,color=red]\n"); /* Include an edge for the high pointer. */ if (serialized_high < 0) { /* The high pointer is a nonterminal. */ cork_buffer_append_printf (&dot_data->scratch, " n%d -> n%d", (-serialized_node), (-serialized_high)); } else { /* The high pointer is a terminal. */ ipset_value high_value = (ipset_value) serialized_high; if (high_value == dot_data->default_value) { /* The terminal is the default value, so instead of a real * terminal, connect this pointer to a dummy circle node. */ cork_buffer_append_printf (&dot_data->scratch, " high%d " "[shape=circle," "fixedsize=true," "height=0.25," "width=0.25," "label=\"\"]\n" " n%d -> high%d", (-serialized_node), (-serialized_node), (-serialized_node)); } else { /* The terminal isn't a default, so go ahead and output it. */ cork_buffer_append_printf (&dot_data->scratch, " n%d -> t%d", (-serialized_node), serialized_high); } } cork_buffer_append_printf (&dot_data->scratch, " [style=solid,color=black]\n"); /* Output the clauses to the stream. */ return write_string(save_data->stream, dot_data->scratch.buf); }
static int bz_pacman__package(void *user_data) { struct bz_env *env = user_data; struct bz_value *ctx = bz_env_as_value(env); struct cork_path *staging_dir; struct cork_path *binary_package_dir; struct cork_path *package_build_dir; struct cork_path *pkgbuild; struct cork_path *package_file; const char *package_name; const char *version; const char *pkgrel; const char *pkgext; const char *architecture; const char *license; bool verbose; struct cork_env *exec_env; struct cork_exec *exec; struct cork_buffer buf = CORK_BUFFER_INIT(); bool staging_exists; rii_check(bz_install_dependency_string("pacman", ctx)); rii_check(bz_package_message(env, "pacman")); rip_check(package_name = bz_env_get_string(env, "name", true)); clog_info("(%s) Package using pacman", package_name); rip_check(staging_dir = bz_env_get_path(env, "staging_dir", true)); rip_check(binary_package_dir = bz_env_get_path(env, "binary_package_dir", true)); rip_check(package_build_dir = bz_env_get_path(env, "package_build_dir", true)); rip_check(pkgbuild = bz_env_get_path(env, "pacman.pkgbuild", true)); rip_check(package_file = bz_env_get_path(env, "pacman.package_file", true)); rip_check(version = bz_env_get_string(env, "pacman.version", true)); rip_check(pkgrel = bz_env_get_string(env, "pacman.pkgrel", true)); rip_check(pkgext = bz_env_get_string(env, "pacman.pkgext", true)); rip_check(architecture = bz_env_get_string(env, "pacman.arch", true)); rip_check(license = bz_env_get_string(env, "license", true)); rie_check(verbose = bz_env_get_bool(env, "verbose", true)); rii_check(bz_file_exists(cork_path_get(staging_dir), &staging_exists)); if (CORK_UNLIKELY(!staging_exists)) { cork_error_set_printf (ENOENT, "Staging directory %s does not exist", cork_path_get(staging_dir)); return -1; } /* NOTE: pacman runs ldconfig automatically, so unlike the other packagers, * we do NOT need to add an ldconfig call to the post-install and * post-remove scripts. */ /* Create the temporary directory and the packaging destination */ rii_check(bz_create_directory(cork_path_get(package_build_dir), 0750)); rii_check(bz_create_directory(cork_path_get(binary_package_dir), 0750)); /* Create a PKGBUILD file for this package */ cork_buffer_append_printf(&buf, "pkgname='%s'\n", package_name); cork_buffer_append_printf(&buf, "pkgver='%s'\n", version); cork_buffer_append_printf(&buf, "pkgrel='%s'\n", pkgrel); cork_buffer_append_printf(&buf, "arch=('%s')\n", architecture); cork_buffer_append_printf(&buf, "license=('%s')\n", license); rii_check(bz_pacman_fill_deps(env, &buf, "depends", "dependencies")); cork_buffer_append_printf(&buf, "package () {\n" " rm -rf \"${pkgdir}\"\n" " cp -a '%s' \"${pkgdir}\"\n" "}\n", cork_path_get(staging_dir) ); /* Add pre- and post-install scripts, if necessary. */ rii_check(bz_pacman_add_install_scripts(env, &buf)); ei_check(bz_create_file(cork_path_get(pkgbuild), &buf, 0640)); cork_buffer_done(&buf); exec_env = cork_env_clone_current(); cork_env_add(exec_env, "PKGDEST", cork_path_get(binary_package_dir)); cork_env_add(exec_env, "PKGEXT", pkgext); exec = cork_exec_new_with_params("makepkg", "-sf", NULL); cork_exec_set_cwd(exec, cork_path_get(package_build_dir)); cork_exec_set_env(exec, exec_env); clog_info("(%s) Create %s using pacman", package_name, cork_path_get(package_file)); return bz_subprocess_run_exec(verbose, NULL, exec); error: cork_buffer_done(&buf); return -1; }