Panda3D
pdecrypt.cxx
1 // Filename: pdecrypt.cxx
2 // Created by: drose (01Sep04)
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 "encrypt_string.h"
18 #include "pnotify.h"
19 #include "panda_getopt.h"
20 #include "preprocess_argv.h"
21 
22 string password;
23 bool got_password = false;
24 
25 void
26 usage() {
27  cerr
28  << "\nUsage:\n"
29  << " pdecrypt file.pe [file2.pe file3.pe ...]\n"
30  << " pdecrypt -o dest_file file.pe\n\n"
31  << "\n"
32 
33  << "This program reverses the operation of a previous pencrypt command. It\n"
34  << "decrypts the contents of the named source file(s) and removes the .pe\n"
35  << "extension. The encryption algorithm need not be specified; it can be\n"
36  << "determined by examining the header of each encrypted file. The password\n"
37  << "must match the encryption password exactly. If it does not, an error may\n"
38  << "or may not be reported; but the file will not be decrypted correctly even\n"
39  << "if no error is reported.\n\n"
40 
41  << "Options:\n\n"
42 
43  << " -p \"password\"\n"
44  << " Specifies the password to use for decryption. If this is not specified,\n"
45  << " the user is prompted from standard input.\n\n";
46 }
47 
48 int
49 main(int argc, char **argv) {
50  // A call to pystub() to force libpystub.so to be linked in.
51  pystub();
52 
53  extern char *optarg;
54  extern int optind;
55  const char *optstr = "o:p:h";
56 
57  Filename dest_filename;
58  bool got_dest_filename = false;
59 
60  preprocess_argv(argc, argv);
61  int flag = getopt(argc, argv, optstr);
62 
63  while (flag != EOF) {
64  switch (flag) {
65  case 'o':
66  dest_filename = Filename::from_os_specific(optarg);
67  got_dest_filename = true;
68  break;
69 
70  case 'p':
71  password = optarg;
72  got_password = true;
73  break;
74 
75  case 'h':
76  case '?':
77  default:
78  usage();
79  return 1;
80  }
81  flag = getopt(argc, argv, optstr);
82  }
83 
84  argc -= (optind-1);
85  argv += (optind-1);
86 
87  if (argc < 2) {
88  usage();
89  return 1;
90  }
91 
92  if (got_dest_filename && argc > 2) {
93  cerr << "Only one input file allowed in conjunction with -o.\n";
94  return 1;
95  }
96 
97  bool all_ok = true;
98  for (int i = 1; i < argc; i++) {
99  Filename source_file = Filename::from_os_specific(argv[i]);
100  if (!got_dest_filename && source_file.get_extension() != "pe") {
101  cerr << source_file
102  << " doesn't end in .pe; can't derive filename of output file.\n";
103  all_ok = false;
104 
105  } else {
106  Filename dest_file = dest_filename;
107  if (!got_dest_filename) {
108  dest_file = source_file.get_fullpath_wo_extension();
109  }
110 
111  // Open source file
112  pifstream read_stream;
113  source_file.set_binary();
114  if (!source_file.open_read(read_stream)) {
115  cerr << "Couldn't read: " << source_file << endl;
116  all_ok = false;
117 
118  } else {
119  // Open destination file
120  pofstream write_stream;
121  dest_file.set_binary();
122  if (!dest_file.open_write(write_stream, true)) {
123  cerr << "Failed to open: " << dest_file << endl;
124  all_ok = false;
125 
126  } else {
127  // Prompt for password.
128  if (!got_password) {
129  cerr << "Enter password: ";
130  getline(cin, password);
131  got_password = true;
132  }
133 
134  cerr << dest_file << "\n";
135  bool success = decrypt_stream(read_stream, write_stream, password);
136 
137  read_stream.close();
138  write_stream.close();
139 
140  if (!success) {
141  cerr << "Failure decrypting " << source_file << "\n";
142  all_ok = false;
143  dest_file.unlink();
144 
145  } else {
146  if (!got_dest_filename) {
147  source_file.unlink();
148  }
149  }
150  }
151  }
152  }
153  }
154 
155  if (all_ok) {
156  return 0;
157  } else {
158  return 1;
159  }
160 }
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