static int processor(uint8_t *f, int fd, size_t l) { uint8_t frag[33]; size_t start, off; ssize_t scan; int rc = EXIT_SUCCESS; int stop = 0; char ch = 0; if (stdin_nobuf()) { return EXIT_FAILURE; } while (1) { if (0xa != ch) { printf("\n> "); } ch = fgetc(stdin); printf("%c", ch); switch (ch) { case '+': if (readnum(&start)) { printf("\nINVALID START\n"); break; } if (readnum(&off)) { printf("\nINVALID LENGTH\n"); break; } printf("%lx\n", off+start); break; case '-': if (readnum(&start)) { printf("\nINVALID START\n"); break; } if (readnum(&off)) { printf("\nINVALID LENGTH\n"); break; } printf("%lx\n", start-off); break; case 'e': if (readnum(&off)) { printf("\nINVALID OFFSET\n"); break; } if (-1 == expand(&f, fd, l, off)) { stop = 1; rc = EXIT_FAILURE; break; } l += off; printf("\nEXTENDED %lu BYTES\n", (long unsigned)off); break; case 'f': if (readnum(&start) || (start >= l)) { printf("\nINVALID START\n"); break; } if (readnum(&off)) { printf("\nINVALID LENGTH\n"); break; } if (-1 == read_fragment(frag, off)) { printf("\nINVALID FRAGMENT\n"); break; } printf("\nFIND FRAG FROM %lx SIZE %lu\n", start, off); find_frag(f+start, l-start, start, frag, off); break; case 'i': if (readnum(&start) || (start >= l)) { printf("\nINVALID START\n"); break; } if (-1 == expand(&f, fd, l, 1)) { stop = 1; rc = EXIT_FAILURE; break; } l++; if (-1 == shift_by(f+start, l-start)) { stop = 1; rc = EXIT_FAILURE; break; } break; case 'l': printf(" %lx\n", l); break; case 0x4: case 'q': printf("\nQUIT\n"); stop++; break; case 'r': if (readnum(&start) || (start >=l)) { printf("\nINVALID START\n"); break; } if (readnum(&off) || ((start+off) > l)) { printf("\nINVALID OFFSET\n"); rc = EXIT_FAILURE; break; } if (0 == off) { off = (l - start); } printhex(f+start, off, start); break; case 's': if (readnum(&start) || (start >= l)) { printf("\nINVALID START\n"); break; } if (readnum(&off)) { printf("\nINVALID LENGTH\n"); break; } if (-1 == read_fragment(frag, off)) { printf("\nINVALID FRAGMENT\n"); break; } printf("\nSCAN FRAG FROM %lx SIZE %lu\n", start, off); while (-1 != (scan = find_frag(f+start, l-start, start, frag, off))) { start += scan + 1; } break; case 'w': if (readnum(&start) || (start >=l)) { printf("\nINVALID START\n"); break; } writehex(f+start, l-start); break; } if (stop) { break; } } return rc; }
int write_file(char *pathname, unsigned int fragment, unsigned int frag_bytes, unsigned int offset, unsigned int blocks, long long start, char *block_ptr, unsigned int mode) { unsigned int file_fd, bytes, i; unsigned int *block_list; TRACE("write_file: regular file, blocks %d\n", blocks); if((block_list = malloc(blocks * sizeof(unsigned int))) == NULL) { ERROR("write_file: unable to malloc block list\n"); return FALSE; } if(swap) { unsigned int sblock_list[blocks]; memcpy(sblock_list, block_ptr, blocks * sizeof(unsigned int)); SQUASHFS_SWAP_INTS(block_list, sblock_list, blocks); } else memcpy(block_list, block_ptr, blocks * sizeof(unsigned int)); if((file_fd = open(pathname, O_CREAT | O_WRONLY, (mode_t) mode)) == -1) { ERROR("write_file: failed to create file %s, because %s\n", pathname, strerror(errno)); free(block_list); return FALSE; } for(i = 0; i < blocks; i++) { if((bytes = read_data_block(start, block_list[i], file_data)) == 0) { ERROR("write_file: failed to read data block 0x%llx\n", start); goto failure; } if(write(file_fd, file_data, bytes) < bytes) { ERROR("write_file: failed to write data block 0x%llx\n", start); goto failure; } start += SQUASHFS_COMPRESSED_SIZE_BLOCK(block_list[i]); } if(frag_bytes != 0) { char *fragment_data = read_fragment(fragment); if(fragment_data == NULL) goto failure; if(write(file_fd, fragment_data + offset, frag_bytes) < frag_bytes) { ERROR("write_file: failed to write fragment %d\n", fragment); goto failure; } } close(file_fd); return TRUE; failure: close(file_fd); free(block_list); return FALSE; }