Rev 17 | Rev 19 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 17 | Rev 18 | ||
---|---|---|---|
Line 86... | Line 86... | ||
86 | uint32_t mtime_for_inline_files; // same as above but only for files that don't exist on the build host (i.e. files with an explicit content blob) |
86 | uint32_t mtime_for_inline_files; // same as above but only for files that don't exist on the build host (i.e. files with an explicit content blob) |
87 | char *prefix; // [prefix=path] install path (e.g. "proc/boot") |
87 | char *prefix; // [prefix=path] install path (e.g. "proc/boot") |
88 | bool should_follow_symlinks; // follow symlinks |
88 | bool should_follow_symlinks; // follow symlinks |
89 | bool should_autosymlink_dylib; // dynamic libraries should be written under their official SONAME and a named symlink be created pointing at them |
89 | bool should_autosymlink_dylib; // dynamic libraries should be written under their official SONAME and a named symlink be created pointing at them |
90 | bool should_keep_ld_output; // whether to keep .sym files produced by ld calls, togglable by the [+keeplinked] attribute |
90 | bool should_keep_ld_output; // whether to keep .sym files produced by ld calls, togglable by the [+keeplinked] attribute |
- | 91 | bool should_ignore_duplicates; // [+|-dupignore] whether to ignore duplicates |
|
- | 92 | bool should_allow_nonexistent_files; // [+|-optional] whether to continue processing on unexistent files |
|
91 | bool is_compiled_bootscript; // entry has [+script] attribute |
93 | bool is_compiled_bootscript; // entry has [+script] attribute |
92 | int extra_ino_flags; // bitmap of extra inode flags (IFS_INO_xxx) |
94 | int extra_ino_flags; // bitmap of extra inode flags (IFS_INO_xxx) |
93 | char *search; // [search=path[:path]] binary search path (the default one will be constructed at startup) |
95 | char *search; // [search=path[:path]] binary search path (the default one will be constructed at startup) |
94 | 96 | ||
95 | buffer_t data; // the resolved file's own data bytes |
97 | buffer_t data; // the resolved file's own data bytes |
Line 218... | Line 220... | ||
218 | { false, "/lib/dll" }, // prefix with $PROCESSOR/ |
220 | { false, "/lib/dll" }, // prefix with $PROCESSOR/ |
219 | { false, "/usr/lib" } // prefix with $PROCESSOR/ |
221 | { false, "/usr/lib" } // prefix with $PROCESSOR/ |
220 | }; |
222 | }; |
221 | static thread_local char *resolved_pathname = NULL; |
223 | static thread_local char *resolved_pathname = NULL; |
222 | 224 | ||
- | 225 | void *reallocated_ptr; |
|
- | 226 | char *resolved_search_path; |
|
- | 227 | char *replacement; |
|
- | 228 | size_t old_searchpath_len; |
|
- | 229 | size_t new_searchpath_len; |
|
- | 230 | size_t replacement_len; |
|
- | 231 | size_t middlebit_len; |
|
- | 232 | size_t endbit_len; |
|
223 | size_t defaultpath_index; |
233 | size_t defaultpath_index; |
224 | struct stat stat_buf; |
234 | struct stat stat_buf; |
- | 235 | int erase_index; |
|
- | 236 | char erased_char; |
|
- | 237 | char *varname; |
|
225 |
|
238 | char *nextsep; |
- | 239 | char *endbit; |
|
226 |
|
240 | char *token; |
227 | 241 | ||
228 | // initial allocation (per thread) |
242 | // initial allocation (per thread) |
229 | if (resolved_pathname == NULL) |
243 | if (resolved_pathname == NULL) |
230 | { |
244 | { |
231 | resolved_pathname = malloc (MAXPATHLEN); |
245 | resolved_pathname = malloc (MAXPATHLEN); |
Line 282... | Line 296... | ||
282 | search_paths_or_NULL_for_MKIFS_PATH_envvar = (SEARCH_PATH != NULL ? SEARCH_PATH : getenv ("MKIFS_PATH")); |
296 | search_paths_or_NULL_for_MKIFS_PATH_envvar = (SEARCH_PATH != NULL ? SEARCH_PATH : getenv ("MKIFS_PATH")); |
283 | 297 | ||
284 | // construct a potential final path using each element of the search path |
298 | // construct a potential final path using each element of the search path |
285 | if (search_paths_or_NULL_for_MKIFS_PATH_envvar != NULL) |
299 | if (search_paths_or_NULL_for_MKIFS_PATH_envvar != NULL) |
286 | { |
300 | { |
- | 301 | // the first step is to resolve all environment variables in the search path |
|
287 |
|
302 | resolved_search_path = strdup (search_paths_or_NULL_for_MKIFS_PATH_envvar); |
- | 303 | ASSERT_WITH_ERRNO (resolved_search_path); |
|
- | 304 | while ((((token = strstr (resolved_search_path, "${")) != NULL) && ((endbit = strchr (token, '}')) != NULL)) // look for variables in the "${VARNAME}" format *AND* in "$VARNAME" format |
|
- | 305 | || (((token = strstr (resolved_search_path, "$")) != NULL) && ((middlebit_len = strspn (token, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_")) != strlen (token)))) |
|
- | 306 | { |
|
- | 307 | if (token[1] == '{') // "${VARNAME}" format |
|
- | 308 | { |
|
- | 309 | endbit++; // locate where the end bit begins |
|
- | 310 | varname = token + 2; // skip the leading two characters: "${" |
|
- | 311 | erase_index = -1; // we shall split the string at the character that's *just before* where the end bit starts |
|
- | 312 | } |
|
- | 313 | else // "$VARNAME" format |
|
- | 314 | { |
|
- | 315 | endbit = &token[middlebit_len]; // locate where the end bit begins |
|
- | 316 | varname = token + 1; // skip the leading '$' |
|
- | 317 | erase_index = 0; // we shall split the string at the character that's *right where* the end bit starts |
|
- | 318 | } |
|
- | 319 | old_searchpath_len = strlen (resolved_search_path); // measure current string length |
|
- | 320 | endbit_len = strlen (endbit); // measure the length of the end bit (skip the closing curly brace) |
|
- | 321 | erased_char = endbit[erase_index]; // remember which is the character we're going to erase |
|
- | 322 | endbit[erase_index] = 0; // split the string at the end of the variable name |
|
- | 323 | replacement = getenv (varname); // peek at the environment for its value |
|
- | 324 | if (replacement == NULL) |
|
- | 325 | replacement = ""; // if this variable isn't defined, fallback to an empty string, just like what a UNIX shell does |
|
- | 326 | endbit[erase_index] = erased_char; // put the erased character back |
|
- | 327 | replacement_len = strlen (replacement); // measure replacement length |
|
- | 328 | new_searchpath_len = (size_t) token - (size_t) resolved_search_path + replacement_len + endbit_len; // measure updated search path len |
|
- | 329 | if (new_searchpath_len > old_searchpath_len) |
|
- | 330 | { |
|
- | 331 | reallocated_ptr = realloc (resolved_search_path, new_searchpath_len + 1); // grow it if necessary |
|
- | 332 | ASSERT_WITH_ERRNO (reallocated_ptr); |
|
- | 333 | token = &((char *) reallocated_ptr)[token - resolved_search_path]; // fix the pointers that may have moved |
|
- | 334 | endbit = &((char *) reallocated_ptr)[endbit - resolved_search_path]; // fix the pointers that may have moved |
|
- | 335 | resolved_search_path = reallocated_ptr; |
|
- | 336 | } |
|
- | 337 | memmove (token + replacement_len, endbit, endbit_len + 1); // move the end bit to its final location (including its nul terminator) |
|
- | 338 | memcpy (token, replacement, replacement_len); // and patch the replacement in between |
|
- | 339 | } |
|
- | 340 | ||
- | 341 | // now split this search path string into multiple tokens and process them one after the other |
|
- | 342 | token = (*resolved_search_path != 0 ? resolved_search_path : NULL); |
|
288 | nextsep = (token != NULL ? &token[strcspn (token, PATH_SEP)] : NULL); |
343 | nextsep = (token != NULL ? &token[strcspn (token, PATH_SEP)] : NULL); |
289 | while (token != NULL) |
344 | while (token != NULL) |
290 | { |
345 | { |
- | 346 | // look under this search path at each of the known subpaths |
|
291 | for (defaultpath_index = 0; defaultpath_index < sizeof (default_paths) / sizeof (default_paths[0]); defaultpath_index++) |
347 | for (defaultpath_index = 0; defaultpath_index < sizeof (default_paths) / sizeof (default_paths[0]); defaultpath_index++) |
292 | { |
348 | { |
293 | sprintf_s (resolved_pathname, MAXPATHLEN, "%.*s/%s/%s/%s", (int) (nextsep - token), token, (default_paths[defaultpath_index].uses_processor_base ? image_processor_base : image_processor), default_paths[defaultpath_index].subpath, pathname); |
349 | sprintf_s (resolved_pathname, MAXPATHLEN, "%.*s/%s/%s/%s", (int) (nextsep - token), token, (default_paths[defaultpath_index].uses_processor_base ? image_processor_base : image_processor), default_paths[defaultpath_index].subpath, pathname); |
294 | if ((stat (resolved_pathname, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
350 | if ((stat (resolved_pathname, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
295 | return (resolved_pathname); // if a file can indeed be found at this location, stop searching |
351 | return (resolved_pathname); // if a file can indeed be found at this location, stop searching |
Line 298... | Line 354... | ||
298 | token = (*nextsep != 0 ? nextsep + 1 : NULL); |
354 | token = (*nextsep != 0 ? nextsep + 1 : NULL); |
299 | nextsep = (token != NULL ? &token[strcspn (token, PATH_SEP)] : NULL); |
355 | nextsep = (token != NULL ? &token[strcspn (token, PATH_SEP)] : NULL); |
300 | } |
356 | } |
301 | } |
357 | } |
302 | 358 | ||
303 | // file not found in search paths: look under QNX_TARGET |
359 | // file not found in search paths: look under QNX_TARGET at each of the known subpaths |
304 | for (defaultpath_index = 0; defaultpath_index < sizeof (default_paths) / sizeof (default_paths[0]); defaultpath_index++) |
360 | for (defaultpath_index = 0; defaultpath_index < sizeof (default_paths) / sizeof (default_paths[0]); defaultpath_index++) |
305 | { |
361 | { |
306 | sprintf_s (resolved_pathname, MAXPATHLEN, "%s/%s/%s/%s", QNX_TARGET, (default_paths[defaultpath_index].uses_processor_base ? image_processor_base : image_processor), default_paths[defaultpath_index].subpath, pathname); |
362 | sprintf_s (resolved_pathname, MAXPATHLEN, "%s/%s/%s/%s", QNX_TARGET, (default_paths[defaultpath_index].uses_processor_base ? image_processor_base : image_processor), default_paths[defaultpath_index].subpath, pathname); |
307 | if ((stat (resolved_pathname, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
363 | if ((stat (resolved_pathname, &stat_buf) == 0) && S_ISREG (stat_buf.st_mode)) |
308 | return (resolved_pathname); // if a file can indeed be found at this location, stop searching |
364 | return (resolved_pathname); // if a file can indeed be found at this location, stop searching |
Line 637... | Line 693... | ||
637 | static size_t add_fsentry (fsentry_t **fsentries, size_t *fsentry_count, parms_t *entry_parms, const char *stored_pathname, const char *buildhost_pathname) |
693 | static size_t add_fsentry (fsentry_t **fsentries, size_t *fsentry_count, parms_t *entry_parms, const char *stored_pathname, const char *buildhost_pathname) |
638 | { |
694 | { |
639 | static thread_local char *candidate_pathname = NULL; |
695 | static thread_local char *candidate_pathname = NULL; |
640 | static int inode_count = 0; // will be preincremented each time this function is called |
696 | static int inode_count = 0; // will be preincremented each time this function is called |
641 | 697 | ||
- | 698 | const char *stored_pathname_without_leading_slash; |
|
642 | const char *original_stored_pathname = NULL; |
699 | const char *original_stored_pathname = NULL; |
643 | buffer_t *shstrtab = NULL; |
700 | buffer_t *shstrtab = NULL; |
644 | const char *canonical_dylib_name; |
701 | const char *canonical_dylib_name; |
645 | const char *dynamic_strings; // strings table of the ".dynamic" section |
702 | const char *dynamic_strings; // strings table of the ".dynamic" section |
646 | const char *last_dirsep; |
703 | const char *last_dirsep; |
647 | char *global_envstring = NULL; |
704 | char *global_envstring = NULL; |
648 | size_t global_envstring_len = 0; |
705 | size_t global_envstring_len = 0; |
- | 706 | size_t fsentry_index; |
|
649 | char *startup_name = NULL; |
707 | char *startup_name = NULL; |
650 | char *procnto_name = NULL; |
708 | char *procnto_name = NULL; |
651 | char *resolved_pathname; |
709 | char *resolved_pathname; |
652 | void *reallocated_ptr; |
710 | void *reallocated_ptr; |
653 | void *old_data; |
711 | void *old_data; |
Line 669... | Line 727... | ||
669 | { |
727 | { |
670 | if (strcmp (stored_pathname, "/proc/boot/boot") == 0) // is it the kernel ? |
728 | if (strcmp (stored_pathname, "/proc/boot/boot") == 0) // is it the kernel ? |
671 | { |
729 | { |
672 | // HACK: for now just consider the kernel as a binary blob |
730 | // HACK: for now just consider the kernel as a binary blob |
673 | // FIXME: reimplement properly |
731 | // FIXME: reimplement properly |
674 | #ifdef PROCNTO_WIP |
732 | #ifdef PROCNTO_WIP |
675 | char *linebit_start; |
733 | char *linebit_start; |
676 | char *content_line; |
734 | char *content_line; |
677 | char *write_ptr; |
735 | char *write_ptr; |
678 | char *token; |
736 | char *token; |
679 | char *value; |
737 | char *value; |
Line 941... | Line 999... | ||
941 | } |
999 | } |
942 | else if (buildhost_pathname != NULL) // else was a source file pathname supplied ? |
1000 | else if (buildhost_pathname != NULL) // else was a source file pathname supplied ? |
943 | { |
1001 | { |
944 | resolved_pathname = resolve_pathname (buildhost_pathname, entry_parms->search); // locate the file |
1002 | resolved_pathname = resolve_pathname (buildhost_pathname, entry_parms->search); // locate the file |
945 | if (resolved_pathname == NULL) |
1003 | if (resolved_pathname == NULL) |
- | 1004 | { |
|
- | 1005 | if (entry_parms->should_allow_nonexistent_files) |
|
- | 1006 | { |
|
- | 1007 | LOG_WARNING ("filesystem entry \"%s\" specified in \"%s\" line %d not found on build host: ignoring", buildhost_pathname, buildfile_pathname, lineno); |
|
- | 1008 | return (*fsentry_count); // if we're allowed to continue when a file to add doesn't exist, do so, else die with an error message |
|
- | 1009 | } |
|
946 | DIE_WITH_EXITCODE (1, "filesystem entry \"%s\" specified in \"%s\" line %d not found on build host: %s", buildhost_pathname, buildfile_pathname, lineno, strerror (errno)); |
1010 | DIE_WITH_EXITCODE (1, "filesystem entry \"%s\" specified in \"%s\" line %d not found on build host: %s", buildhost_pathname, buildfile_pathname, lineno, strerror (errno)); |
- | 1011 | } |
|
947 | if (!Buffer_ReadFromFile (&entry_parms->data, resolved_pathname)) |
1012 | if (!Buffer_ReadFromFile (&entry_parms->data, resolved_pathname)) |
948 | DIE_WITH_EXITCODE (1, "filesystem entry \"%s\" specified in \"%s\" line %d can't be read: %s", buildhost_pathname, buildfile_pathname, lineno, strerror (errno)); |
1013 | DIE_WITH_EXITCODE (1, "filesystem entry \"%s\" specified in \"%s\" line %d can't be read: %s", buildhost_pathname, buildfile_pathname, lineno, strerror (errno)); |
949 | stat (resolved_pathname, &stat_buf); // can't fail, since we could read it |
1014 | stat (resolved_pathname, &stat_buf); // can't fail, since we could read it |
950 | if (entry_parms->mtime == UINT32_MAX) |
1015 | if (entry_parms->mtime == UINT32_MAX) |
951 | entry_parms->mtime = (uint32_t) stat_buf.st_mtime; |
1016 | entry_parms->mtime = (uint32_t) stat_buf.st_mtime; |
Line 1009... | Line 1074... | ||
1009 | if (strchr (entry_parms->data.bytes, ':') == NULL) |
1074 | if (strchr (entry_parms->data.bytes, ':') == NULL) |
1010 | DIE_WITH_EXITCODE (1, "device entry \"%s\" malformed (no 'dev:rdev' pair)", stored_pathname); |
1075 | DIE_WITH_EXITCODE (1, "device entry \"%s\" malformed (no 'dev:rdev' pair)", stored_pathname); |
1011 | LOG_INFO ("fifo: ino 0x%x uid %d gid %d mode 0%o path \"%s\" dev:rdev %s)", inode_count + 1, entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname, entry_parms->data.bytes); |
1076 | LOG_INFO ("fifo: ino 0x%x uid %d gid %d mode 0%o path \"%s\" dev:rdev %s)", inode_count + 1, entry_parms->uid, entry_parms->gid, entry_parms->st_mode, stored_pathname, entry_parms->data.bytes); |
1012 | } |
1077 | } |
1013 | 1078 | ||
- | 1079 | // have a pointer to where the stored pathname actually starts, without the leading slash |
|
- | 1080 | stored_pathname_without_leading_slash = stored_pathname[0] == '/' ? &stored_pathname[1] : stored_pathname; |
|
- | 1081 | ||
- | 1082 | // see if this item already has an entry in the current list of filesystem entries |
|
- | 1083 | for (fsentry_index = 0; fsentry_index < *fsentry_count; fsentry_index++) |
|
- | 1084 | { |
|
- | 1085 | fsentry = &(*fsentries)[fsentry_index]; // quick access to fs entry slot |
|
- | 1086 | if ( (S_ISDIR (fsentry->header.mode) && (strcmp (fsentry->u.dir.path, stored_pathname_without_leading_slash) == 0)) |
|
- | 1087 | || (S_ISREG (fsentry->header.mode) && (strcmp (fsentry->u.file.path, stored_pathname_without_leading_slash) == 0)) |
|
- | 1088 | || (S_ISLNK (fsentry->header.mode) && (strcmp (fsentry->u.symlink.path, stored_pathname_without_leading_slash) == 0)) |
|
- | 1089 | || (S_ISFIFO (fsentry->header.mode) && (strcmp (fsentry->u.symlink.path, stored_pathname_without_leading_slash) == 0))) |
|
- | 1090 | break; // stop searching as soon as we find a duplicate |
|
- | 1091 | } |
|
- | 1092 | ||
- | 1093 | // is there already an entry for this item ? |
|
- | 1094 | if (fsentry_index < *fsentry_count) |
|
- | 1095 | { |
|
- | 1096 | // if we should NOT ignore duplicates, bomb out, else just reuse that entry |
|
- | 1097 | if (!entry_parms->should_ignore_duplicates) |
|
- | 1098 | DIE_WITH_EXITCODE (1, "duplicate detected: entry \"%s\" specified in \"%s\" line %d already exists in IFS file", stored_pathname, buildfile_pathname, lineno); |
|
- | 1099 | } |
|
1014 | // grow filesystem entries array to hold one more slot |
1100 | else // this is a new entry: grow filesystem entries array to hold one more slot |
- | 1101 | { |
|
1015 | reallocated_ptr = realloc (*fsentries, (*fsentry_count + 1) * sizeof (fsentry_t)); // attempt to reallocate |
1102 | reallocated_ptr = realloc (*fsentries, (*fsentry_count + 1) * sizeof (fsentry_t)); // attempt to reallocate |
1016 | ASSERT_WITH_ERRNO (reallocated_ptr); |
1103 | ASSERT_WITH_ERRNO (reallocated_ptr); // verify |
1017 | *fsentries = reallocated_ptr; // save reallocated pointer |
1104 | *fsentries = reallocated_ptr; // save reallocated pointer |
1018 | fsentry = &(*fsentries)[*fsentry_count]; // quick access to fs entry slot |
1105 | fsentry = &(*fsentries)[*fsentry_count]; // quick access to fs entry slot |
- | 1106 | (*fsentry_count)++; // remember there's one entry more in the array |
|
- | 1107 | } |
|
- | 1108 | ||
- | 1109 | // save (or update) this entry's parameters |
|
1019 | fsentry->header.extattr_offset = 0; |
1110 | fsentry->header.extattr_offset = 0; |
1020 | fsentry->header.ino = entry_parms->extra_ino_flags | (++inode_count); |
1111 | fsentry->header.ino = entry_parms->extra_ino_flags | (++inode_count); |
1021 | fsentry->header.mode = entry_parms->st_mode; |
1112 | fsentry->header.mode = entry_parms->st_mode; |
1022 | fsentry->header.gid = entry_parms->gid; |
1113 | fsentry->header.gid = entry_parms->gid; |
1023 | fsentry->header.uid = entry_parms->uid; |
1114 | fsentry->header.uid = entry_parms->uid; |
1024 | fsentry->header.mtime = (entry_parms->mtime == UINT32_MAX ? (uint32_t) time (NULL) : entry_parms->mtime); |
1115 | fsentry->header.mtime = (entry_parms->mtime == UINT32_MAX ? (uint32_t) time (NULL) : entry_parms->mtime); |
1025 | if (S_ISDIR (entry_parms->st_mode)) |
1116 | if (S_ISDIR (entry_parms->st_mode)) |
1026 | { |
1117 | { |
1027 | fsentry->u.dir.path = strdup ( |
1118 | fsentry->u.dir.path = strdup (stored_pathname_without_leading_slash); |
1028 | 1119 | ||
1029 | fsentry->header.size = (uint16_t) ROUND_TO_UPPER_MULTIPLE (sizeof (fsentry->header) + strlen (fsentry->u.dir.path) + 1, image_align); // now we can set the size |
1120 | fsentry->header.size = (uint16_t) ROUND_TO_UPPER_MULTIPLE (sizeof (fsentry->header) + strlen (fsentry->u.dir.path) + 1, image_align); // now we can set the size |
1030 | fsentry->UNSAVED_was_data_written = true; // no data to save |
1121 | fsentry->UNSAVED_was_data_written = true; // no data to save |
1031 | } |
1122 | } |
1032 | else if (S_ISREG (entry_parms->st_mode)) |
1123 | else if (S_ISREG (entry_parms->st_mode)) |
1033 | { |
1124 | { |
1034 | fsentry->u.file.offset = WILL_BE_FILLED_LATER; // will be filled later in main() when the file's data blob will be written to the output file |
1125 | fsentry->u.file.offset = WILL_BE_FILLED_LATER; // will be filled later in main() when the file's data blob will be written to the output file |
1035 | fsentry->u.file.size = (uint32_t) entry_parms->data.size; |
1126 | fsentry->u.file.size = (uint32_t) entry_parms->data.size; |
1036 | fsentry->u.file.path = strdup ( |
1127 | fsentry->u.file.path = strdup (stored_pathname_without_leading_slash); |
1037 | fsentry->u.file.UNSAVED_databuf = malloc (entry_parms->data.size); |
1128 | fsentry->u.file.UNSAVED_databuf = malloc (entry_parms->data.size); |
1038 | ASSERT_WITH_ERRNO (fsentry->u.file.UNSAVED_databuf); |
1129 | ASSERT_WITH_ERRNO (fsentry->u.file.UNSAVED_databuf); |
1039 | memcpy (fsentry->u.file.UNSAVED_databuf, entry_parms->data.bytes, entry_parms->data.size); |
1130 | memcpy (fsentry->u.file.UNSAVED_databuf, entry_parms->data.bytes, entry_parms->data.size); |
1040 | 1131 | ||
1041 | fsentry->header.size = (uint16_t) ROUND_TO_UPPER_MULTIPLE (sizeof (fsentry->header) + sizeof (uint32_t) + sizeof (uint32_t) + strlen (fsentry->u.file.path) + 1, image_align); // now we can set the size |
1132 | fsentry->header.size = (uint16_t) ROUND_TO_UPPER_MULTIPLE (sizeof (fsentry->header) + sizeof (uint32_t) + sizeof (uint32_t) + strlen (fsentry->u.file.path) + 1, image_align); // now we can set the size |
1042 | fsentry->UNSAVED_was_data_written = false; // there *IS* data to save |
1133 | fsentry->UNSAVED_was_data_written = false; // there *IS* data to save |
1043 | } |
1134 | } |
1044 | else if (S_ISLNK (entry_parms->st_mode)) |
1135 | else if (S_ISLNK (entry_parms->st_mode)) |
1045 | { |
1136 | { |
1046 | fsentry->u.symlink.sym_offset = (uint16_t) (strlen ( |
1137 | fsentry->u.symlink.sym_offset = (uint16_t) (strlen (stored_pathname_without_leading_slash) + 1); |
1047 | fsentry->u.symlink.sym_size = (uint16_t) entry_parms->data.size; |
1138 | fsentry->u.symlink.sym_size = (uint16_t) entry_parms->data.size; |
1048 | fsentry->u.symlink.path = strdup ( |
1139 | fsentry->u.symlink.path = strdup (stored_pathname_without_leading_slash); |
1049 | fsentry->u.symlink.contents = strdup (entry_parms->data.bytes); |
1140 | fsentry->u.symlink.contents = strdup (entry_parms->data.bytes); |
1050 | ASSERT_WITH_ERRNO (fsentry->u.symlink.contents); |
1141 | ASSERT_WITH_ERRNO (fsentry->u.symlink.contents); |
1051 | 1142 | ||
1052 | fsentry->header.size = (uint16_t) ROUND_TO_UPPER_MULTIPLE (sizeof (fsentry->header) + sizeof (uint16_t) + sizeof (uint16_t) + (size_t) fsentry->u.symlink.sym_offset + fsentry->u.symlink.sym_size + 1, image_align); // now we can set the size |
1143 | fsentry->header.size = (uint16_t) ROUND_TO_UPPER_MULTIPLE (sizeof (fsentry->header) + sizeof (uint16_t) + sizeof (uint16_t) + (size_t) fsentry->u.symlink.sym_offset + fsentry->u.symlink.sym_size + 1, image_align); // now we can set the size |
1053 | fsentry->UNSAVED_was_data_written = true; // no data to save |
1144 | fsentry->UNSAVED_was_data_written = true; // no data to save |
1054 | } |
1145 | } |
1055 | else // necessarily a device node |
1146 | else // necessarily a device node |
1056 | { |
1147 | { |
1057 | fsentry->u.device.dev = strtol (entry_parms->data.bytes, NULL, 0); // use strtol() to parse decimal (...), hexadecimal (0x...) and octal (0...) numbers |
1148 | fsentry->u.device.dev = strtol (entry_parms->data.bytes, NULL, 0); // use strtol() to parse decimal (...), hexadecimal (0x...) and octal (0...) numbers |
1058 | fsentry->u.device.rdev = strtol (strchr (entry_parms->data.bytes, ':') + 1, NULL, 0); // use strtol() to parse decimal (...), hexadecimal (0x...) and octal (0...) numbers |
1149 | fsentry->u.device.rdev = strtol (strchr (entry_parms->data.bytes, ':') + 1, NULL, 0); // use strtol() to parse decimal (...), hexadecimal (0x...) and octal (0...) numbers |
1059 | fsentry->u.device.path = strdup ( |
1150 | fsentry->u.device.path = strdup (stored_pathname_without_leading_slash); |
1060 | 1151 | ||
1061 | fsentry->header.size = (uint16_t) ROUND_TO_UPPER_MULTIPLE (sizeof (fsentry->header) + sizeof (uint32_t) + sizeof (uint32_t) + strlen (fsentry->u.device.path), image_align); // now we can set the size |
1152 | fsentry->header.size = (uint16_t) ROUND_TO_UPPER_MULTIPLE (sizeof (fsentry->header) + sizeof (uint32_t) + sizeof (uint32_t) + strlen (fsentry->u.device.path), image_align); // now we can set the size |
1062 | fsentry->UNSAVED_was_data_written = true; // no data to save |
1153 | fsentry->UNSAVED_was_data_written = true; // no data to save |
1063 | } |
1154 | } |
1064 | (*fsentry_count)++; |
- | |
1065 | 1155 | ||
1066 | // should we also add a symlink to this entry ? (in case we stored a dylib file under its canonical name) |
1156 | // should we also add a symlink to this entry ? (in case we stored a dylib file under its canonical name) |
1067 | if (original_stored_pathname != NULL) |
1157 | if (original_stored_pathname != NULL) |
1068 | { |
1158 | { |
1069 | entry_parms->is_compiled_bootscript = false; |
1159 | entry_parms->is_compiled_bootscript = false; |
Line 1233... | Line 1323... | ||
1233 | else if (strcmp (token, "-followlink") == 0) entry_parms.should_follow_symlinks = false; |
1323 | else if (strcmp (token, "-followlink") == 0) entry_parms.should_follow_symlinks = false; |
1234 | else if (strcmp (token, "+autolink") == 0) entry_parms.should_autosymlink_dylib = true; |
1324 | else if (strcmp (token, "+autolink") == 0) entry_parms.should_autosymlink_dylib = true; |
1235 | else if (strcmp (token, "-autolink") == 0) entry_parms.should_autosymlink_dylib = false; |
1325 | else if (strcmp (token, "-autolink") == 0) entry_parms.should_autosymlink_dylib = false; |
1236 | else if (strcmp (token, "+keeplinked") == 0) entry_parms.should_keep_ld_output = true; |
1326 | else if (strcmp (token, "+keeplinked") == 0) entry_parms.should_keep_ld_output = true; |
1237 | else if (strcmp (token, "-keeplinked") == 0) entry_parms.should_keep_ld_output = false; |
1327 | else if (strcmp (token, "-keeplinked") == 0) entry_parms.should_keep_ld_output = false; |
- | 1328 | else if (strcmp (token, "+dupignore") == 0) entry_parms.should_ignore_duplicates = true; |
|
- | 1329 | else if (strcmp (token, "-dupignore") == 0) entry_parms.should_ignore_duplicates = false; |
|
- | 1330 | else if (strcmp (token, "+optional") == 0) entry_parms.should_allow_nonexistent_files = true; |
|
- | 1331 | else if (strcmp (token, "-optional") == 0) entry_parms.should_allow_nonexistent_files = false; |
|
1238 | else LOG_WARNING ("unimplemented attribute in \"%s\" line %d: '%s'", buildfile_pathname, lineno, token); |
1332 | else LOG_WARNING ("unimplemented attribute in \"%s\" line %d: '%s'", buildfile_pathname, lineno, token); |
1239 | #undef REACH_TOKEN_VALUE |
1333 | #undef REACH_TOKEN_VALUE |
1240 | 1334 | ||
1241 | token = strtok_r (NULL, RECORD_SEP, &ctx); // proceed to next attribute token |
1335 | token = strtok_r (NULL, RECORD_SEP, &ctx); // proceed to next attribute token |
1242 | } |
1336 | } |
Line 1254... | Line 1348... | ||
1254 | } } while (0) |
1348 | } } while (0) |
1255 | #define APPLY_DEFAULT_ATTR_STR(attr,descr,fmt) do { if (((default_parms->attr == NULL) && (entry_parms.attr != NULL)) || ((default_parms->attr != NULL) && (entry_parms.attr == NULL)) || ((default_parms->attr != NULL) && (entry_parms.attr != NULL) && (strcmp (entry_parms.attr, default_parms->attr) != 0))) { \ |
1349 | #define APPLY_DEFAULT_ATTR_STR(attr,descr,fmt) do { if (((default_parms->attr == NULL) && (entry_parms.attr != NULL)) || ((default_parms->attr != NULL) && (entry_parms.attr == NULL)) || ((default_parms->attr != NULL) && (entry_parms.attr != NULL) && (strcmp (entry_parms.attr, default_parms->attr) != 0))) { \ |
1256 | LOG_INFO ("changing default " descr " from " fmt " to " fmt " by attribute at \"%s\" line %d", (default_parms->attr != NULL ? default_parms->attr : "none"), entry_parms.attr, buildfile_pathname, lineno); \ |
1350 | LOG_INFO ("changing default " descr " from " fmt " to " fmt " by attribute at \"%s\" line %d", (default_parms->attr != NULL ? default_parms->attr : "none"), entry_parms.attr, buildfile_pathname, lineno); \ |
1257 | default_parms->attr = entry_parms.attr; \ |
1351 | default_parms->attr = entry_parms.attr; \ |
1258 | } } while (0) |
1352 | } } while (0) |
1259 | //APPLY_DEFAULT_ATTR_STR (new_cwd, "current working directory", "\"%s\""); |
1353 | //APPLY_DEFAULT_ATTR_STR (new_cwd, "current working directory", "\"%s\""); |
1260 | APPLY_DEFAULT_ATTR_STR (search, "search path list", "\"%s\""); |
1354 | APPLY_DEFAULT_ATTR_STR (search, "search path list", "\"%s\""); |
1261 | APPLY_DEFAULT_ATTR_STR (prefix, "prefix", "\"%s\""); |
1355 | APPLY_DEFAULT_ATTR_STR (prefix, "prefix", "\"%s\""); |
1262 | APPLY_DEFAULT_ATTR_NUM (dperms, "directory permissions", "0%o"); |
1356 | APPLY_DEFAULT_ATTR_NUM (dperms, "directory permissions", "0%o"); |
1263 | APPLY_DEFAULT_ATTR_NUM (perms, "file permissions", "0%o"); |
1357 | APPLY_DEFAULT_ATTR_NUM (perms, "file permissions", "0%o"); |
1264 | APPLY_DEFAULT_ATTR_NUM (uid, "owner ID", "%d"); |
1358 | APPLY_DEFAULT_ATTR_NUM (uid, "owner ID", "%d"); |
1265 | APPLY_DEFAULT_ATTR_NUM (gid, "group ID", "%d"); |
1359 | APPLY_DEFAULT_ATTR_NUM (gid, "group ID", "%d"); |
1266 | APPLY_DEFAULT_ATTR_NUM (st_mode, "inode type", "0%o"); |
1360 | APPLY_DEFAULT_ATTR_NUM (st_mode, "inode type", "0%o"); |
1267 | APPLY_DEFAULT_ATTR_NUM (is_compiled_bootscript, "compiled script state", "%d"); |
1361 | APPLY_DEFAULT_ATTR_NUM (is_compiled_bootscript, "compiled script state", "%d"); |
1268 | APPLY_DEFAULT_ATTR_NUM (should_follow_symlinks, "symlink resolution", |
1362 | APPLY_DEFAULT_ATTR_NUM (should_follow_symlinks, "symlink resolution flag", "%d"); |
1269 | APPLY_DEFAULT_ATTR_NUM (should_autosymlink_dylib, "dylib canonical name symlinking", "%d"); |
1363 | APPLY_DEFAULT_ATTR_NUM (should_autosymlink_dylib, "dylib canonical name symlinking", "%d"); |
1270 | APPLY_DEFAULT_ATTR_NUM (should_keep_ld_output, "linker output preservation", |
1364 | APPLY_DEFAULT_ATTR_NUM (should_keep_ld_output, "linker output preservation flag", "%d"); |
- | 1365 | APPLY_DEFAULT_ATTR_NUM (should_ignore_duplicates, "ignore duplicates flag", "%d"); |
|
- | 1366 | APPLY_DEFAULT_ATTR_NUM (should_allow_nonexistent_files, "ignore nonexistent files flag", "%d"); |
|
1271 | #undef APPLY_DEFAULT_ATTR_STR |
1367 | #undef APPLY_DEFAULT_ATTR_STR |
1272 | #undef APPLY_DEFAULT_ATTR_NUM |
1368 | #undef APPLY_DEFAULT_ATTR_NUM |
1273 | return; // end of line reached, proceed to the next line |
1369 | return; // end of line reached, proceed to the next line |
1274 | } |
1370 | } |
1275 | // end of attributes parsing |
1371 | // end of attributes parsing |