/* * NAME: path_string() * DESCRIPTION: check and resolve a string path */ char *path_string(char *buf, char *file, unsigned int len) { if (len >= STRINGSZ || strlen(file) != len) { return (char *) NULL; } return path_resolve(buf, file); }
/* * Called when a new image is loaded. * Currently only acts when the main executable is loaded to set exename global. */ static void ImageLoad(IMG img, VOID * v) { // XXX: check if this works correctly when execv() is used. if (IMG_IsMainExecutable(img)) { exename = path_resolve(IMG_Name(img)); pid = getpid(); PROVLOG_EXEC(exename, pid); // Add stdin/stdout/stderr to watched file descriptors. // This should take place while loading the image in order to have // exename available. if ( atoi(TrackStdin.Value().c_str()) ) { ufd_t ufd = ufdmap.get(STDIN_FILENO); std::string fdn = fdname(STDIN_FILENO); fdset.insert(STDIN_FILENO); LOG( "Watching fd" + decstr(STDIN_FILENO) + " (" + fdn + ").\n"); PROVLOG_OPEN(ufd, fdn, fcntl(STDIN_FILENO, F_GETFL), 0); } if ( atoi(TrackStdout.Value().c_str()) ) { ufd_t ufd = ufdmap.get(STDOUT_FILENO); std::string fdn = fdname(STDOUT_FILENO); fdset.insert(STDOUT_FILENO); LOG( "Watching fd" + decstr(STDOUT_FILENO) + " (" + fdn + ").\n"); PROVLOG_OPEN(ufd, fdn, fcntl(STDOUT_FILENO, F_GETFL), 0); } if ( atoi(TrackStderr.Value().c_str()) ) { ufd_t ufd = ufdmap.get(STDERR_FILENO); std::string fdn = fdname(STDERR_FILENO); fdset.insert(STDERR_FILENO); LOG( "Watching fd" + decstr(STDERR_FILENO) + " (" + fdn + ").\n"); PROVLOG_OPEN(ufd, fdn, fcntl(STDERR_FILENO, F_GETFL), 0); } } }
/* * NAME: path->from() * DESCRIPTION: resolve a (possibly relative) path */ char *path_from(char *buf, char *from, char *file) { char buf2[STRINGSZ]; if (file[0] != '/' && strlen(from) + strlen(file) < STRINGSZ - 4) { sprintf(buf2, "%s/../%s", from, file); file = buf2; } return path_resolve(buf, file); }
/* * NAME: path->ed_write() * DESCRIPTION: resolve an editor write file path */ char *path_ed_write(char *buf, char *file) { frame *f; f = cframe; if (OBJR(f->oindex)->flags & O_DRIVER) { return path_resolve(buf, file); } else { PUSH_STRVAL(f, str_new(file, (long) strlen(file))); call_driver_object(f, "path_write", 1); if (f->sp->type != T_STRING) { i_del_value(f->sp++); return (char *) NULL; } path_resolve(buf, f->sp->u.string->text); str_del((f->sp++)->u.string); return buf; } }
/* * NAME: path->include() * DESCRIPTION: resolve an include path */ char *path_include(char *buf, char *from, char *file, string ***strs, int *nstr) { frame *f; int i; value *v; string **str; *strs = NULL; *nstr = 0; if (c_autodriver()) { return path_from(buf, from, file); } f = cframe; PUSH_STRVAL(f, str_new(from, strlen(from))); PUSH_STRVAL(f, str_new(file, (long) strlen(file))); if (!call_driver_object(f, "include_file", 2)) { f->sp++; return path_from(buf, from, file); } if (f->sp->type == T_STRING) { /* simple path */ path_resolve(buf, f->sp->u.string->text); str_del((f->sp++)->u.string); return buf; } else if (f->sp->type == T_ARRAY) { /* * Array of strings. Check that the array does indeed contain only * strings, then return it. */ i = f->sp->u.array->size; if (i != 0) { v = d_get_elts(f->sp->u.array); while ((v++)->type == T_STRING) { if (--i == 0) { *nstr = i = f->sp->u.array->size; str = ALLOC(string*, i); do { str_ref(*str++ = (--v)->u.string); } while (--i != 0); *strs = str; arr_del((f->sp++)->u.array); /* return the untranslated path, as well */ return path_from(buf, from, file); } }
/** * Creates a process given the inputString from stdin */ process* create_process(tok_t *input_str_tokens, int token_count, tok_t token_markers[], int bg) { /* Make sure there's an actual program to be run */ if (input_str_tokens[0] != NULL) { pid_t pid = fork(); int status; int pgid = getpgrp(); if (pid >= 0) { if (pid == 0) { process p; // Initial fill in of process struct p.argv = input_str_tokens; p.argc = token_count; p.pid = getpid(); // if bg process, don't bring to fg if (bg == 0) { if (pgid == 0) pgid = p.pid; setpgid(p.pid, pgid); tcsetpgrp(STDIN_FILENO, pgid); p.background = 'n'; } else { fprintf(stdout, "\n[1] %d\n", p.pid); tcsetpgrp(shell_terminal, shell_pgid); p.background = 'y'; fputc('\n', stdin); } /* Signal control back to normal. */ signal (SIGINT, SIG_DFL); signal (SIGQUIT, SIG_DFL); signal (SIGTSTP, SIG_DFL); signal (SIGTTIN, SIG_DFL); signal (SIGTTOU, SIG_DFL); signal (SIGCHLD, SIG_DFL); p.completed = 'n'; p.stopped = 'n'; p.next = NULL; p.prev = NULL; char *prog = path_resolve(input_str_tokens[0]); // Make sure args end with null byte; input_str_tokens[token_count] = '\0'; // Check for any redirection, if found set appropriately for (int i = 0; token_markers[i] && (i < MAXTOKS-1); i+=2) { int in_out = token_markers[i][0] == '<' ? 0 : 1; int fd; if (in_out == 0) { fd = open(token_markers[i+1], O_RDONLY); p.stdin = fd; } else { fd = open(token_markers[i+1], O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IRGRP | S_IWGRP | S_IWUSR); p.stdout = fd; } dup2(fd, in_out); close(fd); } // execute program after resolution, redirection int ret; ret = execv(prog, input_str_tokens); free(prog); // update process struct p.completed = 'y'; p.stopped = 'y'; // If there any errors present if (ret == -1) perror("execve"); // When background task completes if (bg) fprintf(stdout, "[1] +done %d.\n", p.pid); exit(ret); } else { if (!bg) wait(&status); else { fputc('\n', stdin); } } } } return NULL; }
int main(int argc, char ** argv) { //set up logging //g_log_set_default_handler(log_write, NULL); path_set(".", NULL); const char * prefix = path_resolve(argv[1]); if (prefix == NULL) { return EXIT_FAILURE; } string_t file = string_new("%s/%s", prefix, argv[1]); meta_t * meta = meta_parse(file.string); GHashTableIter itr; List * next; block_t * block; LOG(LOG_INFO, "Module: %s", file.string); LOG(LOG_INFO, "=================================="); LOG(LOG_INFO, "Author:\t %s", meta->author); LOG(LOG_INFO, "Version:\t %s", meta->version); LOG(LOG_INFO, "Pre-Activater:\t %s", meta->preactivate); LOG(LOG_INFO, "Post-Activator: %s", meta->postactivate); LOG(LOG_INFO, "Initializer:\t %s", meta->initialize); LOG(LOG_INFO, "Description:\t %s\n", meta->description); if (list_length(meta->dependencies) > 0) { LOG(LOG_INFO, "Dependencies"); LOG(LOG_INFO, "=================================="); next = meta->dependencies; while (next != NULL) { LOG(LOG_INFO, "%s", (gchar *)next->data); next = next->next; } } if (list_length(meta->cfgentries) > 0) { LOG(LOG_INFO, " "); LOG(LOG_INFO, "Configuration Params"); LOG(LOG_INFO, "=================================="); next = meta->cfgentries; while (next != NULL) { cfgentry_t * cfg = next->data; if (cfg->desc == NULL) LOG(LOG_INFO, "(%c) %s", cfg->type, cfg->name); else LOG(LOG_INFO, "(%c) %s - %s", cfg->type, cfg->name, cfg->desc); next = next->next; } } if (list_length(meta->calentries) > 0) { LOG(LOG_INFO, " "); LOG(LOG_INFO, "Calibration Params"); LOG(LOG_INFO, "=================================="); if (meta->calupdate != NULL) LOG(LOG_INFO, "Update: %s", meta->calupdate); next = meta->calentries; while (next != NULL) { calentry_t * cal = next->data; if (cal->desc == NULL) LOG(LOG_INFO, "(%s)\t%s", cal->sig, cal->name); else LOG(LOG_INFO, "(%s)\t%s - %s", cal->sig, cal->name, cal->desc); next = next->next; } } if (list_length(meta->syscalls) > 0) { LOG(LOG_INFO, " "); LOG(LOG_INFO, "Syscalls"); LOG(LOG_INFO, "=================================="); next = meta->syscalls; while (next != NULL) { syscall_t * syscall = next->data; if (syscall->desc == NULL) LOG(LOG_INFO, "%s(%s)", syscall->name, syscall->sig); else LOG(LOG_INFO, "%s(%s) - %s", syscall->name, syscall->sig, syscall->desc); next = next->next; } } if (g_hash_table_size(meta->blocks) > 0) { LOG(LOG_INFO, " "); LOG(LOG_INFO, "Blocks"); LOG(LOG_INFO, "=================================="); g_hash_table_iter_init(&itr, meta->blocks); while (g_hash_table_iter_next(&itr, NULL, (gpointer *)&block)) { if (block->desc == NULL) LOG(LOG_INFO, "%s", block->name); else LOG(LOG_INFO, "%s - %s", block->name, block->desc); if (block->new_name != NULL) LOG(LOG_INFO, " Constructor: %s(%s)", block->new_name, block->new_sig); if (block->ondestroy_name != NULL) LOG(LOG_INFO, " Destructor: %s()", block->ondestroy_name); LOG(LOG_INFO, " Update: %s", block->onupdate_name); next = block->inputs; while (next != NULL) { bio_t * in = next->data; if (in->desc == NULL) LOG(LOG_INFO, " -> input (%c) %s", in->sig, in->name); else LOG(LOG_INFO, " -> input (%c) %s - %s", in->sig, in->name, in->desc); next = next->next; } next = block->outputs; while (next != NULL) { bio_t * out = next->data; if (out->desc == NULL) LOG(LOG_INFO, " <- output (%c) %s", out->sig, out->name); else LOG(LOG_INFO, " <- output (%c) %s - %s", out->sig, out->name, out->desc); next = next->next; } } } LOG(LOG_INFO, " "); //empty line return 0; }