Panda3D
punzip.cxx
1 // Filename: punzip.cxx
2 // Created by:
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "pystub.h"
16 #include "filename.h"
17 #include "compress_string.h"
18 #include "pnotify.h"
19 #include "panda_getopt.h"
20 #include "preprocess_argv.h"
21 
22 void
23 usage() {
24  cerr
25  << "\nUsage:\n"
26  << " punzip file.pz [file2.pz file3.pz ...]\n"
27  << " punzip -c <file >dest_file\n"
28  << " punzip -o dest_file file.pz\n\n"
29 
30  << "This program reverses the operation of a previous pzip command. It\n"
31  << "uncompresses the contents of the named source file(s) and removes the .pz\n"
32  << "extension.\n\n";
33 }
34 
35 int
36 main(int argc, char **argv) {
37  // A call to pystub() to force libpystub.so to be linked in.
38  pystub();
39 
40  extern char *optarg;
41  extern int optind;
42  const char *optstr = "o:ch";
43 
44  Filename dest_filename;
45  bool got_dest_filename = false;
46  bool use_stdout = false;
47 
48  preprocess_argv(argc, argv);
49  int flag = getopt(argc, argv, optstr);
50 
51  while (flag != EOF) {
52  switch (flag) {
53  case 'o':
54  dest_filename = Filename::from_os_specific(optarg);
55  got_dest_filename = true;
56  break;
57 
58  case 'c':
59  use_stdout = true;
60  break;
61 
62  case 'h':
63  case '?':
64  default:
65  usage();
66  return 1;
67  }
68  flag = getopt(argc, argv, optstr);
69  }
70 
71  argc -= (optind-1);
72  argv += (optind-1);
73 
74  if (use_stdout) {
75  if (argc > 1) {
76  cerr << "No filenames allowed in conjunction with -c.\n";
77  return 1;
78  }
79 
80  bool success = decompress_stream(cin, cout);
81  if (!success) {
82  cerr << "Failure compressing standard input\n";
83  return 1;
84  }
85  return 0;
86  }
87 
88  if (argc < 2) {
89  usage();
90  return 1;
91  }
92 
93  if (got_dest_filename && argc > 2) {
94  cerr << "Only one input file allowed in conjunction with -o.\n";
95  return 1;
96  }
97 
98  bool all_ok = true;
99  for (int i = 1; i < argc; i++) {
100  Filename source_file = Filename::from_os_specific(argv[i]);
101  if (!got_dest_filename && source_file.get_extension() != "pz") {
102  cerr << source_file
103  << " doesn't end in .pz; can't derive filename of output file.\n";
104  all_ok = false;
105 
106  } else {
107  Filename dest_file = dest_filename;
108  if (!got_dest_filename) {
109  dest_file = source_file.get_fullpath_wo_extension();
110  }
111 
112  // Open source file
113  pifstream read_stream;
114  source_file.set_binary();
115  if (!source_file.open_read(read_stream)) {
116  cerr << "Couldn't read: " << source_file << endl;
117  all_ok = false;
118 
119  } else {
120  // Open destination file
121  pofstream write_stream;
122  dest_file.set_binary();
123  if (!dest_file.open_write(write_stream, true)) {
124  cerr << "Failed to open: " << dest_file << endl;
125  all_ok = false;
126 
127  } else {
128  cerr << dest_file << "\n";
129  bool success = decompress_stream(read_stream, write_stream);
130 
131  read_stream.close();
132  write_stream.close();
133 
134  if (!success) {
135  cerr << "Failure decompressing " << source_file << "\n";
136  all_ok = false;
137  dest_file.unlink();
138 
139  } else {
140  if (!got_dest_filename) {
141  source_file.unlink();
142  }
143  }
144  }
145  }
146  }
147  }
148 
149  if (all_ok) {
150  return 0;
151  } else {
152  return 1;
153  }
154 }
bool open_write(ofstream &stream, bool truncate=true) const
Opens the indicated ifstream for writing the file, if possible.
Definition: filename.cxx:2045
void set_binary()
Indicates that the filename represents a binary file.
Definition: filename.I:494
string get_extension() const
Returns the file extension.
Definition: filename.I:477
bool open_read(ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
Definition: filename.cxx:2003
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:44
bool unlink() const
Permanently deletes the file associated with the filename, if possible.
Definition: filename.cxx:2554
string get_fullpath_wo_extension() const
Returns the full filename–directory and basename parts–except for the extension.
Definition: filename.I:448
static Filename from_os_specific(const string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes, and no drive letter) based on the supplied filename string that describes a filename in the local system conventions (for instance, on Windows, it may use backslashes or begin with a drive letter and a colon).
Definition: filename.cxx:332