-.TH "CHPATHTOOL" "5" "Dec 2007" "Portage 2.2-prefix" "Portage"
+.TH "CHPATHTOOL" "5" "May 2011" "Portage 2.2-prefix" "Portage"
.SH NAME
chpathtool \- changes paths inside files
.SH SYNOPSIS
.RB "The important difference of " chpathtool " when compared to e.g.
.BR sed "(1)
is that for the strings it replaces, it maintains the original string
-.RI "length of " magic " by padding the " value " string with zero
-.RI "bytes, until the size of " magic " is reached.
+.RI "length of " magic " by prepending as much '/'-characters as needed
+.RI "to the " value " string to match the size of " magic " for binary files."
.P
.RB "For efficiency, " chpathtool " will operate recursively if
.IR in-file " is a directory. In that case, " out-file " is assumed
.P
.BR chpathtool " is meant for the Prefix branch of Portage to relocate
packages from one prefix offset to another. This ability allows for the
-use of binary packages, even though built for a different prefix offset.
-.RB "When " chpathtool " has found a match inside a binary file, it replaces
+use of binary packages, even though built for a different offset prefix.
+.P
+.RB "When " chpathtool " has found a match inside a binary file,
+it simply uses the replacement string which has been prepended with as
+many '/'-characters as necessary to match the size of the to be replaced
+string. This strategy makes an awkward but correct path on UNIX
+systems, and has the advantage of being as long as the original path.
+This is in particular important for binary files that may store
+information about the original string. An example is C-code where the
+optimizer replaced a strlen(static_path_var) with the actual length of
+that string. The strings cannot be just shortened also because in
+binaries typically offsets are used to find relevant pieces of data.
+Changing the size here would break those offsets.
+.P
+For text files, it avoids adding many '/'-characters because the
+previously mentioned string length problem is typically is not going to
+be a problem. Here,
+.B chpathtool
+replaces
the string, and searches for the end of the string in the form of a
zero-byte ('\\0'). At this byte, the neccessary padding bytes are
-inserted, such that the binary internally doesn't change in size. This
-is important for binaries where offsets are used to find relevant pieces
-of data. For certain files, this zero-byte is never found, such as in
-.RB "e.g. text files. For those files, " chpathtool " will " not "
+inserted, such that the file internally doesn't change in size, if it
+happens to have zero-bytes in it. It is to be expected that for text
+files, this zero-byte is never found, and
+.BR "chpathtool " will " not "
write out the padding zero-bytes, and produce a warning about this
instead.
.P
* chpathtool replaces a given string (magic) into another (value),
* thereby paying attention to the original size of magic in order not
* to change offsets in the file changed. To achieve this goal, value
- * is not greater in size than magic, and the difference in size between
- * the two is compensated by adding NULL-bytes at the end of a modified
- * string. The end of a string is considered to be at the first
- * NULL-byte encountered after magic. If no such NULL-byte is found, as
- * in a plain text file, the padding NULL-bytes are silently dropped.
+ * may not be greater in size than magic, and for binary files, the
+ * difference in size between the two is compensated by prepending
+ * '/'-characters to value uptil it matches the size of magic. For text
+ * files magic is just replaced with value, with the additional logic
+ * that the end of a string is considered to be at the first NULL-byte
+ * encountered after magic. If no such NULL-byte is found, the padding
+ * NULL-bytes are silently dropped. Since this is done on text files,
+ * this is likely the case.
*/
#include <stdio.h>
firstblock = 0;
/* examine the bytes we read to judge if they are binary or
* text; in case of the latter we can avoid writing ugly
- * paths with zilions of backslashes */
+ * paths with zilions of slashes */
for (pos = 0; pos < len; pos++) {
/* this is a very stupid assumption, but I don't know
* anything better: if we find a byte that's out of