static void send_stat_packet(int to_peer, int xfer_fd) { struct stat st; if (fstat(xfer_fd, &st) == -1) die_errno("fstat"); struct xfer_msg m = { .type = XFER_MSG_STAT, .u.stat.atime = st.st_atime, .u.stat.mtime = st.st_mtime, #ifdef HAVE_STRUCT_STAT_ST_ATIM .u.stat.atime_ns = st.st_atim.tv_nsec, #endif #ifdef HAVE_STRUCT_STAT_ST_MTIM .u.stat.mtime_ns = st.st_mtim.tv_nsec, #endif .u.stat.size = st.st_size, .u.stat.ugo_bits = st.st_mode & 0777, }; send_xfer_msg(to_peer, &m); } struct xfer_ctx { int from_peer; int to_peer; const struct cmd_xfer_stub_info* info; }; static uint32_t recv_data_header(int from_peer) { struct xfer_msg m = recv_xfer_msg(from_peer); if (m.type != XFER_MSG_DATA) die(ECOMM, "unexpected message type %u", (unsigned) m.type); return m.u.data.payload_size; } static void send_data_header(int to_peer, uint32_t size) { struct xfer_msg m = { .type = XFER_MSG_DATA, .u.data.payload_size = size, }; send_xfer_msg(to_peer, &m); } static uint64_t copy_loop_posix_recv( int from_peer, int dest_fd) { SCOPED_RESLIST(rl); struct growable_buffer buf = { 0 }; uint64_t total_written = 0; size_t chunksz; do { chunksz = recv_data_header(from_peer); dbg("data chunk header chunksz=%u", (unsigned) chunksz); resize_buffer(&buf, chunksz); if (read_all(from_peer, buf.buf, chunksz) != chunksz) die(ECOMM, "unexpected EOF"); write_all(dest_fd, buf.buf, chunksz); if (SATADD(&total_written, total_written, chunksz)) die(ECOMM, "file size too large"); } while (chunksz > 0); return total_written; } static void copy_loop_posix_send( int to_peer, int source_fd) { SCOPED_RESLIST(rl); size_t bufsz = 32 * 1024; uint8_t* buf = xalloc(bufsz); size_t nr_read; assert(bufsz <= UINT32_MAX); do { nr_read = read_all(source_fd, buf, bufsz); send_data_header(to_peer, nr_read); write_all(to_peer, buf, nr_read); } while (nr_read > 0); }
ssize_t PackedAudioPacket<T>::read_from_fd(int fd) { return read_all(fd, _data, size_bytes( )); }
/** * main functiom - for colne or restore data */ int main(int argc, char **argv){ char* source; /// source data int dfr; /// file descriptor for source and target int r_size; /// read and write size char* buffer; /// buffer data char* buffer2; /// buffer data unsigned long long block_id, copied = 0; /// block_id is every block in partition /// copied is copied block count off_t offset = 0, sf = 0; /// seek postition, lseek result int start, stop; /// start, range, stop number for progress bar char bitmagic[8] = "BiTmAgIc";// only for check postition char bitmagic_r[8]; /// read magic string from image int cmp; /// compare magic string char *bitmap; /// the point for bitmap data int debug = 0; /// debug or not unsigned long crc = 0xffffffffL; /// CRC32 check code for writint to image unsigned long crc_ck = 0xffffffffL; /// CRC32 check code for checking unsigned long crc_ck2 = 0xffffffffL; /// CRC32 check code for checking int c_size; /// CRC32 code size char* crc_buffer; /// buffer data for malloc crc code int done = 0; int s_count = 0; int rescue_num = 0; int tui = 0; /// text user interface int pui = 0; /// progress mode(default text) int raw = 0; char image_hdr_magic[512]; progress_bar prog; /// progress_bar structure defined in progress.h image_head image_hdr; /// image_head structure defined in partclone.h /** * get option and assign to opt structure * check parameter and read from argv */ parse_option_chkimg(argc, argv, &opt); /** * if "-d / --debug" given * open debug file in "/var/log/partclone.log" for log message */ debug = opt.debug; open_log(opt.logfile); /** * using Text User Interface */ if (opt.ncurses){ pui = NCURSES; log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n"); } else if (opt.dialog){ pui = DIALOG; log_mesg(1, 0, 0, debug, "Using Dialog User Interface mode.\n"); } else pui = TEXT; tui = open_pui(pui, opt.fresh); if ((opt.ncurses) && (tui == 0)){ opt.ncurses = 0; log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n"); } else if ((opt.dialog) && (tui == 1)){ m_dialog.percent = 1; } /// print partclone info print_partclone_info(opt); /* if (geteuid() != 0) log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n"); else log_mesg(1, 0, 0, debug, "UID is root.\n"); */ /** * open source and target * clone mode, source is device and target is image file/stdout * restore mode, source is image file/stdin and target is device * dd mode, source is device and target is device !!not complete */ #ifdef _FILE_OFFSET_BITS log_mesg(1, 0, 0, debug, "enable _FILE_OFFSET_BITS %i\n", _FILE_OFFSET_BITS); #endif dfr = open_source(opt.source, &opt); if (dfr == -1) { log_mesg(0, 1, 1, debug, "Erro EXIT.\n"); } /** * get partition information like super block, image_head, bitmap * from device or image file. */ log_mesg(1, 0, 0, debug, "Checking image hdr - get image_head from image file\n"); restore_image_hdr(&dfr, &opt, &image_hdr); /// check the image magic if (memcmp(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) != 0) log_mesg(0, 1, 1, debug, "The Image magic error. This file is NOT partclone Image\n"); /// alloc a memory to restore bitmap bitmap = (char*)malloc(sizeof(char)*image_hdr.totalblock); if(bitmap == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %lli\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from image file log_mesg(0, 0, 1, debug, "Calculating bitmap... "); log_mesg(0, 0, 1, debug, "Please wait... "); get_image_bitmap(&dfr, opt, image_hdr, bitmap); log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); log_mesg(1, 0, 0, debug, "print image_head\n"); /// print option to log file if (debug) print_opt(opt); /// print image_head print_image_hdr_info(image_hdr, opt); /** * initial progress bar */ start = 0; /// start number of progress bar stop = image_hdr.usedblocks; /// get the end of progress number, only used block log_mesg(1, 0, 0, debug, "Initial Progress bar\n"); /// Initial progress bar progress_init(&prog, start, stop, image_hdr.block_size); copied = 1; /// initial number is 1 /** * start read and write data between device and image file */ /** * read magic string from image file * and check it. */ r_size = read_all(&dfr, bitmagic_r, 8, &opt); /// read a magic string cmp = memcmp(bitmagic, bitmagic_r, 8); if(cmp != 0) log_mesg(0, 1, 1, debug, "bitmagic error %i\n", cmp); /// start restore image file to partition for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ){ r_size = 0; if((block_id + 1) == image_hdr.totalblock) done = 1; #ifdef _FILE_OFFSET_BITS if(copied == image_hdr.usedblocks) done = 1; #endif if (bitmap[block_id] == 1){ /// The block is used log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id); log_mesg(1, 0, 0, debug, "bitmap=%i, ",bitmap[block_id]); offset = (off_t)(block_id * image_hdr.block_size); buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data if(buffer == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt); log_mesg(1, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size); if (r_size <0) log_mesg(0, 1, 1, debug, "read errno = %i \n", errno); /// read crc32 code and check it. crc_ck = crc32(crc_ck, buffer, r_size); crc_buffer = (char*)malloc(CRC_SIZE); ///alloc a memory to copy data if(crc_buffer == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt); if (c_size < CRC_SIZE) log_mesg(0, 1, 1, debug, "read CRC error, please check your image file. \n"); memcpy(&crc, crc_buffer, CRC_SIZE); if (memcmp(&crc, &crc_ck, CRC_SIZE) != 0){ log_mesg(1, 0, 0, debug, "CRC Check error. 64bit bug before v0.1.0 (Rev:250M), enlarge crc size and recheck again....\n "); /// check again buffer2 = (char*)malloc(image_hdr.block_size+CRC_SIZE); ///alloc a memory to copy data if(buffer2 == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } memcpy(buffer2, buffer, image_hdr.block_size); memcpy(buffer2+image_hdr.block_size, crc_buffer, CRC_SIZE); memcpy(buffer, buffer2+CRC_SIZE, image_hdr.block_size); crc_ck2 = crc32(crc_ck2, buffer, r_size); c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt); if (c_size < CRC_SIZE) log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno)); memcpy(&crc, crc_buffer, CRC_SIZE); if (memcmp(&crc, &crc_ck2, CRC_SIZE) != 0) { log_mesg(0, 1, 1, debug, "CRC error again at %i...\n ", sf); } else { crc_ck = crc_ck2; } free(buffer2); } else { crc_ck2 = crc_ck; } /// free buffer free(buffer); free(crc_buffer); copied++; /// count copied block log_mesg(1, 0, 0, debug, "end\n"); } update_pui(&prog, copied, done); if(done = 1) break; } // end of for print_finish_info(opt); close (dfr); /// close source free(bitmap); /// free bitmp close_pui(pui); printf("Checked successfully.\n"); if(opt.debug) close_log(); return 0; /// finish }
static gboolean recv_message (GIOChannel *channel, GIOCondition cond, gpointer data) { gint fd = g_io_channel_unix_get_fd (channel); gboolean retval = TRUE; #ifdef VERBOSE g_print ("gio-test: ...from %d:%s%s%s%s\n", fd, (cond & G_IO_ERR) ? " ERR" : "", (cond & G_IO_HUP) ? " HUP" : "", (cond & G_IO_IN) ? " IN" : "", (cond & G_IO_PRI) ? " PRI" : ""); #endif if (cond & (G_IO_ERR | G_IO_HUP)) { shutdown_source (data); retval = FALSE; } if (cond & G_IO_IN) { char buf[BUFSIZE]; guint nbytes; guint nb; int i, j, seq; GIOError error; error = read_all (fd, channel, (gchar *) &seq, sizeof (seq), &nb); if (error == G_IO_ERROR_NONE) { if (nb == 0) { #ifdef VERBOSE g_print ("gio-test: ...from %d: EOF\n", fd); #endif shutdown_source (data); return FALSE; } g_assert (nb == sizeof (nbytes)); for (i = 0; i < nkiddies; i++) if (seqtab[i].fd == fd) { if (seq != seqtab[i].seq) { g_print ("gio-test: ...from %d: invalid sequence number %d, expected %d\n", fd, seq, seqtab[i].seq); g_assert_not_reached (); } seqtab[i].seq++; break; } error = read_all (fd, channel, (gchar *) &nbytes, sizeof (nbytes), &nb); } if (error != G_IO_ERROR_NONE) return FALSE; if (nb == 0) { #ifdef VERBOSE g_print ("gio-test: ...from %d: EOF\n", fd); #endif shutdown_source (data); return FALSE; } g_assert (nb == sizeof (nbytes)); if (nbytes >= BUFSIZE) { g_print ("gio-test: ...from %d: nbytes = %d (%#x)!\n", fd, nbytes, nbytes); g_assert_not_reached (); } g_assert (nbytes >= 0 && nbytes < BUFSIZE); #ifdef VERBOSE g_print ("gio-test: ...from %d: %d bytes\n", fd, nbytes); #endif if (nbytes > 0) { error = read_all (fd, channel, buf, nbytes, &nb); if (error != G_IO_ERROR_NONE) return FALSE; if (nb == 0) { #ifdef VERBOSE g_print ("gio-test: ...from %d: EOF\n", fd); #endif shutdown_source (data); return FALSE; } for (j = 0; j < nbytes; j++) if (buf[j] != ' ' + ((nbytes + j) % 95)) { g_print ("gio-test: ...from %d: buf[%d] == '%c', should be '%c'\n", fd, j, buf[j], 'a' + ((nbytes + j) % 32)); g_assert_not_reached (); } #ifdef VERBOSE g_print ("gio-test: ...from %d: OK\n", fd); #endif } } return retval; }
/** Implement a cpuworker. 'data' is an fdarray as returned by socketpair. * Read and writes from fdarray[1]. Reads requests, writes answers. * * Request format: * Task type [1 byte, always CPUWORKER_TASK_ONION] * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_CHALLENGE_LEN * Response format: * Success/failure [1 byte, boolean.] * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_REPLY_LEN * Negotiated keys KEY_LEN*2+DIGEST_LEN*2 * * (Note: this _should_ be by addr/port, since we're concerned with specific * connections, not with routers (where we'd use identity).) */ static void cpuworker_main(void *data) { char question[ONIONSKIN_CHALLENGE_LEN]; uint8_t question_type; tor_socket_t *fdarray = data; tor_socket_t fd; /* variables for onion processing */ char keys[CPATH_KEY_MATERIAL_LEN]; char reply_to_proxy[ONIONSKIN_REPLY_LEN]; char buf[LEN_ONION_RESPONSE]; char tag[TAG_LEN]; crypto_pk_t *onion_key = NULL, *last_onion_key = NULL; fd = fdarray[1]; /* this side is ours */ #ifndef TOR_IS_MULTITHREADED tor_close_socket(fdarray[0]); /* this is the side of the socketpair the * parent uses */ tor_free_all(1); /* so the child doesn't hold the parent's fd's open */ handle_signals(0); /* ignore interrupts from the keyboard, etc */ #endif tor_free(data); dup_onion_keys(&onion_key, &last_onion_key); for (;;) { ssize_t r; if ((r = recv(fd, (void *)&question_type, 1, 0)) != 1) { // log_fn(LOG_ERR,"read type failed. Exiting."); if (r == 0) { log_info(LD_OR, "CPU worker exiting because Tor process closed connection " "(either rotated keys or died)."); } else { log_info(LD_OR, "CPU worker exiting because of error on connection to Tor " "process."); log_info(LD_OR,"(Error on %d was %s)", fd, tor_socket_strerror(tor_socket_errno(fd))); } goto end; } tor_assert(question_type == CPUWORKER_TASK_ONION); if (read_all(fd, tag, TAG_LEN, 1) != TAG_LEN) { log_err(LD_BUG,"read tag failed. Exiting."); goto end; } if (read_all(fd, question, ONIONSKIN_CHALLENGE_LEN, 1) != ONIONSKIN_CHALLENGE_LEN) { log_err(LD_BUG,"read question failed. Exiting."); goto end; } if (question_type == CPUWORKER_TASK_ONION) { if (onion_skin_server_handshake(question, onion_key, last_onion_key, reply_to_proxy, keys, CPATH_KEY_MATERIAL_LEN) < 0) { /* failure */ log_debug(LD_OR,"onion_skin_server_handshake failed."); *buf = 0; /* indicate failure in first byte */ memcpy(buf+1,tag,TAG_LEN); /* send all zeros as answer */ memset(buf+1+TAG_LEN, 0, LEN_ONION_RESPONSE-(1+TAG_LEN)); } else { /* success */ log_debug(LD_OR,"onion_skin_server_handshake succeeded."); buf[0] = 1; /* 1 means success */ memcpy(buf+1,tag,TAG_LEN); memcpy(buf+1+TAG_LEN,reply_to_proxy,ONIONSKIN_REPLY_LEN); memcpy(buf+1+TAG_LEN+ONIONSKIN_REPLY_LEN,keys,CPATH_KEY_MATERIAL_LEN); } if (write_all(fd, buf, LEN_ONION_RESPONSE, 1) != LEN_ONION_RESPONSE) { log_err(LD_BUG,"writing response buf failed. Exiting."); goto end; } log_debug(LD_OR,"finished writing response."); } } end: if (onion_key) crypto_pk_free(onion_key); if (last_onion_key) crypto_pk_free(last_onion_key); tor_close_socket(fd); crypto_thread_cleanup(); spawn_exit(); }
/** * main functiom - for colne or restore data */ int main(int argc, char **argv) { #ifdef MEMTRACE setenv("MALLOC_TRACE", "partclone_mtrace.log", 1); mtrace(); #endif char* source; /// source data char* target; /// target data char* buffer; /// buffer data for malloc used char* buffer2; /// buffer data for malloc used int dfr, dfw; /// file descriptor for source and target int r_size, w_size; /// read and write size //unsigned long long block_id, copied = 0; /// block_id is every block in partition /// copied is copied block count off_t offset = 0, sf = 0; /// seek postition, lseek result int start, stop; /// start, range, stop number for progress bar unsigned long long total_write = 0; /// the copied size unsigned long long needed_size = 0; /// the copied size unsigned long long needed_mem = 0; /// the copied size char bitmagic[8] = "BiTmAgIc";// only for check postition char bitmagic_r[8]="00000000";/// read magic string from image int cmp; /// compare magic string unsigned long *bitmap; /// the point for bitmap data int debug = 0; /// debug or not unsigned long crc = 0xffffffffL; /// CRC32 check code for writint to image unsigned long crc_ck = 0xffffffffL; /// CRC32 check code for checking unsigned long crc_ck2 = 0xffffffffL; /// CRC32 check code for checking int c_size; /// CRC32 code size int n_crc_size = CRC_SIZE; char* crc_buffer; /// buffer data for malloc crc code //int done = 0; int s_count = 0; int rescue_num = 0; unsigned long long rescue_pos = 0; unsigned long long main_pos = 0; int tui = 0; /// text user interface int pui = 0; /// progress mode(default text) int next=1,next_int=1,next_max_count=7,next_count=7,i; unsigned long long next_block_id; char* cache_buffer; int nx_current=0; char bbuffer[4096]; int flag; int pres; pthread_t prog_thread; void *p_result; char *bad_sectors_warning_msg = "*************************************************************************\n" "* WARNING: The disk has bad sector. This means physical damage on the *\n" "* disk surface caused by deterioration, manufacturing faults or other *\n" "* reason. The reliability of the disk may stay stable or degrade fast. *\n" "* Use the --rescue option to efficiently save as much data as possible! *\n" "*************************************************************************\n"; image_head image_hdr; /// image_head structure defined in partclone.h memset(&image_hdr, 0, sizeof(image_hdr)); /** * get option and assign to opt structure * check parameter and read from argv */ parse_options(argc, argv, &opt); /** * if "-d / --debug" given * open debug file in "/var/log/partclone.log" for log message */ memset(&fs_opt, 0, sizeof(fs_cmd_opt)); debug = opt.debug; fs_opt.debug = debug; fs_opt.ignore_fschk = opt.ignore_fschk; next_max_count = opt.max_block_cache-1; next_count = opt.max_block_cache-1; //if(opt.debug) open_log(opt.logfile); /** * using Text User Interface */ if (opt.ncurses) { pui = NCURSES; log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n"); } else pui = TEXT; tui = open_pui(pui, opt.fresh); if ((opt.ncurses) && (tui == 0)) { opt.ncurses = 0; log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n"); } /// print partclone info print_partclone_info(opt); if (geteuid() != 0) log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n"); else log_mesg(1, 0, 0, debug, "UID is root.\n"); /// ignore crc check if(opt.ignore_crc) log_mesg(1, 0, 1, debug, "Ignore CRC error\n"); /** * open source and target * clone mode, source is device and target is image file/stdout * restore mode, source is image file/stdin and target is device * dd mode, source is device and target is device !!not complete */ #ifdef _FILE_OFFSET_BITS log_mesg(1, 0, 0, debug, "enable _FILE_OFFSET_BITS %i\n", _FILE_OFFSET_BITS); #endif source = opt.source; target = opt.target; dfr = open_source(source, &opt); if (dfr == -1) { log_mesg(0, 1, 1, debug, "Erro EXIT.\n"); } dfw = open_target(target, &opt); if (dfw == -1) { log_mesg(0, 1, 1, debug, "Error Exit.\n"); } /** * get partition information like super block, image_head, bitmap * from device or image file. */ if (opt.clone) { log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n"); log_mesg(0, 0, 1, debug, "Reading Super Block\n"); /// get Super Block information from partition initial_image_hdr(source, &image_hdr); /// check memory size if (check_mem_size(image_hdr, opt, &needed_mem) == -1) log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %lld bytes memory\n", needed_mem); strncpy(image_hdr.version, IMAGE_VERSION, VERSION_SIZE); /// alloc a memory to restore bitmap bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock)); if(bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %i\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from partition log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... "); readbitmap(source, image_hdr, bitmap, pui); needed_size = (unsigned long long)(((image_hdr.block_size+sizeof(unsigned long))*image_hdr.usedblocks)+sizeof(image_hdr)+sizeof(char)*image_hdr.totalblock); if (opt.check) check_free_space(&dfw, needed_size); log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap); log_mesg(1, 0, 0, debug, "Writing super block and bitmap... "); // write image_head to image file w_size = write_all(&dfw, (char *)&image_hdr, sizeof(image_head), &opt); if(w_size == -1) log_mesg(0, 1, 1, debug, "write image_hdr to image error\n"); // write bitmap information to image file for (i = 0; i < image_hdr.totalblock; i++) { if (pc_test_bit(i, bitmap)) { bbuffer[i % sizeof(bbuffer)] = 1; } else { bbuffer[i % sizeof(bbuffer)] = 0; } if (i % sizeof(bbuffer) == sizeof(bbuffer) - 1 || i == image_hdr.totalblock - 1) { w_size = write_all(&dfw, bbuffer, 1 + (i % sizeof(bbuffer)), &opt); if(w_size == -1) log_mesg(0, 1, 1, debug, "write bitmap to image error\n"); } } log_mesg(0, 0, 1, debug, "done!\n"); } else if (opt.restore) { log_mesg(1, 0, 0, debug, "restore image hdr - get image_head from image file\n"); log_mesg(1, 0, 1, debug, "Reading Super Block\n"); /// get image information from image file restore_image_hdr(&dfr, &opt, &image_hdr); /// check memory size if (check_mem_size(image_hdr, opt, &needed_mem) == -1) log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %lld bytes memory\n", needed_mem); /// alloc a memory to restore bitmap bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock)); if(bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } /// check the image magic if (memcmp(image_hdr.magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) != 0) log_mesg(0, 1, 1, debug, "This is not partclone image.\n"); /// check the file system //if (strcmp(image_hdr.fs, FS) != 0) // log_mesg(0, 1, 1, debug, "%s can't restore from the image which filesystem is %s not %s\n", argv[0], image_hdr.fs, FS); log_mesg(2, 0, 0, debug, "initial main bitmap pointer %lli\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from image file log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... "); get_image_bitmap(&dfr, opt, image_hdr, bitmap); /// check the dest partition size. if (opt.restore_row_file) check_free_space(&dfw, image_hdr.device_size); else if(opt.check) check_size(&dfw, image_hdr.device_size); log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); } else if (opt.dd) { log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n"); log_mesg(1, 0, 1, debug, "Reading Super Block\n"); /// get Super Block information from partition initial_image_hdr(source, &image_hdr); /// check memory size if (check_mem_size(image_hdr, opt, &needed_mem) == -1) log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %lld bytes memory\n", needed_mem); strncpy(image_hdr.version, IMAGE_VERSION, VERSION_SIZE); /// alloc a memory to restore bitmap bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock)); if(bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %i\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from partition log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... "); readbitmap(source, image_hdr, bitmap, pui); /// check the dest partition size. if(opt.check) { check_size(&dfw, image_hdr.device_size); } log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); } else if (opt.domain) { log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n"); log_mesg(1, 0, 1, debug, "Reading Super Block\n"); /// get Super Block information from partition initial_image_hdr(source, &image_hdr); /// check memory size if (check_mem_size(image_hdr, opt, &needed_mem) == -1) log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %lld bytes memory\n", needed_mem); strncpy(image_hdr.version, IMAGE_VERSION, VERSION_SIZE); /// alloc a memory to restore bitmap bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock)); if(bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %i\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from partition log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... "); readbitmap(source, image_hdr, bitmap, pui); log_mesg(2, 0, 0, debug, "check main bitmap pointer %i\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); } log_mesg(1, 0, 0, debug, "print image_head\n"); /// print option to log file if (debug) print_opt(opt); /// print image_head print_image_hdr_info(image_hdr, opt); /** * initial progress bar */ //progress_bar prog; /// progress_bar structure defined in progress.h start = 0; /// start number of progress bar stop = (image_hdr.usedblocks); /// get the end of progress number, only used block log_mesg(1, 0, 0, debug, "Initial Progress bar\n"); /// Initial progress bar if (opt.no_block_detail) flag = NO_BLOCK_DETAIL; else flag = IO; progress_init(&prog, start, stop, image_hdr.totalblock, flag, image_hdr.block_size); copied = 0; /// initial number is 0 /** * thread to print progress */ pres = pthread_create(&prog_thread, NULL, thread_update_pui, NULL); /** * start read and write data between device and image file */ if (opt.clone) { w_size = write_all(&dfw, bitmagic, 8, &opt); /// write a magic string /// read data from the first block and log the offset sf = lseek(dfr, 0, SEEK_SET); log_mesg(1, 0, 0, debug, "seek %lli for reading data string\n",sf); if (sf == (off_t)-1) log_mesg(0, 1, 1, debug, "seek set %lli\n", sf); buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data if(buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } log_mesg(0, 0, 0, debug, "Total block %i\n", image_hdr.totalblock); /// start clone partition to image file log_mesg(1, 0, 0, debug, "start backup data...\n"); for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ) { r_size = 0; w_size = 0; main_pos = lseek(dfr, 0, SEEK_CUR); log_mesg(3, 0, 0, debug, "man pos = %lli\n", main_pos); if (pc_test_bit(block_id, bitmap)) { /// if the block is used log_mesg(1, 0, 0, debug, "block_id=%lli, ",block_id); log_mesg(2, 0, 0, debug, "bitmap=%i, ",pc_test_bit(block_id, bitmap)); offset = (off_t)(block_id * image_hdr.block_size); #ifdef _FILE_OFFSET_BITS sf = lseek(dfr, offset, SEEK_SET); if (sf == -1) log_mesg(0, 1, 1, debug, "source seek error = %lli, ",sf); #endif /// read data from source to buffer memset(buffer, 0, image_hdr.block_size); rescue_pos = lseek(dfr, 0, SEEK_CUR); r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt); log_mesg(3, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size); if (r_size != (int)image_hdr.block_size) { if ((r_size == -1) && (errno == EIO)) { if (opt.rescue) { r_size = 0; for (rescue_num = 0; rescue_num < image_hdr.block_size; rescue_num += SECTOR_SIZE) { rescue_sector(&dfr, rescue_pos + rescue_num, buffer + rescue_num, &opt); r_size+=SECTOR_SIZE; } } else log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg); } else log_mesg(0, 1, 1, debug, "read error: %s(%i) \n", strerror(errno), errno); } /// write buffer to target w_size = write_all(&dfw, buffer, image_hdr.block_size, &opt); log_mesg(3, 0, 0, debug, "bs=%i and w=%i, ",image_hdr.block_size, w_size); if (w_size != (int)image_hdr.block_size) log_mesg(0, 1, 1, debug, "write error %i \n", w_size); /// generate crc32 code and write it. crc_buffer = (char*)malloc(CRC_SIZE); ///alloc a memory to copy data if(crc_buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } crc = crc32(crc, buffer, w_size); memcpy(crc_buffer, &crc, CRC_SIZE); c_size = write_all(&dfw, crc_buffer, CRC_SIZE, &opt); /// free buffer free(crc_buffer); copied++; /// count copied block total_write += (unsigned long long)(w_size); /// count copied size log_mesg(3, 0, 0, debug, "total=%lli, ", total_write); /// read or write error if (r_size != w_size) log_mesg(0, 1, 1, debug, "read(%i) and write(%i) different\n", r_size, w_size); log_mesg(2, 0, 0, debug, "end\n"); } else { #ifndef _FILE_OFFSET_BITS /// if the block is not used, I just skip it. log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id); sf = lseek(dfr, image_hdr.block_size, SEEK_CUR); log_mesg(2, 0, 0, debug, "skip seek=%lli, ",sf); if (sf == (off_t)-1) log_mesg(0, 1, 1, debug, "clone seek error %lli errno=%i\n", (long long)offset, (int)errno); log_mesg(2, 0, 0, debug, "end\n"); #endif } } /// end of for free(buffer); } else if (opt.restore) { /** * read magic string from image file * and check it. */ r_size = read_all(&dfr, bitmagic_r, 8, &opt); /// read a magic string cmp = memcmp(bitmagic, bitmagic_r, 8); if(cmp != 0) log_mesg(0, 1, 1, debug, "bitmagic error %i\n", cmp); /// seek to the first sf = lseek(dfw, 0, SEEK_SET); log_mesg(1, 0, 0, debug, "seek %lli for writing dtat string\n",sf); if (sf == (off_t)-1) log_mesg(0, 1, 1, debug, "seek set %lli\n", sf); cache_buffer = (char*)malloc(image_hdr.block_size * (next_max_count+1)); if(cache_buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data if(buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } /// start restore image file to partition log_mesg(1, 0, 0, debug, "start restore data...\n"); for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ) { r_size = 0; w_size = 0; if (pc_test_bit(block_id, bitmap)) { /// The block is used log_mesg(1, 0, 0, debug, "block_id=%lli, ",block_id); log_mesg(2, 0, 0, debug, "bitmap=%i, ",pc_test_bit(block_id, bitmap)); memset(buffer, 0, image_hdr.block_size); r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt); log_mesg(3, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size); if (r_size <0) log_mesg(0, 1, 1, debug, "read errno = %i \n", errno); /// read crc32 code and check it. crc_ck = crc32(crc_ck, buffer, r_size); crc_buffer = (char*)malloc(CRC_SIZE); ///alloc a memory to copy data if(crc_buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt); if (c_size < CRC_SIZE) log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno)); memcpy(&crc, crc_buffer, CRC_SIZE); /*FIX: 64bit image can't ignore crc error*/ if ((memcmp(&crc, &crc_ck, CRC_SIZE) != 0) && (!opt.ignore_crc)) { log_mesg(1, 0, 0, debug, "CRC Check error. 64bit bug before v0.1.0 (Rev:250M), enlarge crc size and recheck again....\n "); /// check again buffer2 = (char*)malloc(image_hdr.block_size+CRC_SIZE); ///alloc a memory to copy data if(buffer2 == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } memcpy(buffer2, buffer, image_hdr.block_size); memcpy(buffer2+image_hdr.block_size, crc_buffer, CRC_SIZE); memcpy(buffer, buffer2+CRC_SIZE, image_hdr.block_size); crc_ck2 = crc32(crc_ck2, buffer, r_size); c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt); if (c_size < CRC_SIZE) log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno)); memcpy(&crc, crc_buffer, CRC_SIZE); if ((memcmp(&crc, &crc_ck2, CRC_SIZE) != 0 )&& (!opt.ignore_crc)) { log_mesg(0, 1, 1, debug, "CRC error again at %i...\n ", sf); } else { crc_ck = crc_ck2; } free(buffer2); } else { crc_ck2 = crc_ck; } if(next != next_count) { memset(cache_buffer, 0, image_hdr.block_size*next_max_count); for (next_int = 1; next_int <= next_max_count; next_int++) { next_block_id = block_id+next_int; if (pc_test_bit(next_block_id, bitmap)) { next++; } else { next_count = next; break; } next_count = next; } log_mesg(1, 0, 0, debug, "next = %i\n",next); } if ((next == next_count) &&(nx_current < next)) { memcpy(cache_buffer+(image_hdr.block_size*nx_current), buffer, image_hdr.block_size); w_size = 0; nx_current++; } if ((next == next_count) && (nx_current == next)) { #ifdef _FILE_OFFSET_BITS offset = (off_t)((block_id-next+1) * image_hdr.block_size); sf = lseek(dfw, offset, SEEK_SET); if (sf == -1) log_mesg(0, 1, 1, debug, "target seek error = %lli, ",sf); #endif /// write block from buffer to partition w_size = write_all(&dfw, cache_buffer, (image_hdr.block_size*nx_current), &opt); log_mesg(1, 0, 0, debug, "bs=%i and w=%i, ",(image_hdr.block_size*nx_current), w_size); if (w_size != (int)image_hdr.block_size*nx_current) log_mesg(0, 1, 1, debug, "write error %i \n", w_size); next = 1; next_count = next_max_count; nx_current=0; } /// free buffer free(crc_buffer); copied++; /// count copied block total_write += (unsigned long long) w_size; /// count copied size /// read or write error //if ((r_size != w_size) || (r_size != image_hdr.block_size)) // log_mesg(0, 1, 1, debug, "read and write different\n"); log_mesg(1, 0, 0, debug, "end\n"); } else { /// for restore to row file, mount -o loop used. if ((block_id == (image_hdr.totalblock-1)) && (opt.restore_row_file)) { write_last_block(&dfw, image_hdr.block_size, block_id, &opt); } else { #ifndef _FILE_OFFSET_BITS /// if the block is not used, I just skip it. log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id); sf = lseek(dfw, image_hdr.block_size, SEEK_CUR); log_mesg(2, 0, 0, debug, "seek=%lli, ",sf); if (sf == (off_t)-1) log_mesg(0, 1, 1, debug, "seek error %lli errno=%i\n", (long long)offset, (int)errno); log_mesg(2, 0, 0, debug, "end\n"); #endif } } } // end of for free(buffer); } else if (opt.dd) { sf = lseek(dfr, 0, SEEK_SET); log_mesg(1, 0, 0, debug, "seek %lli for reading data string\n",sf); if (sf == (off_t)-1) log_mesg(0, 1, 1, debug, "seek set %lli\n", sf); main_pos = lseek(dfr, 0, SEEK_CUR); log_mesg(1, 0, 0, debug, "man pos = %lli\n", main_pos); log_mesg(0, 0, 0, debug, "Total block %i\n", image_hdr.totalblock); buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data if(buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } /// start clone partition to image file log_mesg(1, 0, 0, debug, "start backup data device-to-device...\n"); for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ) { r_size = 0; w_size = 0; if (pc_test_bit(block_id, bitmap)) { /// if the block is used log_mesg(1, 0, 0, debug, "block_id=%lli, ",block_id); log_mesg(2, 0, 0, debug, "bitmap=%i, ",pc_test_bit(block_id, bitmap)); offset = (off_t)(block_id * image_hdr.block_size); #ifdef _FILE_OFFSET_BITS sf = lseek(dfr, offset, SEEK_SET); if (sf == -1) log_mesg(0, 1, 1, debug, "source seek error = %lli, ",sf); sf = lseek(dfw, offset, SEEK_SET); if (sf == -1) log_mesg(0, 1, 1, debug, "target seek error = %lli, ",sf); #endif /// read data from source to buffer memset(buffer, 0, image_hdr.block_size); rescue_pos = lseek(dfr, 0, SEEK_CUR); r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt); log_mesg(3, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size); if (r_size != (int)image_hdr.block_size) { if ((r_size == -1) && (errno == EIO)) { if (opt.rescue) { r_size = 0; for (rescue_num = 0; rescue_num < image_hdr.block_size; rescue_num += SECTOR_SIZE) { rescue_sector(&dfr, rescue_pos + rescue_num, buffer + rescue_num, &opt); r_size+=SECTOR_SIZE; } } else log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg); } else log_mesg(0, 1, 1, debug, "read error: %s(%i) \n", strerror(errno), errno); } /// write buffer to target w_size = write_all(&dfw, buffer, image_hdr.block_size, &opt); log_mesg(3, 0, 0, debug, "bs=%i and w=%i, ",image_hdr.block_size, w_size); if (w_size != (int)image_hdr.block_size) log_mesg(0, 1, 1, debug, "write error %i \n", w_size); copied++; /// count copied block total_write += (unsigned long long)(w_size); /// count copied size log_mesg(2, 0, 0, debug, "total=%lli, ", total_write); /// read or write error if (r_size != w_size) log_mesg(0, 1, 1, debug, "read and write different\n"); log_mesg(1, 0, 0, debug, "end\n"); } else { #ifndef _FILE_OFFSET_BITS /// if the block is not used, I just skip it. log_mesg(2, 0, 0, debug, "block_id=%lli, ",block_id); sf = lseek(dfr, image_hdr.block_size, SEEK_CUR); log_mesg(2, 0, 0, debug, "skip source seek=%lli, ",sf); sf = lseek(dfw, image_hdr.block_size, SEEK_CUR); log_mesg(2, 0, 0, debug, "skip target seek=%lli, ",sf); if (sf == (off_t)-1) log_mesg(0, 1, 1, debug, "clone seek error %lli errno=%i\n", (long long)offset, (int)errno); #endif } } /// end of for free(buffer); } else if (opt.domain) { log_mesg(0, 0, 0, debug, "Total block %i\n", image_hdr.totalblock); log_mesg(1, 0, 0, debug, "start writing domain log...\n"); // write domain log comment and status line dprintf(dfw, "# Domain logfile created by %s v%s\n", EXECNAME, VERSION); dprintf(dfw, "# Source: %s\n", opt.source); dprintf(dfw, "# Offset: 0x%08llX\n", opt.offset_domain); dprintf(dfw, "# current_pos current_status\n"); dprintf(dfw, "0x%08llX ?\n", opt.offset_domain + (image_hdr.totalblock * image_hdr.block_size)); dprintf(dfw, "# pos size status\n"); // start logging the used/unused areas next_block_id = 0; cmp = pc_test_bit(0, bitmap); for( block_id = 0; block_id <= image_hdr.totalblock; block_id++ ) { if (block_id < image_hdr.totalblock) { nx_current = pc_test_bit(block_id, bitmap); if (nx_current == 1) copied++; } else nx_current = -1; if (nx_current != cmp) { dprintf(dfw, "0x%08llX 0x%08llX %c\n", opt.offset_domain + (next_block_id * image_hdr.block_size), (block_id - next_block_id) * image_hdr.block_size, cmp ? '+' : '?'); next_block_id = block_id; cmp = nx_current; } // don't bother updating progress } /// end of for } done = 1; pres = pthread_join(prog_thread, &p_result); update_pui(&prog, copied, block_id, done); sync_data(dfw, &opt); print_finish_info(opt); close (dfr); /// close source close (dfw); /// close target free(bitmap); /// free bitmp close_pui(pui); printf("Cloned successfully.\n"); if(opt.debug) close_log(); #ifdef MEMTRACE muntrace(); #endif return 0; /// finish }
{ SCOPED_RESLIST(rl_send_stub); struct child_start_info csi = { .flags = CHILD_MERGE_STDERR, .exename = "adb", .argv = argv_concat((const char*[]){"adb", NULL}, adb_args ?: empty_argv, (const char*[]){"push", local, remote, NULL}, NULL), }; struct child* adb = child_start(&csi); fdh_destroy(adb->fd[0]); char buf[512]; size_t len = read_all(adb->fd[1]->fd, buf, sizeof (buf)); fdh_destroy(adb->fd[1]); int status = child_wait(adb); if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) { if (len == sizeof (buf)) --len; while (len > 0 && isspace(buf[len - 1])) --len; buf[len] = '\0'; char* epos = buf; while (*epos != '\0' && isspace(*epos)) ++epos;
static void parse_arguments (int argc, char **argv, Arguments *arg) { int c; /* defaults */ arg->me = argv[0]; arg->device = NULL; arg->forward_port = -1; arg->host_name = NULL; arg->host_port = DEFAULT_HOST_PORT; arg->proxy_name = NO_PROXY; arg->proxy_port = DEFAULT_PROXY_PORT; arg->proxy_buffer_size = NO_PROXY_BUFFER; arg->proxy_buffer_timeout = -1; arg->content_length = DEFAULT_CONTENT_LENGTH; arg->use_std = FALSE; arg->use_daemon = TRUE; arg->strict_content_length = FALSE; arg->keep_alive = DEFAULT_KEEP_ALIVE; arg->max_connection_age = DEFAULT_CONNECTION_MAX_TIME; arg->proxy_authorization = NULL; arg->user_agent = NULL; for (;;) { int option_index = 0; static struct option long_options[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V' }, { "no-daemon", no_argument, 0, 'w' }, { "stdin-stdout", no_argument, 0, 's' }, #ifdef DEBUG_MODE { "debug", required_argument, 0, 'D' }, { "logfile", required_argument, 0, 'l' }, #endif { "proxy", required_argument, 0, 'P' }, { "device", required_argument, 0, 'd' }, { "timeout", required_argument, 0, 'T' }, { "keep-alive", required_argument, 0, 'k' }, { "user-agent", required_argument, 0, 'U' }, { "forward-port", required_argument, 0, 'F' }, { "content-length", required_argument, 0, 'c' }, { "strict-content-length", no_argument, 0, 'S' }, { "proxy-buffer-size", required_argument, 0, 'B' }, { "proxy-authorization", required_argument, 0, 'A' }, { "max-connection-age", required_argument, 0, 'M' }, { "proxy-authorization-file", required_argument, 0, 'z' }, { 0, 0, 0, 0 } }; static const char *short_options = "A:B:c:d:F:hk:M:P:sST:U:Vwz:" #ifdef DEBUG_MODE "D:l:" #endif ; c = getopt_long (argc, argv, short_options, long_options, &option_index); if (c == -1) break; switch (c) { case 0: fprintf (stderr, "option %s", long_options[option_index].name); if (optarg) fprintf (stderr, " with arg %s", optarg); fprintf (stderr, "\n"); break; case 'A': arg->proxy_authorization = optarg; break; case 'B': arg->proxy_buffer_size = atoi_with_postfix (optarg); break; case 'c': arg->content_length = atoi_with_postfix (optarg); break; case 'd': arg->device = optarg; break; #ifdef DEBUG_MODE case 'D': if (optarg) debug_level = atoi (optarg); else debug_level = 1; break; case 'l': debug_file = fopen (optarg, "w"); if (debug_file == NULL) { fprintf (stderr, "%s: couldn't open file %s for writing\n", arg->me, optarg); exit (1); } break; #endif case 'F': arg->forward_port = atoi (optarg); break; case 'k': arg->keep_alive = atoi (optarg); break; case 'M': arg->max_connection_age = atoi (optarg); break; case 'h': usage (stdout, arg->me); exit (0); case 'P': name_and_port (optarg, &arg->proxy_name, &arg->proxy_port); if (arg->proxy_port == -1) arg->proxy_port = DEFAULT_PROXY_PORT; if (arg->proxy_buffer_timeout == -1) arg->proxy_buffer_timeout = DEFAULT_PROXY_BUFFER_TIMEOUT; break; case 's': arg->use_std=TRUE; arg->use_daemon=FALSE; break; case 'S': arg->strict_content_length = TRUE; break; case 'T': arg->proxy_buffer_timeout = atoi (optarg); break; case 'U': arg->user_agent = optarg; break; case 'V': printf ("htc (%s) %s\n", PACKAGE, VERSION); exit (0); case 'w': arg->use_daemon=FALSE; break; case 'z': { struct stat s; char *auth; int f; f = open (optarg, O_RDONLY); if (f == -1) { fprintf (stderr, "couldn't open %s: %s\n", optarg, strerror (errno)); exit (1); } if (fstat (f, &s) == -1) { fprintf (stderr, "error fstating %s: %s\n", optarg, strerror (errno)); exit (1); } auth = malloc (s.st_size + 1); if (auth == NULL) { fprintf (stderr, "out of memory whilst allocating " "authentication string\n"); exit (1); } if (read_all (f, auth, s.st_size) == -1) { fprintf (stderr, "error reading %s: %s\n", optarg, strerror (errno)); exit (1); } /* * If file ends with a "\r\n" or "\n", chop them off. */ if (s.st_size >= 1 && auth[s.st_size - 1] == '\n') { s.st_size -= (s.st_size >= 2 && auth[s.st_size - 2] == '\r') ? 2 : 1; } auth[s.st_size] = 0; arg->proxy_authorization = auth; } break; case '?': break; default: fprintf (stderr, "?? getopt returned character code 0%o ??\n", c); } } if (optind == argc - 1) { name_and_port (argv[optind], &arg->host_name, &arg->host_port); if (arg->host_port == -1) arg->host_port = DEFAULT_HOST_PORT; } else { fprintf (stderr, "%s: the destination of the tunnel must be specified.\n" "%s: try '%s --help' for help.\n", arg->me, arg->me, arg->me); exit (1); } if (arg->device == NULL && arg->forward_port == -1 && !arg->use_std) { fprintf (stderr, "%s: one of --device, --forward-port or --stdin-stdout must be used.\n" "%s: try '%s -help' for help.\n", arg->me, arg->me, arg->me); exit (1); } if ((arg->device != NULL && arg->forward_port != -1) || (arg->device != NULL && arg->use_std) || (arg->forward_port != -1 && arg->use_std)) { fprintf (stderr, "%s: only one of --device, --forward-port or --stdin-stdout can be used.\n" "%s: try '%s --help' for help.\n", arg->me, arg->me, arg->me); exit (1); } /* Removed test ((arg->device == NULL) == (arg->forward_port == -1)) * by Sampo Niskanen - those have been tested already! */ if (arg->host_name == NULL || arg->host_port == -1 || (arg->proxy_name != NO_PROXY && arg->proxy_port == -1)) { usage (stderr, arg->me); exit (1); } if (debug_level == 0 && debug_file != NULL) { fprintf (stderr, "%s: --logfile can't be used without debugging\n", arg->me); exit (1); } if (arg->proxy_name == NO_PROXY) { if (arg->proxy_buffer_size != NO_PROXY_BUFFER) { fprintf (stderr, "%s: warning: --proxy-buffer-size can't be " "used without --proxy\n", arg->me); arg->proxy_buffer_size = NO_PROXY_BUFFER; } if (arg->proxy_buffer_timeout != -1) { fprintf (stderr, "%s: warning: --proxy-buffer-timeout can't be " "used without --proxy\n", arg->me); arg->proxy_buffer_timeout = -1; } if (arg->proxy_authorization != NULL) { fprintf (stderr, "%s: warning: --proxy-authorization can't be " "used without --proxy\n", arg->me); arg->proxy_authorization = NULL; } } else if (arg->proxy_buffer_size == NO_PROXY_BUFFER) arg->proxy_buffer_timeout = -1; }
/** * main functiom - for colne or restore data */ int main(int argc, char **argv){ char* source; /// source data char* target; /// target data char* buffer; /// buffer data for malloc used char* buffer2; /// buffer data for malloc used int dfr, dfw; /// file descriptor for source and target int r_size, w_size; /// read and write size //unsigned long long block_id, copied = 0; /// block_id is every block in partition /// copied is copied block count off_t offset = 0, sf = 0; /// seek postition, lseek result int start, stop; /// start, range, stop number for progress bar unsigned long long total_write = 0; /// the copied size unsigned long long needed_size = 0; /// the copied size unsigned long long needed_mem = 0; /// the copied size char bitmagic[8] = "BiTmAgIc";// only for check postition char bitmagic_r[8]; /// read magic string from image int cmp; /// compare magic string unsigned long *bitmap; /// the point for bitmap data int debug = 0; /// debug or not unsigned long crc = 0xffffffffL; /// CRC32 check code for writint to image unsigned long crc_ck = 0xffffffffL; /// CRC32 check code for checking unsigned long crc_ck2 = 0xffffffffL; /// CRC32 check code for checking int c_size; /// CRC32 code size //int done = 0; int s_count = 0; int tui = 0; /// text user interface int pui = 0; /// progress mode(default text) int raw = 0; char image_hdr_magic[512]; int next=1,next_int=1,next_max_count=7,next_count=7; unsigned long long next_block_id; char* cache_buffer; int nx_current=0; int flag; pthread_t prog_thread; int pres; void *p_result; //progress_bar prog; /// progress_bar structure defined in progress.h image_head image_hdr; /// image_head structure defined in partclone.h /** * get option and assign to opt structure * check parameter and read from argv */ parse_options(argc, argv, &opt); /** * if "-d / --debug" given * open debug file in "/var/log/partclone.log" for log message */ debug = opt.debug; //if(opt.debug) open_log(opt.logfile); /** * using Text User Interface */ if (opt.ncurses){ pui = NCURSES; log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n"); } else pui = TEXT; tui = open_pui(pui, opt.fresh); if ((opt.ncurses) && (tui == 0)){ opt.ncurses = 0; log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n"); } next_max_count = opt.max_block_cache-1; next_count = opt.max_block_cache-1; /// print partclone info print_partclone_info(opt); if (geteuid() != 0) log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n"); else log_mesg(1, 0, 0, debug, "UID is root.\n"); /// ignore crc check if(opt.ignore_crc) log_mesg(1, 0, 1, debug, "Ignore CRC error\n"); /** * open source and target * clone mode, source is device and target is image file/stdout * restore mode, source is image file/stdin and target is device * dd mode, source is device and target is device !!not complete */ #ifdef _FILE_OFFSET_BITS log_mesg(1, 0, 0, debug, "enable _FILE_OFFSET_BITS %i\n", _FILE_OFFSET_BITS); #endif source = opt.source; target = opt.target; dfr = open_source(source, &opt); if (dfr == -1) { log_mesg(0, 1, 1, debug, "Erro EXIT.\n"); } dfw = open_target(target, &opt); if (dfw == -1) { log_mesg(0, 1, 1, debug, "Error Exit.\n"); } /** * get partition information like super block, image_head, bitmap * from device or image file. */ if (opt.restore){ log_mesg(1, 0, 0, debug, "restore image hdr - get image_head from image file\n"); /// get first 512 byte r_size = read_all(&dfr, image_hdr_magic, 512, &opt); /// check the image magic if (memcmp(image_hdr_magic, IMAGE_MAGIC, IMAGE_MAGIC_SIZE) == 0){ restore_image_hdr_sp(&dfr, &opt, &image_hdr, image_hdr_magic); /// check memory size if (check_mem_size(image_hdr, opt, &needed_mem) == -1) log_mesg(0, 1, 1, debug, "Ther is no enough free memory, partclone suggests you should have %llu bytes memory\n", needed_mem); /// alloc a memory to restore bitmap bitmap = (unsigned long*)calloc(sizeof(unsigned long), LONGS(image_hdr.totalblock)); if(bitmap == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } /// check the file system //if (strcmp(image_hdr.fs, FS) != 0) // log_mesg(0, 1, 1, debug, "%s can't restore from the image which filesystem is %s not %s\n", argv[0], image_hdr.fs, FS); log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from image file log_mesg(0, 0, 1, debug, "Calculating bitmap... "); log_mesg(0, 0, 1, debug, "Please wait... "); get_image_bitmap(&dfr, opt, image_hdr, bitmap); /// check the dest partition size. if (opt.restore_raw_file) check_free_space(&dfw, image_hdr.device_size); else if(opt.check) check_size(&dfw, image_hdr.device_size); log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); }else{ log_mesg(1, 0, 0, debug, "This is not partclone image.\n"); raw = 1; //sf = lseek(dfr, 0, SEEK_SET); log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n"); /// get Super Block information from partition if (dfr != 0) initial_dd_hdr(dfr, &image_hdr); else initial_dd_hdr(dfw, &image_hdr); /// check the dest partition size. if(opt.check){ check_size(&dfw, image_hdr.device_size); } } } log_mesg(1, 0, 0, debug, "print image_head\n"); /// print option to log file if (debug) print_opt(opt); /// print image_head print_image_hdr_info(image_hdr, opt); /** * initial progress bar */ start = 0; /// start number of progress bar stop = (image_hdr.usedblocks+1); /// get the end of progress number, only used block log_mesg(1, 0, 0, debug, "Initial Progress bar\n"); /// Initial progress bar if (opt.no_block_detail) flag = NO_BLOCK_DETAIL; else flag = IO; progress_init(&prog, start, stop, image_hdr.totalblock, flag, image_hdr.block_size); copied = 0; /// initial number is 0 /** * thread to print progress */ pres = pthread_create(&prog_thread, NULL, thread_update_pui, NULL); /** * start read and write data between device and image file */ if ((opt.restore) && (!raw)) { /** * read magic string from image file * and check it. */ r_size = read_all(&dfr, bitmagic_r, 8, &opt); /// read a magic string cmp = memcmp(bitmagic, bitmagic_r, 8); if(cmp != 0) log_mesg(0, 1, 1, debug, "bitmagic error %i\n", cmp); cache_buffer = (char*)malloc(image_hdr.block_size * (next_max_count+1)); if(cache_buffer == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data if(buffer == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } /// seek to the first sf = lseek(dfw, opt.offset, SEEK_SET); log_mesg(1, 0, 0, debug, "seek %lli for writing dtat string\n",sf); if (sf == (off_t)-1) log_mesg(0, 1, 1, debug, "seek set %ji\n", (intmax_t)sf); /// start restore image file to partition for( block_id = 0; block_id < image_hdr.totalblock; block_id++ ){ r_size = 0; w_size = 0; if (pc_test_bit(block_id, bitmap)){ /// The block is used log_mesg(2, 0, 0, debug, "block_id=%llu, ",block_id); log_mesg(1, 0, 0, debug, "bitmap=%i, ",pc_test_bit(block_id, bitmap)); memset(buffer, 0, image_hdr.block_size); r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt); log_mesg(1, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size); if (r_size <0) log_mesg(0, 1, 1, debug, "read errno = %i \n", errno); /// read crc32 code and check it. crc_ck = crc32(crc_ck, buffer, r_size); char crc_buffer[CRC_SIZE]; c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt); if (c_size < CRC_SIZE) log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno)); /*FIX: 64bit image can't ignore crc error*/ if ((memcmp(crc_buffer, &crc_ck, CRC_SIZE) != 0) && (!opt.ignore_crc) ){ log_mesg(1, 0, 0, debug, "CRC Check error. 64bit bug before v0.1.0 (Rev:250M), enlarge crc size and recheck again....\n "); /// check again buffer2 = (char*)malloc(image_hdr.block_size+CRC_SIZE); ///alloc a memory to copy data if(buffer2 == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } memcpy(buffer2, buffer, image_hdr.block_size); memcpy(buffer2+image_hdr.block_size, crc_buffer, CRC_SIZE); memcpy(buffer, buffer2+CRC_SIZE, image_hdr.block_size); crc_ck2 = crc32(crc_ck2, buffer, r_size); c_size = read_all(&dfr, crc_buffer, CRC_SIZE, &opt); if (c_size < CRC_SIZE) log_mesg(0, 1, 1, debug, "read CRC error: %s, please check your image file. \n", strerror(errno)); if ((memcmp(crc_buffer, &crc_ck2, CRC_SIZE) != 0) && (!opt.ignore_crc)){ log_mesg(0, 1, 1, debug, "CRC error again at %ji...\n ", (intmax_t)sf); } else { crc_ck = crc_ck2; } free(buffer2); } else { crc_ck2 = crc_ck; } if(next != next_count){ memset(cache_buffer, 0, image_hdr.block_size*next_max_count); for (next_int = 1; next_int <= next_max_count; next_int++) { next_block_id = block_id+next_int; if (pc_test_bit(next_block_id, bitmap)) { next++; } else { next_count = next; break; } next_count = next; } log_mesg(1, 0, 0, debug, "next = %i\n",next); } if ((next == next_count) &&(nx_current < next)){ memcpy(cache_buffer+(image_hdr.block_size*nx_current), buffer, image_hdr.block_size); w_size = 0; nx_current++; } if ((next == next_count) && (nx_current == next)){ #ifdef _FILE_OFFSET_BITS offset = (off_t)(((block_id-next+1) * image_hdr.block_size)+opt.offset); sf = lseek(dfw, offset, SEEK_SET); if (sf == -1) log_mesg(0, 1, 1, debug, "target seek error = %ji, ", (intmax_t)sf); #endif /// write block from buffer to partition w_size = write_all(&dfw, cache_buffer, (image_hdr.block_size*nx_current), &opt); log_mesg(1, 0, 0, debug, "bs=%i and w=%i, ",(image_hdr.block_size*nx_current), w_size); if (w_size != image_hdr.block_size*nx_current) log_mesg(0, 1, 1, debug, "write error %i \n", w_size); next = 1; next_count = next_max_count; nx_current=0; } copied++; /// count copied block total_write += (unsigned long long) w_size; /// count copied size /// read or write error //if ((r_size != w_size) || (r_size != image_hdr.block_size)) // log_mesg(0, 1, 1, debug, "read and write different\n"); log_mesg(1, 0, 0, debug, "end\n"); } else { /// for restore to raw file, mount -o loop used. if ((block_id == (image_hdr.totalblock-1)) && (opt.restore_raw_file)){ write_last_block(&dfw, image_hdr.block_size, block_id, &opt); } else { #ifndef _FILE_OFFSET_BITS /// if the block is not used, I just skip it. log_mesg(2, 0, 0, debug, "block_id=%llu, ",block_id); sf = lseek(dfw, image_hdr.block_size, SEEK_CUR); log_mesg(2, 0, 0, debug, "seek=%ji, ", (intmax_t)sf); if (sf == (off_t)-1) log_mesg(0, 1, 1, debug, "seek error %ji errno=%i\n", (intmax_t)offset, errno); log_mesg(2, 0, 0, debug, "end\n"); #endif } } //if (!opt.quiet) // update_pui(&prog, copied, block_id, done); } // end of for /// free buffer free(cache_buffer); free(buffer); done = 1; pres = pthread_join(prog_thread, &p_result); update_pui(&prog, copied, block_id, done); sync_data(dfw, &opt); } else if ((opt.restore) && (raw)){ /// start clone partition to image file //write image_head to image file w_size = write_all(&dfw, image_hdr_magic, 512, &opt); if(w_size == -1) log_mesg(0, 1, 1, debug, "write image_hdr to image error\n"); block_id = 1; buffer = (char*)malloc(image_hdr.block_size); ///alloc a memory to copy data if(buffer == NULL){ log_mesg(0, 1, 1, debug, "%s, %i, ERROR:%s", __func__, __LINE__, strerror(errno)); } do { r_size = 0; w_size = 0; memset(buffer, 0, image_hdr.block_size); log_mesg(1, 0, 0, debug, "block_id=%llu, ",block_id); /// read data from source to buffer r_size = read_all(&dfr, buffer, image_hdr.block_size, &opt); log_mesg(1, 0, 0, debug, "bs=%i and r=%i, ",image_hdr.block_size, r_size); if (r_size != (int)image_hdr.block_size){ if (r_size == 0){ //EIO done = 1; } else { log_mesg(0, 1, 1, debug, "read error: %s(%i) rsize=%i\n", strerror(errno), errno, r_size); } } if (r_size == image_hdr.block_size){ /// write buffer to target w_size = write_all(&dfw, buffer, image_hdr.block_size, &opt); log_mesg(2, 0, 0, debug, "bs=%i and w=%i, ",image_hdr.block_size, w_size); if (w_size != (int)image_hdr.block_size) log_mesg(0, 1, 1, debug, "write error %i \n", w_size); } else if (r_size < image_hdr.block_size){ /// write readed buffer to target w_size = write_all(&dfw, buffer, r_size, &opt); log_mesg(2, 0, 0, debug, "bs=%i and w=%i, ",image_hdr.block_size, w_size); if (w_size != r_size) log_mesg(0, 1, 1, debug, "write error %i \n", w_size); } else { w_size = 0; } /// read or write error if (r_size != w_size) log_mesg(0, 1, 1, debug, "read and write different\n"); log_mesg(1, 0, 0, debug, "end\n"); block_id++; copied++; /// count copied block total_write += (unsigned long long)(w_size); /// count copied size log_mesg(1, 0, 0, debug, "total=%llu, ", total_write); //if (!opt.quiet) //update_pui(&prog, copied, block_id, done); } while (done == 0);/// end of for pres = pthread_join(prog_thread, &p_result); update_pui(&prog, copied, block_id, done); sync_data(dfw, &opt); /// free buffer free(buffer); } print_finish_info(opt); close (dfr); /// close source close (dfw); /// close target free(bitmap); /// free bitmp close_pui(pui); fprintf(stderr, "Cloned successfully.\n"); if(opt.debug) close_log(); return 0; /// finish }
int do_http_get(int s, const char *path, const char *hostname, size_t expected_bytes, size_t *read_bytes, size_t *write_bytes, struct timeval *datarequesttime, struct timeval *dataresponsetime, struct timeval *datacompletetime, struct timeval *dataperctime) { char buf[HTTP_BUF_LEN]; int len; // Length of request, not including \0 int perc_logged = -1; // Last logged timestamp for fraction of received bytes char is_first = 1; len = snprintf(buf, HTTP_BUF_LEN, "GET %s HTTP/1.0\r\nPragma: no-cache\r\n" "Host: %s\r\n\r\n", path, hostname); // Check for overflow or error if (len >= HTTP_BUF_LEN || len < 0) return -1; // Write the request fprintf(stderr, "Response: %s\n", buf); if (write_all(s, buf, len, 1) != len) return -1; *write_bytes = len; // Get when request is sent if (gettimeofday(datarequesttime, NULL)) { perror("getting datarequesttime"); return -1; } // Half-close the socket //if (shutdown(s, SHUT_WR)) // return -1; // Default, in case no data is returned dataresponsetime -> tv_sec = dataresponsetime -> tv_usec = 0; // Read the response *read_bytes = 0; while ((len = read_all(s, buf, HTTP_READ_LEN, 1)) > 0) { buf[len] = '\0'; fprintf(stderr, "Response: %s\n", buf); *read_bytes += len; // Get when start of response was received if (is_first) { is_first = 0; if (gettimeofday(dataresponsetime, NULL)) { perror("getting dataresponsetime"); return -1; } } // Get when the next 10% of expected bytes are received; this is a // while loop for cases when we expect only very few bytes and read // more than 10% of them in a single read_all() call. while (*read_bytes < expected_bytes && (*read_bytes * 10) / expected_bytes > perc_logged + 1) { if (gettimeofday(&dataperctime[++perc_logged], NULL)) { perror("getting dataperctime"); return -1; } } } // Get when response is complete if (gettimeofday(datacompletetime, NULL)) { perror("getting datacompletetime"); return -1; } return len; }
/** Send a resolve request for <b>hostname</b> to the Tor listening on * <b>sockshost</b>:<b>socksport</b>. Store the resulting IPv4 * address (in host order) into *<b>result_addr</b>. */ static int do_connect(const char *hostname, const char *filename, uint32_t sockshost, uint16_t socksport, int reverse, int version, size_t expected_bytes, uint32_t *result_addr, char **result_hostname) { int s; struct sockaddr_in socksaddr; char *req = NULL; int len = 0; int retval; assert(hostname); assert(filename); assert(result_addr); assert(version == 4 || version == 5); *result_addr = 0; *result_hostname = NULL; // Get time that connection was started if (gettimeofday(&starttime, NULL)) { perror("getting starttime"); return -1; } // Create the socket for connecting to SOCKS server s = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); if (s<0) { perror("creating socket"); return -1; } // Get time that socket was created if (gettimeofday(&sockettime, NULL)) { perror("getting sockettime"); return -1; } // Connect to the SOCKS server memset(&socksaddr, 0, sizeof(socksaddr)); socksaddr.sin_family = AF_INET; socksaddr.sin_port = htons(socksport); socksaddr.sin_addr.s_addr = htonl(sockshost); if (connect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) { perror("connecting to SOCKS host"); return -1; } // Get time that socket was connected if (gettimeofday(&connecttime, NULL)) { perror("getting connecttime"); return -1; } // Negotiate authentication method for SOCKS 5 if (version == 5) { retval = do_socks5_negotiate(s); if (retval) return retval; } // Get time that negotiation was completed if (gettimeofday(&negotiatetime, NULL)) { perror("getting negotiatetime"); return -1; } if ((len = build_socks_connect_request(&req, "", hostname, reverse, version))<0) { fprintf(stderr, "error generating SOCKS request: %d\n", len); return -1; } if (write_all(s, req, len, 1) != len) { perror("sending SOCKS request"); free(req); return -1; } free(req); // Get time that request was sent if (gettimeofday(&requesttime, NULL)) { perror("getting requesttime"); return -1; } if (version == 4) { char reply_buf[RESPONSE_LEN_4]; if (read_all(s, reply_buf, RESPONSE_LEN_4, 1) != RESPONSE_LEN_4) { fprintf(stderr, "Error reading SOCKS4 response.\n"); return -1; } if (parse_socks4a_connect_response(reply_buf, RESPONSE_LEN_4, result_addr)<0){ return -1; } } else { char reply_buf[RESPONSE_LEN_5]; if (read_all(s, reply_buf, RESPONSE_LEN_5, 1) != RESPONSE_LEN_5) { fprintf(stderr, "Error reading SOCKS5 response\n"); return -1; } if (parse_socks5_connect_response(reply_buf, RESPONSE_LEN_5, s, result_addr, result_hostname)<0){ return -1; } } // Get time that response was received if (gettimeofday(&responsetime, NULL)) { perror("getting responsetime"); return -1; } /* char reply_buf[1]; while (read_all(s, reply_buf, 1, 1) != 0) { fprintf(stderr,"Extra data: 0x%x\n", reply_buf[0]); } */ // Request a file using HTTP do_http_get(s, filename, hostname, expected_bytes, &read_bytes, &write_bytes, &datarequesttime, &dataresponsetime, &datacompletetime, dataperctime); didtimeout = 0; // Output status information output_status_information(); return 0; }
// if the image is in a directly supported format return the raw data otherwise decode & return the bitmap bool MCImageImport(IO_handle p_stream, IO_handle p_mask_stream, MCPoint &r_hotspot, char *&r_name, MCImageCompressedBitmap *&r_compressed, MCImageBitmap *&r_bitmap) { bool t_success = true; uindex_t t_width = 0, t_height = 0; uint8_t t_head[8]; uindex_t t_size = 8; uint32_t t_compression = F_RLE; if (t_success) t_success = MCS_read(t_head, sizeof(uint8_t), t_size, p_stream) == IO_NORMAL && t_size == 8 && MCS_seek_cur(p_stream, -8) == IO_NORMAL; if (t_success) { if (memcmp(t_head, "GIF87a", 6) == 0) t_compression = F_GIF; else if (memcmp(t_head, "GIF89a", 6) == 0) t_compression = F_GIF; else if (memcmp(t_head, "\211PNG", 4) == 0) t_compression = F_PNG; else if (memcmp(t_head, "\xff\xd8", 2) == 0) t_compression = F_JPEG; else if (MCImageGetMetafileGeometry(p_stream, t_width, t_height)) t_compression = F_PICT; if (t_compression != F_RLE) { t_success = MCImageCreateCompressedBitmap(t_compression, r_compressed); if (t_success) { if (t_success) t_success = read_all(p_stream, r_compressed->data, r_compressed->size); r_compressed->width = t_width; r_compressed->height = t_height; } } else { MCImageBitmap *t_bitmap = nil; if (memcmp(t_head, "BM", 2) == 0) t_success = MCImageDecodeBMP(p_stream, r_hotspot, t_bitmap); else if (memcmp(t_head, "#define", 7) == 0) t_success = MCImageDecodeXBM(p_stream, r_hotspot, r_name, t_bitmap); else if (memcmp(t_head, "/* XPM", 6) == 0) t_success = MCImageDecodeXPM(p_stream, t_bitmap); else if (t_head[0] == 'P' && (t_head[1] >= '1' && t_head[1] <= '6')) { t_success = MCImageDecodeNetPBM(p_stream, t_bitmap); // may have a mask image if (t_success && p_mask_stream != nil) { MCImageBitmap *t_mask = nil; t_success = MCImageDecodeNetPBM(p_mask_stream, t_mask) && MCImageBitmapApplyMask(t_bitmap, t_mask); MCImageFreeBitmap(t_mask); } } else // if all else fails, assume it's an XWD t_success = MCImageDecodeXWD(p_stream, r_name, t_bitmap); if (t_success) r_bitmap = t_bitmap; else MCImageFreeBitmap(t_bitmap); } } return t_success; }
int spawn(char *argv[], int *status) { pid_t pid; int err_pipe[2]; if (pipe(err_pipe) == -1) return -1; pid = fork(); if (pid == -1) { /* error */ return -1; } else if (pid == 0) { /* child */ int dev_null, err, i; close(err_pipe[0]); fcntl(err_pipe[1], F_SETFD, FD_CLOEXEC); /* redirect stdout and stderr to /dev/null if possible */ dev_null = open("/dev/null", O_WRONLY); if (dev_null != -1) { dup2(dev_null, 1); dup2(dev_null, 2); } /* not interactive, close stdin */ close(0); /* close unused fds */ for (i = 3; i < 30; i++) close(i); execvp(argv[0], argv); /* error */ err = errno; write_all(err_pipe[1], &err, sizeof(int)); exit(1); } else { /* parent */ int rc, errno_save, child_errno; close(err_pipe[1]); rc = read_all(err_pipe[0], &child_errno, sizeof(int)); errno_save = errno; close(err_pipe[0]); waitpid(pid, status, 0); if (rc == -1) { errno = errno_save; return -1; } if (rc == sizeof(int)) { errno = child_errno; return -1; } if (rc != 0) { errno = EMSGSIZE; return -1; } return 0; } }
int buse_main(const char* dev_file, const struct buse_operations *aop, void *userdata) { int sp[2]; int nbd, sk, err, tmp_fd; u_int64_t from; u_int32_t len; ssize_t bytes_read; struct nbd_request request; struct nbd_reply reply; void *chunk; assert(!socketpair(AF_UNIX, SOCK_STREAM, 0, sp)); nbd = open(dev_file, O_RDWR); assert(nbd != -1); assert(ioctl(nbd, NBD_SET_SIZE, aop->size) != -1); assert(ioctl(nbd, NBD_CLEAR_SOCK) != -1); if (!fork()) { /* The child needs to continue setting things up. */ close(sp[0]); sk = sp[1]; if(ioctl(nbd, NBD_SET_SOCK, sk) == -1){ fprintf(stderr, "ioctl(nbd, NBD_SET_SOCK, sk) failed.[%s]\n", strerror(errno)); } #if defined NBD_SET_FLAGS && defined NBD_FLAG_SEND_TRIM else if(ioctl(nbd, NBD_SET_FLAGS, NBD_FLAG_SEND_TRIM) == -1){ fprintf(stderr, "ioctl(nbd, NBD_SET_FLAGS, NBD_FLAG_SEND_TRIM) failed.[%s]\n", strerror(errno)); } #endif else{ err = ioctl(nbd, NBD_DO_IT); fprintf(stderr, "nbd device terminated with code %d\n", err); if (err == -1) fprintf(stderr, "%s\n", strerror(errno)); } ioctl(nbd, NBD_CLEAR_QUE); ioctl(nbd, NBD_CLEAR_SOCK); exit(0); } /* The parent opens the device file at least once, to make sure the * partition table is updated. Then it closes it and starts serving up * requests. */ tmp_fd = open(dev_file, O_RDONLY); assert(tmp_fd != -1); close(tmp_fd); close(sp[1]); sk = sp[0]; reply.magic = htonl(NBD_REPLY_MAGIC); reply.error = htonl(0); while ((bytes_read = read(sk, &request, sizeof(request))) > 0) { assert(bytes_read == sizeof(request)); memcpy(reply.handle, request.handle, sizeof(reply.handle)); len = ntohl(request.len); from = ntohll(request.from); assert(request.magic == htonl(NBD_REQUEST_MAGIC)); switch(ntohl(request.type)) { /* I may at some point need to deal with the the fact that the * official nbd server has a maximum buffer size, and divides up * oversized requests into multiple pieces. This applies to reads * and writes. */ case NBD_CMD_READ: fprintf(stderr, "Request for read of size %d\n", len); assert(aop->read); chunk = malloc(len); reply.error = aop->read(chunk, len, from, userdata); write_all(sk, (char*)&reply, sizeof(struct nbd_reply)); if(reply.error == 0) write_all(sk, (char*)chunk, len); free(chunk); break; case NBD_CMD_WRITE: fprintf(stderr, "Request for write of size %d\n", len); assert(aop->write); chunk = malloc(len); read_all(sk, chunk, len); reply.error = aop->write(chunk, len, from, userdata); free(chunk); write_all(sk, (char*)&reply, sizeof(struct nbd_reply)); break; case NBD_CMD_DISC: /* Handle a disconnect request. */ assert(aop->disc); aop->disc(userdata); return 0; #ifdef NBD_FLAG_SEND_FLUSH case NBD_CMD_FLUSH: assert(aop->flush); reply.error = aop->flush(userdata); write_all(sk, (char*)&reply, sizeof(struct nbd_reply)); break; #endif #ifdef NBD_FLAG_SEND_TRIM case NBD_CMD_TRIM: assert(aop->trim); reply.error = aop->trim(from, len, userdata); write_all(sk, (char*)&reply, sizeof(struct nbd_reply)); break; #endif default: assert(0); } } if (bytes_read == -1) fprintf(stderr, "%s\n", strerror(errno)); return 0; }
Mod::Mod(tl::FsNode& root) { auto sprite_dir = root / "sprites"_S; auto sound_dir = root / "sounds"_S; this->large_sprites = read_full_tga((sprite_dir / "large.tga"_S).try_get_source(), &this->pal); this->small_sprites = read_full_tga((sprite_dir / "small.tga"_S).try_get_source()); this->small_font_sprites = read_full_tga((sprite_dir / "text.tga"_S).try_get_source()); //this->font_sprites = read_full_tga((sprite_dir / "font.tga"_S).try_get_source(), &this->pal); tl::Palette dummyPal; tl::read_tga((sprite_dir / "font.tga"_S).try_get_source(), this->font_sprites, dummyPal); worm_sprites[0] = tl::Image(16, 7 * 3 * 16, 4); worm_sprites[1] = tl::Image(16, 7 * 3 * 16, 4); muzzle_fire_sprites[0] = tl::Image(16, 7 * 16, 4); muzzle_fire_sprites[1] = tl::Image(16, 7 * 16, 4); auto worms = large_sprites.crop(tl::RectU(0, 16 * 16, 16, 16 * (16 + 7 * 3))); worm_sprites[0].blit(worms); worm_sprites[1].blit(worms, 0, 0, 0, tl::ImageSlice::Flip); auto muzzle_fire = large_sprites.crop(tl::RectU(0, 16 * 9, 16, 16 * (9 + 7))); muzzle_fire_sprites[0].blit(muzzle_fire); muzzle_fire_sprites[1].blit(muzzle_fire, 0, 0, 0, tl::ImageSlice::Flip); { for (u32 y = 0; y < this->large_sprites.height(); ++y) { LargeSpriteRow row = {0, 0}; for (u32 x = 0; x < 16; ++x) { auto p = tl::Color(this->large_sprites.unsafe_pixel32(x, y)); bool draw = p.a() > 0; bool half = p.a() == 1 || p.a() == 2; bool bit0 = draw; bool bit1 = !(!draw || half); row.bit0 |= bit0 << x; row.bit1 |= bit1 << x; } this->large_sprites_bits.push_back(row); } } auto r = (root / "tc.dat"_S); auto src = r.try_get_source(); auto buf = src.read_all(); ss::Expander expander(buf); //auto* tc = expander.expand_root<TcData>(*(ss::StructOffset<TcDataReader> const*)buf.begin()); auto* tc = (liero::TcData *)expander.expand(liero::TcData::expand_program(), buf.begin()); this->tcdata = tc; this->weapon_types = tc->weapons().begin(); this->level_effects = tc->level_effects().begin(); this->nobject_types = tc->nobjects().begin(); this->sobject_types = tc->sobjects().begin(); for (auto& sound_name : tc->sound_names()) { tl::Vec<i16> sound_data; read_wav((sound_dir / sound_name.get()).try_get_source(), sound_data); this->sounds.push_back(move(sound_data)); } this->mod_data = expander.to_buffer(); }
/* XXX it would really be good to have a built-in I/O forwarder so * that we can make sure the output from this test program looks * somewhat reasonable. It's also the sure-fire way to make sure that * we know what's really going on. */ static int test_run_arr(int nprocs, int arr, int flags, int (*test_func)(int, struct bproc_test_info_t *)) { int pid,a,r,i; int pfd[2]; int status; struct bproc_test_info_t ti; if (nnodes == -1) { fprintf(stderr, "bproc_test: call bproc_test_init() first!\n"); exit(1); } /* Assign nodes to this arrangement */ ti.nprocs = nprocs; ti.arr = arr; ti.scratch = 0; for (i=0; i < nprocs; i++) { if (proc_arr(arr, i) == proc_fe) ti.node[i] = BPROC_NODE_MASTER; else if (proc_arr(arr, i) == proc_inv) ti.node[i] = node_inv; else { a = proc_arr(arr, i); if (a >= proc_sl_d) a -= proc_sl_d - proc_sl; a -= proc_sl; if (a >= nnodes) return 2; ti.node[i] = nodes[a]; } } /* Setup the first (parent) process */ pid = bproc_rfork(ti.node[0]); if (pid < 0) { fprintf(stderr, "bproc_rfork(%d)=%d; errno=%d (%s)\n", ti.node[0], pid, errno, bproc_strerror(errno)); return 3; } if (pid > 0) { if (waitpid(pid, &status, 0) != pid) { fprintf(stderr, "Failed to wait on proc 0: %s\n", strerror(errno)); return 1; } if (!WIFEXITED(status)) { printf(" abnormal exit"); return 1; } else if (WEXITSTATUS(status) != 0) { printf(" exit_status=%d", WEXITSTATUS(status)); return 1; } else { return 0; } } /* PROC 0: PARENT */ ti.pid[0] = getpid(); if (flags & bproc_test_no_auto_create) exit(test_func(0, &ti)); /* Create cihld processes */ for (i=1; i < nprocs; i++) { a = proc_arr(arr,i); pipe(pfd); pid = fork(); if (pid < 0) { perror("fork"); exit(100); } if (pid == 0) { close(pfd[0]); if (pfd[1] != STDOUT_FILENO) { dup2(pfd[1], STDOUT_FILENO); close(pfd[1]); } /* We need the cruddy built-in I/O forwarding here because * we use it to inform the parent about the PID *after* * moving. The side-effect of doing it this way is that * we know that child process is on the node where it * should be before going on. */ if (ti.node[i] != ti.node[0]) { if (bproc_move(ti.node[i])) exit(101); } /* PROC i: CHILD */ if (proc_isdetach(a)) { /* Detach self from parent by forking again. */ pid = fork(); if (pid < 0) exit(102); if (pid > 0) exit(0); /* child continues and does stuff */ } /* Tell parent about PID */ ti.pid[i] = getpid(); if (write(STDOUT_FILENO, &ti.pid[i], sizeof(ti.pid[i])) != sizeof(ti.pid[i])) { exit(103); } close(STDOUT_FILENO); /* Do the test */ exit(test_func(i, &ti)); } /* PROC 0: PARENT */ close(pfd[1]); r = read_all(pfd[0], &ti.pid[i], sizeof(ti.pid[i])); if (r != sizeof(ti.pid[i])) { fprintf(stderr, "Failed to get PID from child %d\n", i); exit(104); } close(pfd[0]); if (proc_isdetach(a)) { int status; /* Wait for intermediate process to exit */ if (waitpid(pid, &status, 0) != pid) exit(105); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) exit(106); } } exit(test_func(0, &ti)); }
/** Send a resolve request for <b>hostname</b> to the Tor listening on * <b>sockshost</b>:<b>socksport</b>. Store the resulting IPv4 * address (in host order) into *<b>result_addr</b>. */ static int do_resolve(const char *hostname, uint32_t sockshost, uint16_t socksport, int reverse, int version, tor_addr_t *result_addr, char **result_hostname) { int s = -1; struct sockaddr_in socksaddr; char *req = NULL; ssize_t len = 0; tor_assert(hostname); tor_assert(result_addr); tor_assert(version == 4 || version == 5); tor_addr_make_unspec(result_addr); *result_hostname = NULL; s = tor_open_socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); if (s<0) { log_sock_error("creating_socket", -1); return -1; } memset(&socksaddr, 0, sizeof(socksaddr)); socksaddr.sin_family = AF_INET; socksaddr.sin_port = htons(socksport); socksaddr.sin_addr.s_addr = htonl(sockshost); if (connect(s, (struct sockaddr*)&socksaddr, sizeof(socksaddr))) { log_sock_error("connecting to SOCKS host", s); goto err; } if (version == 5) { char method_buf[2]; if (write_all(s, "\x05\x01\x00", 3, 1) != 3) { log_err(LD_NET, "Error sending SOCKS5 method list."); goto err; } if (read_all(s, method_buf, 2, 1) != 2) { log_err(LD_NET, "Error reading SOCKS5 methods."); goto err; } if (method_buf[0] != '\x05') { log_err(LD_NET, "Unrecognized socks version: %u", (unsigned)method_buf[0]); goto err; } if (method_buf[1] != '\x00') { log_err(LD_NET, "Unrecognized socks authentication method: %u", (unsigned)method_buf[1]); goto err; } } if ((len = build_socks_resolve_request(&req, "", hostname, reverse, version))<0) { log_err(LD_BUG,"Error generating SOCKS request"); tor_assert(!req); goto err; } if (write_all(s, req, len, 1) != len) { log_sock_error("sending SOCKS request", s); tor_free(req); goto err; } tor_free(req); if (version == 4) { char reply_buf[RESPONSE_LEN_4]; if (read_all(s, reply_buf, RESPONSE_LEN_4, 1) != RESPONSE_LEN_4) { log_err(LD_NET, "Error reading SOCKS4 response."); goto err; } if (parse_socks4a_resolve_response(hostname, reply_buf, RESPONSE_LEN_4, result_addr)<0) { goto err; } } else { char reply_buf[16]; if (read_all(s, reply_buf, 4, 1) != 4) { log_err(LD_NET, "Error reading SOCKS5 response."); goto err; } if (reply_buf[0] != 5) { log_err(LD_NET, "Bad SOCKS5 reply version."); goto err; } /* Give a user some useful feedback about SOCKS5 errors */ if (reply_buf[1] != 0) { log_warn(LD_NET,"Got SOCKS5 status response '%u': %s", (unsigned)reply_buf[1], socks5_reason_to_string(reply_buf[1])); if (reply_buf[1] == 4 && !strcasecmpend(hostname, ".onion")) { log_warn(LD_NET, "%s is a hidden service; those don't have IP addresses. " "To connect to a hidden service, you need to send the hostname " "to Tor; we suggest an application that uses SOCKS 4a.", hostname); } goto err; } if (reply_buf[3] == 1) { /* IPv4 address */ if (read_all(s, reply_buf, 4, 1) != 4) { log_err(LD_NET, "Error reading address in socks5 response."); goto err; } tor_addr_from_ipv4n(result_addr, get_uint32(reply_buf)); } else if (reply_buf[3] == 4) { /* IPv6 address */ if (read_all(s, reply_buf, 16, 1) != 16) { log_err(LD_NET, "Error reading address in socks5 response."); goto err; } tor_addr_from_ipv6_bytes(result_addr, reply_buf); } else if (reply_buf[3] == 3) { /* Domain name */ size_t result_len; if (read_all(s, reply_buf, 1, 1) != 1) { log_err(LD_NET, "Error reading address_length in socks5 response."); goto err; } result_len = *(uint8_t*)(reply_buf); *result_hostname = tor_malloc(result_len+1); if (read_all(s, *result_hostname, result_len, 1) != (int) result_len) { log_err(LD_NET, "Error reading hostname in socks5 response."); goto err; } (*result_hostname)[result_len] = '\0'; } } tor_close_socket(s); return 0; err: tor_close_socket(s); return -1; }
ssize_t AudioPacket::read_from_fd(int fd) { return read_all(fd, _data, _size); }
void hh_load(value in_filename) { CAMLparam1(in_filename); FILE* fp = fopen(String_val(in_filename), "rb"); if (fp == NULL) { caml_failwith("Failed to open file"); } uint64_t magic = 0; read_all(fileno(fp), (void*)&magic, sizeof magic); assert(magic == MAGIC_CONSTANT); size_t revlen = 0; read_all(fileno(fp), (void*)&revlen, sizeof revlen); char revision[revlen]; read_all(fileno(fp), (void*)revision, revlen * sizeof(char)); assert(strncmp(revision, BuildInfo_kRevision, revlen) == 0); read_all(fileno(fp), (void*)&heap_init_size, sizeof heap_init_size); int compressed_size = 0; read_all(fileno(fp), (void*)&compressed_size, sizeof compressed_size); char* chunk_start = save_start(); pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); pthread_t thread; decompress_args args; int thread_started = 0; // see hh_save for a description of what we are parsing here. while (compressed_size > 0) { char* compressed = malloc(compressed_size * sizeof(char)); assert(compressed != NULL); uintptr_t chunk_size = 0; read_all(fileno(fp), (void*)&chunk_size, sizeof chunk_size); read_all(fileno(fp), compressed, compressed_size * sizeof(char)); if (thread_started) { intptr_t success = 0; int rc = pthread_join(thread, (void*)&success); free(args.compressed); assert(rc == 0); assert(success); } args.compressed = compressed; args.compressed_size = compressed_size; args.decompress_start = chunk_start; args.decompressed_size = chunk_size; pthread_create(&thread, &attr, (void* (*)(void*))decompress, &args); thread_started = 1; chunk_start += chunk_size; read_all(fileno(fp), (void*)&compressed_size, sizeof compressed_size); } if (thread_started) { int success; int rc = pthread_join(thread, (void*)&success); free(args.compressed); assert(rc == 0); assert(success); } fclose(fp); CAMLreturn0; }
int filter_png(struct media_info const *info, int out_fd, int in_fd) { FILE *fp = fdopen(out_fd, "wb"); struct png_struct_def *png_ptr = NULL; struct png_info_def *png_info = NULL; volatile int rc = EX_SOFTWARE; png_bytep row_pointers[info->height]; void * volatile raw_data = NULL; void * volatile rgb_data = NULL; size_t rgb_stride = info->width * ((info->bpp + 7) / 8) * 3; if (!fp) { perror("fdopen()"); return EX_OSERR; } png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) goto out; if (setjmp(png_jmpbuf(png_ptr))) goto out; /* allocate memory for raw (YCbCr) image data */ raw_data = png_malloc(png_ptr, info->stride * info->height); if (!raw_data) goto out; rgb_data = png_malloc(png_ptr, rgb_stride * info->height); if (!rgb_data) goto out; for (size_t y = 0; y < info->height; ++y) row_pointers[y] = rgb_data + y * rgb_stride; png_info = png_create_info_struct(png_ptr); if (!png_info) goto out; png_init_io(png_ptr, fp); png_set_user_limits(png_ptr, info->width, info->height); png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); /* atm, only 8bpp support is implemented */ assert(info->bpp == 8); for (;;) { bool eof = false; if (read_all(in_fd, raw_data, info->stride * info->height, &eof)) ; /* noop */ else if (!eof) goto out; else break; convert_yuv422_rgb888(rgb_data, raw_data, info->bpp, info->width, info->height); png_set_rows(png_ptr, png_info, row_pointers); png_set_IHDR(png_ptr, png_info, info->width, info->height, info->bpp, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); png_write_png(png_ptr, png_info, PNG_TRANSFORM_IDENTITY, NULL); fflush(fp); break; } rc = 0; out: png_free(png_ptr, rgb_data); png_free(png_ptr, raw_data); png_destroy_write_struct(&png_ptr, &png_info); fclose(fp); return rc; }
int main(int argc, char **argv){ int sockfd, connsockfd, cont = 2, i, socketsecundario; struct sockaddr_in server, client; struct pollfd desc_set[MAX_CLIENT];//Definido para 10 utilizadores em max_client struct table_t *table=(struct table_t*)malloc(sizeof(struct table_t)); char *terminal = malloc(sizeof(char)); int nbytes, msg_size, count; socklen_t size_client; // Verifica se foi passado algum argumento if (argc != 3 && argc != 5){ printf("Servidor sem replicação: Uso: ./table_server <porto_servidor> <size_table>\n"); printf("Servidor com replicação: Uso: ./table_server <porto_servidor> <porto2_servidor> <size_table> <ip_serverSecundario>\n"); return -1; } //Ligar servidor replicado if(argc == 5){ socketsecundario = ligarBackup(argv[4], argv[2]); } // Cria socket TCP if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { perror("Erro ao criar socket"); return -1; } // Preenche estrutura server para bind server.sin_family = AF_INET; server.sin_addr.s_addr = htonl(INADDR_ANY); server.sin_port = htons(atoi(argv[1])); // Faz bind if (bind(sockfd, (struct sockaddr *) &server, sizeof(server)) < 0){ perror("Erro ao fazer bind"); close(sockfd); return -1; }; // Faz listen if(listen(sockfd, 20) < 0){ perror("Erro ao executar listen"); close(sockfd); return -1; }; //cria table table=table_skel_init(atoi(argv[2])); desc_set[0].fd=fileno(stdin); desc_set[0].events=POLLIN; desc_set[0].revents=0; desc_set[1].fd=sockfd; //Listen socket desc_set[1].events=POLLIN; desc_set[1].revents=0; for(i=2; i< MAX_CLIENT; i++){ desc_set[i].fd=-1; desc_set[i].events=0; desc_set[i].revents=0; } printf("**Estrutura de dados criada**\n**Servidor 'a espera de dados**\n"); //Espera por dados nos sockets abertos while(poll(desc_set, MAX_CLIENT, -1) >= 0){ /*Tentativa de nova ligacao*/ if(desc_set[1].revents & POLLIN){ connsockfd = accept( desc_set[1].fd, ( struct sockaddr * )&client, &size_client); //adiciona connsockfd a desc_set desc_set[cont].fd=connsockfd; desc_set[cont].events=POLLIN; cont++; } /*Testar se ha algum evento extra por exemplo o pedido de informaçao do conteudo actual do server*/ if(desc_set[0].revents & POLLIN){ fgets(terminal, MAX_MSG, stdin); terminal=strtok(terminal, "\n"); if(strcmp(terminal, "print")== 0){ int conta=0; char **tabela; tabela = table_get_keys(table); printf("A tabela actual e': \n"); while(tabela[conta]!=NULL){ printf("Key na posição [%d]: %s", conta, tabela[conta]); conta++; } }else{ printf("erro! escreva print para apresentar o conteudo actual do server\n"); } } for(i=2; i<cont; i++){ if (desc_set[i].revents & POLLIN) { // Lê string enviada pelo cliente do socket referente a conexão if((nbytes = read(desc_set[i].fd,&msg_size,sizeof(int))) <= 0){ //perror("Erro ao receber dados do cliente1"); close(desc_set[i].fd); continue; } msg_size=ntohl(msg_size); char *msg_buf=(char *)malloc(msg_size+1); if((nbytes = read_all(desc_set[i].fd,msg_buf,msg_size)) < 0){ perror("Erro ao receber dados do cliente2"); close(desc_set[i].fd); continue; } struct message_t *msg_recebida = buffer_to_message(msg_buf, msg_size); free(msg_buf); if(argc==5){ //actualizar o backup de acordo com o tipo de escrita if((msg_recebida->opcode)==OC_PUT){ if(actualizarBackup(msg_recebida->content.entry->key, msg_recebida->content.entry->value,1)==-1) perror("Erro a receber OK do servidor secundario\n"); } if((msg_recebida->opcode)==OC_COND_PUT){ if(actualizarBackup(msg_recebida->content.entry->key, msg_recebida->content.entry->value,1)==-1) perror("Erro a receber OK do servidor secundario\n"); } if((msg_recebida->opcode)==OC_DEL){ if(actualizarBackup(msg_recebida->content.key, msg_recebida->content.entry->value,0)==-1) perror("Erro a receber OK do servidor secundario\n"); } } int res=invoke(msg_recebida); //Envia resposta ao cliente depois de converter para formato de rede msg_size = message_to_buffer(msg_recebida,&msg_buf); msg_size = htonl(msg_size); free_message(msg_recebida); // Envia tamanho do buffer ao cliente através do socket referente a conexão if((nbytes = write(desc_set[i].fd,(char*)&msg_size,sizeof(int))) != sizeof(int)){ perror("Erro ao enviar resposta ao cliente"); close(desc_set[i].fd); continue; } msg_size=ntohl(msg_size); if((nbytes = write_all(desc_set[i].fd,msg_buf,msg_size) != msg_size)){ perror("Erro ao enviar resposta ao cliente"); close(desc_set[i].fd); continue; } //Verifica-se se a ligaçao foi desligada if (desc_set[i].revents & POLLHUP){ close(desc_set[i].fd); desc_set[i].fd = -1; desc_set[i].events = 0; } } } } //elimina table table_skel_destroy(); // Fecha socket close(connsockfd); close(sockfd); return 0; }
static int call_daemon(const char *socket_path, int op, char *buf, size_t buflen, int *num, const char **err_context) { char op_buf[8]; int op_len; int s; ssize_t ret; int32_t reply_len = 0; struct sockaddr_un srv_addr; if (((op == UUIDD_OP_BULK_TIME_UUID) || (op == UUIDD_OP_BULK_RANDOM_UUID)) && !num) { if (err_context) *err_context = _("bad arguments"); errno = EINVAL; return -1; } if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { if (err_context) *err_context = _("socket"); return -1; } srv_addr.sun_family = AF_UNIX; strncpy(srv_addr.sun_path, socket_path, sizeof(srv_addr.sun_path)); srv_addr.sun_path[sizeof(srv_addr.sun_path) - 1] = '\0'; if (connect(s, (const struct sockaddr *) &srv_addr, sizeof(struct sockaddr_un)) < 0) { if (err_context) *err_context = _("connect"); close(s); return -1; } if (op == UUIDD_OP_BULK_RANDOM_UUID) { if ((*num) * UUID_LEN > buflen - 4) *num = (buflen - 4) / UUID_LEN; } op_buf[0] = op; op_len = 1; if ((op == UUIDD_OP_BULK_TIME_UUID) || (op == UUIDD_OP_BULK_RANDOM_UUID)) { memcpy(op_buf + 1, num, sizeof(int)); op_len += sizeof(int); } ret = write_all(s, op_buf, op_len); if (ret < 0) { if (err_context) *err_context = _("write"); close(s); return -1; } ret = read_all(s, (char *) &reply_len, sizeof(reply_len)); if (ret < 0) { if (err_context) *err_context = _("read count"); close(s); return -1; } if (reply_len < 0 || (size_t) reply_len > buflen) { if (err_context) *err_context = _("bad response length"); close(s); return -1; } ret = read_all(s, (char *) buf, reply_len); if ((ret > 0) && (op == UUIDD_OP_BULK_TIME_UUID)) { if (reply_len >= (int) (UUID_LEN + sizeof(int))) memcpy(buf + UUID_LEN, num, sizeof(int)); else *num = -1; } if ((ret > 0) && (op == UUIDD_OP_BULK_RANDOM_UUID)) { if (reply_len >= (int) sizeof(int)) memcpy(buf, num, sizeof(int)); else *num = -1; } close(s); return ret; }
int spawn(char *argv[], int *status, int do_wait) { pid_t pid; int err_pipe[2]; if (pipe(err_pipe) == -1) return -1; pid = fork(); if (pid == -1) { /* error */ return -1; } else if (pid == 0) { /* child */ int dev_null, err, i; /* create grandchild and exit child to avoid zombie processes */ if (!do_wait) { switch (fork()) { case 0: /* grandchild */ break; case -1: /* error */ _exit(127); default: /* parent of grandchild */ _exit(0); } } close(err_pipe[0]); fcntl(err_pipe[1], F_SETFD, FD_CLOEXEC); /* redirect stdout and stderr to /dev/null if possible */ dev_null = open("/dev/null", O_WRONLY); if (dev_null != -1) { dup2(dev_null, 1); dup2(dev_null, 2); } /* not interactive, close stdin */ close(0); /* close unused fds */ for (i = 3; i < 30; i++) close(i); execvp(argv[0], argv); /* error */ err = errno; write_all(err_pipe[1], &err, sizeof(int)); exit(1); } else { /* parent */ int rc, errno_save, child_errno, tmp; close(err_pipe[1]); rc = read_all(err_pipe[0], &child_errno, sizeof(int)); errno_save = errno; close(err_pipe[0]); if (!do_wait) status = &tmp; waitpid(pid, status, 0); if (rc == -1) { errno = errno_save; return -1; } if (rc == sizeof(int)) { errno = child_errno; return -1; } if (rc != 0) { errno = EMSGSIZE; return -1; } return 0; } }
static void server_loop(const char *socket_path, const char *pidfile_path, int debug, int timeout, int quiet) { struct sockaddr_un my_addr, from_addr; struct flock fl; socklen_t fromlen; int32_t reply_len = 0; uuid_t uu; mode_t save_umask; char reply_buf[1024], *cp; char op, str[UUID_STR_LEN]; int i, s, ns, len, num; int fd_pidfile, ret; fd_pidfile = open(pidfile_path, O_CREAT | O_RDWR, 0664); if (fd_pidfile < 0) { if (!quiet) fprintf(stderr, _("Failed to open/create %s: %m\n"), pidfile_path); exit(EXIT_FAILURE); } cleanup_pidfile = pidfile_path; cleanup_socket = 0; signal(SIGALRM, terminate_intr); alarm(30); fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; fl.l_pid = 0; while (fcntl(fd_pidfile, F_SETLKW, &fl) < 0) { if ((errno == EAGAIN) || (errno == EINTR)) continue; if (!quiet) fprintf(stderr, _("Failed to lock %s: %m\n"), pidfile_path); exit(EXIT_FAILURE); } ret = call_daemon(socket_path, 0, reply_buf, sizeof(reply_buf), 0, 0); if (ret > 0) { if (!quiet) printf(_("uuidd daemon already running at pid %s\n"), reply_buf); exit(EXIT_FAILURE); } alarm(0); if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { if (!quiet) fprintf(stderr, _("Couldn't create unix stream socket: %m")); exit(EXIT_FAILURE); } /* * Make sure the socket isn't using fd numbers 0-2 to avoid it * getting closed by create_daemon() */ while (!debug && s <= 2) { s = dup(s); if (s < 0) err(EXIT_FAILURE, "dup"); } /* * Create the address we will be binding to. */ my_addr.sun_family = AF_UNIX; strncpy(my_addr.sun_path, socket_path, sizeof(my_addr.sun_path)); my_addr.sun_path[sizeof(my_addr.sun_path) - 1] = '\0'; unlink(socket_path); save_umask = umask(0); if (bind(s, (const struct sockaddr *) &my_addr, sizeof(struct sockaddr_un)) < 0) { if (!quiet) fprintf(stderr, _("Couldn't bind unix socket %s: %m\n"), socket_path); exit(EXIT_FAILURE); } umask(save_umask); if (listen(s, SOMAXCONN) < 0) { if (!quiet) fprintf(stderr, _("Couldn't listen on unix " "socket %s: %m\n"), socket_path); exit(EXIT_FAILURE); } cleanup_socket = socket_path; if (!debug) create_daemon(); signal(SIGHUP, terminate_intr); signal(SIGINT, terminate_intr); signal(SIGTERM, terminate_intr); signal(SIGALRM, terminate_intr); signal(SIGPIPE, SIG_IGN); sprintf(reply_buf, "%8d\n", getpid()); if (ftruncate(fd_pidfile, 0)) { /* Silence warn_unused_result */ } write_all(fd_pidfile, reply_buf, strlen(reply_buf)); if (fd_pidfile > 1) close(fd_pidfile); /* Unlock the pid file */ while (1) { fromlen = sizeof(from_addr); if (timeout > 0) alarm(timeout); ns = accept(s, (struct sockaddr *) &from_addr, &fromlen); alarm(0); if (ns < 0) { if ((errno == EAGAIN) || (errno == EINTR)) continue; else err(EXIT_FAILURE, "accept"); } len = read(ns, &op, 1); if (len != 1) { if (len < 0) perror("read"); else printf(_("Error reading from client, " "len = %d\n"), len); goto shutdown_socket; } if ((op == UUIDD_OP_BULK_TIME_UUID) || (op == UUIDD_OP_BULK_RANDOM_UUID)) { if (read_all(ns, (char *) &num, sizeof(num)) != 4) goto shutdown_socket; if (debug) printf(_("operation %d, incoming num = %d\n"), op, num); } else if (debug) printf(_("operation %d\n"), op); switch (op) { case UUIDD_OP_GETPID: sprintf(reply_buf, "%d", getpid()); reply_len = strlen(reply_buf) + 1; break; case UUIDD_OP_GET_MAXOP: sprintf(reply_buf, "%d", UUIDD_MAX_OP); reply_len = strlen(reply_buf) + 1; break; case UUIDD_OP_TIME_UUID: num = 1; __uuid_generate_time(uu, &num); if (debug) { uuid_unparse(uu, str); printf(_("Generated time UUID: %s\n"), str); } memcpy(reply_buf, uu, sizeof(uu)); reply_len = sizeof(uu); break; case UUIDD_OP_RANDOM_UUID: num = 1; __uuid_generate_random(uu, &num); if (debug) { uuid_unparse(uu, str); printf(_("Generated random UUID: %s\n"), str); } memcpy(reply_buf, uu, sizeof(uu)); reply_len = sizeof(uu); break; case UUIDD_OP_BULK_TIME_UUID: __uuid_generate_time(uu, &num); if (debug) { uuid_unparse(uu, str); printf(P_("Generated time UUID %s " "and %d following\n", "Generated time UUID %s " "and %d following\n", num - 1), str, num - 1); } memcpy(reply_buf, uu, sizeof(uu)); reply_len = sizeof(uu); memcpy(reply_buf + reply_len, &num, sizeof(num)); reply_len += sizeof(num); break; case UUIDD_OP_BULK_RANDOM_UUID: if (num < 0) num = 1; if (num > 1000) num = 1000; if (num * UUID_LEN > (int) (sizeof(reply_buf) - sizeof(num))) num = (sizeof(reply_buf) - sizeof(num)) / UUID_LEN; __uuid_generate_random((unsigned char *) reply_buf + sizeof(num), &num); if (debug) { printf(P_("Generated %d UUID:\n", "Generated %d UUIDs:\n", num), num); for (i = 0, cp = reply_buf + sizeof(num); i < num; i++, cp += UUID_LEN) { uuid_unparse((unsigned char *)cp, str); printf("\t%s\n", str); } } reply_len = (num * UUID_LEN) + sizeof(num); memcpy(reply_buf, &num, sizeof(num)); break; default: if (debug) printf(_("Invalid operation %d\n"), op); goto shutdown_socket; } write_all(ns, (char *) &reply_len, sizeof(reply_len)); write_all(ns, reply_buf, reply_len); shutdown_socket: close(ns); } }
void client_update(network net, char *address) { int fd = socket_setup(0); struct hostent *hp; /* host information */ struct sockaddr_in server; /* server address */ /* fill in the server's address and data */ bzero((char*)&server, sizeof(server)); server.sin_family = AF_INET; server.sin_port = htons(SERVER_PORT); /* look up the address of the server given its name */ hp = gethostbyname(address); if (!hp) { perror("no such host"); fprintf(stderr, "could not obtain address of %s\n", "localhost"); } /* put the host's address into the server address structure */ memcpy((void *)&server.sin_addr, hp->h_addr_list[0], hp->h_length); if (connect(fd, (struct sockaddr *) &server, sizeof(server)) < 0) { error("error connecting"); } /* send a message to the server */ int i; //printf("Sending\n"); for(i = 0; i < net.n; ++i){ if(net.layers[i].type == CONVOLUTIONAL){ convolutional_layer layer = net.layers[i]; write_all(fd, (char*) layer.bias_updates, layer.n*sizeof(float)); int num = layer.n*layer.c*layer.size*layer.size; write_all(fd, (char*) layer.filter_updates, num*sizeof(float)); memset(layer.bias_updates, 0, layer.n*sizeof(float)); memset(layer.filter_updates, 0, num*sizeof(float)); } if(net.layers[i].type == CONNECTED){ connected_layer layer = net.layers[i]; write_all(fd, (char *)layer.bias_updates, layer.outputs*sizeof(float)); write_all(fd, (char *)layer.weight_updates, layer.outputs*layer.inputs*sizeof(float)); memset(layer.bias_updates, 0, layer.outputs*sizeof(float)); memset(layer.weight_updates, 0, layer.inputs*layer.outputs*sizeof(float)); } } //printf("Sent\n"); for(i = 0; i < net.n; ++i){ if(net.layers[i].type == CONVOLUTIONAL){ convolutional_layer layer = net.layers[i]; read_all(fd, (char*) layer.biases, layer.n*sizeof(float)); int num = layer.n*layer.c*layer.size*layer.size; read_all(fd, (char*) layer.filters, num*sizeof(float)); #ifdef GPU push_convolutional_layer(layer); #endif } if(net.layers[i].type == CONNECTED){ connected_layer layer = net.layers[i]; read_all(fd, (char *)layer.biases, layer.outputs*sizeof(float)); read_all(fd, (char *)layer.weights, layer.outputs*layer.inputs*sizeof(float)); #ifdef GPU push_connected_layer(layer); #endif } } //printf("Updated\n"); close(fd); }
void send() { int readBytes = read_all(sender, data, DATA_SIZE); std::string msg = "read " + std::to_string(readBytes); ensure(readBytes != -1, "Couldn't read sent data", msg.c_str()); write_all(receiver, data, readBytes); }
static ssize_t do_getpass(const char *prompt, char *buf, size_t buflen, int twice, const or_options_t *options) { if (options->keygen_force_passphrase == FORCE_PASSPHRASE_OFF) { tor_assert(buflen); buf[0] = 0; return 0; } char *prompt2 = NULL; char *buf2 = NULL; int fd = -1; ssize_t length = -1; if (options->use_keygen_passphrase_fd) { twice = 0; fd = options->keygen_passphrase_fd; length = read_all(fd, buf, buflen-1, 0); if (length >= 0) buf[length] = 0; goto done_reading; } if (twice) { const char msg[] = "One more time:"; size_t p2len = strlen(prompt) + 1; if (p2len < sizeof(msg)) p2len = sizeof(msg); prompt2 = tor_malloc(strlen(prompt)+1); memset(prompt2, ' ', p2len); memcpy(prompt2 + p2len - sizeof(msg), msg, sizeof(msg)); buf2 = tor_malloc_zero(buflen); } while (1) { length = tor_getpass(prompt, buf, buflen); if (length < 0) goto done_reading; if (! twice) break; ssize_t length2 = tor_getpass(prompt2, buf2, buflen); if (length != length2 || tor_memneq(buf, buf2, length)) { fprintf(stderr, "That didn't match.\n"); } else { break; } } done_reading: if (twice) { tor_free(prompt2); memwipe(buf2, 0, buflen); tor_free(buf2); } if (options->keygen_force_passphrase == FORCE_PASSPHRASE_ON && length == 0) return -1; return length; }
/* * Authenticate the user with the given password. */ static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *request) { rlm_smsotp_t *inst = instance; VALUE_PAIR *state; int bufsize; int *fdp; rlm_rcode_t rcode = RLM_MODULE_FAIL; char buffer[1000]; char output[1000]; fdp = fr_connection_get(inst->pool); if (!fdp) return RLM_MODULE_FAIL; /* Get greeting */ bufsize = read_all(fdp, buffer, sizeof(buffer)); if (bufsize <= 0) { REDEBUG("Failed reading from socket"); goto done; } /* * Look for the 'state' attribute. */ #define WRITE_ALL(_a,_b,_c) if (write_all(_a,_b,_c) < 0) goto done; state = fr_pair_find_by_num(request->packet->vps, PW_STATE, 0, TAG_ANY); if (state) { RDEBUG("Found reply to access challenge"); /* send username */ snprintf(output, sizeof(output), "check otp for %s\n", request->username->vp_strvalue); WRITE_ALL(fdp, output, strlen(output)); (void) read_all(fdp, buffer, sizeof(buffer)); /* send password */ snprintf(output, sizeof(output), "user otp is %s\n", request->password->vp_strvalue); WRITE_ALL(fdp, output, strlen(output)); (void) read_all(fdp, buffer, sizeof(buffer)); /* set uuid */ snprintf(output, sizeof(output), "otp id is %s\n", state->vp_strvalue); WRITE_ALL(fdp, output, strlen(output)); (void) read_all(fdp, buffer, sizeof(buffer)); /* now check the otp */ WRITE_ALL(fdp, "get check result\n", 17); (void) read_all(fdp, buffer, sizeof(buffer)); /* end the sesssion */ WRITE_ALL(fdp, "quit\n", 5); RDEBUG("answer is %s", buffer); if (strcmp(buffer,"OK") == 0) { rcode = RLM_MODULE_OK; } goto done; } RDEBUG("Generating OTP"); /* set username */ snprintf(output, sizeof(output), "generate otp for %s\n", request->username->vp_strvalue); WRITE_ALL(fdp, output, strlen(output)); (void) read_all(fdp, buffer, sizeof(buffer)); /* end the sesssion */ WRITE_ALL(fdp, "quit\n", 5); RDEBUG("Unique ID is %s", buffer); /* check the return string */ if (strcmp(buffer,"FAILED") == 0) { /* smsotp script returns a error */ goto done; } /* * Create the challenge, and add it to the reply. */ pair_make_reply("Reply-Message", inst->challenge, T_OP_EQ); pair_make_reply("State", buffer, T_OP_EQ); /* * Mark the packet as an Access-Challenge packet. * * The server will take care of sending it to the user. */ request->reply->code = PW_CODE_ACCESS_CHALLENGE; DEBUG("rlm_smsotp: Sending Access-Challenge"); rcode = RLM_MODULE_HANDLED; done: fr_connection_release(inst->pool, fdp); return rcode; }
int main(int argc, char **argv) { struct option long_options[] = { {"help", no_argument, NULL, 'h'}, {"legal", no_argument, NULL, 'l'}, {"verbose", no_argument, NULL, 'v'}, {"quiet", no_argument, NULL, 'q'}, {"repl", no_argument, NULL, 'r'}, {"static-fns", no_argument, NULL, 's'}, {"elide-asserts", no_argument, NULL, 'a'}, {"cache", required_argument, NULL, 'k'}, {"eval", required_argument, NULL, 'e'}, {"theme", required_argument, NULL, 't'}, {"classpath", required_argument, NULL, 'c'}, {"auto-cache", no_argument, NULL, 'K'}, {"init", required_argument, NULL, 'i'}, {"main", required_argument, NULL, 'm'}, // development options {"javascript", no_argument, NULL, 'j'}, {"out", required_argument, NULL, 'o'}, {0, 0, 0, 0} }; int opt, option_index; while ((opt = getopt_long(argc, argv, "h?lvrsak:je:t:c:o:Ki:qm:", long_options, &option_index)) != -1) { switch (opt) { case 'h': usage(argv[0]); exit(0); case 'l': legal(); return 0; case 'v': verbose = true; break; case 'q': quiet = true; break; case 'r': repl = true; break; case 's': static_fns = true; break; case 'a': elide_asserts = true; break; case 'k': cache_path = argv[optind - 1]; break; case 'K': cache_path = ".planck_cache"; { char *path_copy = strdup(cache_path); char *dir = dirname(path_copy); if (mkdir_p(dir) < 0) { fprintf(stderr, "Could not create %s: %s\n", cache_path, strerror(errno)); } free(path_copy); } break; case 'j': javascript = true; break; case 'e': num_scripts += 1; scripts = realloc(scripts, num_scripts * sizeof(struct script)); scripts[num_scripts - 1].type = "text"; scripts[num_scripts - 1].expression = true; scripts[num_scripts - 1].source = argv[optind - 1]; break; case 'i': num_scripts += 1; scripts = realloc(scripts, num_scripts * sizeof(struct script)); scripts[num_scripts - 1].type = "path"; scripts[num_scripts - 1].expression = false; scripts[num_scripts - 1].source = argv[optind - 1]; break; case 'm': main_ns_name = argv[optind - 1]; case 't': theme = argv[optind - 1]; break; case 'c': { char *classpath = argv[optind - 1]; char *source = strtok(classpath, ":"); while (source != NULL) { char *type = "src"; if (str_has_suffix(source, ".jar") == 0) { type = "jar"; } num_src_paths += 1; src_paths = realloc(src_paths, num_src_paths * sizeof(struct src_path)); src_paths[num_src_paths - 1].type = type; src_paths[num_src_paths - 1].path = strdup(source); source = strtok(NULL, ":"); } break; } case 'o': out_path = argv[optind - 1]; break; case '?': usage(argv[0]); exit(1); default: printf("unhandled argument: %c\n", opt); } } int num_rest_args = 0; char **rest_args = NULL; if (optind < argc) { num_rest_args = argc - optind; rest_args = malloc((argc - optind) * sizeof(char*)); int i = 0; while (optind < argc) { rest_args[i++] = argv[optind++]; } } if (num_scripts == 0 && main_ns_name == NULL && num_rest_args == 0) { repl = true; } if (main_ns_name != NULL && repl) { printf("Only one main-opt can be specified."); } JSGlobalContextRef ctx = JSGlobalContextCreate(NULL); JSStringRef nameRef = JSStringCreateWithUTF8CString("planck"); JSGlobalContextSetName(ctx, nameRef); evaluate_script(ctx, "var global = this;", "<init>"); register_global_function(ctx, "AMBLY_IMPORT_SCRIPT", function_import_script); bootstrap(ctx, out_path); register_global_function(ctx, "PLANCK_CONSOLE_LOG", function_console_log); register_global_function(ctx, "PLANCK_CONSOLE_ERROR", function_console_error); evaluate_script(ctx, "var console = {};"\ "console.log = PLANCK_CONSOLE_LOG;"\ "console.error = PLANCK_CONSOLE_ERROR;", "<init>"); evaluate_script(ctx, "var PLANCK_VERSION = \"" PLANCK_VERSION "\";", "<init>"); // require app namespaces evaluate_script(ctx, "goog.require('planck.repl');", "<init>"); // without this things won't work evaluate_script(ctx, "var window = global;", "<init>"); register_global_function(ctx, "PLANCK_READ_FILE", function_read_file); register_global_function(ctx, "PLANCK_LOAD", function_load); register_global_function(ctx, "PLANCK_LOAD_DEPS_CLJS_FILES", function_load_deps_cljs_files); register_global_function(ctx, "PLANCK_CACHE", function_cache); register_global_function(ctx, "PLANCK_EVAL", function_eval); register_global_function(ctx, "PLANCK_GET_TERM_SIZE", function_get_term_size); register_global_function(ctx, "PLANCK_PRINT_FN", function_print_fn); register_global_function(ctx, "PLANCK_PRINT_ERR_FN", function_print_err_fn); register_global_function(ctx, "PLANCK_SET_EXIT_VALUE", function_set_exit_value); is_tty = isatty(STDIN_FILENO) == 1; register_global_function(ctx, "PLANCK_RAW_READ_STDIN", function_raw_read_stdin); register_global_function(ctx, "PLANCK_RAW_WRITE_STDOUT", function_raw_write_stdout); register_global_function(ctx, "PLANCK_RAW_FLUSH_STDOUT", function_raw_flush_stdout); register_global_function(ctx, "PLANCK_RAW_WRITE_STDERR", function_raw_write_stderr); register_global_function(ctx, "PLANCK_RAW_FLUSH_STDERR", function_raw_flush_stderr); { JSValueRef arguments[num_rest_args]; for (int i = 0; i < num_rest_args; i++) { arguments[i] = c_string_to_value(ctx, rest_args[i]); } JSValueRef args_ref = JSObjectMakeArray(ctx, num_rest_args, arguments, NULL); JSValueRef global_obj = JSContextGetGlobalObject(ctx); JSStringRef prop = JSStringCreateWithUTF8CString("PLANCK_INITIAL_COMMAND_LINE_ARGS"); JSObjectSetProperty(ctx, JSValueToObject(ctx, global_obj, NULL), prop, args_ref, kJSPropertyAttributeNone, NULL); JSStringRelease(prop); } evaluate_script(ctx, "cljs.core.set_print_fn_BANG_.call(null,PLANCK_PRINT_FN);", "<init>"); evaluate_script(ctx, "cljs.core.set_print_err_fn_BANG_.call(null,PLANCK_PRINT_ERR_FN);", "<init>"); char *elide_script = str_concat("cljs.core._STAR_assert_STAR_ = ", elide_asserts ? "false" : "true"); evaluate_script(ctx, elide_script, "<init>"); free(elide_script); { JSValueRef arguments[4]; arguments[0] = JSValueMakeBoolean(ctx, repl); arguments[1] = JSValueMakeBoolean(ctx, verbose); JSValueRef cache_path_ref = NULL; if (cache_path != NULL) { JSStringRef cache_path_str = JSStringCreateWithUTF8CString(cache_path); cache_path_ref = JSValueMakeString(ctx, cache_path_str); } arguments[2] = cache_path_ref; arguments[3] = JSValueMakeBoolean(ctx, static_fns); JSValueRef ex = NULL; JSObjectCallAsFunction(ctx, get_function(ctx, "planck.repl", "init"), JSContextGetGlobalObject(ctx), 4, arguments, &ex); debug_print_value("planck.repl/init", ctx, ex); } if (repl) { evaluate_source(ctx, "text", "(require '[planck.repl :refer-macros [apropos dir find-doc doc source pst]])", true, false, "cljs.user", "dumb"); } evaluate_script(ctx, "goog.provide('cljs.user');", "<init>"); evaluate_script(ctx, "goog.require('cljs.core');", "<init>"); evaluate_script(ctx, "cljs.core._STAR_assert_STAR_ = true;", "<init>"); // Process init arguments for (int i = 0; i < num_scripts; i++) { // TODO: exit if not successfull evaluate_source(ctx, scripts[i].type, scripts[i].source, scripts[i].expression, false, NULL, theme); } // Process main arguments if (main_ns_name != NULL) { run_main_in_ns(ctx, main_ns_name, num_rest_args, rest_args); } else if (!repl && num_rest_args > 0) { char *path = rest_args[0]; struct script script; if (strcmp(path, "-") == 0) { char *source = read_all(stdin); script.type = "text"; script.source = source; script.expression = false; } else { script.type = "path"; script.source = path; script.expression = false; } evaluate_source(ctx, script.type, script.source, script.expression, false, NULL, theme); } else if (repl) { if (!quiet) { banner(); } char *home = getenv("HOME"); char *history_path = NULL; if (home != NULL) { char history_name[] = ".planck_history"; int len = strlen(home) + strlen(history_name) + 2; history_path = malloc(len * sizeof(char)); snprintf(history_path, len, "%s/%s", home, history_name); linenoiseHistoryLoad(history_path); } char *prompt = javascript ? " > " : " => "; char *line; while ((line = linenoise(prompt)) != NULL) { if (javascript) { JSValueRef res = evaluate_script(ctx, line, "<stdin>"); print_value("", ctx, res); } else { evaluate_source(ctx, "text", line, true, true, "cljs.user", theme); } linenoiseHistoryAdd(line); if (history_path != NULL) { linenoiseHistorySave(history_path); } free(line); } } return exit_value; }
/** * main function - for clone or restore data */ int main(int argc, char **argv) { #ifdef MEMTRACE setenv("MALLOC_TRACE", "partclone_mtrace.log", 1); mtrace(); #endif char* source; /// source data char* target; /// target data int dfr, dfw; /// file descriptor for source and target int r_size, w_size; /// read and write size unsigned cs_size = 0; /// checksum_size int start, stop; /// start, range, stop number for progress bar unsigned long *bitmap = NULL; /// the point for bitmap data int debug = 0; /// debug level int tui = 0; /// text user interface int pui = 0; /// progress mode(default text) int flag; int pres = 0; pthread_t prog_thread; void *p_result; static const char *const bad_sectors_warning_msg = "*************************************************************************\n" "* WARNING: The disk has bad sectors. This means physical damage on the *\n" "* disk surface caused by deterioration, manufacturing faults, or *\n" "* another reason. The reliability of the disk may remain stable or *\n" "* degrade quickly. Use the --rescue option to efficiently save as much *\n" "* data as possible! *\n" "*************************************************************************\n"; file_system_info fs_info; /// description of the file system image_options img_opt; init_fs_info(&fs_info); init_image_options(&img_opt); /** * get option and assign to opt structure * check parameter and read from argv */ parse_options(argc, argv, &opt); /** * if "-d / --debug" given * open debug file in "/var/log/partclone.log" for log message */ memset(&fs_opt, 0, sizeof(fs_cmd_opt)); debug = opt.debug; fs_opt.debug = debug; fs_opt.ignore_fschk = opt.ignore_fschk; //if(opt.debug) open_log(opt.logfile); /** * using Text User Interface */ if (opt.ncurses) { pui = NCURSES; log_mesg(1, 0, 0, debug, "Using Ncurses User Interface mode.\n"); } else pui = TEXT; tui = open_pui(pui, opt.fresh); if ((opt.ncurses) && (!tui)) { opt.ncurses = 0; pui = TEXT; log_mesg(1, 0, 0, debug, "Open Ncurses User Interface Error.\n"); } /// print partclone info print_partclone_info(opt); #ifndef CHKIMG if (geteuid() != 0) log_mesg(0, 1, 1, debug, "You are not logged as root. You may have \"access denied\" errors when working.\n"); else log_mesg(1, 0, 0, debug, "UID is root.\n"); #endif /// ignore crc check if (opt.ignore_crc) log_mesg(1, 0, 1, debug, "Ignore CRC errors\n"); /** * open source and target * clone mode, source is device and target is image file/stdout * restore mode, source is image file/stdin and target is device * dd mode, source is device and target is device !!not complete */ source = opt.source; target = opt.target; log_mesg(1, 0, 0, debug, "source=%s, target=%s \n", source, target); dfr = open_source(source, &opt); if (dfr == -1) { log_mesg(0, 1, 1, debug, "Error exit\n"); } #ifndef CHKIMG dfw = open_target(target, &opt); if (dfw == -1) { log_mesg(0, 1, 1, debug, "Error exit\n"); } #else dfw = -1; #endif /** * get partition information like super block, bitmap from device or image file. */ if (opt.clone) { log_mesg(1, 0, 0, debug, "Initiate image options - version %s\n", IMAGE_VERSION_CURRENT); img_opt.checksum_mode = opt.checksum_mode; img_opt.checksum_size = get_checksum_size(opt.checksum_mode, opt.debug); img_opt.blocks_per_checksum = opt.blocks_per_checksum; cs_size = img_opt.checksum_size; log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n"); log_mesg(0, 0, 1, debug, "Reading Super Block\n"); /// get Super Block information from partition read_super_blocks(source, &fs_info); if (img_opt.checksum_mode != CSM_NONE && img_opt.blocks_per_checksum == 0) { const unsigned int buffer_capacity = opt.buffer_size > fs_info.block_size ? opt.buffer_size / fs_info.block_size : 1; // in blocks img_opt.blocks_per_checksum = buffer_capacity; } log_mesg(1, 0, 0, debug, "%u blocks per checksum\n", img_opt.blocks_per_checksum); check_mem_size(fs_info, img_opt, opt); /// alloc a memory to store bitmap bitmap = pc_alloc_bitmap(fs_info.totalblock); if (bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from partition log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... \n"); read_bitmap(source, fs_info, bitmap, pui); update_used_blocks_count(&fs_info, bitmap); if (opt.check) { unsigned long long needed_space = 0; needed_space += sizeof(image_head) + sizeof(file_system_info) + sizeof(image_options); needed_space += get_bitmap_size_on_disk(&fs_info, &img_opt, &opt); needed_space += cnv_blocks_to_bytes(fs_info.usedblocks, fs_info.block_size, &img_opt); check_free_space(&dfw, needed_space); } log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Writing super block and bitmap...\n"); write_image_desc(&dfw, fs_info, img_opt, &opt); write_image_bitmap(&dfw, fs_info, img_opt, bitmap, &opt); log_mesg(0, 0, 1, debug, "done!\n"); } else if (opt.restore) { log_mesg(1, 0, 0, debug, "restore image hdr - get information from image file\n"); log_mesg(1, 0, 1, debug, "Reading Super Block\n"); /// get image information from image file load_image_desc(&dfr, &opt, &fs_info, &img_opt); cs_size = img_opt.checksum_size; check_mem_size(fs_info, img_opt, opt); /// alloc a memory to restore bitmap bitmap = pc_alloc_bitmap(fs_info.totalblock); if (bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from image file log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait...\n"); load_image_bitmap(&dfr, opt, fs_info, img_opt, bitmap); #ifndef CHKIMG /// check the dest partition size. if (opt.restore_raw_file) check_free_space(&dfw, fs_info.device_size); else if (opt.check) check_size(&dfw, fs_info.device_size); #endif log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); } else if (opt.dd || opt.domain) { log_mesg(1, 0, 0, debug, "Initial image hdr - get Super Block from partition\n"); log_mesg(1, 0, 1, debug, "Reading Super Block\n"); /// get Super Block information from partition read_super_blocks(source, &fs_info); check_mem_size(fs_info, img_opt, opt); /// alloc a memory to restore bitmap bitmap = pc_alloc_bitmap(fs_info.totalblock); if (bitmap == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } log_mesg(2, 0, 0, debug, "initial main bitmap pointer %p\n", bitmap); log_mesg(1, 0, 0, debug, "Initial image hdr - read bitmap table\n"); /// read and check bitmap from partition log_mesg(0, 0, 1, debug, "Calculating bitmap... Please wait... "); read_bitmap(source, fs_info, bitmap, pui); /// check the dest partition size. if (opt.dd && opt.check) { check_size(&dfw, fs_info.device_size); } log_mesg(2, 0, 0, debug, "check main bitmap pointer %p\n", bitmap); log_mesg(0, 0, 1, debug, "done!\n"); } log_mesg(1, 0, 0, debug, "print image information\n"); /// print option to log file if (debug) print_opt(opt); print_file_system_info(fs_info, opt); /** * initial progress bar */ start = 0; /// start number of progress bar stop = (fs_info.usedblocks); /// get the end of progress number, only used block log_mesg(1, 0, 0, debug, "Initial Progress bar\n"); /// Initial progress bar if (opt.no_block_detail) flag = NO_BLOCK_DETAIL; else flag = IO; progress_init(&prog, start, stop, fs_info.totalblock, flag, fs_info.block_size); copied = 0; /// initial number is 0 /** * thread to print progress */ pres = pthread_create(&prog_thread, NULL, thread_update_pui, NULL); if(pres) log_mesg(0, 1, 1, debug, "%s, %i, thread create error\n", __func__, __LINE__); /** * start read and write data between source and destination */ if (opt.clone) { const unsigned long long blocks_total = fs_info.totalblock; const unsigned int block_size = fs_info.block_size; const unsigned int buffer_capacity = opt.buffer_size > block_size ? opt.buffer_size / block_size : 1; // in blocks unsigned char checksum[cs_size]; unsigned int blocks_in_cs, blocks_per_cs, write_size; char *read_buffer, *write_buffer; blocks_per_cs = img_opt.blocks_per_checksum; log_mesg(1, 0, 0, debug, "#\nBuffer capacity = %u, Blocks per cs = %u\n#\n", buffer_capacity, blocks_per_cs); write_size = cnv_blocks_to_bytes(buffer_capacity, block_size, &img_opt); read_buffer = (char*)malloc(buffer_capacity * block_size); write_buffer = (char*)malloc(write_size + cs_size); if (read_buffer == NULL || write_buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } /// read data from the first block if (lseek(dfr, 0, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno)); log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total); /// start clone partition to image file log_mesg(1, 0, 0, debug, "start backup data...\n"); blocks_in_cs = 0; init_checksum(img_opt.checksum_mode, checksum, debug); block_id = 0; do { /// scan bitmap unsigned long long i, blocks_skip, blocks_read; unsigned int cs_added = 0, write_offset = 0; off_t offset; /// skip unused blocks for (blocks_skip = 0; block_id + blocks_skip < blocks_total && !pc_test_bit(block_id + blocks_skip, bitmap); blocks_skip++); if (block_id + blocks_skip == blocks_total) break; if (blocks_skip) block_id += blocks_skip; /// read blocks for (blocks_read = 0; block_id + blocks_read < blocks_total && blocks_read < buffer_capacity && pc_test_bit(block_id + blocks_read, bitmap); ++blocks_read); if (!blocks_read) break; offset = (off_t)(block_id * block_size); if (lseek(dfr, offset, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno)); r_size = read_all(&dfr, read_buffer, blocks_read * block_size, &opt); if (r_size != (int)(blocks_read * block_size)) { if ((r_size == -1) && (errno == EIO)) { if (opt.rescue) { memset(read_buffer, 0, blocks_read * block_size); for (r_size = 0; r_size < blocks_read * block_size; r_size += PART_SECTOR_SIZE) rescue_sector(&dfr, offset + r_size, read_buffer + r_size, &opt); } else log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg); } else log_mesg(0, 1, 1, debug, "read error: %s\n", strerror(errno)); } /// calculate checksum for (i = 0; i < blocks_read; ++i) { memcpy(write_buffer + write_offset, read_buffer + i * block_size, block_size); write_offset += block_size; update_checksum(checksum, read_buffer + i * block_size, block_size); if (blocks_per_cs > 0 && ++blocks_in_cs == blocks_per_cs) { memcpy(write_buffer + write_offset, checksum, cs_size); ++cs_added; write_offset += cs_size; blocks_in_cs = 0; if (opt.reseed_checksum) init_checksum(img_opt.checksum_mode, checksum, debug); } } /// write buffer to target w_size = write_all(&dfw, write_buffer, write_offset, &opt); if (w_size != write_offset) log_mesg(0, 1, 1, debug, "image write ERROR:%s\n", strerror(errno)); /// count copied block copied += blocks_read; /// next block block_id += blocks_read; /// read or write error if (r_size + cs_added * cs_size != w_size) log_mesg(0, 1, 1, debug, "read(%i) and write(%i) different\n", r_size, w_size); } while (1); if (blocks_in_cs > 0) { // Write the checksum for the latest blocks w_size = write_all(&dfw, (char*)checksum, cs_size, &opt); if (w_size != cs_size) log_mesg(0, 1, 1, debug, "image write ERROR:%s\n", strerror(errno)); } free(write_buffer); free(read_buffer); } else if (opt.restore) { const unsigned long long blocks_total = fs_info.totalblock; const unsigned int block_size = fs_info.block_size; const unsigned int buffer_capacity = opt.buffer_size > block_size ? opt.buffer_size / block_size : 1; // in blocks const unsigned int blocks_per_cs = img_opt.blocks_per_checksum; unsigned long long blocks_used = fs_info.usedblocks; unsigned int blocks_in_cs, buffer_size, read_offset; unsigned char checksum[cs_size]; char *read_buffer, *write_buffer; int bugcheck = 0; unsigned long long blocks_used_fix = 0, test_block = 0; log_mesg(1, 0, 0, debug, "#\nBuffer capacity = %u, Blocks per cs = %u\n#\n", buffer_capacity, blocks_per_cs); // fix some super block record incorrect for (test_block = 0; test_block < blocks_total; ++test_block) if (pc_test_bit(test_block, bitmap)) blocks_used_fix++; if (blocks_used_fix != blocks_used) { blocks_used = blocks_used_fix; log_mesg(1, 0, 0, debug, "info: fixed used blocks count\n"); } buffer_size = cnv_blocks_to_bytes(buffer_capacity, block_size, &img_opt); if (img_opt.image_version != 0x0001) read_buffer = (char*)malloc(buffer_size + cs_size); else { // Allocate more memory in case the image is affected by the 64 bits bug read_buffer = (char*)malloc(buffer_size + buffer_capacity * cs_size); } write_buffer = (char*)malloc(buffer_capacity * block_size); if (read_buffer == NULL || write_buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } #ifndef CHKIMG /// seek to the first if (lseek(dfw, opt.offset, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno)); #endif /// start restore image file to partition log_mesg(1, 0, 0, debug, "start restore data...\n"); blocks_in_cs = 0; init_checksum(img_opt.checksum_mode, checksum, debug); block_id = 0; do { unsigned int i; unsigned char cs_saved[cs_size]; unsigned long long blocks_written, bytes_skip; unsigned int read_size; // max chunk to read using one read(2) syscall int blocks_read = copied + buffer_capacity < blocks_used ? buffer_capacity : blocks_used - copied; if (!blocks_read) break; read_offset = bugcheck ? 4 : 0; log_mesg(1, 0, 0, debug, "blocks_read = %d\n", blocks_read); read_size = cnv_blocks_to_bytes(blocks_read, block_size, &img_opt); // increase read_size to make room for the checksum if (blocks_per_cs > 0) { if (bugcheck) { read_size += blocks_read * cs_size; } else if (blocks_read % blocks_per_cs) { // adjust read_size to read the right number of checksum unsigned long total_cs = get_checksum_count(copied + blocks_read, &img_opt); unsigned long copied_cs = get_checksum_count(copied, &img_opt); unsigned long newer_cs = get_checksum_count(blocks_read, &img_opt); unsigned long extra_cs = total_cs - copied_cs - newer_cs; if ((blocks_read < buffer_capacity) && (blocks_used % blocks_per_cs)) { // it is the last read and there is a partial chunk at the end ++extra_cs; } read_size += extra_cs * cs_size; log_mesg(1, 0, 0, debug, "# extra cs = %u\n", extra_cs); } } // read chunk from image log_mesg(1, 0, 0, debug, "read more: "); r_size = read_all(&dfr, read_buffer, read_size, &opt); if (r_size != read_size) log_mesg(0, 1, 1, debug, "read ERROR:%s\n", strerror(errno)); // read buffer is the follows: // <blocks_per_cs><cs1><blocks_per_cs><cs2>... // write buffer should be the following: // <block1><block2>... // fill up write buffer, validate checksum recheck: memcpy(cs_saved, checksum, cs_size); for (i = 0; i < blocks_read; ++i) { memcpy(write_buffer + i * block_size, read_buffer + read_offset, block_size); if (opt.ignore_crc) { read_offset += block_size; if (++blocks_in_cs == blocks_per_cs) read_offset += cs_size; continue; } update_checksum(checksum, read_buffer + read_offset, block_size); if (++blocks_in_cs == blocks_per_cs) { if (memcmp(read_buffer + read_offset + block_size, checksum, cs_size)) { if (bugcheck || img_opt.image_version != 0x0001) log_mesg(0, 1, 1, debug, "CRC error, block_id=%llu...\n ", block_id + i); else { log_mesg(1, 0, 0, debug, "CRC Check error. 64bit bug before v0.1.0 (Rev:250M), " "trying enlarge crc size and recheck again...\n"); // the bug has written the crc with 4 extra bytes, so the read buffer is like this: // <block1><crc1><bug><block2><crc2><bug>... read_offset += 4; blocks_in_cs -= 1; bugcheck = 1; memcpy(checksum, cs_saved, cs_size); goto recheck; } } read_offset += cs_size; if (bugcheck) read_offset += cs_size; blocks_in_cs = 0; if (opt.reseed_checksum) init_checksum(img_opt.checksum_mode, checksum, debug); } read_offset += block_size; } blocks_written = 0; do { int blocks_write; /// count bytes to skip for (bytes_skip = 0; block_id < blocks_total && !pc_test_bit(block_id, bitmap); block_id++, bytes_skip += block_size); #ifndef CHKIMG /// skip empty blocks if (bytes_skip > 0 && lseek(dfw, (off_t)bytes_skip, SEEK_CUR) == (off_t)-1) log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno)); #endif /// blocks to write for (blocks_write = 0; block_id + blocks_write < blocks_total && blocks_written + blocks_write < blocks_read && pc_test_bit(block_id + blocks_write, bitmap); blocks_write++); #ifndef CHKIMG // write blocks if (blocks_write > 0) { w_size = write_all(&dfw, write_buffer + blocks_written * block_size, blocks_write * block_size, &opt); if (w_size != blocks_write * block_size) { if (!opt.skip_write_error) log_mesg(0, 1, 1, debug, "write block %llu ERROR:%s\n", block_id + blocks_written, strerror(errno)); else log_mesg(0, 0, 1, debug, "skip write block %llu error:%s\n", block_id + blocks_written, strerror(errno)); } } #endif blocks_written += blocks_write; block_id += blocks_write; copied += blocks_write; } while (blocks_written < blocks_read); } while(1); if (blocks_in_cs) { log_mesg(1, 0, 0, debug, "check latest chunk's checksum covering %u blocks\n", blocks_in_cs); if (memcmp(read_buffer + read_offset, checksum, cs_size)) log_mesg(0, 1, 1, debug, "CRC error, block_id=%llu...\n ", block_id); } free(write_buffer); free(read_buffer); #ifndef CHKIMG /// restore_raw_file option if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, bitmap)) { if (ftruncate(dfw, (off_t)(blocks_total * block_size)) == -1) log_mesg(0, 0, 1, debug, "ftruncate ERROR:%s\n", strerror(errno)); } #endif } else if (opt.dd) { char *buffer; int block_size = fs_info.block_size; unsigned long long blocks_total = fs_info.totalblock; int buffer_capacity = block_size < opt.buffer_size ? opt.buffer_size / block_size : 1; buffer = (char*)malloc(buffer_capacity * block_size); if (buffer == NULL) { log_mesg(0, 1, 1, debug, "%s, %i, not enough memory\n", __func__, __LINE__); } block_id = 0; if (lseek(dfr, 0, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR:%d\n", strerror(errno)); log_mesg(0, 0, 0, debug, "Total block %llu\n", blocks_total); /// start clone partition to partition log_mesg(1, 0, 0, debug, "start backup data device-to-device...\n"); do { /// scan bitmap unsigned long long blocks_skip, blocks_read; off_t offset; /// skip unused blocks for (blocks_skip = 0; block_id + blocks_skip < blocks_total && !pc_test_bit(block_id + blocks_skip, bitmap); blocks_skip++); if (block_id + blocks_skip == blocks_total) break; if (blocks_skip) block_id += blocks_skip; /// read chunk from source for (blocks_read = 0; block_id + blocks_read < blocks_total && blocks_read < buffer_capacity && pc_test_bit(block_id + blocks_read, bitmap); ++blocks_read); if (!blocks_read) break; offset = (off_t)(block_id * block_size); if (lseek(dfr, offset, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "source seek ERROR:%s\n", strerror(errno)); if (lseek(dfw, offset + opt.offset, SEEK_SET) == (off_t)-1) log_mesg(0, 1, 1, debug, "target seek ERROR:%s\n", strerror(errno)); r_size = read_all(&dfr, buffer, blocks_read * block_size, &opt); if (r_size != (int)(blocks_read * block_size)) { if ((r_size == -1) && (errno == EIO)) { if (opt.rescue) { memset(buffer, 0, blocks_read * block_size); for (r_size = 0; r_size < blocks_read * block_size; r_size += PART_SECTOR_SIZE) rescue_sector(&dfr, offset + r_size, buffer + r_size, &opt); } else log_mesg(0, 1, 1, debug, "%s", bad_sectors_warning_msg); } else log_mesg(0, 1, 1, debug, "source read ERROR %s\n", strerror(errno)); } /// write buffer to target w_size = write_all(&dfw, buffer, blocks_read * block_size, &opt); if (w_size != (int)(blocks_read * block_size)) { if (opt.skip_write_error) log_mesg(0, 0, 1, debug, "skip write block %lli error:%s\n", block_id, strerror(errno)); else log_mesg(0, 1, 1, debug, "write block %lli ERROR:%s\n", block_id, strerror(errno)); } /// count copied block copied += blocks_read; /// next block block_id += blocks_read; /// read or write error if (r_size != w_size) { if (opt.skip_write_error) log_mesg(0, 0, 1, debug, "read and write different\n"); else log_mesg(0, 1, 1, debug, "read and write different\n"); } } while (1); free(buffer); /// restore_raw_file option if (opt.restore_raw_file && !pc_test_bit(blocks_total - 1, bitmap)) { if (ftruncate(dfw, (off_t)(blocks_total * block_size)) == -1) log_mesg(0, 0, 1, debug, "ftruncate ERROR:%s\n", strerror(errno)); } } else if (opt.domain) { int cmp, nx_current = 0; unsigned long long next_block_id = 0; log_mesg(0, 0, 0, debug, "Total block %i\n", fs_info.totalblock); log_mesg(1, 0, 0, debug, "start writing domain log...\n"); // write domain log comment and status line dprintf(dfw, "# Domain logfile created by %s v%s\n", EXECNAME, VERSION); dprintf(dfw, "# Source: %s\n", opt.source); dprintf(dfw, "# Offset: 0x%08llX\n", opt.offset_domain); dprintf(dfw, "# current_pos current_status\n"); dprintf(dfw, "0x%08llX ?\n", opt.offset_domain + (fs_info.totalblock * fs_info.block_size)); dprintf(dfw, "# pos size status\n"); // start logging the used/unused areas cmp = pc_test_bit(0, bitmap); for (block_id = 0; block_id <= fs_info.totalblock; block_id++) { if (block_id < fs_info.totalblock) { nx_current = pc_test_bit(block_id, bitmap); if (nx_current) copied++; } else nx_current = -1; if (nx_current != cmp) { dprintf(dfw, "0x%08llX 0x%08llX %c\n", opt.offset_domain + (next_block_id * fs_info.block_size), (block_id - next_block_id) * fs_info.block_size, cmp ? '+' : '?'); next_block_id = block_id; cmp = nx_current; } // don't bother updating progress } /// end of for } done = 1; pres = pthread_join(prog_thread, &p_result); if(pres) log_mesg(0, 1, 1, debug, "%s, %i, thread join error\n", __func__, __LINE__); update_pui(&prog, copied, block_id, done); #ifndef CHKIMG sync_data(dfw, &opt); #endif print_finish_info(opt); /// close source close(dfr); /// close target if (dfw != -1) close(dfw); /// free bitmp free(bitmap); close_pui(pui); #ifndef CHKIMG fprintf(stderr, "Cloned successfully.\n"); #else printf("Checked successfully.\n"); #endif if (opt.debug) close_log(); #ifdef MEMTRACE muntrace(); #endif return 0; /// finish }