Width given in format string is larger than the destination buffer.
Type mismatch between scanf format specifier (unsigned long long) and the variable type (long long).
str*cpy / strlen performance fix.

Calculating length of a string two times is unnecessary, and using strncpy width known string length can be replaced with memcpy.
Variable type fix for fgetc.

Reading a single character is fine with fgetc. But if you want to check for EOF, then you have to use 'int' as type,
and if the return value is not EOF, then it can be cast to 'char'.

Example for fail scenario before the fix: if the file contains 0xff character, then the code will interpret it as EOF.
0xff can be banned, but this should be checked in a proper way and not in the reading code.
Preventing use-after-freed possibility.

Probably the original intention was to prevent the possibility of a use-after-freed bug.
But the last strs = NULL statement has no effect, because it's just a local copy.
However, it makes sense to put a similar solution inside the loop right after the memory release.
This way if some codes try to use a previously freed array, then the array will seem to be empty.
String lib performance fix: using memcpy when the length is known.

Using strncpy(target, string, strlen(string)) equals with memcpy(target, string, strlen(string).
Both of them remove the \0 from the end. But for longer string memcpy is definitely more efficient,
because it does not have to search for string termination.

Usually the performance difference is small, and this kind of code rarely used elsewhere,
but a string handling lib should be efficient.
Type fix: 'char*' should be used for string storing instead of 'char'.
Fix for an unlikely memory leak in a unit test.

1 or 2 hosts work fine, otherwise the reserved memory should be released.
(However, using not 1 or 2 is quite hypothetical.)
strncpy fixes: wrong buffer size, lack of termination and similar errors are fixed.

There are lot of fixes here, but they are in a few main category:
1, strncpy(target, source, TARGETSIZE-1)  -> strlcpy(target, source, TARGETSIZE)
   If the target's last byte is not \0, then the string will not be terminated.
2, strncpy(target, source, TARGETSIZE) -> strlcpy(target, source, TARGETSIZE)
   If the source is longer than the target, then the string will not get NUL termination
3, combination of memset + strncpy or strncpy + buffer[last_byte]=0 -> strlcpy
   It's ugly and inefficient but at least gives correct result.

Remark: the usual string length (e.g. variable name, path) is much shorter than the buffer size (1k or 4k)
Using strncpy is quite inefficient because it always fills the rest of the array with 0s.
If you definitely need this feature, then rather use a memset + strlcpy + comment.
(E.g. // I want to fill this whole buffer with 0s, because it contained a private key previously.)
strncpy / strncat inefficiencies.

strncpy with known length can be replace with memcpy.
manual \0 + strncat is ugly, and strlcpy just does the job well.
strncpy + manual termination -> strlcpy
A few more strncpy fixes: buffer size limit, termination, etc.
Memory leak fix in 'ConfigurationDestroy'.
Redmine#4913: file_hash function
Redmine #4730: Add findfiles support for Windows by glob() replacement
Move several low level file functions to libutils.

This was they can be used from libcompat replacement functions.
Sync master ChangeLog up with version in 3.6.x branch.
Add message aid on Windows to avoid dir separator errors in findfiles.
Add SeqSoftSort, SeqBinaryLookup and SeqBinaryIndexOf functions.
Move DeleteDirectoryTree and FILE_SEPARATOR to libutils.

They don't depend on anything in libpromises, and this makes them
available for use outside of libpromises as well.
Redmine #2917: Rewrite file monitoring (files changes attribute).

The old implementation suffered from the fact that the database layout
was unsuited for the task. Each was indexed solely by filename,
however we want to do detection of file removals as well. Since, if
the file has vanished from the file system, we don't have the database
key anymore, it was not possible to find vanished files without
traversing the entire database.

While this was possible, you had to choose between two evils. Either
you traverse the entire database once at the end of the run, and
report missing files then, but this has the disadvantage that you
cannot tie the message to any particular promise, nor can you report
it correctly in Mission Portal. The other alternative is to check
after each file promise, but this has the disadvantage that each
promise pays the price of every other file promise combined, since we
have to traverse the entire database, and do a stat for every entry
(if you had one directory with 200000 files, and 200 directories with
just a few files, performance would be on the order of 200x200000
iterations, even if you did not run the promise that had 200000 files
in it).

The solution is to change the database format. The stat and checksum
information remains semantically the same (with a few minor tweaks to
the DB key), but we add a directory listing for each monitored
directory, so that we can look up the list without knowing which file
we are looking for, only the containing directory.

All the information is now also contained within one single database,
instead of the two that existed before. It has a new name and the old
databases will be migrated to the new name and format if they exist.

A lot of reorganizing was also done as part of this, with all "files
changes" related code gathered in one file: files_changes.c.