When I hear about C programs that were a disaster because they used OO-like techniques, the operative word is usually "disaster" and not "C" or "OO". In other words, there were other things wrong with the project that had nothing to do with the selection of language or programming paradigm, like hiring inexperienced programmers or mandating a single programming paradigm for the whole codebase.
Good C code will have a lot fewer objects than say, Java, because most of the things you want to use C for, you can accomplish just fine with structs and functions. But you shouldn't shy away from a struct full of function pointers or an ADT with opaque pointer types and appropriately-namespaced member functions just because you're afraid a maintenance programmer won't get it. It's their responsibility to learn the language.