static int sync_super_unlocked(void) { int fd; fd = vbfs_ctx.fd; if (vbfs_ctx.super.super_vbfs_dirty == SUPER_CLEAN) return 0; vbfs_superblock_disk->vbfs_super.bad_extend_current = cpu_to_le32(vbfs_ctx.super.bad_extend_current); vbfs_superblock_disk->vbfs_super.extend_bitmap_current = cpu_to_le32(vbfs_ctx.super.extend_bitmap_current); vbfs_superblock_disk->vbfs_super.inode_bitmap_current = cpu_to_le32(vbfs_ctx.super.inode_bitmap_current); vbfs_superblock_disk->vbfs_super.s_mount_time = cpu_to_le32(vbfs_ctx.super.s_mount_time); vbfs_superblock_disk->vbfs_super.s_state = cpu_to_le32(vbfs_ctx.super.s_state); /* bad extend array sync */ /* */ if (write_to_disk(fd, vbfs_superblock_disk, VBFS_SUPER_OFFSET, VBFS_SUPER_SIZE)) return -1; vbfs_ctx.super.super_vbfs_dirty = SUPER_CLEAN; return 0; }
static bool disk_ctrl_writeb(void *_disk_state, uint32_t addr, uint8_t val){ disk_state* disk_state = (struct disk_state*) _disk_state; uint32_t offset = addr - DISK_MEM_BASE; if(offset >= DISK_MEM_BORDER){ return false; } /* Adress is in range [0xD000; 0xD400] */ switch (offset) { case DISK_BNR: disk_state->bnr &= ~(0xFF << 24); disk_state->bnr |= val << 24; return true; case DISK_BNR_1: disk_state->bnr &= ~(0xFF << 16); disk_state->bnr |= val << 16; return true; case DISK_BNR_2: disk_state->bnr &= ~(0xFF << 8); disk_state->bnr |= val << 8; return true; case DISK_BNR_3: disk_state->bnr &= ~(0xFF << 0); disk_state->bnr |= val << 0; return true; case DISK_ERR_REG: disk_state->err_reg = val; return true; case DISK_READ_WRITE: disk_state->read_write = val; if(val == 0) { if(!read_from_disk(_disk_state)){ disk_state->err_reg = 1; return false; } return true; } else if(val == 1) { if(!write_to_disk(_disk_state)){ disk_state->err_reg = 1; return false; } return true; } else { return true; } default: /* Check if adress is in range [0xD200, 0xD400] */ if(offset < DISK_MEM_BUF){ return false; } offset = offset - DISK_MEM_BUF; disk_state->buffer[offset] = val; return true; } }
/* * Unpin the given files list in the file cache * @params file_cache type file_cache, list of files to be pinned and its count num_files * @return void */ void file_cache_unpin_files(file_cache *fct, const char **files, int num_files) { // for each file in files // if file exists in cache then // a) decrease pin count // b) write to disk if dirty and pin count is 0 // else undefined behaviour size_t idx; for (idx = 0; idx < num_files; idx++) { // lockdown to prevent duplicate removals pthread_mutex_lock(&(fct->mutex)); // check if file exists in cache file *loc = find_in_cache(fct, files[idx]); // file found and it has been pinned before if (NULL != loc && loc->pins > 0) { (loc->pins)--; if (true == loc->dirty && 0 == loc->pins) { write_to_disk(loc); loc->dirty = false; } if (0 == loc->pins) { // also decrement the actual cached files count since this is technically a clean entry which can be reused for caching other files fct->actual_size--; } } pthread_mutex_unlock(&(fct->mutex)); } }
/* * Pin given files of size num_files in the file_cache file_cache *fct * @params file_cache type file_cache, list of file names, number of files * @return void */ void file_cache_pin_files(file_cache *fct, const char **files, int num_files) { // for each file in files // if file exists in cache then increment pin count // else try to find a spot to fill the cache entry with file size_t idx; for (idx = 0; idx < num_files; idx++) { // check if file exists in cache, lock down to prevent duplicate additions pthread_mutex_lock(&(fct->mutex)); file *loc = find_in_cache(fct, files[idx]); // if file already present, then inc #pins if (NULL != loc) { (loc->pins)++; pthread_mutex_unlock(&(fct->mutex)); continue; } // else find a spot to fit the file int spot = findspot_in_cache(fct); // no spot found so continue to see if any other files have existing // pins that can be increased, else dont do anything if (spot == -1) { pthread_mutex_unlock(&(fct->mutex)); continue; } // previously something exists, need to write to disk if dirty and clear if (NULL != fct->file_struct[spot]) { if (true == fct->file_struct[spot]->dirty) { write_to_disk(fct->file_struct[spot]); } // clean the entry in cache free(fct->file_struct[idx]->content); fct->file_struct[idx]->content = NULL; // decrement actual cache size fct->actual_size--; // free that entry free(fct->file_struct[idx]); fct->file_struct[idx] = NULL; } // Yep! this can be improved by simply overwriting the old memory // allocate space fct->file_struct[idx] = malloc(sizeof(file)); // initialize name, pins, dirty flag and read contents fct->file_struct[idx]->file_name = files[idx]; fct->file_struct[idx]->pins = 1; fct->file_struct[idx]->dirty = false; // read contents read_from_disk(fct->file_struct[idx]); // increment cache size fct->actual_size++; pthread_mutex_unlock(&(fct->mutex)); } }
Address Pager::evict(Page * p) { //remove form list p->next->prev = p->prev; p->prev->next = p->next; Address res = p->address; write_to_disk(p); return res; }
static int write_extend(__u32 extend_no, void *buf) { size_t len = vbfs_params.extend_size_kb * 1024; int fd = vbfs_params.fd; off64_t offset = (__u64)extend_no * len; if (write_to_disk(fd, buf, offset, len)) { return -1; } return 0; }
int put(const keyType* key, const valType* val, lsm* tree){ int r = 0; if(tree->next_empty == tree->block_size){ // buffer is full and must be written to disk r = write_to_disk(tree); } node n; n.key = *key; n.val = *val; tree->block[tree->next_empty] = n; tree->next_empty += 1; return r; }
int write_extend(uint32_t extend_no, void *buf) { size_t len = get_extend_size(); int fd = get_disk_fd(); off64_t offset = (uint64_t)extend_no * len; //log_dbg("%u", extend_no); if (write_to_disk(fd, buf, offset, len)) return -1; return 0; }
void *disk_thread_procedure(void *PTR) { struct recorder *d = (struct recorder *) PTR; while(!observe_end_of_process()) { /* Wait for data at the ring buffer. */ int nbytes = d->minimal_frames * sizeof(float) * d->channels; nbytes = jack_ringbuffer_wait_for_read(d->ring_buffer, nbytes, d->pipe[0]); /* Drop excessive data to not overflow the local buffer. */ if(nbytes > d->buffer_bytes) { eprintf("ambix-jrecord: impossible condition, read space (%d > %d).\n", nbytes, d->buffer_bytes); nbytes = d->buffer_bytes; } /* Read data from the ring buffer. */ jack_ringbuffer_read(d->ring_buffer, (char *) d->d_buffer, nbytes); /* Do write operation. The sample count *must* be an integral number of frames. */ int nframes = (nbytes / sizeof(float))/ d->channels; interleave_split(d->d_buffer, d->channels, d->a_channels, d->a_buffer, d->e_buffer, nframes); write_to_disk(d, nframes); /* Handle timer */ d->timer_counter += nframes; if(d->timer_frames > 0 && d->timer_counter >= d->timer_frames) { return NULL; } } return NULL; }
int main(void) { int option, i = 0; FILE *fp1; point *start =NULL; // root node do // do while loop { //Display user menu printf("\n\n0 - quit\n"); printf("1 - ADD A Record\n"); printf("2 - Remove A Record\n"); printf("3 - Display All Records\n"); printf("4 - Save\n"); printf("5 - Load Saved Data\n"); printf("Enter Option: "); fflush(stdout); scanf("%2d", &option); getchar(); //Process option switch (option) // switch statement to decide next action { case 1: start = add_point(start); break; case 2: display_all(start); start = remove_point(start); break; case 3: display_all(start); break; case 4: write_to_disk(fp1, start); break; case 5: start = NULL; start = read_from_disk(fp1,start); printf("\nSAVED DATA:\n"); break; } }while (option != 0); return 0; }
/* * Destroy the file cache. Free file contents, file_structure and the file_cache itself * @params file_cache type structure * @return void */ void file_cache_destroy(file_cache *fct) { // make sure no other thread is in between doing something else pthread_mutex_lock(&(fct->mutex)); size_t i; // for every file in cache, if it is dirty, write contents to disk for (i = 0; i < fct->max_size; i++) { if (NULL != fct->file_struct[i] && true == fct->file_struct[i]->dirty) { write_to_disk(fct->file_struct[i]); fct->file_struct[i]->dirty = false; } // if content is not NULL then free if (NULL != fct->file_struct[i] && NULL != fct->file_struct[i]->content) { free(fct->file_struct[i]->content); } // free file_struct free(fct->file_struct[i]); } fct->max_size = 0; // unlock mutex and free file_cache pthread_mutex_unlock(&(fct->mutex)); free(fct); fct = NULL; }
int store_data(char *line) { float rain,temp1,temp2; int rtn,j,ptr,i,k,ws; char *cptr,num[10]; time_t tt,tloc; if (!Daemon) printf ("%s",line); find_minute(); //if (!Daemon) printf("Min_today = %d \n",Min_today); cptr = strstr(line,"Wind Speed"); if (cptr !=NULL) { for(i=0;i<LINE_SZ;i++) { if (line[i] == '=') { ptr = i+1; break; } } j=0; k=ptr; for (i=ptr;i<(LINE_SZ - ptr);i++) { if (line[i] == ' ') { break; } else { num[j] = line[i]; j++; } } num[j+1] = 0; sscanf(num,"%d",&ws); ws = ws; //if (!Daemon) printf("Wind Speed parsed is %s\t%d\n",num,ws); Wind_speed[Min_today] = ws; } cptr = strstr(line,"Rain"); if (cptr !=NULL) { for(i=0;i<LINE_SZ;i++) { if (line[i] == '=') { ptr = i+1; break; } } j=0; k=ptr; for (i=ptr;i<(LINE_SZ - ptr);i++) { if (line[i] == ' ') { break; } else { num[j] = line[i]; j++; } } num[j+1] = 0; sscanf(num,"%f",&rain); //if (!Daemon) printf("Rain parsed is %s\t%f\n",num,rain); Rain[Min_today] = rain; } cptr = strstr(line,"Temp #01"); if (cptr !=NULL) { if (!Daemon) printf("Parsing Temp #01 line.....\n"); for(i=0;i<LINE_SZ;i++) { if (line[i] == '=') { ptr = i+1; break; } } j=0; k=ptr; for (i=ptr;i<(LINE_SZ - ptr);i++) { if (line[i] == 'F' || line[i] == 'C') { break; } else { num[j] = line[i]; j++; } } num[j+1] = 0; sscanf(num,"%f",&temp1); if (!Daemon) printf("temp1 parsed is %s\t%f\n",num,temp1); Temp1[Min_today] = temp1; if (Oww_temp_1_dev != -1) { if (!Daemon) { printf ("Writing to dev %d-%s temp %3.2f\n",Oww_temp_1_dev,T->device[Oww_temp_1_dev].name,temp1); } T->device[Oww_temp_1_dev].f_state = temp1; tt = time(&tloc); T->device[Oww_temp_1_dev].change_time = tt; } else { printf("***Unable to find Oww_temp_1_dev****\n"); } } cptr = strstr(line,"Temp #02"); if (cptr !=NULL) { for(i=0;i<LINE_SZ;i++) { if (line[i] == '=') { ptr = i+1; break; } } j=0; k=ptr; for (i=ptr;i<(LINE_SZ - ptr);i++) { if (line[i] == 'F' || line[i] == 'C') { break; } else { num[j] = line[i]; j++; } } num[j+1] = 0; sscanf(num,"%f",&temp2); //if (!Daemon) printf("temp2 parsed is %s\t%f\n",num,temp2); Temp2[Min_today] = temp2; if (Oww_temp_2_dev != -1) { if (!Daemon) { printf ("Writing to dev %d-%s temp %3.2f\n",Oww_temp_2_dev,T->device[Oww_temp_2_dev].name,temp2); } T->device[Oww_temp_2_dev].f_state = temp2; tt = time(&tloc); T->device[Oww_temp_2_dev].change_time = tt; } else { printf("***Unable to find Oww_temp_2_dev****\n"); } if (Disk_save) { write_to_disk(); Disk_save = 0; } } }
int as_copy(struct addrspace *old, struct addrspace **ret) { struct addrspace *newas; newas = as_create(); if (newas==NULL) { return ENOMEM; } // kprintf(" **** inside as copy **** \n"); // spinlock_acquire(newas->as_splock); // spinlock_acquire(old->as_splock); if(use_small_lock == true && swapping_started == true) { lock_acquire(newas->as_lock); lock_acquire(old->as_lock); } else if(use_big_lock == true && swapping_started == true) lock_acquire(as_lock); struct as_region* r_old = old->as_region_list; while(r_old != NULL) { struct as_region* r_new = (struct as_region*)kmalloc(sizeof(struct as_region)); if(r_new == NULL) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } //spinlock_release(old->as_splock); //spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } r_new->region_base = r_old->region_base; r_new->region_npages = r_old->region_npages; r_new->can_read = r_old->can_read; r_new->can_write = r_old->can_write; r_new->can_execute = r_old->can_execute; int ret = region_list_add_node(&newas->as_region_list,r_new); if(ret == -1) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } r_old = r_old->next; } struct page_table_entry* p_old = old->as_page_list; while(p_old != NULL) { struct page_table_entry* p_new = (struct page_table_entry*)kmalloc(sizeof(struct page_table_entry)); if(p_new == NULL) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } p_new->vaddr = p_old->vaddr; p_new->swap_pos = -1; KASSERT(p_old->page_state != SWAPPING); while(p_old->page_state == SWAPPING) { thread_yield(); } // if(!spinlock_do_i_hold) // KASSERT(p_old->page_state != SWAPPING); if(p_old->page_state == MAPPED) { if(use_page_lock == true && swapping_started == true) lock_acquire(coremap[(p_old->paddr)/PAGE_SIZE].page_lock); if(p_old->page_state == MAPPED) { paddr_t paddr = get_user_page(p_old->vaddr, false, newas); KASSERT(p_old->page_state == MAPPED); // int spl = splhigh(); if(use_small_lock == true && swapping_started == true) { if(lock_do_i_hold(newas->as_lock) == false) lock_acquire(newas->as_lock); if(lock_do_i_hold(old->as_lock) == false) lock_acquire(newas->as_lock); } else if(use_big_lock == true && swapping_started == true) { if(lock_do_i_hold(as_lock) == false) lock_acquire(as_lock); } if(paddr == 0) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } uint32_t old_index = p_old->paddr/PAGE_SIZE; KASSERT(coremap[old_index].is_victim == false); KASSERT(coremap[paddr/PAGE_SIZE].is_victim == false); memmove((void*)PADDR_TO_KVADDR(paddr), (const void *)PADDR_TO_KVADDR(p_old->paddr), //use this? or PADDR_TO_KVADDR like dumbvm does?. But why does dumbvm do that in the first place. PAGE_SIZE); // i know why, cannot call functions on user memory addresses. So convert it into a kv address. // the function will translate it into a physical address again and free it. ugly Hack. but no other way. p_new->paddr = paddr; p_new->page_state = MAPPED; // splx(spl); int ret = page_list_add_node(&newas->as_page_list,p_new); if(ret == -1) { if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); as_destroy(newas); return ENOMEM; } if(use_page_lock == true && swapping_started == true) { if(lock_do_i_hold(coremap[paddr/PAGE_SIZE].page_lock) == true) lock_release(coremap[paddr/PAGE_SIZE].page_lock); if(lock_do_i_hold(coremap[(p_old->paddr/PAGE_SIZE)].page_lock) == true) lock_release(coremap[(p_old->paddr/PAGE_SIZE)].page_lock); } } } if(p_old->page_state == SWAPPED) { // this page is in disk, so we need to create a copy of that page somewhere in disk and then update the page table entry of the new process. // going with the disk->memory->disk approach suggested in a recitation video by jinghao shi. // Allocate a buffer at vm_bootstrap of size 4k (1 page). Use this buffer to temporarily copy data from disk to here and then to disk again // then clear the buffer. This buffer is a shared resource, so we need a lock around it. // kprintf("in as_copy swap code \n"); // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); swap_in(p_old->vaddr,old,copy_buffer_vaddr, p_old->swap_pos); // kprintf("completed swap in \n"); int pos = mark_swap_pos(p_new->vaddr, newas); KASSERT(pos != -1); int err = write_to_disk(KVADDR_TO_PADDR(copy_buffer_vaddr)/PAGE_SIZE, pos); // kprintf("completed writing to disk \n"); KASSERT(err == 0); // spinlock_acquire(newas->as_splock); // spinlock_acquire(old->as_splock); // as_zero_region(KVADDR_TO_PADDR(copy_buffer_vaddr),1); p_new->page_state = SWAPPED; p_new->swap_pos = pos; p_new->paddr = 0; if(use_page_lock == true && swapping_started == true) { if(lock_do_i_hold(coremap[(p_old->paddr/PAGE_SIZE)].page_lock) == true) lock_release(coremap[(p_old->paddr/PAGE_SIZE)].page_lock); } } p_old = p_old->next; } newas->as_heap_start = old->as_heap_start; newas->as_heap_end = old->as_heap_end; *ret = newas; if(use_big_lock == true && swapping_started == true) lock_release(as_lock); else if(use_small_lock == true && swapping_started == true) { lock_release(old->as_lock); lock_release(newas->as_lock); } // kprintf("exiting as copy \n"); // spinlock_release(old->as_splock); // spinlock_release(newas->as_splock); return 0; }
~parameter_cache() { #ifdef BOOST_COMPUTE_USE_OFFLINE_CACHE write_to_disk(); #endif // BOOST_COMPUTE_USE_OFFLINE_CACHE }
int main(int argc, char *argv[]) { int fd, status; pid_t pid; char klikdir[PATH_MAX]; snprintf(klikdir,PATH_MAX,"/tmp/.klik_%ld",(long int)getpid()); if (mkdir(klikdir,0700)<0) { perror("mkdir"); exit(EXIT_FAILURE); } if (chdir(klikdir)<0) { perror("chdir"); exit(EXIT_FAILURE); } if (write_to_disk(RUNTIME_TGZ,(void *)_binary_runtime_tgz_start,(size_t)_binary_runtime_tgz_size)<0) exit(EXIT_FAILURE); if (write_to_disk(IMAGE_TGZ,(void *)_binary_image_tgz_start,(size_t)_binary_image_tgz_size)<0) exit(EXIT_FAILURE); if ((pid=fork())<0) { perror("fork"); exit(EXIT_FAILURE); } if (pid==0) { /* child #1 */ if ((pid=fork())<0) { perror("fork"); exit(EXIT_FAILURE); } if (pid==0) { /* child #2 - unpack image archive */ char *newargv[]={"tar","zxf",IMAGE_TGZ,NULL}; execv(TARCMD,newargv); } else { /* continue child #1 - unpack runtime archive */ char *newargv[]={"tar","zxf",RUNTIME_TGZ,NULL}; if (wait(&status)<0) { perror("wait"); exit(EXIT_FAILURE); } if (!WIFEXITED(status)) { fprintf(stderr,"child error\n"); exit(EXIT_FAILURE); } execv(TARCMD,newargv); } /* never reach here */ perror("execv"); exit(EXIT_FAILURE); } /* parent - wait child #1 and launch umview*/ char *newargv[]={"umview","-q","-p","umfuse","/bin/sh","-c",MOUNT_CMD,NULL}; setenv("LD_LIBRARY_PATH",klikdir,1); if (wait(&status)<0) { perror("wait"); exit(EXIT_FAILURE); } if (!WIFEXITED(status)) { fprintf(stderr,"child error\n"); exit(EXIT_FAILURE); } if (unlink(RUNTIME_TGZ)<0) { perror("unlink"); exit(EXIT_FAILURE); } if (unlink(IMAGE_TGZ)<0) { perror("unlink"); exit(EXIT_FAILURE); } execv(UMVIEW,newargv); /* never reach here */ perror("execv"); exit(EXIT_FAILURE); }
int create_volume(struct tcplay_opts *opts) { char *pass, *pass_again; char *h_pass = NULL; char buf[1024]; disksz_t blocks, hidden_blocks = 0; size_t blksz; struct tchdr_enc *ehdr, *hehdr; struct tchdr_enc *ehdr_backup, *hehdr_backup; uint64_t tmp; int error, r, ret; pass = h_pass = pass_again = NULL; ehdr = hehdr = NULL; ehdr_backup = hehdr_backup = NULL; ret = -1; /* Default to returning error */ if (opts->cipher_chain == NULL) opts->cipher_chain = tc_cipher_chains[0]; if (opts->prf_algo == NULL) opts->prf_algo = &pbkdf_prf_algos[0]; if (opts->h_cipher_chain == NULL) opts->h_cipher_chain = opts->cipher_chain; if (opts->h_prf_algo == NULL) opts->h_prf_algo = opts->prf_algo; if ((error = get_disk_info(opts->dev, &blocks, &blksz)) != 0) { tc_log(1, "could not get disk info\n"); return -1; } if ((blocks*blksz) <= MIN_VOL_BYTES) { tc_log(1, "Cannot create volumes on devices with less " "than %d bytes\n", MIN_VOL_BYTES); return -1; } if (opts->interactive) { if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) || ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) { tc_log(1, "could not allocate safe passphrase memory\n"); goto out; } if ((error = read_passphrase("Passphrase: ", pass, MAX_PASSSZ, PASS_BUFSZ, 0) || (read_passphrase("Repeat passphrase: ", pass_again, MAX_PASSSZ, PASS_BUFSZ, 0)))) { tc_log(1, "could not read passphrase\n"); goto out; } if (strcmp(pass, pass_again) != 0) { tc_log(1, "Passphrases don't match\n"); goto out; } free_safe_mem(pass_again); pass_again = NULL; } else { /* In batch mode, use provided passphrase */ if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) { tc_log(1, "could not allocate safe " "passphrase memory"); goto out; } if (opts->passphrase != NULL) { strncpy(pass, opts->passphrase, MAX_PASSSZ); pass[MAX_PASSSZ] = '\0'; } } if (opts->nkeyfiles > 0) { /* Apply keyfiles to 'pass' */ if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ, opts->keyfiles, opts->nkeyfiles))) { tc_log(1, "could not apply keyfiles\n"); goto out; } } if (opts->hidden) { if (opts->interactive) { if (((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) || ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) { tc_log(1, "could not allocate safe " "passphrase memory\n"); goto out; } if ((error = read_passphrase("Passphrase for hidden volume: ", h_pass, MAX_PASSSZ, PASS_BUFSZ, 0) || (read_passphrase("Repeat passphrase: ", pass_again, MAX_PASSSZ, PASS_BUFSZ, 0)))) { tc_log(1, "could not read passphrase\n"); goto out; } if (strcmp(h_pass, pass_again) != 0) { tc_log(1, "Passphrases for hidden volume don't " "match\n"); goto out; } free_safe_mem(pass_again); pass_again = NULL; } else { /* In batch mode, use provided passphrase */ if ((h_pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) { tc_log(1, "could not allocate safe " "passphrase memory"); goto out; } if (opts->h_passphrase != NULL) { strncpy(h_pass, opts->h_passphrase, MAX_PASSSZ); h_pass[MAX_PASSSZ] = '\0'; } } if (opts->n_hkeyfiles > 0) { /* Apply keyfiles to 'h_pass' */ if ((error = apply_keyfiles((unsigned char *)h_pass, PASS_BUFSZ, opts->h_keyfiles, opts->n_hkeyfiles))) { tc_log(1, "could not apply keyfiles\n"); goto out; } } if (opts->interactive) { hidden_blocks = 0; } else { hidden_blocks = opts->hidden_size_bytes/blksz; if (hidden_blocks == 0) { tc_log(1, "hidden_blocks to create volume " "cannot be zero!\n"); goto out; } if (opts->hidden_size_bytes >= (blocks*blksz) - MIN_VOL_BYTES) { tc_log(1, "Hidden volume needs to be " "smaller than the outer volume\n"); goto out; } } /* This only happens in interactive mode */ while (hidden_blocks == 0) { if ((r = _humanize_number(buf, sizeof(buf), (uint64_t)(blocks * blksz))) < 0) { sprintf(buf, "%"DISKSZ_FMT" bytes", (blocks * blksz)); } printf("The total volume size of %s is %s (bytes)\n", opts->dev, buf); memset(buf, 0, sizeof(buf)); printf("Size of hidden volume (e.g. 127M): "); fflush(stdout); if ((fgets(buf, sizeof(buf), stdin)) == NULL) { tc_log(1, "Could not read from stdin\n"); goto out; } /* get rid of trailing newline */ buf[strlen(buf)-1] = '\0'; if ((error = _dehumanize_number(buf, &tmp)) != 0) { tc_log(1, "Could not interpret input: %s\n", buf); continue; } if (tmp >= (blocks*blksz) - MIN_VOL_BYTES) { tc_log(1, "Hidden volume needs to be " "smaller than the outer volume\n"); hidden_blocks = 0; continue; } hidden_blocks = (size_t)tmp; hidden_blocks /= blksz; } } if (opts->interactive) { /* Show summary and ask for confirmation */ printf("Summary of actions:\n"); if (opts->secure_erase) printf(" - Completely erase *EVERYTHING* on %s\n", opts->dev); printf(" - Create %svolume on %s\n", opts->hidden?("outer "):"", opts->dev); if (opts->hidden) { printf(" - Create hidden volume of %"DISKSZ_FMT" bytes at end of " "outer volume\n", hidden_blocks * blksz); } printf("\n Are you sure you want to proceed? (y/n) "); fflush(stdout); if ((fgets(buf, sizeof(buf), stdin)) == NULL) { tc_log(1, "Could not read from stdin\n"); goto out; } if ((buf[0] != 'y') && (buf[0] != 'Y')) { tc_log(1, "User cancelled action(s)\n"); goto out; } } /* erase volume */ if (opts->secure_erase) { tc_log(0, "Securely erasing the volume...\nThis process may take " "some time depending on the size of the volume\n"); if (opts->state_change_fn) opts->state_change_fn(opts->api_ctx, "secure_erase", 1); if ((error = secure_erase(opts->dev, blocks * blksz, blksz)) != 0) { tc_log(1, "could not securely erase device %s\n", opts->dev); goto out; } if (opts->state_change_fn) opts->state_change_fn(opts->api_ctx, "secure_erase", 0); } tc_log(0, "Creating volume headers...\nDepending on your system, this " "process may take a few minutes as it uses true random data which " "might take a while to refill\n"); if (opts->weak_keys_and_salt) { tc_log(0, "WARNING: Using a weak random generator to get " "entropy for the key material. Odds are this is NOT " "what you want.\n"); } if (opts->state_change_fn) opts->state_change_fn(opts->api_ctx, "create_header", 1); /* create encrypted headers */ ehdr = create_hdr((unsigned char *)pass, (opts->nkeyfiles > 0)?MAX_PASSSZ:strlen(pass), opts->prf_algo, opts->cipher_chain, blksz, blocks, VOL_RSVD_BYTES_START/blksz, blocks - (MIN_VOL_BYTES/blksz), 0, opts->weak_keys_and_salt, &ehdr_backup); if (ehdr == NULL) { tc_log(1, "Could not create header\n"); goto out; } if (opts->hidden) { hehdr = create_hdr((unsigned char *)h_pass, (opts->n_hkeyfiles > 0)?MAX_PASSSZ:strlen(h_pass), opts->h_prf_algo, opts->h_cipher_chain, blksz, blocks, blocks - (VOL_RSVD_BYTES_END/blksz) - hidden_blocks, hidden_blocks, 1, opts->weak_keys_and_salt, &hehdr_backup); if (hehdr == NULL) { tc_log(1, "Could not create hidden volume header\n"); goto out; } } if (opts->state_change_fn) opts->state_change_fn(opts->api_ctx, "create_header", 0); tc_log(0, "Writing volume headers to disk...\n"); if ((error = write_to_disk(opts->dev, 0, blksz, ehdr, sizeof(*ehdr))) != 0) { tc_log(1, "Could not write volume header to device\n"); goto out; } /* Write backup header; it's offset is relative to the end */ if ((error = write_to_disk(opts->dev, (blocks*blksz - BACKUP_HDR_OFFSET_END), blksz, ehdr_backup, sizeof(*ehdr_backup))) != 0) { tc_log(1, "Could not write backup volume header to device\n"); goto out; } if (opts->hidden) { if ((error = write_to_disk(opts->dev, HDR_OFFSET_HIDDEN, blksz, hehdr, sizeof(*hehdr))) != 0) { tc_log(1, "Could not write hidden volume header to " "device\n"); goto out; } /* Write backup hidden header; offset is relative to end */ if ((error = write_to_disk(opts->dev, (blocks*blksz - BACKUP_HDR_HIDDEN_OFFSET_END), blksz, hehdr_backup, sizeof(*hehdr_backup))) != 0) { tc_log(1, "Could not write backup hidden volume " "header to device\n"); goto out; } } /* Everything went ok */ tc_log(0, "All done!\n"); ret = 0; out: if (pass) free_safe_mem(pass); if (h_pass) free_safe_mem(h_pass); if (pass_again) free_safe_mem(pass_again); if (ehdr) free_safe_mem(ehdr); if (hehdr) free_safe_mem(hehdr); if (ehdr_backup) free_safe_mem(ehdr_backup); if (hehdr_backup) free_safe_mem(hehdr_backup); return ret; }
int modify_volume(struct tcplay_opts *opts) { struct tcplay_info *info; struct tchdr_enc *ehdr, *ehdr_backup; const char *new_passphrase = opts->new_passphrase; const char **new_keyfiles = opts->new_keyfiles; struct pbkdf_prf_algo *new_prf_algo = opts->new_prf_algo; int n_newkeyfiles = opts->n_newkeyfiles; char *pass, *pass_again; int ret = -1; off_t offset, offset_backup = 0; const char *dev; size_t blksz; disksz_t blocks; int error; ehdr = ehdr_backup = NULL; pass = pass_again = NULL; info = NULL; if (TC_FLAG_SET(opts->flags, ONLY_RESTORE)) { if (opts->interactive) { if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) { tc_log(1, "could not allocate safe " "passphrase memory"); goto out; } } else { new_passphrase = opts->passphrase; } new_keyfiles = opts->keyfiles; n_newkeyfiles = opts->nkeyfiles; new_prf_algo = NULL; } info = info_map_common(opts, pass); if (info == NULL) goto out; if (opts->interactive && !TC_FLAG_SET(opts->flags, ONLY_RESTORE)) { if (((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) || ((pass_again = alloc_safe_mem(PASS_BUFSZ)) == NULL)) { tc_log(1, "could not allocate safe passphrase memory\n"); goto out; } if ((error = read_passphrase("New passphrase: ", pass, MAX_PASSSZ, PASS_BUFSZ, 0) || (read_passphrase("Repeat passphrase: ", pass_again, MAX_PASSSZ, PASS_BUFSZ, 0)))) { tc_log(1, "could not read passphrase\n"); goto out; } if (strcmp(pass, pass_again) != 0) { tc_log(1, "Passphrases don't match\n"); goto out; } free_safe_mem(pass_again); pass_again = NULL; } else if (!opts->interactive) { /* In batch mode, use provided passphrase */ if ((pass = alloc_safe_mem(PASS_BUFSZ)) == NULL) { tc_log(1, "could not allocate safe " "passphrase memory"); goto out; } if (new_passphrase != NULL) { strncpy(pass, new_passphrase, MAX_PASSSZ); pass[MAX_PASSSZ] = '\0'; } } if (n_newkeyfiles > 0) { /* Apply keyfiles to 'pass' */ if ((error = apply_keyfiles((unsigned char *)pass, PASS_BUFSZ, new_keyfiles, n_newkeyfiles))) { tc_log(1, "could not apply keyfiles\n"); goto out; } } ehdr = copy_reencrypt_hdr((unsigned char *)pass, (opts->n_newkeyfiles > 0)?MAX_PASSSZ:strlen(pass), new_prf_algo, opts->weak_keys_and_salt, info, &ehdr_backup); if (ehdr == NULL) { tc_log(1, "Could not create header\n"); goto out; } dev = (TC_FLAG_SET(opts->flags, SYS)) ? opts->sys_dev : opts->dev; if (TC_FLAG_SET(opts->flags, SYS) || TC_FLAG_SET(opts->flags, FDE)) { /* SYS and FDE don't have backup headers (as far as I understand) */ if (info->hidden) { offset = HDR_OFFSET_HIDDEN; } else { offset = HDR_OFFSET_SYS; } } else { if (info->hidden) { offset = HDR_OFFSET_HIDDEN; offset_backup = -BACKUP_HDR_HIDDEN_OFFSET_END; } else { offset = 0; offset_backup = -BACKUP_HDR_OFFSET_END; } } if ((error = get_disk_info(dev, &blocks, &blksz)) != 0) { tc_log(1, "could not get disk information\n"); goto out; } tc_log(0, "Writing new volume headers to disk/file...\n"); if (TC_FLAG_SET(opts->flags, SAVE_TO_FILE)) { if ((error = write_to_file(opts->hdr_file_out, ehdr, sizeof(*ehdr))) != 0) { tc_log(1, "Could not write volume header to file\n"); goto out; } } else { if ((error = write_to_disk(dev, offset, blksz, ehdr, sizeof(*ehdr))) != 0) { tc_log(1, "Could not write volume header to device\n"); goto out; } if (!TC_FLAG_SET(opts->flags, SYS) && !TC_FLAG_SET(opts->flags, FDE)) { if ((error = write_to_disk(dev, offset_backup, blksz, ehdr_backup, sizeof(*ehdr_backup))) != 0) { tc_log(1, "Could not write backup volume header to device\n"); goto out; } } } /* Everything went ok */ tc_log(0, "All done!\n"); ret = 0; out: if (pass) free_safe_mem(pass); if (pass_again) free_safe_mem(pass_again); if (ehdr) free_safe_mem(ehdr); if (ehdr_backup) free_safe_mem(ehdr_backup); if (info) free_safe_mem(info); return ret; }
/******************************************************************************** *Function: search_chunk *Description: Analyze the given chunk by running each defined search spec on it *Return: TRUE/FALSE **********************************************************************************/ int search_chunk(f_state *s, unsigned char *buf, f_info *i, u_int64_t chunk_size, u_int64_t f_offset) { u_int64_t c_offset = 0; //u_int64_t foundat_off = 0; //u_int64_t buf_off = 0; unsigned char *foundat = buf; unsigned char *current_pos = NULL; unsigned char *header_pos = NULL; unsigned char *newbuf = NULL; unsigned char *ind_ptr = NULL; u_int64_t current_buflen = chunk_size; int tryBS[3] = { 4096, 1024, 512 }; unsigned char *extractbuf = NULL; u_int64_t file_size = 0; s_spec *needle = NULL; int j = 0; int bs = 0; int rem = 0; int x = 0; int found_ind = FALSE; off_t saveme; //char comment[32]; for (j = 0; j < s->num_builtin; j++) { needle = &search_spec[j]; foundat = buf; /*reset the buffer for the next search spec*/ #ifdef DEBUG printf(" SEARCHING FOR %s's\n", needle->suffix); #endif bs = 0; current_buflen = chunk_size; while (foundat) { needle->written = FALSE; found_ind = FALSE; memset(needle->comment, 0, COMMENT_LENGTH - 1); if (chunk_size <= (foundat - buf)) { #ifdef DEBUG printf("avoided seg fault in search_chunk()\n"); #endif foundat = NULL; break; } current_buflen = chunk_size - (foundat - buf); //if((foundat-buf)< 1 ) break; #ifdef DEBUG //foundat_off=foundat; //buf_off=buf; //printf("current buf:=%llu (foundat-buf)=%llu \n", current_buflen, (u_int64_t) (foundat_off - buf_off)); #endif if (signal_caught == SIGTERM || signal_caught == SIGINT) { user_interrupt(s, i); printf("Cleaning up.\n"); signal_caught = 0; } if (get_mode(s, mode_quick)) /*RUN QUICK SEARCH*/ { #ifdef DEBUG //printf("quick mode is on\n"); #endif /*Check if we are not on a block head, adjust if so*/ rem = (foundat - buf) % s->block_size; if (rem != 0) { foundat += (s->block_size - rem); } if (memwildcardcmp(needle->header, foundat, needle->header_len, needle->case_sen ) != 0) { /*No match, jump to the next block*/ if (current_buflen > s->block_size) { foundat += s->block_size; continue; } else /*We are out of buffer lets go to the next search spec*/ { foundat = NULL; break; } } header_pos = foundat; } else /**********RUN STANDARD SEARCH********************/ { foundat = bm_search(needle->header, needle->header_len, foundat, current_buflen, //How much to search through needle->header_bm_table, needle->case_sen, //casesensative SEARCHTYPE_FORWARD); header_pos = foundat; } if (foundat != NULL && foundat >= 0) /*We got something, run the appropriate heuristic to find the EOF*/ { current_buflen = chunk_size - (foundat - buf); if (get_mode(s, mode_ind_blk)) { #ifdef DEBUG printf("ind blk detection on\n"); #endif //dumpInd(foundat+12*1024,1024); for (x = 0; x < 3; x++) { bs = tryBS[x]; if (ind_block(foundat, current_buflen, bs)) { if (get_mode(s, mode_verbose)) { sprintf(needle->comment, " (IND BLK bs:=%d)", bs); } //dumpInd(foundat+12*bs,bs); #ifdef DEBUG printf("performing mem move\n"); #endif if(current_buflen > 13 * bs)//Make sure we have enough buffer { if (!memmove(foundat + 12 * bs, foundat + 13 * bs, current_buflen - 13 * bs)) break; found_ind = TRUE; #ifdef DEBUG printf("performing mem move complete\n"); #endif ind_ptr = foundat + 12 * bs; current_buflen -= bs; chunk_size -= bs; break; } } } } c_offset = (foundat - buf); current_pos = foundat; /*Now lets analyze the file and see if we can determine its size*/ // printf("c_offset=%llu %x %x %llx\n", c_offset,foundat,buf,c_offset); foundat = extract_file(s, c_offset, foundat, current_buflen, needle, f_offset); #ifdef DEBUG if (foundat == NULL) { printf("Foundat == NULL!!!\n"); } #endif if (get_mode(s, mode_write_all)) { if (needle->written == FALSE) { /*write every header we find*/ if (current_buflen >= needle->max_len) { file_size = needle->max_len; } else { file_size = current_buflen; } sprintf(needle->comment, " (Header dump)"); extractbuf = (unsigned char *)malloc(file_size * sizeof(char)); memcpy(extractbuf, header_pos, file_size); write_to_disk(s, needle, file_size, extractbuf, c_offset + f_offset); free(extractbuf); } } else if (!foundat) /*Should we search further?*/ { /*We couldn't determine where the file ends, now lets check to see * if we should try again */ if (current_buflen < needle->max_len) /*We need to bridge the gap*/ { #ifdef DEBUG printf(" Bridge the gap\n"); #endif saveme = ftello(i->handle); /*grow the buffer and try to extract again*/ newbuf = read_from_disk(c_offset + f_offset, i, needle->max_len); if (newbuf == NULL) break; current_pos = extract_file(s, c_offset, newbuf, needle->max_len, needle, f_offset); /*Lets put the fp back*/ fseeko(i->handle, saveme, SEEK_SET); free(newbuf); } else { foundat = header_pos; /*reset the foundat pointer to the location of the last header*/ foundat += needle->header_len + 1; /*jump past the header*/ } } } if (found_ind) { /*Put the ind blk back in, re-arrange the buffer so that the future blks names come out correct*/ #ifdef DEBUG printf("Replacing the ind block\n"); #endif /*This is slow, should we do this??????*/ if (!memmove(ind_ptr + 1 * bs, ind_ptr, current_buflen - 13 * bs)) break; memset(ind_ptr, 0, bs - 1); chunk_size += bs; memset(needle->comment, 0, COMMENT_LENGTH - 1); } } //end while } return TRUE; }