56 using namespace basis;
 
   70 #define BASE_LOG(to_print) program_wide_logger::get().log(to_print, ALWAYS_PRINT) 
   71 #define LOG(to_print) STAMPED_EMERGENCY_LOG(program_wide_logger::get(), to_print) 
   76 const char *
ERROR_TITLE = 
"An Error Caused Incomplete Installation";
 
   89   virtual int execute();
 
  106   MessageBox(0, to_unicode_temp(msg), to_unicode_temp(title),
 
  107       MB_OK | MB_ICONINFORMATION);
 
  114     %s: This program unpacks its contents into the locations\n\ 
  115  specified at packing time.  The --target flag can be used to specify a\n\ 
  116 different %s directory for the installation (for components that use\n\ 
  117 the default %s variable to specify their install folder).\n\ 
  118     One can also pass a --keyword flag to specify a keyword; the files in the\n\ 
  119 bundle that are marked with that keyword will be installed, but files that\n\ 
  120 are missing the keyword will not be.\n\ 
  121     Further, variables can be overridden on the command line in the\n\ 
  123 The line below uses all these parameters as an example:\n\n\ 
  124   %s --target c:\\Program Files\\gubernator --keyword dlls_only SILENT=true\n\ 
  128     One helpful variable is \"%s\".  This is where the unpacking log file\n\ 
  129 will be written to.  The default is \"~/logs\" (or \"$TMP/logs\" on win32)\n\ 
  142 const int MAXIMUM_BACKUPS = 200;
 
  144   for (
int i = 0; i < MAXIMUM_BACKUPS; i++) {
 
  146     if (target_file.
exists()) {
 
  164     = { 
'm', 
'u', 
'f', 
't', 
'i', 
'l', 
'o', 
'c', 0, 0, 0, 0, 0, 0, 0, 0 };
 
  166 int unpacker_stub::execute()
 
  170     if (IsUserAnAdmin()) {
 
  171       ::MessageBox(0, to_unicode_temp(
"IS admin in bundler"), to_unicode_temp(
"bundler"), MB_OK);
 
  173       ::MessageBox(0, to_unicode_temp(
"NOT admin in bundler"), to_unicode_temp(
"bundler"), MB_OK);
 
  187   environment::set(
"EXE_END", 
"");  
 
  188   environment::set(
"DLL_START", 
"lib");  
 
  189   environment::set(
"DLL_END", 
".so");  
 
  191   environment::set(
"EXE_END", 
".exe");
 
  192   environment::set(
"DLL_START", 
"");
 
  193   environment::set(
"DLL_END", 
".dll");
 
  197   bool provided_target = 
false;  
 
  199   cmds.get_value(
"target", target);
 
  201     provided_target = 
false;
 
  205     provided_target = 
true;
 
  212       logdir = environment::TMP() + 
"/logs";
 
  217       astring homedir = environment::get(
"HOME");
 
  218       logdir = homedir + 
"/logs";
 
  225   cmds.get_value(
"keyword", keyword);
 
  229   for (
int x = 0; x < cmds.entries(); x++) {
 
  232     if (curr.
text().
find(
'=', 0) < 0) 
continue;  
 
  238     vars_set += 
astring(
"variable set: ") + var + 
"=" + value
 
  239         + parser_bits::platform_eol_to_chars();
 
  241       provided_target = 
true;
 
  244     _variables.add(var, value);
 
  245     environment::set(var, value);
 
  253   astring logname = logdir + 
"/" + appname + 
".log";
 
  259   BASE_LOG(appname + 
" command-line parameters:");
 
  269       "stubby window title");
 
  282   if (!this_exe.exists()) {
 
  290   our_exe.seek(manifest_offset);  
 
  293   if (our_exe.read(temp_packed, 2 * 
sizeof(
int)) <= 0) {
 
  301   _manifest.insert(0, item_count);  
 
  304   for (
int i = 0; i < (int)item_count; i++) {
 
  323   LOG(
"read the following info from manifest:");
 
  325   for (
int i = 0; i < _manifest.length(); i++) {
 
  330   critical_events::alert_message(
temp, 
"manifest contents");
 
  336   for (
int festdex = 0; festdex < _manifest.length(); festdex++) {
 
  338     int size_left = curr.
_size;
 
  342     curr.
_parms = parser_bits::substitute_env_vars(curr.
_parms, 
false);
 
  351     bool keyword_good = 
true;
 
  354       keyword_good = 
false;
 
  364               + 
": was provided explicitly as " + target);
 
  365         } 
else if (_variables.find(curr.
_payload)) {
 
  367               + 
": was provided on command line.");
 
  376             astring logname = logdir + 
"/" + appname + 
".log";
 
  383             provided_target = 
true;
 
  391         if (var_value.
empty()) {
 
  394               "*not* defined, for item #%d.", curr.
_payload.
s(), festdex),
 
  405       if (!provided_target) {
 
  407         BASE_LOG(
astring(
"No TARGET has been specified; please provide one on the command line.") + parser_bits::platform_eol_to_chars());
 
  414       if (keyword_good && !target_dir.
exists()
 
  415           && !directory::recursive_create(target_dir)) {
 
  416         LOG(
a_sprintf(
"failed to create directory %s for item #%d: ",
 
  423         if (target_file.exists()) {
 
  425           keyword_good = 
false;
 
  432         if (target_file.exists()) {
 
  434           if (!new_file_name) {
 
  436             keyword_good = 
false;  
 
  442             int retval = rename(curr.
_payload.
s(), new_file_name.
s());
 
  445               keyword_good = 
false;  
 
  456       bool first_read = 
true;
 
  458       bool too_tiny_complaint_already = 
false;
 
  464       while (first_read || !our_exe.eof()) {
 
  502                 " size on read (expected %d, got %d): ", festdex, 
packed_size,
 
  506           uncompressed.reset(real_size + 
KILOBYTE);  
 
  507           uLongf destlen = uncompressed.length();
 
  508           int uncomp_ret = uncompress(uncompressed.access(), &destlen,
 
  510           if (uncomp_ret != Z_OK) {
 
  516           if (
int(destlen) != real_size) {
 
  517             LOG(
a_sprintf(
"got a different unpacked size for item #%d: ",
 
  522           size_left -= real_size;
 
  524             if (!too_tiny_complaint_already) {
 
  525               LOG(
a_sprintf(
"item #%d was larger than expected (non-fatal): ",
 
  527               too_tiny_complaint_already = 
true;
 
  531           uncompressed.zap(real_size, uncompressed.length() - 1);
 
  535             ret = targo->
write(uncompressed);
 
  536             if (ret != uncompressed.length()) {
 
  544       if (targo) targo->
close();
 
  566       astring prev_dir = application_configuration::current_directory();
 
  575           launch_process::AWAIT_APP_EXIT | launch_process::HIDE_APP_WINDOW, kid);
 
  580             LOG(
astring(
"failed to launch process, targ=")
 
  590           LOG(
astring(
"ignoring failure to launch process, targ=")
 
  614 #ifdef __BUILD_STATIC_APPLICATION__ 
int print_instructions(bool good, const astring &program_name)
The application_shell is a base object for console programs.
const basis::astring & text() const
observes the string contents.
parameter_types type() const
observes the type of the parameter.
a_sprintf is a specialization of astring that provides printf style support.
Provides a dynamically resizable ASCII character string.
const char * s() const
synonym for observe. the 's' stands for "string", if that helps.
bool empty() const
empty() reports if the string is empty, that is, of zero length().
int length() const
Returns the current length of the string.
int find(char to_find, int position=0, bool reverse=false) const
Locates "to_find" in "this".
A very common template for a dynamic array of bytes.
Manages a bank of textual definitions of variables.
const structures::string_table & table() const
provides a constant peek at the string_table holding the values.
int symbols() const
returns the number of entries in the variable_tokenizer.
bool parse(const basis::astring &to_tokenize)
parses the string using our established sentinel characters.
Provides file managment services using the standard I/O support.
int write(const basis::abyte *buffer, int buffer_size)
writes "buffer_size" bytes into the file from "buffer".
void close()
shuts down the open file, if any.
bool set_time(const basis::astring &filename)
sets the time for the the "filename" to the currently held time.
virtual bool unpack(basis::byte_array &packed_form)
Provides operations commonly needed on file names.
bool exists() const
returns true if the file exists.
basis::astring rootname() const
returns the root part of the basename without an extension.
const basis::astring & raw() const
returns the astring that we're holding onto for the path.
filename dirname() const
returns the directory for the filename.
combines a file_logger with a console logger, behaving like the 'tee' command.
A base class for a very usable logger with a filter_set and eol awareness.
bool member(const contents &to_test) const
Returns true if the item "to_test" is a member of this set.
Provides a symbol_table that holds strings as the content.
const basis::astring & name(int index) const
returns the name held at the "index".
@ TEST_VARIABLE_DEFINED
check for required variable's presence.
@ OMIT_PACKING
for a source side exe, do not pack the file.
@ SET_VARIABLE
this item just has a variable assignment.
@ QUIET_FAILURE
when errors happen, no popup message happens.
@ IGNORE_ERRORS
if set, errors in an item will not stop program.
@ TARGET_EXECUTE
the file should be executed on unbundling.
@ MAKE_BACKUP_FILE
save a copy if original file already exists.
@ NO_OVERWRITE
target file will not be overwritten if exists.
#define NULL_POINTER
The value representing a pointer to nothing.
#define DEFINE_CLASS_NAME(objname)
Defines the name of a class by providing a couple standard methods.
Provides macros that implement the 'main' program of an application.
#define HOOPLE_MAIN(obj_name, obj_args)
options that should work for most unix and linux apps.
Implements an application lock to ensure only one is running at once.
window_handle create_simplistic_window(const basis::astring &formal(window_title), const basis::astring &formal(class_name))
void whack_simplistic_window(window_handle formal(f_window))
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
unsigned char abyte
A fairly important unit which is seldom defined...
unsigned int un_int
Abbreviated name for unsigned integers.
const int KILOBYTE
Number of bytes in a kilobyte.
str basename(str pathname)
A platform independent way to obtain the timestamp of a file.
A logger that sends to the console screen using the standard output device.
A dynamic container class that holds any kind of object via pointers.
bool obscure_detach(byte_array &packed_form, un_int &to_detach)
shifts the number back and checks validity, false returned if corrupted.
int packed_size(const byte_array &packed_form)
Reports the size required to pack a byte array into a byte array.
we will read the manifest pieces out of our own exe image.
basis::un_int _flags
uses the special_bundling_flags.
basis::astring _parms
the parameters to pass on the command line.
basis::astring _payload
guts of the chunk, such as location for file on target or a variable definition.
static bool read_an_obscured_int(filesystem::byte_filer &bundle, basis::un_int &found)
reads in our obscured packing format for an int, which takes 8 bytes.
static bool read_manifest(filesystem::byte_filer &bundle, manifest_chunk &to_fill)
reads a chunk out of the "bundle" and stores it in "to_fill".
basis::un_int _size
the size of the packed file.
virtual void text_form(basis::base_string &state_fill) const
Provides a text view of all the important info owned by this object.
basis::byte_array c_filetime
more than enough room for unix file time.
structures::string_set _keywords
keywords applicable to this item.
#define BASE_LOG(to_print)
abyte MANIFEST_OFFSET_ARRAY[]
const astring TARGET_WORD
const astring LOGDIR_WORD
astring find_unique_backup_name(astring original_file)
void show_message(const astring &msg, const astring &title)
Support for unicode builds.