Пример #1
0
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;
}
Пример #2
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);
}
Пример #3
0
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, "|");
    }
}
Пример #4
0
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;
}
Пример #5
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);
}
Пример #6
0
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;
}
Пример #7
0
static void
cork_command_add_breadcrumb(struct cork_command *command)
{
    cork_buffer_append_printf(&breadcrumbs_buf, " %s", command->name);
}
Пример #8
0
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);
}
Пример #9
0
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;
}