Panu Matilainen [Tue, 28 Sep 2010 11:55:29 +0000 (14:55 +0300)]
Decide header sigtag based on what was actually written
- makeGPGSignature() figures the signature type by parsing the
created signature, use that instead of the rather bogus tag
based on %_signature macro value passed from the cli level.
Panu Matilainen [Mon, 27 Sep 2010 14:15:15 +0000 (17:15 +0300)]
Handle non-terminated substrings centrally in expandMacro()
- expandMacro() is big and ugly already, but handling the non-terminated
substrings there once and for all avoids having to ping-pong recurse
through couple of helpers to get there.
Panu Matilainen [Mon, 27 Sep 2010 13:32:15 +0000 (16:32 +0300)]
Dynamic expansion buffer reallocation for lua macros too
Panu Matilainen [Mon, 27 Sep 2010 13:22:38 +0000 (16:22 +0300)]
Panu Matilainen [Mon, 27 Sep 2010 13:03:56 +0000 (16:03 +0300)]
Eliminate the internal in-place-expansion buffer limitation
- Return the dynamically allocated expansion buffer to callers from
expandU(), except using a slightly less cryptic expandThis() name
for it now. Also deal with non-terminated strings centrally in
expandThis() instead of doing alloc + copy to terminate in every caller.
Panu Matilainen [Mon, 27 Sep 2010 11:22:56 +0000 (14:22 +0300)]
Simplify / sanitize expandU() a bit
- Instead of saving and restoring the bits we'll mess with, just
make a temporary expansion state struct with non-buffer state
copied from "parent".
Panu Matilainen [Mon, 27 Sep 2010 11:05:37 +0000 (14:05 +0300)]
Dynamically reallocate macro expansion buffer (ticket #45)
- Eliminate the underlying limitation of macro expansion limit by
growing the buffer as needed when adding characters to it. This
doesn't fix the entire issue yet however: expandU() and expandMacros()
are still limited to caller-specified buffer size, and output
from lua-macros isn't dynamically resized. One step at a time...
Panu Matilainen [Mon, 27 Sep 2010 10:05:37 +0000 (13:05 +0300)]
Let expandMacro() allocate its own buffer
- More pre-requisites for dynamic buffer resizing, callers have no
clue how much expandMacro() is going to need.
Panu Matilainen [Mon, 27 Sep 2010 09:19:13 +0000 (12:19 +0300)]
Track current expansion point via distance to buffer start
- Supposedly no functional changes, just paving way for dynamic
buffer resizing which is impossible when accessing pointers directly.
Panu Matilainen [Fri, 24 Sep 2010 09:48:15 +0000 (12:48 +0300)]
Push the macro buffer size limit down by one level
- Turn expandMacros() into a wrapper around internal doExpandMacros()
which returns the expanded string in a newly allocated buffer, use
the internal version for rpmExpand() too.
Panu Matilainen [Mon, 27 Sep 2010 07:02:17 +0000 (10:02 +0300)]
Eliminate unused spec field from macro expansion state struct
Panu Matilainen [Mon, 27 Sep 2010 06:33:35 +0000 (09:33 +0300)]
Avoid calloc() in macro findEntry()
- It's just the macro name we're grabbing here, that ought to fit
on stack comfortably enough.
Panu Matilainen [Fri, 24 Sep 2010 07:49:19 +0000 (10:49 +0300)]
Avoid unnecessary round-trip through expandT() where possible
- In the cases where expandT() was called with strlen(source) we can
now just bypass it and call expandMacro() directly, avoiding an
unnecessary string copy.
Panu Matilainen [Fri, 24 Sep 2010 07:42:38 +0000 (10:42 +0300)]
Use function arguments to pass, duh, arguments into functions. Duh.
- No functional changes, just eliminating mindless save-and-restore
ping-pong through macro expansion state struct.
Jindrich Novy [Sun, 26 Sep 2010 16:45:34 +0000 (18:45 +0200)]
Fix segfault in rpmdeps (RhBug:637357)
Panu Matilainen [Wed, 22 Sep 2010 13:37:12 +0000 (16:37 +0300)]
Eliminate separate fileIndexEntry from rpmal
- This is exactly the same structure as availableIndexEntry, no need
for a different struct for it.
Panu Matilainen [Wed, 22 Sep 2010 11:28:32 +0000 (14:28 +0300)]
Use headerNextTag() for header format iteration
- Doesn't really win anything performance-wise but makes the code nicer
Panu Matilainen [Wed, 22 Sep 2010 06:46:25 +0000 (09:46 +0300)]
Use HEADER_MAGIC_FOO enums instead of 0/1 in python header code
Panu Matilainen [Wed, 22 Sep 2010 06:19:07 +0000 (09:19 +0300)]
Remove double const in urlstring struct
Panu Matilainen [Wed, 22 Sep 2010 06:14:12 +0000 (09:14 +0300)]
Make rpmsqAction compatible to sa_sigaction
Hajime Taira [Tue, 21 Sep 2010 22:27:34 +0000 (22:27 +0000)]
l10n: Updated Japanese (ja) translation to 100%
New status: 732 messages complete with 0 fuzzies and 0 untranslated.
Transmitted-via: Transifex (www.transifex.net).
Panu Matilainen [Tue, 21 Sep 2010 13:57:08 +0000 (16:57 +0300)]
Remove double const on rpmrc tables
Panu Matilainen [Tue, 21 Sep 2010 13:43:46 +0000 (16:43 +0300)]
Fix rpmRC/int return mismatch by counting errors from handleOneTrigger
Panu Matilainen [Tue, 21 Sep 2010 13:39:59 +0000 (16:39 +0300)]
Use rpmTag as psm scriptTag for type correctness
Panu Matilainen [Tue, 21 Sep 2010 13:35:10 +0000 (16:35 +0300)]
Default to the common case wrt dir name/index tags, not relocation
- Avoids an unnecessary extra initialization in the common case, and
also avoids int/enum mismatch from initializing to 0.
Panu Matilainen [Tue, 21 Sep 2010 13:28:34 +0000 (16:28 +0300)]
Move PTOK type enum out of the sprintfToken struct
- While legal in C++, the enum and its values are only visible within
the scope it was declared in, making it invisible to the rest of
the program.
Panu Matilainen [Tue, 21 Sep 2010 13:18:22 +0000 (16:18 +0300)]
Remove bunch of double consts in librpmbuild
Panu Matilainen [Tue, 21 Sep 2010 12:55:02 +0000 (15:55 +0300)]
Initialize nametag to RPMTAG_NOT_FOUND in parseRCPOT()
- Doesn't matter what the value is, the switch (somewhat hysterically)
makes it default to RPMTAG_REQUIRENAME in unknown cases anyway
Panu Matilainen [Tue, 21 Sep 2010 12:53:38 +0000 (15:53 +0300)]
Const pedantry: taropts only ever points to string constants
Panu Matilainen [Tue, 21 Sep 2010 12:38:41 +0000 (15:38 +0300)]
Move expression type enum out of the struct
- While legal in C++, the enum and its values are only visible within
the scope it was declared in, making it invisible to the rest of
the program.
Panu Matilainen [Tue, 21 Sep 2010 12:25:53 +0000 (15:25 +0300)]
Use actual enum values in tag table sentinel to avoid int/enum mismatch
- tagLoadIndex() looks for NULL in tag name, the other values aren't
looked at so it doesn't matter...
Panu Matilainen [Tue, 21 Sep 2010 12:21:12 +0000 (15:21 +0300)]
Add "c++ protection" to (hopefully) all of our internal headers
Panu Matilainen [Tue, 21 Sep 2010 12:17:46 +0000 (15:17 +0300)]
Missing c++ end marker in rpmdb_internal.h, oops
Panu Matilainen [Tue, 21 Sep 2010 12:13:02 +0000 (15:13 +0300)]
Add "C++ protection" to the public rpmutil.h header, oops...
Panu Matilainen [Tue, 21 Sep 2010 12:11:04 +0000 (15:11 +0300)]
void stepping on toes of relatives, part 5
- Eliminate remaining (hopefully) C++ reserved keywords in rpmbuild cli tool
Panu Matilainen [Tue, 21 Sep 2010 12:08:08 +0000 (15:08 +0300)]
Avoid stepping on toes of relatives, part 4
- Eliminate remaining (hopefully) C++ reserved keywords in librpm
Panu Matilainen [Tue, 21 Sep 2010 12:07:08 +0000 (15:07 +0300)]
Avoid stepping on toes of relatives, part 3
- Eliminate remaining (hopefully) C++ reserved keywords in librpmbuild
Panu Matilainen [Tue, 21 Sep 2010 12:02:43 +0000 (15:02 +0300)]
Avoid stepping on toes of relatives, part 2
- Eliminate uses of "class" which is a reserved keyword in C++
Panu Matilainen [Tue, 21 Sep 2010 11:55:03 +0000 (14:55 +0300)]
Avoid stepping on toes of relatives, part 1
- Eliminate uses of "this" which is a reserved keyword in C++
Panu Matilainen [Tue, 21 Sep 2010 11:50:40 +0000 (14:50 +0300)]
Queryformat string sanity in queryArgCallback()
- Use our string helper functions instead of manual length calculations
and allocations
Panu Matilainen [Tue, 21 Sep 2010 11:49:36 +0000 (14:49 +0300)]
Use rasprintf() instead of manual alloc + sprintf()
Panu Matilainen [Tue, 21 Sep 2010 11:47:46 +0000 (14:47 +0300)]
Rename tagtbl.c -> tagtbl.C
- This isn't a regular source file: its not compiled as such but only
included from tagname.c. Rename to disambiguate, and make it similar
to rpmhash.[CH]
Panu Matilainen [Tue, 21 Sep 2010 11:47:14 +0000 (14:47 +0300)]
Use the macro allocator variants within librpm*
Panu Matilainen [Tue, 21 Sep 2010 11:33:57 +0000 (14:33 +0300)]
Use _free() instead of rfree() where "return value" is assigned
Panu Matilainen [Tue, 21 Sep 2010 11:26:29 +0000 (14:26 +0300)]
Return explicit NULL from various fooFree() functions everywhere
Panu Matilainen [Tue, 21 Sep 2010 11:22:29 +0000 (14:22 +0300)]
Return typed pointers from rpmluaFree() and rpmluavFree()
Panu Matilainen [Tue, 21 Sep 2010 11:19:11 +0000 (14:19 +0300)]
Return typed pointer from headerformat cacheFree()
Panu Matilainen [Tue, 21 Sep 2010 11:16:23 +0000 (14:16 +0300)]
Return typed pointer from freeHardLink()
Panu Matilainen [Tue, 21 Sep 2010 11:14:29 +0000 (14:14 +0300)]
Use typed instead of void pointer for fsm dnl iterator
- Passing a void pointer for an internal helper function which
casts to the destination is just ... pfff.
Panu Matilainen [Tue, 21 Sep 2010 11:12:55 +0000 (14:12 +0300)]
Use typed instead of void pointer for fsm map iterator
- Passing a void pointer for an internal helper function which
casts to the destination is just ... pfff.
Panu Matilainen [Tue, 21 Sep 2010 11:04:44 +0000 (14:04 +0300)]
Adjust pgpMpiSet() dest type to match actual use
Panu Matilainen [Tue, 21 Sep 2010 11:03:43 +0000 (14:03 +0300)]
Error string is const char *, not void pointer
Panu Matilainen [Tue, 21 Sep 2010 10:43:48 +0000 (13:43 +0300)]
Adjust internal io read, write and digest update to take buf as void pointer
- This matches ffread() and read() much better, avoiding pile of casts.
- By some stroke of genious, glibc cookie interfaces disagree with the
other file stream protos by using char * for buf. Argh. Add explicit
cast for the schizophrenia.
Panu Matilainen [Tue, 21 Sep 2010 10:41:25 +0000 (13:41 +0300)]
Avoid using void pointer when we have a real type for the memfail function
Panu Matilainen [Tue, 21 Sep 2010 10:39:25 +0000 (13:39 +0300)]
Move the RPMVERSION constant among its friends in depends.c
- Doesn't make any difference, just grouping similar goo in one spot.
Panu Matilainen [Tue, 21 Sep 2010 10:29:01 +0000 (13:29 +0300)]
strrchr() family considered harmful, part 666
- strrchr() was silently casting away a const on a string coming
from rpmtdGetString(). Add an explicit cast and warning/fixme commentary
to the compressFilelist() hack which modifies (and then restores) the
const string.
Panu Matilainen [Tue, 21 Sep 2010 10:14:20 +0000 (13:14 +0300)]
strstr() considered harmful, part 541
- buf isn't const here, it's modified through pointer acquired through
strstr() which silently casts away the const.
Panu Matilainen [Tue, 21 Sep 2010 10:11:56 +0000 (13:11 +0300)]
Use RPMTAG_NOT_FOUND instead of for "invalid tag" value
Panu Matilainen [Tue, 21 Sep 2010 10:02:53 +0000 (13:02 +0300)]
Move RPMTAG_NOT_FOUND into rpmTag enumeration
- Permits presenting "invalid tag" cleanly via the rpmTag enum type
on function returns etc
Panu Matilainen [Tue, 21 Sep 2010 09:49:46 +0000 (12:49 +0300)]
Move rpmHeaderTagFunc() a bit to avoid unnecessary forward declaration
Panu Matilainen [Tue, 21 Sep 2010 09:45:53 +0000 (12:45 +0300)]
Move format extension table a bit to avoid unnecessary forward declaration
Panu Matilainen [Tue, 21 Sep 2010 09:40:33 +0000 (12:40 +0300)]
Use the new tag type/return type getters everywhere
- Instead of masking and bitfiddling all over the place, use the
new getters to get the exact (enum) type directly. rpmTagGetType()
is now unused within rpm but leaving around for backwards compatibility
Panu Matilainen [Tue, 21 Sep 2010 09:30:05 +0000 (12:30 +0300)]
Add yet more rpmTagTagTagFoo() functions
- Two stupid new getters: one for the real tag type, and another
for the return type. rpmTagGetType() returns both requiring bitmasking
all over the place
Panu Matilainen [Tue, 21 Sep 2010 09:27:27 +0000 (12:27 +0300)]
Split tag type and return type to separate fields in tag table
- rpmTagType is a pure enum really, avoid mixing it up unnecessarily
Panu Matilainen [Tue, 21 Sep 2010 09:26:23 +0000 (12:26 +0300)]
Use the enum name instead of value when generating the tagtable source
- This makes the table populated with actual enums instead of the
numbers they present
Panu Matilainen [Tue, 21 Sep 2010 09:23:18 +0000 (12:23 +0300)]
Use proper types for tag and format extension functions
- Stuff the tag prototypes into misc.h in lack of better place
- Actually use the headerTagFooFunction prototypes instead of void *
Panu Matilainen [Tue, 21 Sep 2010 09:15:44 +0000 (12:15 +0300)]
Differentiate between the possible te types and iterator selector values
- Transaction elements can only be of one type (hence the enum),
but the transaction set iteration permits selecting more than
one. Add a new typedef dummy for this purpose only.
Panu Matilainen [Tue, 21 Sep 2010 09:07:27 +0000 (12:07 +0300)]
Change fdstat functions to take fdOpx enum to fix int/enum mismatches
Panu Matilainen [Tue, 21 Sep 2010 09:06:24 +0000 (12:06 +0300)]
Fix up silly int/enum and type vs variable name mixups in urlPath()
Panu Matilainen [Tue, 21 Sep 2010 08:58:08 +0000 (11:58 +0300)]
Use actual rpmTags in place of the old HEADER_FOO defines everywhere
Panu Matilainen [Tue, 21 Sep 2010 08:40:49 +0000 (11:40 +0300)]
Rename specdFlags to remove unnecessary type vs variable name confusion
Panu Matilainen [Tue, 21 Sep 2010 08:37:21 +0000 (11:37 +0300)]
Fix up bunch of silly int vs rpmRC return code mismatches
Panu Matilainen [Tue, 21 Sep 2010 08:10:14 +0000 (11:10 +0300)]
Stop abusing enum typedefs for bitfield types
- Enums are fine for defining the bitfield flags, but the bitfield
itself is not an enumeration. Add a separate typedef on "rpmFlags"
type (presenting a bitfield of flags) for all of these. Compilers
hardly care, but the typedefs give a nice visual clue for
us humans using these flags far away from ho^H^H definitions.
Panu Matilainen [Fri, 17 Sep 2010 06:03:34 +0000 (09:03 +0300)]
Expel Tarjan from his nest
- Nested functions are a gcc-extension and very non-portable. Refactor
to eliminate the nesting by passing the "global" variables via
a struct from detectSCCs().
Panu Matilainen [Wed, 15 Sep 2010 08:54:11 +0000 (11:54 +0300)]
Dont check source packages against installed obsoletes
- Regression originating from somewhere around commit
781cfed0fd9c9651a2dd49175a85536f0b34b95b, obsoletes from installed
packages were matched against the package being built.
Building obsoleted packages needs to be possible, they could be for
an older distro for example.
Panu Matilainen [Tue, 14 Sep 2010 06:44:06 +0000 (09:44 +0300)]
Plug memleak from rpmSpecCheckDeps()
- We need to call rpmtsEmpty(), not rpmtsClean() to purge the
transaction elements in the set...
Héctor Daniel Cabrera [Mon, 13 Sep 2010 15:33:00 +0000 (15:33 +0000)]
l10n: Updated Spanish (Castilian) (es) translation to 100%
New status: 744 messages complete with 0 fuzzies and 0 untranslated.
Transmitted-via: Transifex (www.transifex.net).
Taylon Silmer [Mon, 13 Sep 2010 13:30:27 +0000 (13:30 +0000)]
l10n: Updated Portuguese (Brazilian) (pt_BR) translation to 100%
New status: 732 messages complete with 0 fuzzies and 0 untranslated.
Transmitted-via: Transifex (www.transifex.net).
Panu Matilainen [Mon, 13 Sep 2010 12:03:18 +0000 (15:03 +0300)]
Replace dbi walking copy-slop with an internal helper function
Panu Matilainen [Mon, 13 Sep 2010 11:16:44 +0000 (14:16 +0300)]
Rearrange newRpmdb() a bit for clarity
- Avoid allocating the structure until we know its ok.
Panu Matilainen [Mon, 13 Sep 2010 11:05:02 +0000 (14:05 +0300)]
Eliminate broken "can't happen" early return
- Opening RPMDBI_PACKAGES should indeed never fail, but if it does
this would return way too early, leaking memory and references
left and right. Also the dbi is rarely used for anything, only
the rewrite mode used by markReplacedFiles() needs it, dbi
is actually unused on dbiCclose()
Panu Matilainen [Mon, 13 Sep 2010 10:46:15 +0000 (13:46 +0300)]
Rearrange rpmdbInitIterator() a bit for clarity
- Avoid allocating the iterator until we know it's not an error.
Doing the chaining earlier doesn't help anything here as the
cursor used here wasn't linked to the mi at this point, and avoids
having to free up partially initialized structure in case of errors.
- Group the mi initialization to make the actual initialization
stand out from the (unnecessary) zeroing of the calloc()'ed struct.
Panu Matilainen [Mon, 13 Sep 2010 10:08:33 +0000 (13:08 +0300)]
Eliminate all fooUnlink() functions out of the API
- These are internal helpers only, all refcount users need to use
fooFree() or similar for correct operation. Add fwd declarations
where necessary to avoid moving code around unnecessarily.
- We could add these back later as aliases to fooFree() but for now,
just get them out of the way.
Panu Matilainen [Mon, 13 Sep 2010 10:06:31 +0000 (13:06 +0300)]
Unify header creation between headerNew() and headerLoad()
- Use internal helper instead of copy-slop code to allocate + init
the structure
Panu Matilainen [Mon, 13 Sep 2010 10:05:55 +0000 (13:05 +0300)]
Fix some broken fooUnlink() usages
- unreferencing should always go through fooFree() which does
the real refcounting and frees when references go out
Panu Matilainen [Mon, 13 Sep 2010 08:25:24 +0000 (11:25 +0300)]
Lift header verifying out of rpmdbNextIterator()
- No functional changes, just splicing up the ugly function
Panu Matilainen [Mon, 13 Sep 2010 07:44:14 +0000 (10:44 +0300)]
Minor optimizations on DBT initializations
- Move the DBT key+data to local scope where possible, only bother
zeroing them if they're actually going to be accessed.
Panu Matilainen [Mon, 13 Sep 2010 07:27:42 +0000 (10:27 +0300)]
...and now eliminate the unnecessary pointer variables
- Also check for NULL keyp in rpmdbExtendIterator() early to
avoid unnecessary zeroing + potential segfault from strlen(NULL)
Panu Matilainen [Mon, 13 Sep 2010 07:16:50 +0000 (10:16 +0300)]
Eliminate mi_key and mi_data from match iterator structure
- These are not used to hold iterator state but just for temporary
storage. Temporary data belongs to temporary variables.
- Assimilate rpmdbGrowIterator() into rpmdbExtendIterator() which
was just (ab)using mi_key for passing arguments into rpmdbGrowIterator()
and pass as argument instead.
- Declare local structs + pointers to them for this step to keep changes
minimal and "obvious"
Panu Matilainen [Wed, 8 Sep 2010 10:52:30 +0000 (13:52 +0300)]
Add test for manifest query in testsuite
Panu Matilainen [Wed, 8 Sep 2010 10:41:03 +0000 (13:41 +0300)]
Fix _USE_LIBIO test
- Commit
05b2d979e8097d648f91c773f2535a1f6013cb79 caused the
_USE_LIBIO test in rpmio.c to always fail as <stdio.h> wasn't included
yet at the time of the check, causing silent fallback to not
using libio even if actually available. Which in turn revealed
funky other little bugs, addressed in commits
d960e8c18764f7206ad723963f407e960dfb8ad9 and
be3c34dd15814d70a410b6fd646a2be7de14a1b5. Ptooey.
Panu Matilainen [Wed, 8 Sep 2010 10:31:25 +0000 (13:31 +0300)]
Differentiate between IO-errors and non-package "error" in rpmgi foo
- rpmgiLoadReadHeader() tested errno, but this isn't realiable:
rpmgiReadHeader() didn't differentiate between IO and other errors
properly so errno would be tested even when no errors (other than
not being a header) were present. This could be pretty much whatever
when no IO errors occurred in rpmgiReadHeader() but the file just
wasn't a header. With libio errno was typically EBADF, causing the
remaining code to execute, but without libio this happened to be
ENOENTRY, causing a silent failure on manifest query.
- This junk needs to die, really.
Panu Matilainen [Wed, 8 Sep 2010 10:01:57 +0000 (13:01 +0300)]
Fix rpmReadPackageManifest() on non-fpio FD when libio isn't available
- With libio, fdGetFILE() works on any io-type, but that's not the
case when libio isn't available. Using fdopen() makes it work
on both.
Panu Matilainen [Tue, 7 Sep 2010 20:15:08 +0000 (23:15 +0300)]
Turn rpmQueryVerify() into query iterator initializer
- Eliminates quite a bunch of redundant error code return hoop-jumping
and makes the iterator init + frees nicely paired all together
inside rpmcliArgIter().
Panu Matilainen [Tue, 7 Sep 2010 20:04:12 +0000 (23:04 +0300)]
Lift the remaining oddball case out of rpmQueryVerify()
- specfile queries are handled differently from everything else,
handle the special case in rpmcliArgIter()
Panu Matilainen [Tue, 7 Sep 2010 19:52:26 +0000 (22:52 +0300)]
Eliminate qva_mi and qva_gi from rpmQVKArguments
- These are internal only stuff and have no business being exported
in the API. Pass the iterators around in, duh, arguments as needed.
Panu Matilainen [Tue, 7 Sep 2010 19:39:14 +0000 (22:39 +0300)]
Eliminate some dozen redundant rpmcliShowMatches() calls
- Simply call it once at the end, its common for all the cases
Panu Matilainen [Tue, 7 Sep 2010 19:22:25 +0000 (22:22 +0300)]
Cut some extra twists from the query maze
- RPMQV_ALL and RPMQV_RPM do nothing but call rpmcli/giShowMatches()
in rpmQueryVerify(), call them directly from rpmcliArgIter() instead
- Make iterator allocation + deallocation symmetric: both
rpmcliArgIter() and rpmQueryVerify() now free what they alloced,
rpmfooShowMatches() is a weird place for freeing
Panu Matilainen [Tue, 7 Sep 2010 19:02:53 +0000 (22:02 +0300)]
Eliminate rpmQueryVerify() from librpm API
- This is an inconsistent oddball interface which only works for
limited query types, "cli" level API users are better off calling
rpmcliQuery() / rpmcliArgIter() instead
Panu Matilainen [Wed, 8 Sep 2010 04:48:04 +0000 (07:48 +0300)]
Urk, mixed up in branches and wrong stuff getting pushed. Revert.
- This reverts commits
9ac127c35272772e0fc862608f4bde9748862b3d and
7abc26e300afd4da71f220db496f813571a37f5a