/* Open a local file to store the downloaded data */ int axel_open( axel_t *axel ) { int i, fd; long long int j; if( axel->conf->verbose > 0 ) axel_message( axel, _("Opening output file %s"), axel->filename ); snprintf( buffer, MAX_STRING, "%s.st", axel->filename ); axel->outfd = -1; /* Check whether server knows about RESTart and switch back to single connection download if necessary */ if( !axel->conn[0].supported ) { axel_message( axel, _("Server unsupported, " "starting from scratch with one connection.") ); axel->conf->num_connections = 1; axel->conn = realloc( axel->conn, sizeof( conn_t ) ); axel_divide( axel ); } else if( ( fd = open( buffer, O_RDONLY ) ) != -1 ) { read( fd, &axel->conf->num_connections, sizeof( axel->conf->num_connections ) ); axel->conn = realloc( axel->conn, sizeof( conn_t ) * axel->conf->num_connections ); memset( axel->conn + 1, 0, sizeof( conn_t ) * ( axel->conf->num_connections - 1 ) ); axel_divide( axel ); read( fd, &axel->bytes_done, sizeof( axel->bytes_done ) ); for( i = 0; i < axel->conf->num_connections; i ++ ) read( fd, &axel->conn[i].currentbyte, sizeof( axel->conn[i].currentbyte ) ); axel_message( axel, _("State file found: %lld bytes downloaded, %lld to go."), axel->bytes_done, axel->size - axel->bytes_done ); close( fd ); if( ( axel->outfd = open( axel->filename, O_WRONLY, 0666 ) ) == -1 ) { axel_message( axel, _("Error opening local file") ); return( 0 ); } } /* If outfd == -1 we have to start from scrath now */ if( axel->outfd == -1 ) { axel_divide( axel ); if( ( axel->outfd = open( axel->filename, O_CREAT | O_WRONLY, 0666 ) ) == -1 ) { axel_message( axel, _("Error opening local file") ); return( 0 ); } /* And check whether the filesystem can handle seeks to past-EOF areas.. Speeds things up. :) AFAIK this should just not happen: */ if( lseek( axel->outfd, axel->size, SEEK_SET ) == -1 && axel->conf->num_connections > 1 ) { /* But if the OS/fs does not allow to seek behind EOF, we have to fill the file with zeroes before starting. Slow.. */ axel_message( axel, _("Crappy filesystem/OS.. Working around. :-(") ); lseek( axel->outfd, 0, SEEK_SET ); memset( buffer, 0, axel->conf->buffer_size ); j = axel->size; while( j > 0 ) { write( axel->outfd, buffer, min( j, axel->conf->buffer_size ) ); j -= axel->conf->buffer_size; } } } return( 1 ); }
/* Open a local file to store the downloaded data */ int axel_open(axel_t *axel) { int i; #if WIN32 HANDLE fd; DWORD byte; #else int fd; #endif long long int j; if (0 < axel->conf->verbose) { axel_message(axel, _("Opening output file %s"), axel->filename); } snprintf(buffer, MAX_STRING, "%s.st", axel->filename); #if WIN32 axel->outfd = INVALID_HANDLE_VALUE; #else axel->outfd = -1; #endif /* Check whether server knows about RESTart and switch back to single connection download if necessary */ if (!axel->conn[0].supported) { axel_message(axel, _("Server unsupported, " "starting from scratch with one connection.")); axel->conf->num_connections = 1; axel->conn = realloc(axel->conn, sizeof(conn_t)); axel_divide(axel); } #if WIN32 else if (INVALID_HANDLE_VALUE != (fd = CreateFile(buffer, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0))) #else else if ((fd = open(buffer, O_RDONLY)) != -1) #endif { #if WIN32 ReadFile(fd, &axel->conf->num_connections, sizeof(axel->conf->num_connections), &byte, NULL); #else read(fd, &axel->conf->num_connections, sizeof(axel->conf->num_connections)); #endif axel->conn = realloc(axel->conn, sizeof(conn_t) * axel->conf->num_connections); memset(axel->conn + 1, 0, sizeof(conn_t) * (axel->conf->num_connections - 1)); axel_divide(axel); #if WIN32 ReadFile(fd, &axel->bytes_done, sizeof(axel->bytes_done), &byte, NULL); #else read(fd, &axel->bytes_done, sizeof(axel->bytes_done)); #endif for (i = 0; i < axel->conf->num_connections; i++) { #if WIN32 ReadFile(fd, &axel->conn[i].currentbyte, sizeof(axel->conn[i].currentbyte), &byte, NULL); #else read(fd, &axel->conn[i].currentbyte, sizeof(axel->conn[i].currentbyte)); #endif } axel_message(axel, _("State file found: %lld bytes downloaded, %lld to go."), axel->bytes_done, axel->size - axel->bytes_done); #if WIN32 CloseHandle(fd); #else close(fd); #endif #if WIN32 if (INVALID_HANDLE_VALUE == (axel->outfd = CreateFile(axel->filename, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0))) #else if ((axel->outfd = open(axel->filename, O_WRONLY, 0666)) == -1) #endif { axel_message(axel, _("Error opening local file")); return 0; } } /* If outfd == -1 we have to start from scrath now */ #if WIN32 if (INVALID_HANDLE_VALUE == axel->outfd) #else if (axel->outfd == -1) #endif { axel_divide(axel); #if WIN32 if (INVALID_HANDLE_VALUE == (axel->outfd = CreateFile(axel->filename, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0))) #else if ((axel->outfd = open(axel->filename, O_CREAT | O_WRONLY, 0666)) == -1) #endif { axel_message(axel, _("Error opening local file")); return 0; } /* And check whether the filesystem can handle seeks to past-EOF areas.. Speeds things up. :) AFAIK this should just not happen: */ #if WIN32 if (INVALID_SET_FILE_POINTER == SetFilePointer(axel->outfd, axel->size, NULL, FILE_BEGIN) && 1 < axel->conf->num_connections) #else if (lseek(axel->outfd, axel->size, SEEK_SET) == -1 && axel->conf->num_connections > 1) #endif { /* But if the OS/fs does not allow to seek behind EOF, we have to fill the file with zeroes before starting. Slow.. */ axel_message(axel, _("Crappy filesystem/OS.. Working around. :-(")); #if WIN32 SetFilePointer(axel->outfd, 0, NULL, FILE_BEGIN); #else lseek(axel->outfd, 0, SEEK_SET); #endif memset(buffer, 0, axel->conf->buffer_size); j = axel->size; while (0 < j) { #if WIN32 WriteFile(axel->outfd, buffer, min(j, axel->conf->buffer_size), &byte, NULL); #else write(axel->outfd, buffer, min(j, axel->conf->buffer_size)); #endif j -= axel->conf->buffer_size; } } } return 1; }