Пример #1
0
Файл: rpc.c Проект: aosm/distcc
int dcc_r_token_string(int ifd, const char *expect_token,
                       char **p_str)
{
    unsigned a_len;
    int ret;
        
    if ((ret = dcc_r_token_int(ifd, expect_token, &a_len)))
        return ret;

    if ((ret = dcc_r_str_alloc(ifd, a_len, p_str)))
        return ret;
    
    return 0;
}
Пример #2
0
int dcc_r_many_files(int in_fd,
                     const char *dirname,
                     enum dcc_compress compr)
{
    int ret = 0;
    unsigned int n_files;
    unsigned int i;
    char *name = 0;
    char *link_target = 0;
    char token[5];

    if ((ret = dcc_r_token_int(in_fd, "NFIL", &n_files)))
        return ret;

    for (i = 0; i < n_files; ++i) {
        /* like dcc_r_argv */
        unsigned int link_or_file_len;

        if ((ret = dcc_r_token_string(in_fd, "NAME", &name)))
            goto out_cleanup;

        /* FIXME: verify that name starts with '/' and doesn't contain '..'. */
        if ((ret = prepend_dir_to_name(dirname, &name)))
            goto out_cleanup;

        if ((ret = dcc_r_sometoken_int(in_fd, token, &link_or_file_len)))
            goto out_cleanup;

        /* Must prepend the dirname for the file name, a link's target name. */
        if (strncmp(token, "LINK", 4) == 0) {

            if ((ret = dcc_r_str_alloc(in_fd, link_or_file_len, &link_target))){
                goto out_cleanup;
            }
            /* FIXME: verify that link_target doesn't contain '..'.
             * But the include server uses '..' to reference system
             * directories (see _MakeLinkFromMirrorToRealLocation
             * in include_server/compiler_defaults.py), so we'll need to
             * modify that first. */
            if (link_target[0] == '/') {
                if ((ret = prepend_dir_to_name(dirname, &link_target))) {
                    goto out_cleanup;
                }
            }
            if ((ret = dcc_mk_tmp_ancestor_dirs(name))) {
                goto out_cleanup;
            }
            if (symlink(link_target, name) != 0) {
                rs_log_error("failed to create path for %s: %s", name,
                             strerror(errno));
                ret = 1;
                goto out_cleanup;
            }
            if ((ret = dcc_add_cleanup(name))) {
                /* bailing out */
                unlink(name);
                goto out_cleanup;
            }
        } else if (strncmp(token, "FILE", 4) == 0) {
            if ((ret = dcc_r_file(in_fd, name, link_or_file_len, compr))) {
                goto out_cleanup;
            }
            if ((ret = dcc_add_cleanup(name))) {
              /* bailing out */
              unlink(name);
              goto out_cleanup;
            }
        } else {
            char buf[4 + sizeof(link_or_file_len)];
            /* unexpected token */
            rs_log_error("protocol derailment: expected token FILE or LINK");
            /* We should explain what happened here, but we have already read
             * a few more bytes.
             */
            strncpy(buf, token, 4);
            /* TODO(manos): this is probably not kosher */
            memcpy(&buf[4], &link_or_file_len, sizeof(link_or_file_len));
            dcc_explain_mismatch(buf, 12, in_fd);
            ret = EXIT_PROTOCOL_ERROR;
            goto out_cleanup;
        }

out_cleanup:
        free(name);
        name = NULL;
        free(link_target);
        link_target = NULL;
        if (ret)
            break;
    }
    return ret;
}
Пример #3
0
int dcc_r_many_files(int in_fd,
                     const char *dirname,
                     enum dcc_compress compr)
{
    int ret = 0;
    unsigned int n_files;
    unsigned int i;
    char *name = NULL;
    char *link_target = NULL;
    char token[5];

#ifdef XCODE_INTEGRATION
    /* NOTE: If this function is ever used for something besides pump
     * mode support for receiving things to be compiled, then it should
     * take another argument to include/exclude this fixup. */
    char *xci_name, *xci_link_target, *extension;
#endif

    if ((ret = dcc_r_token_int(in_fd, "NFIL", &n_files)))
        return ret;

    for (i = 0; i < n_files; ++i) {
        /* like dcc_r_argv */
        unsigned int link_or_file_len;

        if ((ret = dcc_r_token_string(in_fd, "NAME", &name)))
            goto out_cleanup;

#ifdef XCODE_INTEGRATION
        xci_name = dcc_xci_unmask_developer_dir(name);
        if (xci_name) {
            free(name);
            name = xci_name;
            xci_name = NULL;
        } else {
            ret = EXIT_OUT_OF_MEMORY;
            goto out_cleanup;
        }
#endif

        /* FIXME: verify that name starts with '/' and doesn't contain '..'. */
        if ((ret = prepend_dir_to_name(dirname, &name)))
            goto out_cleanup;

        if ((ret = dcc_r_sometoken_int(in_fd, token, &link_or_file_len)))
            goto out_cleanup;

        /* Must prepend the dirname for the file name, a link's target name. */
        if (strncmp(token, "LINK", 4) == 0) {

            if ((ret = dcc_r_str_alloc(in_fd, link_or_file_len, &link_target))){
                goto out_cleanup;
            }
            rs_trace("got '%s'", link_target);

#ifdef XCODE_INTEGRATION
            xci_link_target = dcc_xci_unmask_developer_dir(link_target);
            if (xci_link_target) {
                free(link_target);
                link_target = xci_link_target;
                xci_link_target = NULL;
            } else {
                ret = EXIT_OUT_OF_MEMORY;
                goto out_cleanup;
            }
#endif
          
            /* FIXME: verify that link_target doesn't contain '..'.
             * But the include server uses '..' to reference system
             * directories (see _MakeLinkFromMirrorToRealLocation
             * in include_server/compiler_defaults.py), so we'll need to
             * modify that first. */
            if (link_target[0] == '/') {
                if ((ret = prepend_dir_to_name(dirname, &link_target))) {
                    goto out_cleanup;
                }
            }
            if ((ret = dcc_mk_tmp_ancestor_dirs(name))) {
                goto out_cleanup;
            }
            if (symlink(link_target, name) != 0) {
                rs_log_error("failed to create path for %s: %s", name,
                             strerror(errno));
                ret = 1;
                goto out_cleanup;
            }
            if ((ret = dcc_add_cleanup(name))) {
                /* bailing out */
                unlink(name);
                goto out_cleanup;
            }
        } else if (strncmp(token, "FILE", 4) == 0) {
            if ((ret = dcc_r_file(in_fd, name, link_or_file_len, compr))) {
                goto out_cleanup;
            }
#ifdef XCODE_INTEGRATION
            if ((extension = dcc_find_extension(name))
                 && !strcmp(extension, ".hmap")
                 && (ret = dcc_xci_headermap_fix(name, dirname))) {
                unlink(name);
                goto out_cleanup;
            }
#endif
            if ((ret = dcc_add_cleanup(name))) {
              /* bailing out */
              unlink(name);
              goto out_cleanup;
            }
        } else {
            char buf[4 + sizeof(link_or_file_len)];
            /* unexpected token */
            rs_log_error("protocol derailment: expected token FILE or LINK");
            /* We should explain what happened here, but we have already read
             * a few more bytes.
             */
            strncpy(buf, token, 4);
            /* TODO(manos): this is probably not kosher */
            memcpy(&buf[4], &link_or_file_len, sizeof(link_or_file_len));
            dcc_explain_mismatch(buf, 12, in_fd);
            ret = EXIT_PROTOCOL_ERROR;
            goto out_cleanup;
        }

out_cleanup:
        if (name) {
            free(name);
            name = NULL;
        }
        if (link_target) {
            free(link_target);
            link_target = NULL;
        }
        if (ret)
            break;
    }
    return ret;
}