/** * Remove all files needed for correct working after chrooting * from solution directory * * @param __dir - where files should be deleted */ static void remove_chroot_data (const char *__dir) { int i = 0; char full[4096]; INF_DEBUG_LOG ("Removing chroot data from %s\n", __dir); while (chroot_items[i][0]) { snprintf (full, BUF_SIZE (full), "%s/%s", __dir, chroot_items[i]); unlinkdir (full); i++; } }
void unlinkdir(const char *dir,int contentonly) { struct stat st; DIR *dirp; struct dirent *direntp; char dname[MAXLEN]; int err; dirp=opendir(dir); if (!dirp) return; while ((direntp = readdir(dirp)) != NULL) { if (direntp->d_name[0] == '.' && (direntp->d_name[1] == '\0' || (direntp->d_name[1] == '.' && direntp->d_name[2] == '\0'))) continue; if (snprintf(dname,sizeof(dname),"%s/%s",dir,direntp->d_name)>=sizeof(dname)) { debuga(_("directory name to delete too long: %s/%s\n"),dir,direntp->d_name); exit(EXIT_FAILURE); } #ifdef HAVE_LSTAT err=lstat(dname,&st); #else err=stat(dname,&st); #endif if (err) { debuga(_("cannot stat %s\n"),dname); exit(EXIT_FAILURE); } if (S_ISREG(st.st_mode)) { if (unlink(dname)) { debuga(_("cannot delete %s - %s\n"),dname,strerror(errno)); exit(EXIT_FAILURE); } } else if (S_ISDIR(st.st_mode)) { unlinkdir(dname,0); } else { debuga(_("unknown path type %s\n"),dname); } } closedir(dirp); if (!contentonly) { if (rmdir(dir)) { debuga(_("cannot delete %s - %s\n"),dir,strerror(errno)); exit(EXIT_FAILURE); } } }
int vrfydir(const struct periodstruct *per1, const char *addr, const char *site, const char *us, const char *form) { FILE *fp_ou; int num=1, count=0; char wdir[MAXLEN]; char dirname2[MAXLEN]; int y1, y2; int m1, m2; int d1, d2; int wlen, wlen2; time_t curtime; struct tm *loctm; strcpy(wdir,outdir); wlen=strlen(wdir); y1=per1->start.tm_year+1900; y2=per1->end.tm_year+1900; m1=per1->start.tm_mon+1; m2=per1->end.tm_mon+1; d1=per1->start.tm_mday; d2=per1->end.tm_mday; if(IndexTree == INDEX_TREE_DATE) { wlen+=sprintf(wdir+wlen,"%04d",y1); if(y1!=y2) wlen+=sprintf(wdir+wlen,"-%04d",y2); if(access(wdir, R_OK) != 0) my_mkdir(wdir); wlen+=sprintf(wdir+wlen,"/%02d",m1); if(m1 != m2) wlen+=sprintf(wdir+wlen,"-%02d",m2); if(access(wdir, R_OK) != 0) my_mkdir(wdir); wlen+=sprintf(wdir+wlen,"/%02d",d1); if(d1!=d2) wlen+=sprintf(wdir+wlen,"-%02d",d2); } else { if(df[0] == 'u') { wlen=snprintf(wdir+wlen,sizeof(wdir)-wlen,"%04d%s%02d-%04d%s%02d",y1, conv_month_name(m1),d1,y2,conv_month_name(m2),d2); } else if(df[0] == 'e') { wlen=snprintf(wdir+wlen,sizeof(wdir)-wlen,"%02d%s%04d-%02d%s%04d",d1, conv_month_name(m1),y1,d2,conv_month_name(m2),y2); } else if(df[0] == 'w') { wlen2=strftime(wdir+wlen, sizeof(wdir)-wlen, "%Y.%U", &per1->start); if (wlen2==0) return(-1); wlen+=wlen2; } } if(us[0] != '\0') { struct userinfostruct *uinfo=userinfo_find_from_id(us); if (uinfo) { strcat(wdir,"-"); strcat(wdir,uinfo->filename); } } if(addr[0] != '\0') { strcat(wdir,"-"); strcat(wdir,addr); } if(site[0] != '\0') { strcat(wdir,"-"); strcat(wdir,site); } strcpy(outdirname,wdir); if(IndexTree != INDEX_TREE_DATE) { if(!OverwriteReport) { while(num) { if(access(wdir,R_OK) == 0) { sprintf(wdir,"%s.%d",outdirname,num); num++; count++; } else break; } if(count > 0) { if(debug) debuga(_("File %s already exists, moved to %s\n"),outdirname,wdir); rename(outdirname,wdir); } } else { if(access(outdirname,R_OK) == 0) { unlinkdir(outdirname,1); } } my_mkdir(outdirname); } else { strcpy(dirname2,wdir); if(!OverwriteReport) { while(num) { if(access(wdir,R_OK) == 0) { sprintf(wdir,"%s.%d",dirname2,num); num++; count++; } else break; } if(count > 0) { if(debug) debuga(_("File %s already exists, moved to %s\n"),dirname2,wdir); rename(dirname2,wdir); strcpy(dirname2,wdir); } } else { if(access(wdir,R_OK) == 0) { unlinkdir(wdir,1); } } if(access(wdir, R_OK) != 0) my_mkdir(wdir); } strcpy(dirname2,wdir); sprintf(wdir,"%s/sarg-date",outdirname); if ((fp_ou = fopen(wdir, "wt")) == 0) { debuga(_("cannot open %s for writing\n"),wdir); perror("SARG:"); exit(EXIT_FAILURE); } time(&curtime); //strftime(wdir,sizeof(wdir),"%a %b %d %H:%M:%S %Z %Y",localtime(&curtime)); loctm=localtime(&curtime); strftime(wdir,sizeof(wdir),"%Y-%m-%d %H:%M:%S",loctm); if (fprintf(fp_ou,"%s %d\n",wdir,loctm->tm_isdst)<0) { debuga(_("Failed to write the date in %s\n"),wdir); perror("SARG:"); exit(EXIT_FAILURE); } if (fclose(fp_ou)==EOF) { debuga(_("Failed to write the date in %s\n"),wdir); perror("SARG:"); exit(EXIT_FAILURE); } copy_images(); return(0); }
/** * Main testing thread */ static void testing_thread (gpointer __data, gpointer __user_data) { wt_task_t *task = __data; char pchar[65536]; /* Directories for current testing stuff */ char cur_testing_dir[4096]; char cur_data_dir[4096]; char lock_file[4096]; int points = 0, rc; char errors[MAX_TESTS * (MAX_ERRCODE + 1)]; FILE *stream; assarr_t *all_params; /* Update status of the task */ TASK_SET_STATUS (*task, TS_RUNNING); INF_DEBUG_LOG ("Started new thread for testing task %ld\n", task->sid); all_params = assarr_create (); /* Calculating current testing and data directories */ snprintf (cur_testing_dir, BUF_SIZE (cur_testing_dir), "%s/%ld", testing_dir, task->sid); snprintf (cur_data_dir, BUF_SIZE (cur_data_dir), "%s/%s/%s", data_dir, problems_dir, (char*) TASK_INPUT_PARAM (*task, "PROBLEMID")); /* Delete all unwanted data */ unlinkdir (cur_testing_dir); /* Create global testing root. */ /* Deny reading of this root to deny getting listing of this catalogue */ /* to executable solutions. */ fmkdir (testing_dir, 00773); /* Create current testing directory */ mutex_lock (lck_mutex); snprintf (lock_file, BUF_SIZE (lock_file), "%s/lock", cur_testing_dir); fmkdir (cur_testing_dir, 00777); flock_set (lock_file); mutex_unlock (lck_mutex); /* Some initialization */ points = 0; strcpy (errors, ""); /* Start logging */ print_common_info (task); /* * TODO: Add TASK_SET_RESULT_MESSAGE() in case of testing crash */ INF_DEBUG_LOG ("Task %ld. Check for required parameters\n", task->sid); /* Check for required data */ if (!check_required_params (task, pchar)) { strcpy (errors, "CR"); TASK_LOG (*task, "\n========\n" "Fatal error: Required params aren't defined: %s! " "Testing aborted.\n", pchar); REPORT (all_params, "Required params aren't defined: %s.", pchar); goto __done_; } /**** * TESTING STUFF */ /* * Step 0: Saving solution source to file */ INF_DEBUG_LOG ("Task %ld. Step 0: Save solution\n", task->sid); if (!save_solution (task, cur_testing_dir)) { strcpy (errors, "CR"); TASK_LOG (*task, "\n========\nFatal error: unable to save solution! " "Testing aborted.\n"); REPORT (all_params, "Error saving solution."); goto __done_; } /* * Step 1: Compiling colution */ INF_DEBUG_LOG ("Task %ld. Step 1: Compile solution\n", task->sid); rc = compile_solution (task, cur_testing_dir, cur_data_dir, all_params); TESTING_CHECK_ACTIVE; if (rc < 0) { /* Fatal errors while compile */ INF_DEBUG_LOG ("[EE] Task %ld. Ctirical error during solution " "compilation process\n"); points = 0; strcpy (errors, "CR"); TASK_LOG (*task, "\n========\nFatal error while compiling solution. " "Testing aborted.\n"); goto __done_; } if (!rc) { /* Simple compilation error */ points = 0; strcpy (errors, "CE"); goto __done_; } /* * Step 2: Exec solution at all tests */ testing_main_loop (task, cur_data_dir, cur_testing_dir, &points, errors, all_params); TESTING_CHECK_ACTIVE; __done_: /* Updating avaliable parameters */ snprintf (pchar, BUF_SIZE (pchar), "%d", points); assarr_set_value (all_params, "POINTS", strdup (pchar)); assarr_set_value (all_params, "ERRORS", strdup (errors)); /* Set output parameters for WebInterface */ set_output_params (task, all_params); /* Some uinitialization */ assarr_destroy (all_params, assarr_deleter_free_ref_data); if (strcmp (errors, "OK")) { snprintf (pchar, BUF_SIZE (pchar), "Points: %d. Errors: %s", points, errors); } else { int bonus = atoi (TASK_INPUT_PARAM (*task, "BONUS")); snprintf (pchar, BUF_SIZE (pchar), "Points: %d. Bonus: %d", points - bonus, bonus); } TASK_SET_RESULT_MESSAGE (*task, pchar); if (strcmp (errors, "CE") && strcmp (errors, "CR")) { TASK_LOG (*task, "\n========\nTesting completed: %s\n", pchar); } /* Save log */ snprintf (pchar, BUF_SIZE (pchar), "%s/%s", cur_testing_dir, SOLUTION_ERRORS_LOG); stream = fopen (pchar, "w"); if (stream) { fprintf (stream, "%s", log_banner); TASK_LOG_FLUSH (*task, stream); fclose (stream); } chmod (pchar, 00660); INF_DEBUG_LOG ("Task %ld tested\n", task->sid); /* Now task is completely tested */ TASK_SET_STATUS (*task, TS_FINISHED); goto __all_done_; __free_: assarr_destroy (all_params, assarr_deleter_free_ref_data); TASK_SET_STATUS (*task, TS_INTERRUPTED); __all_done_: flock_clear (lock_file); unlink_unwanted_testing_dirs (); INF_DEBUG_LOG ("Leave testing thread\n"); }
/** * Unlink all unwanted testing dirs */ static void unlink_unwanted_testing_dirs (void) { static BOOL initialized = FALSE; static timeval_t last_unlink; timeval_t cur = now (); mutex_lock (unlink_mutex); INF_DEBUG_LOG ("Start unlinking unwanted dirs\n"); if (!initialized) { last_unlink = now (); initialized = TRUE; } if (CHECK_TIME_DELTA (last_unlink, cur, unlink_interval)) { char *cur_dir; char lock_file[4096], full[4096]; int to_delete = 0; dynastruc_t *ls; mutex_lock (lck_mutex); ls = dir_listing (testing_dir); mutex_unlock (lck_mutex); to_delete = dyna_length (ls) - keep_alive_testdirs; if (to_delete < 0) { to_delete = 0; } DYNA_FOREACH (ls, cur_dir); if (!to_delete) { DYNA_BREAK; } snprintf (full, BUF_SIZE (full), "%s/%s", testing_dir, cur_dir); snprintf (lock_file, BUF_SIZE (lock_file), "%s/lock", full); if (!flock_test (lock_file)) { INF_INFO ("Unlink testing dir %s\n", cur_dir); unlinkdir (full); } else { INF_DEBUG_LOG ("Skipping unlinking testing dir %s\n", cur_dir); } to_delete--; DYNA_DONE; dyna_destroy (ls, dyna_deleter_free_ref_data); last_unlink = cur; } mutex_unlock (unlink_mutex); INF_DEBUG_LOG ("Unwanted dirs have been just deleted\n"); }