bool cct_check_str_eq(const char *file, int line, const char *expression, const char *expected, const char *actual, bool free1, bool free2) { bool result; if (expected && actual && str_eq(actual, expected)) { cct_check_passed(file, line, expression); result = true; } else { char *exp_str = expected ? format("\"%s\"", expected) : x_strdup("(null)"); char *act_str = actual ? format("\"%s\"", actual) : x_strdup("(null)"); cct_check_failed(file, line, expression, exp_str, act_str); free(exp_str); free(act_str); result = false; } if (free1) { free((char *)expected); } if (free2) { free((char *)actual); } return result; }
bool cct_check_args_eq(const char *file, int line, const char *expression, struct args *expected, struct args *actual, bool free1, bool free2) { bool result; if (expected && actual && args_equal(actual, expected)) { cct_check_passed(file, line, expression); result = true; } else { char *exp_str = expected ? args_to_string(expected) : x_strdup("(null)"); char *act_str = actual ? args_to_string(actual) : x_strdup("(null)"); cct_check_failed(file, line, expression, exp_str, act_str); free(exp_str); free(act_str); result = false; } if (free1) { args_free(expected); } if (free2) { args_free(actual); } return result; }
struct resource * fdstream_resource (const char * path, int fd, const char * content_type) { struct fdstream * st; if ((st = calloc (1, sizeof(*st))) == NULL) return NULL; st->path = x_strdup (path); if (st->path == NULL) { free (st); return NULL; } st->content_type = x_strdup (content_type); if (st->content_type == NULL) { free (st); free ((char *)st->path); return NULL; } st->stream = stream_open (fd); if (st->stream == NULL) { free (st); free ((char *)st->path); free ((char *)st->content_type); return NULL; } return resource_new (fdstream_check, fdstream_head, fdstream_body, fdstream_delete, st); }
static void conf_item_receiver(const char *descr, const char *origin, void *context) { (void)context; received_conf_items[n_received_conf_items].descr = x_strdup(descr); received_conf_items[n_received_conf_items].origin = x_strdup(origin); ++n_received_conf_items; }
static int verify_object(struct conf *conf, struct manifest *mf, struct object *obj, struct hashtable *stated_files, struct hashtable *hashed_files) { for (uint32_t i = 0; i < obj->n_file_info_indexes; i++) { struct file_info *fi = &mf->file_infos[obj->file_info_indexes[i]]; char *path = mf->files[fi->index]; struct file_stats *st = hashtable_search(stated_files, path); if (!st) { struct stat file_stat; if (x_stat(path, &file_stat) != 0) { return 0; } st = x_malloc(sizeof(*st)); st->size = file_stat.st_size; st->mtime = file_stat.st_mtime; st->ctime = file_stat.st_ctime; hashtable_insert(stated_files, x_strdup(path), st); } if (fi->size != st->size) { return 0; } if (conf->sloppiness & SLOPPY_FILE_STAT_MATCHES) { if (fi->mtime == st->mtime && fi->ctime == st->ctime) { cc_log("mtime/ctime hit for %s", path); continue; } else { cc_log("mtime/ctime miss for %s", path); } } struct file_hash *actual = hashtable_search(hashed_files, path); if (!actual) { struct mdfour hash; hash_start(&hash); int result = hash_source_code_file(conf, &hash, path); if (result & HASH_SOURCE_CODE_ERROR) { cc_log("Failed hashing %s", path); return 0; } if (result & HASH_SOURCE_CODE_FOUND_TIME) { return 0; } actual = x_malloc(sizeof(*actual)); hash_result_as_bytes(&hash, actual->hash); actual->size = hash.totalN; hashtable_insert(hashed_files, x_strdup(path), actual); } if (memcmp(fi->hash, actual->hash, mf->hash_size) != 0 || fi->size != actual->size) { return 0; } } return 1; }
static char * find_executable_in_path(const char *name, const char *exclude_name, char *path) { path = x_strdup(path); // Search the path looking for the first compiler of the right name that // isn't us. char *saveptr = NULL; for (char *tok = strtok_r(path, PATH_DELIM, &saveptr); tok; tok = strtok_r(NULL, PATH_DELIM, &saveptr)) { #ifdef _WIN32 char namebuf[MAX_PATH]; int ret = SearchPath(tok, name, NULL, sizeof(namebuf), namebuf, NULL); if (!ret) { char *exename = format("%s.exe", name); ret = SearchPath(tok, exename, NULL, sizeof(namebuf), namebuf, NULL); free(exename); } (void) exclude_name; if (ret) { free(path); return x_strdup(namebuf); } #else struct stat st1, st2; char *fname = format("%s/%s", tok, name); // Look for a normal executable file. if (access(fname, X_OK) == 0 && lstat(fname, &st1) == 0 && stat(fname, &st2) == 0 && S_ISREG(st2.st_mode)) { if (S_ISLNK(st1.st_mode)) { char *buf = x_realpath(fname); if (buf) { char *p = basename(buf); if (str_eq(p, exclude_name)) { // It's a link to "ccache"! free(p); free(buf); continue; } free(buf); free(p); } } // Found it! free(path); return fname; } free(fname); #endif } free(path); return NULL; }
static void alloc_pw(struct passwd *target, struct passwd *source) { *target = *source; /* we care only about these strings */ target->pw_dir = x_strdup(source->pw_dir); target->pw_name = x_strdup(source->pw_name); target->pw_shell = x_strdup(source->pw_shell); }
/* return the base name of a file - caller frees */ char *str_basename(const char *s) { char *p = strrchr(s, '/'); if (p) { return x_strdup(p+1); } return x_strdup(s); }
static int _pam_parse(int flags, int argc, const char **argv, char **maildir, int *hashcount) { int ctrl=0; if (flags & PAM_SILENT) { ctrl |= PAM_MAIL_SILENT; } *hashcount = 0; /* step through arguments */ for (; argc-- > 0; ++argv) { /* generic options */ if (!strcmp(*argv,"debug")) ctrl |= PAM_DEBUG_ARG; else if (!strcmp(*argv,"quiet")) ctrl |= PAM_QUIET_MAIL; else if (!strcmp(*argv,"standard")) ctrl |= PAM_STANDARD_MAIL | PAM_EMPTY_TOO; else if (!strncmp(*argv,"dir=",4)) { *maildir = x_strdup(4+*argv); if (*maildir != NULL) { D(("new mail directory: %s", *maildir)); ctrl |= PAM_NEW_MAIL_DIR; } else { _log_err(LOG_CRIT, "failed to duplicate mail directory - ignored"); } } else if (!strncmp(*argv,"hash=",5)) { char *ep = NULL; *hashcount = strtol(*argv+5,&ep,10); if (!ep || (*hashcount < 0)) { *hashcount = 0; } } else if (!strcmp(*argv,"close")) { ctrl |= PAM_LOGOUT_TOO; } else if (!strcmp(*argv,"nopen")) { ctrl |= PAM_NO_LOGIN; } else if (!strcmp(*argv,"noenv")) { ctrl |= PAM_NO_ENV; } else if (!strcmp(*argv,"empty")) { ctrl |= PAM_EMPTY_TOO; } else { _log_err(LOG_ERR,"pam_parse: unknown option; %s",*argv); } } if ((*hashcount != 0) && !(ctrl & PAM_NEW_MAIL_DIR)) { *maildir = x_strdup(DEFAULT_MAIL_DIRECTORY); ctrl |= PAM_NEW_MAIL_DIR; } return ctrl; }
/* find an executable by name in $PATH. Exclude any that are links to exclude_name */ char *find_executable(const char *name, const char *exclude_name) { char *path; char *tok; struct stat st1, st2; if (*name == '/') { return x_strdup(name); } path = getenv("F90CACHE_PATH"); if (!path) { path = getenv("PATH"); } if (!path) { fc_log("no PATH variable!?\n"); return NULL; } path = x_strdup(path); /* search the path looking for the first compiler of the right name that isn't us */ for (tok=strtok(path,":"); tok; tok = strtok(NULL, ":")) { char *fname; x_asprintf(&fname, "%s/%s", tok, name); /* look for a normal executable file */ if (access(fname, X_OK) == 0 && lstat(fname, &st1) == 0 && stat(fname, &st2) == 0 && S_ISREG(st2.st_mode)) { /* if its a symlink then ensure it doesn't point at something called exclude_name */ if (S_ISLNK(st1.st_mode)) { char *buf = x_realpath(fname); if (buf) { char *p = str_basename(buf); if (strcmp(p, exclude_name) == 0) { /* its a link to "f90cache" ! */ free(p); free(buf); continue; } free(buf); free(p); } } /* found it! */ free(path); return fname; } free(fname); } return NULL; }
static char * get_root(void) { #ifndef _WIN32 return x_strdup("/"); #else char volume[4]; // "C:\" GetVolumePathName(get_cwd(), volume, sizeof(volume)); return x_strdup(volume); #endif }
/* Case insentively matches against wildcards */ int strcasematch(const char *str, const char *mask) { char *newstr, *newmask; int ret; newstr = strlwr(x_strdup(str)); newmask = strlwr(x_strdup(mask)); ret = strmatch(newstr, newmask); free(newstr); free(newmask); return ret; }
int main(int argc, char *argv[]) { char *program_name, *compiler_name, *other_wrappers, *sysroot; struct args *compiler_args, *cmd; compiler_args = args_init(argc, argv); /* check if we were called directly. */ program_name = basename(compiler_args->argv[0]); args_remove_first(compiler_args); if (str_eq(program_name, MYNAME)) { /* the first argument should be a compiler */ if (compiler_args->argc < 1 || compiler_args->argv[0][0] == '-') { fprintf(stderr, "%s", USAGE_TEXT); exit(1); } compiler_name = x_strdup(compiler_args->argv[0]); args_remove_first(compiler_args); } else { compiler_name = x_strdup(program_name); } free(program_name); other_wrappers = getenv(MYNAME "_OTHER_WRAPPERS"); if (!other_wrappers) { other_wrappers = "ccache distcc"; } cmd = find_all_executables(compiler_name, MYNAME, other_wrappers); if (!cmd) { fatal("No valid executables named %s found!", compiler_name); } free(compiler_name); sysroot = getenv("SYSROOT"); if (sysroot) { args_add(cmd, "--sysroot"); args_add(cmd, sysroot); } args_extend(cmd, compiler_args); args_free(compiler_args); execute(cmd->argv); return 1; }
// Set argument at given index. void args_set(struct args *args, int index, const char *value) { assert(index < args->argc); free(args->argv[index]); args->argv[index] = x_strdup(value); }
/* * Trims leading/trailing spaces from the string, returns a copy of it if it * is modified. */ char * x_strtrim(char *s) { char *base = s; char *d; if (s != 0 && *s != '\0') { char *t = x_strdup(base); s = t; d = s; while (isspace(CharOf(*s))) { ++s; } while ((*d++ = *s++) != '\0') { ; } if (*t != '\0') { s = t + strlen(t); while (s != t && isspace(CharOf(s[-1]))) { *--s = '\0'; } } if (!strcmp(t, base)) { free(t); } else { base = t; } } return base; }
static int inst_ans(t_line *l) { l->ans = x_strdup(l->oldstr); if (l->ans == NULL) return (1); return (0); }
char *eof_ret(void) { g_inheredoc = 0; g_inheredoc_2 = 0; ft_printf("\n"); return (x_strdup(g_heredoc_expected)); }
/* * Call this with in_out pointing to data filled in by x_getpwnam() or by * x_getpwnam(). It finds the user's logon name, if possible. As a side * effect, it updates in_out to fill in possibly more-relevant data, i.e., * in case there is more than one alias for the same uid. */ char * x_getlogin(uid_t uid, struct passwd *in_out) { char *login_name = NULL; login_name = login_alias(x_getenv("LOGNAME"), uid, in_out); if (IsEmpty(login_name)) { login_name = login_alias(x_getenv("USER"), uid, in_out); } #ifdef HAVE_GETLOGIN /* * Of course getlogin() will fail if we're started from a window-manager, * since there's no controlling terminal to fuss with. For that reason, we * tried first to get something useful from the user's $LOGNAME or $USER * environment variables. */ if (IsEmpty(login_name)) { TRACE2(("...try getlogin\n")); login_name = login_alias(getlogin(), uid, in_out); } #endif if (IsEmpty(login_name)) login_name = in_out->pw_name; if (!IsEmpty(login_name)) login_name = x_strdup(login_name); TRACE2(("x_getloginid ->%s\n", NonNull(login_name))); return login_name; }
static bool parse_sloppiness(const char *str, void *result, char **errmsg) { unsigned *value = (unsigned *)result; char *word, *p, *q, *saveptr = NULL; if (!str) { return *value; } p = x_strdup(str); q = p; while ((word = strtok_r(q, ", ", &saveptr))) { if (str_eq(word, "file_macro")) { *value |= SLOPPY_FILE_MACRO; } else if (str_eq(word, "file_stat_matches")) { *value |= SLOPPY_FILE_STAT_MATCHES; } else if (str_eq(word, "include_file_ctime")) { *value |= SLOPPY_INCLUDE_FILE_CTIME; } else if (str_eq(word, "include_file_mtime")) { *value |= SLOPPY_INCLUDE_FILE_MTIME; } else if (str_eq(word, "pch_defines")) { *value |= SLOPPY_PCH_DEFINES; } else if (str_eq(word, "time_macros")) { *value |= SLOPPY_TIME_MACROS; } else { *errmsg = format("unknown sloppiness: \"%s\"", word); free(p); return false; } q = NULL; } free(p); return true; }
static int _pam_parse(int argc, const char **argv, char **users) { int ctrl=0; /* step through arguments */ for (ctrl=0; argc-- > 0; ++argv) { /* generic options */ if (!strcmp(*argv,"debug")) ctrl |= PAM_DEBUG_ARG; else if (!strncmp(*argv,"users=",6)) { *users = x_strdup(6+*argv); if (*users == NULL) { ctrl |= PAM_NO_ANON; _pam_log(LOG_CRIT, "failed to duplicate user list - anon off"); } } else if (!strcmp(*argv,"ignore")) { ctrl |= PAM_IGNORE_EMAIL; } else { _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); } } return ctrl; }
void ft_init_line_heredoc(t_line *l) { if (g_line != NULL) l->sizeprompt = g_line->sizeprompt; l->size = 0; l->str = x_strdup(""); l->count = 0; }
char * x_getenv(const char *name) { char *result; result = x_strdup(x_nonempty(getenv(name))); TRACE2(("getenv(%s) %s\n", name, result)); return result; }
static bool parse_string(const char *str, void *result, char **errmsg) { char **value = (char **)result; (void)errmsg; free(*value); *value = x_strdup(str); return true; }
void args_add(struct args *args, const char *s) { args->argv = (char **)x_realloc(args->argv, (args->argc + 2) * sizeof(char *)); args->argv[args->argc] = x_strdup(s); args->argc++; args->argv[args->argc] = NULL; }
/* return the dir name of a file - caller frees */ char *dirname(char *s) { char *p; s = x_strdup(s); p = strrchr(s, '/'); if (p) { *p = 0; } return s; }
// Add an argument into the front of the argument list. void args_add_prefix(struct args *args, const char *s) { args->argv = (char **)x_realloc(args->argv, (args->argc + 2) * sizeof(char *)); memmove(&args->argv[1], &args->argv[0], (args->argc+1) * sizeof(args->argv[0])); args->argv[0] = x_strdup(s); args->argc++; }
PAMH_ARG_DECL(int get_pwd_hash, const char *name, struct passwd **pwd, char **hash) { int retval; struct spwd *spwdent = NULL; retval = get_account_info(PAMH_ARG(name, pwd, &spwdent)); if (retval != PAM_SUCCESS) { return retval; } if (spwdent) *hash = x_strdup(spwdent->sp_pwdp); else *hash = x_strdup((*pwd)->pw_passwd); if (*hash == NULL) return PAM_BUF_ERR; return PAM_SUCCESS; }
/* sort the files we've found and delete the oldest ones until we are below the thresholds */ static void sort_and_clean(void) { unsigned i; const char *ext; char *last_base = x_strdup(""); if (num_files > 1) { /* Sort in ascending mtime order. */ qsort(files, num_files, sizeof(struct files *), (COMPAR_FN_T)files_compare); } /* delete enough files to bring us below the threshold */ for (i = 0; i < num_files; i++) { if ((cache_size_threshold == 0 || cache_size <= cache_size_threshold) && (files_in_cache_threshold == 0 || files_in_cache <= files_in_cache_threshold)) { break; } ext = get_extension(files[i]->fname); if (str_eq(ext, ".o") || str_eq(ext, ".d") || str_eq(ext, ".gcno") || str_eq(ext, ".dia") || str_eq(ext, ".stderr") || str_eq(ext, "")) { char *base = remove_extension(files[i]->fname); if (!str_eq(base, last_base)) { /* Avoid redundant unlinks. */ /* * Make sure that all sibling files are deleted so that a cached result * is removed completely. Note the order of deletions -- the stderr * file must be deleted last because if the ccache process gets killed * after deleting the .stderr but before deleting the .o, the cached * result would be inconsistent. */ delete_sibling_file(base, ".o"); delete_sibling_file(base, ".d"); delete_sibling_file(base, ".gcno"); delete_sibling_file(base, ".dia"); delete_sibling_file(base, ".stderr"); delete_sibling_file(base, ""); /* Object file from ccache 2.4. */ } free(last_base); last_base = base; } else { /* .manifest or unknown file. */ delete_file(files[i]->fname, files[i]->size); } } free(last_base); }
static struct hashtable * create_string_index_map(char **strings, uint32_t len) { struct hashtable *h = create_hashtable(1000, hash_from_string, strings_equal); for (uint32_t i = 0; i < len; i++) { uint32_t *index = x_malloc(sizeof(*index)); *index = i; hashtable_insert(h, x_strdup(strings[i]), index); } return h; }
/* Create a conf struct with default values. */ struct conf * conf_create(void) { size_t i; struct conf *conf = x_malloc(sizeof(*conf)); conf->base_dir = x_strdup(""); conf->cache_dir = format("%s/.ccache", get_home_directory()); conf->cache_dir_levels = 2; conf->compiler = x_strdup(""); conf->compiler_check = x_strdup("mtime"); conf->compression = false; conf->compression_level = 6; conf->cpp_extension = x_strdup(""); conf->direct_mode = true; conf->disable = false; conf->extra_files_to_hash = x_strdup(""); conf->hard_link = false; conf->hash_dir = false; conf->log_file = x_strdup(""); conf->max_files = 0; conf->max_size = (uint64_t)5 * 1000 * 1000 * 1000; conf->path = x_strdup(""); conf->prefix_command = x_strdup(""); conf->read_only = false; conf->read_only_direct = false; conf->recache = false; conf->run_second_cpp = false; conf->sloppiness = 0; conf->stats = true; conf->temporary_dir = x_strdup(""); conf->umask = UINT_MAX; /* default: don't set umask */ conf->unify = false; conf->cache_repo_path = x_strdup(""); conf->item_origins = x_malloc(CONFITEMS_TOTAL_KEYWORDS * sizeof(char *)); for (i = 0; i < CONFITEMS_TOTAL_KEYWORDS; ++i) { conf->item_origins[i] = "default"; } return conf; }