#!/usr/bin/ruby -w
# $Id: mem,v 1.6 2001/11/11 16:44:15 hip Exp hip $
#
# Memory monitor for linux 2.4.7
# http://www.xs4all.nl/~hipster
#
# Copyright (C) 2001  Michel van de Ven <hipster@xs4all.nl>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

class Meminfo
  def initialize
    @proc = File.open("/proc/meminfo")
    @interval = (ARGV.shift || 1).to_f
    @maxlines = (ENV['LINES'] || /\d+/.match(`stty size`)[0] || 25).to_i
    @format = "%7s %7s %7s %7s %7s %7s %7s %7s %7s\n"
    @h = Hash.new
    @regex = Regexp.new(/(\w+):\s+(\d+)/)
    trap "SIGINT", lambda { close; exit }
  end

  def run
    lines = 1
    header
    loop{
      lines += 1
      if lines == @maxlines
        header
        lines = 2
      end
      sample
      sleep
    }
  end

  def header
    printf(@format, "avail", "free", "buffers", "cached", "scached", "active",
           "inact", "swap", "swfree")
  end

  def sample
    @proc.seek 0, IO::SEEK_SET
    @proc.readlines[3..-1].each{ |line|
      tag, value = @regex.match(line)[1..2]
      @h[tag] = value.to_i
    }
    printf(@format,
           @h['MemFree'] + @h['Inactive'] + @h['SwapFree'],
           @h['MemFree'], @h['Buffers'], @h['Cached'], @h['SwapCached'],
           @h['Active'], @h['Inactive'],
           @h['SwapTotal'] - @h['SwapFree'], @h['SwapFree'])
  end

  def sleep
    Kernel::sleep @interval
  end

  def close
    @proc.close
  end
end

Meminfo.new.run
