Eine Frage des guten Codes

Blackbird
Hallo zusammen.

Vor ein paar Tagen habe ich festgestellt das meine VPN Verbiundungen ab einer bestimmten
Verbindungszahl nicht mehr aufgebaut wurden. Das Problem war einfach das die Bandbreite
für den gleichzeitigen Aufbau von n Verbindungen nicht reicht.
Die Lösung recht einfach: Die Verbindungen einfach mit einem bestimmten Zeitabstand voneinander
Starten.

Zum Starten einer Verbindung muss man auf der Kommandozeile folgenden Befehl eingeben:

code:
1:
2:
3:
   > ipsec auto --up "verbindungsname"


Die Sache ist nur die das nun solange auf der Kommandozeile Meldungen gemacht werden bis
der Befehl erfogreich ausgeführt wurde. Das bedeutet aber auch das solange dies nicht
der Fall ist der Befehl aktiv ist und die Konsole blockiert.

Man kann dem Befehl auch einfach mit STRG-C abrrechen, damit wird die Verbindung dann im
Hintergrund weiter ausgeführt.

( JA ICH WEISS VIEL BLA BLA !! Kotzen )

Also gut ich wollte ein Programm schreiben das folgendes machen sollte:
1 Einlesen der Datei /etc/ipsec.conf
2 Suchen aller Verbindungsnamen (haben immer folgendes Format: "conn name\n")
3 Für jeden Verbindungsname ipsec auto --up "verbindungsname" ausführen
4 Diesen Befehl nach einer gewissen Zeit beenden

Schritt 3 und 4 sollen dabei für jeden gefunden Verbindungsnamen ausgeführt werden.

Folgendes ist dabei herausgekommen:

code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:

#include <pthread.h>
#include "eighdr.h"   //Enthält nur ein paar Makros und Funktions-Prototypen 
                      //benötigt wird aber nur fehler_meld
#include <signal.h>

#define WAIT_TIME 12  //Zeitintervall in dem die Verbindungen gestartet werden
#define BUFFER 255

void vpn();
void chomp(char *);

pid_t pid;
char  *connection;

int main(){
   pthread_t thread;
   FILE  *fz;     
      
   char buffer[BUFFER];
   char *tok;
   char *exclude1 = "block";   
   char *exclude2 = "private";   
   char *exclude3 = "private-or-clear";   
   char *exclude4 = "clear-or-private";   
   char *exclude5 = "clear";   
   char *exclude6 = "packetdefault";
      
   // ipsec .conf Datei öffnen
   if( (fz = fopen("/etc/ipsec.conf", "r")) == NULL)
      fehler_meld(FATAL_SYS, "Konnte ipsec.conf nicht öffen\n");
      
      //Datei Zeilenweise auslesen
      while( fgets(buffer,BUFFER, fz) != NULL ) {
         // Ersten Token aus String exrtrahieren
         tok = strtok(buffer, " ");
           
         // Prüfen ob Zeile eine Verbindungsdefinition ist
         // (erster Token muss gleich "conn" sein)
         if( strcmp(tok, "conn") != 0 )
            continue;
         
         // Verbindungsname extrahieren   
         connection = strtok(NULL, " ");
         // vom Verbindungsname "\n" entfernen
         chomp(connection);
         
         // Verbindungen die ausgelassen werden sollen werden hier
         // heraus gefiltert.
         if( strcmp(connection,exclude1) == 0 ||      
             strcmp(connection,exclude2) == 0 || 
             strcmp(connection,exclude3) == 0 ||
             strcmp(connection,exclude4) == 0 ||
             strcmp(connection,exclude5) == 0 ||
             strcmp(connection,exclude6) == 0
         ) continue;         
   
         if(pthread_create(&thread, NULL, (void *)&vpn, (void *) NULL) != 0) 
            fehler_meld(FATAL_SYS, "Fehler bei Thread Erstellung......");
   
         // Auf Beendigung des Threads warten.
         pthread_join(thread, NULL);
   } 
   
   return(0);
}

void vpn() {
   
   // fork() für execl aufrufen
   if( (pid = fork()) < 0 )
      fehler_meld(FATAL_SYS, "Fehler bei fork()\n");
            
   if(pid==0){
      printf("Starte Verbindung %s...\n", connection);       
   
      // Standartausgabe unterdrücken
      if (freopen("/dev/null", "a", stdout) != stdout)
            fehler_meld(FATAL_SYS, "Fehler bei freopen mit stdout");
            
         // Auszuführender Befehl
         char cmd[100] = "ipsec auto --up ";
         
         // Argument für Befehl anhängen
         strcat(cmd, connection);
         
         // Befehl ausführen
         execl("/bin/sh", "sh", "-c", cmd, NULL);
   }
   else{
      // WAIT_TIME warten und danach Prozess der durch execl 
      // überlagert wird beenden
      sleep(WAIT_TIME);
      kill(pid, SIGINT);
      
      //Thread verlassen.
      pthread_exit((void *) 0);
   }
}

void chomp(char *str) {
   size_t p=strlen(str);
   /* \n mit \0 überschreiben */
   str[p-1]='\0';
}


Dieses Programm Funtkioniert auch einwandfrei, aber ich Frage mich nur ob der Aufwand nicht einfach
viel zu groß ist und ob man das Problem nicht in einer etwas eleganteren Art und Weise hätte Lösen
können.

Ich habe z.B auch versucht ohne Threads auszukommen aber dann hatte ich immer Probleme damit die
Verbindungsnamen zu übergeben etc.


Ich danke schon einmal im Voraus für hoffentlich kommende Kommentare

MFG Blackbird
Hanfling
Vielleicht wäre nen einfaches Bash Script, etc. passender.
Allerdings solltest du so oder so Threads verwenden, da du je eh gleichzeitig Verbindungen herstellen kannst.