in reply to Recursive file opening: reading an undef at the end of file

I suspect you mean
if (/^I/) { read_cal(substr($_,1), $mode); } else { print "|$_|\n"; }
rather than
if (/^I/) { read_cal(substr($_,1), $mode); } print "|$_|\n";
This is because your $_ variable has been altered by the recursion, so using it is no longer appropriate! If you really want to keep it, you'll have to use a named, local variable.