Ejemplo n.º 1
0
/**
 * Return a pointer to the extension, including the dot, or NULL.
 * Same as dcc_find_extension(), but the argument and return
 * value are both pointers to const.
 **/
const char * dcc_find_extension_const(const char *sfile) {
#if 0
  return dcc_find_extension((char *) sfile);
#else
  /* The following intermediate variable works around a bug in gcc 4.2.3 where
   * for the code above gcc spuriously reports "warning: passing argument 1
   * of 'dcc_find_extension' discards qualifiers from pointer target type",
   * despite the explicit cast. */
  char *sfile_nonconst = (char *)sfile;
  return dcc_find_extension(sfile_nonconst);
#endif
}
Ejemplo n.º 2
0
static int dcc_set_file_extension(const char *sfile,
                                  const char *new_ext,
                                  char **ofile)
{
    char *dot, *o;

    o = strdup(sfile);
    if (!o) {
        rs_log_error("strdup failed (out of memory?)");
        return EXIT_DISTCC_FAILED;
    }
    dot = dcc_find_extension(o);
    if (!dot) {
        rs_log_error("couldn't find extension in \"%s\"", o);
        return EXIT_DISTCC_FAILED;
    }
    if (strlen(dot) < strlen(new_ext)) {
        rs_log_error("not enough space for new extension");
        return EXIT_DISTCC_FAILED;
    }
    strcpy(dot, new_ext);
    *ofile = o;

    return 0;
}
Ejemplo n.º 3
0
Archivo: serve.c Proyecto: aosm/distcc
static int dcc_input_tmpnam(char * orig_input,
                            char **tmpnam_ret)
{
    const char *input_exten;
    
    rs_trace("input file %s", orig_input);
    input_exten = dcc_find_extension(orig_input);
    if (input_exten)
        input_exten = dcc_preproc_exten(input_exten);
    if (!input_exten)           /* previous line might return NULL */
        input_exten = ".tmp";
    return dcc_make_tmpnam("distccd", input_exten, tmpnam_ret);
}
Ejemplo n.º 4
0
/* Go through arguments (in @p argv), and relevant environment variables, and
 * find out where the dependencies output should go.  Return that location in a
 * newly allocated string in @p dotd_fname.  @p needs_dotd is set to true if the
 * compilation command line and environent imply that a .d file must be
 * produced.  @p sets_dotd_target is set to true if there is a -MQ or -MT
 * option.  This is to be used on the client, so that the client knows where to
 * put the .d file it gets from the server. @p dotd_target is set only if
 * @needs_dotd is true and @sets_dotd_target is false and the target is given in
 * the DEPENDENCIES_OUTPUT environment variable.
 *
 * Note: -M is not handled here, because this option implies -E.
 *
 * TODO(manos): it does not support SUNPRO_DEPENDENCIES.
 */
int dcc_get_dotd_info(char **argv, char **dotd_fname,
                      int *needs_dotd, int *sets_dotd_target,
                      char **dotd_target)
{
    char *deps_output = 0;

    char *input_file;
    char *output_file;
    char **new_args;  /* will throw this away */
    int has_dash_o = 0;
    char *env_var = 0;
    int ret;
    int i;
    char *a;

    *needs_dotd = 0;
    *sets_dotd_target = 0;
    *dotd_target = NULL;

    env_var = getenv("DEPENDENCIES_OUTPUT");

    if (env_var != NULL) {
        *needs_dotd = 1;
    }

    for (i = 0; (a = argv[i]); i++) {
        if (strcmp(a, "-MT") == 0) {
            *sets_dotd_target = 1;
            ++i;
            continue;
        }
        if (strcmp(a, "-MQ") == 0) {
            *sets_dotd_target = 1;
            ++i;
            continue;
        }
        /* Catch-all for all -MD, -MMD, etc, options.
         * -MQ and -MT do not imply a deps file is expected.
         */
        if (strncmp(a, "-M", 2) == 0) {
            *needs_dotd = 1;
        }
        if (strcmp(a, "-MF") == 0) {
            ++i;
            deps_output = argv[i];
        } else if (strncmp(a, "-MF", 3) == 0) {
            deps_output = argv[i] + 3;
        } else if (strcmp(a, "-o") == 0) {
            has_dash_o = 1;
        }
    }

    /* TODO(csilvers): we also need to parse -Wp,-x,-y,-z, in the same
     * way we do gcc flags in the for loop above.  Note that the -Wp
     * flags are passed to cpp, with slightly different semantics than
     * gcc flags (eg -Wp,-MD takes a filename argument, while -MD does
     * not).
     */

    if (deps_output) {
        *dotd_fname = strdup(deps_output);
        if (*dotd_fname == NULL) {
            return EXIT_OUT_OF_MEMORY;
        } else {
            return 0;
        }
    }

    /* ok, so there is no explicit setting of the deps filename. */
    deps_output = env_var;
    if (deps_output) {
        char *space;
        *dotd_fname = strdup(deps_output);
        if (*dotd_fname == NULL) {
            return EXIT_OUT_OF_MEMORY;
        }
        space = strchr(*dotd_fname, ' ');
        if (space != NULL) {
            *space = '\0';
            *dotd_target = space + 1;
        }

        return 0;
    }

    /* and it's not set explicitly in the variable */

    { /* Call dcc_scan_args to find the input/output files in order to calculate
         a name for the .d file.*/

        char *extension;
        char *tmp_dotd_fname;
        ret = dcc_scan_args(argv, &input_file, &output_file, &new_args, NULL);
        if (ret)
            return ret;
        /* if .o is set, just append .d.
         * otherwise, take the basename of the input, and set the suffix to .d */
        if (has_dash_o)
          tmp_dotd_fname = strdup(output_file);
        else
          tmp_dotd_fname = strdup(input_file);
        if (tmp_dotd_fname == NULL) return EXIT_OUT_OF_MEMORY;
        extension = dcc_find_extension(tmp_dotd_fname);
        /* Whether derived from input or output filename, we peel the extension
           off (if it exists). */
        if (extension) {
          /* dcc_find_extension guarantees that there is space for 'd'. */
          extension[1] = 'd';
          extension[2] = '\0';
          *dotd_fname = tmp_dotd_fname;
        }
        else { /* There is no extension (or name ends with a "."). */
          if (tmp_dotd_fname[strlen(tmp_dotd_fname) - 1] == '.')
            checked_asprintf(dotd_fname, "%s%s", tmp_dotd_fname, "d");
          else
            checked_asprintf(dotd_fname, "%s%s", tmp_dotd_fname, ".d");
          if (*dotd_fname == NULL) {
            return EXIT_OUT_OF_MEMORY;
          }
          free(tmp_dotd_fname);
        }
        return 0;
    }
}
Ejemplo n.º 5
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;
}