示例#1
0
Static Stmt *proc_fwritebytes()
{
    Expr *ex, *ex2, *vex, *fex;
    Type *type;

    if (!skipopenparen())
	return NULL;
    fex = p_expr(tp_text);
    if (!skipcomma())
	return NULL;
    vex = p_expr(NULL);
    if (!skipcomma())
	return NULL;
    ex2 = p_expr(tp_integer);
    skipcloseparen();
    type = vex->val.type;
    ex = makeexpr_bicall_4("fwrite", tp_integer,
                           makeexpr_addr(vex),
                           convert_size(type, ex2, "FWRITEBYTES"),
                           makeexpr_long(1),
                           filebasename(copyexpr(fex)));
    if (checkfilewrite) {
        ex = makeexpr_bicall_2(name_SETIO, tp_void,
                               makeexpr_rel(EK_EQ, ex, makeexpr_long(1)),
                               makeexpr_long(3));
    }
    return wrapopencheck(makestmt_call(ex), fex);
}
示例#2
0
void main(){
	//ouverture 
	int fd ;
	fd = open("/home/marms/Documents/ASR/C/TP5/x.mp3", O_CREAT |  O_RDONLY, 0666 );
    if( fd == -1 ){
    	printf("erreur ouverture\n");
    	exit(15);
    }	
	
  	printf("\n====ESSAIS PERMUTE======\n");
	  
	  	u16 *x= (u16*)malloc(sizeof(u16)); 
	  	*x=0x4244;//BD
	 	affiche_u16(x);
		permut2(x); //DB 
		affiche_u16(x);
		printf("x, %0x\n",*x);

		u32* g= (u32*)malloc(sizeof(u32));
		*g=0x10203040;
		permut4(g);			
	 	printf("g, %0x\n",*g);
	printf("\n======FIN PERMUTE=======\n");
  
	u8* a = (u8*) malloc(sizeof(u8));
	if(! read_u8(fd,a)){ printf("echec3\n");}
	affiche_u8(a);


	u16* e = (u16*) malloc(sizeof(u16));
	if(! read_u16(fd,e)){ printf("echec3\n");}
	affiche_u16(e);
	
	u32* f = (u32*) malloc(sizeof(u32));
	if(! read_u32(fd,f)){ printf("echec4\n");}
	affiche_u32(f);	



		*h = 0x6d776e6e ; 
		affiche_u32(h);
		aff_bin((u8*)h);	 printf("\n"); 
	    *h=	convert_size(*h);
		aff_bin((u8*)h); printf("\n"); 
	//fermeture
    close(fd);
}
示例#3
0
int tag_read_id3_header(int fd, id3v2_header_t *header)
{
	if(strcmp("ID3", read_string(fd, header->ID3, 3, 0)))
		return -1;

	if(!read_u16(fd, &(header->version)))
		return -1;

	// version valide
	if(header->version > 0x0300)
		return -1;

	if(!read_u8(fd, &(header->flags)))
		return -1;

	if(!read_u32(fd, &(header->size)))
		return -1;

	header->size = convert_size(header->size);
	return 0;
}
示例#4
0
int tag_read_id3_header(int fd, id3v2_header_t *header)
{
	if(strcmp("ID3", read_string(fd, header->ID3, 3, 0)) != 0)
	{
		printf("titi1");
		return -1;
	}


	if(!read_u16(fd, &(header->version)))
	{
		printf("titi2");
		return -1;
	}

	// version valide
	if(header->version > 0x0300)
	{
		printf("titi3");
		return -1;
	}

	if(!read_u8(fd, &(header->flags)))
	{
		printf("titi4");
		return -1;
	}

	if(!read_u32(fd, &(header->size)))
	{
		printf("titi5");
		return -1;
	}

	header->size = convert_size(header->size);
	return 0;
}
示例#5
0
文件: tag_test.c 项目: haderer/IDV3v2
void test_converts(){

	assertTrue_byte("Convert Size", convert_size(1836543598),230553454);
	assertTrue_byte("Convert Size", convert_size(17782),8950);
}
示例#6
0
文件: main.c 项目: proffK/fusesfs
int main(int argc, char* argv[]) {
        int opt = 0;
        struct sfs_options sfs_opts;
        /* Service variables */
        size_t rsrvd_size       = MBR_SIZE;
        size_t index_size       = 0;
        size_t block_size       = 0;
        size_t total_blocks     = 0;
        size_t index_sz_perblk  = 0;
        off_t  file_size        = 0;
        char*  index_size_s     = NULL;
        char*  block_size_s     = NULL;
        char*  label            = NULL;
        /* Struct for getopt_long */
        static struct option const long_options[] = {
                {"help", no_argument, NULL, 'h'},
                {"metadata", required_argument, NULL, 'm'},
                {"block-size", required_argument, NULL, 'b'},
                {"label", required_argument, NULL, 'l'},
                {"version", no_argument, NULL, 'v'},
                {NULL, 0, NULL, 0}
        };
        if (argc == 1) {
                fprintf(stderr, "No parameters.\n");
                usage(EXIT_FAILURE);
        }
        /* Get user options */
        while ((opt = getopt_long(argc - 1, argv, "hm:b:l:", 
                long_options, NULL)) != -1) {
                switch (opt) {    
                case 'h':
                        usage(EXIT_SUCCESS);
                        break;
                case 'm':
                        index_size_s = optarg; 
                        break;
                case 'b':
                        block_size_s = optarg;
                        break;
                case 'l':
                        label = optarg;
                        break;
                case 'v':
                        usage(EXIT_SUCCESS);
                        break; 
                default:
                        usage(EXIT_FAILURE);
                }                     
        }
        /* 
         * Try to open file 
         */
        int fd = open(argv[argc - 1], O_RDWR);
        if (fd == -1 && argc == 2) 
                usage(EXIT_SUCCESS);

        if (fd == -1) {
                fprintf(stderr, "Invalid input file/device.\n");
                usage(EXIT_INPFILE);
        }
        /*
         * File size calculate and check it
         */
        file_size = lseek(fd, 0, SEEK_END);
        close(fd);
        if (file_size < (MBR_SIZE + INDEX_MIN_SIZE)) {
                fprintf(stderr, "Too small file size.\n");
                fprintf(stderr, "%s %luB\n", "The smallest file size is", 
                                             MBR_SIZE + INDEX_MIN_SIZE);
                exit(EXIT_FILELRG);
        }
        /* 
         * Handler blocksize data 
         */ 
        if (block_size_s == NULL) 
                block_size = DEFAULT_BLOCK_SIZE;
        else {
                block_size = convert_size(block_size_s, 0);
                /* block size must be greater than 128B */
                if (block_size <= DEFAULT_MIN_BLOCK/2 || errno == EINVAL) {
                        fprintf(stderr, "Invalid block size.\n");
                        usage(EXIT_NOBS);
                }
                long int divisor = DEFAULT_MIN_BLOCK;
                /* Check on the power of two */
                while (divisor > 0 && (divisor != block_size)) 
                        divisor <<= 1;

                if (divisor < 0) {
                        fprintf(stderr, "Block size isn't the power of 2.\n");
                        usage(EXIT_BSDGR2);
                }
        }
        if (block_size > file_size) {
                fprintf(stderr, "Block size more than file size.\n");
                usage(EXIT_BSLRG);
        }
        if (file_size % block_size != 0) {
                fprintf(stderr, "Block size isn't a divisor of data size.\n");
                usage(EXIT_BSDIV);
        }
        /*
         * Calculate reserved area size in bytes
         */
        if (block_size <= MBR_SIZE)
                rsrvd_size = MBR_SIZE;
        else
                rsrvd_size = block_size;
        /* 
         * Handler index size 
         */
        if (index_size_s == NULL) {
                double buf = DEFAULT_INDEX_PERCENT * file_size / 100L;
                index_size = (size_t)round(buf);

        } else {
                index_size = convert_size(index_size_s, file_size);
                if (index_size == 0 || errno == EINVAL) {
                        fprintf(stderr, "Invalid metadata size.\n");
                        usage(EXIT_NOMD);
                }
                
        }
        /* Auto align to BLOCK_SIZE (up) */
        if (index_size % block_size != 0)
                index_size += block_size - index_size % block_size; 
        /* Check index size(maybe file size too small) */
        if (index_size > (file_size - rsrvd_size)) {
                fprintf(stderr, "Index area size more or equal than file"
                                " size.\n");
                usage(EXIT_MDLRG);
        }
        /* Check size of index area */
        if (index_size < INDEX_MIN_SIZE) {
                fprintf(stderr, "Index part size too small.\n");
                usage(EXIT_MDSML);
        } 
        /*
         * Handler label name
         */
        unsigned length = 0;
        int i = 0;
        if (label != NULL && (length = strlen(label)) >= VOLUME_NAME_SIZE) {
                fprintf(stderr, "%s %ld %s", "Label shouldn't be longer"
                                " than ", VOLUME_NAME_SIZE - 1,
                                " symbols.\n");
                usage(EXIT_LBL);
        }
        /* Check on unsupported symbols */ 
        for (i = 0; i < length; i++)
                if (label[i] < 0x20   || 
                   (label[i] >= 0x80  && label[i] <= 0x9F) ||
                    label[i] == '"'   || label[i] == '*'   ||
                    label[i] == ':'   || label[i] == '<'   ||
                    label[i] == '>'   || label[i] == '?'   ||
                    label[i] == '\\'  || label[i] == 0x5C  ||
                    label[i] == 0x7F  || label[i] == 0xA0) {
                        fprintf(stderr, "Unsupported symbol \'%c\' "
                                        "in volume name.\n", label[i]);
                        usage(EXIT_LBL);
                }
        /*
         * Start to flll fields of options struct
         */
        total_blocks = file_size / block_size;
        /* Convert reserved area size to size in blocks */
        rsrvd_size /= block_size;
        /* Convert index area size to align size per block size */
        if (index_size % block_size == 0) 
                index_sz_perblk = index_size / block_size;
        else
                index_sz_perblk = index_size / block_size + 1;
        /* Fill struct */
        sfs_opts.time_stamp = time(NULL);
        sfs_opts.data_size = total_blocks - rsrvd_size - index_sz_perblk; 
        sfs_opts.index_size = index_size;
        sfs_opts.total_block = total_blocks;
        sfs_opts.reserved_size = rsrvd_size;
        sfs_opts.block_size = (size_t)log2(block_size) - BEGIN_POWER_OF_BS;
        if (label != NULL)
                strcpy(sfs_opts.label, label);
        else 
                sfs_opts.label[0] = '\0';
        sfs_opts.file_name = (char*) calloc((strlen(argv[argc - 1]) + 1), sizeof(char));
        strcpy(sfs_opts.file_name, argv[argc - 1]);
        /*
         * Create empty SFS image 
         */
        if (image_create(sfs_opts) != 0) {
                free(sfs_opts.file_name);
                return EXIT_FAILURE;
        }
        free(sfs_opts.file_name);
        return EXIT_SUCCESS;
}
string copy_file(string title, const char *dirfrom, const char *dirto, const char *filename, double filesize, double copy_currentsize, double copy_totalsize, int numfiles_current, int numfiles_total, int check_flag, int showprogress)
{
	string cfrom=(string)dirfrom+(string)filename;
	string ctoo=(string)dirto+(string)filename;
	FILE *from, *to;
	string ret="";
	double percent=copy_currentsize/copy_totalsize*100, oldpercent=percent, changepercent=0, current_copy_size=0;
	string current;
	string sfilename=(string)filename;
	string scurrent_files=int_to_string(numfiles_current);
	string stotal_files=int_to_string(numfiles_total);
	string stotal_size=convert_size(copy_totalsize, "auto");

	PF.printf((title+" '"+sfilename+"'\r\n").c_str());
	PF.printf(("- source: "+cfrom+" \r\n").c_str());
	PF.printf(("- dest: "+ctoo+" \r\n").c_str());

	if ((from = fopen(cfrom.c_str(), "rb"))==NULL) return "Cannot open source file ("+cfrom+") for reading!";
	if (check_flag!=1)
	{
		char* buf = (char*) calloc (1, CHUNK+1);
		size_t size;
		if ((to = fopen(ctoo.c_str(), "wb"))==NULL) return "Cannot open destination file ("+ctoo+") for writing!";
		do
		{
			//draw_copy(title, dirfrom, dirto, filename, cfrom, copy_currentsize, copy_totalsize, numfiles_current, numfiles_total, countsize);
			size = fread(buf, 1, CHUNK, from);
			if(ferror(from)) return "Error reading source file ("+cfrom+")!";
			fwrite(buf, 1, size, to);
			if (ferror(to)) return "Error writing destination file ("+ctoo+")!";
			
			if (showprogress==0)
			{
				current_copy_size=current_copy_size+(double)size;
				percent=(copy_currentsize+current_copy_size)/copy_totalsize*100;
				changepercent=percent-oldpercent;
				current="Processing "+scurrent_files+" of "+stotal_files+" files ("+convert_size(copy_currentsize+current_copy_size, "auto")+"/"+stotal_size+")";
				//PF.printf((" "+int_to_string((int)percent)+"%% "+current+" \r\n").c_str());
				//PF.printf((" change"+int_to_string((int)changepercent)+"%% real"+int_to_string((int)percent)+"%% "+current+" \r\n").c_str());
				Mess.ProgressBarDialogFlip();
				if (changepercent>1)
				{
					Mess.SingleProgressBarDialogChangeMessage(current.c_str());
					Mess.ProgressBarDialogFlip();
					Mess.SingleProgressBarDialogIncrease(changepercent);
					Mess.ProgressBarDialogFlip();
					oldpercent=percent-(changepercent-(int)changepercent);
				}
			}
		}
		while(!feof(from));
		free(buf);
	}
	else
	{
		char* buf = (char*) calloc (1, CHUNK+1);
		char* buf2 = (char*) calloc (1, CHUNK+1);
		size_t size, size2;
		if ((to = fopen(ctoo.c_str(), "rb"))==NULL) return "Cannot open destination file ("+ctoo+") for reading!";
		do
		{
			size = fread(buf, 1, CHUNK, from);
			if(ferror(from)) return "Error reading source file ("+cfrom+")!";
			size2 = fread(buf2, 1, CHUNK, to);
			if (ferror(to)) return "Error reading destination file ("+ctoo+")!";
			if (size != size2) return "Source and destination files have different sizes!";
			if (memcmp(buf, buf2, size)!=0) return "Source and destination files are different!";

			if (showprogress==0)
			{
				current_copy_size=current_copy_size+(double)size;
				percent=(copy_currentsize+current_copy_size)/copy_totalsize*100;
				changepercent=percent-oldpercent;
				current="Processing "+scurrent_files+" of "+stotal_files+" files ("+convert_size(copy_currentsize+current_copy_size, "auto")+"/"+stotal_size+")";
				//PF.printf((" "+int_to_string((int)percent)+"%% "+current+" \r\n").c_str());
				//PF.printf((" change"+int_to_string((int)changepercent)+"%% real"+int_to_string((int)percent)+"%% "+current+" \r\n").c_str());
				Mess.ProgressBarDialogFlip();
				if (changepercent>1)
				{
					Mess.SingleProgressBarDialogChangeMessage(current.c_str());
					Mess.ProgressBarDialogFlip();
					Mess.SingleProgressBarDialogIncrease((int)changepercent);
					Mess.ProgressBarDialogFlip();
					oldpercent=percent-(changepercent-(int)changepercent);
				}
			}
		}
		while(!feof(from) || !feof(to));
		free(buf);
		free(buf2);
	}

	if (fclose(from)==EOF) return "Cannot close source file ("+cfrom+")!";
	if (fclose(to)==EOF) return "Cannot close destination file ("+ctoo+")!";

	return "";
}
示例#8
0
int
Downloader::file_download(void)
{
	int i;
	int ret = 0;

	init_local_file_name();
	if(file_exist(localPath)){
		cout<<_("File already exist: ")<<localPath<<endl;
		return 0;
	}
	cout<<_("Begin to download: ")
		<<(task.get_local_file() ? task.get_local_file() : task.url.get_file())<<endl;
	char buf[6];
	double time = get_current_time();
	convert_size(buf, task.fileSize);
	cout<<_("FileSize: ")<<buf<<endl;

	if(task.fileSize == 0){
		int fd;
		fd = creat(localPath, 00644);
		if(fd < 0){
			perror(_("Error when I create the file"));
			return -1;
		}else{
			close(fd);
			return 0;
		}
	}

	if(!task.resumeSupported || task.fileSize < 0){
		threadNum = 1;
		delete[] blocks;
		blocks = new Block[1];
		blocks[0].size = task.fileSize;
		blocks[0].bufferFile.open(localMg);
	}else if(file_exist(localMg)){
		ret = init_threads_from_mg();
	}else{
		ret = init_threads_from_info();
	}
	if(ret < 0){
		cerr<<_("Init threads failed")<<endl;
		return ret;
	}

	for(i = 0; i < threadNum; i ++){
		if(thread_create() < 0){
			perror(_("Create thread failed"));
			return -1;
		}
	}

	off_t *data;
	data = new off_t[threadNum];

	for(i = 0; i < threadNum; i ++){
		data[i] = blocks[i].startPoint;
	}
	pb->init();
	pb->set_total_size(task.fileSize);
	pb->set_block_num(threadNum);
	pb->set_start_point(data);

	// update loop
	global_downloading = true;
	while(1){
		if(global_sigint_received){
			delete[] data;
			save_temp_file_exit();
		}

		for(i = 0; i < threadNum; i ++){
			data[i] = blocks[i].downloaded;
		}
		pb->update(data);

		if(schedule() == 0){
			break; // all the thread are exit
		}
		usleep(250000);
	}

	delete[] data;
	// recheck the size of the file if possible
	if(task.fileSize >= 0){
		off_t downloaded;
		downloaded = 0;
		for(i = 0; i < threadNum; i ++){
			downloaded += blocks[i].downloaded;
		}
		// the downloaded maybe bigger than the filesize
		// because the overlay of the data
		if(downloaded < task.fileSize){
			cerr<<_("!!!Some error happend when downloaded")<<endl;
			cerr<<_("!!!So Redownloading is recommended")<<endl;
			save_temp_file_exit();
		}
		truncate(localMg, task.fileSize);
	}
	
	if(rename(localMg, localPath) < 0){
		perror(_("Rename failed"));
		return -1;
	}
	global_downloading = false;

	time = get_current_time() - time;
	convert_time(buf, time);
	cout<<_("Download successfully in ")<<buf<<_(" M:S")<<endl;

	return 0;
}; // end of file_download
int main(int argc, char ** argv) {
	static char * buffer[32];
	static char buffer_size[16];
	const char * device = DEFAULT_DEVICE;
	ssize_t size = DEFAULT_SIZE;
	bool no_rewind = false;
	bool rewind = false;

	ssize_t max_buffer_size = MAX_BUFFER_SIZE;
	ssize_t min_buffer_size = MIN_BUFFER_SIZE;
	ssize_t tmp_size = 0;

	enum {
		OPT_DEVICE     = 'd',
		OPT_HELP       = 'h',
		OPT_MAX_BUFFER = 'M',
		OPT_MIN_BUFFER = 'm',
		OPT_NO_REWIND  = 'r',
		OPT_REWIND     = 'R',
		OPT_SIZE       = 's',
		OPT_VERSION    = 'V',
	};

	static struct option op[] = {
		{ "device",          1, 0, OPT_DEVICE },
		{ "help",            0, 0, OPT_HELP },
		{ "max-buffer-size", 1, 0, OPT_MAX_BUFFER },
		{ "min-buffer-size", 1, 0, OPT_MIN_BUFFER },
		{ "no-rewind",       0, 0, OPT_NO_REWIND },
		{ "size",            1, 0, OPT_SIZE },
		{ "rewind-at-start", 0, 0, OPT_REWIND },
		{ "version",         0, 0, OPT_VERSION },

		{ 0, 0, 0, 0 },
	};

	static int lo;
	for (;;) {
		int c = getopt_long(argc, argv, "d:hm:M:s:rRV?", op, &lo);

		if (c == -1)
			break;

		switch (c) {
			case OPT_DEVICE:
				device = optarg;
				break;

			case OPT_HELP:
			case '?':
				printf("tape-benchmark (" TAPEBENCHMARK_VERSION ")\n");
				printf("  -d, --device=DEV           : use this device DEV instead of \"" DEFAULT_DEVICE "\"\n");
				printf("  -h, --help                 : show this and quit\n");
				convert_size(buffer_size, 16, MAX_BUFFER_SIZE);
				printf("  -M, --max-buffer-size=SIZE : maximum buffer size (instead of %s)\n", buffer_size);
				convert_size(buffer_size, 16, MIN_BUFFER_SIZE);
				printf("  -m, --min-buffer-size=SIZE : minimum buffer size (instead of %s)\n", buffer_size);
				convert_size(buffer_size, 16, DEFAULT_SIZE);
				printf("  -s, --size=SIZE            : size of file (default: %s)\n", buffer_size);
				printf("  -r, --no-rewind            : no rewind tape between step (default: rewind between step)\n");
				printf("  -R, --rewind-at-start      : rewind tape before writing on tape, (default: no rewind at start)\n\n");

				printf("SIZE can be specified with (BKGT)\n");
				printf("  1B => 1 byte, 1K => 1024B, 1M => 1024K, 1G => 1024M, 1T => 1024G\n");
				printf("Another way to set the size is by specifying an integer which will be interpreted as a power of two.\n");
				printf("  10 => 2^10 bytes (= 1K), 16 => 2^16 bytes (= 64K), 24 => 2^24 bytes (= 16M), and so on\n");
				printf("Constraint: min-buffer-size and max-buffer-size should be a power of two\n\n");

				printf("Note: this programme will allocate 32 buffers of max-buffer-size\n");

				return 0;

			case OPT_MAX_BUFFER:
				tmp_size = parse_size(optarg);
				if (check_size(tmp_size)) {
					max_buffer_size = tmp_size;
				} else {
					printf("Error: max-buffer-size should be a power of two\n");
					return 1;
				}
				break;

			case OPT_MIN_BUFFER:
				tmp_size = parse_size(optarg);
				if (check_size(tmp_size)) {
					min_buffer_size = tmp_size;
				} else {
					printf("Error: min-buffer-size should be a power of two\n");
					return 1;
				}
				break;

			case OPT_NO_REWIND:
				no_rewind = true;
				break;

			case OPT_SIZE:
				size = parse_size(optarg);
				break;

			case OPT_REWIND:
				rewind = true;
				break;

			case OPT_VERSION:
				printf("tape-benchmark (" TAPEBENCHMARK_VERSION ", date and time : " __DATE__ " " __TIME__ ")\n");
				printf("checksum of source code: " TAPEBENCHMARK_SRCSUM "\n");
				printf("git commit: " TAPEBENCHMARK_GIT_COMMIT "\n");
				return 0;
		}
	}

	print_time();
	print_flush("Openning \"%s\"... ", device);
	int fd_tape = open(device, O_RDONLY);
	if (fd_tape < 0) {
		printf("failed!!!, because %m\n");
		return 2;
	}

	struct mtget mt;
	int failed = ioctl(fd_tape, MTIOCGET, &mt);
	if (failed != 0) {
		close(fd_tape);
		printf("Oops: seem not to be a valid tape device\n");
		return 2;
	}

	if (GMT_WR_PROT(mt.mt_gstat)) {
		close(fd_tape);
		printf("Oops: Write lock enabled\n");
		return 2;
	}

	failed = close(fd_tape);

	fd_tape = open(device, O_WRONLY);
	if (fd_tape < 0) {
		printf("failed!!!, because %m\n");
		return 2;
	} else {
		printf("fd: %d\n", fd_tape);
	}

	if (rewind && !rewind_tape(fd_tape))
		return 2;

	ssize_t current_block_size = (mt.mt_dsreg & MT_ST_BLKSIZE_MASK) >> MT_ST_BLKSIZE_SHIFT;

	print_time();
	print_flush("Generate random data from \"/dev/urandom\"... ");
	int fd_ran = open("/dev/urandom", O_RDONLY);
	if (fd_ran < 0) {
		printf("Failed to open because %m\n");
		close(fd_tape);
		return 2;
	}

	int j;
	for (j = 0; j < 32; j++) {
		buffer[j] = malloc(max_buffer_size);
		if (buffer[j] == NULL) {
			printf("Error: failed to allocated memory (size: %zd) because %m\n", max_buffer_size);
			close(fd_tape);
			close(fd_ran);
			return 3;
		}

		ssize_t nb_read = read(fd_ran, buffer[j], max_buffer_size);
		if (nb_read < 0)
			printf("\nWarning: failed to read from \"/dev/urandom\" because %m\n");
		else if (nb_read < max_buffer_size)
			printf("\nWarning: read less than expected, %zd instead of %zd\n", nb_read, max_buffer_size);
	}
	close(fd_ran);
	printf("done\n");

	static char clean_line[64];
	memset(clean_line, ' ', 64);

	ssize_t write_size;
	for (write_size = min_buffer_size; write_size <= max_buffer_size; write_size <<= 1) {
		if (current_block_size > 0) {
			write_size = current_block_size;
			printf("Warning: block size is defined to %zd instead of %zd\n", current_block_size, write_size);
		}

		struct pollfd plfd = { fd_tape, POLLOUT, 0 };

		int pll_rslt = poll(&plfd, 1, 100);
		int poll_retry = 0;

		while (pll_rslt < 1) {
			if (poll_retry == 0)
				printf("Device is no ready, so we wait until");
			else
				printf(".");
			fflush(stdout);
			poll_retry++;

			pll_rslt = poll(&plfd, 1, 6000);

			if (pll_rslt > 0)
				printf("\n");
		}

		struct timeval time_start;
		gettimeofday(&time_start, NULL);

		ssize_t nb_loop = size / write_size;
		convert_size(buffer_size, 16, write_size);

		print_time();
		printf("Starting, nb loop: %zd, block size: %s\n", nb_loop, buffer_size);

		struct timespec start, last, current;
		clock_gettime(CLOCK_MONOTONIC, &start);
		last = start;

		int write_error = 0;
		long long int i;
		static int last_width = 64;
		for (i = 0; i < nb_loop; i++) {
			ssize_t nb_write = write(fd_tape, buffer[i & 0x1F], write_size);
			if (nb_write < 0) {
				if (last_width > 0)
					printf("\r%*s\r", last_width, clean_line);

				switch (errno) {
					case EINVAL:
						convert_size(buffer_size, 16, write_size >> 1);
						printf("It seems that you cannot use a block size greater than %s\n", buffer_size);
						break;

					case EBUSY:
						printf("rDevice is busy, so we wait a few seconds before restarting\n");
						sleep(8);

						print_time();
						printf("Restarting, nb loop: %zd, block size: %s\n", nb_loop, buffer_size);
						i = -1;

						clock_gettime(CLOCK_MONOTONIC, &start);
						break;

					default:
						printf("Oops: an error occured => (%d) %m\n", errno);
						printf("fd: %d, buffer: %p, count: %zd\n", fd_tape, buffer[i & 0x1F], write_size);
						break;
				}
				write_error = 1;
				break;
			}

			clock_gettime(CLOCK_MONOTONIC, &current);

			if (last.tv_sec + 5 <= current.tv_sec) {
				float pct = 100 * i;
				double time_spent = difftime(current.tv_sec, start.tv_sec);
				double speed = i * write_size;
				speed /= time_spent;
				convert_size(buffer_size, 16, speed);

				printf("\r%*s\r", last_width, clean_line);
				printf("loop: %lld, current speed %s, done: %.2f%%%n", i, buffer_size, pct / nb_loop, &last_width);
				fflush(stdout);

				last = current;
			}
		}

		printf("\r%*s\r", last_width, clean_line);

		struct timeval end;
		gettimeofday(&end, 0);

		clock_gettime(CLOCK_MONOTONIC, &current);

		double time_spent = difftime(current.tv_sec, start.tv_sec);
		double speed = i * write_size;
		speed /= time_spent;
		convert_size(buffer_size, 16, speed);

		print_time();
		printf("Finished, current speed %s\n", buffer_size);

		struct mtget mt2;
		failed = ioctl(fd_tape, MTIOCGET, &mt2);
		if (failed != 0) {
			printf("MTIOCGET failed => %m\n");
			break;
		}

		struct mtop eof = { MTWEOF, 1 };
		failed = ioctl(fd_tape, MTIOCTOP, &eof);
		if (failed != 0) {
			printf("Weof failed => %m\n");
			break;
		}

		struct mtop nop = { MTNOP, 1 };
		failed = ioctl(fd_tape, MTIOCTOP, &nop);
		if (failed != 0) {
			printf("Nop failed => %m\n");
			break;
		}

		failed = ioctl(fd_tape, MTIOCGET, &mt2);
		if (failed != 0) {
			printf("MTIOCGET failed => %m\n");
			break;
		}

		if (!no_rewind) {
			if (mt.mt_fileno < 2) {
				rewind_tape(fd_tape);
			} else {
				print_time();
				print_flush("Moving backward space 1 file... ");

				static struct mtop rewind = { MTBSFM, 2 };
				failed = ioctl(fd_tape, MTIOCTOP, &rewind);
				if (failed != 0)
					printf("Failed => %m\n");
				else
					printf("done\n");
			}
		}

		failed = ioctl(fd_tape, MTIOCGET, &mt2);
		if (failed)
			printf("MTIOCGET failed => %m\n");

		if (current_block_size > 0 || write_error)
			break;
	}

	close(fd_tape);

	for (j = 0; j < 32; j++)
		free(buffer[j]);

	return 0;
}