crm_report is an insanely large and complicated shell script:
wc -l tools/{crm_report.in,report.collector.in,report.common.in} 481 tools/crm_report.in 885 tools/report.collector.in 890 tools/report.common.in 2256 total
There was a time when problems kept coming up in the code, and an attempt was made to convert it to C. This was more than halfway completed in this branch in a fork, but had to be shelved due to more important things coming up. It should be relatively straightforward, but time-consuming, to complete. (It supports XML output but will need an API schema once finished.)
The shell-based crm_report has an undeclared dependency on perl that will go away when converted to C.
One of the complexities of the shell-based crm_report is that it copies report.collector and report.common to other nodes and executes them. The C version adds a new command-line option that the original crm_report instance can invoke on the other nodes instead. Mixed-version clusters may have trouble with this, but that's uncommon enough that we can just document the limitation.
This convenience function may come in handy at some point:
static bool is_dir(const char *name) { struct stat dirinfo; return (name != NULL) && (stat(name, &dirinfo) == 0) && S_ISDIR(dirinfo.st_mode); }
fnmatch(3) may come in handy to replace shell globbing.