1 /* 2 * Copyright 2014, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <errno.h> 8 #include <fcntl.h> 9 #include <getopt.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <unistd.h> 14 15 #include <package/hpkg/HPKGDefs.h> 16 #include <package/hpkg/PackageReader.h> 17 #include <package/hpkg/PackageWriter.h> 18 19 #include "package.h" 20 #include "PackageWriterListener.h" 21 22 23 using BPackageKit::BHPKG::BPackageReader; 24 using BPackageKit::BHPKG::BPackageWriter; 25 using BPackageKit::BHPKG::BPackageWriterListener; 26 using BPackageKit::BHPKG::BPackageWriterParameters; 27 28 29 int 30 command_recompress(int argc, const char* const* argv) 31 { 32 bool quiet = false; 33 bool verbose = false; 34 int32 compressionLevel = BPackageKit::BHPKG::B_HPKG_COMPRESSION_LEVEL_BEST; 35 36 while (true) { 37 static struct option sLongOptions[] = { 38 { "help", no_argument, 0, 'h' }, 39 { "quiet", no_argument, 0, 'q' }, 40 { "verbose", no_argument, 0, 'v' }, 41 { 0, 0, 0, 0 } 42 }; 43 44 opterr = 0; // don't print errors 45 int c = getopt_long(argc, (char**)argv, "+0123456789:hqv", 46 sLongOptions, NULL); 47 if (c == -1) 48 break; 49 50 switch (c) { 51 case '0': 52 case '1': 53 case '2': 54 case '3': 55 case '4': 56 case '5': 57 case '6': 58 case '7': 59 case '8': 60 case '9': 61 compressionLevel = c - '0'; 62 break; 63 64 case 'h': 65 print_usage_and_exit(false); 66 break; 67 68 case 'q': 69 quiet = true; 70 break; 71 72 case 'v': 73 verbose = true; 74 break; 75 76 default: 77 print_usage_and_exit(true); 78 break; 79 } 80 } 81 82 // The remaining arguments are the input package file and optionally the 83 // output package file, i.e. one or two more arguments. 84 if (argc - optind < 1 || argc - optind > 2) 85 print_usage_and_exit(true); 86 87 const char* inputPackageFileName = argv[optind++]; 88 const char* outputPackageFileName = optind < argc ? argv[optind++] : NULL; 89 90 // If compression is used, an output file is required. 91 if (compressionLevel != 0 && outputPackageFileName == NULL) { 92 fprintf(stderr, "Error: Writing to stdout is supported only with " 93 "compression level 0.\n"); 94 return 1; 95 } 96 97 // TODO: Implement streaming support! 98 if (outputPackageFileName == NULL) { 99 fprintf(stderr, "Error: Writing to stdout is not supported yet.\n"); 100 return 1; 101 } 102 103 // open the input package 104 PackageWriterListener listener(verbose, quiet); 105 106 BPackageReader packageReader(&listener); 107 status_t error = packageReader.Init(inputPackageFileName); 108 if (error != B_OK) 109 return 1; 110 111 // write the output package 112 BPackageWriterParameters writerParameters; 113 writerParameters.SetCompressionLevel(compressionLevel); 114 115 BPackageWriter packageWriter(&listener); 116 error = packageWriter.Init(outputPackageFileName, &writerParameters); 117 if (error != B_OK) 118 return 1; 119 120 error = packageWriter.Recompress(&packageReader); 121 if (error != B_OK) 122 return 1; 123 124 if (verbose) 125 printf("\nsuccessfully wrote package '%s'\n", outputPackageFileName); 126 127 return 0; 128 } 129