If recursion is okay, then u need to walk the list recursively, and then reverse the list as you unwind. This can be accomplished by allowing another parameter to the recursive call to provide the pointer needed to walk through the beginning the list as the recursive calls are unwinding from the end. This implementation uses no extra local variables per recursive call, only the variables provided in the parameters.
void swap_left (node *a, node *b, int tmp) {
a->data = b->data;
b->data = tmp;
}
void reverse_recursively (node *cur, node **tail) {
if (cur) {
reverse_recursively(cur->next, tail);
if (*tail) {
swap_left(cur, *tail, cur->data);
if (cur != *tail) *tail = (*tail)->next;
if (cur == *tail) *tail = 0;
}
}
}
void reverse (node *list) {
reverse_recursively(list, &list);
}