/* * print_record() * Print struct futmpx details to given stream. Used for debugging only. */ void print_record(FILE *fp, int record_no, int record_start_byte, struct futmpx record) { fprintf(fp, "record number: %i \n", record_no); fprintf(fp, "start byte: %i \n", record_start_byte); fprintf(fp, "user: "******"inittab id: "); safe_print_str(fp, record.ut_id, sizeof(record.ut_id)); fprintf(fp, "line: "); safe_print_str(fp, record.ut_line, sizeof(record.ut_line)); fprintf(fp, "pid: %i\n", record.ut_pid); fprintf(fp, "type: "); print_type(fp, record.ut_type); fprintf(fp, "termination status: %i\n", record.ut_exit.e_termination); fprintf(fp, "exit status: %i\n", record.ut_exit.e_exit); print_time(fp, record.ut_tv); fprintf(fp, "session id: %i\n", record.ut_session); /* padding skipped */ fprintf(fp, "hostname length: %i\n", record.ut_syslen); fprintf(fp, "hostname: "); safe_print_str(fp, record.ut_host, min(record.ut_syslen, sizeof(record.ut_host))); fprintf(fp, "\n"); fflush(fp); }
void my_safe_print_str(const char* val, int max_len) { char *heap_end; #ifdef __linux__ if (!safe_print_str(val, max_len)) return; #endif heap_end= (char*) sbrk(0); if (!PTR_SANE(val)) { my_safe_printf_stderr("%s", "is an invalid pointer\n"); return; } for (; max_len && PTR_SANE(val) && *val; --max_len) my_write_stderr((val++), 1); my_safe_printf_stderr("%s", "\n"); }
int my_safe_print_str(const char* val, int max_len) { char *heap_end; #ifdef __linux__ // Try and make use of /proc filesystem to safely print memory contents. if (!safe_print_str(val, max_len)) return 0; #endif heap_end= (char*) sbrk(0); if (!PTR_SANE(val)) { my_safe_printf_stderr("%s", "is an invalid pointer"); return 1; } for (; max_len && PTR_SANE(val) && *val; --max_len) my_write_stderr((val++), 1); my_safe_printf_stderr("%s", "\n"); return 0; }
void dis(struct ubik_stream *s, struct ubik_value *v) { ubik_word i; if (v->type == UBIK_NOV) return; ubik_fprintf(s, "\n%" PRIxPTR "%s\n", v->gc.id, v->gc.root ? "*" : ""); if (v->dbg.used) { ubik_fprintf(s, "DBG L%" PRIu16 " C%" PRIu8 " %s\n", v->dbg.line, v->dbg.col, v->dbg.name); } switch (v->type) { case UBIK_STR: ubik_fprintf(s, "STR\n%" PRIu64 "\n", v->str.length); safe_print_str(s, &v->str); ubik_fprintf(s, "\n"); return; case UBIK_RAT: ubik_fprintf(s, "RAT\n%" PRId64 "\n%" PRIu64 "\n", v->rat.num, v->rat.den); return; case UBIK_TUP: ubik_fprintf(s, "TUP\n%" PRIu64 "\n", v->tup.n); for (i = 0; i < v->tup.n; i++) ubik_fprintf(s, "%" PRIu64 " %" PRIu64 "\n", v->tup.elems[i]->gc.id, v->tup.types[i]->gc.id); return; case UBIK_FUN: ubik_fprintf(s, "FUN\n%" PRIu64 "\n%" PRIu64 "\n%" PRIx64 "\n", v->fun.n, v->fun.arity, v->fun.result); for (i = 0; i < v->fun.n; i++) dis_node(s, &v->fun.nodes[i], i); return; case UBIK_MUL: ubik_fprintf(s, "MUL\n"); return; case UBIK_TYP: ubik_fprintf(s, "TYP\n"); switch (v->typ.t) { case UBIK_TYPE_STR: ubik_fprintf(s, "str\n"); return; case UBIK_TYPE_RAT: ubik_fprintf(s, "rat\n"); return; case UBIK_TYPE_BOO: ubik_fprintf(s, "boo\n"); return; case UBIK_TYPE_ADT: ubik_fprintf(s, "adt\n%" PRIuPTR "\n", v->typ.adt.n_ctors); for (i = 0; i < v->typ.adt.n_ctors; i++) dis_ctor(s, &v->typ.adt.ctors[i], i); return; case UBIK_TYPE_APP: ubik_fprintf(s, "app\n"); ubik_fprintf(s, "%" PRIu64 " %" PRIu64 "\n", v->typ.app.arg->gc.id, v->typ.app.res->gc.id); return; case UBIK_TYPE_VAR: ubik_fprintf(s, "var\n%" PRIuPTR "\n", v->typ.var.id); return; default: ubik_fprintf(s, "unknown %d\n", v->typ.t); return; } case UBIK_IMP: ubik_fprintf(s, "IMP\n"); return; case UBIK_BOO: ubik_fprintf(s, "BOO\n%s\n", v->boo.value ? "true" : "false"); return; case UBIK_PAP: ubik_fprintf(s, "PAP\n%" PRIu64 "\n%" PRIu64 "\n%" PRIu64 "\n%" PRIu64 "\n", v->pap.func->gc.id, v->pap.base_func->gc.id, v->pap.arg->gc.id, v->pap.arg_type->gc.id); return; case UBIK_NOV: ubik_unreachable("no-value dis"); case UBIK_MAX_VALUE_TYPE: default: ubik_unreachable("bad value type in workspace"); } }