/*--------------------------------- HEAD ---------------------------------------------------* * * Projekt : gcc-cross-compile-pfad-patch * Version : 0.4 * Author : André Raupach * Datei : gcc_cross_compile_pfad_patch.c * Datum : 25.10.2007 * Beschreibung : Wenn ein Cross-Compiler erstellt und installiert wird sind seine Pfade * fest eingestellt. Dies ist fuer uns nicht aktzeptabel. Dieses Programm * dient dazu einen eingestellten Pfad durch einen neuen zu ersetzen solange * der neue Pfad nicht grösser als der alte Pfad ist. Dazu werden die Binary's * der entsprechenden Dateien modifiziert. Die Dateien werden in dem alten * Pfad gesucht. * * History: Name Datum Version Aenderung * André Raupach 25.10.2007 0.1 anlegen der Datei * André Raupach 29.10.2007 0.2 Einbau einer Überprüfung, dass der Patch selber * nicht gepatched wird wenn er sich im Verzeichniss * welches gepatched wird befindet. * André Raupach 04.12.2007 0.3 Grosse Änderung: * Alle Dateien werden gepatched ausser die, welche im * Stammvereichnis liegen (Patch und shellskript liegen dort) * Erweiterung des Patches auf einen weiteren Pfad. * Änderung des ersten Pfad Patches so das dieser Fehlerfrei * angewendet wird. * André Raupach 11.12.2007 0.4 Einbau eines Dateigroessenvergleich nach dem Patchen um * sicher zu gehen das die Groesse der Datei sich nicht * geändert hat. * ********************************** END HEAD ***********************************************/ /*--------------------------------- DEFINES -----------------------------------------------*/ //Warum die Aufteilung des alten Pfades in drei Teile? Dies ist wichitg da manche Teile des Pfades //mal benötigt werden und mal nicht. #define PAR_ALTER_PFAD_STAMM "-aps" //Damit ist das Verzeichniss gemeint in dem die GU ausgecheckt wurde. absolute Pfadangabe (/home/mustermann/GU_TEST) #define PAR_ALTER_PFAD_FILESYSTEM "-apf" //Damit ist nur das Verzeichnis gemeint welches genutzt wurde um den Pfad etwas länger zu machen filesystem-filesystem-... #define PAR_ALTER_PFAD_GCCGEN "-apg" //Damit ist der Ordner gemeint in dem der Compiler erzeugt wurde. z.B.: GCC_x86_64_ur8_build #define PAR_NEUER_PFAD "-np" #define PAR_HILFE "-h" #define TRUE 1 #define FALSE 0 /********************************** END DEFINES ********************************************/ /*--------------------------------- INCLUDES ----------------------------------------------*/ #include #include #include #include #include #include #include #include #include /********************************** END INCLUDES ********************************************/ char *s_programm_name = NULL; char *s_programm_path = NULL; /*--------------------------------- AUSGABE HILFE ------------------------------------------*/ /* Die Funktion "f_hilfe" zeigt auf dem stdout eine Hilfeausgabe an, die alle Parameter und eine kurze * Erklärung enthält. * Keine Rückgabe. */ void f_hilfe(void) { printf("\n\nDie Hilfe.\n"); printf("%s\tAngabe des Stammpfades. /home/name/name_GU \n", PAR_ALTER_PFAD_STAMM); printf("%s\tAngabe des Verzeichnisnamen in dem der Compiler installiert wurde. filesystem-filesystem-... \n", PAR_ALTER_PFAD_FILESYSTEM); printf("%s\tAngabe des Verzeichnisnamen in dem die Compilererstellung stattfindet. GCC_x86_64_ur8_build\n", PAR_ALTER_PFAD_GCCGEN); printf("%s\tNeuer Pfad der in den Cross-Compiler eingestellt werden soll.\n", PAR_NEUER_PFAD); printf("%s\tDiese Hilfe\n\n", PAR_HILFE); } /********************************** END AUSGABE HILFE ***************************************/ /*--------------------------------- GLOBALE VARIABLEN---------------------------------------*/ /********************************** END GLOBALE VARIABLEN ***********************************/ /*--------------------------------- PATCHE EXEC -------------------------------------------*/ /* Die Funktion "f_patche_exec" dient dazu eine einzelne Datei komplett zu patchen. Das heisst alle * alten Pfade durch den neuen zu ersetzen. * Der erste Parameter ist der Name der Datei die gepatched werden soll. * Rückgabe ist 0 für alles OK ansonsten wird ein Fehlercode gesendet. */ int f_patche_exec(char *s_datei, char *s_alter_pfad_stamm, char *s_alter_pfad_filesystem, char *s_alter_pfad_gccgen, char *s_neuer_pfad) { int fd; //Filedescriptor struct stat stat; //Um einige Informationen über die verwendete Datei zu erhalten int i_alter_pfad_len; //länge des alten Pfades int i_neuer_pfad_len; //länge des neuen Pfades int i_alter_pfad_gccgen_len;//länge des alten Generierungspfades plus "/../" char c_fuell_char; //mit diesem Char werden evenuell auftretende Lücken bei der Ersetzung der Pfade aufgefüllt. int i_feld_len; //Die ist die Länge des Strings der bearbeitet werden muss char *p_mmap_datei = NULL; //Pointer auf die in den Speicher gemappte Datei char *p_mmap_akt_pos = NULL;//Pointer der zum Durchsuchen der in den Speicher gemappten Datei verwendet wird. char s_buffer_p1[1024] ; char s_buffer_p2[1024] ; int i_datei_groesse_vor_optimierung; int count = 0; //ein \n am Ende eines Pfades ist unerwünscht und muss entfernt werden if (s_datei[strlen(s_datei)-1] == '\n') { s_datei[strlen(s_datei)-1] = '\0'; } printf("Verarbeite Datei: %s ", s_datei); //zu Patchende Datei mit Lese und Schreibrechten öffnen fd = open(s_datei, O_RDWR); if(fd < 0) { printf("Error\n"); printf("Konnte Datei %s nicht oeffnen.\n", s_datei); return (-errno); } //ermitteln einiger Informationen über die Datei. if (fstat(fd, &stat) < 0) { printf("Error\n"); printf("Konnte Eigenschaften der Datei %s nicht ermitteln.\n", s_datei); return (-errno); } //Test ob die Datei eine 0 Byte Datei ist. Diese würden Zu Fehler führen welche logischer weise keine sind. Eine 0 byte Datei muss nicht gepatched werden. if(stat.st_size == 0) { printf("OK\nDie Datei %s hat die Dateigrösse %d byte und braucht bzw. kann nicht optimiert werden.\n\n", s_datei,stat.st_size); return 0; } else { i_datei_groesse_vor_optimierung = stat.st_size; } //mappen der Datei in den Speicher. Wichtig hier die Mapping flags müssen auf shared gesetzt sein //da sonst kein Speichern in die Datei möglich ist und alle Änderungen einfach verloren gehen. p_mmap_datei = mmap(NULL, stat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 ); if ( (long)p_mmap_datei < 0) { int errnosave = errno; printf("Error\n"); printf("Konnte Datei %s nicht in den Speicher mappen. Errorcode: %d\n", s_datei, errno); switch(errnosave) { case EACCES: printf("Fehlercode: EACCES\n"); break; case EAGAIN: printf("Fehlercode: EAGAIN\n"); break; case EINVAL: printf("Fehlercode: EINVAL\n"); break; case ENFILE: printf("Fehlercode: ENFILE\n"); break; case ENODEV: printf("Fehlercode: ENODEV\n"); break; case ENOMEM: printf("Fehlercode: ENOMEM\n"); break; case EPERM: printf("Fehlercode: EPERM\n"); break; case ETXTBSY: printf("Fehlercode: ETXTBSY\n"); break; //case SIGSEGV: printf("Fehlercode: SIGSEGV\n"); // break; //case SIGBUS: printf("Fehlercode: SIGBUS\n"); // break; default: printf("Unbekannter Fehlercode\n"); break; } return (errnosave); } //Start des Patchens //Vorbereitung der Suchpfade bzw. der Pfade, welche ersetzt werden sollen. //Hier wird der Pfad /home/name/GCC_bla/filesystem-... durch den neuen Pfad ausgetauscht in dem der Compiler installiert ist. if(s_alter_pfad_gccgen && s_alter_pfad_filesystem) { sprintf(s_buffer_p1, "%s/%s/%s", s_alter_pfad_stamm, s_alter_pfad_gccgen, s_alter_pfad_filesystem); } else { sprintf(s_buffer_p1, "%s", s_alter_pfad_stamm); } i_alter_pfad_len = strlen(s_buffer_p1); i_neuer_pfad_len = strlen(s_neuer_pfad); //Hier wird der unsinnige GCC_bla Pfad aus den restlichen Pfaden gelöscht bei denen dies ohne weiteres möglich ist. GCC_bla/../archiv/ sprintf(s_buffer_p2, "%s/../", s_alter_pfad_gccgen); i_alter_pfad_gccgen_len = strlen(s_buffer_p2); p_mmap_akt_pos = p_mmap_datei; /*--- printf("\nDer alte(%d): \"%s\"\n", i_alter_pfad_len, s_buffer_p1); ---*/ //solange es noch möglich ist den alten Pfad in der gemappten Datei zu finden versuche es while( (p_mmap_akt_pos + i_alter_pfad_len) < (p_mmap_datei + stat.st_size) ) { //Pfad an aktueller position gefunden if(memcmp(p_mmap_akt_pos, s_buffer_p1, i_alter_pfad_len) == 0) { //....gefunden... //Beim Patchen gibt es zwei Unterschiede. Einmal haben wir Pfade die Null terminiert sind und einmal in //Hochkommata eingebettet sind ("xxx"). Wenn also vor dem Pfad ein '"' zu finden ist dann handelt es sich //um die eine Variante sonst um die andere. Sonderfall: ganz am anfang (erstes Byte) hat keinen Vorgänger //also auch keine '"' vor sich. //Im Fall der '"' Muss die Länge des zu bearbeitenden String anders berechnet werden und das hintere '"' mit //in den String integriert werden. Ausserdem unterscheiden sich die FüllZeichen da einmal viele Nullterminierungen //genutzt werden können und im Fall des '"' Leerzeichen verwendet werden müssen. if( ((p_mmap_akt_pos-1) < p_mmap_datei) || (p_mmap_akt_pos[-1] != '"')) { i_feld_len = strlen(p_mmap_akt_pos); c_fuell_char = '\0'; } else { //die minus 1 bei ((off_t)p_mmap_akt_pos - 1) ist nötig um auch das '"' hinter dem Pfad mit zu verarbeiten. Der String wird also erweitert. i_feld_len = (off_t)strchr(p_mmap_akt_pos, '"') - ((off_t)p_mmap_akt_pos - 1); c_fuell_char = ' '; } //printf("[%d]\n[%.*s]\n", i_feld_len, i_feld_len, p_mmap_akt_pos); //Kopiere an die Startposition des alten Pfades den neuen Pfad memcpy(p_mmap_akt_pos, s_neuer_pfad, i_neuer_pfad_len); //Kopiere die restlichen Pfadangaben hinter dem alten Pfad nun hinter den neuen Pfad. Im Fall des '"' auch das '"'. memcpy(p_mmap_akt_pos + i_neuer_pfad_len, p_mmap_akt_pos + i_alter_pfad_len, i_feld_len - i_alter_pfad_len); //Als letztes werden nun die Füllzeichen eingefügt. die Anzahl der einzufügenden Füllzeichen ist dabei von der differenz des neuen kompletten Pfades //zum alten abhängig. Es gilt das die Grösse der Datei und damit der Ersetzung immer gleich sein muss. memset(p_mmap_akt_pos + i_neuer_pfad_len + i_feld_len - i_alter_pfad_len, c_fuell_char, i_alter_pfad_len - i_neuer_pfad_len); count++; //printf("[%.*s]\n", i_feld_len, p_mmap_akt_pos); //bei einer Ersetzung kann der eben eingefügte Pfad für eine erneute Überprüfung übersprungen werden. p_mmap_akt_pos += i_neuer_pfad_len; continue; } else if(memcmp(p_mmap_akt_pos, s_buffer_p2, i_alter_pfad_gccgen_len) == 0) { //....gefunden... i_feld_len = strlen(p_mmap_akt_pos); c_fuell_char = '\0'; //Kopiere die restlichen Pfadangaben hinter dem s_buffer_p2 Pfad nun an die startposition p_mmap_akt_pos. memcpy(p_mmap_akt_pos, p_mmap_akt_pos + i_alter_pfad_gccgen_len, i_feld_len - i_alter_pfad_gccgen_len ); //Als letztes werden nun die Füllzeichen eingefügt. die Anzahl der einzufügenden Füllzeichen ist dabei von der groesse des entfernten Pfades //abhängig. Es gilt das die Grösse der Datei und damit der Ersetzung immer gleich sein muss. memset(p_mmap_akt_pos + i_feld_len - i_alter_pfad_gccgen_len, c_fuell_char, i_alter_pfad_gccgen_len); //printf("[%.*s]\n", i_feld_len, p_mmap_akt_pos); count++; p_mmap_akt_pos += 1; continue; } //nichts gefunden also zum nächsten Byte und wieder vergleichen p_mmap_akt_pos++; } //bei der Synchronisation wird die im Speicher befindliche gemappte Datei wieder lokal gespeichert if ( msync(p_mmap_datei, stat.st_size, MS_SYNC) < 0) { printf("Error\n"); printf("Konnte die Datei %s nicht Synchronisieren.\n", s_datei); return (-errno); } //Hier wird die Datei wieder aus dem Speicher entfernt und der Speicher steht anderen Dingen zur Verfügung if(munmap(p_mmap_datei, stat.st_size) < 0 ) { printf("Error\n"); printf("Konnte die Datei %s nicht unmappen.\n", s_datei); return (-errno); } //erneutes ermitteln einiger Informationen über die Datei. if (fstat(fd, &stat) < 0) { printf("Error\n"); printf("Konnte Eigenschaften der Datei %s nach dem Patch nicht ermitteln.\n", s_datei); return (-errno); } //Groessenvergleich der Datei vor und nach dem Patchen (eventuell Sinnlos aber was schadet es) if(i_datei_groesse_vor_optimierung != stat.st_size) { printf("Error\n"); printf("Datei %s hat nach dem Patch eine falsche Dateigroesse.\n", s_datei); return (-errno); } close(fd); printf("OK (%d patches)\n", count); return 0; } /********************************** END PATCHE EXEC ****************************************/ /*--------------------------------- SUCHE ALLE EXECUTABLES ---------------------------------*/ /* Die Funktion "f_suche_alle_exec" dient zum Auffinden der Zu patchenden Dateien. Diese sind executabels und * liegen im Pfad s_neuer_pfad. * Rückgabe ist ein Bools der angibt ob alles gut gegangen ist (TRUE) oder nicht (FALSE). */ int f_suche_alle_exec(char *s_alter_pfad_stamm, char *s_alter_pfad_filesystem, char *s_alter_pfad_gccgen, char *s_programm_name, char *s_neuer_pfad) { char b_alles_ok = TRUE; //Boolean für die Rückgabe FILE *fp; //Um Rückgabe von popen zu speichern char s_buffer[1024]; //Um Komandozeilenbefehle und so weiter zu speichern //Konsolenkommando zum auffinden der executabels //sprintf(s_buffer, "find %s -type f -print0 | xargs -0 file | grep -e 'ELF.*execu.*' | grep -v 'statically' | cut -d':' -f1", s_neuer_pfad ); //Konsolenkommando zum Auffinden aller Dateien sprintf(s_buffer, "find %s -mindepth 2 -type f", s_programm_path); /*--- printf("exec: %s\n", s_buffer); ---*/ fp = popen(s_buffer, "r"); if(fp != NULL) { while(!feof(fp)) { if(fgets(s_buffer, sizeof(s_buffer), fp)) { //Da das Patchprogramm im selben Ordner liegt in dem der Patch ausgeführt wird muss //das Programm von der Verarbeitung ausgeschlossen werden. if(strstr(s_buffer, s_programm_name) == NULL) { if (f_patche_exec(s_buffer, s_alter_pfad_stamm, s_alter_pfad_filesystem, s_alter_pfad_gccgen, s_neuer_pfad) != 0) { b_alles_ok = FALSE; printf("Fehler beim patchen der Datei %s \n\n", s_buffer); } } } } pclose(fp); } return b_alles_ok; } /********************************** END SUCHE ALLE EXECUTABLES ******************************/ /*--------------------------------- MAIN ---------------------------------------------------*/ //Hier werden alle wichtigen Variablen am Anfang initialisiert und eingelesen. Ansonsten ist es wie immer die //die MAIN Steuerzentrale. int main(int argc, char *argv[]) { int i; //temporäre Zählvariable char *s_temp = NULL; //temporärer Zwischenspeicher char *s_alter_pfad_stamm = NULL; char *s_alter_pfad_filesystem = NULL; char *s_alter_pfad_gccgen = NULL; char *s_neuer_pfad = NULL; printf("GCC_CROSS_COMPILER_PFAD_PATCH: v1.0\n"); //Ausführung ohne Parameter dann Hinweis geben if (argc < 2) { printf("\nAchtung!!! Es wurden keine Parameter uebergeben.\n"); printf("Folgende Parameter koennen benutzt werden.\n"); f_hilfe(); exit(0); } //Speichern des Programmnamen für spätere Nutzung. Da wir das erste Zeichen aus Sicherheitsgründen nicht haben wollen //Speichern wir argv[0]+1 s_programm_name=strdup(argv[0]+1); s_programm_path=strdup(argv[0]); if(strrchr(s_programm_path, '/')) *strrchr(s_programm_path, '/') = '\0'; //Auswerten der Konsolen-Parameter, wenn welche uebergeben wurden. for(i=1; i < (argc); i++) { if ((strcmp(argv[i], PAR_NEUER_PFAD)) == 0) { //--------------------------------------------------------Angabe des Verzeichnisses in dem die Firmware gespeichert ist. //Git es noch einen Parameter hinter dem aktuell Auszuwertenden if((i+1) < argc ) { //Beginnt dieser folgende Parameter mit einem "-" und ist somit ein neuer Befehl if( memchr(argv[i+1], '-', 2) == NULL ) { //nur wenn der angegebene Pfad existiert dann speichern /*--- if((s_temp = realpath(argv[i+1], s_temp)) != NULL) { ---*/ /*--- s_neuer_pfad = strdup(s_temp); ---*/ s_neuer_pfad = strdup(argv[i + 1]); /*--- free(s_temp); ---*/ /*--- s_temp = NULL; ---*/ /*--- } ---*/ /*--- else { ---*/ /*--- printf("Die Angabe des neuen Pfades ist Fehlerhaft.\nEs wurde folgendes eingegeben: \"%s\".\n", argv[i+1]); ---*/ /*--- exit(0); ---*/ /*--- } ---*/ i++; //wird erhöht um den folgenden Parameter, den wir gerade eingelesen haben, zu ueberspringen } else { printf("Hinter %s wird der neue Pfad erwartet und kein neuer Parameter.\n\"%s\" wurde eingegeben.\n", PAR_NEUER_PFAD, argv[i+1]); exit(0); } } else { printf("Hinter %s wird der neue Pfad erwartet.\nBeispiel: %s /home/name/GU_RELEASE/archiv/tmp-0-gcc_ur8/bin \n", PAR_NEUER_PFAD, PAR_NEUER_PFAD); exit(0); } } else if ((strcmp(argv[i], PAR_ALTER_PFAD_STAMM)) == 0) { //--------------------------------------------------------Angabe des Verzeichnisses in dem die Firmware gespeichert ist. //Git es noch einen Parameter hinter dem aktuell Auszuwertenden if((i+1) < argc ) { //Beginnt dieser folgende Parameter mit einem "-" und ist somit ein neuer Befehl if( memchr(argv[i+1], '-', 2) == NULL ) { //Beginnt der Pfad mit einem / ?? Wenn nicht wurde kein absoluter Pfad angegeben if( memchr(argv[i+1], '/', 1) != NULL ) { s_alter_pfad_stamm = strdup(argv[i+1]); i++; //wird erhöht um den folgenden Parameter, den wir gerade eingelesen haben, zu ueberspringen } else { printf("Bitte nur absolute Pfadangaben verwenden.\n%s ist kein absoluter Pfad\n", argv[i+1]); exit(0); } } else { printf("Hinter %s wird der alte Stamm Pfad erwartet und kein neuer Parameter.\n%s wurde eingegeben.\n", PAR_ALTER_PFAD_STAMM, argv[i+1]); exit(0); } } else { printf("Hinter %s wird der alte Pfad erwartet.\nBeispiel: %s /home/name/GCC_UR8/ \n", PAR_ALTER_PFAD_STAMM, PAR_ALTER_PFAD_STAMM); exit(0); } } else if ((strcmp(argv[i], PAR_ALTER_PFAD_FILESYSTEM)) == 0) { //--------------------------------------------------------Angabe des Verzeichnisses in dem die Firmware gespeichert ist. //Git es noch einen Parameter hinter dem aktuell Auszuwertenden if((i+1) < argc ) { //Beginnt dieser folgende Parameter mit einem "-" und ist somit ein neuer Befehl if( memchr(argv[i+1], '-', 2) == NULL ) { s_alter_pfad_filesystem = strdup(argv[i+1]); i++; //wird erhöht um den folgenden Parameter, den wir gerade eingelesen haben, zu ueberspringen } else { printf("Hinter %s wird der Ordnername des extrem langem fake Ordners erwartet welcher gentutzt wird um diesen Patch möglich zu machen.\n%s wurde eingegeben.\n", PAR_ALTER_PFAD_FILESYSTEM, argv[i+1]); exit(0); } } else { printf("Hinter %s wird der Ordnername des extrem langem fake Ordners erwartet welcher gentutzt wird um diesen Patch möglich zu machen.\nBeispiel: %s filesystem-filesystem-filesystem-filesystem-... \n", PAR_ALTER_PFAD_FILESYSTEM, PAR_ALTER_PFAD_FILESYSTEM); exit(0); } } else if ((strcmp(argv[i], PAR_ALTER_PFAD_GCCGEN)) == 0) { //--------------------------------------------------------Angabe des Verzeichnisses in dem die Firmware gespeichert ist. //Git es noch einen Parameter hinter dem aktuell Auszuwertenden if((i+1) < argc ) { //Beginnt dieser folgende Parameter mit einem "-" und ist somit ein neuer Befehl if( memchr(argv[i+1], '-', 2) == NULL ) { s_alter_pfad_gccgen = strdup(argv[i+1]); i++; //wird erhöht um den folgenden Parameter, den wir gerade eingelesen haben, zu ueberspringen } else { printf("Hinter %s wird der Ordnername werwartet in dem der Compiler generiert wurde.\n%s wurde eingegeben.\n", PAR_ALTER_PFAD_GCCGEN, argv[i+1]); exit(0); } } else { printf("Hinter %s wird der Ordnername werwartet in dem der Compiler generiert wurde.\nBeispiel: %s GCC_x86_64_ur8_build \n", PAR_ALTER_PFAD_GCCGEN, PAR_ALTER_PFAD_GCCGEN); exit(0); } } else if ((strcmp(argv[i], "-file")) == 0) { //--------------------------------------------------------Angabe des Verzeichnisses in dem die Firmware gespeichert ist. /*--- if(s_alter_pfad_gccgen && s_alter_pfad_filesystem) { ---*/ /*--- printf("Der alte: \"%s\"/\"%s\"/\"%s\"\n", s_alter_pfad_stamm, s_alter_pfad_gccgen, s_alter_pfad_filesystem); ---*/ /*--- } else { ---*/ /*--- printf("Der alte: \"%s\"\n", s_alter_pfad_stamm); ---*/ /*--- } ---*/ /*--- printf("Der neue: %s\nProgramm_name: %s\n", s_neuer_pfad, s_programm_name); ---*/ return f_patche_exec(argv[++i], s_alter_pfad_stamm, s_alter_pfad_filesystem, s_alter_pfad_gccgen, s_neuer_pfad); } else { //----------------------------------------------------------------------------------------ein unsinniger Parameter wurde eingegeben oder -h für die Hilfe f_hilfe(); return 0; }//end if }//end for /*--- if(s_alter_pfad_gccgen && s_alter_pfad_filesystem) { ---*/ /*--- printf("Der alte: \"%s\"/\"%s\"/\"%s\"\n", s_alter_pfad_stamm, s_alter_pfad_gccgen, s_alter_pfad_filesystem); ---*/ /*--- } else { ---*/ /*--- printf("Der alte: \"%s\"\n", s_alter_pfad_stamm); ---*/ /*--- } ---*/ /*--- printf("Der neue: %s\nProgramm_name: %s\n", s_neuer_pfad, s_programm_name); ---*/ //patchen if (f_suche_alle_exec(s_alter_pfad_stamm, s_alter_pfad_filesystem, s_alter_pfad_gccgen, s_programm_name, s_neuer_pfad) == FALSE) { printf("\n####################################################################\n"); printf("ACHTUNG!!! Beim Patchen sind Fehler aufgetreten.\n"); printf("####################################################################\n\n"); } else { printf("\nDer Patchvorgang wurde erfolgreich abgeschlossen.\n\n"); } //nötige Freigaben if(s_temp != NULL) { free(s_temp); } if(s_programm_name != NULL) { free(s_programm_name); } if(s_alter_pfad_stamm != NULL) { free(s_alter_pfad_stamm); } if(s_alter_pfad_filesystem != NULL) { free(s_alter_pfad_filesystem); } if(s_alter_pfad_gccgen != NULL) { free(s_alter_pfad_gccgen); } if(s_neuer_pfad != NULL) { free(s_neuer_pfad); } return 0; } /********************************** END MAIN *******************************************/