void print_swap_stats(outbuffer_t * out) { int size, cnt, end; sw_block_t *m; outbuf_add(out, "Swap information:\n"); outbuf_add(out, "-------------------------\n"); outbuf_addv(out, "Progs swapped: %10lu\n", num_swapped); outbuf_addv(out, "Linenum bytes: %10lu\n", line_num_bytes_swapped); outbuf_addv(out, "Total bytes swapped: %10lu\n", total_bytes_swapped); if (!swap_file) { outbuf_add(out, "No swap file\n"); return; } size = cnt = 0; for (m = swap_free; m; size += m->length, cnt++, m = m->next); swap_seek(0, 2); #ifdef SWAP_USE_FD end = tell(swap_file) - last_data; #else end = ftell(swap_file) - last_data; #endif if (end) { size += end; cnt++; } outbuf_addv(out, "Freed bytes: %10lu (%d chunks)\n", size, cnt); }
void stat_living_objects (outbuffer_t * out) { outbuf_add(out, "Hash table of living objects:\n"); outbuf_add(out, "-----------------------------\n"); outbuf_addv(out, "%d living named objects, average search length: %4.2f\n\n", num_living_names, (double) search_length / num_searches); }
int add_string_status (outbuffer_t * out, int verbose) { #ifdef STRING_STATS if (verbose == 1) { outbuf_add(out, "All strings:\n"); outbuf_add(out, "-------------------------\t Strings Bytes\n"); } if (verbose != -1) outbuf_addv(out, "All strings:\t\t\t%8d %8d + %d overhead\n", num_distinct_strings, bytes_distinct_strings, overhead_bytes); if (verbose == 1) { outbuf_addv(out, "Total asked for\t\t\t%8d %8d\n", allocd_strings, allocd_bytes); outbuf_addv(out, "Space actually required/total string bytes %d%%\n", (bytes_distinct_strings + overhead_bytes) * 100 / allocd_bytes); outbuf_addv(out, "Searches: %d Average search length: %6.3f\n", num_str_searches, (double) search_len / num_str_searches); } return (bytes_distinct_strings + overhead_bytes); #else if (verbose) outbuf_add(out, "<String statistics disabled, no information available>\n"); return 0; #endif }
int heart_beat_status (outbuffer_t * ob, int verbose) { char buf[20]; if (verbose == 1) { outbuf_add(ob, "Heart beat information:\n"); outbuf_add(ob, "-----------------------\n"); outbuf_addv(ob, "Number of objects with heart beat: %d, starts: %d\n", num_hb_objs, num_hb_calls); /* passing floats to varargs isn't highly portable so let sprintf handle it */ sprintf(buf, "%.2f", perc_hb_probes); outbuf_addv(ob, "Percentage of HB calls completed last time: %s\n", buf); } return (0); } /* heart_beat_status() */
void dump_malloc_data (outbuffer_t * ob) { int net; net = stats.alloc_calls - stats.free_calls; outbuf_add(ob, "using debug malloc:\n\n"); outbuf_addv(ob, "total malloc'd: %10lu\n", total_malloced); outbuf_addv(ob, "high water mark: %10lu\n", hiwater); outbuf_addv(ob, "overhead: %10lu\n", (MD_TABLE_SIZE * sizeof(md_node_t *)) + (net * MD_OVERHEAD)); outbuf_addv(ob, "#alloc calls: %10lu\n", stats.alloc_calls); outbuf_addv(ob, "#free calls: %10lu\n", stats.free_calls); outbuf_addv(ob, "#alloc - #free: %10lu\n", net); outbuf_addv(ob, "#realloc calls: %10lu\n", stats.realloc_calls); }
void f_debug_info (void) { svalue_t *arg; outbuffer_t out; outbuf_zero(&out); arg = sp - 1; switch (arg[0].u.number) { case 0: { int i, flags; object_t *obj2; ob = arg[1].u.ob; flags = ob->flags; outbuf_addv(&out, "O_HEART_BEAT : %s\n", flags & O_HEART_BEAT ? "TRUE" : "FALSE"); #ifndef NO_WIZARDS outbuf_addv(&out, "O_IS_WIZARD : %s\n", flags & O_IS_WIZARD ? "TRUE" : "FALSE"); #endif #ifdef NO_ADD_ACTION outbuf_addv(&out, "O_LISTENER : %s\n", flags & O_LISTENER ? "TRUE" : "FALSE"); #else outbuf_addv(&out, "O_ENABLE_COMMANDS : %s\n", flags & O_ENABLE_COMMANDS ? "TRUE" : "FALSE"); #endif outbuf_addv(&out, "O_CLONE : %s\n", flags & O_CLONE ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_VIRTUAL : %s\n", flags & O_VIRTUAL ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_DESTRUCTED : %s\n", flags & O_DESTRUCTED ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_ONCE_INTERACTIVE: %s\n", flags & O_ONCE_INTERACTIVE ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_RESET_STATE : %s\n", flags & O_RESET_STATE ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_WILL_CLEAN_UP : %s\n", flags & O_WILL_CLEAN_UP ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_WILL_RESET : %s\n", flags & O_WILL_RESET ? "TRUE" : "FALSE"); #ifdef HAVE_ZLIB if (ob->interactive) { outbuf_addv(&out, "O_COMPRESSED : %s\n", ob->interactive->compressed_stream ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_ZMP : %s\n", ob->interactive->iflags & USING_ZMP ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_GMCP : %s\n", ob->interactive->iflags & USING_GMCP ? "TRUE" : "FALSE"); outbuf_addv(&out, "O_MXP : %s\n", ob->interactive->iflags & USING_MXP ? "TRUE" : "FALSE"); } #endif #ifndef NO_LIGHT outbuf_addv(&out, "total light : %d\n", ob->total_light); #endif #ifndef NO_RESETS outbuf_addv(&out, "next_reset : %d\n", ob->next_reset); #endif outbuf_addv(&out, "time_of_ref : %d\n", ob->time_of_ref); outbuf_addv(&out, "ref : %d\n", ob->ref); #ifdef DEBUG outbuf_addv(&out, "extra_ref : %d\n", ob->extra_ref); #endif outbuf_addv(&out, "name : '/%s'\n", ob->obname); outbuf_addv(&out, "next_all : OBJ(/%s)\n", ob->next_all ? ob->next_all->obname : "NULL"); if (obj_list == ob) outbuf_add(&out, "This object is the head of the object list.\n"); for (obj2 = obj_list, i = 1; obj2; obj2 = obj2->next_all, i++) if (obj2->next_all == ob) { outbuf_addv(&out, "Previous object in object list: OBJ(/%s)\n", obj2->obname); outbuf_addv(&out, "position in object list:%d\n", i); } break; } case 1: ob = arg[1].u.ob; outbuf_addv(&out, "program ref's %d\n", ob->prog->ref); outbuf_addv(&out, "Name /%s\n", ob->prog->filename); outbuf_addv(&out, "program size %d\n", ob->prog->program_size); outbuf_addv(&out, "function flags table %d (%d) \n", ob->prog->last_inherited + ob->prog->num_functions_defined, (ob->prog->last_inherited + ob->prog->num_functions_defined)* sizeof(unsigned short)); outbuf_addv(&out, "compiler function table %d (%d) \n", ob->prog->num_functions_defined, ob->prog->num_functions_defined * sizeof(function_t)); outbuf_addv(&out, "num strings %d\n", ob->prog->num_strings); outbuf_addv(&out, "num vars %d (%d)\n", ob->prog->num_variables_defined, ob->prog->num_variables_defined * (sizeof(char *) + sizeof(short))); outbuf_addv(&out, "num inherits %d (%d)\n", ob->prog->num_inherited, ob->prog->num_inherited * sizeof(inherit_t)); outbuf_addv(&out, "total size %d\n", ob->prog->total_size); break; case 2: { int i; ob = arg[1].u.ob; for (i=0; i<ob->prog->num_variables_total; i++) { /* inefficient, but: */ outbuf_addv(&out, "%s: ", variable_name(ob->prog, i)); svalue_to_string(&ob->variables[i], &out, 2, 0, 0); outbuf_add(&out, "\n"); } break; } default: bad_arg(1, F_DEBUG_INFO); } pop_stack(); pop_stack(); outbuf_push(&out); }
char *p0f_parse(const uint8_t* packet, uint16_t pklen) { const struct ip_header *iph; const struct tcp_header *tcph; const uint8_t* end_ptr; const uint8_t* opt_ptr; const uint8_t* pay = 0; int32_t ilen,olen; uint8_t op[MAXOPT]; uint8_t ocnt = 0; uint16_t mss_val = 0, wsc_val = 0; uint32_t tstamp = 0; uint32_t quirks = 0; pkcnt++; outbuf_reset(); /* Paranoia! */ end_ptr = packet + pklen; iph = (const struct ip_header*)(packet); /* Whoops, IP header ends past end_ptr */ if ((const uint8_t*)(iph + 1) > end_ptr) return NULL; if ( ((iph->ihl & 0x40) != 0x40) || iph->proto != IPPROTO_TCP) { return NULL; } /* If the declared length is shorter than the snapshot (etherleak or such), truncate this bad boy. */ opt_ptr = (const uint8_t*)iph + htons(iph->tot_len); if (end_ptr > opt_ptr) end_ptr = opt_ptr; ilen = iph->ihl & 15; /* Borken packet */ if (ilen < 5) return NULL; if (ilen > 5) { quirks |= QUIRK_IPOPT; } tcph = (const struct tcp_header*)(packet + (ilen << 2)); opt_ptr = (const uint8_t*)(tcph + 1); if (ack_mode && (tcph->flags & (TH_ACK|TH_SYN)) != (TH_ACK|TH_SYN)) return NULL; if (rst_mode && (tcph->flags & TH_RST) != TH_RST) return NULL; /* Whoops, TCP header would end past end_ptr */ if (opt_ptr > end_ptr) return NULL; if (rst_mode && (tcph->flags & TH_ACK)) quirks |= QUIRK_RSTACK; if (tcph->seq == tcph->ack) quirks |= QUIRK_SEQEQ; if (!tcph->seq) quirks |= QUIRK_SEQ0; if (tcph->flags & ~(TH_SYN|TH_ACK|TH_RST|TH_ECE|TH_CWR)) quirks |= QUIRK_FLAGS; ilen=((tcph->doff) << 2) - sizeof(struct tcp_header); if ( (const uint8_t*)opt_ptr + ilen < end_ptr) { #ifdef DEBUG_EXTRAS uint32_t i; outbuf_add(" -- EXTRA PAYLOAD (packet below): "); for (i=0; i< (uint32_t)end_ptr - ilen - (uint32_t)opt_ptr; i++) outbuf_add("%02x ",*(opt_ptr + ilen + i)); outbuf_add("%c",'\n'); fflush(0); #endif /* DEBUG_EXTRAS */ quirks |= QUIRK_DATA; pay = opt_ptr + ilen; } while (ilen > 0) { ilen--; switch (*(opt_ptr++)) { case TCPOPT_EOL: /* EOL */ op[ocnt] = TCPOPT_EOL; ocnt++; if (ilen) { quirks |= QUIRK_PAST; } /* This goto will be probably removed at some point. */ goto end_parsing; case TCPOPT_NOP: /* NOP */ op[ocnt] = TCPOPT_NOP; ocnt++; break; case TCPOPT_SACKOK: /* SACKOK LEN */ op[ocnt] = TCPOPT_SACKOK; ocnt++; ilen--; opt_ptr++; break; case TCPOPT_MAXSEG: /* MSS LEN D0 D1 */ if (opt_ptr + 3 > end_ptr) { borken: quirks |= QUIRK_BROKEN; goto end_parsing; } op[ocnt] = TCPOPT_MAXSEG; mss_val = GET16(opt_ptr+1); ocnt++; ilen -= 3; opt_ptr += 3; break; case TCPOPT_WSCALE: /* WSCALE LEN D0 */ if (opt_ptr + 2 > end_ptr) goto borken; op[ocnt] = TCPOPT_WSCALE; wsc_val = *(uint8_t *)(opt_ptr + 1); ocnt++; ilen -= 2; opt_ptr += 2; break; case TCPOPT_TIMESTAMP: /* TSTAMP LEN T0 T1 T2 T3 A0 A1 A2 A3 */ if (opt_ptr + 9 > end_ptr) goto borken; op[ocnt] = TCPOPT_TIMESTAMP; memcpy(&tstamp, opt_ptr+5, 4); if (tstamp) quirks |= QUIRK_T2; memcpy(&tstamp, opt_ptr+1, 4); tstamp = ntohl(tstamp); ocnt++; ilen -= 9; opt_ptr += 9; break; default: /* Hrmpf... */ if (opt_ptr + 1 > end_ptr) goto borken; op[ocnt] = *(opt_ptr-1); olen = *(uint8_t*)(opt_ptr)-1; if (olen > 32 || (olen < 0)) goto borken; ocnt++; ilen -= olen; opt_ptr += olen; break; } if (ocnt >= MAXOPT-1) goto borken; /* Whoops, we're past end_ptr */ if (ilen > 0) if (opt_ptr >= end_ptr) goto borken; } end_parsing: if (tcph->ack) quirks |= QUIRK_ACK; if (tcph->urg) quirks |= QUIRK_URG; if (tcph->_x2) quirks |= QUIRK_X2; if (!iph->id) quirks |= QUIRK_ZEROID; find_match( /* total */ ntohs(iph->tot_len), /* DF */ (ntohs(iph->off) & IP_DF) != 0, /* TTL */ iph->ttl, /* WSS */ ntohs(tcph->win), /* src */ iph->saddr, /* dst */ iph->daddr, /* sp */ ntohs(tcph->sport), /* dp */ ntohs(tcph->dport), /* ocnt */ ocnt, /* op */ op, /* mss */ mss_val, /* wsc */ wsc_val, /* tst */ tstamp, /* TOS */ iph->tos, /* Q? */ quirks, /* ECN */ tcph->flags & (TH_ECE|TH_CWR), /* pkt */ (uint8_t*)iph, /* len */ end_ptr - (uint8_t*)iph, /* pay */ pay ); return outbuf_return(); }
static inline void find_match(uint16_t tot,uint8_t df,uint8_t ttl,uint16_t wss,uint32_t src, uint32_t dst,uint16_t sp,uint16_t dp,uint8_t ocnt,uint8_t* op,uint16_t mss, uint8_t wsc,uint32_t tstamp,uint8_t tos,uint32_t quirks,uint8_t ecn, uint8_t* pkt,uint8_t plen,uint8_t* pay) { uint32_t j; uint8_t* a; uint8_t nat=0; struct fp_entry* p; uint8_t orig_df = df; uint8_t* tos_desc = 0; struct fp_entry* fuzzy = 0; uint8_t fuzzy_now = 0; re_lookup: p = bh[SIGHASH(tot,ocnt,quirks,df)]; if (tos) tos_desc = lookup_tos(tos); while (p) { /* Cheap and specific checks first... */ /* psize set to zero means >= PACKET_BIG */ if (p->size) { if (tot ^ p->size) { p = p->next; continue; } } else if (tot < PACKET_BIG) { p = p->next; continue; } if (ocnt ^ p->optcnt) { p = p->next; continue; } if (p->zero_stamp ^ (!tstamp)) { p = p->next; continue; } if (p->df ^ df) { p = p->next; continue; } if (p->quirks ^ quirks) { p = p->next; continue; } /* Check MSS and WSCALE... */ if (!p->mss_mod) { if (mss ^ p->mss) { p = p->next; continue; } } else if (mss % p->mss) { p = p->next; continue; } if (!p->wsc_mod) { if (wsc ^ p->wsc) { p = p->next; continue; } } else if (wsc % p->wsc) { p = p->next; continue; } /* Then proceed with the most complex WSS check... */ switch (p->wsize_mod) { case 0: if (wss ^ p->wsize) { p = p->next; continue; } break; case MOD_CONST: if (wss % p->wsize) { p = p->next; continue; } break; case MOD_MSS: if (mss && !(wss % mss)) { if ((wss / mss) ^ p->wsize) { p = p->next; continue; } } else if (!(wss % 1460)) { if ((wss / 1460) ^ p->wsize) { p = p->next; continue; } } else { p = p->next; continue; } break; case MOD_MTU: if (mss && !(wss % (mss+40))) { if ((wss / (mss+40)) ^ p->wsize) { p = p->next; continue; } } else if (!(wss % 1500)) { if ((wss / 1500) ^ p->wsize) { p = p->next; continue; } } else { p = p->next; continue; } break; } /* Numbers agree. Let's check options */ for (j=0; j<ocnt; j++) if (p->opt[j] ^ op[j]) goto continue_search; /* Check TTLs last because we might want to go fuzzy. */ if (p->ttl < ttl) { if (use_fuzzy) fuzzy = p; p = p->next; continue; } /* Naah... can't happen ;-) */ if (!p->no_detail) if (p->ttl - ttl > MAXDIST) { if (use_fuzzy) fuzzy = p; p = p->next; continue; } continue_fuzzy: /* Match! */ if (mss & wss) { if (p->wsize_mod == MOD_MSS) { if ((wss % mss) && !(wss % 1460)) nat=1; } else if (p->wsize_mod == MOD_MTU) { if ((wss % (mss+40)) && !(wss % 1500)) nat=2; } } if (!no_known) { a=(uint8_t*)&src; outbuf_add("%s ",p->os); if (!no_osdesc) outbuf_add("%s ",p->desc); if (nat == 1) outbuf_add("(NAT!) "); else if (nat == 2) outbuf_add("(NAT2!) "); if (ecn) outbuf_add("(ECN) "); if (orig_df ^ df) outbuf_add("(firewall!) "); if (tos) { if (tos_desc) outbuf_add("[%s] ",tos_desc); else outbuf_add("[tos %d] ",tos); } if (p->generic) outbuf_add("[GENERIC] "); if (fuzzy_now) outbuf_add("[FUZZY] "); if (p->no_detail) outbuf_add("* "); else if (tstamp) outbuf_add("up: %d hrs ",tstamp/360000); if (always_sig || (p->generic && !no_unknown)) { outbuf_add("Signature: ["); display_signature(ttl,tot,orig_df,op,ocnt,mss,wss,wsc,tstamp,quirks); if (p->generic) outbuf_add(":%s:?] ",p->os); else outbuf_add("] "); } if (!no_extra && !p->no_detail) { a=(uint8_t*)&dst; if (fuzzy_now) outbuf_add(" link: %s", lookup_link(mss,1)); else outbuf_add(" distance %d, link: %s", p->ttl - ttl, lookup_link(mss,1)); } } return; continue_search: p = p->next; } if (!df) { df = 1; goto re_lookup; } if (use_fuzzy && fuzzy) { df = orig_df; fuzzy_now = 1; p = fuzzy; fuzzy = 0; goto continue_fuzzy; } if (mss & wss) { if ((wss % mss) && !(wss % 1460)) nat=1; else if ((wss % (mss+40)) && !(wss % 1500)) nat=2; } if (!no_unknown) { a=(uint8_t*)&src; outbuf_add("UNKNOWN ["); display_signature(ttl,tot,orig_df,op,ocnt,mss,wss,wsc,tstamp,quirks); outbuf_add(":?:?] "); if (rst_mode) { /* Display a reasonable diagnosis of the RST+ACK madness! */ switch (quirks & (QUIRK_RSTACK | QUIRK_SEQ0 | QUIRK_ACK)) { /* RST+ACK, SEQ=0, ACK=0 */ case QUIRK_RSTACK | QUIRK_SEQ0: outbuf_add("(invalid-K0) "); break; /* RST+ACK, SEQ=0, ACK=n */ case QUIRK_RSTACK | QUIRK_ACK | QUIRK_SEQ0: outbuf_add("(refused) "); break; /* RST+ACK, SEQ=n, ACK=0 */ case QUIRK_RSTACK: outbuf_add("(invalid-K) "); break; /* RST+ACK, SEQ=n, ACK=n */ case QUIRK_RSTACK | QUIRK_ACK: outbuf_add("(invalid-KA) "); break; /* RST, SEQ=n, ACK=0 */ case 0: outbuf_add("(dropped) "); break; /* RST, SEQ=m, ACK=n */ case QUIRK_ACK: outbuf_add("(dropped 2) "); break; /* RST, SEQ=0, ACK=0 */ case QUIRK_SEQ0: outbuf_add("(invalid-0) "); break; /* RST, SEQ=0, ACK=n */ case QUIRK_ACK | QUIRK_SEQ0: outbuf_add("(invalid-0A) "); break; } } if (nat == 1) outbuf_add("(NAT!) "); else if (nat == 2) outbuf_add("(NAT2!) "); if (ecn) outbuf_add("(ECN) "); if (tos) { if (tos_desc) outbuf_add("[%s] ",tos_desc); else outbuf_add("[tos %d] ",tos); } if (tstamp) outbuf_add("up: %d hrs ",tstamp/360000); if (!no_extra) { a=(uint8_t*)&dst; outbuf_add(" link: %s", lookup_link(mss,1)); } fflush(0); } }
static inline void display_signature(uint8_t ttl,uint16_t tot,uint8_t df,uint8_t* op,uint8_t ocnt, uint16_t mss,uint16_t wss,uint8_t wsc,uint32_t tstamp, uint32_t quirks) { uint32_t j; uint8_t d=0; if (mss && wss && !(wss % mss)) outbuf_add("S%d",wss/mss); else if (wss && !(wss % 1460)) outbuf_add("S%d",wss/1460); else if (mss && wss && !(wss % (mss+40))) outbuf_add("T%d",wss/(mss+40)); else if (wss && !(wss % 1500)) outbuf_add("T%d",wss/1500); else if (wss == 12345) outbuf_add("*(12345)"); else outbuf_add("%d",wss); if (tot < PACKET_BIG) outbuf_add(":%d:%d:%d:",ttl,df,tot); else outbuf_add(":%d:%d:*(%d):",ttl,df,tot); for (j=0; j<ocnt; j++) { switch (op[j]) { case TCPOPT_NOP: outbuf_add("%c", 'N'); d=1; break; case TCPOPT_WSCALE: outbuf_add("W%d",wsc); d=1; break; case TCPOPT_MAXSEG: outbuf_add("M%d",mss); d=1; break; case TCPOPT_TIMESTAMP: outbuf_add("%c",'T'); if (!tstamp) outbuf_add("%c",'0'); d=1; break; case TCPOPT_SACKOK: outbuf_add("%c",'S'); d=1; break; case TCPOPT_EOL: outbuf_add("%c",'E'); d=1; break; default: outbuf_add("?%d",op[j]); d=1; break; } if (j != ocnt-1) outbuf_add("%c",','); } if (!d) outbuf_add("%c",'.'); outbuf_add("%c",':'); if (!quirks) outbuf_add("%c",'.'); else { if (quirks & QUIRK_RSTACK) outbuf_add("%c",'K'); if (quirks & QUIRK_SEQEQ) outbuf_add("%c",'Q'); if (quirks & QUIRK_SEQ0) outbuf_add("%c",'0'); if (quirks & QUIRK_PAST) outbuf_add("%c",'P'); if (quirks & QUIRK_ZEROID) outbuf_add("%c",'Z'); if (quirks & QUIRK_IPOPT) outbuf_add("%c",'I'); if (quirks & QUIRK_URG) outbuf_add("%c",'U'); if (quirks & QUIRK_X2) outbuf_add("%c",'X'); if (quirks & QUIRK_ACK) outbuf_add("%c",'A'); if (quirks & QUIRK_T2) outbuf_add("%c",'T'); if (quirks & QUIRK_FLAGS) outbuf_add("%c",'F'); if (quirks & QUIRK_DATA) outbuf_add("%c",'D'); if (quirks & QUIRK_BROKEN) outbuf_add("%c",'!'); } }
void dump_file_descriptors (outbuffer_t * out) { int i; dev_t dev; struct stat stbuf; outbuf_add(out, "Fd Device Number Inode Mode Uid Gid Size\n"); outbuf_add(out, "-- ------------- ----- ------ ----- ----- ----------\n"); for (i = 0; i < FD_SETSIZE; i++) { /* bug in NeXT OS 2.1, st_mode == 0 for sockets */ if (fstat(i, &stbuf) == -1) continue; #if !defined(WIN32) if (S_ISCHR(stbuf.st_mode) || S_ISBLK(stbuf.st_mode)) dev = stbuf.st_rdev; else #endif dev = stbuf.st_dev; outbuf_addv(out, "%2d", i); outbuf_addv(out, "%13x", dev); outbuf_addv(out, "%9d", stbuf.st_ino); outbuf_add(out, " "); switch (stbuf.st_mode & S_IFMT) { case S_IFDIR: outbuf_add(out, "d"); break; case S_IFCHR: outbuf_add(out, "c"); break; #ifdef S_IFBLK case S_IFBLK: outbuf_add(out, "b"); break; #endif case S_IFREG: outbuf_add(out, "f"); break; #ifdef S_IFIFO case S_IFIFO: outbuf_add(out, "p"); break; #endif #ifdef S_IFLNK case S_IFLNK: outbuf_add(out, "l"); break; #endif #ifdef S_IFSOCK case S_IFSOCK: outbuf_add(out, "s"); break; #endif default: outbuf_add(out, "?"); break; } outbuf_addv(out, "%5o", stbuf.st_mode & ~S_IFMT); outbuf_addv(out, "%7d", stbuf.st_uid); outbuf_addv(out, "%7d", stbuf.st_gid); outbuf_addv(out, "%12d", stbuf.st_size); outbuf_add(out, "\n"); } }
/* * Converts any LPC datatype into an arbitrary string format * and returns a pointer to this string. * Scary number of parameters for a recursive function. */ void svalue_to_string (svalue_t * obj, outbuffer_t * outbuf, int indent, int trailing, int indent2) { int i; /* prevent an infinite recursion on self-referential structures */ if (indent > 20) { outbuf_add(outbuf, "..."); return; } if (!indent2) add_space(outbuf, indent); switch ((obj->type & ~T_FREED)) { case T_INVALID: outbuf_add(outbuf, "T_INVALID"); break; case T_LVALUE: outbuf_add(outbuf, "lvalue: "); svalue_to_string(obj->u.lvalue, outbuf, indent + 2, trailing, 0); break; case T_REF: if(!obj->u.ref->lvalue) kill_ref(obj->u.ref); else { outbuf_add(outbuf, "ref: "); svalue_to_string(obj->u.ref->lvalue, outbuf, indent + 2, trailing, 0); } break; case T_NUMBER: numadd(outbuf, obj->u.number); break; case T_REAL: outbuf_addv(outbuf, "%f", obj->u.real); break; case T_STRING: outbuf_add(outbuf, "\""); outbuf_add(outbuf, obj->u.string); outbuf_add(outbuf, "\""); break; case T_CLASS: { int n = obj->u.arr->size; outbuf_add(outbuf, "CLASS( "); numadd(outbuf, n); outbuf_add(outbuf, n == 1 ? " element\n" : " elements\n"); for (i = 0; i < (obj->u.arr->size) - 1; i++) svalue_to_string(&(obj->u.arr->item[i]), outbuf, indent + 2, 1, 0); if(obj->u.arr->size) svalue_to_string(&(obj->u.arr->item[i]), outbuf, indent + 2, 0, 0); outbuf_add(outbuf, "\n"); add_space(outbuf, indent); outbuf_add(outbuf, " )"); break; } case T_ARRAY: if (!(obj->u.arr->size)) { outbuf_add(outbuf, "({ })"); } else { outbuf_add(outbuf, "({ /* sizeof() == "); numadd(outbuf, obj->u.arr->size); outbuf_add(outbuf, " */\n"); for (i = 0; i < (obj->u.arr->size) - 1; i++) svalue_to_string(&(obj->u.arr->item[i]), outbuf, indent + 2, 1, 0); svalue_to_string(&(obj->u.arr->item[i]), outbuf, indent + 2, 0, 0); outbuf_add(outbuf, "\n"); add_space(outbuf, indent); outbuf_add(outbuf, "})"); } break; #ifndef NO_BUFFER_TYPE case T_BUFFER: outbuf_add(outbuf, "<buffer>"); break; #endif case T_FUNCTION: { svalue_t tmp; object_t *ob; tmp.type = T_ARRAY; outbuf_add(outbuf, "(: "); switch (obj->u.fp->hdr.type) { case FP_LOCAL | FP_NOT_BINDABLE: ob = obj->u.fp->hdr.owner; if (!ob || ob->flags & O_DESTRUCTED) { outbuf_add(outbuf, "0"); break; } outbuf_add(outbuf, function_name(ob->prog, obj->u.fp->f.local.index)); break; case FP_SIMUL: outbuf_add(outbuf, simuls[obj->u.fp->f.simul.index].func->funcname); break; case FP_FUNCTIONAL: case FP_FUNCTIONAL | FP_NOT_BINDABLE: { char buf[10]; int n = obj->u.fp->f.functional.num_arg; outbuf_add(outbuf, "<code>("); for (i=1; i < n; i++) { sprintf(buf, "$%i, ", i); outbuf_add(outbuf, buf); } if (n) { sprintf(buf, "$%i", n); outbuf_add(outbuf, buf); } outbuf_add(outbuf, ")"); break; } case FP_EFUN: { int i; i = obj->u.fp->f.efun.index; outbuf_add(outbuf, query_instr_name(i)); break; } } if (obj->u.fp->hdr.args) { for (i=0; i<obj->u.fp->hdr.args->size; i++) { outbuf_add(outbuf, ", "); svalue_to_string(&(obj->u.fp->hdr.args->item[i]), outbuf, indent, 0, 0); } } } outbuf_add(outbuf, " :)"); break; case T_MAPPING: if (!(obj->u.map->count)) { outbuf_add(outbuf, "([ ])"); } else { outbuf_add(outbuf, "([ /* sizeof() == "); numadd(outbuf, obj->u.map->count); outbuf_add(outbuf, " */\n"); for (i = 0; i <= obj->u.map->table_size; i++) { mapping_node_t *elm; for (elm = obj->u.map->table[i]; elm; elm = elm->next) { svalue_to_string(&(elm->values[0]), outbuf, indent + 2, 0, 0); outbuf_add(outbuf, " : "); svalue_to_string(&(elm->values[1]), outbuf, indent + 4, 1, 1); } } add_space(outbuf, indent); outbuf_add(outbuf, "])"); } break; case T_OBJECT: { svalue_t *temp; if (obj->u.ob->flags & O_DESTRUCTED) { numadd(outbuf, 0); break; } outbuf_addchar(outbuf, '/'); outbuf_add(outbuf, obj->u.ob->obname); if (!max_eval_error && !too_deep_error) { push_object(obj->u.ob); temp = safe_apply_master_ob(APPLY_OBJECT_NAME, 1); if (temp && temp != (svalue_t *) -1 && (temp->type == T_STRING)) { outbuf_add(outbuf, " (\""); outbuf_add(outbuf, temp->u.string); outbuf_add(outbuf, "\")"); } } break; } default: outbuf_addv(outbuf, "!ERROR: GARBAGE SVALUE: %x!", obj->type); } /* end of switch (obj->type) */ if (trailing) outbuf_add(outbuf, ",\n"); } /* end of svalue_to_string() */
void show_mstats(outbuffer_t * ob, char * s) { outbuf_add(ob, "No malloc statistics available with SYSMALLOC\n"); }