// Progranism Source Code: Version 2.5.1 // This new version of Progranisms should handle restrictive environments better // It implements a better method of seeding the random number generator // Returning to asexual behavior // 2.5.1: Modified mutation selection code // This is Linux code and should not compile under Windows #include #include #include #include #include FILE *load_file(const char *file); void create_child(FILE *file); int main(int argc, char *argv[]) { struct timeval seed; FILE *file = NULL; // Seed the random number generator with the number of microseconds since the Epoch // This ensures that even when two Progranisms execute at the "same" time they will get // different seeds gettimeofday(&seed, NULL); srand(seed.tv_usec); // Wait 30 seconds, +- 7 sleep(30 + (rand() % 14) - 7); // Get a file pointer to this progranism file = load_file(argv[0]); if(file == NULL) return -1; // Create the children. int i; for(i = 0; i < 2; ++i) create_child(file); // Close files fclose(file); // All done return 0; } // This is a big function. It creates a new progranism from the two given files // and then executes it. void create_child(FILE *file) { int len = 0; int i = 0; FILE *child; char child_name[1024]; // Generate a random name for the child sprintf(child_name, "progranism-%i%i", rand(), rand()); child = fopen(child_name, "wb"); if(child == NULL) return; // Since file is used many times they can be in bad conditions (like EOF). clearerr(file); // Get the length of the file. This will be the file length of the child. fseek(file, 0, SEEK_END); len = ftell(file); // Reset to the beginning of the file fseek(file, 0, SEEK_SET); // Now write the child while(1) { int byte = fgetc(file); if(byte == EOF) break; // If this byte needs to be mutated than do so // Will cause 1 mutation every 7 children (on average). if((rand() % (len * 7)) == 7) { switch(rand() % 3) { case 0: // ADD fputc(rand() & 0xFF, child); fputc(byte, child); break; case 1: // REMOVE break; case 2: //CHANGE fputc(rand() & 0xFF, child); break; default: break; } } else fputc(byte, child); ++i; } fclose(child); // Make executable and execute chmod(child_name, S_IEXEC | S_IREAD | S_IWRITE); char temp[1024]; sprintf(temp, "./%s &", child_name); system(temp); } // Simply loads a file and returns its FILE * FILE *load_file(const char *file) { return fopen(file, "rb"); }