• Diese Seite verwendet Cookies. Indem du diese Website weiterhin nutzt, erklärst du dich mit der Verwendung von Cookies einverstanden. Erfahre mehr

nette kleinigkeiten

kith

unfuck me!
Mitarbeiter
Themenstarter #1
ich weiss zwar nicht inwiefern dieser thread eine gute idee ist, aber jeder der will, soll mal hier eine kleinigkeit posten die ihm das leben mit openbsd erleichtert, oder erleichtert hat (wie z.b. ein kleiner schlecht dokumentierter flag in irgendeinem *.conf file, oder einer option/flag in einem tool, underrated admin software etc etc. ihr versteht was ich meine). irgendetwas worueber ihr entweder durch zufall, oder nach stundenlangem schweisstreibendem suchen gestolpert seid und was euch persoenlich gut gefallen hat. :)
und damit nachfolgende diesen thread nicht in den dunklen tiefen des forums suchen muessen mach ich ihn mal sticky.

ps. es waere natuerlich noch hilfreich wenn ihr kurz&&praezise den zusammenhang eurer netten kleinigkeit erklaeren koenntet :).
 
Zuletzt bearbeitet:
#2
Code:
# $Id: .zshrc,v 1.6 2003/06/06 14:29:10 dope Exp dope $
#
# Copyright by Christan Schneider <strcat@gmx.net>
# Created under OpenBSD 3.2 with Zsh 4.0.6 

export CVSROOT='CVSROOT=ZENSORED
# $ pkg_add $PKG_PATH/package.tgz
export PKG_PATH='ftp://ftp.openbsd.org/pub/OpenBSD/3.2/packages/i386'
# some alias 
alias pversion='make show VARNAME=VERSION'
alias Comm='make show VARNAME=COMMENT'
alias wth='make show VARNAME=DESCRIPTION
alias scvsup='cd /usr && cvs -q get -P src'
alias pcvsup='cd /usr && cvs -q get -P ports'

# useful function's
# find process and kill it
# ,----[ Sample Output ]
# | $ pskill telnet
# | killing telnet (process 20529)...[1]  + 20529 killed     telnet
# | slaughtered.
# | $ 
# `----
function pskill()
{
        if [[ $# = 0 ]]
        then
        echo "Usage : pskill pattern"
        echo "Exampe: pskill sshd"
        else
        local pid
        pid=$(ps -ax | grep $1 | awk '{ print $1 }')
        echo -n "killing $1 (process $pid)..."
        kill -9 `print -r $pid`
        echo "slaughtered."
        fi
}

# Use 'view' to read manpages, if u want colors, regex - search like
# vi(m), ...
function vman()
{
 /usr/bin/man $* | col -b | /usr/local/bin/view -c 'set ft=man nomod nolist' -
}

# make screenshot of current desktop (use import from ImageMagic)
# See man date(1) and man import(1) for details 
# Note: If you don't have 'import', install ImageMagick
sshot ()
{ sleep 5; import -window root `date "+%Y-%m-%d%--%H:%M:%S"`.jpg }

# search for various types or README file in dir and display them in $PAGER
readme ()
{   
        local files
        files=(./(#i)*(read*me|lue*m(in|)ut)*(ND))
        if (($#files))
        then $PAGER $files
        else
        Print 'No README files.'
        fi
}
  
# find all suid files
suidfind()
{ ls -l /**/*(su0x) }

# Search in /usr/ports/INDEX and shows the path from /usr/ports/
# *without* programversion!
# ,----[ Sample Output ]
# | $ search irssi
# | net/irssi
# | net/irssi,socks
# | net/irssi-icb
# | $ 
# `----
# 
# If u need only the version, simple use oneliner2 and it's look like
# follows:
# ,----[ Sample Output ]
# | $ search irssi
# | irssi-0.8.5
# | irssi-0.8.5-socks
# | irssi-icb-0.13
# | $ 
# `----
function search()
{
 if [[ $# = 0 ]]
    then
    echo "     Usage        : $0 pattern"
    echo "     Example      : search irssi"
    else
    grep -i $1 /usr/ports/INDEX| cut -d\| -f 2
    # oneliner2: grep -i irssi /usr/ports/INDEX | cut -d\| -f 1,1
 fi
}

# Autocomplete for current dir on filetypes
compctl -g '*.Z *.gz *.tgz' + -g '*' zcat gunzip
compctl -g '*.tar.Z *.tar.gz *.tgz *.tar.bz2' + -g '*' tar
compctl -g '*.zip *.ZIP' + -g '*' unzip
compctl -g '*.(mp3|MP3|ogg|OGG|temp|TEMP)' + -g '*(-/)'  mpg123 xmms
compctl -g '*.(htm|html|php|shtml)'  + -g w3m links lynx
compctl -g '*.(jpg|JPG|jpeg|JPEG|gif|GIF|png|PNG|bmp)' + -g '*(-/)' gimp
compctl -g '*.(e|E|)(ps|PS)' + -g '*(-/)' gs ghostview nup psps pstops psmulti psnup psselect gv
compctl -g '*.tex*' + -g '*(-/)' {,la,gla,ams{la,},{g,}sli}tex texi2dvi
compctl -g '*.dvi' + -g '*(-/)' dvips
und noch einiges, aber meine komplette ~/.zshrc wollte ihr nicht haben (753 Zeilen).
Ansonsten kommen noch diverse Scripte wie port-update.pl, add-patch.sh, make-my-kernel.sh, .. dazu.
 

kith

unfuck me!
Mitarbeiter
Themenstarter #3
hmm (dumm das ich kein zsh benutze). war fuer mich erst nach genauem hinschauen verstaendlich. hast du vielleicht sowas fuer ksh || bash? :)
was ist mit den anderen? ;) kommt schon! traut euch!
 
#4
Original geschrieben von kith
hmm (dumm das ich kein zsh benutze).
Dann installier sie (ist die funktionellste Shell).

hast du vielleicht sowas fuer ksh || bash? :)
Die function()'s (bis auf readme() und suidfind()) funktionieren auch unter der Bash && Ksh, aber ich weisz nicht in wieweit die Ksh 'compctl' implementiert hat.
Ansonsten wirf mal 'n Blick auf dotfiles.com und klick Dich da durch die Dotfiles. Ich hab hier nur die Zsh zusaetzlich installiert (die Bash hat ausgedient).

Die restlichen Dateien (~/.vim(rc), ~/.mutt(rc), ...) sind zu komplex um die hier zu posten *g*
 

ookami

Kette rechts!
#5
hallo,

zeigt in der *term, das aktuelle verzeichnis und den aktuellen befehl an. :)

Code:
case $TERM in
	*xterm*|rxvt|(E|a|dt)term)
	precmd () {
		print -Pn "\033]0;{%20<..<%~}\a" 
	}
	preexec () {
		print -Pn "\033]0;<$1> {%20<..<%~} \a" 
	}
	unset TMOUT
	;;
esac
 

cdp_xe

Well-Known Member
#6
Setze ich unter Solaris ein, hab ich aber ursprünglich unter OpenBSD gebastellt. Es müssten nur die Pfade angepasst werden. Im laufe der letzten Monate ist mir dieses Skript als sehr hilfreich erschienen, vielleicht kanns jmd. brauchen.
(auf meiner Seite sind noch ein paar weitere OpenBSD-/Solaris-Skripte zu finden).

Code:
#!/bin/zsh

#  apachelog.sh -  simple apache access_log parser
#  (c) 2003 Steffen Wendzel
#  [email]cdp_xe@gmx.net[/email] | [url]http://cdp.doomed-reality.org[/url]

# usage: ./apachelog <#-of-lines from access_log> \
#                    <#-of-lines from error_log>

# v. 0.2

LOGFILE=/usr/local/apache/logs/access_log 
ERRORLOG=/usr/local/apache/logs/error_log
LINEDEF=200 # default lines access_log
LERRDEF=15  # default lines error_log
SEC=4 # seconds to wait between access_log and error_log

MORE=more # || less

if [ $1 ]; then
	LINES=$1
else
	LINES=$LINEDEF
fi

if [ $2 ]; then
	LINEERR=$2
else
	LINEERR=$LERRDEF
fi

echo "parsing the last $LINES lines of your access_log..."

tail -$LINES $LOGFILE|nawk '

function line (){
  i=1
  for(i=8;i--;i>0){
     printf "__________"
  }
  print ""
}
  
BEGIN{
  line()
  print " Client\t| Code\t| Bytes\t| Request"
  #line()
}

{
  if($1 != "192.168.0.1"){
	print $1 "\t| " $9 "\t| " $10 "\t| " $6" "$7" "$8
  }
}

END{
  line()
}'|egrep -v "root.exe|winnt/system32/cmd.exe|default.ida?"|$MORE


echo "parsing the last $LINES lines of your error_log..."
tail -$LINEERR $ERRORLOG|egrep -v "winnt/system32/cmd.exe|root.exe|default.ida"|$MORE

exit 0
 

CW

Netswimmer
#7
Sich schon mal darüber geärgert, dass es mehr als nur eine tar.gz-Datei zu entpacken gibt und tar aber jeweils eine Datei pro Entpackvorgang schlucken kann?

So gehe ich vor:

1.) Folgende Zeilen als ein ausführbares File anlegen (z.B. untar):

#!/bin/sh

for a in `ls -1 *.gz`; do tar xzvf $a; done

2.) In das Verzeichnis mit den vielen tar-Dateien gehen und folgendes eingeben:

sh untar *


Und prompt werden alle vorhandenen tar-Dateien entpackt.


Gruß

CW
 
Zuletzt bearbeitet:
#10
Hi,

Auszug aus meiner -profile: Startet den SSH-Agent beim Einloggen und lädt meinen Key:

trap '
test -n "$SSH_AGENT_PID" && eval `ssh-agent -k` ;
' 0
if [ "$SSH_AUTH_SOCK" = "" ]
then
eval `ssh-agent`
/usr/bin/tty > /dev/null && ssh-add
fi
 
#11
Noch besser, XDM authentifizierung durch pam_ssh (laed auch den Key automatisch). Sollte theoretisch auch mit login gehen:

Einfach /etc/pam.d/xdm (-CURRENT) editieren und die Zeilen mit pam_ssh auskommentieren. Naeheres siehe pam_ssh(8).

Code:
#
# $FreeBSD: src/etc/pam.d/xdm,v 1.8 2003/04/30 21:57:54 markm Exp $
#
# PAM configuration for the "xdm" service
#

# auth
auth            required        pam_nologin.so          no_warn
#auth           sufficient      pam_krb5.so             no_warn try_first_pass
auth            sufficient      pam_ssh.so              no_warn try_first_pass
auth            required        pam_unix.so             no_warn try_first_pass

# account
#account        required        pam_krb5.so
account         required        pam_unix.so

# session
session         required        pam_ssh.so              want_agent
session         required        pam_permit.so
 
#12
Original geschrieben von MrFixit
Noch besser, XDM authentifizierung durch pam_ssh (laed auch den Key automatisch). Sollte theoretisch auch mit login gehen:

Einfach /etc/pam.d/xdm (-CURRENT) editieren und die Zeilen mit pam_ssh auskommentieren. Naeheres siehe pam_ssh(8).
...ist doch aber für FreeBSD, und ned OpenBSD ;-)
 

Ekimus

Active Member
#13
ToDo Skript für die Konsole

Das ist jetzt zwar nicht OBSD bezogen, mag aber für den einen oder anderen von nutzen sein und da ich keine passende Rubrik auf bsdforen.de gefunden habe, landet es erstmal in diesem Thread. Es handelt sich hierbei um ein Konsolen ToDo Skript, welches ich grad Programmier. Es basiert auf Perl und XML.

Funktionen sind unter anderem, dass anhängen einer Notiz, vergabe von Prioritäten und die Aufteilung in Kategorien.

Download und eine Anleitung gibt es auf der ctodo Page. Über Feedback, verbesserungs Vorschläge, Wünsche, usw. würd ich mich freuen.

Gruss, Ekimus
 
#14
mein pkg_add script

hallo erstmal.

ich hab mir ein kleines perl-script geschrieben welches die arbeit mit pkg_add (insbesondere die suche) vereinfachen soll.

Code:
#!/usr/bin/perl
#
# Description
# ~~~~~~~~~~~
# ppkg lets you search for packages on OpenBSD ftp server. For example, if you are looking for perl lib packages and you don't know the version number, you 
# search for "libwww" and get a list of all packages matching /libwww/i. After this you can install a package by choosing its number.
#
# Note: For install a package you need to be logged in as root.
#
# If you get the error message: "No such file or directory" while trying to install, you are probably not root and the pkg_add command is not found.
#
# Requirements
# ~~~~~~~~~~~~
# ppkg is using Net::FTP. You can find it at [url]http://search.cpan.org/~jhi/perl-5.8.1/lib/Net/FTP.pm[/url]
# Try: perl -MCPAN -e 'install "Net::FTP"'
#
# Installation
# ~~~~~~~~~~~~
# (Save this file to your harddisk.)
#
# $ su
# $ mv ppkg.pl /usr/local/bin/ppkg
# $ chmod +x /usr/local/bin/ppkg
#
# You have to log in again for the changes to take effect.
#
# Author
# ~~~~~~
# [url]http://jaffhar.ath.cx[/url]
# jaffhar _at_ arcor _dot_ de

use strict;
use Net::FTP;

my ($i,$k,@exe,%pkgs,%count,%sv);
my $host = 'ftp.openbsd.org';

@ARGV || die "usage: ppkg <name> [<name> <name> etc.] (searches for /name/i)";

open(OS,"uname -srm|") || die "error when trying 'uname -srm': $!\n";
my ($system,$release,$machine) = split(/ /,<OS>);
close(OS);

if($system eq 'OpenBSD') {
  if($release && chomp($machine)) {

    my $path = '/pub/'.$system.'/'.$release.'/packages/'.$machine;
    print "your system: $system $release $machine\n";
    print "your ftp-dir: [url]ftp://[/url]".$host.$path."\n";
    my $ftp = Net::FTP->new($host) || die "could not connect: $!\n";
    print "connection OK. ";

    $ftp->login('anonymous') || die $ftp->message;
    print "login OK. ";
    $ftp->cwd($path) || die $ftp->message;
    print "cwd OK.\nsearching for matching files...\n";

    foreach ($ftp->ls) {
      my $file = $_;
      foreach (@ARGV) {
        if($file =~ /$_/i) {
          $pkgs{$_} = $pkgs{$_}.":$file";
          $i=1;
        }
      }
    }

    if($i)
    {
      $i=0;
      foreach (keys(%pkgs)) {
        print "total\t$_\n~~~~~\t";
        print "~" x length($_);
        print "\n";
        my @array = split(/:/,$pkgs{$_});
        my $j;
        foreach (@array) { if($_) { $i++; $j++; print "$i\t$j\t$_\n"; $exe[$i] = $_; } }
        $count{$_} = $j;
        print "\n";
      }       

      print "total:\t$i matches found\n";
      foreach (@ARGV) {
        $count{$_} = 0 if !$count{$_};
        print "$_:\t$count{$_} matches found\n";
      }

      print "\nyou have the following options:\n";
      print "  - enter one 'total' package number to install [e.g. 1]\n";
      print "  - enter more than one 'total' package number to install [e.g. 1 2 15 8]\n";
      print "  - enter a range of 'total' package numbers to install [e.g. 1-5]\n";
      print "  - enter 'p<number>' to install all packages from one argument of your search query [e.g. p4]\n";
      my $j;
      foreach (keys(%pkgs)) {
        $j++;
        print "    |- p$j > $_ ($count{$_} packages)\n";
        $sv{$j} = $_;
      }
      print "  - you can combine all these options [e.g. 1 16-21 p1 7 p2]\n";
      print "  * any other key to cancel\n";
      print "install: "; my $input = <STDIN>;

      my @pkgs = split(/ /,$input);
      foreach (@pkgs) {
        $k++;
        if($_ =~ /^([0-9]+)$/) {
          if($exe[$1]) {
            my $cmd = "pkg_add [url]ftp://[/url]".$host.$path."/".$exe[$1];
            print "#cmd($k) pkg($1)\ttrying: $cmd\n";
            open(CMD,"$cmd|") or print "#cmd($k) pkg($1)\terror installing package: $!\n";
            next unless <CMD>;
          }
          else { print "#cmd($k) pkg($1)\tthere is no such package number!\n" }
        }
        elsif($_ =~ /^([0-9]+)\-([0-9]+)$/) {
          if($1 >= $2) { print "#cmd($k)\terror in package number range!\n" }
          else {
            for(my$m=$1;$m<=$2;$m++) {
              if($exe[$m]) {
                my $cmd = "pkg_add [url]ftp://[/url]".$host.$path."/".$exe[$m];
                print "#cmd($k) pkg($m)\ttrying: $cmd\n";
                open(CMD,"$cmd|") or print "#cmd($k) pkg($m)\terror installing package: $!\n";
                next unless <CMD>;
              }
              else { print "#cmd($k) pkg($m)\tthere is no such package number!\n" }
            }
          }
        }
        elsif($_ =~ /^p([0-9]+)$/) {
          if($sv{$1}) {
            my $j;
            my $hash = $pkgs{$sv{$1}};
            my @array = split(/:/,$hash);
            foreach (@array) {
              if($_) {
                $j++;
                my $cmd = "pkg_add [url]ftp://[/url]".$host.$path."/".$_;
                print "#cmd($k) pkg(p$1:$j)\ttrying: $cmd\n";
                open(CMD,"$cmd|") or print "#cmd($k) pkg(p$1:$j)\terror installing package: $!\n";
                next unless <CMD>;                
              }
            }
          }
          else { print "#cmd($k) pkg(p$1)\tthere is no such option!\n" }
        }
        else { print "cancelled. bye!\n"; last }
      }
    }
    else { print "sorry, no matches found.\n" }    
    $ftp->quit;
  }
  else { die "error detecting release version or machine name!\n" }
}
else { die "you need an OpenBSD system!\n" }
beispielausgabe:
-------------------

Code:
tzunami# ppkg amaya bb blubb
your system: OpenBSD 3.4 i386
your ftp-dir: [url]ftp://ftp.openbsd.org/pub/OpenBSD/3.4/packages/i386[/url]
connection OK. login OK. cwd OK.
searching for matching files...
total   bb
~~~~~   ~~
1       1       bbdate-0.2.3.tgz
2       2       bbkeys-0.8.4.tgz
3       3       bbpager-0.3.1.tgz
4       4       bubblemon-1.2.9.tgz
5       5       bubblemon-dockapp-1.4.tgz
6       6       cbb-0.73.tgz
7       7       gabber-0.8.7.tgz
8       8       libbind-9.2.2.tgz
9       9       libbio-2.0.tgz
10      10      libbonobo-2.2.3.tgz
11      11      libbonoboui-2.2.4.tgz
12      12      mac-robber-1.00.tgz
13      13      xbubble-0.2.tgz
14      14      xscrabble-1.0.tgz

total   amaya
~~~~~   ~~~~~
15      1       amaya-5.1p1-motif.tgz
16      2       amaya-english-dict-20011029.tgz
17      3       amaya-french-dict-20011029.tgz

total:  17 matches found
amaya:  3 matches found
bb:     14 matches found
blubb:  0 matches found

you have the following options:
  - enter one 'total' package number to install [e.g. 1]
  - enter more than one 'total' package number to install [e.g. 1 2 15 8]
  - enter a range of 'total' package numbers to install [e.g. 1-5]
  - enter 'p<number>' to install all packages from one argument of your search query [e.g. p4]
    |- p1 > bb (14 packages)
    |- p2 > amaya (3 packages)
  - you can combine all these options [e.g. 1 16-21 p1 7 p2]
  * any other key to cancel
install:
mein englisch ist vll nicht das beste, aber es ist funzt.
ich wuerd mich ueber feedback freuen.
bastel noch gerade an ner colored version fuer xterm.

mfg tzunami
 

megamimi

Active Member
#15
hi,

ähnlich wie das von cdp_xe...
Zeigt nur Anfragen ohne Fehlermeldung an den Apachen an (nützlich um die ganzen exploit mir den ewig langen URIs nicht sehen zu müssen....):
Code:
#! /usr/bin/perl -w
# display only valid apache requests
open(LOGFILE,"$ARGV[0]") or die "Bitte Logfile angeben\n";
while($zeile=<LOGFILE>){
        @tmp=split(/ /,$zeile);
        print $zeile unless ($tmp[$#tmp - 1] ne "200"); 
}
close(LOGFILE);
Also ich könnte nicht mehr ohne...

cu mimi
 

d4mi4n

volksoperator on duty
#16
hab hier ein kleines perlscript zum homeverzeichnis sichern, nicht die beste programierkunst aber trotzdem fein

Code:
#!/usr/local/bin/perl
#
#
#
#   simple script for homedir backups
#   homedir is stored in /tmp/backup/*username*/*date*_*time*.tar.gz   
#   run this script as root	
#

use strict;
use warnings;

my $homedir = "/usr/home/";
my $destdir = "/tmp/backup/";
my $date = &currentdate();

unless(@ARGV){
	&usage();
}

my $username = $ARGV[0];

if (@ARGV > 1){
	&usage();
}

if(! defined getpwnam($username)){
	print "user exists? ...no\nERROR: user $username does not exist\n";
	exit -1;
}else{
	print "user exists? ...yes\n";
}

$homedir .= $username;
if (-d $destdir){
	print "backupdir exists? ...ok\n";
	if (-d ($destdir.$username)){
		print "user-backupdir exists? ...ok\n";
	}else{	
		print "user-backupdir exists? ...no\n";
		mkdir $destdir.$username or die "ERROR: could not make user-backupdirektory\n";
		print "user-backupdir created\n";
	}
}else{	
	print "backupdir exists? ...no\n";
	mkdir $destdir or die "ERROR: could not make backupdirektory\n";
	print "backupdir created\n";
	mkdir $destdir.$username or die "ERROR: could not make user-backupdirektory\n";
	print "user-backupdir created\n";
}

print "running tar for backup...\n";
system ("tar -zcvf $destdir$username/$date.tar.gz $homedir") == 0 or die "system failed, ErrorCode: $?\n";
print "\nbackup successful\nhomedirectory backed up in $destdir$username/$date.tar.gz\n";

sub currentdate(){
	(my $sec,my $min,my $hrs,my $day,my $mon,my $year) = (localtime(time))[0,1,2,3,4,5];
	my $time = sprintf("%02d%02d%02d", $hrs, $min, $sec);
	$year += 1900;
	$mon += 1;
	my $date = sprintf("%04d%02d%02d", $year, $mon, $day);
	return $date."_".$time;
}

sub usage(){
	print "usage: backuphome username\n";
	exit(1);
}
 
#17
tzunami hat gesagt.:
hallo erstmal.

ich hab mir ein kleines perl-script geschrieben welches die arbeit mit pkg_add (insbesondere die suche) vereinfachen soll.

[...]

mein englisch ist vll nicht das beste, aber es ist funzt.
ich wuerd mich ueber feedback freuen.
bastel noch gerade an ner colored version fuer xterm.

mfg tzunami
Respekt. Das Ding hat auf Anhieb meine Anfängermeckereien an der Paketverwaltung von OpenBSD ausgeräumt. Sehr sehr nützlich.
 
#18
function pskill()
{
if [[ $# = 0 ]]
then
echo "Usage : pskill pattern"
echo "Exampe: pskill sshd"
else
local pid
pid=$(ps -ax | grep $1 | awk '{ print $1 }')
echo -n "killing $1 (process $pid)..."
kill -9 `print -r $pid`
echo "slaughtered."
fi
}


Also, grep und awk auf einer Zeile, das muss nicht sein - dann lieber:

pid=$(ps -ax | awk "/$1/ { print \$1 }")

Ausserdem gleich "kill -9" zu benutzen ist auch zu heftig. Man sollte zuerst kill versuchen.

ps -awx | awk "/$1/ { print \$1 }" | xargs kill

Gruss
Alex, der Langweiler
 
#19
afarber hat gesagt.:
Also, grep und awk auf einer Zeile, das muss nicht sein - dann lieber:
Du hast eine Pipe und einen Prozess weniger. Und? Bei einer function() deren Laufzeit =<1s liegt, spielt das IMO nicht die geringste Rolle. Und wieso "heftig"? Die function() heisst ja pskill und nicht psbittebittebendedichdochlieberprozess.
`cd /usr/ports/sysutils/proctools && make && make install clean'; dann hat man eine eklige Portierung von pkill(1) und pgrep(1).
 

oenone

Well-Known Member
#25
strcat hat gesagt.:
Bei OpenBSD nicht.
und ob...
strcat hat gesagt.:
Weil es komfortabler ist. Oder liest Du Deine Mails mit /usr/bin/mail, schreibst sie mit /bin/ed und verwendest TWM als Windowmanager?
das ist etwas ganz anderes. hier geht es um programme, die anderes tun oder mehr komfort bieten (wie du schon meintest).
was ich meinte waren programme, die es in dieser funktionalität schon im grundsystem gibt..
(btw, default-wm bei openbsd ist fvwm, vi ist auch mit dabei)

auf bald
oenone