This might help with getting you started:
Code:
struct node {
void *data;
struct node *next;
};
// assign b to a->next and return a.
struct node *cons(struct node *a, struct node *b);
// reverse each element in lst, then return a pointer to the first element.
struct node *reverse(struct node *lst);
// count the number of elements in lst.
size_t length(const struct node *lst);
// search for 'key' in lst. return a lst->data if it can be found, and a null
// pointer otherwise.
void *find(const void *key, const struct node *lst,
int (*compar) (const void *, const void *));
Basically you just leave allocation and anything to do with the 'data' member up to the code that uses the library. These functions are easy and straightforward to write, so a library isn't usually needed in practice.