void do_symlink(const u8 * base, u32 offset, u32 size, const char *path, const char *name, int mode) { // Allocate the uncompressed string u8 link_contents[size + 1]; // do uncompression uncompress_data(base, base + offset, size, link_contents); link_contents[size] = 0; printsize(size, compressed_size(base, base + offset, size)); printf("%s -> %s", name, link_contents); // Check if we are actually unpacking if (path[0] == '-') { return; } // Make local copy if (symlink((const char *)link_contents, path) == -1) { perror(path); exit(1); } }
bool compressed_output_stream::flush() { VAST_ENTER(); if (valid_bytes_ == 0) VAST_RETURN(true); void* dst_data; size_t dst_size; if (!sink_.raw(&dst_data, &dst_size)) VAST_RETURN(false); auto compressed_bound = compressed_size(valid_bytes_); compressed_.resize(compressed_bound); size_t n; if (4 + compressed_bound > dst_size) { // Block may be too large for the output stream buffer. Thus we need to // compress it first into a temporary buffer and then write it out in raw // form. n = compress(compressed_.data(), compressed_.size()); VAST_ASSERT(n > 0); VAST_ASSERT(n <= std::numeric_limits<uint32_t>::max()); VAST_ASSERT(n <= compressed_bound); total_bytes_ += sink_.write<uint32_t>(&n); total_bytes_ += sink_.write_raw(compressed_.data(), n); } else { // We have enough space to directly write the full block into the // underlying output buffer, no need to use the scratch space. n = compress(4 + reinterpret_cast<uint8_t*>(dst_data), compressed_.size()); VAST_ASSERT(n > 0); VAST_ASSERT(n <= std::numeric_limits<uint32_t>::max()); VAST_ASSERT(n <= compressed_bound); auto four = sink_.write<uint32_t>(&n); if (four != sizeof(uint32_t)) VAST_RETURN(false); total_bytes_ += four + n; sink_.skip(n); } valid_bytes_ = 0; VAST_RETURN(true); }
void do_file(const u8* base, u32 offset, u32 size, const char* path, const char* name, int mode) { int fd; u8* file_data; const u8* srcdata; // Allow for uncompressed XIP executable if (mode & S_ISVTX) { // It seems that the offset may not necessarily be page // aligned. This is silly because mkcramfs wastes // the alignment space, whereas it might be used if it wasn't // bogusly in our file extent. // // blksize must be a power of 2 for the following to work, but it seems // quite likely. srcdata=(const u8*)(((u32)(base+offset)+blksize-1) & ~(blksize-1)); printsize(size, srcdata+size-(base+offset)); printf("%s", name); } else { printsize(size, compressed_size(base, base+offset, size) ); printf("%s", name); } // Check if we are actually unpacking if (path[0]=='-') { return; } // Make local copy fd=open(path, O_CREAT|O_TRUNC|O_RDWR, mode); if (fd == -1) { perror("create"); return; }; if (ftruncate(fd, size) == -1) { perror("ftruncate"); close(fd); return; } file_data = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (file_data == MAP_FAILED) { perror("mmap"); close(fd); return; } // Allow for uncompressed XIP executable if (mode & S_ISVTX) { memcpy(file_data, srcdata, size); } else { if(uncompress_data(base, base+offset, size, file_data) == -1) { printf("failed to decompress data\n"); } } munmap(file_data, size); close(fd); }