1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Copyright 2011, Oliver Tappe <zooey@hirschkaefer.de> 4 * Distributed under the terms of the MIT License. 5 */ 6 7 8 #include <dirent.h> 9 #include <errno.h> 10 #include <getopt.h> 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <string.h> 14 15 #include <Entry.h> 16 17 #include <package/PackageInfo.h> 18 #include <package/hpkg/HPKGDefs.h> 19 #include <package/hpkg/PackageWriter.h> 20 21 #include "package.h" 22 #include "StandardErrorOutput.h" 23 24 25 using BPackageKit::BHPKG::BPackageWriterListener; 26 using BPackageKit::BHPKG::BPackageWriter; 27 28 29 class PackageWriterListener : public BPackageWriterListener { 30 public: 31 PackageWriterListener(bool verbose, bool quiet) 32 : fVerbose(verbose), fQuiet(quiet) 33 { 34 } 35 36 virtual void PrintErrorVarArgs(const char* format, va_list args) 37 { 38 vfprintf(stderr, format, args); 39 } 40 41 virtual void OnEntryAdded(const char* path) 42 { 43 if (fQuiet || !fVerbose) 44 return; 45 46 printf("\t%s\n", path); 47 } 48 49 virtual void OnTOCSizeInfo(uint64 uncompressedStringsSize, 50 uint64 uncompressedMainSize, uint64 uncompressedTOCSize) 51 { 52 if (fQuiet || !fVerbose) 53 return; 54 55 printf("----- TOC Info -----------------------------------\n"); 56 printf("cached strings size: %10llu (uncompressed)\n", 57 uncompressedStringsSize); 58 printf("TOC main size: %10llu (uncompressed)\n", 59 uncompressedMainSize); 60 printf("total TOC size: %10llu (uncompressed)\n", 61 uncompressedTOCSize); 62 } 63 64 virtual void OnPackageAttributesSizeInfo(uint32 stringCount, 65 uint32 uncompressedSize) 66 { 67 if (fQuiet || !fVerbose) 68 return; 69 70 printf("----- Package Attribute Info ---------------------\n"); 71 printf("string count: %10lu\n", stringCount); 72 printf("package attributes size: %10lu (uncompressed)\n", 73 uncompressedSize); 74 } 75 76 virtual void OnPackageSizeInfo(uint32 headerSize, uint64 heapSize, 77 uint64 tocSize, uint32 packageAttributesSize, uint64 totalSize) 78 { 79 if (fQuiet) 80 return; 81 82 printf("----- Package Info ----------------\n"); 83 printf("header size: %10lu\n", headerSize); 84 printf("heap size: %10llu\n", heapSize); 85 printf("TOC size: %10llu\n", tocSize); 86 printf("package attributes size: %10lu\n", packageAttributesSize); 87 printf("total size: %10llu\n", totalSize); 88 printf("-----------------------------------\n"); 89 } 90 91 private: 92 bool fVerbose; 93 bool fQuiet; 94 }; 95 96 97 int 98 command_create(int argc, const char* const* argv) 99 { 100 const char* changeToDirectory = NULL; 101 bool quiet = false; 102 bool verbose = false; 103 104 while (true) { 105 static struct option sLongOptions[] = { 106 { "help", no_argument, 0, 'h' }, 107 { "quiet", no_argument, 0, 'q' }, 108 { "verbose", no_argument, 0, 'v' }, 109 { 0, 0, 0, 0 } 110 }; 111 112 opterr = 0; // don't print errors 113 int c = getopt_long(argc, (char**)argv, "+C:hqv", sLongOptions, NULL); 114 if (c == -1) 115 break; 116 117 switch (c) { 118 case 'C': 119 changeToDirectory = optarg; 120 break; 121 122 case 'h': 123 print_usage_and_exit(false); 124 break; 125 126 case 'q': 127 quiet = true; 128 break; 129 130 case 'v': 131 verbose = true; 132 break; 133 134 default: 135 print_usage_and_exit(true); 136 break; 137 } 138 } 139 140 // The remaining arguments is the package file, i.e. one more argument. 141 if (optind + 1 != argc) 142 print_usage_and_exit(true); 143 144 const char* packageFileName = argv[optind++]; 145 146 // create package 147 PackageWriterListener listener(verbose, quiet); 148 BPackageWriter packageWriter(&listener); 149 status_t result = packageWriter.Init(packageFileName); 150 if (result != B_OK) 151 return 1; 152 153 // change directory, if requested 154 if (changeToDirectory != NULL) { 155 if (chdir(changeToDirectory) != 0) { 156 listener.PrintError( 157 "Error: Failed to change the current working directory to " 158 "\"%s\": %s\n", changeToDirectory, strerror(errno)); 159 } 160 } 161 162 // add all files of current directory 163 DIR* dir = opendir("."); 164 if (dir == NULL) { 165 listener.PrintError("Error: Failed to opendir '.': %s\n", 166 strerror(errno)); 167 return 1; 168 } 169 while (dirent* entry = readdir(dir)) { 170 if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) 171 continue; 172 173 result = packageWriter.AddEntry(entry->d_name); 174 if (result != B_OK) 175 return 1; 176 } 177 closedir(dir); 178 179 // write the package 180 result = packageWriter.Finish(); 181 if (result != B_OK) 182 return 1; 183 184 if (verbose) 185 printf("\nsuccessfully created package '%s'\n", packageFileName); 186 187 return 0; 188 } 189