Changeset 1638


Ignore:
Timestamp:
2000-11-01T08:09:20+13:00 (24 years ago)
Author:
cs025
Message:

Fundamental changes in the method of handling logs to further bypass faults
in the Microsoft implementation of C++ fstream class.

Location:
trunk/gsinstaller
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/gsinstaller/gsinstall.cpp

    r1588 r1638  
    350350    }
    351351
    352   // open the log for writing
     352  // set the log for writing
    353353  FilePath *logPath = new FilePath(this->destinationPath->pathString(), "install.log");
    354   this->openLog(logPath->pathString(), true);
    355   delete logPath;
    356 }
     354  this->setLogFile(logPath->pathString());
     355  delete logPath;}
    357356
    358357bool GSInstall::setUninstall()
     
    394393  // will in fact be the temporary directory as outlined above)
    395394  FilePath *logPath = new FilePath(this->sourcePath->pathString(), "install.log");
    396   this->openLog(logPath->pathString(), false);
     395  this->setLogFile(logPath->pathString());
     396  this->readLog();
    397397  delete logPath;
    398398 
     
    951951          // will be deleted, it must be closed; copying may also fail, so it's
    952952          // safer to close it before doing either.
    953           install.closeLog();
     953          install.recordLog();
    954954
    955955          // if the install is empty, terminate all final items (currently the
     
    999999        install.updateSetupExe();
    10001000
    1001         // the log will need reopening (probably failed initially)
    1002         install.reopenLog();
    1003 
    10041001        // close log
    1005         install.closeLog();
     1002        install.recordLog();
    10061003
    10071004        // do further actions
  • trunk/gsinstaller/unInstall.cpp

    r1560 r1638  
    55#include "File.h"
    66
    7 bool installManager::openLog(string filename, bool write)
     7bool installManager::ensureLog()
    88{
    9   string command;
    10   stringArray params;
    11 
    12   // close the log if already open
    13   if (this->logfile.rdbuf()->is_open())
    14     {
    15       this->closeLog();
    16     }
    17 
    18   // note the new file details and do an open
    19   this->logfileName = filename;
    20   this->logfile.open(filename.c_str(), ios::out | ios::in);
    21    
     9    HANDLE fHandle;
     10
     11    fHandle = CreateFile(this->logfileName.c_str(), GENERIC_READ | GENERIC_WRITE,
     12                         FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
     13                         FILE_ATTRIBUTE_NORMAL, NULL);
     14    if (fHandle == INVALID_HANDLE_VALUE)
     15    {
     16        fHandle = CreateFile(this->logfileName.c_str(), GENERIC_READ | GENERIC_WRITE,
     17                         FILE_SHARE_WRITE, NULL, CREATE_NEW,
     18                             FILE_ATTRIBUTE_NORMAL, NULL);
     19        if (fHandle != INVALID_HANDLE_VALUE)
     20        {   
     21            CloseHandle(fHandle);
     22            return true;
     23        }
     24        return false;
     25    }
     26    else
     27    {   CloseHandle(fHandle);
     28    }
     29    return true;
     30}
     31
     32bool installManager::setLogFile(string filename)
     33{   this->logfileName = filename;
     34    this->setModule("default");
     35    return true;
     36}
     37
     38bool installManager::readLog()
     39{   string command;
     40    stringArray params;
     41
     42  // open the log file
     43    this->logfile.open(this->logfileName.c_str(), ios::in);
     44
     45    // Get the commands into this object from the existing log file
     46    while ((command = this->readCommand(params)) != "")
     47    {   if (command[0] == '[' && command[command.length()-1] == ']')
     48        { this->setModule(command.substr(1, command.length() - 2));
     49        }
     50        else
     51        {   unInstallCommand action(command, params);
     52            this->storeCommand(action);
     53        }
     54    }
     55    this->changed = false;
     56
     57    // close the logfile
     58    this->logfile.close();
     59 
     60  // set to the default module
     61  this->setModule("default");
     62  return true;
     63}
     64
     65void installManager::setModule(string moduleName)
     66{   this->currentModule = moduleName;
     67}
     68
     69bool installManager::storeCommand(unInstallCommand &command)
     70{ this->modules[this->currentModule].push_back(command);
     71    this->changed = true; // set the "changed" flag
     72    return true;
     73}
     74
     75bool installManager::writeCommand(unInstallCommand &command)
     76{ if (!this->writeString(command.command))
     77    { return false;
     78  }
     79    for (unsigned int p = 0; p < command.parameters.size(); p ++)
     80  { if (!this->writeSeparator())
     81    { return false;
     82    }
     83    if (!this->writeString(command.parameters[p]))
     84    { return false;
     85    }
     86  }
     87  if (!this->writeString("\n"))
     88  { return false;
     89  }
     90  return true;
     91}
     92
     93bool installManager::writeString(char *buffer)
     94{ string s(buffer);
     95    return this->writeString(s);
     96}
     97
     98bool installManager::writeString(string str)
     99{ bool quote;
     100
     101    // TODO: check for space characters in str and quote if necessary
     102    quote = str.find_first_of(' ') < str.length();
     103
     104    if (quote)
     105  { this->logfile << "\"";
     106  }
     107    this->logfile << str;
     108  if (quote)
     109  { this->logfile << "\"";
     110  }
     111  return true;
     112}
     113
     114bool installManager::writeSeparator()
     115{   this->logfile << " ";
     116    return true;
     117}
     118
     119string installManager::readString()
     120{   string reply = "";
     121    char c;
     122
     123  if (this->logfile.eof())
     124    {   return reply;
     125  }
     126
     127  this->logfile >> c;
     128  while (c <= ' ' && !this->logfile.eof())
     129  { this->logfile.get();
     130  }
     131
     132  if (this->logfile.eof())
     133  { return reply;
     134  }
     135
     136  if (c == '\"')
     137  { do
     138    {   c = this->logfile.get();
     139        if (c != '\"')
     140      { reply += c;
     141      }
     142    }
     143    while (c != '\"' && !this->logfile.eof());
     144  }
     145  else
     146  { while (c > ' ')
     147    { reply += c;
     148        if (this->logfile.eof())
     149      { break;
     150      }
     151        c = this->logfile.get();
     152    }
     153    if (!this->logfile.eof())
     154    {   this->logfile.putback(c);
     155    }
     156    //this->logfile >> reply;
     157  }
     158  return reply;
     159}
     160
     161string installManager::readCommand(stringArray &array)
     162{   string reply = "";
     163  char c;
     164
     165  array.clear();
     166
     167  if (this->logfile.eof())
     168  { return reply;
     169  }
     170
     171    reply = this->readString();
     172  if (reply == "")
     173  { return reply;
     174  }
     175
     176  while(!this->logfile.eof() &&
     177            (c = this->logfile.get()) != '\n')
     178  { this->logfile.putback(c);
     179    array.add(this->readString());
     180  }
     181  if (!this->logfile.eof())
     182  { this->logfile.putback(c);
     183  }
     184
     185  return reply;
     186}
     187
     188string installManager::popCommand(stringArray &array)
     189{ string command;
     190
     191  if (this->modules[this->currentModule].size() == 0)
     192  { command = "";
     193  }
     194  else
     195  { unsigned int last;
     196
     197      last = this->modules[this->currentModule].size() - 1;
     198    command = this->modules[this->currentModule][last].commandName();
     199    array       = this->modules[this->currentModule][last].parameterList();
     200    this->modules[this->currentModule].erase(this->modules[this->currentModule].begin() + last);
     201  }
     202  return command;
     203}
     204
     205bool installManager::recordLog()
     206{
     207    // just return if there are no changes to record
     208    if (this->changed == false)
     209    {   return true;
     210    }
     211
    22212  // if the file didn't open, then this is almost certainly being compiled
    23213  // with Microsoft Visual C++ which has a library which fails to open the
    24214  // file if it doesn't already exist.  Do a createfile and hope for success.
    25215  // TODO: add proper error handling here
    26   if (!this->logfile.rdbuf()->is_open() && write == true)
    27     {
    28       HANDLE fHandle;
    29       fHandle = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
    30                FILE_SHARE_WRITE, NULL, CREATE_NEW,
    31                FILE_ATTRIBUTE_NORMAL, NULL);
    32       if (fHandle)
    33     {
    34       CloseHandle(fHandle);
    35     }
    36       this->logfile.open(filename.c_str(), ios::out | ios::in);
    37     }
    38 
    39   // if we aren't seeking write access, then get the commands into this
    40   // object
    41   if (write == false)
    42     {
    43       while ((command = this->readCommand(params)) != "")
    44     {
    45       if (command[0] == '[' && command[command.length()-1] == ']')
    46         {
    47           this->setModule(command.substr(1, command.length() - 2));
    48         }
    49       else
    50         {   
    51           unInstallCommand action(command, params);
    52           this->storeCommand(action);
    53         }
    54     }
    55     }
    56 
    57   // set to the default module
    58   this->setModule("default");
    59   return true;
    60 }
    61 
    62 bool installManager::reopenLog()
    63 {
    64   if (this->logfile.rdbuf()->is_open())
    65     {
    66       this->logfile.close();
    67     }
    68   else
    69     {
    70       this->logfile.close();
    71     }
    72  
    73   this->logfile.open(this->logfileName.c_str(), ios::out | ios::in);
    74   return true;
    75 }
    76 
    77 void installManager::setModule(string moduleName)
    78 {
    79   this->currentModule = moduleName;
    80 }
    81 
    82 bool installManager::storeCommand(unInstallCommand &command)
    83 {
    84   this->modules[this->currentModule].push_back(command);
    85   return true;
    86 }
    87 
    88 bool installManager::writeCommand(unInstallCommand &command)
    89 {
    90   if (!this->writeString(command.command))
    91     {
    92       return false;
    93     }
    94   for (unsigned int p = 0; p < command.parameters.size(); p ++)
    95     {
    96       if (!this->writeSeparator())
    97     {
    98       return false;
    99     }
    100       if (!this->writeString(command.parameters[p]))
    101     {
    102       return false;
    103     }
    104     }
    105   if (!this->writeString("\n"))
    106     {
    107       return false;
    108     }
    109   return true;
    110 }
    111 
    112 bool installManager::writeString(char *buffer)
    113 {
    114   string s(buffer);
    115   return this->writeString(s);
    116 }
    117 
    118 bool installManager::writeString(string str)
    119 {
    120   bool quote;
    121 
    122   // TODO: check for space characters in str and quote if necessary
    123   quote = str.find_first_of(' ') < str.length();
    124 
    125   if (quote)
    126     {
    127       this->logfile << string("\"");
    128     }
    129   this->logfile << str;
    130 
    131   if (quote)
    132     {
    133       this->logfile << string("\"");
    134     }
    135   return true;
    136 }
    137 
    138 bool installManager::writeSeparator()
    139 {
    140   this->logfile << string(" ");
    141   return true;
    142 }
    143 
    144 string installManager::readString()
    145 {
    146   string reply = "";
    147   char c;
    148 
    149   if (this->logfile.eof())
    150     {
    151       return reply;
    152     }
    153 
    154   this->logfile >> c;
    155   while (c <= ' ' && !this->logfile.eof())
    156     {
    157       this->logfile.get();
    158     }
    159  
    160   if (this->logfile.eof())
    161     {
    162       return reply;
    163     }
    164  
    165   if (c == '\"')
    166     {
    167       do
    168     {
    169       c = this->logfile.get();
    170       if (c != '\"')
    171         {
    172           reply += c;
    173         }
    174     }
    175       while (c != '\"' && !this->logfile.eof());
    176     }
    177   else
    178     {
    179       while (c > ' ')
    180     {
    181       reply += c;
    182       if (this->logfile.eof())
    183         {
    184           break;
    185         }
    186       c = this->logfile.get();
    187     }
    188       if (!this->logfile.eof())
    189     {
    190       this->logfile.putback(c);
    191     }
    192       //this->logfile >> reply;
    193     }
    194   return reply;
    195 }
    196 
    197 string installManager::readCommand(stringArray &array)
    198 {
    199   string reply = "";
    200   char c;
    201  
    202   array.clear();
    203  
    204   if (this->logfile.eof())
    205     {
    206       return reply;
    207     }
    208  
    209   reply = this->readString();
    210   if (reply == "")
    211     {
    212       return reply;
    213     }
    214  
    215   while(!this->logfile.eof() &&
    216     (c = this->logfile.get()) != '\n')
    217     {
    218       this->logfile.putback(c);
    219       array.add(this->readString());
    220     }
    221   if (!this->logfile.eof())
    222     {
    223       this->logfile.putback(c);
    224     }
    225  
    226   return reply;
    227 }
    228 
    229 string installManager::popCommand(stringArray &array)
    230 {
    231   string command;
    232  
    233   if (this->modules[this->currentModule].size() == 0)
    234     {
    235       command = "";
    236     }
    237   else
    238     {
    239       unsigned int last;
    240      
    241       last = this->modules[this->currentModule].size() - 1;
    242       command = this->modules[this->currentModule][last].commandName();
    243       array = this->modules[this->currentModule][last].parameterList();
    244       this->modules[this->currentModule].erase(this->modules[this->currentModule].begin() + last);
    245     }
    246   return command;
    247 }
    248 
    249 bool installManager::closeLog()
    250 {
    251   if (this->logfile.rdbuf()->is_open() == false)
    252     {
    253       return false;
    254     }
    255 
    256   unInstallCommandMap::iterator here = this->modules.begin();
    257   unInstallCommandMap::iterator end = this->modules.end();
    258  
     216    this->ensureLog();
     217    this->logfile.open(this->logfileName.c_str(), ios::out);
     218   
     219    unInstallCommandMap::iterator here = this->modules.begin();
     220    unInstallCommandMap::iterator end  = this->modules.end();
     221
     222    while (here != end)
     223    {   
     224        this->writeString("[" + (*here).first + "]\n");
     225   
     226        unInstallCommandList::iterator  ahere = (*here).second.begin();
     227        unInstallCommandList::iterator  aend  = (*here).second.end();
     228
     229        while (ahere != aend)
     230        {   this->writeCommand(*ahere);
     231            ahere ++;
     232        }
     233        here ++;
     234    }
     235    this->logfile.close();
     236
     237    this->changed = false;
     238
     239    return true;
     240}
     241
     242bool installManager::isEmpty()
     243{ unInstallCommandMap::iterator here = this->modules.begin();
     244    unInstallCommandMap::iterator end  = this->modules.end();
     245
    259246  while (here != end)
    260     {
    261       this->writeString("[" + (*here).first + "]\n");
    262      
    263       unInstallCommandList::iterator ahere = (*here).second.begin();
    264       unInstallCommandList::iterator aend  = (*here).second.end();
    265       while (ahere != aend)
    266     {
    267       this->writeCommand(*ahere);
    268       ahere ++;
    269     }
    270       here ++;
    271     }
    272   this->logfile.close();
    273   return true;
    274 }
    275 
    276 bool installManager::isEmpty()
    277 {
    278   unInstallCommandMap::iterator here = this->modules.begin();
    279   unInstallCommandMap::iterator end = this->modules.end();
    280 
    281   while (here != end)
    282     {
    283       this->writeString("[" + (*here).first + "]\n");
    284 
    285       unInstallCommandList::iterator ahere = (*here).second.begin();
    286       unInstallCommandList::iterator aend = (*here).second.end();
    287       if (ahere != aend)
    288     {
    289       return false;
    290     }
    291       here ++;
    292     }
     247  { this->writeString("[" + (*here).first + "]\n");
     248
     249    unInstallCommandList::iterator  ahere = (*here).second.begin();
     250    unInstallCommandList::iterator  aend  = (*here).second.end();
     251    if (ahere != aend)
     252    {   return false;
     253    }
     254    here ++;
     255  }
    293256  return true;
    294257}
    295258
    296259installManager::~installManager()
    297 {
    298   if (this->logfile.rdbuf()->is_open())
    299     {
    300       this->closeLog();
    301     }
    302 }
     260{   this->recordLog();
     261}
  • trunk/gsinstaller/unInstall.h

    r1539 r1638  
    5555  string currentModule;
    5656  unInstallCommandMap modules;
     57  bool  changed;
    5758
    5859  bool writeString(string str);
     
    6364  string readCommand(stringArray &params);
    6465public:
    65   installManager() { };
    66   bool openLog(string filename, bool write);
    67   bool closeLog();
    68   bool reopenLog();
     66  installManager() { this->changed = false; }
     67  bool setLogFile(string filename);
     68  bool ensureLog();
     69  bool readLog();
     70  bool recordLog();
    6971  void setModule(string moduleName);
    7072  bool storeCommand(unInstallCommand &command);
Note: See TracChangeset for help on using the changeset viewer.