Your problem is that you pass as an attribute in your function, the data of the first node and not the address of the data of your first node. How does this affects us in this case? Any changes you make on the first node, are just changes in a local variable of your function that lives in the stack of your program and when your function returns, this variable will be gone and so the changes you have made.
Check this out, you may understand it better. Imagine that this is a snapshot of your ram and the grey cells are memory indexes and the white cells are the corresponding data:

When you have a variable like b (lets call it a "single pointer" variable) and you pass b as an attribute to a function, you actually pass the data of b (0x1) and not the address of b (0x3). With this in mind, you can notice that you are able to change the contents of 0x1 (for example add 10 and make it '30') but you cannot change the contents of 0x3, which is what you want.
If you want to be able to change the root of your list from a function without returning something, you have to pass the address of the address, or the "double pointer" variable, like c. Passing it like this you are able to:
a) change the data of 0x3: *first = ....
b) change the data of 0x1: **first = ....
If you want to check if understood it, think want is going to happen if you change the data of first. For example:
int **temp = ....;
first = temp;
Now that we mention the theoretical part, in order to follow what i am proposing, you have to change your code into something like this:
func(&first); //pass the address of first variable
.
.
func(<variableType> **first) { // receive with double star
.
.
*first = ...; // change the root using single star
.
.
}
list *, i.e. alist **, and then pass&firstto it, then you can modify what it points to.