Está intentando agrupar el código de acuerdo con la estructura. La agrupación C es por archivo. Pones todas las funciones y variables internas en un encabezado o un encabezado y un archivo de objeto ".o" compilado a partir de un archivo fuente de CA.
No es necesario reinventar la orientación a objetos desde cero para un programa en C, que no es un lenguaje orientado a objetos.
He visto esto antes. Es algo extraño. Los codificadores, algunos de ellos, tienen aversión a pasar un objeto que quieren cambiar a una función para cambiarlo, aunque esa es la forma estándar de hacerlo.
Culpo a C ++, porque ocultó el hecho de que el objeto de clase es siempre el primer parámetro en una función miembro, pero está oculto. Así que parece que no está pasando el objeto a la función, aunque sí.
Client.addClient(Client& c);
C es flexible y puede tomar las cosas pasajeras por referencia.
La función AC a menudo devuelve solo un byte de estado o int y eso a menudo se ignora. En su caso, una forma adecuada podría ser
err = addClient( container_t cnt, client_t c);
if ( err != 0 )
{ fprintf(stderr, "could not add client (%d) \n", err );
addClient estaría en Client.ho Client.c