You can use bindgen to generate Rust bindings for a C library given a header file. You can use cheddar to generate a C header file for Rust code with extern fns. This should help with (a).
So you could set up cheddar, then use bindgen to generate functions which call the original c library. At this point all the Rust code will be doing is generating a (hopefully) functionally identical header file for a Rust library that calls the C library. Then you could run automated tools on the library to generate Rust functions and move things over function by function. Starting with the functions that are at the bottom of the dependency tree.
Rust has no significant runtime, no garbage collection, and is intended to run as fast as C (if you notice any significant deviations, complain on the irc channel, mailing list, or /r/Rust subreddit). So it should be reasonably straightforward as long as the C is well formed and you don’t introduce any stale/null pointer dereferences.
Does that make sense?
EDIT: Also note that there’s a gcc crate you can use to actually build a C library from source using a Rust buildscript. Depending on how you do things, you might find it useful.
The docs describe the fn call interface here: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe...
Then you need a .h header. I would include a .la and .pc so other toolchains can set their options correctly. The build instructions for users would be something like cargo build or make (which calls cargo).
PS: Mozilla does ;)