void create_archive_from_files(int number_of_arguments, char** files) { FILE* archive = NULL; int i = first_argument_position; errno = 0; // If the user wants to create the archive file so the first argument is // the name of the archive. if(MAKE_ARCHIVE_FLAG) { archive = fopen(files[first_argument_position], "w"); if(archive == NULL && errno != 0) goto error; i++; } do { errno = 0; FILE* current_file = fopen(files[i], "r"); if(current_file == NULL && errno != 0) goto error; FILE_HEADER header; build_ustar_header_from_file(&header, files[i]); size_t filesize = oct2dec(header.size); char* buffer = malloc(filesize); memset(buffer, 0, filesize); fread(buffer, filesize, 1, current_file); if(MAKE_ARCHIVE_FLAG) { write_header_to_archive(&header, archive); fwrite(buffer, filesize, 1, archive); unsigned int space_needed = calculate_number_of_block(filesize); space_needed *= BLOCK_SIZE; complete_current_block(filesize, space_needed, archive); if(VERBOSE_FLAG) printf("'%s' a été archivé.\n", files[i]); } else { printf_header(&header); printf("%.*s\n", (int)filesize, buffer); } free(buffer); buffer = NULL; fclose(current_file); current_file = NULL; i++; } while(i < number_of_arguments); // Write an ending null block at the end of the archive if(MAKE_ARCHIVE_FLAG) { write_null_block(archive); fclose(archive); archive = NULL; } // Here is a jump in case of an error during opening the archive error: // Avoid a wrong error display at the end of the function if(i != number_of_arguments) fprintf(stderr, "%s '%s' : %s\n", OPENING_ERR, files[i], strerror(errno)); }
int main (int argc, char **argv) { struct stat sbuf; unsigned char *ptr; int ifd; char *datafile = *(argv+1); imagefile = *(argv+2); ifd = open(imagefile, O_RDWR|O_CREAT|O_TRUNC|O_BINARY, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); if (ifd < 0) { fprintf(stderr, "Can't open %s: %s\n", imagefile, strerror(errno)); exit(EXIT_FAILURE); } /* * Must be -w then: * * Write dummy header, to be fixed later * */ memset((void *)hdr, 0, sizeof(struct spl_header)); if (write(ifd, (void *)hdr, sizeof(struct spl_header)) != sizeof(struct spl_header)) { fprintf(stderr, "Write error on %s: %s\n", imagefile, strerror(errno)); exit(EXIT_FAILURE); } /* Copy the binary data into imagefile */ copy_file(ifd, datafile, 0); (void)fsync(ifd); if (fstat(ifd, &sbuf) < 0) { fprintf(stderr, "Can't stat %s: %s\n", imagefile, strerror(errno)); exit(EXIT_FAILURE); } ptr = (unsigned char *)mmap(0, sbuf.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, ifd, 0); if ((unsigned char *)MAP_FAILED == ptr) { fprintf(stderr, "Can't map %s: %s\n", imagefile, strerror(errno)); exit(EXIT_FAILURE); } /* Build new header */ hdr = (struct spl_header *)ptr; hdr->marker = SPL_MARKER; hdr->size = sbuf.st_size; printf_header(hdr); (void)munmap((void *)ptr, sbuf.st_size); (void)fsync(ifd); /* Close the file */ if (close(ifd)) { fprintf(stderr, "Close error on %s:%s\n", imagefile, strerror(errno)); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }