static int batch_fs_dryrun_chdir (struct batch_queue *q, const char *path) { FILE *log; if ((log = fopen(q->logfile, "a"))) { char *escaped_path = string_escape_shell(path); batch_queue_set_option(q, "cwd", xxstrdup(path)); fprintf(log, "cd %s\n", escaped_path); fclose(log); free(escaped_path); return 0; } else { return -1; } }
//BUG: Too much code repetition! char *resource_monitor_locate(char *path_from_cmdline) { char *monitor_path; struct stat buf; debug(D_RMON,"locating resource monitor executable...\n"); monitor_path = path_from_cmdline; if(monitor_path) { debug(D_RMON,"trying executable from path provided at command line.\n"); if(stat(monitor_path, &buf) == 0) if(S_ISREG(buf.st_mode) && access(monitor_path, R_OK|X_OK) == 0) return xxstrdup(monitor_path); } monitor_path = getenv(RESOURCE_MONITOR_ENV_VAR); if(monitor_path) { debug(D_RMON,"trying executable from $%s.\n", RESOURCE_MONITOR_ENV_VAR); if(stat(monitor_path, &buf) == 0) if(S_ISREG(buf.st_mode) && access(monitor_path, R_OK|X_OK) == 0) return xxstrdup(monitor_path); } debug(D_RMON,"trying executable at local directory.\n"); //LD_CONFIG version. monitor_path = string_format("./resource_monitor"); if(stat(monitor_path, &buf) == 0) if(S_ISREG(buf.st_mode) && access(monitor_path, R_OK|X_OK) == 0) return xxstrdup(monitor_path); //static "vanilla" version free(monitor_path); monitor_path = string_format("./resource_monitorv"); if(stat(monitor_path, &buf) == 0) if(S_ISREG(buf.st_mode) && access(monitor_path, R_OK|X_OK) == 0) return xxstrdup(monitor_path); debug(D_RMON,"trying executable at installed path location.\n"); //LD_CONFIG version. free(monitor_path); monitor_path = string_format("%s/bin/resource_monitor", INSTALL_PATH); if(stat(monitor_path, &buf) == 0) if(S_ISREG(buf.st_mode) && access(monitor_path, R_OK|X_OK) == 0) return xxstrdup(monitor_path); free(monitor_path); monitor_path = string_format("%s/bin/resource_monitorv", INSTALL_PATH); if(stat(monitor_path, &buf) == 0) if(S_ISREG(buf.st_mode) && access(monitor_path, R_OK|X_OK) == 0) return xxstrdup(monitor_path); return NULL; }
/** Read multiple lines connected by shell continuation symbol * (backslash). Return as a single line. Caller will own the * memory. * The continuation is detected when backslash is the last symbol * before the newline character, and the symbol last before last is * not the backslash (double backslash is an escape sequence for * backslash itself). */ char* get_continued_line(struct lexer_book *bk) { char *cont_line = NULL; char *raw_line = NULL; int cont = 1; while(cont && ((raw_line=get_line(bk->stream)) != NULL)) { bk->column_number = 1; bk->line_number++; if(bk->line_number % 1000 == 0) { debug(D_DEBUG, "read line %ld\n", bk->line_number); } /* Strip whitespace */ string_chomp(raw_line); while(isspace(*raw_line)) { raw_line++; bk->column_number++; } size_t len = strlen(raw_line); if(len>0 && raw_line[len-1] == '\\' && (len==1 || raw_line[len-2] != '\\')) { raw_line[len-1] = '\0'; cont++; } else { cont = 0; } if(cont_line) { cont_line = string_combine(cont_line,raw_line); } else { cont_line = xxstrdup(raw_line); } } if(cont > 1) { dag_parse_error(bk, "No line found after line continuation backslash"); free(cont_line); cont_line = NULL; fatal("Unable to parse the makeflow file"); } return cont_line; }
char *dag_node_resources_wrap_options(struct dag_node *n, const char *default_options, batch_queue_type_t batch_type) { switch(batch_type) { case BATCH_QUEUE_TYPE_WORK_QUEUE: return dag_node_resources_wrap_as_wq_options(n, default_options); break; case BATCH_QUEUE_TYPE_CONDOR: return dag_node_resources_wrap_as_condor_options(n, default_options); break; default: if(default_options) return xxstrdup(default_options); else return NULL; } }
pfs_resolve_t pfs_resolve( const char *logical_name, char *physical_name, time_t stoptime ) { pfs_resolve_t result = PFS_RESOLVE_UNCHANGED; struct mount_entry *e; const char *t; if(!resolve_cache) resolve_cache = hash_table_create(0,0); t = hash_table_lookup(resolve_cache,logical_name); if(t) { strcpy(physical_name,t); result = PFS_RESOLVE_CHANGED; } else { for(e=mount_list;e;e=e->next) { result = mount_entry_check(logical_name,e->prefix,e->redirect,physical_name); if(result!=PFS_RESOLVE_UNCHANGED) break; } } switch(result) { case PFS_RESOLVE_UNCHANGED: strcpy(physical_name,logical_name); break; case PFS_RESOLVE_CHANGED: clean_up_path(physical_name); break; case PFS_RESOLVE_FAILED: debug(D_RESOLVE,"%s failed",logical_name); break; case PFS_RESOLVE_ENOENT: debug(D_RESOLVE,"%s ENOENT",logical_name); break; case PFS_RESOLVE_DENIED: debug(D_RESOLVE,"%s denied",logical_name); break; } if(result==PFS_RESOLVE_UNCHANGED || result==PFS_RESOLVE_CHANGED) { debug(D_RESOLVE,"%s = %s",logical_name,physical_name); if(!hash_table_lookup(resolve_cache,logical_name)) { hash_table_insert(resolve_cache,logical_name,xxstrdup(physical_name)); } } return result; }
struct dag_task_category *dag_task_category_lookup_or_create(struct dag *d, const char *label) { struct dag_task_category *category; category = hash_table_lookup(d->task_categories, label); if(!category) { category = malloc(sizeof(struct dag_task_category)); category->label = xxstrdup(label); category->nodes = list_create(); category->variables = hash_table_create(0, 0); category->resources = make_rmsummary(-1); hash_table_insert(d->task_categories, label, category); } return category; }
/** Reads a single summary from stream. Summaries are not parsed, here we simply read between markers (--) **/ char *rmsummary_read_single_chunk(FILE *stream) { struct buffer b; char line[MAX_LINE]; /* Skip comments, blank lines, and markers before the summary */ char c; while( (c = getc(stream)) == '#' || isblank(c) || c == '-' ) { ungetc(c, stream); /* Make sure we read complete comment lines */ do { line[MAX_LINE - 1] = '\0'; fgets(line, MAX_LINE, stream); } while(line[MAX_LINE - 1]); } if(feof(stream)) { return NULL; } buffer_init(&b); ungetc(c, stream); while( (c = getc(stream)) != EOF ) { ungetc(c, stream); if(c == '#' || c == '\n') continue; if(c == '-') break; fgets(line, MAX_LINE, stream); buffer_printf(&b, "%s", line); } char *summ = xxstrdup(buffer_tostring(&b)); buffer_free(&b); return summ; }
char * ast_word_list_execute( int linenum, struct ast_word *w ) { char *t, *line = 0; int i, len; glob_t g; while( w ) { /* This isn't correct. We need more thought on how to handle wildcards. if(strpbrk(w->text,"*[")) { */ if(0) { if(glob(w->text,GLOB_FLAGS,0,&g)==0) { len=1; for(i=0;i<g.gl_pathc;i++) { len += strlen(g.gl_pathv[i])+1; } t = xxmalloc(len); t[0]=0; for(i=0;i<g.gl_pathc;i++) { strcat(t,g.gl_pathv[i]); strcat(t," "); } globfree(&g); } else { ftsh_error(FTSH_ERROR_FAILURE,linenum,"couldn't expand pattern %s",w->text); if(line) free(line); return 0; } } else { t=xxstrdup(w->text); } if(line) { line = string_combine_multi( line, " ", t, 0 ); } else { line = t; } w = w->next; } return variable_subst(line,linenum); }
void nvpair_parse(struct nvpair *n, const char *data) { char *text = xxstrdup(data); char *name, *value; name = strtok(text, " "); while(name) { value = strtok(0, "\n"); if(value) { nvpair_insert_string(n, name, value); } else { break; } name = strtok(0, " "); } free(text); }
struct fsm_construct_handle *fsm_construct_init(char *name) { struct fsm_construct_handle *handle; handle = xxmalloc(sizeof(struct fsm_construct_handle)); handle->fsm_state_list = xxcalloc(1024,sizeof(struct fsm_state_list)); handle->fsm_state_list_size = 1024; handle->fsm_sigma_list = xxcalloc(1024,sizeof(struct fsm_sigma_list)); handle->fsm_sigma_list_size = 1024; handle->fsm_sigma_hash = xxcalloc(SIGMA_HASH_SIZE,sizeof(struct fsm_sigma_hash)); handle->maxstate = -1; handle->maxsigma = -1; handle->numfinals = 0; if (name == NULL) { handle->name = NULL; } else { handle->name = xxstrdup(name); } return(handle); }
char *dag_task_category_wrap_options(struct dag_task_category *category, const char *default_options, batch_queue_type_t batch_type) { switch(batch_type) { case BATCH_QUEUE_TYPE_WORK_QUEUE: case BATCH_QUEUE_TYPE_WORK_QUEUE_SHAREDFS: return dag_task_category_wrap_as_wq_options(category, default_options); break; case BATCH_QUEUE_TYPE_CONDOR: return dag_task_category_wrap_as_condor_options(category, default_options); break; default: if(default_options) return xxstrdup(default_options); else return NULL; } }
static char * ast_bareword_execute( int linenum, char *line ) { int argc; char **argv; char *result=0; if(string_split_quotes(line,&argc,&argv)) { if(argc==1) { result = xxstrdup(argv[0]); } else if(argc>1) { ftsh_error(FTSH_ERROR_SYNTAX,linenum,"expected only one word here, but got garbage following '%s'",argv[0]); } else { ftsh_error(FTSH_ERROR_SYNTAX,linenum,"expected a word here, but found nothing"); } free(argv); } return result; }
/* Parse a string for summary fields. Separator is usually '\n' or ',' */ struct rmsummary *rmsummary_parse_from_str(const char *buffer, const char separator) { char key[MAX_LINE], value[MAX_LINE]; char *token, *saveptr; if(!buffer) return NULL; // strtok does not work with const char. char *buffer_copy = xxstrdup(buffer); const char delim[] = { separator, '\n', '\0'}; struct rmsummary *s = make_rmsummary(-1); /* if source have no last_error, we do not want the -1 from above */ s->last_error = 0; token = strtok_r(buffer_copy, delim, &saveptr); while(token) { if(sscanf(token, "%[^:]:%*[ \t]%[^\n]", key, value) >= 2) { char *key_trim = string_trim_spaces(key); char *value_trim = string_trim_spaces(value); /* remove units if present */ if(strcmp("limits_exceeded", key_trim) != 0) { char *space = strchr(value_trim, ' '); if(space) *space = '\0'; } rmsummary_assign_field(s, key_trim, value_trim); } token = strtok_r(NULL, delim, &saveptr); } free(buffer_copy); return s; }
struct list *catalog_query_sort_hostlist(const char *hosts) { const char *next_host; char *n; struct catalog_host *h; struct list *previously_up = list_create(); struct list *previously_down = list_create(); if(string_null_or_empty(hosts)) { next_host = CATALOG_HOST; } else { next_host = hosts; } if(!down_hosts) { down_hosts = set_create(0); } do { int port; char host[DOMAIN_NAME_MAX]; h = xxmalloc(sizeof(*h)); next_host = parse_hostlist(next_host, host, &port); h->host = xxstrdup(host); h->url = string_format("http://%s:%d/query.json", host, port); h->down = 0; set_first_element(down_hosts); while((n = set_next_element(down_hosts))) { if(!strcmp(n, host)) { h->down = 1; } } if(h->down) { list_push_tail(previously_down, h); } else { list_push_tail(previously_up, h); } } while (next_host); return list_splice(previously_up, previously_down); }
char *parse_str(const char *fname, struct jx *spec, const char *key, const char *default_value) { int found = 0; struct jx *val = jx_lookup_guard(spec, key, &found); const char *result = default_value; if(found) { if(jx_istype(val, JX_STRING)) { result = val->u.string_value; } else { fatal("Value of %s for '%s' is not a string.", key, fname); } } if(result) { return xxstrdup(result); } else { return NULL; } }
static int dag_parse_node_regular_command(struct lexer *bk, struct dag_node *n) { struct buffer b; buffer_init(&b); struct token *t; while((t = lexer_next_token(bk)) && t->type != TOKEN_NEWLINE) { switch(t->type) { case TOKEN_SPACE: buffer_printf(&b, " "); break; case TOKEN_LITERAL: buffer_printf(&b, "%s", t->lexeme); break; case TOKEN_IO_REDIRECT: buffer_printf(&b, "%s", t->lexeme); break; default: lexer_report_error(bk, "Unexpected command token: %s.\n", lexer_print_token(t)); break; } lexer_free_token(t); } if(!t) { lexer_report_error(bk, "Command does not end with newline.\n"); } n->command = xxstrdup(buffer_tostring(&b)); buffer_free(&b); debug(D_MAKEFLOW_PARSER, "node command=%s", n->command); return 1; }
static int builtin_export( int line, int argc, char **argv, time_t stoptime ) { char *expr; char *name; char *value; if(argc<2) { ftsh_error(FTSH_ERROR_SYNTAX,line,"export: exactly one argument needed"); return 0; } else if(argc>2) { ftsh_error(FTSH_ERROR_SYNTAX,line,"export: too many arguments"); return 0; } name = argv[1]; value = buffer_load(name); if(!value) value = xxstrdup(""); expr = malloc(strlen(name)+strlen(value)+3); if(!expr) { free(name); free(value); return 0; } ftsh_error(FTSH_ERROR_COMMAND,line,"EXPORT %s (%s)",name,value); sprintf(expr,"%s=%s",name,value); /* Depending on the libc, this call may leak memory */ /* by leaving multiple exprs allocated. No solution */ /* except to leak. Don't export in an infinite loop. */ putenv(expr); free(name); free(value); return 1; }
// workers_by_item format: "item1_name:item1_value, item2_name:item2_value, ..." // returns the item value of item - "item_name" int workers_by_item(const char *workers_by_item, const char *item_name) { if(!workers_by_item || !item_name) { return -1; } char *wbi, *item, *eq; wbi = xxstrdup(workers_by_item); item = strtok(wbi, " \t,"); while(item) { eq = strchr(item, ':'); if(eq) { int n; *eq = '\0'; if(!strncmp(item, item_name, WORK_QUEUE_LINE_MAX)) { n = atoi(eq+1); if(n < 0) { *eq = '='; fprintf(stderr, "Number of workers in item \"%s\" is invalid.\n", item); break; } else { free(wbi); return n; } } *eq = ':'; } else { if(!strncmp(item, "n/a", 3)) { break; } else { fprintf(stderr, "Invalid worker distribution item: \"%s\".\n", item); break; } } item = strtok(0, " \t,"); } free(wbi); return -1; }
/* Returns a pointer to a new struct dag described by filename. Return NULL on * failure. */ struct dag *dag_from_file(const char *filename) { FILE *dagfile; struct dag *d = NULL; dagfile = fopen(filename, "r"); if(dagfile == NULL) debug(D_DEBUG, "makeflow: unable to open file %s: %s\n", filename, strerror(errno)); else { d = dag_create(); d->filename = xxstrdup(filename); if(!dag_parse(d, dagfile)) { free(d); d = NULL; } fclose(dagfile); } return d; }
/* Return the dag_file associated with the local name filename. * If one does not exist, it is created. */ struct dag_file *dag_file_lookup_or_create(struct dag *d, const char *filename) { struct dag_file *f; f = hash_table_lookup(d->file_table, filename); if(f) return f; f = malloc(sizeof(struct dag_file)); f->filename = xxstrdup(filename); f->needed_by = list_create(0); f->target_of = NULL; f->ref_count = 0; hash_table_insert(d->file_table, f->filename, (void *) f); return f; }
void dag_parse_append_variable(struct lexer_book *bk, int nodeid, struct dag_node *n, const char *name, const char *value) { struct dag_lookup_set sd = { bk->d, NULL, NULL, NULL }; struct dag_variable_value *vd = dag_lookup(name, &sd); struct dag_variable_value *v; if(n) { v = dag_get_variable_value(name, n->variables, nodeid); if(v) { dag_variable_value_append_or_create(v, value); } else { char *new_value; if(vd) { new_value = string_format("%s %s", vd->value, value); } else { new_value = xxstrdup(value); } dag_variable_add_value(name, n->variables, nodeid, new_value); free(new_value); } } else { if(vd) { dag_variable_value_append_or_create(vd, value); } else { dag_variable_add_value(name, bk->d->variables, nodeid, value); } } }
int nvpair_print_alloc(struct nvpair *n, char **text) { size_t needed; char *key; void *value; buffer_t b; buffer_init(&b); buffer_abortonfailure(&b, 0); hash_table_firstkey(n->table); while(hash_table_nextkey(n->table, &key, &value)) { buffer_printf(&b, "%s %s\n", key, (char *) value); } *text = xxstrdup(buffer_tostring(&b, &needed)); buffer_free(&b); return needed; }
struct sigma *sigma_copy(struct sigma *sigma) { int f = 0; struct sigma *copy_sigma, *copy_sigma_s; if (sigma == NULL) { return NULL; } copy_sigma_s = xxmalloc(sizeof(struct sigma)); for (copy_sigma = copy_sigma_s; sigma != NULL; sigma=sigma->next) { if (f == 1) { copy_sigma->next = xxmalloc(sizeof(struct sigma)); copy_sigma = copy_sigma->next; } copy_sigma->number = sigma->number; if (sigma->symbol != NULL) copy_sigma->symbol = xxstrdup(sigma->symbol); else copy_sigma->symbol = NULL; copy_sigma->next = NULL; f = 1; } return(copy_sigma_s); }
struct rmsummary *rmsummary_parse_single(char *buffer, char separator) { char key[MAX_LINE], value[MAX_LINE]; char *token, *saveptr; if(!buffer) return NULL; buffer = xxstrdup(buffer); const char delim[] = { separator, '\n', '\0'}; struct rmsummary *s = make_rmsummary(-1); token = strtok_r(buffer, delim, &saveptr); while(token) { if(sscanf(token, "%[^:]:%*[ \t]%[^\n]", key, value) >= 2) { char *key_trim = string_trim_spaces(key); char *value_trim = string_trim_spaces(value); /* remove units if present */ if(strcmp("limits_exceeded", key_trim) != 0) { char *space = strchr(value_trim, ' '); if(space) *space = '\0'; } rmsummary_assign_field(s, key_trim, value_trim); } token = strtok_r(NULL, delim, &saveptr); } free(buffer); return s; }
struct rmDsummary *parse_summary(FILE *stream, char *filename, struct hash_table *categories) { static FILE *last_stream = NULL; static int summ_id = 1; if(last_stream != stream) { last_stream = stream; summ_id = 1; } else { summ_id++; } struct rmsummary *so = rmsummary_parse_next(stream); if(!so) return NULL; if(categories) { struct category *c = category_lookup_or_create(categories, ALL_SUMMARIES_CATEGORY); category_accumulate_summary(c, so, NULL); if(so->category) { c = category_lookup_or_create(categories, so->category); category_accumulate_summary(c, so, NULL); } } struct rmDsummary *s = rmsummary_to_rmDsummary(so); s->file = xxstrdup(filename); if(!s->task_id) { s->task_id = get_rule_number(filename); } rmsummary_delete(so); return s; }
static int dag_check( void * instance_struct, struct dag *d){ struct archive_instance *a = (struct archive_instance*)instance_struct; unsigned char digest[SHA1_DIGEST_LENGTH]; // Takes hash of filename and stores it in digest sha1_file(d->filename, digest); // Makes a c string copy of your hash address a->source_makeflow = xxstrdup(sha1_string(digest)); // If a is in write mode using the -w flag if (a->write) { // Formats archive file directory char *source_makeflow_file_dir = string_format("%s/files/%.2s", a->dir, a->source_makeflow); // If the directory was not able to be created and directory already exists if (!create_dir(source_makeflow_file_dir, 0777) && errno != EEXIST){ // Prints out a debug error debug(D_ERROR|D_MAKEFLOW_HOOK, "could not create makeflow archiving directory %s: %d %s\n", source_makeflow_file_dir, errno, strerror(errno)); // Frees memory for source_makeflow_file_dir free(source_makeflow_file_dir); return MAKEFLOW_HOOK_FAILURE; } // Gets the path of the archive file char *source_makeflow_file_path = string_format("%s/%s", source_makeflow_file_dir, a->source_makeflow); // Frees memory free(source_makeflow_file_dir); // If the file was unable to be copied to the new path if (!copy_file_to_file(d->filename, source_makeflow_file_path)){ // Prints out debug error debug(D_ERROR|D_MAKEFLOW_HOOK, "Could not archive source makeflow file %s\n", source_makeflow_file_path); free(source_makeflow_file_path); return MAKEFLOW_HOOK_FAILURE; } else { // Print out where it is stored at debug(D_MAKEFLOW_HOOK, "Source makeflow %s stored at %s\n", d->filename, source_makeflow_file_path); } free(source_makeflow_file_path); } return MAKEFLOW_HOOK_SUCCESS; }
struct token *lexer_concat_expandable(struct lexer *lx, struct list *tokens) { struct token *t; struct buffer b; buffer_init(&b); char *substitution; list_first_item(tokens); while((t = list_pop_head(tokens))) { switch(t->type) { case TOKEN_SUBSTITUTION: substitution = dag_variable_lookup_string(t->lexeme, lx->environment); if(!substitution) fatal("Variable %s has not yet been defined at line % " PRId64 ".\n", t->lexeme, lx->line_number); buffer_printf(&b, "%s", substitution); free(substitution); break; case TOKEN_LITERAL: if(strcmp(t->lexeme, "") != 0) // Skip empty strings. buffer_printf(&b, "%s", t->lexeme); break; default: lexer_report_error(lx, "Error in expansion, got: %s.\n", lexer_print_token(t)); break; } lexer_free_token(t); } t = lexer_pack_token(lx, TOKEN_LITERAL); t->lexeme = xxstrdup(buffer_tostring(&b)); buffer_free(&b); return t; }
int path_within_dir(const char *path, const char *dir) { if(!path) return 0; char absolute_dir[PATH_MAX+1]; if(!realpath(dir, absolute_dir)) return 0; char *p; if(path[0] == '/') { p = strstr(path, absolute_dir); if(p != path) { return 0; } } char absolute_path[PATH_MAX+1]; char *tmp_path = xxstrdup(path); int rv = 1; while((p = strrchr(tmp_path, '/')) != NULL) { *p = '\0'; if(realpath(tmp_path, absolute_path)) { p = strstr(absolute_path, absolute_dir); if(p != absolute_path) { rv = 0; } break; } else { if(errno != ENOENT) { rv = 0; break; } } } free(tmp_path); return rv; }
/* Adds remotename to the local name filename in the namespace of * the given node. If remotename is NULL, then a new name is * found using dag_node_translate_filename. If the remotename * given is different from a previosly specified, a warning is * written to the debug output, but otherwise this is ignored. */ const char *dag_node_add_remote_name(struct dag_node *n, const char *filename, const char *remotename) { char *oldname; struct dag_file *f = dag_file_from_name(n->d, filename); if(!f) fatal("trying to add remote name %s to unknown file %s.\n", remotename, filename); if(!remotename) remotename = dag_node_translate_filename(n, filename); else remotename = xxstrdup(remotename); oldname = hash_table_lookup(n->remote_names_inv, remotename); if(oldname && strcmp(oldname, filename) == 0) debug(D_DEBUG, "Remote name %s for %s already in use for %s\n", remotename, filename, oldname); itable_insert(n->remote_names, (uintptr_t) f, remotename); hash_table_insert(n->remote_names_inv, remotename, (void *) f); return remotename; }
static char *resource_monitor_check_path(const char *path, const char *executable_opt) { struct stat buf; if(path) { char *monitor_path; if(executable_opt) { monitor_path = string_format("%s/%s", path, executable_opt); } else { monitor_path = xxstrdup(path); } if(stat(monitor_path, &buf) == 0) if(S_ISREG(buf.st_mode) && access(monitor_path, R_OK|X_OK) == 0) return monitor_path; /* If we get here, we did not find a valid monitor at path */ free(monitor_path); } return NULL; }