Mas experimentación del resolv.conf
parent
95d4826615
commit
009e568920
|
@ -46,7 +46,6 @@
|
|||
#include "bridge.h"
|
||||
#include "network-inador-manager.h"
|
||||
#include "dhcp_client.h"
|
||||
#include "struct_addr_union.h"
|
||||
#include "resolv_manager.h"
|
||||
|
||||
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
||||
|
@ -824,20 +823,19 @@ static void _manager_execute_resolvconf_feed (ManagerClientInfo *manager_client,
|
|||
int name_len, wanted;
|
||||
unsigned char iface_prog[256];
|
||||
unsigned char iface_name[256], prog[256];
|
||||
char value[2048];
|
||||
char *point;
|
||||
ResolvConfEntry *entry;
|
||||
GList *pos_entry;
|
||||
ResolvConfEntry *resolv_entries;
|
||||
int entries_count;
|
||||
|
||||
int ns_count;
|
||||
int search_count;
|
||||
int g, h, pos;
|
||||
int g, h, pos, ns_pos;
|
||||
int family;
|
||||
int order = 0;
|
||||
struct_addr direccion;
|
||||
int iface_index;
|
||||
Interface *iface;
|
||||
|
||||
int do_write = 0;
|
||||
|
||||
if (buffer_len < 3) {
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||
return;
|
||||
|
@ -874,7 +872,8 @@ static void _manager_execute_resolvconf_feed (ManagerClientInfo *manager_client,
|
|||
if (iface != NULL) {
|
||||
iface_index = iface->index;
|
||||
} else {
|
||||
iface_index = 0;
|
||||
_manager_send_error (manager_client, NET_INADOR_ERROR_INVALID_VALUE, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||
return;
|
||||
}
|
||||
|
||||
pos = 3 + name_len;
|
||||
|
@ -887,6 +886,10 @@ static void _manager_execute_resolvconf_feed (ManagerClientInfo *manager_client,
|
|||
ns_count = buffer[pos];
|
||||
pos++;
|
||||
|
||||
/* TODO: Sumar las otras entradas */
|
||||
entries_count = ns_count;
|
||||
|
||||
ns_pos = pos;
|
||||
/* Los nameserver vienen con un byte de familia y luego los bytes correspondientes a la IP */
|
||||
for (g = 0; g < ns_count; g++) {
|
||||
/* Revisar que en la longitud venga el byte de la familia */
|
||||
|
@ -914,58 +917,40 @@ static void _manager_execute_resolvconf_feed (ManagerClientInfo *manager_client,
|
|||
_manager_send_error (manager_client, NET_INADOR_ERROR_INCOMPLETE_REQUEST, NET_INADOR_COMMAND_RESOLVCONF_FEED);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tengo un Nameserver completo, buscar y dependiendo del caso, actualizar o crear */
|
||||
memcpy (&direccion, &buffer[pos], wanted);
|
||||
inet_ntop (family, &direccion, value, sizeof (value));
|
||||
|
||||
pos_entry = resolv_parser_search_entry (manager_client->manager->handle->resolver_entries, RESOLV_TYPE_NAMESERVER, family, &direccion, value);
|
||||
if (pos_entry != NULL) {
|
||||
/* De ser posible, hacer conciliación */
|
||||
entry = (ResolvConfEntry *) pos_entry->data;
|
||||
|
||||
if (entry->origin == RESOLV_ORIGIN_FILE) {
|
||||
/* Hacer esta entrada nuestra */
|
||||
entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
||||
entry->owner_interface_index = iface_index;
|
||||
strncpy (entry->owner_prog, prog, sizeof (entry->owner_prog));
|
||||
printf ("/// Asociando una entrada %s existente del archivo al: %s\n", entry->value, entry->owner_prog);
|
||||
} else {
|
||||
/* Existe la entrada, pero no la podemos tomar como nuestra, crear otra */
|
||||
entry = NULL;
|
||||
}
|
||||
} else {
|
||||
entry = NULL;
|
||||
}
|
||||
|
||||
/* Si no existe, crearla */
|
||||
if (entry == NULL) {
|
||||
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
||||
|
||||
entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
||||
entry->resolv_type = RESOLV_TYPE_NAMESERVER;
|
||||
entry->file_order = 0;
|
||||
entry->is_on_file = 0;
|
||||
entry->priority = 0;
|
||||
|
||||
entry->ns_family = family;
|
||||
memcpy (&entry->nameserver, &direccion, wanted);
|
||||
strncpy (entry->value, value, sizeof (entry->value));
|
||||
entry->owner_interface_index = iface_index;
|
||||
strncpy (entry->owner_prog, prog, sizeof (entry->owner_prog));
|
||||
|
||||
/* Anexar al final de la lista */
|
||||
manager_client->manager->handle->resolver_entries = g_list_append (manager_client->manager->handle->resolver_entries, entry);
|
||||
|
||||
/* TODO: Como creamos una entrada via el resolvconf, regenerar el archivo */
|
||||
printf ("/// Nueva entrada %s via resolvconf, programando regeneración.\n", entry->value);
|
||||
}
|
||||
pos += wanted;
|
||||
}
|
||||
|
||||
/* Ahora crear y parsear */
|
||||
/* TODO: Validar otro tipo de entradas */
|
||||
|
||||
/* OK */
|
||||
/* Notificar al cliente */
|
||||
_manager_send_executed (manager_client);
|
||||
|
||||
|
||||
/* Re-agrupar los datos para enviarlos al resolv_manager */
|
||||
resolv_entries = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry) * entries_count);
|
||||
h = 0;
|
||||
|
||||
pos = ns_pos;
|
||||
for (g = 0; g < ns_count; g++) {
|
||||
family = buffer[pos];
|
||||
resolv_entries[h].ns_family = family;
|
||||
pos++; /* El byte de la familia */
|
||||
|
||||
wanted = (family == AF_INET) ? 4 : 16;
|
||||
|
||||
/* Tengo un Nameserver completo, buscar y dependiendo del caso, actualizar o crear */
|
||||
memcpy (&resolv_entries[h].nameserver, &buffer[pos], wanted);
|
||||
inet_ntop (family, &resolv_entries[h].nameserver, resolv_entries[h].value, sizeof (resolv_entries[h].value));
|
||||
|
||||
pos += wanted;
|
||||
resolv_entries[h].resolv_type = RESOLV_TYPE_NAMESERVER;
|
||||
resolv_entries[h].origin = RESOLV_ORIGIN_RESOLVCONF;
|
||||
resolv_entries[h].owner_interface_index = iface_index;
|
||||
strncpy (resolv_entries[h].owner_prog, prog, sizeof (resolv_entries[h].owner_prog));
|
||||
h++;
|
||||
}
|
||||
|
||||
resolv_manager_process_resolvconf_entries (manager_client->manager->handle, resolv_entries, entries_count);
|
||||
}
|
||||
|
||||
static void _manager_execute_resolvconf_remove (ManagerClientInfo *manager_client, unsigned char *buffer, int buffer_len) {
|
||||
|
|
|
@ -53,7 +53,8 @@ typedef struct _ResolvConfEntry {
|
|||
int origin;
|
||||
|
||||
int file_order;
|
||||
int is_on_file;
|
||||
int tagged;
|
||||
int for_purge;
|
||||
int priority;
|
||||
|
||||
int ns_family;
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "resolv_conf_defs.h"
|
||||
#include "struct_addr_union.h"
|
||||
#include "resolv_conf_parser.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define COMMAND_SOCKET_PATH "/tmp/network-inador.socket"
|
||||
|
||||
|
@ -75,6 +76,50 @@ int wait_for_ack_or_error (int s) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
GList * helper_parser_parse_input (GList *all_entries, FILE *fd, int origin) {
|
||||
char buffer[8192], value[2048];
|
||||
ResolvConfEntry *entry = NULL;
|
||||
GList *pos, *next;
|
||||
int g, len;
|
||||
struct_addr direccion;
|
||||
int type;
|
||||
int family;
|
||||
int order;
|
||||
|
||||
order = 0;
|
||||
while (fgets (buffer, sizeof (buffer), fd), feof (fd) == 0) {
|
||||
utils_trim (buffer);
|
||||
utils_trim_comment (buffer);
|
||||
if (buffer[0] == 0) continue;
|
||||
|
||||
type = resolv_conf_parse_line (buffer, &family, &direccion, value, sizeof (value));
|
||||
|
||||
if (type == -1) {
|
||||
/* Linea no válida de acuerdo al parser, ignorar */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Desde el resolvconf helper, siempre anexar al final de la lista */
|
||||
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
||||
|
||||
entry->resolv_type = type;
|
||||
entry->origin = origin;
|
||||
|
||||
entry->ns_family = family;
|
||||
memcpy (&entry->nameserver, &direccion, sizeof (direccion));
|
||||
strncpy (entry->value, value, sizeof (entry->value));
|
||||
|
||||
entry->owner_interface_index = 0;
|
||||
entry->owner_prog[0] = 0;
|
||||
|
||||
all_entries = g_list_append (all_entries, entry);
|
||||
entry->tagged = 1;
|
||||
entry->file_order = order++;
|
||||
}
|
||||
|
||||
return all_entries;
|
||||
}
|
||||
|
||||
void send_entries (int s, GList *entries, const char *iface_prog) {
|
||||
char buffer[2048];
|
||||
int pos, len, pos_name_count;
|
||||
|
@ -243,7 +288,7 @@ int main (int argc, char *argv[]) {
|
|||
|
||||
if (action == 'a') {
|
||||
/* Parsear el archivo primero */
|
||||
entries = resolv_parser_parse_file (NULL, stdin, RESOLV_ORIGIN_RESOLVCONF);
|
||||
entries = helper_parser_parse_input (NULL, stdin, RESOLV_ORIGIN_RESOLVCONF);
|
||||
|
||||
/* Preparar un paquete de datos para enviar via el socket */
|
||||
send_entries (s, entries, iface_prog);
|
||||
|
|
|
@ -88,7 +88,7 @@ int resolv_conf_parse_line (const char *line, int *ns_family, struct_addr *names
|
|||
return -1;
|
||||
}
|
||||
|
||||
GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value) {
|
||||
GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value, int skip_tagged) {
|
||||
GList *g;
|
||||
ResolvConfEntry *entry;
|
||||
|
||||
|
@ -102,6 +102,12 @@ GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, c
|
|||
continue;
|
||||
}
|
||||
|
||||
if (skip_tagged == 1 && entry->tagged == 1) {
|
||||
/* Pasar a la siguiente entrada, nos pidieron omitir las marcadas en el archivo */
|
||||
g = g->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Comparar dependiendo del tipo */
|
||||
if (resolv_type == RESOLV_TYPE_NAMESERVER) {
|
||||
if (ns_family == AF_INET && entry->ns_family == AF_INET) {
|
||||
|
@ -127,7 +133,7 @@ GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, c
|
|||
return NULL;
|
||||
}
|
||||
|
||||
GList * resolv_parser_parse_file (GList *all_entries, FILE *fd, int origin) {
|
||||
GList * resolv_parser_parse_local_file (GList *all_entries, FILE *fd, int origin) {
|
||||
char buffer[8192], value[2048];
|
||||
ResolvConfEntry *entry = NULL;
|
||||
GList *pos, *next;
|
||||
|
@ -137,7 +143,7 @@ GList * resolv_parser_parse_file (GList *all_entries, FILE *fd, int origin) {
|
|||
int family;
|
||||
int order;
|
||||
|
||||
order = 0;
|
||||
order = 1;
|
||||
while (fgets (buffer, sizeof (buffer), fd), feof (fd) == 0) {
|
||||
utils_trim (buffer);
|
||||
utils_trim_comment (buffer);
|
||||
|
@ -150,7 +156,7 @@ GList * resolv_parser_parse_file (GList *all_entries, FILE *fd, int origin) {
|
|||
continue;
|
||||
}
|
||||
/* Tenemos una linea buena, buscar si esta linea ya existe en nuestra lista de entradas */
|
||||
pos = resolv_parser_search_entry (all_entries, type, family, &direccion, value);
|
||||
pos = resolv_parser_search_entry (all_entries, type, family, &direccion, value, 1);
|
||||
|
||||
if (pos != NULL) {
|
||||
/* Ya existe, refrescar que está en el archivo */
|
||||
|
@ -161,6 +167,7 @@ GList * resolv_parser_parse_file (GList *all_entries, FILE *fd, int origin) {
|
|||
|
||||
entry->resolv_type = type;
|
||||
entry->origin = origin;
|
||||
entry->for_purge = 0;
|
||||
|
||||
entry->ns_family = family;
|
||||
memcpy (&entry->nameserver, &direccion, sizeof (direccion));
|
||||
|
@ -171,7 +178,7 @@ GList * resolv_parser_parse_file (GList *all_entries, FILE *fd, int origin) {
|
|||
|
||||
all_entries = g_list_append (all_entries, entry);
|
||||
}
|
||||
entry->is_on_file = 1;
|
||||
entry->tagged = 1;
|
||||
entry->file_order = order++;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,8 +32,9 @@
|
|||
#include "common.h"
|
||||
#endif
|
||||
|
||||
GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value);
|
||||
GList * resolv_parser_parse_file (GList *all_entries, FILE *fd, int origin);
|
||||
int resolv_conf_parse_line (const char *line, int *ns_family, struct_addr *nameserver, char *value, const size_t value_size);
|
||||
GList * resolv_parser_search_entry (GList *all_entries, const int resolv_type, const int ns_family, const struct_addr *nameserver, const char *value, int skip_on_file);
|
||||
GList * resolv_parser_parse_local_file (GList *all_entries, FILE *fd, int origin);
|
||||
|
||||
#endif /* __RESOLV_CONF_PARSER_H__ */
|
||||
|
||||
|
|
|
@ -27,40 +27,154 @@
|
|||
#include <ctype.h>
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#include "resolv_manager.h"
|
||||
#include "common.h"
|
||||
#include "utils.h"
|
||||
#include "resolv_conf_parser.h"
|
||||
#include "interfaces.h"
|
||||
|
||||
void resolv_manager_write (NetworkInadorHandle *handle);
|
||||
|
||||
gint resolv_manager_sort_entries (const void *a, const void *b, gpointer data) {
|
||||
const ResolvConfEntry *aa = (ResolvConfEntry *) a;
|
||||
const ResolvConfEntry *bb = (ResolvConfEntry *) b;
|
||||
|
||||
/* Primero, las purgadas van al final */
|
||||
if (aa->for_purge == 1 && bb->for_purge == 0) {
|
||||
return 1;
|
||||
} else if (aa->for_purge == 0 && bb->for_purge == 1) {
|
||||
return -1;
|
||||
} else if (aa->for_purge == 1) {
|
||||
return 0;
|
||||
}
|
||||
if (aa->tagged == 1 && bb->tagged == 0) {
|
||||
/* TODO: Revisar este orden por prioridades */
|
||||
return -1;
|
||||
} else if (aa->tagged == 0 && bb->tagged == 1) {
|
||||
return 1;
|
||||
} else if (aa->tagged == 1) {
|
||||
/* Como los dos están en el archivo, comparar por el file_order */
|
||||
return (aa->file_order - bb->file_order);
|
||||
}
|
||||
|
||||
/* TODO: Estas entradas necesitan resolverse por prioridad de configuración */
|
||||
return 0;
|
||||
}
|
||||
|
||||
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog) {
|
||||
GList *g, *next;
|
||||
GList *g;
|
||||
ResolvConfEntry *entry;
|
||||
int do_write = 0;
|
||||
|
||||
g = handle->resolver_entries;
|
||||
while (g != NULL) {
|
||||
next = g->next;
|
||||
|
||||
entry = (ResolvConfEntry *) g->data;
|
||||
|
||||
if (entry->origin != RESOLV_ORIGIN_RESOLVCONF) {
|
||||
/* Solo borramos las entradas creadas via resolvconf */
|
||||
g = next;
|
||||
g = g->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry->owner_interface_index != iface_index) {
|
||||
g = next;
|
||||
g = g->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (prog == NULL || strcmp (entry->owner_prog, prog) == 0) {
|
||||
/* Hay que eliminar esta entrada, coincide por la interfaz o nombre de programa */
|
||||
printf ("/// Eliminando entrada %s por via resolvconf. Prog = «%s»\n", entry->value, prog);
|
||||
free (entry);
|
||||
/*free (entry);
|
||||
|
||||
handle->resolver_entries = g_list_delete_link (handle->resolver_entries, g);
|
||||
handle->resolver_entries = g_list_delete_link (handle->resolver_entries, g);*/
|
||||
entry->for_purge = 1;
|
||||
do_write = 1;
|
||||
}
|
||||
|
||||
g = next;
|
||||
g = g->next;
|
||||
}
|
||||
|
||||
/* Solicitar una escritura del archivo, via el resolvconf fuimos modificados */
|
||||
if (do_write == 1) {
|
||||
resolv_manager_write (handle);
|
||||
}
|
||||
}
|
||||
|
||||
void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle) {
|
||||
GList *pos;
|
||||
ResolvConfEntry *entry;
|
||||
|
||||
/* Borrar el atributo "tagged" */
|
||||
pos = handle->resolver_entries;
|
||||
while (pos != NULL) {
|
||||
entry = (ResolvConfEntry *) pos->data;
|
||||
|
||||
entry->tagged = 0;
|
||||
pos = pos->next;
|
||||
}
|
||||
}
|
||||
|
||||
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, ResolvConfEntry *entries, int num_entries) {
|
||||
int g;
|
||||
ResolvConfEntry *entry;
|
||||
GList *pos_entry;
|
||||
int do_write = 0;
|
||||
|
||||
resolv_manager_clear_tag_on_all (handle);
|
||||
|
||||
for (g = 0; g < num_entries; g++) {
|
||||
entry = NULL;
|
||||
while (entry == NULL) {
|
||||
pos_entry = resolv_parser_search_entry (handle->resolver_entries, entries[g].resolv_type, entries[g].ns_family, &entries[g].nameserver, entries[g].value, 1);
|
||||
if (pos_entry == NULL) break;
|
||||
|
||||
/* De ser posible, hacer conciliación */
|
||||
entry = (ResolvConfEntry *) pos_entry->data;
|
||||
|
||||
if (entry->origin == RESOLV_ORIGIN_FILE) {
|
||||
/* Hacer esta entrada nuestra */
|
||||
entry->origin = RESOLV_ORIGIN_RESOLVCONF;
|
||||
entry->owner_interface_index = entries[g].owner_interface_index;
|
||||
entry->tagged = 1;
|
||||
strncpy (entry->owner_prog, entries[g].owner_prog, sizeof (entry->owner_prog));
|
||||
printf ("/// Asociando una entrada %s existente del archivo al: %s\n", entry->value, entry->owner_prog);
|
||||
} else if (entry->origin == RESOLV_ORIGIN_DHCP) {
|
||||
/* Una entrada que coincide con la actual solo se puede re-asociar al resolvconf si pertenece a la misma interfaz */
|
||||
if (entry->owner_interface_index != entries[g].owner_interface_index) {
|
||||
entry->tagged = 1;
|
||||
entry = NULL;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
/* Existe la entrada, pero no la podemos tomar como nuestra, crear otra */
|
||||
entry->tagged = 1;
|
||||
entry = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Si no existe, crearla */
|
||||
if (entry == NULL) {
|
||||
entry = (ResolvConfEntry *) malloc (sizeof (ResolvConfEntry));
|
||||
|
||||
memcpy (entry, &entries[g], sizeof (ResolvConfEntry));
|
||||
entry->file_order = g; /* TODO: Revisar esto del file order */
|
||||
entry->tagged = 0;
|
||||
entry->priority = 0;
|
||||
entry->for_purge = 0;
|
||||
|
||||
/* Anexar al final de la lista */
|
||||
handle->resolver_entries = g_list_append (handle->resolver_entries, entry);
|
||||
|
||||
/* TODO: Como creamos una entrada via el resolvconf, regenerar el archivo */
|
||||
printf ("/// Nueva entrada %s via resolvconf, programando regeneración.\n", entry->value);
|
||||
do_write = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Si hubo actualización cambios, disparar ahora */
|
||||
if (do_write == 1) {
|
||||
resolv_manager_write (handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -74,34 +188,101 @@ void resolv_manager_read_local_etc_resolv (NetworkInadorHandle *handle) {
|
|||
|
||||
printf ("/// Ejecutando lectura de resolv.conf\n");
|
||||
/* Etiquetar las entradas con origen del archivo como "ya no en el archivo", para que cuando se lea el archivo, nos queden las que vamos a eliminar */
|
||||
/* Borrar cuáles están en el archivo */
|
||||
pos = handle->resolver_entries;
|
||||
while (pos != NULL) {
|
||||
entry = (ResolvConfEntry *) pos->data;
|
||||
|
||||
entry->is_on_file = 0;
|
||||
pos = pos->next;
|
||||
}
|
||||
resolv_manager_clear_tag_on_all (handle);
|
||||
|
||||
handle->resolver_entries = resolv_parser_parse_file (handle->resolver_entries, fd, RESOLV_ORIGIN_FILE);
|
||||
handle->resolver_entries = resolv_parser_parse_local_file (handle->resolver_entries, fd, RESOLV_ORIGIN_FILE);
|
||||
|
||||
fclose (fd);
|
||||
|
||||
/* A la salida, borrar las que ya no siguen en el archivo */
|
||||
pos = handle->resolver_entries;
|
||||
while (pos != NULL) {
|
||||
next = pos->next;
|
||||
//next = pos->next;
|
||||
entry = (ResolvConfEntry *) pos->data;
|
||||
|
||||
if (entry->origin == RESOLV_ORIGIN_FILE && entry->is_on_file == 0) {
|
||||
if (entry->origin == RESOLV_ORIGIN_FILE && entry->tagged == 0) {
|
||||
/* Esta entrada se va, la eliminaron */
|
||||
printf ("/// La entrada %s del resolv.conf fué eliminada del archivo. Purgando nosotros.\n", entry->value);
|
||||
|
||||
entry->for_purge = 1;
|
||||
/*handle->resolver_entries = g_list_delete_link (handle->resolver_entries, pos);
|
||||
free (entry);
|
||||
entry = NULL;*/
|
||||
} else {
|
||||
printf ("/// La entrada %s del resolv.conf sigue en el archivo.\n", entry->value);
|
||||
}
|
||||
pos = pos->next;
|
||||
}
|
||||
|
||||
/* Reordenar las entradas. TODO: Falta leer los ficheros de configuración del resolv.conf */
|
||||
handle->resolver_entries = g_list_sort_with_data (handle->resolver_entries, resolv_manager_sort_entries, NULL);
|
||||
}
|
||||
|
||||
void resolv_manager_write (NetworkInadorHandle *handle) {
|
||||
FILE *fd;
|
||||
GList *pos, *next;
|
||||
ResolvConfEntry *entry;
|
||||
Interface *iface;
|
||||
|
||||
/* Antes de hacer la escritura, siempre hacemos una lectura */
|
||||
resolv_manager_read_local_etc_resolv (handle);
|
||||
|
||||
/* Intentar la escritura */
|
||||
fd = fopen ("/etc/resolv.conf", "w");
|
||||
if (fd != NULL) {
|
||||
fprintf (fd, "# Autogenered by NetworkInador, you can change this file, changes are preserved");
|
||||
fprintf (fd, "\n\n");
|
||||
|
||||
pos = handle->resolver_entries;
|
||||
while (pos != NULL) {
|
||||
entry = (ResolvConfEntry *) pos->data;
|
||||
|
||||
if (entry->for_purge == 1) {
|
||||
/* Omitir */
|
||||
pos = pos->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
iface = _interfaces_locate_by_index (handle->interfaces, entry->owner_interface_index);
|
||||
/* Escribir esta entrada "buena" al resolv.conf */
|
||||
if (entry->origin == RESOLV_ORIGIN_FILE) {
|
||||
fprintf (fd, "# This entry was previously on file, preserving");
|
||||
} else if (entry->origin == RESOLV_ORIGIN_DHCP) {
|
||||
fprintf (fd, "# This entry was added via DHCP (on %s) via NetworkInador", (iface != NULL ? iface->name : "unknown"));
|
||||
} else if (entry->origin == RESOLV_ORIGIN_RESOLVCONF) {
|
||||
fprintf (fd, "# This entry was added via resolvconf (%s.%s)", (iface != NULL ? iface->name : "unknown"), entry->owner_prog);
|
||||
} else if (entry->origin == RESOLV_ORIGIN_SLAAC_RDNSS) {
|
||||
fprintf (fd, "# This entry was added via RDNSS (IPv6)");
|
||||
}
|
||||
fprintf (fd, "\n");
|
||||
|
||||
if (entry->resolv_type == RESOLV_TYPE_NAMESERVER) {
|
||||
fprintf (fd, "nameserver %s\n", entry->value);
|
||||
} else if (entry->resolv_type == RESOLV_TYPE_DOMAIN) {
|
||||
fprintf (fd, "domain %s\n", entry->value);
|
||||
} else if (entry->resolv_type == RESOLV_TYPE_SEARCH) {
|
||||
fprintf (fd, "search %s\n", entry->value);
|
||||
} else if (entry->resolv_type == RESOLV_TYPE_SORTLIST) {
|
||||
fprintf (fd, "sortlist %s\n", entry->value);
|
||||
} else if (entry->resolv_type == RESOLV_TYPE_OPTIONS) {
|
||||
fprintf (fd, "options %s\n", entry->value);
|
||||
}
|
||||
pos = pos->next;
|
||||
}
|
||||
|
||||
fclose (fd);
|
||||
}
|
||||
|
||||
/* Purgar las entradas marcadas para purge */
|
||||
pos = handle->resolver_entries;
|
||||
while (pos != NULL) {
|
||||
next = pos->next;
|
||||
entry = (ResolvConfEntry *) pos->data;
|
||||
|
||||
if (entry->for_purge == 1) {
|
||||
handle->resolver_entries = g_list_delete_link (handle->resolver_entries, pos);
|
||||
free (entry);
|
||||
entry = NULL;
|
||||
} else {
|
||||
printf ("/// La entrada %s del resolv.conf sigue en el archivo.\n", entry->value);
|
||||
}
|
||||
pos = next;
|
||||
}
|
||||
|
@ -125,13 +306,5 @@ void resolv_manager_init (NetworkInadorHandle *handle) {
|
|||
handle->resolver_entries = NULL;
|
||||
/* Luego, leer el resolv.conf */
|
||||
resolv_manager_read_local_etc_resolv (handle);
|
||||
|
||||
resolv_manager_read_local_etc_resolv (handle);
|
||||
|
||||
resolv_manager_read_local_etc_resolv (handle);
|
||||
|
||||
resolv_manager_read_local_etc_resolv (handle);
|
||||
|
||||
resolv_manager_read_local_etc_resolv (handle);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,15 @@
|
|||
#ifndef __RESOLV_MANAGER_H__
|
||||
#define __RESOLV_MANAGER_H__
|
||||
|
||||
#include "common.h"
|
||||
#include "struct_addr_union.h"
|
||||
#include "resolv_conf_parser.h"
|
||||
#include "resolv_conf_defs.h"
|
||||
|
||||
void resolv_manager_init (NetworkInadorHandle *handle);
|
||||
void resolv_manager_clear_entries_by_prog (NetworkInadorHandle *handle, const int iface_index, const char *prog);
|
||||
void resolv_manager_process_resolvconf_entries (NetworkInadorHandle *handle, ResolvConfEntry *entries, int num_entries);
|
||||
//void resolv_manager_clear_tag_on_all (NetworkInadorHandle *handle);
|
||||
//void resolv_manager_write (NetworkInadorHandle *handle);
|
||||
|
||||
#endif /* __RESOLV_MANAGER_H__ */
|
||||
|
||||
|
|
Loading…
Reference in New Issue