--- xsys.orig.c 2006-06-02 22:49:34.000000000 +0100 +++ xsys.c 2007-10-15 18:46:10.000000000 +0100 @@ -611,40 +611,157 @@ return XCHAT_EAT_ALL; } + +static unsigned int mem_sprint_stats +( + const char* mem_type_name, + unsigned long long total_kb, + unsigned long long free_kb, + char* string_buffer, + int string_buffer_size +) +{ + char* str_i = string_buffer; + int str_buf_remaining = string_buffer_size; + + if ((string_buffer_size <= 0) || (!string_buffer) || (!mem_type_name)) + { + return 0; + } + + str_i = strncpy (str_i, mem_type_name, str_buf_remaining); + str_i += strlen (mem_type_name); + str_i = strncpy (str_i, " : ", str_buf_remaining); + str_i += 3; + + str_buf_remaining -= (str_i - string_buffer); + + if (total_kb >= 1048576) + { + if (percentages == 0) + { + str_i += snprintf + ( + str_i, + str_buf_remaining, + "%.1fGB/%.1fGB free", + (float) (free_kb / 1048576), + (float) (total_kb / 1048576) + ); + } + else + { + str_i += snprintf + ( + str_i, + str_buf_remaining, + "%.1fGB, %.1f%% free", + (float) (total_kb / 1048576), + percentage (&free_kb, &total_kb) + ); + } + } + else + { + if (percentages == 0) + { + str_i += snprintf + ( + str_i, + str_buf_remaining, + "%lldMB/%lldMB free", + (free_kb / 1024), + (total_kb / 1024) + ); + } + else + { + str_i += snprintf + ( + str_i, + str_buf_remaining, + "%lldMB, %.1f%% free", + (total_kb / 1024), + percentage (&free_kb, &total_kb) + ); + } + } + + str_buf_remaining = string_buffer_size - (str_i - string_buffer); + if (str_buf_remaining < 0) + { + // The string has been truncated and won't be NUL character + // terminated. This is unlikely but possible when using snprintf() + + string_buffer[string_buffer_size - 1] = '\0'; + return (string_buffer_size - 1); + } + + return (str_i - string_buffer); +} + + static int mem_cb(char *word[], char *word_eol[], void *userdata) { - unsigned long long mem_total, mem_free, swap_total, swap_free; - char string[bsize]; + unsigned long long mem_total, mem_free, swap_total, swap_free; + char string[bsize]; + char* str_i = string; + int str_buf_remaining = sizeof(string); + if(xs_parse_meminfo(&mem_total, &mem_free, 0) == 1) { xchat_printf(ph, "ERROR in parse_meminfo!"); return XCHAT_EAT_ALL; } + if(xs_parse_meminfo(&swap_total, &swap_free, 1) == 1) { xchat_printf(ph, "ERROR in parse_meminfo!"); return XCHAT_EAT_ALL; } - - if (percentages != 0) - if (mem_total >= 1048576) - snprintf(string, bsize, "Physical : %.1fGB, %.1f%% free | Swap : %.1fGB, %.1f%% free", - (float)mem_total/1048576, percentage(&mem_free, &mem_total), (float)swap_total/1048576, - percentage(&swap_free, &swap_total)); - else - snprintf(string, bsize, "Physical : %lldMB, %.1f%% free | Swap : %lldMB, %.1f%% free", - mem_total/1024, percentage(&mem_free, &mem_total), swap_total/1024, - percentage(&swap_free, &swap_total)); - else - if (mem_total >= 1048576) - snprintf(string, bsize, "Physical : %.1fGB/%.1fGB Free | Swap : %.1fGB/%.1fGB Free", - (float)mem_free/1048576, (float)mem_total/1048576, (float)swap_free/1048576, (float)swap_total/1048576); - else - snprintf(string, bsize, "Physical : %lldMB/%lldMB Free | Swap : %lldMB/%lldMB Free", - mem_free/1024, mem_total/1024, swap_free/1024, swap_total/1024); - - format_output("mem", string, format); + + if (mem_total != 0) + { + str_i += mem_sprint_stats + ( + "Physical", + mem_total, + mem_free, + str_i, + str_buf_remaining + ); + + str_buf_remaining -= (str_i - string); + } + + str_i = strncpy (str_i, " | ", str_buf_remaining); + str_i += 3; + str_buf_remaining -= 3; + + if (swap_total == 0) + { + const char no_swap[] = "Swap : None mounted"; + + str_i = strncpy (str_i, no_swap, str_buf_remaining); + str_i += (sizeof (no_swap) - 1); + str_buf_remaining -= (sizeof (no_swap) - 1); + } + else + { + str_i += mem_sprint_stats + ( + "Swap", + swap_total, + swap_free, + str_i, + str_buf_remaining + ); + + str_buf_remaining -= (str_i - string); + } + + format_output ("mem", string, format); if((long)userdata) xchat_printf(ph, "%s", string);