<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff Foreground: #000 PrimaryPale: #8cf PrimaryLight: #18f PrimaryMid: #04b PrimaryDark: #014 SecondaryPale: #ffc SecondaryLight: #fe8 SecondaryMid: #db4 SecondaryDark: #841 TertiaryPale: #eee TertiaryLight: #ccc TertiaryMid: #999 TertiaryDark: #666 Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}
h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}
.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}
.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}
.tabSelected {color:[[ColorPalette::PrimaryDark]];
background:[[ColorPalette::TertiaryPale]];
border-left:1px solid [[ColorPalette::TertiaryLight]];
border-top:1px solid [[ColorPalette::TertiaryLight]];
border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}
#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}
.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}
.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}
#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}
.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}
.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}
.tiddler .defaultCommand {font-weight:bold;}
.shadow .title {color:[[ColorPalette::TertiaryDark]];}
.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}
.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}
.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}
.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}
.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}
.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}
.imageLink, #displayArea .imageLink {background:transparent;}
.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}
.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}
.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}
.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}
.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}
.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}
#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}
body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}
hr {height:1px;}
a {text-decoration:none;}
dt {font-weight:bold;}
ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}
.txtOptionInput {width:11em;}
#contentWrapper .chkOptionInput {border:0;}
.externalLink {text-decoration:underline;}
.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}
.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}
/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
#mainMenu .tiddlyLinkExisting,
#mainMenu .tiddlyLinkNonExisting,
#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}
.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}
#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}
.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}
#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}
.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}
.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}
.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}
#contentWrapper {display:block;}
#splashScreen {display:none;}
#displayArea {margin:1em 17em 0 14em;}
.toolbar {text-align:right; font-size:.9em;}
.tiddler {padding:1em 1em 0;}
.missing .viewer,.missing .title {font-style:italic;}
.title {font-size:1.6em; font-weight:bold;}
.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}
.tiddler .button {padding:0.2em 0.4em;}
.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}
.footer {font-size:.9em;}
.footer li {display:inline;}
.annotation {padding:0.5em; margin:0.5em;}
* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0 3px 0 3px;}
.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}
.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0; padding-bottom:0;}
.fieldsetFix {border:0; padding:0; margin:1px 0px;}
.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}
* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers: * [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar) * [[MainMenu]]: The menu (usually on the left) * [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]]) <<option txtUserName>> <<option chkSaveBackups>> [[SaveBackups]] <<option chkAutoSave>> [[AutoSave]] <<option chkRegExpSearch>> [[RegExpSearch]] <<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]] <<option chkAnimate>> [[EnableAnimations]] ---- Also see [[AdvancedOptions]]
<<importTiddlers>>
!Entwicklungsumgebung vorbereiten ~5min
*Virtualbox von [[dieser Webseite|http://www.virtualbox.org/wiki/Downloads]] herunterladen und entsprechend installieren.
*Herunterladen der offiziellen [[Gentoo installations CD|http://mirror.switch.ch/ftp/mirror/gentoo/releases/x86/current-iso/]].
*Erstellen einer 6GB grossen MELS Disk und erzeugen einer virtuellen Instanz für Mels. Hierzu Virtualbox starten und auf das blaue Icon ''Neu'' klicken. Danach befolgt man die Anweisugen des Wizards und stellt sicher, dass folgende Einstellungen verwendet werden.
**Betriebsystem: ''Linux'', Version: ''Gentoo''
**Hauptspeicher: ''2048MB'' oder mehr
**Festplatte erzeugen mit folgenden Werten: ''Dynamisch wachsendes Medium'', mit einer Grösse von ''4GB''
*Damit die virtuelle Umgebung auch irgendwas tut, muss man das heruntergeladene Image als Bootmedium verwenden:
**Sicherstellen, dass die erzeugte VM angewählt ist.
**Auf das gelbe Rad ''Ändern'' klicken
**''Massenspeicher'' wählen
**Auf ''leer'' klicken und dann im Bereich //Attribute// auf das CDROM Symbol klicken. Dann wählt man das heruntergeladene Image aus.
**''Netzwerk'' anklicken und ''Erweitert'' wählen. Dann auf ''~Port-Weiterleitung'' klicken und folgende Settings verwenden:
{{{
Name Protokoll Host-IP Host-Port Gast-IP Gast-Port
ssh TCP 127.0.0.1 22022 - 22
}}}
*Mit der eingestellten ~Port-Weiterleitung könnte man prinzipiell von Windows aus auf die Gentoo Umgebung zugreifen. Was jedoch noch fehlt sind die Einstellungen auf dem von CD gebooteten Gentoo System.
**Damit man sich überhaupt am System anmelden kann muss das root Passwort gesetzt werden.
{{{
passwd root
}}}
**Die virtuelle Maschine besitzt einen DHCP Server welcher dem System eine IP Adresse verpasst.
{{{
dhcpcd
}}}
**ssh Daemon starten.
{{{
/etc/init.d/sshd start
}}}
*Jetzt sollte man mittels Putty auf {{{127.0.0.1}}} mittels {{{ssh}}} auf Port {{{22022}}} zugreifen können.
*Die Build Disk sollte als /dev/sda im System ansprechbar sein. Mittels fdisk eine grosse Partition anlegen und mittels ext3 formatieren.
{{{
fdisk /dev/sda
n,p,1,[ENTER],[ENTER],w
mke2fs -m 0.1 -N 786432 /dev/sda1
}}}
* Mounten der Builddisk (damit man auch Platz hat für das kompilieren).
{{{
mount /dev/sda1 /mnt/gentoo
}}}
!MELS Paketsystem erstellen ~110min
Das Paketsystem enthält eine minimalistische Melsumgebung, in welcher die MELS Pakete erzeugt werden. Weiterhin dient sie auch als Kompilierumgebung um später die Komponenten für das Basissystem erstellen zu können. Da in das Paketsystem nicht gebootet werden muss sondern lediglich durch chroot darauf zugegriffen wird, kann man die Gentoo Installation wesentlich beschleunigen.
!!Gentoo vorbereiten
Mit folgenden Schritten wird das Gentoo System vorbereitet und direkt hinein gechrootet.
*Erstellen des Gentoo Pathes.
{{{
GP=/mnt/gentoo/devsystem
mkdir -p $GP
}}}
*Herunterladen und installieren einer aktuellen Stage3 Umgebung
{{{
cd $GP
wget http://mirror.switch.ch/ftp/mirror/gentoo/releases/x86/current-iso/
img=`grep 'stage3-i686-[0-9]*.tar.bz2"' index.html|cut -d'"' -f10`
rm -f index.html
wget http://mirror.switch.ch/ftp/mirror/gentoo/releases/x86/current-iso/$img
tar xjpf $img
rm -f $img
}}}
*Portage herunterladen und installieren um später Pakete herunterladen zu können.
{{{
wget http://mirror.switch.ch/ftp/mirror/gentoo/releases/snapshots/current/portage-latest.tar.bz2
tar xjf portage-latest.tar.bz2 -C ${GP}/usr
rm -f portage-latest.tar.bz2
}}}
*In die Umgebung chrooten.
{{{
cd ${GP}
mount -t proc proc ${GP}/proc
mount --rbind /dev ${GP}/dev
cp -L /etc/resolv.conf ${GP}/etc/
chroot ${GP} /bin/bash
}}}
*Chroot Umgebung vorbereiten, so dass die Umgebung möglichst minimalistisch bleibt aber trotzdem alles hat um Pakete und Basisimage kompilieren zu können. Den Kernel kompiliet man bereits hier, da es Programme geben kann welche .config abfragen oder teile vom Kernel benötigen. Wahlweise als Textfile zum anklicken und copy & pasten [[[2.6.31|./files/.config-2.6.31]]|[[2.6.32|./files/.config-2.6.32]]|[[2.6.38.4|./files/.config-2.6.38.4]]|[[3.0|./files/.config-3.0]]] oder als .gz Datei [[[2.6.31|./files/.config-2.6.31.gz]]|[[2.6.32|./files/.config-2.6.32.gz]]|[[2.6.38.4|./files/.config-2.6.38.4.gz]]|[[3.0|./files/.config-3.0.gz]]].
{{{
env-update && source /etc/profile
export PS1="(chroot) $PS1"
emerge gentoo-sources
cd /usr/src/linux
# .config Datei erstellen
make oldnoconfig
make
echo 'MAKEOPTS="-j2"' >> /etc/make.conf
echo 'USE="-* xml"' >> /etc/make.conf
}}}
!!Pakete re-/emergen
Nun, da alles vorbereitet ist können zum einen alle benötigten Pakete emerged werden, zum anderen den bestehenden Paketen die neuen ~USE Flags angediehen werden. ACHTUNG! Die Reihenfolge in der man die Pakete macht ist relevant. Macht man zuerst WORLD und dann die benötigten Pakete müssen viele Pakete doppelt emerged werden (z.B. auch grosse wie glibc!). Daher erst die einzelnen Pakete und dann world.
{{{
#~90min
pkglist="app-admin/syslog-ng app-arch/bzip2 app-arch/gzip app-arch/tar app-editors/vim\
app-shells/bash net-misc/dhcpcd net-misc/iputils net-misc/openssh net-misc/telnet-bsd\
net-misc/wget sys-apps/acl sys-apps/attr sys-apps/coreutils sys-apps/diffutils sys-apps/file\
sys-apps/findutils sys-apps/gawk sys-apps/grep sys-apps/less sys-apps/man sys-apps/module-init-tools\
sys-apps/net-tools sys-apps/pciutils sys-apps/sed sys-apps/shadow sys-apps/sysvinit\
sys-apps/util-linux sys-apps/which sys-boot/grub sys-fs/e2fsprogs sys-fs/udev sys-libs/glibc\
sys-libs/ncurses sys-libs/pam sys-libs/readline sys-libs/timezone-data sys-libs/zlib sys-process/procps\
sys-process/vixie-cron"
emerge --newuse --update --deep -v $pkglist
# ~3min
emerge --newuse --update --deep -v world
# ~1min, Gentoolkit um die benötigten Pakete "taren" zu können
emerge -v gentoolkit
}}}
!!Paketieren
* Zuerst müssen einige Pfade erzeugt werden in denen die Paketbestandteile installiert werden. Dieser Schritt ist momentan nötig, da mir noch nicht klar ist, was ich alles von einem Paket benötige.
{{{
BP=/mnt
mkdir -pv ${BP}/pkg-{built,pack,src}
cd ${BP}
}}}
* Nun werden alle Pakete aus {{{$pkglist}}} "paketiert".
{{{
for a in ${pkglist}; do PKGDIR=${BP}/pkg-src quickpkg --include-config=y $a;done
}}}
*Jetzt müssen die quickpkg Pakete entpackt werden ({{{pkg-pack}}}), nötige Dateien von den unnötigen getrennt werden, alte Config Files (momentan noch) in einer separaten Struktur gesichert werden und für die executables eine Liste von Libraies erstellt werden. Die Libliste wird verwendet um zu prüfen ob vom eigentlichen System noch Libraries installiert werden müssen (z.B. libz für less???? damit es bzip2 Dateien anschauen kann??). Nachfolgend wird in etwa folgendes getan:
** Archive nach {{{pkg-pack}}} entpacken.
** leere Verzeichnisse löschen.
** Gentoo spezifische Verzeichnisse und Dateien (var-cache etc.) löschen.
** {{{pkg-pack/extrafiles/<PAKETNAME>}}} erzeugen und darin etc files und ev. andere (scripte, Settings etc.) Files verschieben.
** Executables finden und deren lib-abhängigkeiten finden.
** neu paketieren
{{{
for a in ${pkglist};do
echo "extracting `basename $a`"
tar xjpf ${BP}/pkg-src/${a}*.tbz2 -C ${BP}/pkg-pack >/dev/null 2>&1
echo " ...removing empty directories"
for edir in `find ${BP}/pkg-pack -type d|sort -r`;do
[ "$(ls -A $edir)" ] || rmdir $edir
done
echo " ...removing gentoo specific files"
find ${BP}/pkg-pack -name "*.keep*" -exec rm {} \;
echo " ...creating extrafiles"
if [ -d ${BP}/pkg-pack/etc ]; then
mkdir -p ${BP}/pkg-pack/extrafiles/`basename $a`
mv ${BP}/pkg-pack/etc ${BP}/pkg-pack/extrafiles/`basename $a`/
fi
echo " ...creating liblist"
for llist in `find ${BP}/pkg-pack -type f -executable`;do
if [ "`file $llist|grep 'dynamically linked'`" ];then
ldd $llist|grep '/lib/'|sed -e 's#^.*/\(.*\) .*$#\1#g'>>${BP}/liblist
fi
done
echo " ...repacking"
cd ${BP}/pkg-pack
tar cjpf ${BP}/pkg-built/`basename $a`.tbz2 .
cd -
rm -fr ${BP}/pkg-pack
mkdir ${BP}/pkg-pack
done
}}}
*Das nachfolgende Script erzeugt eine Liste von Paketen, welche die Libraries aus {{{liblist}}} enthalten. Damit kann man ''manuell'' prüfen ob alle Pakete installiert wurden. In der Datei {{{missed}}} findet man schlussendlich die fehlenden Bibliotheken.
{{{
for a in `sort -u ${BP}/liblist`;do echo "processing $a";equery b "$a"|cat - >>pkgliblist;done
for a in `sort -u pkgliblist |sed -e 's/-[0-9]*\..*//g'`;do
[ ! -f ${BP}/pkg-built/`basename $a`.tbz2 ] && echo $a>>misslist
done
sort -u liblist > liblistsorted
for a in `cat misslist`;do pkg=$a;
for b in `equery f $a|grep ^/|grep '/lib'`;do
[ ! -z "`grep \`basename $b\` liblistsorted`" ] && lib=$b
done; echo "missing library $lib from package $pkg"; echo $lib>>missed;done
rm -fr ${BP}/{liblist,pkgliblist,misslist,liblistsorted}
}}}
* Jetzt das ganze Spiel noch einmal für die libraries aus {{{missed}}}. Diesen Schritt führt man von Hand so lange aus, bis keine neuen "missing" Libraries angezeigt werden.
{{{
for llist in `cat missed`;do
ldd $llist|grep '/lib/'|sed -e 's#^.*/\(.*\) .*$#\1#g'>>${BP}/liblist
done
for a in `sort -u ${BP}/liblist`;do echo "processing $a";equery b "$a"|cat - >>pkgliblist;done
for a in `sort -u pkgliblist |sed -e 's/-[0-9]*\..*//g'`;do
[ ! -f ${BP}/pkg-built/`basename $a`.tbz2 ] && echo $a>>misslist
done
sort -u liblist > liblistsorted
for a in `cat misslist`;do pkg=$a;
for b in `equery f $a|grep ^/|grep '/lib'`;do
[ ! -z "`grep \`basename $b\` liblistsorted`" ] && lib=$b
done; echo "missing library $lib from package $pkg"; echo $lib>>missed;done
rm -fr ${BP}/{liblist,pkgliblist,misslist,liblistsorted}
}}}
* In {{{missed}}} stehen nun alle "zusätzlich" benötigten Libraries drinn. Im späteren Verlauf dieser Anleitung werden diese Bibliotheken dann dem MELS Basisimage hinzugefügt.
!MELS Basissystem erstellen
Jetzt wo die Pakete "bereitstehen" wird es an der Zeit, das Basissystem zu erstellen.
!!~BusyBox erstellen. ~2min
~BusyBox ist ein Computerprogramm, das viele ~Standard-Unix-Dienstprogramme in einer einzelnen, kleinen ausführbaren Datei vereint. Obwohl die einzelnen Programme nicht den vollen Funktionsumfang der Originalprogramme nachbilden (können) ist ~BusyBox trotzdem ideal um ein simples System auf die Beine zu stellen, wie etwa die MELS Umgebung.
* Auf der Disk ein build Verzeichnis erstellen.
{{{
BD=${BP}/builddir
mkdir -p $BD/
}}}
*~BusyBox bietet seit einiger Zeit "endlich!" die Möglichkeit an, eine vorkompilierte Version für diverse Systeme herunterzuladen. Dadurch muss man sich nicht selber um herumkompilieren. Das folgende Script sollte //hoffentlich// die aktuellste Version herunterladen. Ansonsten händisch von der URL [[http://www.busybox.net/downloads/binaries/|http://www.busybox.net/downloads/binaries/]] holen.
{{{
cd $BD
wget http://www.busybox.net/downloads/binaries/latest/busybox-i686
}}}
*Für diese ~BusyBox Version erstellt man nun alle nötigen links.
{{{
mv busybox-i686 busybox
chmod 777 busybox
mkdir -p ${BP}/bb/{bin,sbin} ${BP}/bb/usr/{bin,sbin}
for a in `./busybox --list-full`; do ln -s /bb/bin/busybox ${BP}/bb/${a};done
mv busybox ${BP}/bb/bin/
}}}
!!Dropbear kompilieren ~7min
Dropbear ist eine schlanke SSH Variante welche ich installiert haben will um vom Hostsystem direkt auf das Gastsystem zugreifen zu können mittels z.B. Putty. Der Sinn dahinter ist der, dass man - in meinen Augen - komfortabler mit der Umgebung arbeiten kann, wenn man eine grosse History, Korrekte Zeichensätze (y/z) oder die Möglichkeit für Copy&Paste besitzt..
*dropbear herunterladen.
{{{
cd $BD
wget http://matt.ucc.asn.au/dropbear/
v=`grep current index.html |cut -d " " -f2`
rm -f index.html
wget http://matt.ucc.asn.au/dropbear/dropbear-${v}.tar.bz2
}}}
*Archiv entpacken
{{{
tar xvjpf dropbear-${v}.*
}}}
*Vor dem kompilieren von Dropbear muss ''options.h'' angepasst werden.
{{{
cd dropbear-${v}
#Falls es Probleme gibt NO_FAST_EXPTMOD Anpassung entfernen
sed -i "s?^/\*#define NO_FAST_EXPTMOD\*/?#define NO_FAST_EXPTMOD?g" options.h
sed -i "s?^#define DROPBEAR_BLOWFISH?/\*#define DROPBEAR_BLOWFISH\*/?g" options.h
sed -i "s?^#define DROPBEAR_TWOFISH256?/\*#define DROPBEAR_TWOFISH256\*/?g" options.h
sed -i "s?^#define DROPBEAR_TWOFISH128?/\*#define DROPBEAR_TWOFISH128\*/?g" options.h
sed -i "s?^#define DO_HOST_LOOKUP?/\*#define DO_HOST_LOOKUP\*/?g" options.h
sed -i "s?/usr/libexec/sftp-server?/bb/bin/sftp-server?g" options.h
}}}
*Dropbear kann wie ~BusyBox als Multilprogramm kompiliert werden. Dadurch werden alle Programme in ein Binary gepackt. Mit nachfolgenden Befehlen wird der SSH Server dropbear sowie das Key Erstellungs Programm dorpbearkey erzeugt. ''Eventuell macht es Sinn scp mit reinzunehmen?'' - ''Achtung!'' Statisches kompilieren funktioniert nicht, da trotzdem gewisse Libraries benötigt werden. Daher wird dropbear nicht statisch kompiliert!
{{{
./configure --disable-zlib
make PROGRAMS="dropbear dropbearkey" MULTI=1
}}}
!!Kernel erstellen ~60min
Mittels {{{make allnoconfig}}} habe ich eine rudimentäre Konfiguraiton erstellt welche dann mittels {{{make menuconfig}}} an die Gegebenheiten von qemu angepasst wurde. Leider ist das .config File derart gross, dass ich die Datei nicht hier im Tiddler zum kopieren anbieten will.
* Zuerst muss man den aktuellsten Kernel von kernel.org herunterladen. Das nachfolgende Script sollte dies //hoffentlich// automatisch erledigen. Ansonsten händisch die URL von [[http://www.kernel.org|http://www.kernel.org]] holen.
{{{
cd $BD
wget -q http://www.kernel.org
URL=`grep "a href" index.html |grep v3.0|head -1|cut -d '"' -f2`
wget $URL
rm -f index.html
}}}
*Kernel entpacken.
{{{
tar xvjpf `basename $URL`
cd linux-3.0*/
}}}
* Die Konfigurationsdatei kann von diesem Wiki heruntergeladen werden. Wahlweise als Textfile zum anklicken und copy & pasten [[[2.6.31|./files/.config-2.6.31]]|[[2.6.32|./files/.config-2.6.32]]|[[2.6.38.4|./files/.config-2.6.38.4]]|[[3.0|./files/.config-3.0]]] oder als .gz Datei [[[2.6.31|./files/.config-2.6.31.gz]]|[[2.6.32|./files/.config-2.6.32.gz]]|[[2.6.38.4|./files/.config-2.6.38.4.gz]]|[[3.0|./files/.config-3.0.gz]]].
*Anhand der alten .config kann man den neuen Kernel kompilieren. Bei den Fragen kann man tendenziell getrost ''ENTER'' drücken bis man wieder im Prompt ist. Danach kopiert man den Kernel in den Build Path, um diesen von dort einfacher in die QEMU Umgebung kopieren zu können.
{{{
make oldnoconfig
make
cp arch/x86/boot/bzImage ../
}}}
!!Image erstellen ~2min
Als letzer Schritt wird ein 500 MB grosses Image File erstellt. In diesem Image wird das ext2 Dateisystem sowie benötigte Verzeichnisse und Dateien erstellt.
* Zunächst wird ein 500 MB grosses Image File erzeugt, welches mittels loopdevice in das laufende System gemountet wird und welches ein ext2 Dateisystem spendiert bekommt.
{{{
cd $BP
mkdir -p mels-img-mp
dd if=/dev/zero of=mels-img bs=1M count=500
mke2fs -F -m 0 mels-img
mount -o loop mels-img ./mels-img-mp
mp=`pwd`/mels-img-mp
}}}
* Es folgt eine minimale Verzeichnisstruktur.
{{{
mkdir -p ${mp}/{bb,bin,dev,etc,lib,mnt,proc,root,sbin,sys,tmp,var}
mkdir -p ${mp}/dev/pts
mkdir -p ${mp}/var/run/nscd
chmod 777 ${mp}/tmp
chmod o+t ${mp}/tmp
ln -s /tmp ${mp}/var/log
ln -s /bb/bin/login ${mp}/bin/login
}}}
* Kopieren der erzeugten Pakete in das Image.
{{{
mkdir -p ${mp}/mpkg
cp ${BP}/pkg-built/* ${mp}/mpkg/
}}}
* Erstellen einiger Dateien im /etc Verzeichnis, welche das ~Basis-System minimal konfigurieren.
{{{
p=${mp}/etc/fstab
echo -en '# /etc/fstab: static file system information.\n'>>${p}
echo -en '#\n'>>${p}
echo -en '# <file system>\t<mount pt>\t<type>\t<options>\t<dump>\t<pass>\n'>>${p}
echo -en '/dev/root\t/\text2\trw,noauto\t0\t1\n'>>${p}
echo -en 'proc\t/proc\tproc\tdefaults\t0\t0\n'>>${p}
echo -en 'devpts\t/dev/pts\tdevpts\tdefaults,gid=5,mode=620\t0\t0\n'>>${p}
echo -en 'tmpfs\t/tmp\ttmpfs\tdefaults\t0\t0\n'>>${p}
echo -en 'sysfs\t/sys\tsysfs\tdefaults\t0\t0\n'>>${p}
p=${mp}/etc/group
echo -en 'root:x:0:\n'>>${p}
echo -en 'tty:x:5:\n'>>${p}
p=${mp}/etc/hostname
echo -en 'mels\n'>>${p}
p=${mp}/etc/inittab
echo -en '# Format for each entry: <id>:<runlevels>:<action>:<process>\n'>>${p}
echo -en '#\n'>>${p}
echo -en '# id == tty to run on, or empty for /dev/console\n'>>${p}
echo -en '# runlevels == ignored\n'>>${p}
echo -en '# action == one of sysinit, respawn, askfirst, wait, and once\n'>>${p}
echo -en '# process == program to run\n'>>${p}
echo -en '\n'>>${p}
echo -en '# Startup the system\n'>>${p}
echo -en 'null::sysinit:/bb/bin/mount -o remount,rw /\n'>>${p}
echo -en 'null::sysinit:/bb/bin/mount -t proc proc /proc\n'>>${p}
echo -en 'null::sysinit:/bb/bin/mount -a\n'>>${p}
echo -en 'null::sysinit:/bb/bin/hostname -F /etc/hostname\n'>>${p}
echo -en 'null::sysinit:/bb/sbin/ifconfig lo 127.0.0.1 up\n'>>${p}
echo -en 'null::sysinit:/bb/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo\n'>>${p}
echo -en '\n'>>${p}
echo -en '# Set up a couple of gettys\n'>>${p}
echo -en 'tty1::respawn:/bb/sbin/getty 38400 tty1\n'>>${p}
echo -en 'tty2::respawn:/bb/sbin/getty 38400 tty2\n'>>${p}
echo -en '\n'>>${p}
echo -en '# Logging junk\n'>>${p}
echo -en 'null::sysinit:/bb/bin/touch /var/log/messages\n'>>${p}
echo -en 'null::respawn:/bb/sbin/syslogd -n -m 0\n'>>${p}
echo -en 'null::respawn:/bb/sbin/klogd -n\n'>>${p}
echo -en 'tty3::respawn:/bb/usr/bin/tail -f /var/log/messages\n'>>${p}
echo -en '\n'>>${p}
echo -en '# Stuff to do for the 3-finger salute\n'>>${p}
echo -en '::ctrlaltdel:/bb/sbin/reboot\n'>>${p}
echo -en '\n'>>${p}
echo -en '# Stuff to do before rebooting\n'>>${p}
echo -en 'null::shutdown:/bb/usr/bin/killall klogd\n'>>${p}
echo -en 'null::shutdown:/bb/usr/bin/killall syslogd\n'>>${p}
echo -en 'null::shutdown:/bb/bin/umount -a -r\n'>>${p}
echo -en 'null::shutdown:/bb/sbin/swapoff -a\n'>>${p}
p=${mp}/etc/passwd
echo -en 'root:x:0:0:root:/root:/bb/bin/sh\n'>>${p}
p=${mp}/etc/shadow
echo -en 'root::10933:0:99999:7:::\n'>>${p}
p=${mp}/etc/profile
echo -en 'export PATH=/sbin:/usr/sbin:/bin:/usr/bin:/bb/sbin:/bb/usr/sbin:/bb/bin:/bb/usr/bin\n'>>${p}
#echo -en 'alias l="ls -alF"\n'>>${p}
p=${mp}/etc/nsswitch.conf
echo -en 'passwd:\t\tfiles\n'>>${p}
echo -en 'shadow:\t\tfiles\n'>>${p}
echo -en 'group:\t\tfiles\n'>>${p}
echo -en 'hosts:\t\tfiles dns\n'>>${p}
p=${mp}/etc/shells
echo -en '/bb/bin/sh\n'>>${p}
}}}
* Erzeugen der notwendigsten Devices, welche zum booten und rudimentären verwenden des Systems benötigt werden.
{{{
pth=${mp}/dev/
devs="\
c:666:5:1:console c:640:29:0:fb0 b:640:3:0:hda b:640:3:1:hda1 b:640:3:2:hda2 \
b:640:3:3:hda3 b:640:3:4:hda4 b:640:3:5:hda5 b:640:3:6:hda6 b:640:3:7:hda7 \
b:640:3:8:hda8 b:640:3:64:hdb b:640:3:65:hdb1 b:640:3:66:hdb2 b:640:3:67:hdb3 \
b:640:3:68:hdb4 b:640:3:69:hdb5 b:640:3:70:hdb6 b:640:3:71:hdb7 b:640:3:72:hdb8 \
c:640:1:2:kmem c:666:1:3:null c:666:1:8:random c:640:10:135:rtc c:666:5:0:tty \
c:666:4:0:tty0 c:600:4:1:tty1 c:640:4:2:tty2 c:666:4:3:tty3 c:666:4:4:tty4 \
c:666:5:2:ptmx c:666:2:0:ptyp0 c:666:2:1:ptyp1 c:666:2:2:ptyp2 c:666:2:3:ptyp3 \
c:666:57:0:ttyP0 c:666:57:1:ttyP1 c:666:57:2:ttyP2 c:666:57:3:ttyP3 \
c:666:204:148:ttyPSC0 c:666:204:149:ttyPSC1 c:666:204:150:ttyPSC2 \
c:666:204:151:ttyPSC3 c:666:4:64:ttyS0 c:666:4:65:ttyS1 c:666:4:66:ttyS2 \
c:666:4:67:ttyS3 c:666:3:0:ttyp0 c:666:3:1:ttyp1 c:666:3:2:ttyp2 c:666:3:3:ttyp3 \
c:666:1:9:urandom c:666:1:5:zero"
for a in ${devs};do
name=`echo $a|cut -d: -f5`
type=`echo $a|cut -d: -f1`
major=`echo $a|cut -d: -f3`
minor=`echo $a|cut -d: -f4`
perm=`echo $a|cut -d: -f2`
mknod -m ${perm} ${pth}${name} ${type} ${major} ${minor}
done
}}}
* Transferieren des vorgängig kompilierten ~BusyBox.
{{{
cd ${BP}/bb
tar cvjpf - bin sbin usr|tar xvjpf - -C ${mp}/bb
}}}
* Den SSH Server dropbear installieren und benötigte Dateien erzeugen.
{{{
cd ${mp}
mkdir -p ${mp}/etc/dropbear
cp -p ${BD}/dropbear*/dropbearmulti bb/bin/
ln -s dropbearmulti bb/bin/dropbear
ln -s dropbearmulti bb/bin/dropbearkey
cp -p /usr/lib/misc/sftp-server bb/bin/sftp-server
bb/bin/dropbearkey -t rsa -f etc/dropbear/dropbear_rsa_host_key
bb/bin/dropbearkey -t dss -f etc/dropbear/dropbear_dss_host_key
}}}
* Zuerst werden einige Libraries für die Namensauflösung händisch hineinkopiert. Diese werde wahrscheinlich bei Bedarf durch linux-gate oder ld-linux aufgerufen und sind durch ldd nicht angezeigt. Jedoch wenn man auf dem Zielsystem die Binary Dateien straced sieht man, dass diese aufgerufen werden. Danach werdn für alle installierten Binärdateien die benötigten Libraries kopiert. Hierzu werden 4 Durchgänge durchgeführt um Libs von Programmen und Libs von Libs zu finden.
{{{
cd ${mp}
for a in libnss_compat.so.2 libnss_files.so.2 libnss_dns.so.2;do
/bin/cp -p /lib/${a} lib/;done
for round in 1 2 3 4;do
for a in `find . -type f -executable \! -type l`;do
ldd ${a}
done|grep -v "not a dynamic executable"|grep -v "linux-gate.so"|grep \
-v "ld-linux.so"|tr -s ' '|cut -d ' ' -f3>/tmp/liste.txt
for b in `cat /tmp/liste.txt`;do /bin/cp -p $b lib/;done
/bin/rm -f /tmp/liste.txt
done
/bin/cp -p /lib/ld-linux.so.2 lib/
}}}
* Nun werden auch noch die Libraires aus {{{missed}}} hierhin kopiert.
{{{
for a in `sort -u ${BP}/missed`;do cp $a ${mp}/lib/;done
}}}
* Damit das konfigurieren der Netzwerkkarte etwas einfacher wird erstelle ich eine History Datei in welcher die Befehle hierzu vorhanden sind.
{{{
p=${mp}/root/.hush_history
echo -en 'ifconfig eth0 10.0.2.15 broadcast 10.0.2.255 netmask 255.255.255.0\n'>>${p}
echo -en 'route add default gw 10.0.2.2\n'>>${p}
echo -en 'echo "nameserver 10.0.2.3" > /etc/resolv.conf\n'>>${p}
}}}
* Zum Schluss kann das Image unmounted und mittels gzip komprimiert werden.
{{{
cd $BP
umount ${mp}
gzip -9 mels-img
}}}
!QEMU Umgebung für Mels erstellen.
* Im Verzeichnis in welchem man qemu installiert hat, holt man sich nun den bzImage Kernel sowie das Image.
{{{
pscp -P 22022 root@melsdev:/mnt/gentoo/devsystem/mnt/builddir/bzImage .
pscp -P 22022 root@melsdev:/mnt/gentoo/devsystem/mnt/mels-img.gz .
}}}
* Da QEMU keine .gz komprimierten Images verarbeiten kann, muss das Image erst entpackt werden (//Zu einem späteren Zeitpunkt, wenn ich weiss wieviel Platz die MELS Umgebung dereinst brauchen wird, kann man das Image sicher so verkleinern, dass auch ein SCP aus qemu heraus nicht ewig dauern wird.//).
* Nun erstellt man eine Batch Datei - z.B. {{{mels.bat}}} - welche das neue MELS Image lädt und startet.
{{{
@echo off
set SDL_VIDEODRIVER=directx
qemu.exe -L . -redir tcp:22022::22 -cpu pentium3 -no-reboot -soundhw pcspk,es1370 -hda mels-img -kernel bzImage -append "init=/bb/sbin/init root=/dev/hda rw panic=60"
}}}
!Pakete herunterladen
*Zu guter Letzt müssen nur noch die erstellen Pakete transferiert werden, so dass man diese mittels {{{wget}}} in der MELS Umgebung herunterladen kann.
{{{
pscp -P root@melsdev:/mnt/gentoo/devsystem/mnt/pkg-built/*.tbz2 .
}}}
[[MelsWiki]]
/*{{{*/
/* SPEZIFISCHE CSS ANPASSUNGEN VON MATTHIAS EGGER */
/* IM SPEZIELLEN UM DAS "SECTION LINKS PLUGIN" BESSER */
/* INTEGRIEREN ZU KOENNEN. */
.viewer
{ border:1px solid gray; -moz-border-radius:.5em; -webkit-border-radius:.5em; padding:.5em; }
.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]]; -moz-border-radius:.5em; -webkit-border-radius:.5em;}
.floatleft
{ float:left; }
.floatright
{ float:right; }
.clear
{ clear:both; }
.groupbox
{ display:block; margin:1em 1em 1em 1em; padding:1.2em 1.3em; -moz-border-radius:.5em;-webkit-border-radius:.5em; border:1px solid transparent; background:#eef; color:#000; }
.outputbox
{ display:block;
margin:0em 0em 0em .5em;
padding:.5em .5em;
-moz-border-radius:.5em;
-webkit-border-radius:.5em;
border:1px solid #6c6;
background:#cfc; color:#000;
font-family:Monospace;
font-size:9pt;
}
.warnbox
{ display:block;
margin:0em 0em 0em .5em;
padding:.5em .5em;
-moz-border-radius:.5em;
-webkit-border-radius:.5em;
border:1px solid #c66;
background:#fcc; color:#000;
font-size:9pt;
}
/* FONT SIZES */
.big
{ font-size:14pt;line-height:120% }
.medium
{ font-size:12pt;line-height:120% }
.normal
{ font-size:9pt;line-height:120% }
.small
{ font-size:8pt;line-height:120% }
.fine
{ font-size:7pt;line-height:120% }
.tiny
{ font-size:6pt;line-height:120% }
.larger
{ font-size:120%; }
.smaller
{ font-size:80%; }
/* DIESE ANPASSUNGEN UEBERSCHREIBEN DIE */
/* BESTEHENDEN CSS EINSTELLUNGEN */
#sidebarTabs .button
{ margin:0px 0.2em; padding:0.2em 0.3em; border:1px solid transparent;
-moz-border-radius:3px; -webkit-border-radius:3px; display:block; }
#sidebarTabs .button:hover
{ border:1px solid #999; }
.tab
{ padding-bottom:1px;
-moz-border-radius-topleft:.5em;
-moz-border-radius-topright:.5em;
-webkit-border-top-left-radius:.5em;
-webkit-border-top-right-radius:.5em;
}
.tabContents
{ -moz-border-radius:.5em; -webkit-border-radius:.5em; }
.tabContents, .tabSelected
{ background-color:#eef; }
.tabUnselected
{ background-color:#79d; }
.tiddler .subtitle
{ display:inline; }
.tagged
{ border:1px solid #999; -moz-border-radius:3px; -webkit-border-radius:3px; }
.tagged
{ opacity:.7; }
.selected .tagged
{ opacity:1; }
.button, .tiddler .button, #sidebarTabs .button
{ margin:0px; padding: 0px .3em; border:1px solid transparent;
-moz-border-radius:3px; -webkit-border-radius:3px; }
.button:hover
{ border:1px solid #999; }
/*}}}*/
/***
|''Name:''|GermanTranslationPlugin|
|''Description:''|Translation of TiddlyWiki into German|
|''Author:''|BesimKaradeniz (besim (at) karadeniz (dot) de)|
|''Version:''|2.6.3|
|''Date:''|Aug 11, 2011|
|''Comments:''|Visit the home of this translation on [[TiddlyWikiDeutsch|http://www.karadeniz.de/tiddlywiki/]] |
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]] |
|''~CoreVersion:''|2.6.3|
***/
//{{{
//-- TiddlyWiki German Translation - 9a3bf25
//-- Maintainer: Besim Karadeniz <besim(-at-)karadeniz(-dot-)de>
//-- Web: www.karadeniz.de/tiddlywiki/
//--
config.locale = "de"; // W3C language tag
if (config.options.txtUserName == "YourName")
merge(config.options,{txtUserName: "IhrName"});
merge(config.tasks,{
save: {text: "speichern", tooltip: "Änderungen in dieses TiddlyWiki speichern"},
sync: {text: "synchronisieren", tooltip: "Änderungen mit anderen TiddlyWiki-Dateien und Servern synchronisieren", content: '<<sync>>'},
importTask: {text: "importieren", tooltip: "Tiddler und Plugins aus anderen TiddlyWiki-Dateien und Servern importieren", content: '<<importTiddlers>>'},
tweak: {text: "optimieren", tooltip: "Erscheinungsbild und Reaktion des TiddlyWiki optimieren", content: '<<options>>'},
upgrade: {text: "upgraden", tooltip: "Upgraden des Kerncodes von TiddlyWiki", content: '<<upgrade>>'},
plugins: {text: "Plugins", tooltip: "Installierte Plugins verwalten", content: '<<plugins>>'}
});
// Optionen, die im Options-Panel oder/in Cookies eingestellt werden koennen
merge(config.optionsDesc,{
txtUserName: "Ihr Benutzername zum Unterzeichnen Ihrer Einträge",
chkRegExpSearch: "Reguläre Ausdrücke in der Suche aktivieren",
chkCaseSensitiveSearch: "Groß-/Kleinschreibung in der Suche aktivieren",
chkIncrementalSearch: "Inkrementelle Zeichen-für-Zeichen-Suche",
chkAnimate: "Animationen aktivieren",
chkSaveBackups: "Beim Speichern ein Backup erstellen",
chkAutoSave: "Automatisch speichern",
chkGenerateAnRssFeed: "RSS-Feed beim Speichern generieren",
chkSaveEmptyTemplate: "Leere Vorlage beim Speichern generieren",
chkOpenInNewWindow: "Externe Links in einem neuen Fenster öffnen",
chkToggleLinks: "Klick auf geöffnete Tiddler lässt diese schließen",
chkHttpReadOnly: "Bearbeitungsfunktionen ausblenden, wenn Zugriff via HTTP",
chkForceMinorUpdate: "Bearbeitungen als kleine Änderungen mit Beibehaltung von Datum und Zeit behandeln",
chkConfirmDelete: "Löschbestätigung vor dem Löschen von Tiddlern",
chkInsertTabs: "Benutzen Sie die Tabulatortaste um Tabulatorzeichen einzufügen anstelle jeweils zum nächsten Feld zu springen",
txtBackupFolder: "Verzeichnisname für Backup Dateien:",
txtMaxEditRows: "Maximale Zahl von Zeilen in einer Textbox eines Tiddlers:",
txtTheme: "Name des zu verwendenden Themes",
txtFileSystemCharSet: "Standard-Zeichensatz beim Speichern von Änderungen (nur Firefox/Mozilla)"});
merge(config.messages,{
customConfigError: "Beim Laden von Plugins sind Fehler aufgetreten. Siehe PluginManager für Details",
pluginError: "Fehler: %0",
pluginDisabled: "Nicht ausgeführt, da durch 'systemConfigDisable'-Tag deaktiviert",
pluginForced: "Ausgeführt, da durch 'systemConfigForce'-Tag erzwungen",
pluginVersionError: "Nicht ausgeführt, da dieses Plugin eine neuere Version von TiddlyWiki erfordert",
nothingSelected: "Nichts ausgewählt. Sie müssen zuerst ein oder mehrere Elemente auswählen",
savedSnapshotError: "Es scheint, dass dieses TiddlyWiki inkorrekt gespeichert wurde. Bitte besuchen Sie http://www.tiddlywiki.com/#Download für Details",
subtitleUnknown: "(unbekannt)",
undefinedTiddlerToolTip: "Der Tiddler '%0' existiert noch nicht",
shadowedTiddlerToolTip: "Der Tiddler '%0' existiert noch nicht, hat aber einen vordefinierten Schatteneintrag",
tiddlerLinkTooltip: "%0 - %1, %2",
externalLinkTooltip: "Externer Link zu %0",
noTags: "Es gibt keine getaggten Tiddler",
notFileUrlError: "Sie müssen zunächst dieses TiddlyWiki in eine Datei speichern, bevor Änderungen gespeichert werden können",
cantSaveError: "Änderungen können nicht gespeichert werden. Mögliche Gründe:\n- Ihr Browser unterstützt das Abspeichern nicht (Firefox, Internet Explorer, Safari und Opera können dies mit richtiger Konfiguration)\n- Der Pfadname zu Ihrem TiddlyWiki enthält ungültige Zeichen\n- Die TiddlyWiki-HTML-Datei wurde verschoben oder umbenannt",
invalidFileError: "Die originale Datei '%0' scheint kein gültiges TiddlyWiki zu sein",
backupSaved: "Backup gespeichert",
backupFailed: "Fehler beim Speichern des Backup",
rssSaved: "RSS-Feed gespeichert",
rssFailed: "Fehler beim Speichern des RSS-Feed",
emptySaved: "Leere Vorlage gespeichert",
emptyFailed: "Fehler beim Speichern der leeren Vorlage",
mainSaved: "TiddlyWiki-Datei gespeichert",
mainFailed: "Fehler beim Speichern der TiddlyWiki-Datei. Ihre Änderungen wurden nicht gespeichert",
macroError: "Fehler im Makro <<%0>>",
macroErrorDetails: "Fehler beim Ausführen von Makro <<%0>>:\n%1",
missingMacro: "Kein entsprechendes Makro vorhanden",
overwriteWarning: "Ein Tiddler namens '%0' existiert bereits. Wählen Sie OK zum Überschreiben",
unsavedChangesWarning: "WARNUNG! Ungespeicherte Änderungen im TiddlyWiki vorhanden\n\nWählen Sie OK zum Speichern\nWählen Sie ABBRECHEN/CANCEL zum Verwerfen",
confirmExit: "--------------------------------\n\nUngespeicherte Änderungen im TiddlyWiki vorhanden. Wenn Sie fortfahren, werden Sie diese Änderungen verlieren\n\n--------------------------------",
saveInstructions: "SaveChanges",
unsupportedTWFormat: "Nicht unterstütztes TiddlyWiki-Format '%0'",
tiddlerSaveError: "Fehler beim Speichern von Tiddler '%0'",
tiddlerLoadError: "Fehler beim Laden von Tiddler '%0'",
wrongSaveFormat: "Speichern im Speicherformat '%0' nicht möglich. Standardformat zum Speichern wird verwendet.",
invalidFieldName: "Ungültiger Dateiname %0",
fieldCannotBeChanged: "Feld '%0' kann nicht geändert werden",
loadingMissingTiddler: "Es wird versucht, den Tiddler '%0' vom Server '%1' bei\n\n'%2' im Workspace '%3' abzurufen",
upgradeDone: "Das Upgrade auf Version %0 ist komplett\n\nKlicken Sie auf 'OK' zum Neuladen des aktualisierten TiddlyWiki",
invalidCookie: "Ungültiger Cookie '%0'"});
merge(config.messages.messageClose,{
text: "schließen",
tooltip: "diesen Textbereich schließen"});
config.messages.backstage = {
open: {text: "Backstage", tooltip: "Öffnen Sie den Backstage-Bereich für Arbeiten an Entwicklungs- und Bearbeitungsaufgaben"},
close: {text: "schließen", tooltip: "Backstage-Bereich schließen"},
prompt: "Backstage: ",
decal: {
edit: {text: "bearbeiten", tooltip: "Den Tiddler '%0' bearbeiten"}
}
};
config.messages.listView = {
tiddlerTooltip: "Klick für den vollen Text dieses Tiddlers",
previewUnavailable: "(Vorschau nicht vorhanden)"
};
config.messages.dates.months = ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November","Dezember"];
config.messages.dates.days = ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"];
config.messages.dates.shortMonths = ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"];
config.messages.dates.shortDays = ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"];
// Suffixe für Datum (englischsprachig), z.B. "1st","2nd","3rd"..."30th","31st"
config.messages.dates.daySuffixes = ["st","nd","rd","th","th","th","th","th","th","th",
"th","th","th","th","th","th","th","th","th","th",
"st","nd","rd","th","th","th","th","th","th","th",
"st"];
config.messages.dates.am = "am";
config.messages.dates.pm = "pm";
merge(config.messages.tiddlerPopup,{
});
merge(config.views.wikified.tag,{
labelNoTags: "keine Tags",
labelTags: "Tags: ",
openTag: "Öffne Tag '%0'",
tooltip: "Zeige Tiddlers mit Tags '%0'",
openAllText: "Öffne alle",
openAllTooltip: "Alle diese Tiddler öffnen",
popupNone: "Keine anderen Tiddler mit '%0' getaggt"});
merge(config.views.wikified,{
defaultText: "Der Tiddler '%0' existiert noch nicht. Doppelklicken zum Erstellen",
defaultModifier: "(fehlt)",
shadowModifier: "(vordefinierter Schatten-Tiddler)",
dateFormat: "DD. MMM YYYY",
createdPrompt: "erstellt"});
merge(config.views.editor,{
tagPrompt: "Geben Sie die Tags durch Leerstellen getrennt ein, [[benutzen Sie doppelte eckige Klammern]] falls nötig, oder wählen Sie vorhandene",
defaultText: "Geben Sie den Text für '%0' ein"});
merge(config.views.editor.tagChooser,{
text: "Tags",
tooltip: "Wählen Sie vorhandene Tags zum Hinzufügen zu diesem Tiddler aus",
popupNone: "Es sind keine Tags definiert",
tagTooltip: "Tag '%0' hinzufügen"});
merge(config.messages,{
sizeTemplates:
[
{unit: 1024*1024*1024, template: "%0\u00a0GB"},
{unit: 1024*1024, template: "%0\u00a0MB"},
{unit: 1024, template: "%0\u00a0KB"},
{unit: 1, template: "%0\u00a0B"}
]});
merge(config.macros.search,{
label: "suchen",
prompt: "Dieses TiddlyWiki durchsuchen",
placeholder: "",
accessKey: "F",
successMsg: "%0 Tiddler gefunden, die %1 enthalten",
failureMsg: "Keine Tiddler gefunden, die %0 enthalten"});
merge(config.macros.tagging,{
label: "Tagging: ",
labelNotTag: "kein Tagging",
tooltip: "Liste der Tiddler, die mit '%0' getaggt sind"});
merge(config.macros.timeline,{
dateFormat: "DD. MMM YYYY"});
merge(config.macros.allTags,{
tooltip: "Tiddler, die mit '%0' getagged sind, anzeigen",
noTags: "Keine getaggten Tiddler vorhanden"});
config.macros.list.all.prompt = "Alle Tiddler in alphabetischer Reihenfolge";
config.macros.list.missing.prompt = "Tiddler, auf die verwiesen wird, die aber nicht existieren";
config.macros.list.orphans.prompt = "Tiddler, auf die nicht von anderen Tiddlern verwiesen wird";
config.macros.list.shadowed.prompt = "Tiddler, für die Standardeinträge existieren";
config.macros.list.touched.prompt = "Tiddlers, die lokal verändert wurden";
merge(config.macros.closeAll,{
label: "alle schließen",
prompt: "Alle angezeigten Tiddler schließen (außer denen, die gerade bearbeitet werden)"});
merge(config.macros.permaview,{
label: "Permaview",
prompt: "Erzeugt einen URL, mit dem auf alle gerade geöffneten Tiddler verwiesen werden kann"});
merge(config.macros.saveChanges,{
label: "Änderungen speichern",
prompt: "Alle Änderungen speichern",
accessKey: "S"});
merge(config.macros.newTiddler,{
label: "Neuer Tiddler",
prompt: "Neuen Tiddler erstellen",
title: "Neuer Tiddler",
accessKey: "N"});
merge(config.macros.newJournal,{
label: "Neues Journal",
prompt: "Neuen Tiddler mit aktuellem Datum und aktueller Zeit erstellen",
accessKey: "J"});
merge(config.macros.options,{
wizardTitle: "Erweiterte Optionen verändern",
step1Title: "Diese Optionen werden mit Cookies in Ihrem Browser gespeichert",
step1Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='false' name='chkUnknown'>Unbekannte Optionen anzeigen</input>",
unknownDescription: "//(unbekannt)//",
listViewTemplate: {
columns: [
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Description', field: 'description', title: "Beschreibung", type: 'WikiText'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
});
merge(config.macros.plugins,{
wizardTitle: "Plugins verwalten",
step1Title: "Aktuell geladene Plugins",
step1Html: "<input type='hidden' name='markList'></input>",
skippedText: "(Dieses Plugin wurde nicht ausgeführt, da es nach dem Start hinzugefügt wurde)",
noPluginText: "Es sind keine Plugins installiert",
confirmDeleteText: "Wollen Sie wirklich folgende Plugins löschen:\n\n%0",
removeLabel: "systemConfig-Tag entfernen",
removePrompt: "systemConfig-Tag entfernen",
deleteLabel: "löschen",
deletePrompt: "Diese Tiddler endgültig löschen",
listViewTemplate: {
columns: [
{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Description', field: 'Description', title: "Beschreibung", type: 'String'},
{name: 'Version', field: 'Version', title: "Version", type: 'String'},
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Größe", type: 'Size'},
{name: 'Forced', field: 'forced', title: "Erzwungen", tag: 'systemConfigForce', type: 'TagCheckbox'},
{name: 'Disabled', field: 'disabled', title: "Deaktiviert", tag: 'systemConfigDisable', type: 'TagCheckbox'},
{name: 'Executed', field: 'executed', title: "Geladen", type: 'Boolean', trueText: "Ja", falseText: "Nein"},
{name: 'Startup Time', field: 'startupTime', title: "Startzeit", type: 'String'},
{name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Fehler", falseText: "OK"},
{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
],
rowClasses: [
{className: 'error', field: 'error'},
{className: 'warning', field: 'warning'}
]},
listViewTemplateReadOnly: {
columns: [
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Description', field: 'Description', title: "Beschreibung", type: 'String'},
{name: 'Version', field: 'Version', title: "Version", type: 'String'},
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Größe", type: 'Size'},
{name: 'Executed', field: 'executed', title: "Geladen", type: 'Boolean', trueText: "Ja", falseText: "Nein"},
{name: 'Startup Time', field: 'startupTime', title: "Startzeit", type: 'String'},
{name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Fehler", falseText: "OK"},
{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
],
rowClasses: [
{className: 'error', field: 'error'},
{className: 'warning', field: 'warning'}
]}
});
merge(config.macros.toolbar,{
moreLabel: "mehr",
morePrompt: "Weitere Funktionen anzeigen",
lessLabel: "weniger",
lessPrompt: "Zusätzliche Befehle verstecken",
separator: "|"
});
merge(config.macros.refreshDisplay,{
label: "aktualisieren",
prompt: "Gesamte TiddlyWiki-Ansicht aktualisieren"
});
merge(config.macros.importTiddlers,{
readOnlyWarning: "Sie können nicht in eine schreibgeschützte TiddlyWiki-Datei importieren. Versuchen Sie diese über eine file:// URL zu öffnen",
wizardTitle: "Tiddler aus anderer Datei oder anderem Server importieren",
step1Title: "Schritt 1: Server oder TiddlyWiki-Datei ausfindig machen",
step1Html: "Typ des Servers auswählen: <select name='selTypes'><option value=''>Wählen...</option></select><br>URL oder Pfadnamen eingeben: <input type='text' size=50 name='txtPath'><br>...oder nach einer Datei browsen: <input type='file' size=50 name='txtBrowse'><br><hr>...oder einen vordefinierten Feed auswählen: <select name='selFeeds'><option value=''>Wählen...</option></select>",
openLabel: "öffnen",
openPrompt: "Verbindung zu dieser Datei oder Server starten",
statusOpenHost: "Verbindung zum Host starten",
statusGetWorkspaceList: "Liste von vorhandenen Workspaces abrufen",
step2Title: "Schritt 2: Workspace auswählen",
step2Html: "Einen Workspace-Namen eingeben: <input type='text' size=50 name='txtWorkspace'><br>...oder ein Workspace auswählen: <select name='selWorkspace'><option value=''>Wählen...</option></select>",
cancelLabel: "abbrechen",
cancelPrompt: "Diesen Import abbrechen",
statusOpenWorkspace: "Workspace wird geöffnet",
statusGetTiddlerList: "Abrufen der Liste von vorhandenen Workspaces",
errorGettingTiddlerList: "Fehler beim Abrufen der Liste der Tiddler, klicken Sie auf ABBRECHEN/CANCEL, um es nochmal zu probieren",
step3Title: "Schritt 3: Zu importierende Tiddler auswählen",
step3Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='true' name='chkSync'>Links dieser Tiddler zum Server erhalten, um nachfolgende Änderungen synchronisieren zu können</input><br><input type='checkbox' checked='false' name='chkSave'>Speichern der Details dieses Servers in einem 'systemServer'Tiddler namens:</input> <input type='text' size=25 name='txtSaveTiddler'>",
importLabel: "importieren",
importPrompt: "Diese Tiddler importieren",
confirmOverwriteText: "Wollen Sie wirklich folgende Tiddler überschreiben:\n\n%0",
step4Title: "Schritt 4: Importieren von %0 Tiddler",
step4Html: "<input type='hidden' name='markReport'></input>",
doneLabel: "Erledigt",
donePrompt: "Diesen Assistenten schließen",
statusDoingImport: "Tiddler werden importiert",
statusDoneImport: "Alle Tiddler importiert",
systemServerNamePattern: "%2 auf %1",
systemServerNamePatternNoWorkspace: "%1",
confirmOverwriteSaveTiddler: "Der Tiddler '%0' existiert bereits. Klicken Sie auf 'OK' um ihn mit den Details dieses Servers zu überschreiben, oder 'Abbrechen', um ihn unverändert zu lassen",
serverSaveTemplate: "|''Eingabe:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n\nDieser Tiddler wurde automatisch erstellt, um Details dieses Servers aufzuzeichnen",
serverSaveModifier: "(System)",
listViewTemplate: {
columns: [
{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Größe", type: 'Size'},
{name: 'Tags', field: 'tags', title: "Tags", type: 'Tags'}
],
rowClasses: [
]}
});
merge(config.macros.upgrade,{
wizardTitle: "Upgraden des Kerncodes von TiddlyWiki",
step1Title: "Update oder Reparatur dieses TiddlyWiki auf die aktuellste Version",
step1Html: "Sie sind dabei, auf die aktuellste Version des TiddlyWiki-Kerncodes upzugraden (von <a href='%0' class='externalLink' target='_blank'>%1</a>). Ihre Inhalte werden während dem Upgrade erhalten bleiben.<br><br>Bitte beachten Sie, dass Kerncode-Updates mit älteren Plugins kollidieren können. Wenn Sie Probleme mit der aktualisierten Datei beobachten, besuchen Sie bitte <a href='http://www.tiddlywiki.org/wiki/CoreUpgrades' class='externalLink' target='_blank'>http://www.tiddlywiki.org/wiki/CoreUpgrades</a>",
errorCantUpgrade: "Upgrade dieses TiddlyWiki nicht möglich. Sie können nur lokal abgespeicherte TiddlyWiki-Dateien upgraden",
errorNotSaved: "Sie müssen zunächst Änderungen speichern, bevor Sie ein Upgrade starten können",
step2Title: "Upgrade-Details bestätigen",
step2Html_downgrade: "Sie sind dabei, von der TiddlyWiki-Version %1 auf die Version %0 downzugraden.<br><br>Der Downgrade auf eine frühere Version von TiddlyWiki wird nicht empfohlen",
step2Html_restore: "Dieses TiddlyWiki scheint bereits die aktuellste Version des Kerncodes (%0) einzusetzen.<br><br>Sie können mit dem Upgrade fortsetzen, um sicherzustellen, dass der Kerncode nicht korrumpiert oder beschädigt wurde",
step2Html_upgrade: "Sie sind dabei, von der TiddlyWiki-Version %1 auf die Version %0 upzugraden",
upgradeLabel: "upgraden",
upgradePrompt: "Vorbereiten des Upgrade-Prozesses",
statusPreparingBackup: "Backup vorbereiten",
statusSavingBackup: "Backup-Datei speichern",
errorSavingBackup: "Ein Problem mit dem Speichern der Backup-Datei ist aufgetreten",
statusLoadingCore: "Kerncode laden",
errorLoadingCore: "Fehler beim Laden des Kerncodes",
errorCoreFormat: "Fehler im neuen Kerncode",
statusSavingCore: "Neuen Kerncode speichern",
statusReloadingCore: "Neuen Kerncode neu laden",
startLabel: "starten",
startPrompt: "Upgrade-Prozess starten",
cancelLabel: "abbrechen",
cancelPrompt: "Upgrade-Prozess abbrechen",
step3Title: "Upgrade abgebrochen",
step3Html: "Sie haben den Upgrade-Prozess abgebrochen"
});
merge(config.macros.sync,{
listViewTemplate: {
columns: [
{name: 'Selected', field: 'selected', rowName: 'title', type: 'Selector'},
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
{name: 'Server Type', field: 'serverType', title: "Server-Typ", type: 'String'},
{name: 'Server Host', field: 'serverHost', title: "Server-Host", type: 'String'},
{name: 'Server Workspace', field: 'serverWorkspace', title: "Server-Workspace", type: 'String'},
{name: 'Status', field: 'status', title: "Status der Synchronisation", type: 'String'},
{name: 'Server URL', field: 'serverUrl', title: "Server-URL", text: "View", type: 'Link'}
],
rowClasses: [
],
buttons: [
{caption: "Diese Tiddler synchronisieren", name: 'sync'}
]},
wizardTitle: "Mit externen Servern oder Dateien synchronisieren",
step1Title: "Wählen Sie die Tiddler aus, die Sie synchronisieren möchten",
step1Html: '<input type="hidden" name="markList"></input>',
syncLabel: "synchronisieren",
syncPrompt: "Diese Tiddler synchronisieren",
hasChanged: "Verändert während Trennung",
hasNotChanged: "Unverändert während Trennung",
syncStatusList: {
none: {text: "...", display:'none', className:'notChanged'},
changedServer: {text: "Auf dem Server geändert", display:null, className:'changedServer'},
changedLocally: {text: "Im ausgesteckten Zustand geändert", display:null, className:'changedLocally'},
changedBoth: {text: "Im ausgesteckten Zustand und auf dem Server geändert", display:null, className:'changedBoth'},
notFound: {text: "Auf dem Server nicht gefunden", display:null, className:'notFound'},
putToServer: {text: "Aktualisierung auf dem Server gespeichert", display:null, className:'putToServer'},
gotFromServer: {text: "Aktualisierung vom Server abgerufen", display:null, className:'gotFromServer'}
}
});
merge(config.macros.annotations,{
});
merge(config.commands.closeTiddler,{
text: "schließen",
tooltip: "Diesen Tiddler schließen"});
merge(config.commands.closeOthers,{
text: "andere schließen",
tooltip: "Alle anderen Tiddler schließen"});
merge(config.commands.editTiddler,{
text: "bearbeiten",
tooltip: "Diesen Tiddler bearbeiten",
readOnlyText: "betrachten",
readOnlyTooltip: "Quellcode dieses Tiddlers betrachten"});
merge(config.commands.saveTiddler,{
text: "fertig",
tooltip: "Änderungen an diesem Tiddler speichern"});
merge(config.commands.cancelTiddler,{
text: "abbrechen",
tooltip: "Änderungen an diesem Tiddler verwerfen",
warning: "Wollen Sie wirklich Änderungen in '%0' verwerfen?",
readOnlyText: "fertig",
readOnlyTooltip: "Diesen Tiddler normal anzeigen"});
merge(config.commands.deleteTiddler,{
text: "löschen",
tooltip: "Diesen Tiddler löschen",
warning: "Wollen Sie '%0' wirklich löschen?"});
merge(config.commands.permalink,{
text: "Permalink",
tooltip: "Permalink für diesen Tiddler"});
merge(config.commands.references,{
text: "Referenzen",
tooltip: "Alle Tiddler zeigen, die auf diesen verweisen",
popupNone: "Keine Referenzen"});
merge(config.commands.jump,{
text: "springen",
tooltip: "Zu anderem, geöffneten Tiddler springen"});
merge(config.commands.syncing,{
text: "Synchronisierung läuft",
tooltip: "Synchronisation dieses Tiddlers mit einem Server oder einer externen Datei kontrollieren",
currentlySyncing: "<div>Aktuell am Synchronisieren mit <span class='popupHighlight'>'%0'</span> zu:</"+"div><div>Host: <span class='popupHighlight'>%1</span></"+"div><div>Workspace: <span class='popupHighlight'>%2</span></"+"div>", // Hinweis - Das Schließen des <div>-Tag verlassen
notCurrentlySyncing: "Derzeit keine Synchronisierung",
captionUnSync: "Synchronisierung dieses Tiddlers stoppen",
chooseServer: "Diesen Tiddler mit anderem Server synchronisieren:",
currServerMarker: "\u25cf ",
notCurrServerMarker: " "});
merge(config.commands.fields,{
text: "Felder",
tooltip: "Erweiterte Felder dieses Tiddlers anzeigen",
emptyText: "Keine erweiterten Felder für diesen Tiddler vorhanden",
listViewTemplate: {
columns: [
{name: 'Field', field: 'field', title: "Feld", type: 'String'},
{name: 'Value', field: 'value', title: "Wert", type: 'String'}
],
rowClasses: [
],
buttons: [
]}});
merge(config.shadowTiddlers,{
DefaultTiddlers: "[[GettingStarted]]",
MainMenu: "[[GettingStarted]]",
SiteTitle: "Mein TiddlyWiki",
SiteSubtitle: "ein wiederverwendbares nichtlineares, persönliches ~Web-Notizbuch",
SiteUrl: "",
SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD. MMM YYYY" "Journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "Optionen \u00bb" "Optionen von TiddlyWiki ändern">>',
SideBarTabs: '<<tabs txtMainTab "Zeitachse" "Zeitachse" TabTimeline "Alles" "Alle Tiddler" TabAll "Tags" "Alle Tags" TabTags "Mehr" "Weitere Listen" TabMore>>',
TabMore: '<<tabs txtMoreTab "Fehlend" "Fehlende Tiddler" TabMoreMissing "Waisen" "Verwaiste Tiddler" TabMoreOrphans "Schatten" "Tiddler mit Schatteneinträgen" TabMoreShadowed>>'
});
merge(config.annotations,{
AdvancedOptions: "Dieser Schatten-Tiddler bietet Zugang zu diversen erweiterten Optionen",
ColorPalette: "Diese Werte in diesem Schatten-Tiddler legen das Farbschema der Benutzerschnittstelle des TiddlyWiki fest",
DefaultTiddlers: "Die in diesem Schatten-Tiddler aufgelisteten Tiddler werden automatisch beim Start des TiddlyWiki angezeigt",
EditTemplate: "Die HTML-Vorlage in diesem Schatten-Tiddler legt das Aussehen von Tiddler während ihrer Bearbeitung fest",
GettingStarted: "Dieser Schatten-Tiddler bietet eine einfache Bedienungsanleitung",
ImportTiddlers: "Dieser Schatten-Tiddler bietet Zugang zum Import von Tiddler",
MainMenu: "Dieser Schatten-Tiddler dient als Container für das Hauptmenü in der linksseitigen Spalte des Bildschirms",
MarkupPreHead: "Dieser Tiddler wird an der Spitze der <head>-Sektion der HTML-Datei des TiddlyWiki eingefügt",
MarkupPostHead: "Dieser Tiddler wird am Ende der <head>-Sektion der HTML-Datei des TiddlyWiki eingefügt",
MarkupPreBody: "Dieser Tiddler wird an der Spitze der <body>-Sektion der HTML-Datei des TiddlyWiki eingefügt",
MarkupPostBody: "Dieser Tiddler wird am Ende der <body>-Sektion der HTML-Datei des TiddlyWiki unmittelbar nach dem Scriptblock eingefügt",
OptionsPanel: "Dieser Schatten-Tiddler dient als Container für das einblendbare Optionsfeld in der rechtsseitigen Seitenleiste",
PageTemplate: "Die HTML-Vorlage in diesem Schatten-Tiddler legt das allgemeine Aussehen des TiddlyWiki fest",
PluginManager: "Dieser Schatten-Tiddler bietet Zugang zum Plugin-Manager",
SideBarOptions: "Dieser Schatten-Tiddler dient als Container für das Optionsfeld in der rechtsseitigen Seitenleiste",
SideBarTabs: "Dieser Schatten-Tiddler dient als Container für das Tab-Panel in der rechtsseitigen Seitenleiste",
SiteSubtitle: "Dieser Schatten-Tiddler enthält den zweiten Teil der Seitenüberschrift",
SiteTitle: "Dieser Schatten-Tiddler enthält den ersten Teil der Seitenüberschrift",
SiteUrl: "Dieser Schatten-Tiddler sollte den vollständigen Ziel-URL der Veröffentlichung enthalten",
StyleSheetColors: "Dieser Schatten-Tiddler enthält CSS-Definitionen bezüglich der Farbe von Seitenelementen. ''DIESEN TIDDLER NICHT BEARBEITEN'', fügen Sie Ihre Änderungen stattdessen in den StyleSheet-Schatten-Tiddler ein",
StyleSheet: "Dieser Tiddler kann benutzerspezifische CSS-Definitionen enthalten",
StyleSheetLayout: "Dieser Schatten-Tiddler enthält CSS-Definitionen bezüglich dem Aussehen von Seitenelementen. ''DIESEN TIDDLER NICHT BEARBEITEN'', fügen Sie Ihre Änderungen stattdessen in den StyleSheet-Schatten-Tiddler ein",
StyleSheetLocale: "Dieser Schatten-Tiddler enthält CSS-Definitionen bezüglich lokale Übersetzungen",
StyleSheetPrint: "Dieser Schatten-Tiddler enthält CSS-Definitionen zum Drucken",
SystemSettings: "Dieser Tiddler wird zum Speichern von Konfigurationsoptionen für dieses TiddlyWiki-Dokument genutzt",
TabAll: "Dieser Schatten-Tiddler enthält den Inhalt des 'Alles'-Tab in der rechtsseitigen Seitenleiste",
TabMore: "Dieser Schatten-Tiddler enthält den Inhalt des 'Mehr'-Tab in der rechtsseitigen Seitenleiste",
TabMoreMissing: "Dieser Schatten-Tiddler enthält den Inhalt des 'Fehlend'-Tab in der rechtsseitigen Seitenleiste",
TabMoreOrphans: "Dieser Schatten-Tiddler enthält den Inhalt des 'Waisen'-Tab in der rechtsseitigen Seitenleiste",
TabMoreShadowed: "Dieser Schatten-Tiddler enthält den Inhalt des 'Schatten'-Tab in der rechtsseitigen Seitenleiste",
TabTags: "Dieser Schatten-Tiddler enthält den Inhalt des 'Tags'-Tab in der rechtsseitigen Seitenleiste",
TabTimeline: "Dieser Schatten-Tiddler enthält den Inhalt des 'Zeitachse'-Tab in der rechtsseitigen Seitenleiste",
ToolbarCommands: "Dieser Schatten-Tiddler legt fest, welche Befehle in Tiddler-Toolbars angezeigt werden",
ViewTemplate: "Die HTML-Vorlage in diesem Schatten-Tiddler legt das Aussehen der Tiddler fest"
});
// Uebersetzungen von Schatten-Tiddlern ausserhalb der offiziellen lingo.js
merge(config.shadowTiddlers,{
OptionsPanel: "Diese [[Interface-Einstellungen|InterfaceOptions]] zur Anpassung von TiddlyWiki werden in Ihrem Browser gespeichert\n\nIhr Benutzername zum Unterzeichnen Ihrer Einträge. Bitte als WikiWord (z.B. KlausBrandmüller) schreiben\n\n<<option txtUserName>>\n<<option chkSaveBackups>> [[Backups speichern|SaveBackups]]\n<<option chkAutoSave>> [[Automatisch speichern|AutoSave]]\n<<option chkRegExpSearch>> [[RegExp Suche|RegExpSearch]]\n<<option chkCaseSensitiveSearch>> [[Groß-/Kleinschreibung in Suche|CaseSensitiveSearch]]\n<<option chkAnimate>> [[Animationen aktivieren|EnableAnimations]]\n\n----\[[Erweiterte Optionen|AdvancedOptions]]\nPluginManager\nImportTiddlers",
GettingStarted: "Um mit diesem TiddlyWiki zu starten, sollten Sie folgende Tiddler modifizieren:\n* SiteTitle & SiteSubtitle: Den [[Titel|SiteTitle]] und [[Untertitel|SiteSubtitle]] der Site, wie oben angezeigt (nach dem Speichern werden diese auch in der Titelzeile des Browsers angezeigt)\n* MainMenu: Ihr Inhaltsverzeichnis (für gewöhnlich Links)\n* DefaultTiddlers: Beinhaltet die Namen der Tiddler, die Sie angezeigt haben möchten, wenn das TiddlyWiki geöffnet wird.\nSie sollten zudem Ihren Benutzernamen zum Unterzeichnen Ihrer Bearbeitungen eingeben: <<option txtUserName>>",
ViewTemplate: "<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></div>\n<div class='title' macro='view title'></div>\n<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (erstellt am <span macro='view created date'></span>)</div>\n<div class='tagging' macro='tagging'></div>\n<div class='tagged' macro='tags'></div>\n<div class='viewer' macro='view text wikified'></div>\n<div class='tagClear'></div>",
InterfaceOptions: "Die [[Interface-Einstellungen|InterfaceOptions]] werden angezeigt, wenn Sie rechts auf 'Optionen' klicken. Sie werden mit einem Cookie in Ihrem Browser gespeichert, um sie zwischen den Aufrufen zu sichern. Nähere Informationen zu den einzelnen Funktionen finden Sie, wenn Sie die Funktion selbst anklicken.",
WikiWord: "Ein WikiWord ist ein Wort, das aus mehreren einzelnen Wörtern zusammengesetzt ist, in dem jedes Wort mit einem Großbuchstaben beginnt und eine individuelle Seite bezeichnet.",
SaveBackups: "[[Backups speichern|SaveBackups]] ist eine Funktion, mit der automatisch bei jedem Abspeichern ein Backup erstellt wird.",
AutoSave: "[[Automatisches Speichern|AutoSave]] speichert automatisch Änderungen jedes Mal, wenn Sie einen Tiddler bearbeiten. Damit sinken die Chancen, dass Sie Daten verlieren. Beachten Sie jedoch, dass bei aktivierter [[Backup-Funktion|SaveBackups]] natürlich auch eine Menge Backup-Dateien erstellt werden. Entscheiden Sie sich deshalb für die eine oder andere Funktion.",
RegExpSearch: "Mit der [[RegExp Suche|RegExpSearch]] können Sie mit regulären Suchausdrücken flexible Suchanfragen vornehmen.",
CaseSensitiveSearch: "Die Unterscheidung der [[Groß-/Kleinschreibung in Suche|CaseSensitiveSearch]] tut genau dies.",
EnableAnimations: "Diese Funktion aktiviert Animationen, wenn Sie einen Tiddler öffnen oder schließen.",
GenerateAnRssFeed: "Wenn Sie [[RSS-Feed generieren|GenerateAnRssFeed]] aktivieren, speichert TiddlyWiki automatisch einen RSS-2.0-gültigen Feed, so bald Ihr TiddlyWiki gespeichert wird. Der Feed hat den gleichen Dateinamen wie das TiddlyWiki, lediglich jedoch mit der Endung '.xml'.",
OpenLinksInNewWindow: "Diese Funktion öffnet externe Links in einem neuen ~Browser-Fenster.",
SaveEmptyTemplate: "Diese Funktion erwirkt, dass beim Abspeichern von Änderungen eine leere Vorlage von TiddlyWiki erzeugt wird. Dies ist als Hilfe gedacht für Entwickler, die Adaptionen von TiddlyWiki bereitstellen. Die Funktion ist nicht erforderlich, wenn Sie ein normaler Benutzer sind.",
HideEditingFeatures: "Ist diese Funktion aktiviert, werden die Bearbeitungsfunktionen ausgeblendet, wenn das TiddlyWiki über HTTP aufgerufen wird. Der Benutzer hat dann die Möglichkeit, den Tiddler zwar betrachten zu können, aber nicht zu bearbeiten.",
MinorChanged: "Manchmal ist es sinnvoll, dass bei kleinen Änderungen der Tiddler in der Zeitachse nicht automatisch an den Anfang gesetzt wird. Mit Aktivierung dieser Funktion werden alle Bearbeitungen von Tiddlern als kleine Änderungen betrachtet und das Änderungsdatum nicht geändert.",
ConfirmBeforeDeleting: "Bei Aktivierung dieser Funktion fordert TiddlyWiki eine Bestätigung des Benutzers an, wenn ein Tiddler gelöscht werden soll."});
//}}}
In diesem Tiddler sollen alle Kapitel von MELS verlinkt werden. Dabei geht es nicht um tolles Layout etc. sondern nur um den reinen Text. [[MELSBUCH - 00 - Widmung]] [[MELSBUCH - 01 - Einleitung]] [[MELSBUCH - 02 - Prolog]] [[MELSBUCH - 03 - Der Anfang]] [[MELSBUCH - 04 - Der Bootvorgang]]
Dieses Buch ist all denen gewidmet, die den Mut aufbringen in eine neue Welt zu ergründen. Menschen die - wie ich vor langer Zeit - endlich tiefer eintauchen wollen und die Geheimnisse "dahinter" erforschen möchten. Linux ist hierfür das ideale Betriebsystem, denn es lässt einen bis hinunter zum Sourcecode alles selber anschauen und "anfassen". Diese Freiheit birgt aber auch Gefahren. Viel zu schnell kann man sich in der Komplexität verlieren und treibt plötzlich kurslos im offenen Meer des Wissens. Wer einen starken Willen hat, der fährt im Zick-Zack durch dieses Meer, bis er den sicheren Linux Hafen gefunden hat. Im Gepäck hat dieser eine Menge an Wissen, welches er sich auf seiner Reise angeeignet hat. Die meisten jedoch scheuen diesen beschwerlichen Weg und geben nach kurzer Zeit wieder auf. Sie lassen sich wieder an den Strand zurücktreiben, von wo aus sie ihre Reise angetreten haben. Das einzige was übrigbleibt ist die Wehmut im Herzen und die Hoffnung, es irgendwann nochmals zu versuchen und dann doch noch zu schaffen. Diesen Menschen soll das vorliegende Buch als Reiseführer dienen. Es zeigt auf wo geschickte Manöver zum Ziel führen, wie man Strudel umgeht und wie Klippen umschift werden. Wer während der Reise die Augen offen, die Ohren gespitzt und den Geist wach hält, der wird am Ende genug Wissen besitzen um den sicheren Linux Hafen zu finden, und sich in der neuen Welt zurechtzufinden. In diesem Sinne wünsche ich jedem reisenden gute Fahrt! Matthias Egger, im Juli 2011
!Worum geht es in diesem Buch? Manchmal habe ich das Gefühl, dass es in diesem Buch einzig um diesen verrückten Pinguin Names Mux geht. Aber ich will nicht unfair sein. Schliesslich war es Mux, der mich in diese fantastische Welt mit all diesen interessanten Charakteren gebracht hat. Obwohl, wenn ich es mir recht überlege ist das ja eigentlich auch seine Aufgabe... Aber ich glaube ich schweife ab. Primär ist das hier sowas wie ein Reisetagebuch. Andere würden sogar soweit gehen und dieses Buch als einen "Reiseführer durch Linux" bezeichnen. Das ist mir dann jedesmal peinlich weil es sich anhört als wenn ich hier sowas wie den "Reiseführer durch die Galaxis" geschrieben hätte. Dabei beschreibe ich doch nur meine ersten Schritte in der Welt von Linux und wie ich diese erlebt habe. Gut, wer meine Ausführungen nicht einfach nur überfliegt (merke; zum überfliegen von irgendetwas verwende man einen Flugsimulator!) der wird sogar etwas lernen. Apropos lernen. Wer jetzt glaubt dass dieser Reisebericht so etwas wie ein Dia Abend bei Onkel Fritz wird, der hat sich gewaltig geschnitten (Der Verbandskasten ist übrigens hinten links in der Truhe!). Wer nur konsumierend vor dem Monitor sitzen und dabei über Nacht ein erfahrener Linux Anwender werden will, der sollte sich lieber an die nächstgelegene Sekte wenden. Die suchen immer solch naiven Typen! Nein, nein, nein... Dieser Reisebericht verlangt dem Leser einiges ab. Er muss aktiv mitarbeiten. Das fängt damit an, dass im Reisebericht nur erwähnt wird was Mux oder jemand anderes aus MELSTown mir beibringt. Ob man das einfach glaubt oder ob man das selber nochmals ausprobieren und prüfen möchte muss jeder für sich selber entscheiden. Weiterhin wird in meinem Bericht einiges von Virtux's Wissen widergegeben. Obwohl das ganze eher einen theoretischen Charakter hat wir das lesen dieser Blöcke dringendst angeraten. Da steckt nähmlich eine Menge Know-How drinn, welches für das spätere Verstädnis von Nutzen ist. Aber keine Panik. So trocken wie sich das alles anhört wird es keinesfalls! Jedenfalls geht es wie schon gesagt in diesem Bericht um "meine" Reise in die Linux Welt, zu der mich Mux - naja - überredet hat. Im ersten Teil dieses Reiseführers wird erklärt wie man sich beim Händler Sellux aus MELSTown einen kostenlosen Rechner besorgen kann. Danach wird der Rechner so konfiguriert, dass man alle Beispiele aus dem Reisebericht darauf selber nachspielen und ausprobieren kann. Der Vorteil ist, man braucht seinen eigenen Rechner keiner Gefahr auszusetzen wie etwa einer Umpartitionierung und deren zerstörerischen Wirkung bei unsachgemässer Handhabung. Nach dem aktiven durcharbeiten des ersten Teiles ist man bereit für die eigentliche Reise in die Linux Welt. Im zweiten Teil der Dokumentation wird dann auch erklärt wie man hierfür auf seinem eigenen Rechner ein Gentoo basiertes Linux System installiert. Gentoo deshalb, weil dies das flexibelste aller Linuxe ist. Vieles in diesem System muss selber gemacht werden, damit überhaupt etwas funktioniert. Doch im Gegensatz zu z.B. einem LFS (Linux From Scratch) System verfügt Gentoo über einen geniales Paketesystem namens Portage. Dieses System erleichtert nicht nur das installieren neuer Pakete aus den Sourcen sondern löst automatisch benötigte Abhängigkeiten auf und ist - was die Aktualität angeht - kaum zu übertreffen. Ausserdem lässt sich während der Installation das Wissen aus dem ersten Teil sogleich praktisch anwenden. Kurz: Gentoo ist das ideale System. Im dritten und letzten Teil erfährt man vieles über die wohl freundlichste und genialste Komune diesseits der Milchstrasse namens MELSTown. Es werden die wichtigsten Charaktere vorgestellt sowie die Möglichkeiten der Komune (Neudeutsch: Community) selber beizutreten. Und wer weiss... Vielleicht treffen sich unsere Wege gar einmal in Tavernux's Bar "Beim kleinen Melser" und wir trinken etwas miteinander. Aber das wird was kosten. Denn man sagt ja... "Linux is free. Free as in freedom of speech, not free beer"
"... so, noch diesen einen Satz und dann kann ich das Dokument speichern". Doch kaum drückte ich auf den Speichern Knopf, da erschien plötzlich eine Fehlermeldung: "Die Datei kann nicht gespeichert werden. Ueberprüfen Sie den vorhandenen Harddiskplatz und stellen Sie sicher, dass die Datei nicht schreibgeschützt ist." "Scheisse!" rief ich zornig aus. "Verdammte Scheisse! Warum nur muss mir das immer dann passieren, wenn das Dokument beinahe fertig ist?" fragte ich mich und haute wütend mit der Faust auf die Tastatur. Tja, das hätte ich lieber sein lassen sollen. Vielleicht hätte es noch eine Chance gegeben das Dokument irgendwie zu speichern. Vielleicht hätte ich den gesammten Text einfach noch markieren können und mit Copy Paste in ein anderes Dokument retten können. Wer weiss... Ich jedenfalls hatte nun einen "Blue Screen of Death" auf meinem Bildschirm. Und egal was ich auch versuchte, es blieb mir nur noch der Todesgriff; Control-Alt-Delete. Während der Computer neu gestartet wurde, fluchte ich noch einige male aufs heftigste vor mich her. "Wenn dich das Betriebssystem so aufregt, warum startest du es dann nochmals?" fragte mich plötzlich eine Stimme. Erschrocken drehte ich mich um und starrte in die Augen eines... eines... eines Pinguins! "Ein Pinguin !?" entfuhr es mir völlig verdatter. "Na sieh einer an... " meinte dieser oberschlau "... so dumm scheinst du ja gar nicht zu sein. Also, beantworte mir die Frage. Wenn dich das Betriebssystem so aufregt, warum startest du es dann nochmals?" "Weil.... weil...." mir fiel einfach nichts ein. "Weil du masochistisch veranlagt bist und auf diese Crashes stehst?" fiel er mir spottend und mit einem breiten Grinsen im Gesicht ins Wort. Langsam wurde mir dieses Vieh unsympathisch. Und überhaupt. Was hatte dieser Pinguin in meinem Arbeitszimmer verloren und wie war er überhaupt reingekommen? "Oder aber, weil du dir noch nie über Alternativen Gedanken gemacht hast und es darum einfach nicht besser weisst?" unterbrach er mich in meinen Gedanken. "Aeh... ja..." erwiderte ich völlig irritiert. "Na also, es geht ja. Okay, jetzt hör mir mal zu. Ich kann dich auf eine Reise mitnehmen, bei der du ein völlig andersartiges Betriebssystem kennen lernen kannst. Ein Betriebssystem, welches dir alle Freiheiten lässt und dich komplett selber entscheiden lässt was, wie, wo und wann du etwas mit deinem Computer machen willst. Ein Betriebsystem, welches nicht einfach den ganzen Rechner abstürzen lässt, nur weil ein Teilprogramm gerade verrückt spielt." sprudelte es plötzlich aus Ihm heraus. "All das und noch vieles mehr kann ich dir zeigen, wenn du dich innerhalb der nächsten 10 Sekunden entscheidest, mit mir zu kommen." meinte dieser Pinguin fordernd zu mir. "Aber..." ich wollte ihm irgend etwas entgegnen, weil er mich so überrumpelte, doch er unterbrach mich schon wieder. "Frag nicht lange! Du hast nur noch 9 Sekunden! Also beeil dich mit deiner Entscheidung. Du kannst später noch Fragen stellen". Ich war einfach nur baff. Da stand ein - wie mir jetzt erst auffiel - sprechender Pinguin in meinem Arbeitszimmer und drängte mich auf irgend eine abenteuerliche Reise mit zu kommen... "Noch 6 Sekunden" unterbrach er meine Gedanken wieder. Woher kam dieses Vieh überhaupt und was sollte diese Drängerei? Als ob das Wesen meine Gedanken lesen konnte unterbrach es mich wieder "Wenn du nicht schneller machst, dann schliesst sich das Reiseportal wieder und du kannst ewig deinen Abstürzen und blauen Bildschirmen hinterher rennen. Komm schon, was hast du zu verlieren?" Gute Frage, was hatte ich schon zu verlieren? Meinen Verstand wohl kaum, denn der schien ja bereits verloren zu sein... sprechende Pinguine... Pha. Ich kann nicht sagen ob es die Neugier war oder die Tatsache, dass ich regelrecht zu diesem Schritt gedrängt wurde. Jedenfalls schnappte ich mir wirklich die Flosse dieses Pinguins und liess mich auf dieses ungewisse Abenteuer ein. In diesem Moment rechnete ich mit allem. Zum Beispiel dass jetzt irgendwo jemand hervorstürmt und "Reingelegt!" schreien würde. Oder dass ich - mit der einen Hand fest die Blätter der Topf-Pflanze umklammernd - aufwachen würde und merken müsste, dass zuviel "Bluescreen" schlecht für das Gehirn ist. Aber stattdessen fing um mich herum alles zu leuchten an. Der Computer, die Tastatur, der Monitor, mein Schreibtisch, die Kugelschreiber... einfach alles begann von sich aus zu leuchten. Und obwohl das Licht immer heller und gleissender wurde, schmerzte es nicht in den Augen. Ich beschloss meine Augen trotzdem zu schliessen. Man konnte schliesslich nie wissen. "Bleib ganz ruhig." ertönte es da neben mir. "Du wirst gerade erleuchtet! Dein Geist wird für die Neue Welt, welche dich fortan erwartet, empfänglich gemacht." Egal. Ich liess die Augen geschlossen und vernahm ein kichern neben mir. Um mich herum wurde es langsam wieder dunkler. Trotzdem traute ich mich nicht die Augen zu öffnen. Irgendwann stuppste mich der Pinguin von der Seite an und meinte: "Na, hast du die Augen immer noch zu? Mach sie auf, wir sind da!". Vorsichtig öffnete ich das rechte Auge. Doch weil ich nichts erkennen konnte musste ich auch das linke öffnen. Mit weit aufgerissenen Augen starrte ich in absolute Finsterniss. "Mein Gott, das helle Licht muss meine Netzhäute verbrannt haben!" schrie ich auf. "Ach Quatsch!" entgegnete mir da der Pinguin, "Hier drinn ist es schlicht und ergreifend Stockdunkel!". Wenn dieser Pinguin wüsste, wie sehr mich diese Antwort beruhigte! "Aber..." fing ich meine Frage an den Pinguin zu formulieren "WARUM ist es hier so dunkel?". "Na weil wir uns - sozusagen - in deinem Computer befinden und dieser nunmal ausgeschaltet ist." antwortete er so schnell, als ob er gewusst hätte, dass ich diese Frage stellen würde. "Ja und nun?" fragte ich. "Wie geht es nun weiter?". Ich hörte neben mir ein rascheln und klimpern. Plötzlich drückte mir dieses Vieh unsanft einen harten Gegenstand in den Magen. "Oh, Entschuldige!" gluckste er amüsiert. "Hier, nimm diese Taschenlampe." meinte er dann etwas ernster. Ich nahm die Taschenlampe an mich, schaltete sie ein und blendete dem Pinguin voll ins Gesicht. "He spinnst du!? Hoer auf mich zu blenden!" meinte er leicht wütend und hielt seine Flossen vor die Augen. Jetzt musste ich grinsen. Ich leuchtete mit der Lamp wo anders hin und setzte gleich zu einer Frage an. "Sag mal..." begann ich "...hast du auch einen Namen? Und woher kommst du eigentlich?" Der Pinguin schaute mich etwas komisch an, stand dann ganz gerade vor mich hin, drückte stolz seine Brust heraus und begann: "Gestatten, mein Name ist Mux! Ich bin genau wie unser ehrenwerter und weiser Tux ein Vermittler." Stolz erzählte er weiter "Als fliegender Vermittler reise ich umher, auf der Suche nach wissensdurstigen und geplagten wie dir... " bei diesen Worten zwinkerte er mir zu "... um diese in die Welt von Linux einzuführen." "Ahso..." entgegnete ich ihm. "Ja, genau so! Und jetzt trödle nicht so lange rum. Wir haben heute schliesslich noch etwas vor, oder?" mit diesen Worten drehte er sich um und watschelte davon. Mir blieb nicht viel anderes übrig, als ihm zu folgen. Nach einer Weile des umherwatschelns blieb Mux plötzlich stehen und deutete mit seiner Taschenlampe auf ein Gebilde, das wie ein Terminal aussah. Als ich mich dem Gerät näherte konnte ich den Schriftzug ~VirTux darauf lesen. "Das ist ~VirTux. Das virtuelle Abbild unseres weisen und ehrenwerten Vermittlers Tux. Er ist sowas wie ein allwissendes Lexikon und ein virtueller Wissensvermittler. Er wird dir helfen, wenn du zu gewissen Themen mehr wissen benötigst." erklärte mir Mux. "Nimm dir einen Stuhl von da hinten und setz dich da hin." er deutete mit seiner Taschenlampe auf eine Stelle vor einem Rechner. Ich tat wie mir befohlen wurde. Während dessen leuchtete Mux suchend die Wand ab, bis er einen Schalter im Lichtkegel erblicken konnte. Während er auf den Schalter zuwatschelte, knippste er seine Taschenlampe aus. Ich tat es ihm gleich. Für einen Moment war es wieder dunkel. Doch bevor sich meine Augen an die Dunkelheit gewöhnen konnten, folgte auf das Klicken des Lichtschalters bereits wieder das Licht. Wir waren in einem kleinen, völlig Fensterlosen Raum. Um uns herum hingen dicke, verschiedenfarbige Kabel von der Decke und schienen in einem wilden, undurchsichtigen Gewusel überall im Raum zu verlaufen. Vor mir war ein Tisch unter dem ich einen Rechner ausfindig machen konnte, der genau gleich wie mein hemischer Rechner aussah. Während ich mir alles anschaute, hatte Mux sich ebenfalls einen Stuhl geschnappt und sich neben mich gesetzt. "Bist du bereit?" fragte er mich? "Aber ja!" antwortete ich ihm, gespannt darauf wartend, was nun passieren würde. "Gut." begann er. "Was du hier siehst ist ein virtuelles Abbild deines Rechners." dabei deutete er mit der Flosse auf den Rechner unter dem Tisch. "Wir haben uns entschlossen diesen Weg zu gehen, damit die Daten auf deinem Rechner nicht aus Versehen gelöscht oder anderweitig beeinträchtigt werden." fuhr er fort. "Alles was wir hier machen, geschieht demnach nur virtuell. Wenn du also etwas verbockst brauchst du nur die entsprechenden Dateien neu zu installieren und dein virtuelles System ist wieder funktionsfähig."
"Alles was wir hier machen, geschieht demnach nur virtuell..."
Diese Aussage erinnert mich daran, lieber Leser, dass ja nicht jeder die Gelegenheit hat von einem Pinguin entführt und in den eigenen PC eingesaugt zu werden. Ich habe mir daher lange das Hirn darüber zermartert, wie jedermann trotzdem die Möglichkeit bekommt, all das, was Mux und ich erlebt haben, selber ausprobieren zu können. Ich habe gesucht, geforscht, ausprobiert, verworfen und wieder gesucht. Irgendwan fiel mir wieder diese Satz von Mux ein, dass alles nur virtuell geschieht. Da wusste ich, wie ich jedem Leser die Möglichkeit zum aktiv mit-ausprobieren bieten könnte.
Mittels Virtualisierung.
Die einzige Schwierigkeit beim Thema Virtualisierung besteht darin, eine Lösung zu finden die von den allermeisten Lesern auch angewandt werden kann. Das bedeutet zum Beispiel, dass der Virtualisierer völlig Betriebsystem unabhängig sein muss. Auch kann ich nicht verlangen, dass jemand Geld ausgibt, nur um einen plattformunabhängigen Virtualisierer kaufen zu können. Doch dank Fabrice Bellard und seines frei verfügbaren Emulators QEMU ist das alles absolut kein Problem.
!Definition von Virtualisierung
Wenn man von Virtualisierung spricht muss man grundsätzlich zwei Spielarten davon unterscheiden; die reine Virtualisierung und die Emulation. Bei der reinen Virtualisierung versucht man primär die zur verfügung stehenden Hardwareressourcen von der Software zu entkoppeln, um diese optimal den einzelnen Systemen zuteilen zu können. Dabei geht es vor allem um die Hardwarekomponenten wie Prozessor, Hauptspeicher, Festplattenkapazität und Netzwerkanbindungen. Bei der Virtualisierung versucht man also die vorhandenen Ressourcen möglichst effizient auszunutzen. Das lässt sich mit folgendem Beispiel veranschaulichen.
Früher - ich spreche von der Zeit um die Jahrtausendwende 1999/2000 - war es ganz normal, dass man als Geschäftskunde eines Internet Providers einen eigenständigen Server für z.B. seine Webseite zur Verfügung gestellt bekam. Viele dieser Maschinen machten jedoch den Grossteil des Tages nichts weiter als Strom zu verbrauchen, Wärme zu produzieren und darauf zu warten, dass sich auch mal jemand anders als nur die Crawler der Suchmaschienenbetreiber auf die Webseite verirrten. Natürlich gab es auch schon damals die Möglichkeit "Virtualhosts" innerhalb der Apache Konfiguration zu definieren, wodurch eine Apache Instanz gleichzeitig mehrere Webseiten bedienen kann.
Diese Lösung wird auch heutezutage noch oft für kleine Webseiten eingesetzt wie etwa bei kostenlosen Hostingangeboten oder Webseiten mit geringen Ansprüchen. Sobald jedoch anspruchsvollere Webseiten mit vielen PHP Scripts oder auch Firmenpräsenzen auf einem Server laufen sollen sind die VHOSTS denkbar ungeeignet. Denn wird z.B. die Webseite der Firma A mit einer DDOS Attacke konfrontiert, werden derart viele Apache Instanzen blockiert, dass die anderen virtuellen Hosts keine mehr für sich beanspruchen können. Mit einem Schlag sind dann nicht nur die Webpräsenz der Firma A gestört sondern aller Virtualhost Instanzen. Das selbe passiert auch wenn ein Script einer virtuellen Hostinstanz verrückt spielt und den ganzen Speicher auffrisst. Abhilfe schaffen hier echte virtuelle Hosts welche jeweils eigene Ressourcen haben. Werden diese aus irgend einem Grund aufgebraucht sind die anderen virtuellen Hosts nicht davon betroffen.
Bei der Emulation wird dagegen ein komplettes System inkl. all seiner Hardwarekomponenten nachgeahmt. Hierdurch ergibt sich die Möglichkeit die Programme welche für das ursprüngliche System geschrieben wurden im Emulator laufen zu lassen. Ein bekanntes Beispiel für einen Emulator ist der heute noch aktiv gepflegte C64 Emulator [[VICE|http://vice-emu.sourceforge.net/]]. Mit ihm lassen sich die alten C64 Spiele, Demos und Programme aus der Kindheit auf einer Vielzahl von Systemen wiederbeleben.
Da bei der Emulation nicht nur die vorhandenen Ressourcen gemanagt werden müssen sondern das komplette zu emulierende System nachgebildet werden muss (Beim C64 z.B. nebst dem 6510 Prozesor auch der Grafikchip VIC oder der Soundchip SID) ist für die Wiedergabe eines simplen C64 Spieles natürlich eine ungleich stärkere Hardware nötig. Um z.B. einen für den C64 verbreiteten Sidescroller wie [[R-Type|http://de.wikipedia.org/wiki/R-Type]] flüssig wiedergeben zu können (inkl. flüssiger Musikwiedergabe) ist mindestens ein Intel Pentium III System nötig.
!QEMU
QEMU gehört zur Kategorie der Emulatoren. Mit QEMU (englische Abkürzung für „Quick Emulator“) können derzeit die Prozessorarchitekturen x86, ~AMD64 und x86-64, ~PowerPC, ARM, Alpha, m68k (Coldfire), ~MicroBlaze, MIPS und Sparc32/64 emuliert werden. Die Möglichkeit ein x86 System emulieren zu können macht QEMU besonders für Benutzer von Mac OS X oder Solaris Systemen interessant. Haben Sie doch hiermit ebenfalls die Möglichkeit das ~MELSsystem ausprobieren zu können. Aber auch auf einem Windows System (welches normalerweise bereits auf einem x86 oder x86-64 Prozessorsystem läuft) ist die Verwendung von QEMU interessant. Denn durch die virtuelle Maschine ist sichergestellt, dass jedermann die selbe (virtuelle) Hardware verwendet, wodurch Beispiele welche die Hardware beinhalten von allen Lesern 1:1 nachvollzogen werden können.
!!Installation von QEMU und MELS unter Windows
Download Pfad: [[http://dietpc.org/windows/qemu/|http://dietpc.org/windows/qemu/]]
*[[Im QEMU|http://qemu-forum.ipi.fi/]] Forum gibt es den Benutzer [[whitpa|http://qemu-forum.ipi.fi/memberlist.php?mode=viewprofile&u=10633]] welcher relativ zeitnah die aktuellsten Versionen von QEMU für Windows kompiliert. Im oben angegebenen Verzeichnis kann man sich einfach die letzte Version herunterladen.
*Das ZIP Archiv kann man irgendwo hin entpacken wo man mindestens 2GB freien Speicher hat. Falls man kein Packprogramm besitzt kann man sich das frei verfügbare Packprogramm [[7zip|http://7-zip.org/]] herunterladen und installieren.
*Von der [[MELS Homepage|http://]] wird das aktuellste MELS Image heruntergeladen und in das selbe Verzeichnis entpackt in welchem man vorhin QEMU entpackt hat.
*Gestartet wird die Mels Umgebung ganz einfach indem man im QEMU Verzeichnis die Datei {{{mels.bat}}} ausführt (z.B. mittels einem doppelklick).
!!Installation von QEMU und MELS unter Linux
Download Pfad: Distributionsabhängig
Jede Linux Distribution kocht ihr Ureigenstes Süppchen, wenn es um die Bereitstellung von Paketen geht. Einige wie z.B. [[Gentoo|http://www.gentoo.org/]] laden nur die Quelltexte herunter und kompilieren sogleich das Programm, andere verwenden hingegen vorkompilierte Pakete. Doch auch bei den Paketen gibt es Vielfalt ohne Ende. Etwa [[Debians|http://www.debian.org]] .deb Pakete, [[Redhats |http://www.redhat.com/]] .rpm Pakete und viele andere mehr. Und um die Pakete schlussendlich installieren zu können, muss man wiederum je nach Distribution ein anderes Werkzeug verwenden.
Die nachfolgende Liste enthält die Installationsbefehle der gängigsten Distributionen. Falls jemand seine Distribution vermisst, schreibe er mir eine Email mit dem entsprechenden Befehl.
* [[Gentoo Linux|http://www.gentoo.org/]]
{{{
emerge qemu
}}}
* [[Debain|http://www.debian.org/]] und Derivate wie [[Ubuntu|http://www.ubuntu.com/]]
{{{
apt-get install qemu
}}}
* [[Redhat|http://www.redhat.com/]] und Derivate wie [[Fedora|http://fedoraproject.org/]]
{{{
yum install qemu
}}}
* [[SUSE|http://www.suse.com]] und Derivate wie [[OpenSUSE|http://www.opensuse.org]]
{{{
yast -i qemu
}}}
* [[Slackware|http://www.slackware.com/]] - interaktiv mittels {{{pkgtool}}} oder manuell via
{{{
installpkg qemu*.tgz
}}}
Nach der Installation lädt man sich von der [[MELS Homepage|http://]] das aktuellste MELS Image herunter und entpackt es in einem beliebigen Arbeitsverzeichnis. Ein neues Unterverzeichnis im eigenen Home bietet sich dafür an. Danach startet man einfach das darin enthaltene {{{mels.sh}}}.
!!Installation von QEMU und MELS unter Mac OS X
Download Pfad: [[http://www.kju-app.org/|http://www.kju-app.org/]]
In Ermangelung eines Mac OS X Systemes kann ich leider nicht sagen, wie man kju installieren muss. Hier bin ich auf Leserinput angewiesen!
!!Installation von QEMU und MELS unter Solaris
Binaries:[[http://hub.opensolaris.org/bin/view/Project+qemu/downloads|http://hub.opensolaris.org/bin/view/Project+qemu/downloads]]
Bauen aus Sourcen:[[http://hub.opensolaris.org/bin/view/Project+qemu/host|http://hub.opensolaris.org/bin/view/Project+qemu/host]]
In Ermangelung eines Solaris Systemes kann ich leider nicht sagen, wie man qemu installieren muss. Hier bin ich auf Leserinput angewiesen!
!Terminal Client installieren
Natürlich kann man die Mels Umgebung einfach über die gestartete QEMU Oberfläche bedienen. Meine Erfahrung hat jedoch gezeigt, dass es wesentlich einfacher und auch authentischer ist, wenn man mittels einem SSH Client die MELS Umgebung betritt und bedient. Einfacher, weil die eingesetzten Clients meistens mehr komfort als die QEMU Oberfläche bieten wie etwa grosse Historien, bessere copy & paste Möglichkeiten oder die Möglichkeit alles mitzuloggen. Desweiteren hat man durch den Einsatz des Clienten eher das Gefühl, auf einem richtigen, entfernten Linux System eingeloggt zu sein. Das weiss man besonders dann zu schätzen, wenn man von daheim aus auf einen vielleicht weit entfernten Rechner zugreifen muss um zu überprüfen was der Stand der Dinge ist.
!!~PuTTY - Client für Windows
Offizielle Download Adresse: http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
''~PuTTY'' ist ein von Simon Tatham entwickelter und frei verfügbarer Secure Shell-, Telnet- und ~Rlogin-Client für Microsoft Windows. Das Programm dient dazu, eine Verbindung von einem Rechner zu einem ~Secure-Shell- bzw. ~Telnet-Server herzustellen. In dieser textorientierten ~Terminal-Sitzung können Befehle direkt eingegeben werden, welche auf dem fernen System ausgeführt werden.
!!!Einzelne Applikationen
Das ~PuTTY Paket besteht aus folgenden Programmen die kurz vorgestellt werden sollen.
; ~PuTTY
:Terminalemulator mit Telnet- und Remote login und Secure ~Shell-Client;
; PSCP (~PuTTY Secure Copy client)
: ein Secure ~Copy-Client;
; PSFTP (~PuTTY Secure File Transfer (SFTP) client)
: ein SSH File Transfer ~Protocol-Client;
; ~PuTTYtel
: Terminalemulator mit Telnet- und Remote ~login-Client;
; Plink (~PuTTY Link)
: ~PuTTY als Commandline Tool (ohne grafische Oberfläche)
; Pageant (~PuTTY authentication agent)
: ein ~SSH-Agent mit dem ~SSH-Authentifizierungen weitergereicht werden können
; ~PuTTYgen (~PuTTY Key Generator)
: erstellt ~RSA-Kryptosystem und Digital Signature Algorithm Keys, beispielsweise für SSH;
; pterm
: ein unabhängiger ~Terminal-Emulator.
!!!Verbinden mit MELS
Um sich mit der MELS Umgebung verbinden zu können, müssen lediglich einige wenige Einstellungen in ~PuTTY vorgenommen werden.
[img[Rudimentäre PuTTY Settings für MELS|images/PuTTY_MELS.png]]
*{{{127.0.0.1}}} steht für den {{{localhost}}} und {{{22022}}} für den zu verwendenden Port.
*Will man die Settings nicht jedemal eingeben müssen, kann man diese auch mittels Angabe eines Profilnamens (z.B. MELS) abspeichern.
@@''Achtung!''@@ Die Verbindung kann erst aufgebaut werden, wenn in der QEMU Umgebung eine Netzwerkkarte konfiguriert, ein Passwort gesetzt und dropbear aktiviert wurde. Wie das geht wird später erläutert.
!!openSSH - Client für Linux/Solaris/Mac OS X
Von einem Unix-artigen Betriebsystem kann man - sofern ~OpenSSH installiert ist - ganz einfach mittels dem ssh Befehl eine Verbindung aufbauen.
{{{
ssh -p 22022 root@127.0.0.1
}}}
!Der erste Kontakt
Startet man seine MELS Umgebung zum ersten mal, dann sieht man zunächst eine Menge Zeilen im QEMU Fenster vorbeiscrollen. Was diese genau bedeuten werden wir später anschauen. Zunächst sei einfach gesagt, dass die folgende Zeile am interessantesten ist:
{{{
mels login:
}}}
Denn diese banale Zeile ist für uns das Tor zum Linux System. Meldet man sich hier mit dem richtigen Benutzernamen und einem korrekten Passwort an, so kann man diese Welt betreten. Für den Anfang ist es sogar besonders einfach, denn wenn man {{{root}}} eintippt, gefolgt von der Enter (auch bekannt als Return) Taste, befindet man sich bereits im Linux System.
{{{
~ # _
}}}
Soweit so gut. Doch damit man mit dem weiter oben eingerichteten Terminal Client auch mit der MELS Umgebung verbinden kann, muss man in ihr erst einmal alle Voraussetzungen dafür schaffen. Das bedeutet zum einen, dass man die (virtuelle) Netzwerkkarte einrichten muss und zum anderen, dass man ein Programm starten muss (einen so genannten Dämonen) welcher die Verbindungen entgegen nimmt. Um nun ohne lange umschweife loslegen zu können, sind die wichtigsten Befehle bereits in der Historie der Shell gespeichert. Drückt man drei mal hintereinander jeweils drei mal die Pfeil nach oben Taste und bestätigt dann jeweils mit der Return Taste die Eingabe, so wird in null komma nichts das Netzwerk eingerichtet. Nachfolgend noch einmal die drei Befehlszeilen welche man nacheinander eingeben soll und dabei mit Return bestätigen muss:
{{{
ifconfig eth0 10.0.2.15 broadcast 10.0.2.255 netmask 255.255.255.0
route add default gw 10.0.2.2
echo "nameserver 10.0.2.3" > /etc/resolv.conf
}}}
Damit ist das Netzwerk eingerichtet. Was jetzt noch fehlt ist das Programm welches auf die Verbindungsversuche unseres Terminal Clients reagiert. Es heisst {{{dropbear}}}. Tippt man in der MELS Umgebung einfach den Befehl dropbear ein, gefolgt vom drücken der Return Taste (Dieser Schritt wird ab sofort nicht mehr explizit erwähnt.), startet ein SSH Dämon. Was SSH ist, in welchem Zusammenhang dropbear zu SSH steht und wie genau ein Dämon funktioniert wird alles in späteren Teilen des Buches beschrieben.
{{{
dropbear
}}}
Da Dropbear den Zugriff für Benutzerkonten ohne Passwort nicht zulässt, muss für das root Konto mit folgendem Befehl ein Passwort gesetzt werden.
{{{
passwd
Changing password for root
News Password:
Retype Password:
Password for root changed by root
}}}
Verbindet man sich nun wie bei der Installation des jeweiligen Terminal Clients beschrieben mit der MELS Umgebung, dann sollte man nach einer gewissen Zeit in etwa folgende Meldung im Terminal Fenster bekommen.
{{{
# hier root eingeben.
login as:
# hier das vorhin gesetzte Passwort eingeben.
root@127.0.0.1's password:
}}}
!Problembehandlung
!!Verbindung mittels Terminal Client nicht möglich
*'''Blockiert eine Firewall?'''
**Läuft auf dem Rechner vielleicht eine Firewall? Wenn ja sollte man selbige einmal für einen ganz kurzen Moment deaktivieren und dann erneut eine Verbindung mittels dem Terminal Client zur MELS Umgebung aufbauen. Wenn die Verbindung nun funktioniert, dann muss man die Firewall so konfigurieren, dass Verbindungen zum QEMU Programm zugelassen, Verbindungen auf die IP Adresse 127.0.0.1 (den sogenannten localhost) nicht blockiert werden und dass der Port 22022 offen gehalten wird. Wie das geht muss der jeweiligen Dokumentation der Firewall entnommen werden. Nach dem Test bitte nicht vergessen die Firewall wieder zu aktivieren!
*'''Netzwerk in QEMU korrekt konfiguriert?'''
**Als erstes sollte man prüfen ob die Netzwerkkarte in der QEMU Umgebung überhaupt konfiguriert ist. Mittels dem Befehl {{{ifconfig eth0}}} sollte man sehen, dass die '''inet addr: 10.0.2.15''' ist.
{{{
~ # ifconfig eth0
eth0 Link encap:Ethernet HWaddr 52:54:00:12:34:56
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:38 errors:0 dropped:0 overruns:0 frame:0
TX packets:26 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:4238 (4.1 KiB) TX bytes:3247 (3.1 KiB)
Interrupt:11 Base address:0xc100
}}}
***Falls keine Adresse konfiguriert ist sollte man fen Befehl {{{ifconfig eth0 10.0.2.15 broadcast 10.0.2.255 netmask 255.255.255.0}}} nochmals eingeben.
**Falls die IP Adresse korrekt gesetzt ist muss man prüfen ob der default Gateway {{{10.0.2.2}}} erreichbar ist. Ein {{{ping -c 5 10.0.2.2}}} muss '''0% packet loss''' ergeben. Falls man Paketverluste hat stimmt etwas mit der MELS Umgebung nicht. Dieses Problem sollte unbedingt im MELS Forum mitgeteilt werden.
{{{
~ # ping -c 5 10.0.2.2
PING 10.0.2.2 (10.0.2.2): 56 data bytes
64 bytes from 10.0.2.2: seq=0 ttl=255 time=0.312 ms
64 bytes from 10.0.2.2: seq=1 ttl=255 time=0.247 ms
64 bytes from 10.0.2.2: seq=2 ttl=255 time=0.266 ms
64 bytes from 10.0.2.2: seq=3 ttl=255 time=0.262 ms
64 bytes from 10.0.2.2: seq=4 ttl=255 time=0.287 ms
--- 10.0.2.2 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.247/0.274/0.312 ms
}}}
**Kann man den default Gateway anpingen ist vielleicht ein Problem beim routing vorhanden. Der Befehl {{{route}}} sollte in etwa nachfolgendes Bild ergeben. Wenn nicht, muss man die default Route noch einmal mit dem Befehl {{{route add default gw 10.0.2.2}}} setzen.
{{{
~ # route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
default 10.0.2.2 0.0.0.0 UG 0 0 0 eth0
10.0.2.0 * 255.255.255.0 U 0 0 0 eth0
127.0.0.0 * 255.0.0.0 U 0 0 0 lo
}}}
**Obwohl der nachfolgende Test nicht wirklich etwas mit dem Problem des nicht verbinden könnens zu tun hat sollte man trotzdem kurz sicherstellen, dass die Namensauflösung funktioniert. Ein {{{nslookup www.google.com}}} darf keine Meldung der Art {{{nslookup: can't resolve 'www.google.com'}}} bringen. Ansonsten muss man prüfen ob a) die Datei {{{/etc/resolv.conf}}} vorhanden und b) der Inhalt der Datei {{{nameserver 10.0.2.3}}} entspricht. Falls eines der beiden nicht zutrifft sollte man nochmals den Befehl {{{echo "nameserver 10.0.2.3" > /etc/resolv.conf}}} ausführen.
**Zum Schluss kann man nur noch prüfen ob dropbear überhaupt läuft. Ein {{{ps -ef}}} sollte im output irgendwo das Wort dropbear stehen haben. Ist dies nicht der Fall sollte man dropbear noch einmal mittels {{{dropbear}}} starten.
<<sectionTOC>>
"Was meinst du genau mit Virtuell?", fragte ich Mux verunsichert, "Ich kann den Rechner doch direkt vor mir sehen?". Schnell stupste ich den vor mir stehenden Rechner mit meinem Schuh an um mich zu versichern, dass da auch wirklich ein Rechner stand. Ich spürte einen Widerstand durch meinen Schuh hindurch. Na also...
"Wie ich schon sagte, ist alles virtuell. Eine Lüge, wenn du so willst. Der Rechner vor dir fühlt sich zwar an wie ein Rechner, er verhält sich wie ein Rechner und du kannst mit ihm arbeiten wie mit einem Rechner..." hier machte Mux eine kleine Pause "... doch egal was du darauf machst, ob du etwas löscht oder ob du etwas verstellst, dann geschieht dies nur auf diesem Abbild eines Rechners und nicht auf deinem eigentlichen Rechner". Während Mux dies sagte, streckte er seine Flosse aus und drückte auf den Einschaltknopf.
Der Rechner schaltete sich ein, testete erfolgreich seine Hardware und bootete, wie ich relativ schnell feststellen konnte, schon bald das Linux System. Diverse Zeilen rauschten mit rasantem Tempo an uns vorbei bis das scrollen aussetzte und wir nunmehr die Zeile {{{mels login:}}} vor uns hatten.
^^Version <<version>> - [[EditMe|MainMenu]]^^ ---- Entwicklung [[MELS Build|AufbauMELS2011-virtualbox]] ---- [[MELS Buch]] ----
Herzlich Willkommen beim MELS Wiki. In diesem Wiki dreht sich alles um die Linux Distribution MELS. MELS steht für ''M''ein ''E''igenes ''L''inux ''S''ystem und wurde von Matthias Egger erstellt. Jetzt werden sicher einige sagen: "Oh Gott! Nicht noch eine Linux Distribution". Schliesslich zählt der [[Distrowatch|http://distrowatch.com/dwres.php?resource=independence]] zur Zeit (//Stand: 11.09.2011//) 420 Distributionen. Und wäre MELS eine klassische Distribution, ich würde wohl das selbe sagen. Doch MELS ist keine Distribution die sich durch irgend ein Gimmick von anderen abhebt, wie etwa [[Gentoo|http://www.gentoo.org]] mit Portage oder [[SuSE|http://www.novell.com/de-de/linux/]] mit YAST, sondern es ist eine Lerndistribution. Das bedeutet, man kann mit dieser Distribution den Umgang mit Linux (kennen)lernen. Aus diesem Grund besteht MELS auch aus zwei Hauptkomponenten. Dem MELS Buch sowie der MELS Umgebung. Das Buch nimmt den Leser mit auf eine Reise durch die Welt von Linux. Dabei lernt dieser Schritt für Schritt eine Welt kennen und verstehen. Am Ende des Buches sollte der Leser in der Lage sein @@jedes@@ Linux zu bedienen und zu konfigurieren. Damit das ganze nicht in eine trockene und theoretische Leselektüre für das Klo ausartet, wurde die MELS Umgebung geschaffen. In dieser kann der Leser alles was er gerade gelesen und gelernt hat ausprobieren, ohne sein bestehendes System zu tangieren. Und der grosse Vorteil gegenüber einer Live Distribution wie etwa [[Knoppix|http://www.knoppix.org/]] ist die Tatsache, dass während des ausprobierens nicht einmal der Rechner neu gestartet werden muss. Viel Spass mit MELS wünscht Matthias Egger
/***
|Name|SectionLinksPlugin|
|Source|http://www.TiddlyTools.com/#SectionLinksPlugin|
|Documentation|http://www.TiddlyTools.com/#SectionLinksPlugin|
|Version|1.4.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|allow tiddler sections in TiddlyLinks to be used as anchor points|
This plugin enhances the processing of section references so they can be used in links to auto-scroll to the indicated heading within a tiddler (i.e., similar to the 'anchor' behavior provided in HTML by {{{<a name="foo">}}} and {{{<a href="#foo">...</a>}}})
!!!Usage
<<<
!!!!~TiddlyLink syntax
>The standard link syntax has been extended so that a section name can included in a tiddler link (e.g., {{{[[SomeTiddler##SomeSection]]}}}). When clicked, the tiddler is displayed and the specified section heading will be automatically scrolled into view. If the tiddler title is omitted or the 'here' keyword is used (e.g., {{{[[##SomeSection]]}}} or {{{[[here##SomeSection]]>>}}}), then the current containing tiddler is implied by default.
>
>//Note: the enhanced "section"" link syntax can also be used with ''anchor'' elements defined by HTML syntax://
>>{{{<html><a name="sectionname" /></html>}}}
>//This provides an alternative syntax can automatically scroll to content without requiring use of the standard TW section ''heading'' syntax.//
!!!!{{{<<tiddler>>}}} macro
>The {{{<<tiddler SomeTiddler##SomeSection>>}}} syntax has been extended so that when the tiddler title is omitted or the 'here' keyword is used (e.g., {{{<<tiddler ##SomeSection>>}}} or {{{<<tiddler here##SomeSection>>}}}), then the current containing tiddler is implied by default.
!!!!"""<<sectionTOC>>""" macro
>This macro generates a 'Table of Contents'-style numbered-bullet list with links to all sections within the current tiddler. Simply place the following macro at the //end of the tiddler content// (i.e., following all section headings):
{{{
<<sectionTOC>> or <<sectionTOC className>>
}}}
>Note: The macro must occur at the end of the tiddler in order to locate the rendered section headings that precede it. In addition, to position the macro's //output// within the tiddler, you must create a special 'target element' that uses a specified classname (default='sectionTOC'), like this:
{{{
{{sectionTOC{}}}
}}}
>When the {{{<<sectionTOC>>}}} macro is rendered, it will find the matching 'sectionTOC'-classed element and writes it's output there. You can also add the macro and/or target elements directly to the [[ViewTemplate]] definition, so that every tiddler can automatically display the table of contents:
{{{
<span class='sectionTOC'></span> <!-- target element -->
...
<span macro='sectionTOC'></span> <!-- must be at end of tiddler -->
}}}
<<<
!!!Examples
<<<
links to sections defined by ''TW heading syntax'' (e.g, {{{!!!sectionname}}}):{{indent{
[[SectionLinksPlugin##onClickTiddlerLink]]
[[##onClickTiddlerLink]] //(current tiddler implied)//}}}
links to anchors defined by ''HTML syntax'' (e.g., {{{<html><a href="anchorname"></html>}}}):{{indent{
[[SectionLinksPlugin##sampleanchorlink]]
[[##sampleanchorlink]] //(current tiddler implied)//}}}
<<<
!!!Revisions
<<<
2011.02.08 1.4.1 in isExternalLink() hijack, strip section references before testing for external link
2010.08.09 1.4.0 in scrollToSection(), added support for using HTML <a name="..."> anchor elements
2009.08.21 1.3.4 added handling to ignore leading/trailing whitespace in section references
2009.08.21 1.3.3 in createTiddlyLink(), add tiddlyLinkNonExistingSection class if matching section is not found
2009.08.14 1.3.2 in createTiddlyLink(), don't override core value for ~TiddlyLink attribute
2009.08.02 1.3.1 in sectionTOC.handler(), trim leading/trailing whitespace from generated section links
2009.08.01 1.3.0 in scrollToSection(), apply 3-tier section matching (exact, startsWith, contains)
2009.07.06 1.2.2 fixed displayTiddler() hijack
2009.07.03 1.2.1 in {{{<<sectionTOC>>}}}, suppress output if target is not found
2009.06.02 1.2.0 added support for 'here' keyword in {{{[[here##section]]}}} links and {{{<<tiddler here##section>>}}} macro
2009.04.09 1.1.1 in sectionTOC macro, make target visible when TOC is rendered.
2009.01.18 1.1.0 added {{{<<sectionTOC>>}}} macro to generate numbered-bullet links to sections of current tiddler
2009.01.06 1.0.0 converted to stand-alone plugin
2008.10.14 0.0.0 initial release (as [[CoreTweaks]] #784 - http://trac.tiddlywiki.org/ticket/784)
<<<
!!!Code
***/
//{{{
version.extensions.SectionLinksPlugin= {major: 1, minor: 4, revision: 1, date: new Date(2011,2,8)};
Story.prototype.scrollToSection = function(title,section) {
if (!title||!section) return; var t=this.getTiddler(title); if (!t) return null;
var elems=t.getElementsByTagName('*');
var heads=[]; var anchors=[];
for (var i=0; i<elems.length; i++)
if (['H1','H2','H3','H4','H5'].contains(elems[i].nodeName)) heads.push(elems[i]);
for (var i=0; i<elems.length; i++)
if (elems[i].nodeName=='A' && (elems[i].getAttribute('name')||'').length) anchors.push(elems[i]);
var found=null;
for (var i=0; i<heads.length; i++)
if (getPlainText(heads[i]).trim()==section) { found=heads[i]; break; }
if (!found) for (var i=0; i<heads.length; i++)
if (getPlainText(heads[i]).trim().startsWith(section)) { found=heads[i]; break; }
if (!found) for (var i=0; i<heads.length; i++)
if (getPlainText(heads[i]).trim().indexOf(section)!=-1) { found=heads[i]; break; }
if (!found) for (var i=0; i<anchors.length; i++)
if (anchors[i].getAttribute('name')==section) { found=anchors[i]; break; }
if (!found) for (var i=0; i<anchors.length; i++)
if (anchors[i].getAttribute('name').startsWith(section)) { found=anchors[i]; break; }
if (!found) for (var i=0; i<anchors.length; i++)
if (anchors[i].getAttribute('name').indexOf(section)!=-1) { found=anchors[i]; break; }
if (found) {
// if section heading is collapsed, click to expand it - see [[FoldHeadingsPlugin]]
if (hasClass(found,'foldable') && found.nextSibling.style.display=='none') found.onclick();
// scroll *after* tiddler animation
var delay=config.options.chkAnimate?config.animDuration+100:0;
setTimeout('window.scrollTo('+findPosX(found)+','+findPosY(found)+')',delay);
return found;
}
}
//}}}
/***
!!!!core hijacks
***/
/***
!!!!!createTiddlyLink
***/
//{{{
// [[tiddlername##section]] and [[##section]]
if (!window.createTiddlyLink_section)
window.createTiddlyLink_section=window.createTiddlyLink;
window.createTiddlyLink=function(place,title) {
var t=story.findContainingTiddler(place); var tid=t?t.getAttribute('tiddler'):'';
var parts=title.split(config.textPrimitives.sectionSeparator);
var title=parts[0]; var section=parts[1]; if (section) section=section.trim();
if (!title.length || title.toLowerCase()=='here') title=tid; // default=current tiddler
arguments[1]=title;
var btn=createTiddlyLink_section.apply(this,arguments);
if (section) {
btn.setAttribute('section',section);
if (store.getTiddlerText(title+config.textPrimitives.sectionSeparator+section)===null)
addClass(btn,'tiddlyLinkNonExistingSection');
}
return btn;
}
//}}}
/***
!!!!!onClickTiddlerLink
***/
//{{{
if (!window.onClickTiddlerLink_section)
window.onClickTiddlerLink_section=window.onClickTiddlerLink;
window.onClickTiddlerLink=function(ev) {
var e=ev||window.event; var target=resolveTarget(e); var title=null;
while (target!=null && title==null) {
title=target.getAttribute('tiddlyLink');
section=target.getAttribute('section');
target=target.parentNode;
}
var t=story.findContainingTiddler(target); var tid=t?t.getAttribute('tiddler'):'';
if (title!=tid||!section) // avoid excess scrolling for intra-tiddler links
onClickTiddlerLink_section.apply(this,arguments);
story.scrollToSection(title,section);
return false;
}
//}}}
/***
!!!!! displayTiddler
***/
//{{{
if (!Story.prototype.displayTiddler_section)
Story.prototype.displayTiddler_section=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,tiddler)
{
var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
var parts=title.split(config.textPrimitives.sectionSeparator);
var title=parts[0]; var section=parts[1]; if (section) section=section.trim();
if (!title.length || title.toLowerCase()=='here') {
var t=story.findContainingTiddler(place);
title=t?t.getAttribute('tiddler'):'';
}
arguments[1]=title; // default=current tiddler
this.displayTiddler_section.apply(this,arguments);
story.scrollToSection(title,section);
}
//}}}
/***
<html><a name="sampleanchorlink" /></html>This is a sample ''anchor link'': {{{<html><a name="sampleanchorlink" /></html>}}}
!!!!!isExternalLink
***/
//{{{
if (!config.formatterHelpers.isExternalLink_section)
config.formatterHelpers.isExternalLink_section=config.formatterHelpers.isExternalLink;
config.formatterHelpers.isExternalLink=function(link) { // remove section references before testing
var l=link.split(config.textPrimitives.sectionSeparator)[0];
return config.formatterHelpers.isExternalLink_section(l);
}
//}}}
/***
!!!!!tiddler.handler
***/
//{{{
if (!config.macros.tiddler.handler_section)
config.macros.tiddler.handler_section=config.macros.tiddler.handler;
config.macros.tiddler.handler=function(place,macroName,params,wikifier,paramString,tiddler)
{
if (!params[0]) return;
var sep=config.textPrimitives.sectionSeparator;
var parts=params[0].split(sep); var tid=parts[0]; var sec=parts[1]; if (sec) sec=sec.trim();
if ((tid.toLowerCase()=='here'||!tid.length) && sec) { // fixup for 'here##section' and '##section'
var here=story.findContainingTiddler(place)
var tid=here?here.getAttribute('tiddler'):tiddler?tiddler.title:'';
arguments[2][0]=tid+sep+sec;
arguments[4]=paramString.replace(new RegExp('(here)?'+sep+sec),tid+sep+sec);
}
config.macros.tiddler.handler_section.apply(this,arguments);
}
//}}}
/***
!!!!sectionTOC macro
***/
//{{{
config.macros.sectionTOC = {
targetClass: 'sectionTOC',
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var out=[];
var targetClass=params[0]||this.targetClass;
var t=story.findContainingTiddler(place); if (!t) return;
var elems=t.getElementsByTagName('*');
var level=5; // topmost heading level
for (var i=0; i<elems.length; i++) {
var txt=getPlainText(elems[i]).trim();
var link='[['+txt+'|##'+txt+']]';
switch(elems[i].nodeName) {
case 'H1': out.push('#'+link); level=1; break;
case 'H2': out.push('##'+link); level=level<2?level:2; break;
case 'H3': out.push('###'+link); level=level<3?level:3; break;
case 'H4': out.push('####'+link); level=level<4?level:4; break;
case 'H5': out.push('#####'+link); level=level<5?level:5; break;
default: if (hasClass(elems[i],targetClass)) var target=elems[i];
}
}
// trim excess bullet levels
if (level>1) for (var i=0; i<out.length; i++) out[i]=out[i].substr(level-1);
// show numbered list
if (out.length && target) {
if (target.style.display=='none') target.style.display='block';
wikify(out.join('\n'),target);
}
}
}
//}}}
/***
!!!Invoke macro
{{{
<<sectionTOC>>
}}}
***/
// //<<sectionTOC>>
Mein Eigenes Linux System (externe Version)
~MelsWiki
/*{{{*/
/* EGGERSPEZIFISCHE STYLESHEET ANPASSUNGEN */
/* WELCHE IN SEPARATEM TIDDLER AUSGELAGERT */
/* WURDEN ZWECKS EINFACHEREM HANDLING */
[[EggerCSSAnpassungen]]
/*}}}*/
<div class='toolbar' macro='toolbar -closeTiddler closeOthers +editTiddler permalink references jump'></div> <div class='title' macro='view title'></div> <div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (erstellt am <span macro='view created date'></span>)</div> <div class='tagging' macro='tagging'></div> <div class='tagged' macro='tags'></div> <div class='viewer' macro='view text wikified'> <span class='sectionTOC clear small floatright groupbox' style='display:none'> <b>Inhaltsverzeichnis:</b> </span> </div> <div class='tagClear'></div>