void handle_sigchld(int s) { int i; int pid; int bcg; int status; /* pobieram child process id */ while((pid = waitpid(-1, &status, WNOHANG)) > 0) { bcg = 1; fflush(stdout); for(i = 0; i < chld_pids_size; i++) { if(chld_pids[i] == pid) { chld_active--; bcg = 0; break; } } /* zapamietujemy do wypisania ukonczone dziecko z backgroundu */ if(bcg && ended_processes < MAX_COMMANDS) { save_process(pid,status); } } }
int main(int argc, char** argv) { program_name = argv[0]; static char *commands[] = { "save", "restore", "send", "receive", "list", "delete" }; int commands_len = sizeof(commands)/sizeof(char*); static struct option long_options[] = { {"server", 1, 0, 's'}, {"name", 1, 0, 'n'}, {"output", 1, 0, 'o'}, {"nokill", 0, 0, 'K'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, {"file-save", 0, 0, 'f'}, {NULL, 0, NULL, 0} }; int c,i,option_index = 0; if (argc<2) { usage(-1); exit(1); } for (i=0;i<commands_len;i++) { if (!strcmp(commands[i],argv[1])) break; } if (!strcmp(argv[1],"--help") || !strcmp(argv[1],"-h")) { usage(-1); exit(0); } if (i==commands_len) { usage(-1); exit(1); } command_index = i; char** real_argv = malloc(sizeof(char*)*argc-1); real_argv[0] = argv[0]; for (i=1;i<argc-1;i++) { real_argv[i] = argv[i+1]; } char *output=NULL,*host=NULL,*name=NULL; int nokill = FALSE; verbose = 0; flags = 0; while ((c = getopt_long(argc-1, real_argv, "s:vn:hKo:f", long_options, &option_index)) != -1) { switch (c) { case 's': host = malloc(strlen(optarg)); strcpy(host,optarg); break; case 'v': verbose=TRUE; break; case 'n': name = malloc(strlen(optarg)); strcpy(name,optarg); break; case 'h': usage(command_index); exit(0); break; case 'o': output = malloc(strlen(optarg)); strcpy(output,optarg); break; case 'K': nokill = TRUE; break; case 'f': flags |= PROC_FLAG_SAVE_FILE; break; default: fprintf(stderr,"?? getopt returned character code 0%o ??\n", c); } } if (command_index==0) { //save if (optind >= argc-1 && name==NULL) { usage(command_index); exit(1); } pid_t pid = 0; if (name!=NULL) { char tmpproc[100]; sprintf(tmpproc,"ps ux | awk '/%s/ && !/awk/ {print $2}'",name); FILE* proc = popen(tmpproc,"r"); fscanf(proc,"%d",&pid); pclose(proc); } else { pid = atoi(real_argv[optind]); } struct proc_process p = save_process(pid,"test",nokill); if (output!=NULL) { FILE* proc = fopen(output,"w+"); write_process(p,proc,write_to_file_pointer); fclose(proc); } else { char* id; if ((id = send_proc_to_local_server(p))==NULL) write_process(p,stdout,write_to_file_pointer); printf("%s\n",id); } } else if (command_index==1) { //restore if (optind >= argc-1) { usage(command_index); exit(1); } char* f_id = real_argv[optind]; FILE* proc = fopen(f_id,"r"); struct proc_process *p=NULL; if (!proc) { p = receive_proc_from_local_server(f_id); } else { p = read_process(proc,read_from_file_pointer); } if (p!=NULL) restore_process(*p); } else if (command_index==2) { //send if (optind >= argc-1 && name==NULL) { usage(command_index); exit(1); } pid_t pid = 0; struct proc_process *p=NULL; if (name!=NULL) { char tmpproc[100]; sprintf(tmpproc,"ps ux | awk '/%s/ && !/awk/ {print $2}'",name); FILE* proc = popen(tmpproc,"r"); fscanf(proc,"%d",&pid); pclose(proc); struct proc_process tmpp = save_process(pid,"test",nokill); p = &tmpp; } else { char* f_id = real_argv[optind]; FILE* proc = fopen(f_id,"r"); if (!proc) { p = receive_proc_from_local_server(f_id); if (!p) { pid = atoi(real_argv[optind]); struct proc_process tmpp = save_process(pid,"test",nokill); p = &tmpp; } } else { p = read_process(proc,read_from_file_pointer); } } char* ip=DEFAULT_HOST; int port=DEFAULT_PORT; if (host!=NULL) { char* pos = strchr(host,':'); if (pos!=NULL) { *pos='\0'; ip=host; port=*(++pos); } else { ip=host; port = DEFAULT_PORT; } } send_process(*p,ip,port); } else if (command_index==3) { //receive char* id = NULL; if (optind >= argc-1) { id = real_argv[optind]; } struct proc_process *p= receive_proc_from_local_server(id); if (p!=NULL) restore_process(*p); } else if (command_index==4) { //list list_from_local_server(); } else if (command_index==5) { //delete if (optind >= argc-1) { usage(command_index); exit(1); } char id[SIZE_OF_ID]; strcpy(id,real_argv[optind]); delete_from_local_server(id); } return 0; }
//-------- Begin of function GameFile::save_game --------// // // return : <int> 1 - saved successfully. // 0 - not saved. // int GameFile::save_game(const char* fileName) { char full_path[MAX_PATH+1]; File file; String errStr; power.win_opened=1; // to disable power.mouse_handler() if( fileName ) strcpy( file_name, fileName ); int rc = 1; if (!misc.path_cat(full_path, sys.dir_config, file_name, MAX_PATH)) { rc = 0; errStr = _("Path too long to the saved game"); } if( rc ) { rc = file.file_create(full_path, 0, 1); // 0=tell File don't handle error itself // 1=allow the writing size and the read size to be different if( !rc ) errStr = _("Error creating saved game file."); } if( rc ) { save_process(); // process game data before saving the game rc = write_game_header(&file); // write saved game header information if( !rc ) errStr = _("Error creating saved game header."); if( rc ) { rc = write_file(&file); if( !rc ) errStr = _("Error writing saved game data."); } } file.file_close(); power.win_opened=0; //------- when saving error ---------// if( !rc ) { remove( file_name ); // delete the file as it is not complete #ifndef DEBUG errStr = _("Insufficient disk space ! The game is not saved."); // use this message for all types of error message in the release version #endif box.msg( errStr ); } return rc; }
//-------- Begin of function GameFile::save_game --------// // // return : <int> 1 - saved successfully. // 0 - not saved. // int GameFile::save_game(const char* fileName) { char full_path[MAX_PATH+1]; File file; String errStr; power.win_opened=1; // to disable power.mouse_handler() if( fileName ) strcpy( file_name, fileName ); int rc = 1; if (!misc.path_cat(full_path, sys.dir_config, file_name, MAX_PATH)) { rc = 0; errStr = "Path too long to the saved game"; } char lowDiskSpaceFlag = 0; #ifndef NO_WINDOWS // FIXME DWORD sectorPerCluster = 0; DWORD bytePerSector = 0; DWORD freeCluster = 0; DWORD totalCluster = 0; if( GetDiskFreeSpace( NULL, // address of root path, NULL means the current root directory §orPerCluster, &bytePerSector, &freeCluster, &totalCluster)) { DWORD freeSpace = DWORD( (double)freeCluster * sectorPerCluster * bytePerSector / 1024.0); if( misc.is_file_exist(file_name) ) { // if overwritting existing file, count the file size of the existing file file.file_open(file_name); freeSpace += file.file_size() / 1024; // count the existing space file.file_close(); } if( !(rc = freeSpace >= MIN_FREE_SPACE) ) { errStr = "Insufficient disk space ! The game is not saved."; lowDiskSpaceFlag = 1; } } #endif if( rc ) { rc = file.file_create(full_path, 0, 1); // 0=tell File don't handle error itself // 1=allow the writing size and the read size to be different if( !rc ) errStr = "Error creating saved game file."; } if( rc ) { save_process(); // process game data before saving the game rc = write_game_header(&file); // write saved game header information if( !rc ) errStr = "Error creating saved game header."; if( rc ) { rc = write_file(&file); if( !rc ) errStr = "Error writing saved game data."; } } file.file_close(); power.win_opened=0; //------- when saving error ---------// if( !rc ) { if( !lowDiskSpaceFlag ) remove( file_name ); // delete the file as it is not complete #ifndef DEBUG errStr = "Insufficient disk space ! The game is not saved."; // use this message for all types of error message in the release version #endif box.msg( errStr ); } return rc; }
//-------- Begin of function GameFile::save_game --------// // // <char *> pathName save game path, without '\' at the end // <char *> fileName save game filename, null for unchange, use file_name // <char *> gameDesc save game description : null for unchange // // return : <int> 1 - saved successfully. // 0 - not saved. // // ###### begin Gilbert 26/5 ########// int GameFile::save_game(const char *path, const char* fileName, const char *gameDesc) // ###### end Gilbert 26/5 ########// { File file; String errStr; power.win_opened=1; // to disable power.mouse_handler() if( fileName ) { if( path && path[0] != '\0' ) // non empty string { strcpy(file_name, path); strcat(file_name, PATH_DELIM); strcat(file_name, fileName); } else { strcpy(file_name, fileName); } } // #### begin Gilbert 20/1 ######// if( gameDesc ) strncpy( game_desc, gameDesc, SAVE_GAME_DESC_LEN ); game_desc[SAVE_GAME_DESC_LEN] = '\0'; // #### end Gilbert 20/1 ######// // ----- test disk space --------// int rc = 1; char lowDiskSpaceFlag = 0; #ifndef NO_WINDOWS // FIXME DWORD sectorPerCluster = 0; DWORD bytePerSector = 0; DWORD freeCluster = 0; DWORD totalCluster = 0; if( GetDiskFreeSpace( NULL, // address of root path, NULL means the current root directory §orPerCluster, &bytePerSector, &freeCluster, &totalCluster)) { DWORD freeSpace = DWORD( (double)freeCluster * sectorPerCluster * bytePerSector / 1024.0); if( misc.is_file_exist(file_name) ) { // if overwritting existing file, count the file size of the existing file file.file_open(file_name); freeSpace += file.file_size() / 1024; // count the existing space file.file_close(); } if( !(rc = freeSpace >= MIN_FREE_SPACE) ) { errStr = text_game_menu.str_out_of_disk_space(); // "Insufficient disk space ! The game is not saved."; lowDiskSpaceFlag = 1; } } #endif // ##### begin Gilbert 2/11 ######// if( rc ) { // create directory char *lastSlash = NULL; char *s = file_name; while( (s = strchr( s, '\\')) ) { lastSlash = s; ++s; // start again at next character } if( lastSlash ) { char backupChar = *lastSlash; err_when( backupChar != '\\' ); *lastSlash = '\0'; // truncate to and not including the last '\\' misc.mkpath( file_name ); *lastSlash = backupChar; // res } } // ##### end Gilbert 2/11 ######// if( rc ) { rc = file.file_create( file_name, 0, 1 ); // 0=tell File don't handle error itself // 1=allow the writing size and the read size to be different if( !rc ) // errStr = "Error creating saved game file."; errStr = text_game_menu.str_save_error_create(); } if( rc ) { save_process(); // process game data before saving the game rc = write_game_header(&file); // write saved game header information if( !rc ) errStr = text_game_menu.str_save_error_header(); // "Error creating saved game header."; if( rc ) { rc = write_file(&file); if( !rc ) errStr = text_game_menu.str_save_error_general(); // "Error writing saved game data."; } } file.file_close(); power.win_opened=0; //------- when saving error ---------// if( !rc ) { if( !lowDiskSpaceFlag ) remove( file_name ); // delete the file as it is not complete #ifndef DEBUG // errStr = "Insufficient disk space ! The game is not saved."; // use this message for all types of error message in the release version errStr = text_game_menu.str_out_of_disk_space(); #endif box.msg( errStr ); } return rc; }