more complete c implementation; untested