Considerably more difficult than you imagine. Between them, they have almost 70 command-line options or flags. Taking into account that many of those behave differently depending on the presence or absence of other flags, there's a couple hundred different code paths. Then you need to handle directories, files, sparse files, sym- and hard-links, on and across different filesystems, not to mention the various file-like things scattered around (pipes, streams, etc.)
It's not rocket science, but neither is it trivial.