Exemplo n.º 1
0
Errors EntryList_appendCString(EntryList    *entryList,
                               EntryTypes   type,
                               const char   *pattern,
                               PatternTypes patternType
                              )
{
  EntryNode *entryNode;
  #if   defined(PLATFORM_LINUX)
  #elif defined(PLATFORM_WINDOWS)
    String    string;
  #endif /* PLATFORM_... */
  Errors    error;

  assert(entryList != NULL);
  assert(pattern != NULL);

  // allocate entry node
  entryNode = LIST_NEW_NODE(EntryNode);
  if (entryNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  entryNode->type   = type;
  entryNode->string = String_newCString(pattern);

  // init pattern
  #if   defined(PLATFORM_LINUX)
    error = Pattern_initCString(&entryNode->pattern,
                                pattern,
                                patternType,
                                PATTERN_FLAG_NONE
                               );
  #elif defined(PLATFORM_WINDOWS)
    // escape all '\' by '\\'
    string = String_newCString(pattern);
    String_replaceAllCString(string,STRING_BEGIN,"\\","\\\\");

    error = Pattern_init(&entryNode->pattern,
                         string,
                         patternType,
                         PATTERN_FLAG_IGNORE_CASE
                        );

    // free resources
    String_delete(string);
  #endif /* PLATFORM_... */
  if (error != ERROR_NONE)
  {
    String_delete(entryNode->string);
    LIST_DELETE_NODE(entryNode);
    return error;
  }

  // add to list
  List_append(entryList,entryNode);

  return ERROR_NONE;
}
Exemplo n.º 2
0
LOCAL EntryNode *copyEntryNode(EntryNode *entryNode,
                               void      *userData
                              )
{
  EntryNode *newEntryNode;
  #if   defined(PLATFORM_LINUX)
  #elif defined(PLATFORM_WINDOWS)
    String    string;
  #endif /* PLATFORM_... */
  Errors    error;

  assert(entryNode != NULL);

  UNUSED_VARIABLE(userData);

  // allocate entry node
  newEntryNode = LIST_NEW_NODE(EntryNode);
  if (newEntryNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }

  // create entry
  newEntryNode->type   = entryNode->type;
  newEntryNode->string = String_duplicate(entryNode->string);
  #if   defined(PLATFORM_LINUX)
    error = Pattern_init(&newEntryNode->pattern,
                         entryNode->string,
                         entryNode->pattern.type,
                         PATTERN_FLAG_NONE
                        );
  #elif defined(PLATFORM_WINDOWS)
    // escape all '\' by '\\'
    string = String_duplicate(entryNode->string);
    String_replaceAllCString(string,STRING_BEGIN,"\\","\\\\");

    error = Pattern_init(&newEntryNode->pattern,
                         string,
                         entryNode->pattern.type|,
                         PATTERN_FLAG_IGNORE_CASE
                        );

    // free resources
    String_delete(string);
  #endif /* PLATFORM_... */
  if (error != ERROR_NONE)
  {
    String_delete(newEntryNode->string);
    LIST_DELETE_NODE(newEntryNode);
    return NULL;
  }

  return newEntryNode;
}
Exemplo n.º 3
0
LOCAL PatternNode *copyPatternNode(PatternNode *patternNode,
                                   void        *userData
                                  )
{
  PatternNode *newPatternNode;
  Errors      error;

  assert(patternNode != NULL);

  UNUSED_VARIABLE(userData);

  // allocate pattern node
  newPatternNode = LIST_NEW_NODE(PatternNode);
  if (newPatternNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  newPatternNode->string = String_duplicate(patternNode->string);

  // create pattern
  error = Pattern_init(&newPatternNode->pattern,
                       patternNode->string,
                       patternNode->pattern.type,
                       patternNode->pattern.flags
                      );
  if (error != ERROR_NONE)
  {
    String_delete(newPatternNode->string);
    LIST_DELETE_NODE(newPatternNode);
    return NULL;
  }

  return newPatternNode;
}
Exemplo n.º 4
0
void PathName_setSeparator(String* sep)
{
    if (NULL != _separator)
    {
        String_delete(_separator);
    }
    _separator = sep;
}
Exemplo n.º 5
0
LOCAL void freeStringNode(StringNode *stringNode, void *userData)
{
  assert(stringNode != NULL);

  UNUSED_VARIABLE(userData);

  String_delete(stringNode->string);
}
Exemplo n.º 6
0
LOCAL void freeFileFragmentNode(FileFragmentNode *fileFragmentNode, void *userData)
{
  assert(fileFragmentNode != NULL);

  UNUSED_VARIABLE(userData);

  List_done(&fileFragmentNode->fragmentList,NULL,NULL);
  String_delete(fileFragmentNode->fileName);
}
Exemplo n.º 7
0
void PathName_delete(PathName* self)
{
    smug_assert(_invariant(self));
    if (self->root)
    {
        String_delete(self->root);
    }
    if (self->bareName)
    {
        String_delete(self->bareName);
        if (self->extension)
        {
            String_delete(self->extension);
        }
    }
    LinkedList_deleteContents(self->path, String_deleteVoid);
    LinkedList_delete(self->path);
    free(self);
}
Exemplo n.º 8
0
Errors File_close(FileHandle *fileHandle)
{
  assert(fileHandle != NULL);
  assert(fileHandle->file != NULL);
  assert(fileHandle->name != NULL);
 
  fclose(fileHandle->file);
  fileHandle->file = NULL;
  String_delete(fileHandle->name);

  return ERROR_NONE;
}
Exemplo n.º 9
0
Errors Device_close(DeviceHandle *deviceHandle)
{
  assert(deviceHandle != NULL);
  assert(deviceHandle->file != NULL);
  assert(deviceHandle->name != NULL);

  fclose(deviceHandle->file);
  deviceHandle->file = NULL;
  String_delete(deviceHandle->name);

  return ERROR_NONE;
}
Exemplo n.º 10
0
LOCAL void freeEntryNode(EntryNode *entryNode,
                         void      *userData
                        )
{
  assert(entryNode != NULL);
  assert(entryNode->string != NULL);

  UNUSED_VARIABLE(userData);

  Pattern_done(&entryNode->pattern);
  String_delete(entryNode->string);
}
Exemplo n.º 11
0
LOCAL void freePatternNode(PatternNode *patternNode,
                           void        *userData
                          )
{
  assert(patternNode != NULL);
  assert(patternNode->string != NULL);

  UNUSED_VARIABLE(userData);

  Pattern_done(&patternNode->pattern);
  String_delete(patternNode->string);
}
Exemplo n.º 12
0
Errors File_printLine(FileHandle *fileHandle,
                      const char *format,
                      ...
                     )
{
  String  line;
  va_list arguments;
  Errors  error;

  assert(fileHandle != NULL);
  assert(fileHandle->file != NULL);
  assert(format != NULL);

  /* initialise variables */
  line = String_new();

  /* format line */
  va_start(arguments,format);
  String_vformat(line,format,arguments);
  va_end(arguments);

  /* write line */
  error = File_write(fileHandle,String_cString(line),String_length(line));
  if (error != ERROR_NONE)
  {
    String_delete(line);
    return error;
  }
  error = File_write(fileHandle,"\n",1);
  if (error != ERROR_NONE)
  {
    String_delete(line);
    return error;
  }

  /* free resources */
  String_delete(line);

  return ERROR_NONE;
}
Exemplo n.º 13
0
LOCAL void freeFragmentNode(FragmentNode *fragmentNode, void *userData)
{
  assert(fragmentNode != NULL);

  UNUSED_VARIABLE(userData);

  List_done(&fragmentNode->fragmentEntryList,NULL,NULL);
  if (fragmentNode->userData != NULL)
  {
    free(fragmentNode->userData);
  }
  String_delete(fragmentNode->name);
}
Exemplo n.º 14
0
LOCAL String getDestinationFileName(String       destinationFileName,
                                    String       fileName,
                                    const String directory,
                                    uint         directoryStripCount
                                   )
{
    String          pathName,baseName,name;
    StringTokenizer fileNameTokenizer;
    int             z;

    assert(destinationFileName != NULL);
    assert(fileName != NULL);

    if (directory != NULL)
    {
        File_setFileName(destinationFileName,directory);
    }
    else
    {
        String_clear(destinationFileName);
    }
    File_splitFileName(fileName,&pathName,&baseName);
    File_initSplitFileName(&fileNameTokenizer,pathName);
    z = 0;
    while ((z< directoryStripCount) && File_getNextSplitFileName(&fileNameTokenizer,&name))
    {
        z++;
    }
    while (File_getNextSplitFileName(&fileNameTokenizer,&name))
    {
        File_appendFileName(destinationFileName,name);
    }
    File_doneSplitFileName(&fileNameTokenizer);
    File_appendFileName(destinationFileName,baseName);
    String_delete(pathName);
    String_delete(baseName);

    return destinationFileName;
}
Exemplo n.º 15
0
String* PathName_getAsString(PathName* self)
{
    smug_assert(_invariant(self));
    String* path;
    String* fullPath;

    path = String_newJoin(self->path, _getSeparator());
    if (self->root != NULL)
    {
        fullPath = String_newConcat(self->root, path);
        String_delete(path);
    }
    else
    {
        fullPath = path;
    }
    return fullPath;
}
Exemplo n.º 16
0
/*---------------------------------------------------------------------*/

void StringList_init(StringList *stringList)
{
  assert(stringList != NULL);

  List_init(stringList);
}

void StringList_done(StringList *stringList)
{
  assert(stringList != NULL);

  List_done(stringList,(ListNodeFreeFunction)freeStringNode,NULL);
}

StringList *StringList_new(void)
{
  return (StringList*)List_new();
}

StringList *StringList_duplicate(const StringList *stringList)
{
  StringList *newStringList;

  assert(stringList != NULL);

  newStringList = StringList_new();
  if (newStringList == NULL)
  {
    return NULL;
  }

  StringList_copy(newStringList,stringList);

  return newStringList;
}

void StringList_copy(StringList *stringList, const StringList *fromStringList)
{
  StringNode *stringNode;

  assert(stringList != NULL);
  assert(fromStringList != NULL);

  stringNode = fromStringList->head;
  while (stringNode != NULL)
  {
    StringList_append(stringList,stringNode->string);
    stringNode = stringNode->next;
  }
}

void StringList_delete(StringList *stringList)
{
  assert(stringList != NULL);

  List_delete(stringList,(ListNodeFreeFunction)freeStringNode,NULL);
}

void StringList_clear(StringList *stringList)
{
  assert(stringList != NULL);

  List_clear(stringList,(ListNodeFreeFunction)freeStringNode,NULL);
}

void StringList_move(StringList *fromStringList, StringList *toStringList)
{
  assert(fromStringList != NULL);
  assert(toStringList != NULL);

  List_move(fromStringList,toStringList,NULL,NULL,NULL);
}

#ifdef NDEBUG
void StringList_insert(StringList *stringList, const String string, StringNode *nextStringNode)
#else /* not NDEBUG */
void __StringList_insert(const char *__fileName__, ulong __lineNb__, StringList *stringList, const String string, StringNode *nextStringNode)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_duplicate(string),nextStringNode);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_duplicate(__fileName__,__lineNb__,string),nextStringNode);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_insertCString(StringList *stringList, const char *s, StringNode *nextStringNode)
#else /* not NDEBUG */
void __StringList_insertCString(const char *__fileName__, ulong __lineNb__, StringList *stringList, const char *s, StringNode *nextStringNode)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newCString(s),nextStringNode);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newCString(__fileName__,__lineNb__,s),nextStringNode);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_insertChar(StringList *stringList, char ch, StringNode *nextStringNode)
#else /* not NDEBUG */
void __StringList_insertChar(const char *__fileName__, ulong __lineNb__, StringList *stringList, char ch, StringNode *nextStringNode)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newChar(ch),nextStringNode);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newChar(__fileName__,__lineNb__,ch),nextStringNode);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_insertBuffer(StringList *stringList, char *buffer, ulong bufferLength, StringNode *nextStringNode)
#else /* not NDEBUG */
void __StringList_insertBuffer(const char *__fileName__, ulong __lineNb__, StringList *stringList, char *buffer, ulong bufferLength, StringNode *nextStringNode)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newBuffer(buffer,bufferLength),nextStringNode);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newBuffer(__fileName__,__lineNb__,buffer,bufferLength),nextStringNode);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_append(StringList *stringList, const String string)
#else /* not NDEBUG */
void __StringList_append(const char *__fileName__, ulong __lineNb__, StringList *stringList, const String string)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_duplicate(string),NULL);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_duplicate(__fileName__,__lineNb__,string),NULL);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_appendCString(StringList *stringList, const char *s)
#else /* not NDEBUG */
void __StringList_appendCString(const char *__fileName__, ulong __lineNb__, StringList *stringList, const char *s)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newCString(s),NULL);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newCString(__fileName__,__lineNb__,s),NULL);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_appendChar(StringList *stringList, char ch)
#else /* not NDEBUG */
void __StringList_appendChar(const char *__fileName__, ulong __lineNb__, StringList *stringList, char ch)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newChar(ch),NULL);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newChar(__fileName__,__lineNb__,ch),NULL);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_appendBuffer(StringList *stringList, char *buffer, ulong bufferLength)
#else /* not NDEBUG */
void __StringList_appendBuffer(const char *__fileName__, ulong __lineNb__, StringList *stringList, char *buffer, ulong bufferLength)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newBuffer(buffer,bufferLength),NULL);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newBuffer(__fileName__,__lineNb__,buffer,bufferLength),NULL);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
StringNode *StringList_remove(StringList *stringList, StringNode *stringNode)
#else /* not NDEBUG */
StringNode *__StringList_remove(const char *__fileName__, ulong __lineNb__, StringList *stringList, StringNode *stringNode)
#endif /* NDEBUG */
{
  StringNode *nextStringNode;

  assert(stringList != NULL);
  assert(stringNode != NULL);

  nextStringNode = (StringNode*)List_remove(stringList,stringNode);

  String_delete(stringNode->string);
  #ifdef NDEBUG
    stringNode = (StringNode*)LIST_DELETE_NODE(stringNode);
  #else /* not NDEBUG */
    stringNode = (StringNode*)__LIST_DELETE_NODE(__fileName__,__lineNb__,stringNode);
  #endif /* NDEBUG */

  return nextStringNode;
}
Exemplo n.º 17
0
String* PathName_getFileName(PathName* self)
{
    String* ret;
    String* temp;

    smug_assert(_invariant(self));

    if (NULL == self->bareName) return NULL;

    if (NULL == self->extension || String_isEmpty(self->extension))
    {
        ret = String_newCopy(self->bareName);
    }
    else
    {
        temp = String_newConcat(self->bareName, _getDot());
        ret = String_newConcat(temp, self->extension);
        String_delete(temp);
    }
    return ret;
}
Exemplo n.º 18
0
/*---------------------------------------------------------------------*/

void StringList_init(StringList *stringList)
{
  assert(stringList != NULL);

  List_init(stringList);
}

void StringList_done(StringList *stringList)
{
  assert(stringList != NULL);

  List_done(stringList,(ListNodeFreeFunction)freeStringNode,NULL);
}

StringList *StringList_new(void)
{
  return (StringList*)List_new();
}

StringList *StringList_duplicate(const StringList *stringList)
{
  StringList *newStringList;

  assert(stringList != NULL);

  newStringList = StringList_new();
  if (newStringList == NULL)
  {
    return NULL;
  }

  StringList_copy(newStringList,stringList);

  return newStringList;
}

void StringList_copy(StringList *stringList, const StringList *fromStringList)
{
  StringNode *stringNode;

  assert(stringList != NULL);
  assert(fromStringList != NULL);

  stringNode = fromStringList->head;
  while (stringNode != NULL)
  {
    StringList_append(stringList,stringNode->string);
    stringNode = stringNode->next;
  }
}

void StringList_delete(StringList *stringList)
{
  assert(stringList != NULL);

  List_delete(stringList,(ListNodeFreeFunction)freeStringNode,NULL);
}

void StringList_clear(StringList *stringList)
{
  assert(stringList != NULL);

  List_clear(stringList,(ListNodeFreeFunction)freeStringNode,NULL);
}

void StringList_move(StringList *fromStringList, StringList *toStringList)
{
  assert(fromStringList != NULL);
  assert(toStringList != NULL);

  List_move(fromStringList,toStringList,NULL,NULL,NULL);
}

#ifdef NDEBUG
void StringList_insert(StringList *stringList, const String string, StringNode *nextStringNode)
#else /* not NDEBUG */
void __StringList_insert(const char *__fileName__, ulong __lineNb__, StringList *stringList, const String string, StringNode *nextStringNode)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_duplicate(string),nextStringNode);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_duplicate(__fileName__,__lineNb__,string),nextStringNode);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_insertCString(StringList *stringList, const char *s, StringNode *nextStringNode)
#else /* not NDEBUG */
void __StringList_insertCString(const char *__fileName__, ulong __lineNb__, StringList *stringList, const char *s, StringNode *nextStringNode)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newCString(s),nextStringNode);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newCString(__fileName__,__lineNb__,s),nextStringNode);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_insertChar(StringList *stringList, char ch, StringNode *nextStringNode)
#else /* not NDEBUG */
void __StringList_insertChar(const char *__fileName__, ulong __lineNb__, StringList *stringList, char ch, StringNode *nextStringNode)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newChar(ch),nextStringNode);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newChar(__fileName__,__lineNb__,ch),nextStringNode);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_insertBuffer(StringList *stringList, char *buffer, ulong bufferLength, StringNode *nextStringNode)
#else /* not NDEBUG */
void __StringList_insertBuffer(const char *__fileName__, ulong __lineNb__, StringList *stringList, char *buffer, ulong bufferLength, StringNode *nextStringNode)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newBuffer(buffer,bufferLength),nextStringNode);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newBuffer(__fileName__,__lineNb__,buffer,bufferLength),nextStringNode);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_append(StringList *stringList, const String string)
#else /* not NDEBUG */
void __StringList_append(const char *__fileName__, ulong __lineNb__, StringList *stringList, const String string)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_duplicate(string),NULL);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_duplicate(__fileName__,__lineNb__,string),NULL);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_appendCString(StringList *stringList, const char *s)
#else /* not NDEBUG */
void __StringList_appendCString(const char *__fileName__, ulong __lineNb__, StringList *stringList, const char *s)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newCString(s),NULL);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newCString(__fileName__,__lineNb__,s),NULL);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_appendChar(StringList *stringList, char ch)
#else /* not NDEBUG */
void __StringList_appendChar(const char *__fileName__, ulong __lineNb__, StringList *stringList, char ch)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newChar(ch),NULL);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newChar(__fileName__,__lineNb__,ch),NULL);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
void StringList_appendBuffer(StringList *stringList, char *buffer, ulong bufferLength)
#else /* not NDEBUG */
void __StringList_appendBuffer(const char *__fileName__, ulong __lineNb__, StringList *stringList, char *buffer, ulong bufferLength)
#endif /* NDEBUG */
{
  #ifdef NDEBUG
    insertString(stringList,String_newBuffer(buffer,bufferLength),NULL);
  #else /* not NDEBUG */
    insertString(__fileName__,__lineNb__,stringList,__String_newBuffer(__fileName__,__lineNb__,buffer,bufferLength),NULL);
  #endif /* NDEBUG */
}

#ifdef NDEBUG
StringNode *StringList_remove(StringList *stringList, StringNode *stringNode)
#else /* not NDEBUG */
StringNode *__StringList_remove(const char *__fileName__, ulong __lineNb__, StringList *stringList, StringNode *stringNode)
#endif /* NDEBUG */
{
  StringNode *nextStringNode;

  assert(stringList != NULL);
  assert(stringNode != NULL);

  nextStringNode = (StringNode*)List_remove(stringList,stringNode);

  String_delete(stringNode->string);
  #ifdef NDEBUG
    stringNode = (StringNode*)LIST_DELETE_NODE(stringNode);
  #else /* not NDEBUG */
    stringNode = (StringNode*)__LIST_DELETE_NODE(__fileName__,__lineNb__,stringNode);
  #endif /* NDEBUG */

  return nextStringNode;
}

#ifdef NDEBUG
String StringList_getFirst(StringList *stringList, String string)
#else /* not NDEBUG */
String __StringList_getFirst(const char *fileName, ulong lineNb, StringList *stringList, String string)
#endif /* NDEBUG */
{
  StringNode *stringNode;

  assert(stringList != NULL);

  stringNode = (StringNode*)List_getFirst(stringList);
  if (stringNode != NULL)
  {
    if (string != NULL)
    {
      String_set(string,stringNode->string);
      String_delete(stringNode->string);
    }
    else
    {
      string = stringNode->string;
    }
    #ifdef NDEBUG
      LIST_DELETE_NODE(stringNode);
    #else /* not NDEBUG */
      __LIST_DELETE_NODE(fileName,lineNb,stringNode);
    #endif /* NDEBUG */

    return string;
  }
  else
  {
    if (string != NULL)
    {
      String_clear(string);
    }

    return NULL;
  }
}

#ifdef NDEBUG
String StringList_getLast(StringList *stringList, String string)
#else /* not NDEBUG */
String __StringList_getLast(const char *fileName, ulong lineNb, StringList *stringList, String string)
#endif /* NDEBUG */
{
  StringNode *stringNode;

  assert(stringList != NULL);

  stringNode = (StringNode*)List_getLast(stringList);
  if (stringNode != NULL)
  {
    if (string != NULL)
    {
      String_set(string,stringNode->string);
      String_delete(stringNode->string);
    }
    else
    {
      string = stringNode->string;
    }
    #ifdef NDEBUG
      LIST_DELETE_NODE(stringNode);
    #else /* not NDEBUG */
      __LIST_DELETE_NODE(fileName,lineNb,stringNode);
    #endif /* NDEBUG */

    return string;
  }
  else
  {
    if (string != NULL)
    {
      String_clear(string);
    }

    return NULL;
  }
}
Exemplo n.º 19
0
Errors PatternList_appendCString(PatternList  *patternList,
                                 const char   *pattern,
                                 PatternTypes patternType
                                )
{
  PatternNode *patternNode;
  Errors      error;

  assert(patternList != NULL);
  assert(pattern != NULL);

  // allocate pattern node
  patternNode = LIST_NEW_NODE(PatternNode);
  if (patternNode == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  patternNode->string = String_newCString(pattern);

  // init pattern
  error = Pattern_initCString(&patternNode->pattern,
                              pattern,
                              patternType,
                              PATTERN_FLAG_IGNORE_CASE
                             );
  if (error != ERROR_NONE)
  {
    String_delete(patternNode->string);
    LIST_DELETE_NODE(patternNode);
    return error;
  }

  // add to list
  List_append(patternList,patternNode);

  return ERROR_NONE;
}
Exemplo n.º 20
0
Errors Command_restore(StringList                      *archiveFileNameList,
                       PatternList                     *includePatternList,
                       PatternList                     *excludePatternList,
                       JobOptions                      *jobOptions,
                       ArchiveGetCryptPasswordFunction archiveGetCryptPasswordFunction,
                       void                            *archiveGetCryptPasswordUserData,
                       RestoreStatusInfoFunction       restoreStatusInfoFunction,
                       void                            *restoreStatusInfoUserData,
                       bool                            *pauseFlag,
                       bool                            *requestedAbortFlag
                      )
{
    RestoreInfo       restoreInfo;
    byte              *buffer;
    FileFragmentList  fileFragmentList;
    String            archiveFileName;
    Errors            error;
    ArchiveInfo       archiveInfo;
    ArchiveFileInfo   archiveFileInfo;
    FileTypes         fileType;
    FileFragmentNode  *fileFragmentNode;

    assert(archiveFileNameList != NULL);
    assert(includePatternList != NULL);
    assert(excludePatternList != NULL);
    assert(jobOptions != NULL);

    /* initialize variables */
    restoreInfo.includePatternList           = includePatternList;
    restoreInfo.excludePatternList           = excludePatternList;
    restoreInfo.jobOptions                   = jobOptions;
    restoreInfo.pauseFlag                    = pauseFlag;
    restoreInfo.requestedAbortFlag           = requestedAbortFlag;
    restoreInfo.error                        = ERROR_NONE;
    restoreInfo.statusInfoFunction           = restoreStatusInfoFunction;
    restoreInfo.statusInfoUserData           = restoreStatusInfoUserData;
    restoreInfo.statusInfo.doneFiles         = 0L;
    restoreInfo.statusInfo.doneBytes         = 0LL;
    restoreInfo.statusInfo.skippedFiles      = 0L;
    restoreInfo.statusInfo.skippedBytes      = 0LL;
    restoreInfo.statusInfo.errorFiles        = 0L;
    restoreInfo.statusInfo.errorBytes        = 0LL;
    restoreInfo.statusInfo.fileName          = String_new();
    restoreInfo.statusInfo.fileDoneBytes     = 0LL;
    restoreInfo.statusInfo.fileTotalBytes    = 0LL;
    restoreInfo.statusInfo.storageName       = String_new();
    restoreInfo.statusInfo.storageDoneBytes  = 0LL;
    restoreInfo.statusInfo.storageTotalBytes = 0LL;

    /* allocate resources */
    buffer = malloc(BUFFER_SIZE);
    if (buffer == NULL)
    {
        HALT_INSUFFICIENT_MEMORY();
    }
    FileFragmentList_init(&fileFragmentList);
    archiveFileName = String_new();

    while (   ((restoreInfo.requestedAbortFlag == NULL) || !(*restoreInfo.requestedAbortFlag))
              && !StringList_empty(archiveFileNameList)
              && (restoreInfo.error == ERROR_NONE)
          )
    {
        /* pause */
        while ((restoreInfo.pauseFlag != NULL) && (*restoreInfo.pauseFlag))
        {
            Misc_udelay(500*1000);
        }

        StringList_getFirst(archiveFileNameList,archiveFileName);
        printInfo(0,"Restore archive '%s':\n",String_cString(archiveFileName));

        /* open archive */
        error = Archive_open(&archiveInfo,
                             archiveFileName,
                             jobOptions,
                             archiveGetCryptPasswordFunction,
                             archiveGetCryptPasswordUserData
                            );
        if (error != ERROR_NONE)
        {
            printError("Cannot open archive file '%s' (error: %s)!\n",
                       String_cString(archiveFileName),
                       Errors_getText(error)
                      );
            if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
            continue;
        }
        String_set(restoreInfo.statusInfo.storageName,archiveFileName);
        updateStatusInfo(&restoreInfo);

        /* read files */
        while (   ((restoreInfo.requestedAbortFlag == NULL) || !(*restoreInfo.requestedAbortFlag))
                  && !Archive_eof(&archiveInfo)
                  && (restoreInfo.error == ERROR_NONE)
              )
        {
            /* pause */
            while ((restoreInfo.pauseFlag != NULL) && (*restoreInfo.pauseFlag))
            {
                Misc_udelay(500*1000);
            }

            /* get next file type */
            error = Archive_getNextFileType(&archiveInfo,
                                            &archiveFileInfo,
                                            &fileType
                                           );
            if (error != ERROR_NONE)
            {
                printError("Cannot not read next entry in archive '%s' (error: %s)!\n",
                           String_cString(archiveFileName),
                           Errors_getText(error)
                          );
                if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
                break;
            }

            switch (fileType)
            {
            case FILE_TYPE_FILE:
            {
                String           fileName;
                FileInfo         fileInfo;
                uint64           fragmentOffset,fragmentSize;
                FileFragmentNode *fileFragmentNode;
                String           destinationFileName;
                String           directoryName;
//            FileInfo         localFileInfo;
                FileHandle       fileHandle;
                uint64           length;
                ulong            n;

                /* read file */
                fileName = String_new();
                error = Archive_readFileEntry(&archiveInfo,
                                              &archiveFileInfo,
                                              NULL,
                                              NULL,
                                              NULL,
                                              fileName,
                                              &fileInfo,
                                              &fragmentOffset,
                                              &fragmentSize
                                             );
                if (error != ERROR_NONE)
                {
                    printError("Cannot not read 'file' content of archive '%s' (error: %s)!\n",
                               String_cString(archiveFileName),
                               Errors_getText(error)
                              );
                    String_delete(fileName);
                    if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
                    continue;
                }

                if (   (List_empty(includePatternList) || PatternList_match(includePatternList,fileName,PATTERN_MATCH_MODE_EXACT))
                        && !PatternList_match(excludePatternList,fileName,PATTERN_MATCH_MODE_EXACT)
                   )
                {
                    String_set(restoreInfo.statusInfo.fileName,fileName);
                    restoreInfo.statusInfo.fileDoneBytes = 0LL;
                    restoreInfo.statusInfo.fileTotalBytes = fragmentSize;
                    updateStatusInfo(&restoreInfo);

                    /* get destination filename */
                    destinationFileName = getDestinationFileName(String_new(),
                                          fileName,
                                          jobOptions->directory,
                                          jobOptions->directoryStripCount
                                                                );


                    /* check if file fragment exists */
                    fileFragmentNode = FileFragmentList_findFile(&fileFragmentList,fileName);
                    if (fileFragmentNode != NULL)
                    {
                        if (!jobOptions->overwriteFilesFlag && FileFragmentList_checkExists(fileFragmentNode,fragmentOffset,fragmentSize))
                        {
                            printInfo(1,"  Restore file '%s'...skipped (file part %ll..%ll exists)\n",
                                      String_cString(destinationFileName),
                                      fragmentOffset,
                                      (fragmentSize > 0)?fragmentOffset+fragmentSize-1:fragmentOffset
                                     );
                            String_delete(destinationFileName);
                            Archive_closeEntry(&archiveFileInfo);
                            String_delete(fileName);
                            continue;
                        }
                    }
                    else
                    {
                        if (!jobOptions->overwriteFilesFlag && File_exists(destinationFileName))
                        {
                            printInfo(1,"  Restore file '%s'...skipped (file exists)\n",String_cString(destinationFileName));
                            String_delete(destinationFileName);
                            Archive_closeEntry(&archiveFileInfo);
                            String_delete(fileName);
                            continue;
                        }
                        fileFragmentNode = FileFragmentList_addFile(&fileFragmentList,fileName,fileInfo.size);
                    }

                    printInfo(2,"  Restore file '%s'...",String_cString(destinationFileName));

                    /* create directory if not existing */
                    directoryName = File_getFilePathName(String_new(),destinationFileName);
                    if (!File_exists(directoryName))
                    {
                        /* create directory */
                        error = File_makeDirectory(directoryName,
                                                   FILE_DEFAULT_USER_ID,
                                                   FILE_DEFAULT_GROUP_ID,
                                                   fileInfo.permission
                                                  );
                        if (error != ERROR_NONE)
                        {
                            printInfo(2,"FAIL!\n");
                            printError("Cannot create directory '%s' (error: %s)\n",
                                       String_cString(directoryName),
                                       Errors_getText(error)
                                      );
                            String_delete(directoryName);
                            String_delete(destinationFileName);
                            Archive_closeEntry(&archiveFileInfo);
                            String_delete(fileName);
                            if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
                            continue;
                        }

                        /* set owner ship */
                        error = File_setOwner(directoryName,
                                              (jobOptions->owner.userId  != FILE_DEFAULT_USER_ID )?jobOptions->owner.userId:fileInfo.userId,
                                              (jobOptions->owner.groupId != FILE_DEFAULT_GROUP_ID)?jobOptions->owner.groupId:fileInfo.groupId
                                             );
                        if (error != ERROR_NONE)
                        {
                            if (jobOptions->stopOnErrorFlag)
                            {
                                printInfo(2,"FAIL!\n");
                                printError("Cannot set owner ship of directory '%s' (error: %s)\n",
                                           String_cString(directoryName),
                                           Errors_getText(error)
                                          );
                                String_delete(directoryName);
                                String_delete(destinationFileName);
                                Archive_closeEntry(&archiveFileInfo);
                                String_delete(fileName);
                                if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
                                continue;
                            }
                            else
                            {
                                printWarning("Cannot set owner ship of directory '%s' (error: %s)\n",
                                             String_cString(directoryName),
                                             Errors_getText(error)
                                            );
                            }
                        }
                    }
                    String_delete(directoryName);

                    /* write file data */
//if (fileFragmentNode == NULL) File_delete(destinationFileName,TRUE);
                    error = File_open(&fileHandle,destinationFileName,FILE_OPENMODE_WRITE);
                    if (error != ERROR_NONE)
                    {
                        printInfo(2,"FAIL!\n");
                        printError("Cannot create/write to file '%s' (error: %s)\n",
                                   String_cString(destinationFileName),
                                   Errors_getText(error)
                                  );
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(fileName);
                        if (jobOptions->stopOnErrorFlag)
                        {
                            restoreInfo.error = error;
                        }
                        continue;
                    }
                    error = File_seek(&fileHandle,fragmentOffset);
                    if (error != ERROR_NONE)
                    {
                        printInfo(2,"FAIL!\n");
                        printError("Cannot write file '%s' (error: %s)\n",
                                   String_cString(destinationFileName),
                                   Errors_getText(error)
                                  );
                        File_close(&fileHandle);
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(fileName);
                        if (jobOptions->stopOnErrorFlag)
                        {
                            restoreInfo.error = error;
                        }
                        continue;
                    }

                    length = 0;
                    while (   ((restoreInfo.requestedAbortFlag == NULL) || !(*restoreInfo.requestedAbortFlag))
                              && (length < fragmentSize)
                          )
                    {
                        /* pause */
                        while ((restoreInfo.pauseFlag != NULL) && (*restoreInfo.pauseFlag))
                        {
                            Misc_udelay(500*1000);
                        }

                        n = MIN(fragmentSize-length,BUFFER_SIZE);

                        error = Archive_readFileData(&archiveFileInfo,buffer,n);
                        if (error != ERROR_NONE)
                        {
                            printInfo(2,"FAIL!\n");
                            printError("Cannot not read content of archive '%s' (error: %s)!\n",
                                       String_cString(archiveFileName),
                                       Errors_getText(error)
                                      );
                            if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
                            break;
                        }
                        error = File_write(&fileHandle,buffer,n);
                        if (error != ERROR_NONE)
                        {
                            printInfo(2,"FAIL!\n");
                            printError("Cannot write file '%s' (error: %s)\n",
                                       String_cString(destinationFileName),
                                       Errors_getText(error)
                                      );
                            if (jobOptions->stopOnErrorFlag)
                            {
                                restoreInfo.error = error;
                            }
                            break;
                        }
                        restoreInfo.statusInfo.fileDoneBytes += n;
                        updateStatusInfo(&restoreInfo);

                        length += n;
                    }
                    if (File_getSize(&fileHandle) > fileInfo.size)
                    {
                        File_truncate(&fileHandle,fileInfo.size);
                    }
                    File_close(&fileHandle);
                    if ((restoreInfo.requestedAbortFlag != NULL) && (*restoreInfo.requestedAbortFlag))
                    {
                        printInfo(2,"ABORTED\n");
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(fileName);
                        continue;
                    }
#if 0
                    if (restoreInfo.error != ERROR_NONE)
                    {
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(fileName);
                        continue;
                    }
#endif /* 0 */

                    /* set file time, file owner/group */
                    if (jobOptions->owner.userId  != FILE_DEFAULT_USER_ID ) fileInfo.userId  = jobOptions->owner.userId;
                    if (jobOptions->owner.groupId != FILE_DEFAULT_GROUP_ID) fileInfo.groupId = jobOptions->owner.groupId;
                    error = File_setFileInfo(destinationFileName,&fileInfo);
                    if (error != ERROR_NONE)
                    {
                        if (jobOptions->stopOnErrorFlag)
                        {
                            printInfo(2,"FAIL!\n");
                            printError("Cannot set file info of '%s' (error: %s)\n",
                                       String_cString(destinationFileName),
                                       Errors_getText(error)
                                      );
                            String_delete(destinationFileName);
                            Archive_closeEntry(&archiveFileInfo);
                            String_delete(fileName);
                            restoreInfo.error = error;
                            continue;
                        }
                        else
                        {
                            printWarning("Cannot set file info of '%s' (error: %s)\n",
                                         String_cString(destinationFileName),
                                         Errors_getText(error)
                                        );
                        }
                    }

                    /* add fragment to file fragment list */
                    FileFragmentList_add(fileFragmentNode,fragmentOffset,fragmentSize);
//FileFragmentList_print(fileFragmentNode,String_cString(fileName));

                    /* discard fragment list if file is complete */
                    if (FileFragmentList_checkComplete(fileFragmentNode))
                    {
                        FileFragmentList_removeFile(&fileFragmentList,fileFragmentNode);
                    }

                    /* free resources */
                    String_delete(destinationFileName);

                    printInfo(2,"ok\n");
                }
                else
                {
                    /* skip */
                    printInfo(3,"  Restore '%s'...skipped\n",String_cString(fileName));
                }

                /* close archive file, free resources */
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
            }
            break;
            case FILE_TYPE_DIRECTORY:
            {
                String   directoryName;
                FileInfo fileInfo;
                String   destinationFileName;
//            FileInfo localFileInfo;

                /* read directory */
                directoryName = String_new();
                error = Archive_readDirectoryEntry(&archiveInfo,
                                                   &archiveFileInfo,
                                                   NULL,
                                                   NULL,
                                                   directoryName,
                                                   &fileInfo
                                                  );
                if (error != ERROR_NONE)
                {
                    printError("Cannot not read 'directory' content of archive '%s' (error: %s)!\n",
                               String_cString(archiveFileName),
                               Errors_getText(error)
                              );
                    String_delete(directoryName);
                    if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
                    break;
                }

                if (   (List_empty(includePatternList) || PatternList_match(includePatternList,directoryName,PATTERN_MATCH_MODE_EXACT))
                        && !PatternList_match(excludePatternList,directoryName,PATTERN_MATCH_MODE_EXACT)
                   )
                {
                    String_set(restoreInfo.statusInfo.fileName,directoryName);
                    restoreInfo.statusInfo.fileDoneBytes = 0LL;
                    restoreInfo.statusInfo.fileTotalBytes = 00L;
                    updateStatusInfo(&restoreInfo);

                    /* get destination filename */
                    destinationFileName = getDestinationFileName(String_new(),
                                          directoryName,
                                          jobOptions->directory,
                                          jobOptions->directoryStripCount
                                                                );


                    /* check if directory already exists */
                    if (!jobOptions->overwriteFilesFlag && File_exists(destinationFileName))
                    {
                        printInfo(1,
                                  "  Restore directory '%s'...skipped (file exists)\n",
                                  String_cString(destinationFileName)
                                 );
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(directoryName);
                        continue;
                    }

                    printInfo(2,"  Restore directory '%s'...",String_cString(destinationFileName));

                    /* create directory */
                    error = File_makeDirectory(destinationFileName,
                                               FILE_DEFAULT_USER_ID,
                                               FILE_DEFAULT_GROUP_ID,
                                               fileInfo.permission
                                              );
                    if (error != ERROR_NONE)
                    {
                        printInfo(2,"FAIL!\n");
                        printError("Cannot create directory '%s' (error: %s)\n",
                                   String_cString(destinationFileName),
                                   Errors_getText(error)
                                  );
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(directoryName);
                        if (jobOptions->stopOnErrorFlag)
                        {
                            restoreInfo.error = error;
                        }
                        continue;
                    }

                    /* set file time, file owner/group */
                    if (jobOptions->owner.userId  != FILE_DEFAULT_USER_ID ) fileInfo.userId  = jobOptions->owner.userId;
                    if (jobOptions->owner.groupId != FILE_DEFAULT_GROUP_ID) fileInfo.groupId = jobOptions->owner.groupId;
                    error = File_setFileInfo(destinationFileName,&fileInfo);
                    if (error != ERROR_NONE)
                    {
                        if (jobOptions->stopOnErrorFlag)
                        {
                            printInfo(2,"FAIL!\n");
                            printError("Cannot set directory info of '%s' (error: %s)\n",
                                       String_cString(destinationFileName),
                                       Errors_getText(error)
                                      );
                            String_delete(destinationFileName);
                            Archive_closeEntry(&archiveFileInfo);
                            String_delete(directoryName);
                            if (jobOptions->stopOnErrorFlag)
                            {
                                restoreInfo.error = error;
                            }
                            continue;
                        }
                        else
                        {
                            printWarning("Cannot set directory info of '%s' (error: %s)\n",
                                         String_cString(destinationFileName),
                                         Errors_getText(error)
                                        );
                        }
                    }

                    /* free resources */
                    String_delete(destinationFileName);

                    printInfo(2,"ok\n");
                }
                else
                {
                    /* skip */
                    printInfo(3,"  Restore '%s'...skipped\n",String_cString(directoryName));
                }

                /* close archive file */
                Archive_closeEntry(&archiveFileInfo);
                String_delete(directoryName);
            }
            break;
            case FILE_TYPE_LINK:
            {
                String   linkName;
                String   fileName;
                FileInfo fileInfo;
                String   destinationFileName;
//            FileInfo localFileInfo;

                /* read link */
                linkName = String_new();
                fileName = String_new();
                error = Archive_readLinkEntry(&archiveInfo,
                                              &archiveFileInfo,
                                              NULL,
                                              NULL,
                                              linkName,
                                              fileName,
                                              &fileInfo
                                             );
                if (error != ERROR_NONE)
                {
                    printError("Cannot not read 'link' content of archive '%s' (error: %s)!\n",
                               String_cString(archiveFileName),
                               Errors_getText(error)
                              );
                    String_delete(fileName);
                    String_delete(linkName);
                    if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
                    break;
                }

                if (   (List_empty(includePatternList) || PatternList_match(includePatternList,linkName,PATTERN_MATCH_MODE_EXACT))
                        && !PatternList_match(excludePatternList,linkName,PATTERN_MATCH_MODE_EXACT)
                   )
                {
                    String_set(restoreInfo.statusInfo.fileName,linkName);
                    restoreInfo.statusInfo.fileDoneBytes = 0LL;
                    restoreInfo.statusInfo.fileTotalBytes = 00L;
                    updateStatusInfo(&restoreInfo);

                    /* get destination filename */
                    destinationFileName = getDestinationFileName(String_new(),
                                          linkName,
                                          jobOptions->directory,
                                          jobOptions->directoryStripCount
                                                                );


                    /* create link */
                    if (!jobOptions->overwriteFilesFlag && File_exists(destinationFileName))
                    {
                        printInfo(1,
                                  "  Restore link '%s'...skipped (file exists)\n",
                                  String_cString(destinationFileName)
                                 );
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(fileName);
                        String_delete(linkName);
                        if (jobOptions->stopOnErrorFlag)
                        {
                            restoreInfo.error = ERROR_FILE_EXITS;
                        }
                        continue;
                    }

                    printInfo(2,"  Restore link '%s'...",String_cString(destinationFileName));

                    error = File_makeLink(destinationFileName,fileName);
                    if (error != ERROR_NONE)
                    {
                        printInfo(2,"FAIL!\n");
                        printError("Cannot create link '%s' -> '%s' (error: %s)\n",
                                   String_cString(destinationFileName),
                                   String_cString(fileName),
                                   Errors_getText(error)
                                  );
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(fileName);
                        String_delete(linkName);
                        if (jobOptions->stopOnErrorFlag)
                        {
                            restoreInfo.error = error;
                        }
                        continue;
                    }

                    /* set file time, file owner/group */
                    if (jobOptions->owner.userId  != FILE_DEFAULT_USER_ID ) fileInfo.userId  = jobOptions->owner.userId;
                    if (jobOptions->owner.groupId != FILE_DEFAULT_GROUP_ID) fileInfo.groupId = jobOptions->owner.groupId;
                    error = File_setFileInfo(destinationFileName,&fileInfo);
                    if (error != ERROR_NONE)
                    {
                        if (jobOptions->stopOnErrorFlag)
                        {
                            printInfo(2,"FAIL!\n");
                            printError("Cannot set file info of '%s' (error: %s)\n",
                                       String_cString(destinationFileName),
                                       Errors_getText(error)
                                      );
                            String_delete(destinationFileName);
                            Archive_closeEntry(&archiveFileInfo);
                            String_delete(fileName);
                            String_delete(linkName);
                            if (jobOptions->stopOnErrorFlag)
                            {
                                restoreInfo.error = error;
                            }
                            continue;
                        }
                        else
                        {
                            printWarning("Cannot set file info of '%s' (error: %s)\n",
                                         String_cString(destinationFileName),
                                         Errors_getText(error)
                                        );
                        }
                    }

                    /* free resources */
                    String_delete(destinationFileName);

                    printInfo(2,"ok\n");
                }
                else
                {
                    /* skip */
                    printInfo(3,"  Restore '%s'...skipped\n",String_cString(linkName));
                }

                /* close archive file */
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                String_delete(linkName);
            }
            break;
            case FILE_TYPE_SPECIAL:
            {
                String   fileName;
                FileInfo fileInfo;
                String   destinationFileName;
//            FileInfo localFileInfo;

                /* read special device */
                fileName = String_new();
                error = Archive_readSpecialEntry(&archiveInfo,
                                                 &archiveFileInfo,
                                                 NULL,
                                                 NULL,
                                                 fileName,
                                                 &fileInfo
                                                );
                if (error != ERROR_NONE)
                {
                    printError("Cannot not read 'special' content of archive '%s' (error: %s)!\n",
                               String_cString(archiveFileName),
                               Errors_getText(error)
                              );
                    String_delete(fileName);
                    if (restoreInfo.error == ERROR_NONE) restoreInfo.error = error;
                    break;
                }

                if (   (List_empty(includePatternList) || PatternList_match(includePatternList,fileName,PATTERN_MATCH_MODE_EXACT))
                        && !PatternList_match(excludePatternList,fileName,PATTERN_MATCH_MODE_EXACT)
                   )
                {
                    String_set(restoreInfo.statusInfo.fileName,fileName);
                    restoreInfo.statusInfo.fileDoneBytes = 0LL;
                    restoreInfo.statusInfo.fileTotalBytes = 00L;
                    updateStatusInfo(&restoreInfo);

                    /* get destination filename */
                    destinationFileName = getDestinationFileName(String_new(),
                                          fileName,
                                          jobOptions->directory,
                                          jobOptions->directoryStripCount
                                                                );


                    /* create special device */
                    if (!jobOptions->overwriteFilesFlag && File_exists(destinationFileName))
                    {
                        printInfo(1,
                                  "  Restore special device '%s'...skipped (file exists)\n",
                                  String_cString(destinationFileName)
                                 );
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(fileName);
                        if (jobOptions->stopOnErrorFlag)
                        {
                            restoreInfo.error = ERROR_FILE_EXITS;
                        }
                        continue;
                    }

                    printInfo(2,"  Restore special device '%s'...",String_cString(destinationFileName));

                    error = File_makeSpecial(destinationFileName,
                                             fileInfo.specialType,
                                             fileInfo.major,
                                             fileInfo.minor
                                            );
                    if (error != ERROR_NONE)
                    {
                        printInfo(2,"FAIL!\n");
                        printError("Cannot create special device '%s' (error: %s)\n",
                                   String_cString(fileName),
                                   Errors_getText(error)
                                  );
                        String_delete(destinationFileName);
                        Archive_closeEntry(&archiveFileInfo);
                        String_delete(fileName);
                        if (jobOptions->stopOnErrorFlag)
                        {
                            restoreInfo.error = error;
                        }
                        continue;
                    }

                    /* set file time, file owner/group */
                    if (jobOptions->owner.userId  != FILE_DEFAULT_USER_ID ) fileInfo.userId  = jobOptions->owner.userId;
                    if (jobOptions->owner.groupId != FILE_DEFAULT_GROUP_ID) fileInfo.groupId = jobOptions->owner.groupId;
                    error = File_setFileInfo(destinationFileName,&fileInfo);
                    if (error != ERROR_NONE)
                    {
                        if (jobOptions->stopOnErrorFlag)
                        {
                            printInfo(2,"FAIL!\n");
                            printError("Cannot set file info of '%s' (error: %s)\n",
                                       String_cString(destinationFileName),
                                       Errors_getText(error)
                                      );
                            String_delete(destinationFileName);
                            Archive_closeEntry(&archiveFileInfo);
                            String_delete(fileName);
                            if (jobOptions->stopOnErrorFlag)
                            {
                                restoreInfo.error = error;
                            }
                            continue;
                        }
                        else
                        {
                            printWarning("Cannot set file info of '%s' (error: %s)\n",
                                         String_cString(destinationFileName),
                                         Errors_getText(error)
                                        );
                        }
                    }

                    /* free resources */
                    String_delete(destinationFileName);

                    printInfo(2,"ok\n");
                }
                else
                {
                    /* skip */
                    printInfo(3,"  Restore '%s'...skipped\n",String_cString(fileName));
                }

                /* close archive file */
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
            }
            break;
            default:
#ifndef NDEBUG
                HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE();
#endif /* NDEBUG */
                break; /* not reached */
            }
        }

        /* close archive */
        Archive_close(&archiveInfo);
    }

    /* check fragment lists */
    if ((restoreInfo.requestedAbortFlag == NULL) || !(*restoreInfo.requestedAbortFlag))
    {
        for (fileFragmentNode = fileFragmentList.head; fileFragmentNode != NULL; fileFragmentNode = fileFragmentNode->next)
        {
            if (!FileFragmentList_checkComplete(fileFragmentNode))
            {
                printInfo(0,"Warning: incomplete file '%s'\n",String_cString(fileFragmentNode->fileName));
                if (restoreInfo.error == ERROR_NONE) restoreInfo.error = ERROR_FILE_INCOMPLETE;
            }
        }
    }

    /* free resources */
    String_delete(archiveFileName);
    FileFragmentList_done(&fileFragmentList);
    free(buffer);
    String_delete(restoreInfo.statusInfo.fileName);
    String_delete(restoreInfo.statusInfo.storageName);

    if ((restoreInfo.requestedAbortFlag == NULL) || !(*restoreInfo.requestedAbortFlag))
    {
        return restoreInfo.error;
    }
    else
    {
        return ERROR_ABORTED;
    }
}
Exemplo n.º 21
0
Errors Misc_executeCommand(const char        *commandTemplate,
                           const TextMacro   macros[],
                           uint              macroCount,
                           ExecuteIOFunction stdoutExecuteIOFunction,
                           ExecuteIOFunction stderrExecuteIOFunction,
                           void              *executeIOUserData
                          )
{
  Errors          error;
  String          commandLine;
  StringTokenizer stringTokenizer;
  String          token;
  String          command;
  StringList      argumentList;
  const char      *path;
  String          fileName;
  bool            foundFlag;
  char const      **arguments;
  int             pipeStdin[2],pipeStdout[2],pipeStderr[2];
  int             pid;
  StringNode      *stringNode;
  uint            n,z;
  int             status;
  bool            sleepFlag;
  String          stdoutLine,stderrLine;
  int             exitcode;
  int             terminateSignal;

  error = ERROR_NONE;
  if (commandTemplate != NULL)
  {
    commandLine = String_new();
    command     = File_newFileName();
    StringList_init(&argumentList);

    // expand command line
    Misc_expandMacros(commandLine,commandTemplate,macros,macroCount);
    printInfo(3,"Execute command '%s'...",String_cString(commandLine));

    // parse command
    String_initTokenizer(&stringTokenizer,commandLine,STRING_BEGIN,STRING_WHITE_SPACES,STRING_QUOTES,FALSE);
    if (!String_getNextToken(&stringTokenizer,&token,NULL))
    {
      String_doneTokenizer(&stringTokenizer);
      StringList_done(&argumentList);
      String_delete(command);
      String_delete(commandLine);
      return ERRORX_(PARSE_COMMAND,0,String_cString(commandLine));
    }
    File_setFileName(command,token);

    // parse arguments
    while (String_getNextToken(&stringTokenizer,&token,NULL))
    {
      StringList_append(&argumentList,token);
    }
    String_doneTokenizer(&stringTokenizer);

    // find command in PATH
    path = getenv("PATH");
    if (path != NULL)
    {
      fileName  = File_newFileName();
      foundFlag = FALSE;
      String_initTokenizerCString(&stringTokenizer,path,":","",FALSE);
      while (String_getNextToken(&stringTokenizer,&token,NULL) && !foundFlag)
      {
        File_setFileName(fileName,token);
        File_appendFileName(fileName,command);
        if (File_exists(fileName))
        {
          File_setFileName(command,fileName);
          foundFlag = TRUE;
        }
      }
      String_doneTokenizer(&stringTokenizer);
      File_deleteFileName(fileName);
    }

#if 0
fprintf(stderr,"%s,%d: command %s\n",__FILE__,__LINE__,String_cString(command));
stringNode = argumentList.head;
while (stringNode != NULL)
{
fprintf(stderr,"%s,%d: argument %s\n",__FILE__,__LINE__,String_cString(stringNode->string));
stringNode = stringNode->next;
}
#endif /* 0 */

    #if defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID)
#if 1
      // create i/o pipes
      if (pipe(pipeStdin) != 0)
      {
        error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine));
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }
      if (pipe(pipeStdout) != 0)
      {
        error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine));
        close(pipeStdin[0]);
        close(pipeStdin[1]);
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }
      if (pipe(pipeStderr) != 0)
      {
        error = ERRORX_(IO_REDIRECT_FAIL,errno,String_cString(commandLine));
        close(pipeStdout[0]);
        close(pipeStdout[1]);
        close(pipeStdin[0]);
        close(pipeStdin[1]);
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }

      // do fork to start separated process
      pid = fork();
      if      (pid == 0)
      {
        // close stdin, stdout, and stderr and reassign them to the pipes
        close(STDERR_FILENO);
        close(STDOUT_FILENO);
        close(STDIN_FILENO);

        // redirect stdin/stdout/stderr to pipe
        dup2(pipeStdin[0],STDIN_FILENO);
        dup2(pipeStdout[1],STDOUT_FILENO);
        dup2(pipeStderr[1],STDERR_FILENO);

        /* close unused pipe handles (the pipes are duplicated by fork(), thus
           there are two open ends of the pipes)
        */
        close(pipeStderr[0]);
        close(pipeStdout[0]);
        close(pipeStdin[1]);

        // execute of external program
        n = 1+StringList_count(&argumentList)+1;
        arguments = (char const**)malloc(n*sizeof(char*));
        if (arguments == NULL)
        {
          HALT_INSUFFICIENT_MEMORY();
        }
        z = 0;
        arguments[z] = String_cString(command); z++;
        stringNode = argumentList.head;
        while (stringNode != NULL)
        {
          assert(z < n);
          arguments[z] = String_cString(stringNode->string); z++;
          stringNode = stringNode->next;
        }
        assert(z < n);
        arguments[z] = NULL; z++;
        execvp(String_cString(command),(char**)arguments);

        // in case exec() fail, return a default exitcode
        HALT_INTERNAL_ERROR("execvp() returned");
      }
      else if (pid < 0)
      {
        error = ERRORX_(EXEC_FAIL,errno,String_cString(commandLine));
        printInfo(3,"FAIL!\n");

        close(pipeStderr[0]);
        close(pipeStderr[1]);
        close(pipeStdout[0]);
        close(pipeStdout[1]);
        close(pipeStdin[0]);
        close(pipeStdin[1]);
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }

      // close unused pipe handles (the pipe is duplicated by fork(), thus there are two open ends of the pipe)
      close(pipeStderr[1]);
      close(pipeStdout[1]);
      close(pipeStdin[0]);
#else /* 0 */
error = ERROR_NONE;
#endif /* 0 */

      // wait until process terminate and read stdout/stderr
      stdoutLine = String_new();
      stderrLine = String_new();
      status = 0;
      while ((waitpid(pid,&status,WNOHANG) == 0) || (!WIFEXITED(status) && !WIFSIGNALED(status)))
      {
        sleepFlag = TRUE;

        if (readProcessIO(pipeStdout[0],stdoutLine))
        {
          if (stdoutExecuteIOFunction != NULL) stdoutExecuteIOFunction(executeIOUserData,stdoutLine);
          String_clear(stdoutLine);
          sleepFlag = FALSE;
        }
        if (readProcessIO(pipeStderr[0],stderrLine))
        {
          if (stderrExecuteIOFunction != NULL) stderrExecuteIOFunction(executeIOUserData,stderrLine);
          String_clear(stderrLine);
          sleepFlag = FALSE;
        }

        if (sleepFlag)
        {
          Misc_udelay(500LL*1000LL);
        }
      }
      while (readProcessIO(pipeStdout[0],stdoutLine))
      {
        if (stdoutExecuteIOFunction != NULL) stdoutExecuteIOFunction(executeIOUserData,stdoutLine);
        String_clear(stdoutLine);
      }
      while (readProcessIO(pipeStderr[0],stderrLine))
      {
        if (stderrExecuteIOFunction != NULL) stderrExecuteIOFunction(executeIOUserData,stderrLine);
        String_clear(stderrLine);
      }
      String_delete(stderrLine);
      String_delete(stdoutLine);

      // close i/o
      close(pipeStderr[0]);
      close(pipeStdout[0]);
      close(pipeStdin[1]);

      // check exit code
      exitcode = -1;
      if      (WIFEXITED(status))
      {
        exitcode = WEXITSTATUS(status);
        printInfo(3,"ok (exitcode %d)\n",exitcode);
        if (exitcode != 0)
        {
          error = ERRORX_(EXEC_FAIL,exitcode,String_cString(commandLine));
          StringList_done(&argumentList);
          String_delete(command);
          String_delete(commandLine);
          return error;
        }
      }
      else if (WIFSIGNALED(status))
      {
        terminateSignal = WTERMSIG(status);
        error = ERRORX_(EXEC_FAIL,terminateSignal,String_cString(commandLine));
        printInfo(3,"FAIL (signal %d)\n",terminateSignal);
        StringList_done(&argumentList);
        String_delete(command);
        String_delete(commandLine);
        return error;
      }
      else
      {
        printInfo(3,"ok (unknown exit)\n");
      }
    #elif defined(WIN32)
#if 0
HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
      HANDLE hInputWriteTmp,hInputRead,hInputWrite;
      HANDLE hErrorWrite;
      HANDLE hThread;
      DWORD ThreadId;
      SECURITY_ATTRIBUTES sa;


      // Set up the security attributes struct.
      sa.nLength= sizeof(SECURITY_ATTRIBUTES);
      sa.lpSecurityDescriptor = NULL;
      sa.bInheritHandle = TRUE;


      // Create the child output pipe.
      if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0))
         DisplayError("CreatePipe");


      // Create a duplicate of the output write handle for the std error
      // write handle. This is necessary in case the child application
      // closes one of its std output handles.
      if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
                           GetCurrentProcess(),&hErrorWrite,0,
                           TRUE,DUPLICATE_SAME_ACCESS))
         DisplayError("DuplicateHandle");


      // Create the child input pipe.
      if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0))
         DisplayError("CreatePipe");


      // Create new output read handle and the input write handles. Set
      // the Properties to FALSE. Otherwise, the child inherits the
      // properties and, as a result, non-closeable handles to the pipes
      // are created.
      if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
                           GetCurrentProcess(),
                           &hOutputRead, // Address of new handle.
                           0,FALSE, // Make it uninheritable.
                           DUPLICATE_SAME_ACCESS))
         DisplayError("DupliateHandle");

      if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
                           GetCurrentProcess(),
                           &hInputWrite, // Address of new handle.
                           0,FALSE, // Make it uninheritable.
                           DUPLICATE_SAME_ACCESS))
      DisplayError("DupliateHandle");


      // Close inheritable copies of the handles you do not want to be
      // inherited.
      if (!CloseHandle(hOutputReadTmp)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputWriteTmp)) DisplayError("CloseHandle");


      // Get std input handle so you can close it and force the ReadFile to
      // fail when you want the input thread to exit.
      if ( (hStdIn = GetStdHandle(STD_INPUT_HANDLE)) ==
                                                INVALID_HANDLE_VALUE )
         DisplayError("GetStdHandle");

      PrepAndLaunchRedirectedChild(hOutputWrite,hInputRead,hErrorWrite);


      // Close pipe handles (do not continue to modify the parent).
      // You need to make sure that no handles to the write end of the
      // output pipe are maintained in this process or else the pipe will
      // not close when the child process exits and the ReadFile will hang.
      if (!CloseHandle(hOutputWrite)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputRead )) DisplayError("CloseHandle");
      if (!CloseHandle(hErrorWrite)) DisplayError("CloseHandle");


      // Launch the thread that gets the input and sends it to the child.
      hThread = CreateThread(NULL,0,GetAndSendInputThread,
                              (LPVOID)hInputWrite,0,&ThreadId);
      if (hThread == NULL) DisplayError("CreateThread");


      // Read the child's output.
      ReadAndHandleOutput(hOutputRead);
      // Redirection is complete


      // Force the read on the input to return by closing the stdin handle.
      if (!CloseHandle(hStdIn)) DisplayError("CloseHandle");


      // Tell the thread to exit and wait for thread to die.
      bRunThread = FALSE;

      if (WaitForSingleObject(hThread,INFINITE) == WAIT_FAILED)
         DisplayError("WaitForSingleObject");

      if (!CloseHandle(hOutputRead)) DisplayError("CloseHandle");
      if (!CloseHandle(hInputWrite)) DisplayError("CloseHandle");
#endif
    #else /* not defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID) || WIN32 */
      #error pipe()/fork()/waitpid() not available nor Win32 system!
    #endif /* defined(HAVE_PIPE) && defined(HAVE_FORK) && defined(HAVE_WAITPID) || WIN32 */

    // free resources
    StringList_done(&argumentList);
    String_delete(command);
    String_delete(commandLine);
  }

  return error;
}
Exemplo n.º 22
0
LOCAL bool parseDefinition(const char *s, Definition *definition, uint64 maxPosition)
{
  StringTokenizer stringTokenizer;
  String          t;
  String          w;
  uint            length;
  char            buffer[1024];

  assert(definition != NULL);

  t = String_newCString(s);
  String_initTokenizer(&stringTokenizer,t,STRING_BEGIN,":",NULL,FALSE);

  /* get type */
  if (String_getNextToken(&stringTokenizer,&w,NULL))
  {
    if      (String_equalsCString(w,"m")) definition->type = DEFINITION_TYPE_MODIFY;
    else if (String_equalsCString(w,"r")) definition->type = DEFINITION_TYPE_RANDOMIZE;
    else if (String_equalsCString(w,"i")) definition->type = DEFINITION_TYPE_INSERT;
    else if (String_equalsCString(w,"d")) definition->type = DEFINITION_TYPE_DELETE;
    else
    {
      String_doneTokenizer(&stringTokenizer);
      String_delete(t);
      fprintf(stderr,"ERROR: Invalid definition '%s': expected m,i,d!\n",s);
      return FALSE;
    }
  }
  else
  {
    String_doneTokenizer(&stringTokenizer);
    String_delete(t);
    fprintf(stderr,"ERROR: Invalid definition '%s'!\n",s);
    return FALSE;
  }

  /* get position */
  if (String_getNextToken(&stringTokenizer,&w,NULL))
  {
    if (!String_scan(w,STRING_BEGIN,"%llu",&definition->position))
    {
      String_doneTokenizer(&stringTokenizer);
      String_delete(t);
      fprintf(stderr,"ERROR: Invalid position in definition '%s'!\n",s);
      return FALSE;
    }
  }
  else
  {
    definition->position = getRandomInteger64(maxPosition);
  }

  /* get value/length */
  if (String_getNextToken(&stringTokenizer,&w,NULL))
  {
    switch (definition->type)
    {
      case DEFINITION_TYPE_MODIFY:
        definition->value = String_new();
        if (!String_scan(w,STRING_BEGIN,"%S",definition->value))
        {
          String_delete(definition->value);
          String_doneTokenizer(&stringTokenizer);
          String_delete(t);
          fprintf(stderr,"ERROR: Invalid length in definition '%s'!\n",s);
          return FALSE;
        }
        break;
      case DEFINITION_TYPE_RANDOMIZE:
        if (!String_scan(w,STRING_BEGIN,"%u",&length))
        {
          String_doneTokenizer(&stringTokenizer);
          String_delete(t);
          fprintf(stderr,"ERROR: Invalid length in definition '%s'!\n",s);
          return FALSE;
        }
        if (length > sizeof(buffer)) length = sizeof(buffer);
        getRandomBuffer(buffer,length);
        definition->value = String_newBuffer(buffer,length);
        break;
      case DEFINITION_TYPE_INSERT:
        definition->value = String_new();
        if (!String_scan(w,STRING_BEGIN,"%S",definition->value))
        {
          String_delete(definition->value);
          String_doneTokenizer(&stringTokenizer);
          String_delete(t);
          fprintf(stderr,"ERROR: Invalid value in definition '%s'!\n",s);
          return FALSE;
        }
        break;
      case DEFINITION_TYPE_DELETE:
        if (!String_scan(w,STRING_BEGIN,"%u",&definition->length))
        {
          String_doneTokenizer(&stringTokenizer);
          String_delete(t);
          fprintf(stderr,"ERROR: Invalid length in definition '%s'!\n",s);
          return FALSE;
        }
        break;
    }   
  }
  else
  {
    switch (definition->type)
    {
      case DEFINITION_TYPE_MODIFY:
        definition->value = String_newChar((char)getRandomByte(256));
        break;
      case DEFINITION_TYPE_RANDOMIZE:
        getRandomBuffer(buffer,sizeof(buffer));
        definition->value = String_newBuffer(buffer,getRandomInteger(sizeof(buffer)));
        break;
      case DEFINITION_TYPE_INSERT:
        definition->value = String_new();
        if (!String_scan(w,STRING_BEGIN,"%S",&definition->value))
        {
          String_delete(definition->value);
          String_doneTokenizer(&stringTokenizer);
          String_delete(t);
          fprintf(stderr,"ERROR: Invalid value in definition '%s'!\n",s);
          return FALSE;
        }
        break;
      case DEFINITION_TYPE_DELETE:
        if (!String_scan(w,STRING_BEGIN,"%u",&definition->length))
        {
          String_doneTokenizer(&stringTokenizer);
          String_delete(t);
          fprintf(stderr,"ERROR: Invalid length in definition '%s'!\n",s);
          return FALSE;
        }
        break;
    }   
  }

  if (String_getNextToken(&stringTokenizer,&w,NULL))
  {
    String_doneTokenizer(&stringTokenizer);
    String_delete(t);
    fprintf(stderr,"ERROR: Invalid definition '%s'!\n",s);
    return FALSE;
  }

  String_doneTokenizer(&stringTokenizer);
  String_delete(t);

  return TRUE;
}
Exemplo n.º 23
0
Errors Command_compare(StringList                      *archiveFileNameList,
                       EntryList                       *includeEntryList,
                       PatternList                     *excludePatternList,
                       JobOptions                      *jobOptions,
                       ArchiveGetCryptPasswordFunction archiveGetCryptPasswordFunction,
                       void                            *archiveGetCryptPasswordUserData
                      )
{
  byte              *archiveBuffer,*buffer;
  FragmentList      fragmentList;
  String            archiveFileName;
  Errors            failError;
  Errors            error;
  ArchiveInfo       archiveInfo;
  ArchiveFileInfo   archiveFileInfo;
  ArchiveEntryTypes archiveEntryType;
  FragmentNode      *fragmentNode;

  assert(archiveFileNameList != NULL);
  assert(includeEntryList != NULL);
  assert(excludePatternList != NULL);
  assert(jobOptions != NULL);

  /* allocate resources */
  archiveBuffer = (byte*)malloc(BUFFER_SIZE);
  if (archiveBuffer == NULL)
  {
    HALT_INSUFFICIENT_MEMORY();
  }
  buffer = malloc(BUFFER_SIZE);
  if (buffer == NULL)
  {
    free(archiveBuffer);
    HALT_INSUFFICIENT_MEMORY();
  }
  FragmentList_init(&fragmentList);
  archiveFileName = String_new();

  failError = ERROR_NONE;
  while (   !StringList_empty(archiveFileNameList)
         && (failError == ERROR_NONE)
        )
  {
    StringList_getFirst(archiveFileNameList,archiveFileName);
    printInfo(1,"Comparing archive '%s':\n",String_cString(archiveFileName));

    /* open archive */
    error = Archive_open(&archiveInfo,
                         archiveFileName,
                         jobOptions,
                         archiveGetCryptPasswordFunction,
                         archiveGetCryptPasswordUserData
                        );
    if (error != ERROR_NONE)
    {
      printError("Cannot open archive file '%s' (error: %s)!\n",
                 String_cString(archiveFileName),
                 Errors_getText(error)
                );
      if (failError == ERROR_NONE) failError = error;
      continue;
    }

    /* read files */
    while (   !Archive_eof(&archiveInfo)
           && (failError == ERROR_NONE)
          )
    {
      /* get next archive entry type */
      error = Archive_getNextArchiveEntryType(&archiveInfo,
                                              &archiveFileInfo,
                                              &archiveEntryType
                                             );
      if (error != ERROR_NONE)
      {
        printError("Cannot not read next entry in archive '%s' (error: %s)!\n",
                   String_cString(archiveFileName),
                   Errors_getText(error)
                  );
        if (failError == ERROR_NONE) failError = error;
        break;
      }

      switch (archiveEntryType)
      {
        case ARCHIVE_ENTRY_TYPE_FILE:
          {
            String       fileName;
            FileInfo     fileInfo;
            uint64       fragmentOffset,fragmentSize;
            FragmentNode *fragmentNode;
//            FileInfo   localFileInfo;
            FileHandle   fileHandle;
            bool         equalFlag;
            uint64       length;
            ulong        n;
            ulong        diffIndex;

            /* read file */
            fileName = String_new();
            error = Archive_readFileEntry(&archiveInfo,
                                          &archiveFileInfo,
                                          NULL,
                                          NULL,
                                          NULL,
                                          fileName,
                                          &fileInfo,
                                          &fragmentOffset,
                                          &fragmentSize
                                         );
            if (error != ERROR_NONE)
            {
              printError("Cannot not read 'file' content of archive '%s' (error: %s)!\n",
                         String_cString(archiveFileName),
                         Errors_getText(error)
                        );
              String_delete(fileName);
              if (failError == ERROR_NONE) failError = error;
              break;
            }

            if (   (List_empty(includeEntryList) || EntryList_match(includeEntryList,fileName,PATTERN_MATCH_MODE_EXACT))
                && !PatternList_match(excludePatternList,fileName,PATTERN_MATCH_MODE_EXACT)
               )
            {
              printInfo(2,"  Compare file '%s'...",String_cString(fileName));

              /* check file */
              if (!File_exists(fileName))
              {
                printInfo(2,"FAIL!\n");
                printError("File '%s' not found!\n",String_cString(fileName));
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_FILE_NOT_FOUND;
                }
                break;
              }
              if (File_getType(fileName) != FILE_TYPE_FILE)
              {
                printInfo(2,"FAIL!\n");
                printError("'%s' is not a file!\n",String_cString(fileName));
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_WRONG_FILE_TYPE;
                }
                break;
              }

              /* get file fragment list */
              fragmentNode = FragmentList_find(&fragmentList,fileName);
              if (fragmentNode == NULL)
              {
                fragmentNode = FragmentList_add(&fragmentList,fileName,fileInfo.size);
              }
//FragmentList_print(fragmentNode,String_cString(fileName));

              /* open file */
              error = File_open(&fileHandle,fileName,FILE_OPENMODE_READ);
              if (error != ERROR_NONE)
              {
                printInfo(2,"FAIL!\n");
                printError("Cannot open file '%s' (error: %s)\n",
                           String_cString(fileName),
                           Errors_getText(error)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = error;
                }
                continue;
              }

              /* check file size */
              if (fileInfo.size != File_getSize(&fileHandle))
              {
                printInfo(2,"FAIL!\n");
                printError("'%s' differ in size: expected %lld bytes, found %lld bytes\n",
                           String_cString(fileName),
                           fileInfo.size,
                           File_getSize(&fileHandle)
                          );
                File_close(&fileHandle);
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_FILES_DIFFER;
                }
                continue;
              }

              /* check file content */
              error = File_seek(&fileHandle,fragmentOffset);
              if (error != ERROR_NONE)
              {
                printInfo(2,"FAIL!\n");
                printError("Cannot read file '%s' (error: %s)\n",
                           String_cString(fileName),
                           Errors_getText(error)
                          );
                File_close(&fileHandle);
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = error;
                }
                continue;
              }
              length    = 0;
              equalFlag = TRUE;
              diffIndex = 0;
              while ((length < fragmentSize) && equalFlag)
              {
                n = MIN(fragmentSize-length,BUFFER_SIZE);

                /* read archive, file */
                error = Archive_readData(&archiveFileInfo,archiveBuffer,n);
                if (error != ERROR_NONE)
                {
                  printInfo(2,"FAIL!\n");
                  printError("Cannot not read content of archive '%s' (error: %s)!\n",
                             String_cString(archiveFileName),
                             Errors_getText(error)
                            );
                  if (failError == ERROR_NONE) failError = error;
                  break;
                }
                error = File_read(&fileHandle,buffer,n,NULL);
                if (error != ERROR_NONE)
                {
                  printInfo(2,"FAIL!\n");
                  printError("Cannot read file '%s' (error: %s)\n",
                             String_cString(fileName),
                             Errors_getText(error)
                            );
                  if (jobOptions->stopOnErrorFlag)
                  {
                    failError = error;
                  }
                  break;
                }

                /* compare */
                diffIndex = compare(archiveBuffer,buffer,n);
                equalFlag = (diffIndex >= n);
                if (!equalFlag)
                {
                  printInfo(2,"FAIL!\n");
                  printError("'%s' differ at offset %llu\n",
                             String_cString(fileName),
                             fragmentOffset+length+(uint64)diffIndex
                            );
                  if (jobOptions->stopOnErrorFlag)
                  {
                    failError = ERROR_FILES_DIFFER;
                  }
                  break;
                }

                length += n;
              }
              File_close(&fileHandle);
              if (failError != ERROR_NONE)
              {
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                continue;
              }

#if 0
              /* get local file info */
              /* check file time, permissions, file owner/group */
#endif /* 0 */
              printInfo(2,"ok\n");

              /* add fragment to file fragment list */
              FragmentList_addEntry(fragmentNode,fragmentOffset,fragmentSize);

              /* discard fragment list if file is complete */
              if (FragmentList_checkEntryComplete(fragmentNode))
              {
                FragmentList_remove(&fragmentList,fragmentNode);
              }

              /* free resources */
            }
            else
            {
              /* skip */
              printInfo(3,"  Compare '%s'...skipped\n",String_cString(fileName));
            }

            /* close archive file, free resources */
            Archive_closeEntry(&archiveFileInfo);
            String_delete(fileName);
          }
          break;
        case ARCHIVE_ENTRY_TYPE_IMAGE:
          {
            String       imageName;
            DeviceInfo   deviceInfo;
            uint64       blockOffset,blockCount;
            FragmentNode *fragmentNode;
            DeviceHandle deviceHandle;
            bool         equalFlag;
            uint64       block;
            ulong        bufferBlockCount;
            ulong        diffIndex;

            /* read image */
            imageName = String_new();
            error = Archive_readImageEntry(&archiveInfo,
                                           &archiveFileInfo,
                                           NULL,
                                           NULL,
                                           NULL,
                                           imageName,
                                           &deviceInfo,
                                           &blockOffset,
                                           &blockCount
                                          );
            if (error != ERROR_NONE)
            {
              printError("Cannot not read 'image' content of archive '%s' (error: %s)!\n",
                         String_cString(archiveFileName),
                         Errors_getText(error)
                        );
              String_delete(imageName);
              if (failError == ERROR_NONE) failError = error;
              break;
            }

            if (   (List_empty(includeEntryList) || EntryList_match(includeEntryList,imageName,PATTERN_MATCH_MODE_EXACT))
                && !PatternList_match(excludePatternList,imageName,PATTERN_MATCH_MODE_EXACT)
               )
            {
              printInfo(2,"  Compare image '%s'...",String_cString(imageName));

              /* check if device exists */
              if (!File_exists(imageName))
              {
                printInfo(2,"FAIL!\n");
                printError("Device '%s' not found!\n",String_cString(imageName));
                Archive_closeEntry(&archiveFileInfo);
                String_delete(imageName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_FILE_NOT_FOUND;
                }
                break;
              }

              /* get image fragment list */
              fragmentNode = FragmentList_find(&fragmentList,imageName);
              if (fragmentNode == NULL)
              {
                fragmentNode = FragmentList_add(&fragmentList,imageName,deviceInfo.size);
              }

              /* open device */
              error = Device_open(&deviceHandle,imageName,DEVICE_OPENMODE_READ);
              if (error != ERROR_NONE)
              {
                printInfo(2,"FAIL!\n");
                printError("Cannot open file '%s' (error: %s)\n",
                           String_cString(imageName),
                           Errors_getText(error)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(imageName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = error;
                }
                continue;
              }

              /* check image size */
              if (deviceInfo.size != Device_getSize(&deviceHandle))
              {
                printInfo(2,"FAIL!\n");
                printError("'%s' differ in size: expected %lld bytes, found %lld bytes\n",
                           String_cString(imageName),
                           deviceInfo.size,
                           Device_getSize(&deviceHandle)
                          );
                Device_close(&deviceHandle);
                Archive_closeEntry(&archiveFileInfo);
                String_delete(imageName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_FILES_DIFFER;
                }
                continue;
              }

              /* check image content */
              error = Device_seek(&deviceHandle,blockOffset*(uint64)deviceInfo.blockSize);
              if (error != ERROR_NONE)
              {
                printInfo(2,"FAIL!\n");
                printError("Cannot read file '%s' (error: %s)\n",
                           String_cString(imageName),
                           Errors_getText(error)
                          );
                Device_close(&deviceHandle);
                Archive_closeEntry(&archiveFileInfo);
                String_delete(imageName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = error;
                }
                continue;
              }
              block     = 0LL;
              equalFlag = TRUE;
              diffIndex = 0;
              while ((block < blockCount) && equalFlag)
              {
                assert(deviceInfo.blockSize > 0);
                bufferBlockCount = MIN(blockCount-block,BUFFER_SIZE/deviceInfo.blockSize);

                /* read archive, file */
                error = Archive_readData(&archiveFileInfo,archiveBuffer,bufferBlockCount*deviceInfo.blockSize);
                if (error != ERROR_NONE)
                {
                  printInfo(2,"FAIL!\n");
                  printError("Cannot not read content of archive '%s' (error: %s)!\n",
                             String_cString(archiveFileName),
                             Errors_getText(error)
                            );
                  if (failError == ERROR_NONE) failError = error;
                  break;
                }
                error = Device_read(&deviceHandle,buffer,bufferBlockCount*deviceInfo.blockSize,NULL);
                if (error != ERROR_NONE)
                {
                  printInfo(2,"FAIL!\n");
                  printError("Cannot read file '%s' (error: %s)\n",
                             String_cString(imageName),
                             Errors_getText(error)
                            );
                  if (jobOptions->stopOnErrorFlag)
                  {
                    failError = error;
                  }
                  break;
                }

                /* compare */
                diffIndex = compare(archiveBuffer,buffer,bufferBlockCount*deviceInfo.blockSize);
                equalFlag = (diffIndex >= bufferBlockCount*deviceInfo.blockSize);
                if (!equalFlag)
                {
                  printInfo(2,"FAIL!\n");
                  printError("'%s' differ at offset %llu\n",
                             String_cString(imageName),
                             blockOffset*(uint64)deviceInfo.blockSize+block*(uint64)deviceInfo.blockSize+(uint64)diffIndex
                            );
                  if (jobOptions->stopOnErrorFlag)
                  {
                    failError = ERROR_FILES_DIFFER;
                  }
                  break;
                }

                block += (uint64)bufferBlockCount;
              }
              Device_close(&deviceHandle);
              if (failError != ERROR_NONE)
              {
                Archive_closeEntry(&archiveFileInfo);
                String_delete(imageName);
                continue;
              }

#if 0
              /* get local file info */
              /* check file time, permissions, file owner/group */
#endif /* 0 */
              printInfo(2,"ok\n");

              /* add fragment to file fragment list */
              FragmentList_addEntry(fragmentNode,blockOffset*(uint64)deviceInfo.blockSize,blockCount*(uint64)deviceInfo.blockSize);

              /* discard fragment list if file is complete */
              if (FragmentList_checkEntryComplete(fragmentNode))
              {
                FragmentList_remove(&fragmentList,fragmentNode);
              }

              /* free resources */
            }
            else
            {
              /* skip */
              printInfo(3,"  Compare '%s'...skipped\n",String_cString(imageName));
            }

            /* close archive file, free resources */
            Archive_closeEntry(&archiveFileInfo);
            String_delete(imageName);
          }
          break;
        case ARCHIVE_ENTRY_TYPE_DIRECTORY:
          {
            String   directoryName;
            FileInfo fileInfo;
//            String   localFileName;
//            FileInfo localFileInfo;

            /* read directory */
            directoryName = String_new();
            error = Archive_readDirectoryEntry(&archiveInfo,
                                               &archiveFileInfo,
                                               NULL,
                                               NULL,
                                               directoryName,
                                               &fileInfo
                                              );
            if (error != ERROR_NONE)
            {
              printError("Cannot not read 'directory' content of archive '%s' (error: %s)!\n",
                         String_cString(archiveFileName),
                         Errors_getText(error)
                        );
              String_delete(directoryName);
              if (failError == ERROR_NONE) failError = error;
              break;
            }

            if (   (List_empty(includeEntryList) || EntryList_match(includeEntryList,directoryName,PATTERN_MATCH_MODE_EXACT))
                && !PatternList_match(excludePatternList,directoryName,PATTERN_MATCH_MODE_EXACT)
               )
            {
              printInfo(2,"  Compare directory '%s'...",String_cString(directoryName));

              /* check directory */
              if (!File_exists(directoryName))
              {
                printInfo(2,"FAIL!\n");
                printError("Directory '%s' does not exists!\n",String_cString(directoryName));
                Archive_closeEntry(&archiveFileInfo);
                String_delete(directoryName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_FILE_NOT_FOUND;
                }
                break;
              }
              if (File_getType(directoryName) != FILE_TYPE_DIRECTORY)
              {
                printInfo(2,"FAIL!\n");
                printError("'%s' is not a directory!\n",
                           String_cString(directoryName)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(directoryName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_WRONG_FILE_TYPE;
                }
                break;
              }

#if 0
              /* get local file info */
              error = File_getFileInfo(directoryName,&localFileInfo);
              if (error != ERROR_NONE)
              {
                printError("Cannot not read local directory '%s' (error: %s)!\n",
                           String_cString(directoryName),
                           Errors_getText(error)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(directoryName);
                if (failError == ERROR_NONE) failError = error;
                break;
              }

              /* check file time, permissions, file owner/group */
#endif /* 0 */
              printInfo(2,"ok\n");

              /* free resources */
            }
            else
            {
              /* skip */
              printInfo(3,"  Compare '%s'...skipped\n",String_cString(directoryName));
            }

            /* close archive file */
            Archive_closeEntry(&archiveFileInfo);
            String_delete(directoryName);
          }
          break;
        case ARCHIVE_ENTRY_TYPE_LINK:
          {
            String   linkName;
            String   fileName;
            FileInfo fileInfo;
            String   localFileName;
//            FileInfo localFileInfo;

            /* read link */
            linkName = String_new();
            fileName = String_new();
            error = Archive_readLinkEntry(&archiveInfo,
                                          &archiveFileInfo,
                                          NULL,
                                          NULL,
                                          linkName,
                                          fileName,
                                          &fileInfo
                                         );
            if (error != ERROR_NONE)
            {
              printError("Cannot not read 'link' content of archive '%s' (error: %s)!\n",
                         String_cString(archiveFileName),
                         Errors_getText(error)
                        );
              String_delete(fileName);
              String_delete(linkName);
              if (failError == ERROR_NONE) failError = error;
              break;
            }

            if (   (List_empty(includeEntryList) || EntryList_match(includeEntryList,linkName,PATTERN_MATCH_MODE_EXACT))
                && !PatternList_match(excludePatternList,linkName,PATTERN_MATCH_MODE_EXACT)
               )
            {
              printInfo(2,"  Compare link '%s'...",String_cString(linkName));

              /* check link */
              if (!File_exists(linkName))
              {
                printInfo(2,"FAIL!\n");
                printError("Link '%s' -> '%s' does not exists!\n",
                           String_cString(linkName),
                           String_cString(fileName)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                String_delete(linkName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_FILE_NOT_FOUND;
                }
                break;
              }
              if (File_getType(linkName) != FILE_TYPE_LINK)
              {
                printInfo(2,"FAIL!\n");
                printError("'%s' is not a link!\n",
                           String_cString(linkName)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                String_delete(linkName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_WRONG_FILE_TYPE;
                }
                break;
              }

              /* check link content */
              localFileName = String_new();
              error = File_readLink(linkName,localFileName);
              if (error != ERROR_NONE)
              {
                printError("Cannot not read local file '%s' (error: %s)!\n",
                           String_cString(linkName),
                           Errors_getText(error)
                          );
                String_delete(localFileName);
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                String_delete(linkName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = error;
                }
                break;
              }
              if (!String_equals(fileName,localFileName))
              {
                printInfo(2,"FAIL!\n");
                printError("Link '%s' does not contain file '%s'!\n",
                           String_cString(linkName),
                           String_cString(fileName)
                          );
                String_delete(localFileName);
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                String_delete(linkName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_FILES_DIFFER;
                }
                break;
              }
              String_delete(localFileName);

#if 0
              /* get local file info */
              error = File_getFileInfo(linkName,&localFileInfo);
              if (error != ERROR_NONE)
              {
                printError("Cannot not read local file '%s' (error: %s)!\n",
                           String_cString(linkName),
                           Errors_getText(error)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                String_delete(linkName);
                if (failError == ERROR_NONE) failError = error;
                break;
              }

              /* check file time, permissions, file owner/group */
#endif /* 0 */
              printInfo(2,"ok\n");

              /* free resources */
            }
            else
            {
              /* skip */
              printInfo(3,"  Compare '%s'...skipped\n",String_cString(linkName));
            }

            /* close archive file */
            Archive_closeEntry(&archiveFileInfo);
            String_delete(fileName);
            String_delete(linkName);
          }
          break;
        case ARCHIVE_ENTRY_TYPE_SPECIAL:
          {
            String   fileName;
            FileInfo fileInfo;
            FileInfo localFileInfo;

            /* read special */
            fileName = String_new();
            error = Archive_readSpecialEntry(&archiveInfo,
                                             &archiveFileInfo,
                                             NULL,
                                             NULL,
                                             fileName,
                                             &fileInfo
                                            );
            if (error != ERROR_NONE)
            {
              printError("Cannot not read 'special' content of archive '%s' (error: %s)!\n",
                         String_cString(archiveFileName),
                         Errors_getText(error)
                        );
              String_delete(fileName);
              if (failError == ERROR_NONE) failError = error;
              break;
            }

            if (   (List_empty(includeEntryList) || EntryList_match(includeEntryList,fileName,PATTERN_MATCH_MODE_EXACT))
                && !PatternList_match(excludePatternList,fileName,PATTERN_MATCH_MODE_EXACT)
               )
            {
              printInfo(2,"  Compare special device '%s'...",String_cString(fileName));

              /* check special device */
              if (!File_exists(fileName))
              {
                printInfo(2,"FAIL!\n");
                printError("Special device '%s' does not exists!\n",
                           String_cString(fileName)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_FILE_NOT_FOUND;
                }
                break;
              }
              if (File_getType(fileName) != FILE_TYPE_SPECIAL)
              {
                printInfo(2,"FAIL!\n");
                printError("'%s' is not a special device!\n",
                           String_cString(fileName)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = ERROR_WRONG_FILE_TYPE;
                }
                break;
              }

              /* check special settings */
              error = File_getFileInfo(fileName,&localFileInfo);
              if (error != ERROR_NONE)
              {
                printError("Cannot not read local file '%s' (error: %s)!\n",
                           String_cString(fileName),
                           Errors_getText(error)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = error;
                }
                break;
              }
              if (fileInfo.specialType != localFileInfo.specialType)
              {
                printError("Different types of special device '%s'!\n",
                           String_cString(fileName)
                          );
                Archive_closeEntry(&archiveFileInfo);
                String_delete(fileName);
                if (jobOptions->stopOnErrorFlag)
                {
                  failError = error;
                }
                break;
              }
              if (   (fileInfo.specialType == FILE_SPECIAL_TYPE_CHARACTER_DEVICE)
                  || (fileInfo.specialType == FILE_SPECIAL_TYPE_BLOCK_DEVICE)
                 )
              {
                if (fileInfo.major != localFileInfo.major)
                {
                  printError("Different major numbers of special device '%s'!\n",
                             String_cString(fileName)
                            );
                  Archive_closeEntry(&archiveFileInfo);
                  String_delete(fileName);
                  if (jobOptions->stopOnErrorFlag)
                  {
                    failError = error;
                  }
                  break;
                }
                if (fileInfo.minor != localFileInfo.minor)
                {
                  printError("Different minor numbers of special device '%s'!\n",
                             String_cString(fileName)
                            );
                  Archive_closeEntry(&archiveFileInfo);
                  String_delete(fileName);
                  if (jobOptions->stopOnErrorFlag)
                  {
                    failError = error;
                  }
                  break;
                }
              }

#if 0

              /* check file time, permissions, file owner/group */
#endif /* 0 */

              printInfo(2,"ok\n");

              /* free resources */
            }
            else
            {
              /* skip */
              printInfo(3,"  Compare '%s'...skipped\n",String_cString(fileName));
            }

            /* close archive file */
            Archive_closeEntry(&archiveFileInfo);
            String_delete(fileName);
          }
          break;
        default:
          #ifndef NDEBUG
            HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE();
          #endif /* NDEBUG */
          break; /* not reached */
      }
    }

    /* close archive */
    Archive_close(&archiveInfo);
  }

  /* check fragment lists */
  for (fragmentNode = fragmentList.head; fragmentNode != NULL; fragmentNode = fragmentNode->next)
  {
    if (!FragmentList_checkEntryComplete(fragmentNode))
    {
      printInfo(0,"Warning: incomplete entry '%s'\n",String_cString(fragmentNode->name));
      if (failError == ERROR_NONE) failError = ERROR_FILE_INCOMPLETE;
    }
  }

  /* free resources */
  String_delete(archiveFileName);
  FragmentList_done(&fragmentList);
  free(buffer);
  free(archiveBuffer);

  return failError;
}
Exemplo n.º 24
0
bool Password_input(Password   *password,
                    const char *title,
                    uint       modes
                   )
{
  bool okFlag;

  assert(password != NULL);

  Password_clear(password);

  okFlag = FALSE;

  /* input via SSH_ASKPASS program */
  if (((modes & PASSWORD_INPUT_MODE_GUI) != 0) && !okFlag)
  {
    const char *sshAskPassword;
    String     command;
    FILE       *file;
    bool       eolFlag;
    int        ch;

    sshAskPassword = getenv("SSH_ASKPASS");
    if ((sshAskPassword != NULL) && (strcmp(sshAskPassword,"") != 0))
    {
      /* open pipe to external password program */
      command = String_newCString(sshAskPassword);
      if (title != NULL)
      {
        String_format(command," %\"s:",title);
      }
      file = popen(String_cString(command),"r");
      if (file == NULL)
      {
        String_delete(command);
        return FALSE;
      }
      String_delete(command);

      /* read password, discard last LF */
      printInfo(2,"Wait for password...");
      eolFlag = FALSE;
      do
      {
        ch = getc(file);
        if (ch != EOF)
        {
          switch ((char)ch)
          {
            case '\n':
            case '\r':
              eolFlag = TRUE;
              break;
            default:
              Password_appendChar(password,(char)ch);
              break;
          }
        }
        else
        {
          eolFlag = TRUE;
        }
      }
      while (!eolFlag);
      printInfo(2,"ok\n");

      /* close pipe */
      pclose(file);

      okFlag = TRUE;
    }
  }

  /* input via console */
  if (((modes & PASSWORD_INPUT_MODE_CONSOLE) != 0) && !okFlag)
  {
    int            n;
    struct termios oldTermioSettings;
    struct termios termioSettings;
    bool           eolFlag;
    char           ch;

    if (isatty(STDIN_FILENO) == 1)
    {
      /* read data from interactive input */
      if (title != NULL)
      {
        fprintf(stderr,"%s: ",title);fflush(stderr);
      }

      /* save current console settings */
      if (tcgetattr(STDIN_FILENO,&oldTermioSettings) != 0)
      {
        return FALSE;
      }

      /* disable echo */
      memcpy(&termioSettings,&oldTermioSettings,sizeof(struct termios));
      termioSettings.c_lflag &= ~ECHO;
      if (tcsetattr(STDIN_FILENO,TCSANOW,&termioSettings) != 0)
      {
        return FALSE;
      }

      /* input password */
      eolFlag = FALSE;
      do
      {
        if (read(STDIN_FILENO,&ch,1) == 1)
        {
          switch (ch)
          {
            case '\r':
              break;
            case '\n':
              eolFlag = TRUE;
              break;
            default:
              Password_appendChar(password,ch);
              break;
          }
        }
        else
        {
          eolFlag = TRUE;
        }
      }
      while (!eolFlag);

      /* restore console settings */
      tcsetattr(STDIN_FILENO,TCSANOW,&oldTermioSettings);

      if (title != NULL)
      {
        fprintf(stderr,"\n");
      }
    }
    else
    {
      /* read data from non-interactive input */
      eolFlag = FALSE;
      do
      {
        ioctl(STDIN_FILENO,FIONREAD,(char*)&n);
        if (n > 0)
        {
          if (read(STDIN_FILENO,&ch,1) == 1)
          {
            switch (ch)
            {
              case '\r':
                break;
              case '\n':
                eolFlag = TRUE;
                break;
              default:
                Password_appendChar(password,ch);
                break;
            }
          }
          else
          {
            eolFlag = TRUE;
          }
        }
      }
      while (!eolFlag && (n > 0));
    }

    okFlag = TRUE;
  }

  return okFlag;
}
Exemplo n.º 25
0
static BOOL _validPath(String* inputString)
{
    int state;
    int pos;
    char* str;
    String* inputCopy;
    String* validDriveLetters;
    String* invalidDirNameChars;

    validDriveLetters = String_new("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    invalidDirNameChars = String_new("/\\:*?\"<>|");

    state = 0;
    pos = 0;

    inputCopy = String_newCopy(inputString);
    String_toUppercase(inputCopy);
    str = inputCopy->mString;

    while (pos < inputString->mLength)
    {
        switch (state)
        {
        case 0: // Just starting out.
            if (str[pos] == '/' || str[pos] == '\\')
            {
                state = 1; //We have an absolute path on a unix system (accept backslash too, because we're lenient.).
            }
            else if (String_findChar(invalidDirNameChars, str[pos]) != -1)
            {
                state = 666; // Invalid path.
            }
            else if (String_findChar(validDriveLetters, str[pos]) != -1)
            {
                state = 2; // We have a windows drive letter, OR beginning of relative path.
            }
            else
            {
                state = 3; //Valid dirname character, but not letter. Beginning of relative path.
            }
            break;
        case 1: //Beginning of dir name.
            if (String_findChar(invalidDirNameChars, str[pos]) != -1)
            {
                state = 666; // Invalid path.
            }
            else
            {
                state = 3; //Valid dirname character.
            }
            break;
        case 2: //First char was letter. Either drive letter or beginning of dir name.
            if (str[pos] == ':' && (str[pos+1] == '/' || str[pos+1] == '\\'))
            {
                state = 1; pos++; // Absolute windows path.
            }
            else if (String_findChar(invalidDirNameChars, str[pos]) != -1)
            {
                state = 666; // Invalid path.
            }
            else
            {
                state = 3; // Relative path.
            }
            break;
        case 3: //Middle of dirname.
            if (str[pos] == '/' || str[pos] == '\\')
            {
                state = 1; // Found separator, new dirname.
            }
            else if (String_findChar(invalidDirNameChars, str[pos]) != -1)
            {
                state = 666; // Invalid path.
            }
            else
            {
                state = 3; // Name continues.
            }
            break;
        default:
            smug_assert(FALSE);
            break;
        }
        pos++;
    }
    String_delete(inputCopy);
    String_delete(validDriveLetters);
    String_delete(invalidDirNameChars);
    return (state != 666);
}
Exemplo n.º 26
0
char *
tree2string (struct Tree *tree) {
  String s;
  s = String_new();

  if (tree != NULL) {
    if (tree->child[0] != NULL) {
       if (tree->child[1] == NULL) {
         if (tree->child[0]->left != NULL && tree->child[0]->right != NULL) {
           String_appendChar(s, '(');
           tree2string_node(tree->child[0]->left, s);
           String_appendChar(s, ',');
           tree2string_node(tree->child[0]->right, s);
           String_appendCString(s, ");");           

         } else {
           if (tree->child[0]->clust->clustersize == 1) {
             String_appendCString(s, "0;");
           } else {
             unsigned  int i;
             for (i=0; i<tree->child[0]->clust->clustersize-1; i++) {
               String_appendChar(s, '(');
               distance2text(s, tree->child[0]->clust->members[i]->name, 0.0);
             }

             distance2text(s, tree->child[0]->clust->members[i]->name, 0.0);

             for (i=0; i<tree->child[0]->clust->clustersize-2; i++) {
               String_appendCString(s, "):0.0)");
             }

             String_appendCString(s, ");");
           }
         }
       }
    }
  }

//  unsigned int strlen = String_length(s);
  char *buffer = NULL;
//  buffer = malloc(sizeof(char) * (strlen+1));
//  strncpy(buffer, String_cString(s), strlen);

  char *position;
  const char *cString = String_cString(s);
//  fprintf(stderr, "[TREE]: ### %s ###\n", cString);
  position = strchr(cString, ';');
  if (position == NULL) {
    fprintf(stderr, "Error in trees\n");
    exit(-1);
  }
  int index = cString - position;
  if (index < 0) {
    index = -index;
  }
//  fprintf(stderr, "\tindex: %d\n", index);
  buffer = malloc(sizeof(char) * (index+2));
  strncpy(buffer, cString, index+1);
  buffer[index+1] = '\0';
//  fprintf(stderr, "\tbuffer: %s\n", buffer);

  String_delete(s);

  return buffer;
}
Exemplo n.º 27
0
void File_deleteFileName(String fileName)
{
  String_delete(fileName);
}
Exemplo n.º 28
0
PathName* PathName_new(String* string, BOOL isFile)
{
    PathName* newPn;
    int pos;
    String* pathWoRoot;
    String* separators;
    String* fileName;

    // Validate the path.
    if (!_validPath(string)) return NULL;

    separators = String_new("\\/");
    newPn = (PathName*)malloc(sizeof(PathName));

    // Check the root.
    pos = String_findChar(string, ':');
    if (1 == pos)
    {   // This is a Windows absolute path.
        newPn->root = String_newSubString(string, 0, 3);
        pos = 3;
    }
    else if (String_findChar(string, '/') == 0 || String_findChar(string, '\\') == 0)
    {   // This is a Unix absolute path.
        newPn->root = String_new("/");
        pos = 1;
    }
    else
    {   // This is a relative path.
        newPn->root = NULL;
        pos = 0;
    }

    // Parse the rest of the path.
    pathWoRoot = String_newSubString(string, pos, -1);
    newPn->path = String_splitMultiSep(pathWoRoot, separators);
    String_delete(pathWoRoot);

    if (isFile)
    {   // Get the file name.
        if (String_isEmpty((String*)newPn->path->last->item))
        {   // This was supposed to be a file, but the path ended in '/' or '\'
            String_delete(separators);
            PathName_delete(newPn);
            return NULL;
        }
        fileName = (String*)newPn->path->last->item;
        LinkedList_remove(newPn->path, newPn->path->last);
        // Find the extension, if there is one.
        pos = String_findCharReverse(fileName, '.');
        if (-1 == pos)
        {   // No extension (no '.' in file name).
            newPn->bareName = fileName;
            newPn->extension = NULL;
        }
        else
        {   // At least one '.' in file name. Separate out extension.
            newPn->bareName = String_newSubString(fileName, 0, pos);
            newPn->extension = String_newSubString(fileName, pos + 1, -1);
            String_delete(fileName);
        }
    }
    else
    {   // No file name.
        newPn->bareName = NULL;
        newPn->extension = NULL;
        if (String_isEmpty((String*)newPn->path->last->item))
        {   // The string ended in '/' or '\'. Last path element is empty, so remove it.
            String_delete((String*)newPn->path->last->item);
            LinkedList_remove(newPn->path, newPn->path->last);
        }
    }

    String_delete(separators);
    smug_assert(_invariant(newPn));
    return newPn;
}